#
# Copyright (C) 2012-2014 Navraj S. Pannu and Pavol Skubak, Leiden University
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#


#
# Experimental data input - Crystal/Dataset
# 
#

proc crystal_proc { arrayname counter } {
    upvar #0 $arrayname array
    global all_subframes
    
    foreach subframe $all_subframes {
#	trace vdelete array(INPUT_INTENSITY) w "update_main_scroll $subframe"  
 	for  { set i 0 } { $i < $array(N_CRYSTALS) } { incr i} {
	    trace vdelete array(CRYSTAL_INPUT_SUBSTRUCTURE,$i) w "update_main_scroll $subframe"  
 	    trace vdelete array(CRYSTAL_NATIVE,$i) w "update_main_scroll $subframe"  
	}
    }

    OpenSubFrame frame -toggle_display CRYSTAL_NATIVE,$counter open 1

    lappend all_subframes $frame

        CreateLine line \
            label "                                                       " \
            label "                                                       " \
            label "                                                       "

    CloseSubFrame

    OpenSubFrame frame -toggle_display CRYSTAL_NATIVE,$counter open 0

    lappend all_subframes $frame	

    OpenSubFrame frame -toggle_display PREMADE_START open "DETECT"

    lappend all_subframes $frame	

    CreateLine line \
	label "Substructure atom" \
	message "Element name of substructure atom" \
	widget CRYSTAL_ATOM_NAME -width 5 -oblig \
	-command "rungetstuff $arrayname CRYSTAL_ATOM_NAME,$counter" \
	label "Number of substructure atoms per monomer" \
	message "Approximate number of substructure atoms to find per monomer" \
	widget CRYSTAL_N_ATOMS -width 5 \
	-command "rungetstuff $arrayname CRYSTAL_N_ATOMS,$counter"

    CloseSubFrame

    OpenSubFrame frame -toggle_display PREMADE_START hide "DETECT"

    lappend all_subframes $frame	

    CreateLine line \
	label "Number of different anomalous scatterers in crystal" \
        message "More than one type of anomalous scatterer" \
        widget N_WATOMS -command "setup_experiment $arrayname" \
	-command "rungetstuff $arrayname N_WATOMS"


    OpenSubFrame frame -toggle_display CRYSTAL_INPUT_SUBSTRUCTURE,$counter open 1

    lappend all_subframes $frame	
    
# disabled at the moment; we can enable later if we add another file type support
#    CreateLine line \
# 	label "Input substructure " \
# 	message "Input a substructure" \
# 	widget CRYSTAL_INPUT_SUBSTRUCTURE_TYPE \
#	-command "rungetstuff $arrayname CRYSTAL_INPUT_SUBSTRUCTURE_TYPE"

    OpenSubFrame frame -toggle_display CRYSTAL_INPUT_SUBSTRUCTURE_TYPE,$counter open "Pdb"

    lappend all_subframes $frame	

    CreateInputFileLine line \
 	"Enter input substructure PDB file name" \
 	"COORDS in" \
 	SUBSTRUCTURE_INPUT_COORDSIN DIR_SUBSTRUCTURE_INPUT_COORDSIN \
	-command "getatomname $arrayname $counter ; rungetstuff $arrayname SUBSTRUCTURE_INPUT_COORDSIN,$counter"

    CloseSubFrame

    OpenSubFrame frame -toggle_display CRYSTAL_INPUT_SUBSTRUCTURE_TYPE,$counter open "Manual"

    lappend all_subframes $frame	

    CreateLine line \
	label "Coordinate format" \
	message "Choose to input either orthogonal or fractional coordinates" \
	widget COORDINATE_FORMAT \
	-command "rungetstuff $arrayname COORDINATE_FORMAT"


   CreateExtendingFrame N_ATOMS atom_proc \
	"Define Atom" \
	"Add Atom" \
	[list  ATOM_ID \
	     ATOM_X \
	     ATOM_Y \
	     ATOM_Z \
	     ATOM_X_NOREF \
	     ATOM_Y_NOREF \
	     ATOM_Z_NOREF \
	     ATOM_OCCU \
	     ATOM_BISO \
	     ATOM_OCCU_NOREF \
	     ATOM_BISO_NOREF \
	     ISOTROPIC_B] \
	-counter $counter 

    CloseSubFrame

    CloseSubFrame

    CloseSubFrame

    CloseSubFrame

    OpenSubFrame frame -toggle_display CRYSTAL_NATIVE,$counter open 1

    lappend all_subframes $frame

    OpenSubFrame frame -toggle_display INPUT_INTENSITY open 1

    lappend all_subframes $frame

    CreateLabinLine4 line \
	"I" \
	HKLIN "I"  DATA_I {} \
	-sigma "SIGI" DATA_SIGI {} \
	-toggle_display DATA_ANOMALOUS,$counter open 1 \
	-command "rungetstuff $arrayname DATA_I"

    CloseSubFrame
 
    OpenSubFrame frame -toggle_display INPUT_INTENSITY open 0

    lappend all_subframes $frame

    CreateLabinLine4 line \
	"F" \
	HKLIN "F"  DATA_F {} \
	-sigma "SIGF" DATA_SIGF {} \
	-toggle_display DATA_ANOMALOUS,$counter open 1 \
	-command "rungetstuff $arrayname DATA_F"

    CloseSubFrame

    CloseSubFrame

    OpenSubFrame frame -toggle_display CRYSTAL_NATIVE,$counter open 0

    lappend all_subframes $frame


   Create_nolabel_ExtendingFrame N_DATA data_proc \
	"Define Data" \
	"Add new Dataset to this Crystal" \
	[list  DATA_TYPE \
	     DATA_ANOMALOUS \
	     N_WATOMS \
	     ATOM_WAVE_ID1 \
	     DATA_FPRIME1 \
	     DATA_FPRIMEPRIME1 \
	     ATOM_WAVE_ID2 \
	     DATA_FPRIME2 \
	     DATA_FPRIMEPRIME2 \
	     ATOM_WAVE_ID3 \
	     DATA_FPRIME3 \
	     DATA_FPRIMEPRIME3 \
	     ATOM_WAVE_ID4 \
	     DATA_FPRIME4 \
	     DATA_FPRIMEPRIME4 \
	     ATOM_WAVE_ID5 \
	     DATA_FPRIME5 \
	     DATA_FPRIMEPRIME5 \
	     ATOM_WAVE_ID6 \
	     DATA_FPRIME6 \
	     DATA_FPRIMEPRIME6 \
	     DATA_WAVELENGTH \
	     MTZIN \
	     DIR_MTZIN \
	     DATA_I \
	     DATA_SIGI \
	     DATA_I_PLUS \
	     DATA_SIGI_PLUS \
	     DATA_I_MINUS \
	     DATA_SIGI_MINUS \
	     DATA_F \
	     DATA_SIGF \
	     DATA_F_PLUS \
	     DATA_SIGF_PLUS \
	     DATA_F_MINUS \
	     DATA_SIGF_MINUS ] \
	-noaddline \
	-counter $counter 

    CloseSubFrame

    rebuild_varmenus $arrayname

}

proc data_proc { arrayname c2 counter } {

    upvar #0 $arrayname array
    global all_subframes

    foreach subframe $all_subframes {
#	trace vdelete array(INPUT_INTENSITY) w "update_main_scroll $subframe"  
	for  { set i 0 } { $i < $array(N_CRYSTALS) } { incr i} {
	    trace vdelete array(CRYSTAL_INPUT_SUBSTRUCTURE,$i) w "update_main_scroll $subframe"  
	    trace vdelete array(CRYSTAL_NATIVE,$i) w "update_main_scroll $subframe"  
	}
    } 

#    OpenSubFrame frame -toggle_display CRYSTAL_NATIVE,$counter open 0
#
#    lappend all_subframes $frame
#
#    CreateLine line \
#	label "Dataset : $c2" \
#	message "Dataset : $c2" \
#	label "Type" \
#	message "Type" \
#	widget DATA_TYPE \
#	-command "rebuild_varmenus $arrayname" 
#
#    CloseSubFrame
    

    atom_wave_proc $arrayname $counter $c2

#	-command "setup_inputdata_xd $arrayname $counter $c2" \

    CreateLine line \
	label "Input" \
	widget INPUT_DATA  -width 15  \
	-command "rungetstuff $arrayname INPUT_DATA,${counter}_$c2" \
 	message "Either input merged intensities or structure factor amplitudes" 
#	label "          Input data in a separate MTZ file" \
#	widget SEPARATE_MTZIN  \
#	-command "rungetstuff $arrayname SEPARATE_MTZIN,${counter}_$c2" \
# 	message "Input separate mtz file for this crystal/dataset"

#    OpenSubFrame frame -toggle_display SEPARATE_MTZIN,${counter}_$c2 open 1

#    CreateInputFileLine line \
#	"Enter input MTZ file name" \
#	"MTZ in" \
#	MTZIN DIR_MTZIN \
#	-setlabin RFREE_LABEL [list FREE FreeR FreeR_flag] \
#	-setfileparam resolution_min LOW_RES_LIMIT \
#	-setfileparam resolution_max HIGH_RES_LIMIT \
#	-setfileparam space_group_name SPACE_GROUP_NAME \
#        -setfileparam cell_1 CELL_1 \
#        -setfileparam cell_2 CELL_2 \
#        -setfileparam cell_3 CELL_3 \
#        -setfileparam cell_4 CELL_4 \
#        -setfileparam cell_5 CELL_5 \
#        -setfileparam cell_6 CELL_6 \
#	-setfileparam space_group_number SPACE_GROUP_NUMBER \
#	-command "rungetstuff $arrayname MTZIN,${counter}_$c2"

#    CloseSubFrame

    OpenSubFrame frame -toggle_display INPUT_INTENSITY,${counter}_$c2 open 1

    # CreateLabinLine -command does not work properly...
    lappend all_subframes $frame

    CreateLabinLine4 line "Intensity I and its error mtz labels" \
	HKLIN "I"  DATA_I {} \
	-sigma "SIGI" DATA_SIGI {} \
	-toggle_display [Indxv DATA_ANOMALOUS $counter $c2] hide 1

    CreateLabinLine4 line "Friedel pair intensity (I+/I-) and their error mtz labels" \
	HKLIN 	"IP+" DATA_I_PLUS {} \
	-sigma "  SIGIP+" DATA_SIGI_PLUS {} \
	-dependent "IP-" DATA_I_MINUS {} \
	-sigma "  SIGIP-" DATA_SIGI_MINUS {} \
	-toggle_display [Indxv DATA_ANOMALOUS $counter $c2] hide 0 \
	-command "rungetstuff $arrayname DATA_ANOMALOUS,$c2" 


    CloseSubFrame

    OpenSubFrame frame -toggle_display INPUT_INTENSITY,${counter}_$c2 open 0

    lappend all_subframes $frame

    CreateLabinLine4 line \
	"F" \
	HKLIN "F"  DATA_F {} \
	-sigma "SIGF" DATA_SIGF {} \
	-toggle_display [Indxv DATA_ANOMALOUS $counter $c2] hide 1

    CreateLabinLine4 line \
	"F" \
 	HKLIN "FP+" DATA_F_PLUS {} \
	-sigma "SIGFP+" DATA_SIGF_PLUS {} \
	-dependent "FP-" DATA_F_MINUS {} \
	-sigma "SIGFP-" DATA_SIGF_MINUS {} \
	-toggle_display [Indxv DATA_ANOMALOUS $counter $c2] hide 0

    CloseSubFrame

    rebuild_varmenus $arrayname
}

proc atom_proc { arrayname c1 counter } {

    upvar #0 $arrayname array

    if { [info exists array(CRYSTAL_ATOM_NAME,$counter)] } {
	if { $array(ATOM_ID,${counter}_${c1}) == "" } {
	    set array(ATOM_ID,${counter}_${c1}) [string toupper $array(CRYSTAL_ATOM_NAME,$counter)] 
	}
    }	

    if { [info exists array(BFACTOR)] } {
	if { $array(ATOM_BISO,${counter}_${c1}) == "" } {
	    set array(ATOM_BISO,${counter}_${c1}) $array(BFACTOR) 
	}
    }
	
    CreateLine line \
	label "Atom $c1 : " \
	-italic \
	label "Atom ID" \
	message "Atom ID" \
	widget ATOM_ID 
#	 	label "Isotropic B factors" \
#		message "Isotropic B factors " \
#		widget ISOTROPIC_B 
	

    CreateLine line \
	message "Coordinates : " \
	label "Coords : " \
	message "X Coordinate" \
	label "X" \
	widget ATOM_X \
	message "Do not refine x coordinate" \
	label "NOREF" \
	widget ATOM_X_NOREF \
	message "Y Coordinate" \
	label "Y" \
	widget ATOM_Y \
	message "Do not refine y coordinate" \
	label "NOREF" \
	widget ATOM_Y_NOREF \
	message "Z Coordinate" \
	label "Z" \
	widget ATOM_Z \
	message "Do not refine z coordinate" \
	label "NOREF" \
	widget ATOM_Z_NOREF 

    CreateLine line \
	message "Atomic occupancy" \
	label "Occupancy" \
	widget ATOM_OCCU \
	message "Do not refine the occupancy" \
	label "NOREF" \
	widget ATOM_OCCU_NOREF \
	message "Atomic isotropic B factor" \
	label "Biso" \
	widget ATOM_BISO  \
	message "Do not refine the B factor" \
	label "NOREF" \
	widget ATOM_BISO_NOREF 

    rebuild_varmenus $arrayname

}

proc atom_wave_proc { arrayname crys data } {

    upvar #0 $arrayname array
    global all_subframes

    if { [info exists array(CRYSTAL_ATOM_NAME,$crys)] } {
	if { $array(ATOM_WAVE_ID1,${crys}_${data}) == "" } {
	    set array(ATOM_WAVE_ID1,${crys}_${data}) [string toupper $array(CRYSTAL_ATOM_NAME,$crys)] 
	}
    }	

    OpenSubFrame frame -toggle_display PREMADE_START open "DETECT"

    lappend all_subframes $frame

	CreateLine line \
	    label "Wavelength : " \
	    widget DATA_WAVELENGTH \
	    label "Atomic anomalous scattering coefficients : " \
	    -italic \
	    label "f'" \
	    message "f' - F prime" \
	    widget DATA_FPRIME1 -width 5 -oblig \
	    label "f''" \
	    message "f'' - F double prime" \
	    widget DATA_FPRIMEPRIME1 -width 5 -oblig \
	-command "rungetstuff $arrayname DATA_FPRIMEPRIME1"

    CloseSubFrame

    OpenSubFrame frame -toggle_display PREMADE_START hide "DETECT"

    lappend all_subframes $frame 
    
	CreateLine line \
	    label "Wavelength : " \
	    widget DATA_WAVELENGTH 
	for { set i 1 } { $i <= $array(N_WATOMS,$crys) } { incr i } {
	    CreateLine line \
		label "Atom : $i" \
		-italic \
		label "Atom ID" \
		 message "Atom ID" \
		widget ATOM_WAVE_ID$i -oblig \
	-command "rungetstuff $arrayname ATOM_WAVE_ID$i" \
		label "f'" \
		message "f' - F prime" \
		widget DATA_FPRIME$i -oblig \
		label "f''" \
		message "f'' - F double prime" \
		widget DATA_FPRIMEPRIME$i -oblig \
	-command "rungetstuff $arrayname DATA_FPRIMEPRIME$i"
	}

    CloseSubFrame


    rebuild_varmenus $arrayname
}

proc rebuild_varmenus { arrayname } {
    upvar #0 $arrayname array
    global all_subframes

    set inputsubstructure 0
# *NSP
    if { $array(PREMADE_START) != "Substructure detection" } { 
	set inputsubstructure 1
    }
    
    for { set i 1 } { $i <= $array(N_CRYSTALS) } { incr i } {
	foreach subframe $all_subframes {
	    trace vdelete array(CRYSTAL_INPUT_SUBSTRUCTURE,$i) w "update_main_scroll $subframe"
	}
	if {$inputsubstructure == 1} {
 	    if { $array(CRYSTAL_NATIVE,$i) == 0 } {
		set array(CRYSTAL_INPUT_SUBSTRUCTURE,$i) 1
	    }
	} else {
	    set array(CRYSTAL_INPUT_SUBSTRUCTURE,$i) 0
	}
	SetSystemVar block_scroll_update 0
	update_main_scroll $array(FRAME_experiment_proc_0)
    }    
}


#
# The main crank experiment design section
#
#
# Determine which program we should run and run it.   
#
# Also, setup the next program to be run:
#  If we are running program X, then the next logical program is Y.
#
#
proc experiment_proc { arrayname counter } {
    upvar #0 $arrayname array
    global XMLParse

    # Are we building a pipeline?  If so, don't update the
    # varmenus.  We will do so when we're done constructing
    # the pipeline.
    global building_pipeline

    set ProcessList [list detect peak phasing hand dm build refine]

    # Set the PROCESS_NAME to the current process
    #
    if { [info exists array(PROCESS_NAME,[expr $counter + 1])] } {
       set process $array(PROCESS_NAME,$counter)
    } else {
       set process $array(EXPERIMENTAL_PROCESS)
    }


    # Set the correct PROCESS_NAME to the string we just found
    set array(PROCESS_NAME,$counter) $process
    set array(PROCESS_STEP,$counter) $counter
    set NAME [string toupper $process]
    set name [string tolower $process]
    set i 0
    foreach process $ProcessList {
 	if { [string compare [string tolower $process] $name] == 0 } {
 	    ${name}_proc $arrayname $counter

 	    if { ![info exists array(PROCESS_NAME,[expr $counter + 1])] } {
	
		if { [info exists [lindex $ProcessList [expr $i+1]] ] } {
		     set array(EXPERIMENTAL_PROCESS) [lindex $ProcessList [expr $i+1]] 
		}
	    } else {
		set array(EXPERIMENTAL_PROCESS) $array(PROCESS_NAME,[expr $counter + 1])
	    }
	    incr i
	}
    }

    rebuild_varmenus $arrayname
    check_program $arrayname
}

proc clear_program_defaults { arrayname } {
    upvar #0 $arrayname array
}

proc check_program { arrayname } {
    global tcl_platform
    upvar #0 $arrayname array

# ***NSP this needs to be done again!
    set windows 0
    if { [string compare $tcl_platform(platform) "windows"] == 0 } {
	set windows 1
    }

     if { ( [info exists array(N_PROCESS)] && [info exists array(N_CRYSTALS) ] ) } {
	 if { ( ($array(N_PROCESS) == 0) || ($array(N_CRYSTALS) == 0 ) ||
		($array(N_PROCESS) == "") || ($array(N_CRYSTALS) == "" ) ) } {
	     return 0
	 }
     } else {
	 return 0
     }

    # check if the refmac version has the SAD and SIRAS function:
    set refmac_sad 0
    set refmac_siras 0

    if { [file exists [FindExecutable refmac5]] } {
	set refmac_command "refmac5 -i"
	set refmac_script "\nEND\n"
	set command "$refmac_command << \"$refmac_script\""
	catch {eval exec $command } output
	if { [regexp {refmac5; version *([0-9.]*)} $output match version]} {
	    if { $version >= 5.5 } {
		set refmac_sad 1
	    }
	    if { $version >= 5.6 } {
		set refmac_siras 1
	    }
	}
    }
}

proc setup_experiment { arrayname } {
    upvar #0 $arrayname array
    global all_subframes

    set experiment $array(EXPERIMENT_SETUP)

    # Save a few pieces of information for the experiment, so the user
    # doesn't have to re-enter them if they change the experiment.

# save coordinates ***NSP save names
    set save_ncrystal $array(N_CRYSTALS)
    for { set i 1 } { $i <= $array(N_CRYSTALS) } { incr i } {
        if { [info exists array(N_WATOMS,$i)] } {
            if { $array(N_WATOMS,$i) > 6 } {
                WarningMessage "Unfortunately, there is a limit to 6 different types of anomalous atoms to input"
                return
            }
        }

        set save_ndata($i) $array(N_DATA,$i)
        set save_atomname($i) [string toupper $array(CRYSTAL_ATOM_NAME,$i)]
        set save_natoms($i) $array(CRYSTAL_N_ATOMS,$i)
        set save_nwatoms($i) $array(N_WATOMS,$i)
        for { set j 1 } { $j <= $array(N_DATA,$i) } { incr j } {
            for { set k 1 } { $k <= $array(N_WATOMS,$i) } { incr k } {
                set save_fprime($i,$j,$k) $array(DATA_FPRIME$k,${i}_${j})
                set save_fprimeprime($i,$j,$k) $array(DATA_FPRIMEPRIME$k,${i}_${j})
                set save_watomname($i,$j,$k) [string toupper $array(ATOM_WAVE_ID$k,${i}_${j})]
            }
        }
    }

    deletecrystals $arrayname

    for { set i 1 } { $i <= $save_ncrystal } { incr i } {
        if { [info exists save_atomname($i)] } {
            set array(CRYSTAL_ATOM_NAME,$i) [string toupper $save_atomname($i)]
        }

        if { [info exists save_natoms($i)] } {
            set array(CRYSTAL_N_ATOMS,$i) $save_natoms($i)
        }

        if { [info exists save_nwatoms($i)] } {
            if { $array(PREMADE_START) != "Substructure detection" } {
                set array(N_WATOMS,$i) $save_nwatoms($i)
            } else {
                set array(N_WATOMS,$i) 1
            }
        }

        for { set j 1 } { $j <= $save_ndata($i) } { incr j } {
            for { set k 1 } { $k <= $array(N_WATOMS,$i) } { incr k } {
                 if { [info exists save_fprime($i,$j,$k)] } {
                     set array(DATA_FPRIME$k,${i}_${j}) $save_fprime($i,$j,$k)
                 }
                if { [info exists save_fprimeprime($i,$j,$k)] } {
                    set array(DATA_FPRIMEPRIME$k,${i}_${j}) $save_fprimeprime($i,$j,$k)
                }
                if { [info exists save_watomname($i,$j,$k)] } {
                    set array(ATOM_WAVE_ID$k,${i}_${j}) $save_watomname($i,$j,$k)
                }
            }
        }
    }

    # Setup the experiment the user requested
    # 
    # Tcl does not keep the same variable names
    # between invocations of these various options, so
    # in the future consider saving all these values so that the user
    # doesn't have to re-enter values when she changes the experiment
    # type.

    if { [StringSame $experiment "Single wavelength anomalous diffraction (SAD)"] } {
	set array(DATA_TYPE,1_1) "SAD"
	set array(CRYSTAL_NATIVE,1) 0
	set array(DATA_ANOMALOUS,1_1) 1
	update_toggleframe0 crystal_proc 0 $arrayname N_CRYSTALS 1 0
	update_extendingframe0 data_proc 1 $arrayname N_DATA,1 1 1	
    } elseif { [StringSame $experiment "Single isomorphous replacement with anomalous scattering (SIRAS)"] } {	
	set array(DATA_TYPE,1_1) "Native"
	set array(CRYSTAL_NATIVE,1) 1
	set array(DATA_ANOMALOUS,1_1) 0
	set array(DATA_TYPE,2_1) "Derivative"
	set array(DATA_ANOMALOUS,2_1) 1
	set array(CRYSTAL_NATIVE,2) 0
	update_toggleframe0 crystal_proc 0 $arrayname N_CRYSTALS 1 0
	update_extendingframe0 data_proc 1 $arrayname N_DATA,1 1 0
	update_toggleframe0 crystal_proc 1 $arrayname N_CRYSTALS 1 0
	update_extendingframe0 data_proc 2 $arrayname N_DATA,2 1 1
    } elseif { [StringSame $experiment "Two wavelength anomalous diffraction (2W-MAD)"] } {	
	set array(DATA_TYPE,1_1) "Peak"
	set array(DATA_TYPE,1_2) "Inflection"
	set array(CRYSTAL_NATIVE,1) 0
	set array(DATA_ANOMALOUS,1_1) 1
	set array(DATA_ANOMALOUS,1_2) 1	
	update_toggleframe0 crystal_proc 0 $arrayname N_CRYSTALS 1 0
	update_extendingframe0 data_proc 1 $arrayname N_DATA,1 1 0
	update_extendingframe0 data_proc 1 $arrayname N_DATA,1 1 1
    } elseif { [StringSame $experiment "Three wavelength anomalous diffraction (3W-MAD)"] } {	
	set array(DATA_TYPE,1_1) "Peak"
	set array(DATA_TYPE,1_2) "Inflection"
	set array(DATA_TYPE,1_3) "High Remote"
	set array(CRYSTAL_NATIVE,1) 0
	set array(DATA_ANOMALOUS,1_1) 1
 	set array(DATA_ANOMALOUS,1_2) 1
 	set array(DATA_ANOMALOUS,1_3) 1
	update_toggleframe0 crystal_proc 0 $arrayname N_CRYSTALS 1 0
	update_extendingframe0 data_proc 1 $arrayname N_DATA,1 1 0
	update_extendingframe0 data_proc 1 $arrayname N_DATA,1 1 0
	update_extendingframe0 data_proc 1 $arrayname N_DATA,1 1 1
    } elseif { [StringSame $experiment "Four wavelength anomalous diffraction (4W-MAD)"] } {	
	set array(DATA_TYPE,1_1) "Peak"
	set array(DATA_TYPE,1_2) "Inflection"
	set array(DATA_TYPE,1_3) "High Remote"
	set array(DATA_TYPE,1_4) "Low Remote"
	set array(DATA_ANOMALOUS,1_1) 1
 	set array(DATA_ANOMALOUS,1_2) 1
 	set array(DATA_ANOMALOUS,1_3) 1
 	set array(DATA_ANOMALOUS,1_4) 1
	set array(CRYSTAL_NATIVE,1) 0
	update_toggleframe0 crystal_proc 0 $arrayname N_CRYSTALS 1 0
	update_extendingframe0 data_proc 1 $arrayname N_DATA,1 1 0
	update_extendingframe0 data_proc 1 $arrayname N_DATA,1 1 0
	update_extendingframe0 data_proc 1 $arrayname N_DATA,1 1 0
	update_extendingframe0 data_proc 1 $arrayname N_DATA,1 1 1
    } elseif { [StringSame $experiment "Two wavelength anomalous diffraction with native (2W-MAD-N)"] } {	
	set array(DATA_TYPE,1_1) "Native"
	set array(CRYSTAL_NATIVE,1) 1
	set array(DATA_ANOMALOUS,1_1) 0
	set array(DATA_TYPE,2_1) "Peak"
	set array(DATA_TYPE,2_2) "Inflection"
	set array(CRYSTAL_NATIVE,2) 0
	set array(DATA_ANOMALOUS,2_1) 1
	set array(DATA_ANOMALOUS,2_2) 1	
	update_toggleframe0 crystal_proc 0 $arrayname N_CRYSTALS 1 0
	update_extendingframe0 data_proc 1 $arrayname N_DATA,1 1 0
	update_toggleframe0 crystal_proc 1 $arrayname N_CRYSTALS 1 0
	update_extendingframe0 data_proc 2 $arrayname N_DATA,2 1 0
	update_extendingframe0 data_proc 2 $arrayname N_DATA,2 1 1
    } elseif { [StringSame $experiment "Three wavelength anomalous diffraction with native (3W-MAD-N)"] } {	
	set array(DATA_TYPE,1_1) "Native"
	set array(CRYSTAL_NATIVE,1) 1
	set array(DATA_ANOMALOUS,1_1) 0
	set array(DATA_TYPE,2_1) "Peak"
	set array(DATA_TYPE,2_2) "Inflection"
	set array(DATA_TYPE,2_3) "High Remote"
	set array(CRYSTAL_NATIVE,2) 0
	set array(DATA_ANOMALOUS,2_1) 1
	set array(DATA_ANOMALOUS,2_2) 1	
	set array(DATA_ANOMALOUS,2_3) 1	
	update_toggleframe0 crystal_proc 0 $arrayname N_CRYSTALS 1 0
	update_extendingframe0 data_proc 1 $arrayname N_DATA,1 1 0
	update_toggleframe0 crystal_proc 1 $arrayname N_CRYSTALS 1 0
	update_extendingframe0 data_proc 2 $arrayname N_DATA,2 1 0
	update_extendingframe0 data_proc 2 $arrayname N_DATA,2 1 0
	update_extendingframe0 data_proc 2 $arrayname N_DATA,2 1 1
    } elseif { [StringSame $experiment "Four wavelength anomalous diffraction with native (4W-MAD-N)"] } {	
	set array(DATA_TYPE,1_1) "Native"
	set array(CRYSTAL_NATIVE,1) 1
	set array(DATA_ANOMALOUS,1_1) 0
	set array(DATA_TYPE,2_1) "Peak"
	set array(DATA_TYPE,2_2) "Inflection"
	set array(DATA_TYPE,2_3) "High Remote"
	set array(DATA_TYPE,2_4) "Low Remote"
	set array(CRYSTAL_NATIVE,2) 0
	set array(DATA_ANOMALOUS,2_1) 1
	set array(DATA_ANOMALOUS,2_2) 1	
	set array(DATA_ANOMALOUS,2_3) 1	
	set array(DATA_ANOMALOUS,2_4) 1	
	update_toggleframe0 crystal_proc 0 $arrayname N_CRYSTALS 1 0
	update_extendingframe0 data_proc 1 $arrayname N_DATA,1 1 0
	update_toggleframe0 crystal_proc 1 $arrayname N_CRYSTALS 1 0
	update_extendingframe0 data_proc 2 $arrayname N_DATA,2 1 0
	update_extendingframe0 data_proc 2 $arrayname N_DATA,2 1 0
	update_extendingframe0 data_proc 2 $arrayname N_DATA,2 1 0
	update_extendingframe0 data_proc 2 $arrayname N_DATA,2 1 1
    }

    rebuild_varmenus $arrayname


    SetSystemVar block_scroll_update 0	
}


#
# Clear all current program steps and make the default pipeline
#
proc add_program { arrayname } {
    upvar #0 $arrayname array	

    update_toggleframe0 experiment_proc 0 $arrayname N_PROCESS 1 1
    rebuild_varmenus $arrayname
}

#
# Clear all current program steps
#
proc clear_pipeline { arrayname } {
    upvar #0 $arrayname array
    global all_subframes
        
    if { $array(N_PROCESS) > 0 } {
	set n_prog $array(N_PROCESS)
 	for { set i 0 } { $i < $n_prog } { incr i} {
	    delete_frame $arrayname experiment_proc 0
 	}
	set array(N_PROCESS) 0

	foreach subframe $all_subframes {
	    trace vdelete array(SHOW_ALL_PIPELINE_INPUT) w "update_main_scroll $subframe"
	    trace vdelete array(DISPLAY_PIPELINE) w "update_main_scroll $subframe"
	}

	SetSystemVar block_scroll_update 0
	update_main_scroll $array(FRAME_experiment_proc_0)
    }

    rebuild_varmenus $arrayname
}

proc fix_scroll { arrayname } {
    upvar #0 $arrayname array
    global all_subframes
    
    foreach subframe $all_subframes {
	trace vdelete array(SHOW_ALL_PIPELINE_INPUT) w "update_main_scroll $subframe"
	trace vdelete array(DISPLAY_PIPELINE) w "update_main_scroll $subframe"
	trace vdelete array(PREMADE_START) w "update_main_scroll $subframe"
	trace vdelete array(PREMADE_END) w "update_main_scroll $subframe"
	trace vdelete array(IS_FREE) w "update_main_scroll $subframe"
	trace vdelete array(NMONOMERS) w "update_main_scroll $subframe"
    }

    SetSystemVar block_scroll_update 0
    update_main_scroll $array(FRAME_experiment_proc_0)
    rebuild_varmenus $arrayname
}

#
proc add_premade_pipeline { arrayname } {
    upvar #0 $arrayname array

    if { $array(N_PROCESS) > 0 } {
 	clear_pipeline $arrayname
	set $array(N_PROCESS) 0
    }

    # Are we building a pipeline?  If so, don't update the
    # varmenus.  We will do so when we're done constructing
    # the pipeline.
    global building_pipeline
    global no_part_mod
    global part_mod

    set building_pipeline 1

    # Depending on the selection of the user, fill the pipeline with
    # the appropriate programs.
    if { ($array(PARTIAL_MODEL) eq $part_mod) } {

	set array(EXPERIMENTAL_PROCESS) "peak"	
	update_toggleframe0 experiment_proc 0 $arrayname N_PROCESS 1 0	
    if { $array(PARTIAL_AS_SUBSTR) } {
      set array(EXPERIMENTAL_PROCESS) "phasing"
      update_toggleframe0 experiment_proc 0 $arrayname N_PROCESS 1 0
      set array(EXPERIMENTAL_PROCESS) "dm"
      update_toggleframe0 experiment_proc 0 $arrayname N_PROCESS 1 0
    }
	set array(EXPERIMENTAL_PROCESS) "build"
	update_toggleframe0 experiment_proc 0 $arrayname N_PROCESS 1 0
	set array(EXPERIMENTAL_PROCESS) "refine"
 	update_toggleframe0 experiment_proc 0 $arrayname N_PROCESS 1 1

    } else {
	set start $array(PREMADE_START)
	set end $array(PREMADE_END)

	if {  ( ( ( ([ string compare $start "Substructure phasing"]   == 0) || 
		    ([ string compare $start "Hand determination"]     == 0) ||
		    ([ string compare $start "Density modification"]   == 0) ||
		    ([ string compare $start "Model building"]         == 0) ) && 
		  ([ string compare $end   "Substructure detection"]   == 0) ) ||
		( ( ([ string compare $start "Hand determination"]     == 0) ||
		    ([ string compare $start "Density modification"]   == 0) ||
		    ([ string compare $start "Model building"]         == 0) ) && 
		  ( ([ string compare $end   "Substructure detection"] == 0) || 
		    ([ string compare $end   "Substructure phasing"]   == 0) ) ) ||
 		( ([ string compare $start "Model building"]           == 0) && 
		  ( ([ string compare $end   "Substructure detection"] == 0) || 
		     ([ string compare $end   "Substructure phasing"]   == 0) ||
		    ([ string compare $end   "Hand determination"]     == 0) ||
		     ([ string compare $end   "Density modification"]   == 0) ) ) ) } {
	    WarningMessage "The start step selected is after the end step."
	    return
	}

	set done 0

	if { [ string compare $start "Substructure detection"] == 0 } {
	    if { ($array(PARTIAL_MODEL) eq $no_part_mod) } {
		set array(EXPERIMENTAL_PROCESS) "detect"
	    } elseif { ($array(PARTIAL_MODEL) eq $part_mod) } {
		set array(EXPERIMENTAL_PROCESS) "peak"
	    }
	    if { [ string compare $end "Substructure detection"] == 0 } {
		set done 1
	    } else {
		update_toggleframe0 experiment_proc 0 $arrayname N_PROCESS 1 0
	    }
	}  

	if { ( ( ([ string compare $start "Substructure detection"] == 0) ||
		 ([ string compare $start "Substructure phasing"] == 0) ) && 
	       !$done) } {
	    set array(EXPERIMENTAL_PROCESS) "phasing"
	    if { [ string compare $end "Substructure phasing"] == 0 } {
		set done 1
	    } else {
		update_toggleframe0 experiment_proc 0 $arrayname N_PROCESS 1 0
	    }  
	}

	if { ( ( ([ string compare $start "Substructure detection"] == 0) ||
		 ([ string compare $start "Substructure phasing"]   == 0) ||
		 ([ string compare $start "Hand determination"]   == 0) ) &&
	       !$done && !$array(SKIP_HAND) ) } {
	    set array(EXPERIMENTAL_PROCESS) "hand"
	    if { [ string compare $end "Hand determination"] == 0 } {
		set done 1
	    } else {
		update_toggleframe0 experiment_proc 0 $arrayname N_PROCESS 1 0
	    }
	}

	if { ( ( ([ string compare $start "Substructure detection"] == 0) ||
		 ([ string compare $start "Substructure phasing"]   == 0) ||
		 ([ string compare $start "Hand determination"]   == 0) ||
		 ([ string compare $start "Density modification"]   == 0) ) &&
	       !$done) } {
	    set array(EXPERIMENTAL_PROCESS) "dm"

	    if { [ string compare $end "Density modification"] == 0 } {
		set done 1
	    } else {
		update_toggleframe0 experiment_proc 0 $arrayname N_PROCESS 1 0
	    }
	}

	if { !$done } {
	    set array(EXPERIMENTAL_PROCESS) "build"
	    if { [ string compare $end "Model building"] == 0 } {
		set done 1
	    } else {
		update_toggleframe0 experiment_proc 0 $arrayname N_PROCESS 1 0
	    }
	}

	if { !$done } {
	    set array(EXPERIMENTAL_PROCESS) "refine"
	    if { [ string compare $end "Model refinement"] == 0 } {
		set done 1
	    } else {
		update_toggleframe0 experiment_proc 0 $arrayname N_PROCESS 1 0
	    }
	}

	if { $done } {
	    update_toggleframe0 experiment_proc 0 $arrayname N_PROCESS 1 1
	}
    }

    set building_pipeline 0

    rebuild_varmenus $arrayname
}

#
# Check to see if $atomname is present in the file
# $CLIBD/atomsf.lib
#
proc check_atomname { arrayname atomname } {
    upvar #0 $arrayname array
    global env
	
    set atomname [string tolower $atomname]
    set atomsf "[file join $env(CLIBD) atomsf.lib]"

    set file_id [open $atomsf r]

    set done 0
    while { !$done } {
	gets $file_id line
	if { ! [regexp {AD.*} $line]} {
	    set done 1
	 }
    }
	
    lappend atomlist $line
    gets $file_id line
    gets $file_id line
    gets $file_id line
    gets $file_id line

    while { [gets $file_id line] >= 0 } {
	lappend atomlist $line
	gets $file_id line
	gets $file_id line
	gets $file_id line
	gets $file_id line
	lappend cu_structure_factors $line
    }

    set match 0
    for { set i 0 } { $i < [llength $atomlist] } { incr i } {
	if { [regexp {([A-Za-z+0-9-]*) } [lindex $atomlist $i] full atom] } {
	    set atom [string tolower $atom]
	    if { [string compare $atomname $atom] == 0 } {
		set match 1
		set i [expr $i - 1]
		set fprime  [lindex [lindex $cu_structure_factors $i] 0]
		set fprimeprime [lindex [lindex $cu_structure_factors $i] 1]
		break
	    }
	}
    }

    if { $match == 1 } {
	return 1
    } else {
	return 0
    }
}

#
# Get the atomic form factors for $atomname from the information in
# $CLIBD/atomsf.lib
#
proc GetFormFactors { atomname } {
    global env
	
    set atomname [string tolower $atomname]
    set atomsf "[file join $env(CLIBD) atomsf.lib]"

    set file_id [open $atomsf r]

    set done 0
    while { !$done } {
	gets $file_id line
	if { ! [regexp {AD.*} $line]} {
	    set done 1
	}
    }
	
    lappend atomlist $line
    gets $file_id line
    gets $file_id line
    gets $file_id line
    gets $file_id line

    while { [gets $file_id line] >= 0 } {
	lappend atomlist $line
	gets $file_id line
	gets $file_id line
	gets $file_id line
	gets $file_id line
	lappend cu_structure_factors $line
    }

    set match 0
    for { set i 0 } { $i < [llength $atomlist] } { incr i } {
	if { [regexp {([A-Za-z+0-9-]*) } [lindex $atomlist $i] full atom] } {
	    set atom [string tolower $atom]
	    if { [string compare $atomname $atom] == 0 } {
		set match 1
		set i [expr $i - 1]
		set fprime  [lindex [lindex $cu_structure_factors $i] 0]
		set fprimeprime [lindex [lindex $cu_structure_factors $i] 1]
		break
	    }
	}
    }

    if { $match == 1 } {
	return "$fprime $fprimeprime"
    } else {
	return "0.0 0.0"
    }
}

proc deletecrystals { arrayname } {
    upvar #0 $arrayname array
    # Delete all current crystals/datasets

    global all_subframes

    if { $array(N_CRYSTALS) > 0 } {

	set n_crystals $array(N_CRYSTALS)
	for { set i 0 } { $i < $n_crystals } { incr i} {
	    delete_frame $arrayname crystal_proc 0
	}

 	set array(N_CRYSTALS) 0
	rebuild_varmenus $arrayname
    }
}


proc lbl_chck { label } {
    if { $label == "" || [StringSame $label "Unassigned"] } {
       return 1
    } else {
       return 0
    }
}

proc lbl_chck_all { arrayname anom lab1 lab2 lab3 lab4 } {
    upvar #0 $arrayname array
    # checks the inputted labels (returns 1 if there is an unassigned one)
    if { [lbl_chck $array($lab1)] || [lbl_chck $array($lab2)] } {
      return 1
    }
    if { $anom && ( [lbl_chck $array($lab3)] || [lbl_chck $array($lab4)] ) } {
      return 1
    }
    return 0
}


proc switch_rebuild_to_build { arrayname } {
    
}

proc rungetstuff { arrayname par } {
    upvar #0 $arrayname array
    global env
    global tcl_platform
    global part_mod

# puts "par: $par"
    set par_cut2 [string range $par 0 end-2]

    set windows 0
    if { [string compare $tcl_platform(platform) "windows"] == 0 } {
      set windows 1
    }

    # switch between new_free and input_free
    if { $par eq "NEW_FREE" && $array(NEW_FREE) } {
      set array(INPUT_FREE) 0
    } elseif { $par eq "INPUT_FREE" && $array(INPUT_FREE) } {
      set array(NEW_FREE) 0
    } else {
    # use free for refinement by default
      if { $par eq "HKLIN" && !$array(NEW_FREE) && !$array(INPUT_FREE) } {
        if { ($array(FREE_LABEL) ne "Unassigned") && ($array(FREE_LABEL) ne "") } {
          set array(INPUT_FREE) 1
        } else {
          set array(NEW_FREE) 1
        }
      }
    }
    # set IS_FREE (1 if we are using free, 0 otherwise) - needed for toggling subframes
    if { $array(NEW_FREE) || $array(INPUT_FREE) } {
      set array(IS_FREE) 1
    } else {
      set array(IS_FREE) 0
    }
    # set the process exclude options
    for {set i 1} {$i <= $array(N_PROCESS)} {incr i} {
      if { $array(PROCESS_NAME,$i) eq "refine" || $array(PROCESS_NAME,$i) eq "build" } {
        set proc_cap [string toupper $array(PROCESS_NAME,$i)]
        if { ($array(IS_FREE)) && ($par ne "${proc_cap}_EXCLUDE,$i") } {
          set array(${proc_cap}_EXCLUDE,$i) $array(USER_${proc_cap}_EXCLUDE,$i)
        } elseif { !$array(IS_FREE) } {
          set array(${proc_cap}_EXCLUDE,$i) 0
    } } }

    # sequence
    if { ($par eq "SEQIN") && ($array(SEQIN) != "") && ($array(DOCK_SEQUENCE) == 1) } {
      set input_seq "[GetFullFileName0 $arrayname SEQIN]"
      if { [llength [split $input_seq]] > 1 } {  
        WarningMessage "The input sequence file name or directory must not contain any spaces"
        return
      }
      set seq_type [string tolower [string range $input_seq [expr [string length $input_seq] - 3] [string length $input_seq]]]
      set pir_file [string equal $seq_type pir] 
      set seq_file [string equal $seq_type seq]
      set fas_file [string equal $seq_type fas]
      set fasta_file [string equal $seq_type sta]
      if { $fasta_file} {
        set fas_file 1
      }
      if { !( ($pir_file) || ($seq_file)  || ($fas_file) ) } {
        WarningMessage "The sequence file must end with .pir, .seq or .fas, .fasta"
        return 0
      }
      if {[ReadFile $input_seq sequence_text]} {
        set data [split $sequence_text "\n"]
        set formatted ""
        set skip_pir_line 0
        foreach line $data {
          if { [regexp {^>* } $line junk] || ( $skip_pir_line ) } {
		    if { $skip_pir_line } {
			set skip_pir_line 0
		    } else {
			if { $pir_file } { 
			    set skip_pir_line 1 
			}
		    }
		  } else {
 		    regsub -all {[^a-zA-Z]} $line "" tmp
		    if { $tmp != "" } {
			if { $formatted == ""} {
			    set formatted "[string toupper $tmp]"
			} else {
			    set formatted "$formatted[string toupper $tmp]"
			}
		    }
          } 
        }
      } else {
        WarningMessage "The sequence file could not be processed - check its syntax or permissions."
        return 0
      }
      set array(SEQUENCE) $formatted
      set array(NRESIDUES) [string length $formatted]
    } 

    # the data!
    # set the intensity/amplitudes switch and update the menus
    if { [string range $par 0 9] eq "INPUT_DATA" } {
      set ind [string range $par end-3 end]
      if { $array($par) eq "Amplitudes" } {
        set array(INPUT_INTENSITY$ind) 0
      } else {
        set array(INPUT_INTENSITY$ind) 1
      }
      rebuild_varmenus $arrayname
    }
    if { $array(HKLIN) != "" } {
      # check hklin exists
      set hklin [GetFullFileName0 $arrayname HKLIN]
      if { ![file exists $hklin] } {
        WarningMessage "Inputted HKLIN file $hklin does not exist."
        set array(HKLIN) ""
        return
      }
      # initialize mtzin_$i_$j to hklin
      if { $par eq "HKLIN" } {
        for { set i 1 } { $i <= $array(N_CRYSTALS) } { incr i } {
          for { set j 1 } { $j <= $array(N_DATA,$i) } { incr j } {
            set array(MTZIN,${i}_$j) $hklin
#            puts "MTZIN,${i}_$j $array(MTZIN,${i}_$j)"
        } }
      }
      # clear high resol. cutoff if new data has been inputted or detection program has been changed
      if { $par eq "HKLIN" || $par_cut2 eq "DETECT_PROGRAM" } {
        for { set i 1 } { $i <= 9 } { incr i } {
          set array(DETECT_HIGHRES_CUTOFF,$i) ""
          set array(USER_DETECT_HIGHRES_CUTOFF,$i) ""
        }
      }
      if { [llength [split $hklin]] > 1 } {  
        WarningMessage "The input mtz file name or directory must not contain any spaces"
        return
      }
      set good 1
      set crystal_input ""
      # Loop over all crystals/datasets and check all is assigned
      if { $array(N_CRYSTALS) > 0 } {
        set column_list {}
        for { set i 1 } { $i <= $array(N_CRYSTALS) } { incr i } {
          for { set j 1 } { $j <= $array(N_DATA,$i) } { incr j } {
            if { $array(INPUT_INTENSITY,${i}_$j) } {
              set ia I
            } else {
              set ia F
            }
            # Check for presence of both I+ and I-
            # if hklin/mtzin was just specified, we try to emulate the automatic ccp4i label assignment
            if { $array(DATA_ANOMALOUS,${i}_${j}) } {
              set lab1 DATA_${ia}_PLUS,${i}_$j
              set lab2 DATA_SIG${ia}_PLUS,${i}_$j
              set lab3 DATA_${ia}_MINUS,${i}_$j
              set lab4 DATA_SIG${ia}_MINUS,${i}_$j
              if { $par eq "HKLIN" || $par eq "MTZIN,${i}_$j" } {
                SetLabin $arrayname HKLIN $lab1 {} $lab2 {} $lab3 {} $lab4 {}
              }
              if { [lbl_chck_all $arrayname 1 $lab1 $lab2 $lab3 $lab4] } {
                set good 0
              }
              lappend column_list $lab3
              lappend column_list $lab4
            } else {
              if { $array(CRYSTAL_NATIVE,$i) == 0 } {
                set lab1 DATA_${ia},${i}_$j
                set lab2 DATA_SIG${ia},${i}_$j
              } else {
                set lab1 DATA_${ia},${i}
                set lab2 DATA_SIG${ia},${i}
              }
              if { $par eq "HKLIN" || $par eq "MTZIN,${i}_$j" } {
                SetLabin $arrayname HKLIN $lab1 {} $lab2 {}
              }
              if { [lbl_chck_all $arrayname 0 $lab1 $lab2] } {
                set good 0
              }
            }
            lappend column_list $lab1
            lappend column_list $lab2
          }
        }
      } else {
        return
      }
      # Check if any dataset is specified more than once in the experimental data section.
      for { set m 0 } { $m < [expr [llength $column_list] - 1] } { incr m } {
        for { set n [expr $m + 1] } { $n < [llength $column_list] } { incr n } {
          if { [StringSame [lindex $column_list $m] [lindex $column_list $n]] } {
            set good 0
          }
        }
      }
      if { $good == 0 } {
          return 0
      }
      # use crosssec to calculate f',f'' if possible and not set yet
      for { set i 1 } { $i <= $array(N_CRYSTALS) } { incr i } {
       for { set j 1 } { $j <= $array(N_DATA,$i) } { incr j } {
	    set filename [GetFullFileName0 $arrayname MTZIN,${i}_$j]

	    if { $array(INPUT_INTENSITY,${i}_$j) } {
		set column $array(DATA_I_PLUS,${i}_${j})
	    } else {
		set column $array(DATA_F_PLUS,${i}_${j})
	    }
	    
	    GetMtzDatasetFromLabel $filename $column xname dname
	    GetMtzParamFromDataset $filename $xname $dname DWAVES dwave
	
	    if { [info exists dwave] } {
		set array(DATA_WAVELENGTH,${i}_${j}) $dwave
		set array(CRYSTAL_ID,$i) $xname
		set array(DATA_ID,${i}_${j}) $dname

		if { [info exists array(DATA_WAVELENGTH,${i}_${j}) ] } {
		    for { set k 1 } { $k <= $array(N_WATOMS,$i) } { incr k } {
			if { $array(DATA_FPRIME${k},${i}_${j}) == "" || $array(DATA_FPRIMEPRIME${k},${i}_${j}) == "" || $par eq "CRYSTAL_ATOM_NAME" } {
			if { $array(ATOM_WAVE_ID${k},${i}_${j}) != "" } {
			    set atom_id [string toupper $array(ATOM_WAVE_ID${k},${i}_${j})]
			} else {
			    set atom_id [string toupper $array(CRYSTAL_ATOM_NAME,${i})]
			}
 			set command "crossec << \"ATOM $atom_id \n NWAV 1 $array(DATA_WAVELENGTH,${i}_${j}) \""
			catch {eval exec $command} output
			set data $output
			set data [split $data "\n"]
			foreach line $data {
			    regsub -all {\s+} $line " " line
			    if { [regexp {^([A-Za-z+0-9-]*) *([0-9.]*) *([-0-9.]*) *([0-9.].*)} $line junk idd wave fp fpp ] } {
				if { [info exists fp ] } {
					set array(DATA_FPRIME${k},${i}_${j}) $fp
					set array(DATA_FPRIMEPRIME${k},${i}_${j}) $fpp
				}
			    }
			} 
		    }
		}
	    }
       }
      }
      }
    }

    # check the inputted number of monomers / solvent content
    if { [string equal $par NMONOMERS] && $array($par)<=0 } {
      if { ![string is integer -strict $array($par)] || $array($par)<=0 } {
        set array(USER_NMONOMERS) ""
        # it is allowed to remove the value entirely, as a way to return to the defaults
        if { $array($par) ne "" } { 
          WarningMessage "Number of monomers must be an integer greater than 0"
          return
        }
      }
    }
    if { [string equal $par NMONOMERS] } {
      set array(USER_SOLVENT_CONTENT) ""
    }
    if { $par eq "SEQIN" || $par eq "DATA_LAB" || $par eq "HKLIN" || $par eq "NRESIDUES" } {
      set array(USER_SOLVENT_CONTENT) ""
      set array(USER_NMONOMERS) ""
    }
    if { ([string equal $par SOLVENT_CONTENT]) } {
      if { ![string is double -strict $array($par)] || $array($par)<0.0 || $array($par)>1.0 } {
        set array(USER_SOLVENT_CONTENT) ""
        # it is allowed to remove the value entirely, as a way to return to the defaults
        if { $array($par) ne "" } { 
          WarningMessage "Solvent content must be a real number between 0 and 1" 
          return
        }
      }
    }

    # initialize to make separation of model and substructure if partial model is inputted
    if { $par eq "XYZIN" } {
      set array(NOT_SEPAR_PARTIAL) 0
    }

    # couple shelxc+d and afro+crunch2 as of now (other combinations will be tested!)
    set i [string range $par end end]

    if { !([file exists [FindExecutable shelxc]] && [file exists [FindExecutable shelxd]]) } {
	set array(FA_PROGRAM,$i) "afro"
	set array(DETECT_PROGRAM,$i) "crunch2"
    }

    if { $par_cut2 eq "FA_PROGRAM" } {
	if { $array($par) eq "afro" } {
	    set array(DETECT_PROGRAM,$i) "crunch2"
	    set array(USER_DETECT_PROGRAM,$i) "crunch2"
	}
      #elseif { $array($par) eq "shelxc" } {
        #set array(DETECT_PROGRAM,$i) "shelxd"
        #set array(USER_DETECT_PROGRAM,$i) "shelxd"
      #}
    } elseif { $par_cut2 eq "DETECT_PROGRAM" } {
	if { $array($par) eq "crunch2" } {
	    set array(FA_PROGRAM,$i) "afro"
	    set array(USER_FA_PROGRAM,$i) "afro"
	} elseif { $array($par) eq "shelxd" } {
	    set array(FA_PROGRAM,$i) "shelxc"
	    set array(USER_FA_PROGRAM,$i) "shelxc"
	} elseif { $array($par) eq "prasa" } {
	    set array(FA_PROGRAM,$i) "ecalc"
	    set array(USER_FA_PROGRAM,$i) "ecalc"
	}
    }

    # checks passed - accept the parameter as set by user
    # generally, the USER_* variables are used for the script, their counterparts without 
    # the USER_ prefix are used for the GUI (there might be exceptions)
    if { [info exists array(USER_${par})] } {
      set array(USER_${par}) $array($par)
# puts "uuser sets param: USER_${par} $array(USER_${par})"
    }
    # the defaults are set only if not set before or for a few chosen parameters
    # in order to make the gui more responsive:  this might be changed later.
    set defaul 0
    if { !$array(DEFAULTS_SET) } {
      set defaul 1
    }
    set defaul_list "NMONOMERS PEAK_PROGRAM FA_PROGRAM DETECT_PROGRAM PHASING_PROGRAM HAND_DM_PROGRAM PHASE_COMB_PROGRAM DM_PROGRAM REFINE_PROGRAM BUILD_PROGRAM BUILD_COMBINED SEQIN NRESIDUES DOCK_SEQUENCE DATA_LAB HKLIN XYZIN CRYSTAL_ATOM_NAME CRYSTAL_N_ATOMS NEW_FREE PARTIAL_MODEL WINDOW_CREATED PARTIAL_AS_SUBSTR ATOM_WAVE_ID1 ATOM_WAVE_ID2 ATOM_WAVE_ID3 SUBSTRUCTURE_INPUT_COORDSIN PREMADE_START PREMADE_END SKIP_HAND"
    foreach item $defaul_list {
      if { ($item eq $par) || ($item eq $par_cut2) } {
        set defaul 1
      }
    }
    # do not try to get defaults if all input is not collected yet
    if { ($array(SEQIN) eq "" && $array(NRESIDUES) eq "") || $array(HKLIN) eq "" } {
      set defaul 0
    }
    if { $array(PARTIAL_MODEL) eq $part_mod && $array(XYZIN) eq "" } {
      set defaul 0
    }
    for { set i 1 } { $i <= $array(N_CRYSTALS) } { incr i } {
      if { $array(CRYSTAL_ATOM_NAME,${i}) eq "" || ($array(CRYSTAL_INPUT_SUBSTRUCTURE,$i) && $array(SUBSTRUCTURE_INPUT_COORDSIN,$i) eq "" ) } {
        set defaul 0
      }
    }
    if { $defaul } {
# 	puts "Entered setting defaults"
	# Run crank2 with the -d option to get the crank2 defaults
	set workdir [GetDefaultDirPath]
	set prefix  [string trimright [file join $workdir [expr [DbGetNJOBS] + 1]_crank2 _] _]
	set xmlfile [file join $workdir [expr [DbGetNJOBS] + 1]_crank2.xml ] 
#      source [file join $env(CCP4I_TOP) src execute.tcl] 
	namespace import Exec::*
	set crank2_script [CreateComScriptCrank2 $arrayname]
	if { [file exists [FindExecutable ccp4-python] ] } {
	    set cmd "[BinPath ccp4-python] -u [file join $env(CRANK2) crank2.py] -d keyin $crank2_script dirout $prefix xmlout $xmlfile"
	} else {
	    set cmd "[BinPath python] -u [file join $env(CRANK2) crank2.py] -d keyin $crank2_script dirout $prefix xmlout $xmlfile"
	}
	if { [catch {eval exec $cmd} output] } {
#	    puts $output
	    if { [string equal $par NMONOMERS] } {
		WarningMessage "Solvent estimation problem. The number of monomers inputted ($array($par)) may be too unlikely. The complete error message follows: \n\n$output"
	    } else {
		WarningMessage "A problem occured: \n\n $output"
	    }
	    return
	}

      # read and set the defaults
      global XMLParse
      XMLParsefile $xmlfile
      # solvent content / monomers
      if { ([info exists XMLParse([join "process process inp sequence=protein solvent_content" __])]) && ($array(USER_SOLVENT_CONTENT) eq "") } {
        set array(SOLVENT_CONTENT) $XMLParse([join "process process inp sequence=protein solvent_content" __])
      }
      if { ([info exists XMLParse([join "process process inp sequence=protein monomers_asym" __])]) && ($array(USER_NMONOMERS) eq "") } {
        set array(NMONOMERS) $XMLParse([join "process process inp sequence=protein monomers_asym" __])
      }
      # crank2 processes' defaults
      # careful: due to the xml parser limitations, we rely on the order of subprocesses...
      set extra_xmlfile ""
      # first the detection of pdb file type
      # this code is rather ackward/complicated due to the tcl xml parser limitations...
      if { $par eq "XYZIN" || $par eq "CRYSTAL_ATOM_NAME,1_1" || (!$array(DEFAULTS_SET)&&$par ne "PARTIAL_AS_SUBSTR") } {
        set XYZIN "[GetFullFileName0 $arrayname XYZIN]"
        set pi ""
        set xyzin_typ ""
        for {set i 1} {$i < 10} {incr i} {
          if { $xyzin_typ ne "" } { break }
          foreach typ {"partial" "partial+substr" "substr"} {
            if { [info exists XMLParse([join "process process inp model=$typ$pi file=pdb" __])] } {
              if { $XMLParse([join "process process inp model=$typ$pi file=pdb" __]) eq "$XYZIN" } {
                set xyzin_typ $typ
                break
              }
          } }
          IncreaseXMLProcNum $pi
        }
        if { $xyzin_typ eq "partial" } {
          WarningMessage "No substructure atoms found in the XYZIN file!"
        } elseif { $xyzin_typ eq "substr" } {
          WarningMessage "Only substructure found in the XYZIN file. Switching to building from substructure."
          set array(PARTIAL_AS_SUBSTR) 1
          set array(NOT_SEPAR_PARTIAL) 1
          fix_scroll $arrayname ; add_premade_pipeline $arrayname ;  rungetstuff $arrayname PARTIAL_AS_SUBSTR
          return
        }
#        puts $xyzin_typ
      }
      SetDefVal $arrayname "REPLACE_MET_MSE" "process param replace_met_mse" 1
      set pi ""
      if { $array(NEW_FREE) } {
        SetDefVal $arrayname "FREE_FRACTION" "process process param fraction" 1
        if { $array(FREE_FRACTION) ne "" } {
          set array(FREE_FRACTION) [expr $array(FREE_FRACTION)*100]
        }
        IncreaseXMLProcNum $pi
      }
      for {set i 1} {$i <= $array(N_PROCESS)} {incr i} {
        if { [info exists XMLParse([join "process process$pi" __])] } {
          if { $array(PROCESS_NAME,$i) eq "peak" } {
            SetDefVal $arrayname "PEAK_PROGRAM,$i" "process process$pi process program" 1
            SetDefVal $arrayname "PEAK_CYCLES,$i" "process process$pi param num_iter" 1
            SetDefVal $arrayname "REFINE_CYCLES,$i" "process process$pi param refcyc" 1
            SetDefVal $arrayname "PEAK_THRESHOLD,$i" "process process$pi param rms_threshold" 1
            if { $array(PARTIAL_AS_SUBSTR) && !$array(NOT_SEPAR_PARTIAL) } {
              IncreaseXMLProcNum $pi
            }
          } elseif { $array(PROCESS_NAME,$i) eq "detect" } {
            SetDefVal $arrayname "FA_PROGRAM,$i" "process process$pi program" 1
            # only assuming 1 crystal here as of now (SAD/MAD)
            if { $array(USER_CRYSTAL_N_ATOMS,1) eq "" && $array(SEQIN) ne "" && $array(DOCK_SEQUENCE) } {
              SetDefVal $arrayname "CRYSTAL_N_ATOMS,1" "process process$pi inp model=substr exp_num_atoms" 1
              set array(CRYSTAL_N_ATOMS,1) [expr $array(CRYSTAL_N_ATOMS,1)/$array(NMONOMERS)]
            }
            IncreaseXMLProcNum $pi
            SetDefVal $arrayname "DETECT_PROGRAM,$i" "process process$pi program" 1
            SetDefVal $arrayname "DETECT_HIGHRES_CUTOFF,$i" "process process$pi param high_res_cutoff" 1
            if { $array(DETECT_HIGHRES_CUTOFF,$i)!="" && $array(USER_DETECT_HIGHRES_CUTOFF,$i)=="" } {
              set array(DETECT_MANUAL_RESO,$i) 1
            } elseif { $array(USER_DETECT_HIGHRES_CUTOFF,$i)=="" } {
              set array(DETECT_MANUAL_RESO,$i) 0
            }
            if { $array(DETECT_PROGRAM,$i) eq "shelxd" } {
              SetDefVal $arrayname "DETECT_THRESHOLD_SHELX,$i" "process process$pi param threshold_stop" 1
            } else {
              SetDefVal $arrayname "DETECT_THRESHOLD_CRUNCH,$i" "process process$pi param threshold_stop" 1
            }
            SetDefVal $arrayname "DETECT_NUM_CYCLES,$i" "process process$pi param num_trials" 1
          } elseif { $array(PROCESS_NAME,$i) eq "phasing" } {
            SetDefVal $arrayname "PHASING_PROGRAM,$i" "process process$pi program" 1
            SetDefVal $arrayname "PHASING_CYCLES,$i" "process process$pi param cycles" 1
          } elseif { $array(PROCESS_NAME,$i) eq "hand" } {
            SetDefVal $arrayname "HAND_DM_PROGRAM,$i" "process process$pi process process program" 1
            SetDefVal $arrayname "HAND_PHASE_COMB_PROGRAM,$i" "process process$pi process process2 program" 1
            SetDefVal $arrayname "HAND_DM_CYCLES,$i" "process process$pi process param dmcyc" 1
          } elseif { $array(PROCESS_NAME,$i) eq "dm" } {
            SetDefVal $arrayname "DM_PROGRAM,$i" "process process$pi process program" 1
            SetDefVal $arrayname "PHASE_COMB_PROGRAM,$i" "process process$pi process2 program" 1
            SetDefVal $arrayname "DM_CYCLES,$i" "process process$pi param dmcyc" 1
            SetDefVal $arrayname "DM_NCS_PARROT,$i" "process process$pi param ncs_det_ha" 1
          } elseif { $array(PROCESS_NAME,$i) eq "build" } {
            set combined [string equal $XMLParse([join "process process$pi" __]) "comb_phdmmb"]
            SetDefVal $arrayname "BUILD_COMBINED,$i" $combined 0
            if { $array(BUILD_PROGRAM,$i) ne "arpwarp" } {
              SetDefVal $arrayname "BUILD_PROGRAM,$i" "process process$pi process2 program" 1
            }
            if { $combined } {
              SetDefVal $arrayname "REFINE_PROGRAM,$i" "process process$pi process process2 program" 1
              SetDefVal $arrayname "DM_PROGRAM,$i" "process process$pi process process program" 1
              SetDefVal $arrayname "BUILD_CYCLES_MAX,$i" "process process$pi param maxbigcyc" 1
              SetDefVal $arrayname "BUILD_CYCLES_MIN,$i" "process process$pi param minbigcyc" 1
              SetDefVal $arrayname "DM_NCS_PARROT,$i" "process process$pi param ncs_det_ha" 1
              SetDefVal $arrayname "BUILD_SKIP_INIT,$i" "process process$pi param skip_initial_build" 1
              SetDefVal $arrayname "BUILD_EXCLUDE_LAST,$i" "process process$pi param always_exclude_free" 1
              SetDefVal $arrayname "BUILD_EXCLUDE_LAST,$i" [expr !$array(BUILD_EXCLUDE_LAST,$i)] 0
            } else {
              if { $array(BUILD_PROGRAM,$i) ne "arpwarp" } {
                SetDefVal $arrayname "REFINE_PROGRAM,$i" "process process$pi process program" 1
              }
              SetDefVal $arrayname "BUILD_CYCLES,$i" "process process$pi param bigcyc" 1
            }
          } elseif { $array(PROCESS_NAME,$i) eq "refine" } {
            SetDefVal $arrayname "REFINE_PROGRAM,$i" "process process$pi program" 1
            SetDefVal $arrayname "REFINE_CYCLES,$i" "process process$pi param cycles" 1
          } else {
            puts "Unknown process $array(PROCESS_NAME,$i)!"
          }
          IncreaseXMLProcNum $pi
          if { $i==1 } {
            set extra_xmlfile [file join $prefix $XMLParse([join "process process" __]).xml]
          }
        } else {
          puts "Process $array(PROCESS_NAME,$i) not found in the Crank2 XML!"
        }
      }
      # reading in the converted F/F+/F- to make the next crank2 -d job faster (->more responsive gui)
      # this is for the SAD case only as of now! x/dname checking will be needed for other experiments
      if { $extra_xmlfile ne "" } {
        XMLParsefile $extra_xmlfile
        for { set i 1 } { $i <= $array(N_CRYSTALS) } { incr i } {
          for { set j 1 } { $j <= $array(N_DATA,$i) } { incr j } {
            if { $array(INPUT_INTENSITY,${i}_$j) } {
              set pi [RetrieveXMLIndex "process inp fsigf=plus*INDEX* f"]
              if {$pi ne "NotFound"} {
                set array(EXTRA_MTZIN_ANOM_F,${i}_$j) $XMLParse([join "process inp fsigf=plus$pi file=mtz" __])
                set array(EXTRA_F_PLUS,${i}_$j) $XMLParse([join "process inp fsigf=plus$pi f" __])
                set array(EXTRA_SIGF_PLUS,${i}_$j) $XMLParse([join "process inp fsigf=plus$pi sigf" __])
                set array(EXTRA_F_MINUS,${i}_$j) $XMLParse([join "process inp fsigf=minus$pi f" __])
                set array(EXTRA_SIGF_MINUS,${i}_$j) $XMLParse([join "process inp fsigf=minus$pi sigf" __])
              }
            }
            set pi [RetrieveXMLIndex "process inp fsigf=average*INDEX* f"]
            if {$pi ne "NotFound"} {
              set array(EXTRA_MTZIN_AVER_F,${i}_$j) $XMLParse([join "process inp fsigf=average$pi file=mtz" __])
              set array(EXTRA_F_AVER,${i}_$j) $XMLParse([join "process inp fsigf=average$pi f" __])
              set array(EXTRA_SIGF_AVER,${i}_$j) $XMLParse([join "process inp fsigf=average$pi sigf" __])
            }
      } } }

      set array(DEFAULTS_SET) 1
    }

    return
}

proc RetrieveXMLIndex { val } {
  global XMLParse
  set pi ""
  while { ![info exists XMLParse([string map [list *INDEX* $pi] [join "$val" __]])] && ($pi==""||$pi<100) } {
    IncreaseXMLProcNum $pi
  }
  if {$pi==100} {
    set pi "NotFound"
    puts "Problem in retrieving index from xml!!!"
  }
  return $pi
}

proc IncreaseXMLProcNum { pi } {
    upvar 1 pi pilocal
    if { $pilocal eq "" } {
      set pilocal 2
    } else {
      incr pilocal
    }
}

proc SetDefVal { arrayname par val xmlparse } {
    upvar #0 $arrayname array
    global XMLParse
    if { $xmlparse } {
      set val $XMLParse([join "$val" __])
    }
    # the default value is only set if not specified by user in gui (ie only if USER_$par is "")
    # we check for existance of the variable here - otherwise crashes with newly added variables when rerunning old jobs
    if { [info exists array(USER_$par)] } {
     if { ($array(USER_$par) eq "") && ($val ne "None") } {
      if { $val eq "False" } {
        set array($par) 0
      } elseif { $val eq "True" } {
        set array($par) 1
      } else {
        set array($par) $val
      }
    }}
}

# CreateComScriptCrank2 has to be defined in a different namespace to prevent some clashes with
# execute.tcl which were causing errors when eg changing input mtz file to another mtz file
namespace eval Exec {
namespace export CreateComScriptCrank2
source [SearchPath TOP src execute.tcl]

proc CreateComScriptCrank2 { arrayname } {
    upvar #0 $arrayname array
    foreach {key value} [array get array] {
      set use 1
      # of the crank2 parameters, we only want those inputted by the user (with the exception of programs as of now)
      if { [info exists array(USER_$key)] && [string range $key end-8 end-2] ne "PROGRAM"  } {
        set use 0
      }
      # check whether the EXTRA_* files have not been removed in the meantime
      if { [string range $key 0 11] eq "EXTRA_MTZIN_" && ![file exists $value] } {
        set use 0
      }
      # expand the array variables and set all variables
      if { $use } {
        if { [regexp {(.+),([0-6])(_([0-6]))?$} $key junk1 key1 ind1 junk2 ind2] } {
          if { [array exists $key1] || ![info exists $key1] } {
            if { ![string compare $ind2 ""] } {
              set ${key1}($ind1) $value
            } else {
              set ${key1}($ind1,$ind2) $value
            }
          }
        } else {
          set $key $value
        }
      }
    }
    # expand the path for the input files
    if { [info exists SEQIN] } {
      set SEQIN "[GetFullFileName0 $arrayname SEQIN]"
    }
    if { [info exists XYZIN] } {
      set XYZIN "[GetFullFileName0 $arrayname XYZIN]"
    }
    if { [info exists HKLIN] } {
      set HKLIN "[GetFullFileName0 $arrayname HKLIN]"
    }
    for { set i 1 } { $i <= $array(N_CRYSTALS) } { incr i } {
      if { [info exists SUBSTRUCTURE_INPUT_COORDSIN($i)] } {
        set SUBSTRUCTURE_INPUT_COORDSIN($i) "[GetFullFileName0 $arrayname SUBSTRUCTURE_INPUT_COORDSIN,$i]"
      }
      for { set j 1 } { $j <= $array(N_DATA,$i) } { incr j } {
        if { [info exists MTZIN($i,$j)] } {
          set MTZIN($i,$j) "[GetFullFileName0 $arrayname MTZIN,${i}_$j]"
        }
      }
    }
    # partial_model follows some strange way - seems to need this extra setting
    global no_part_mod
    global part_mod
    if { ($array(PARTIAL_MODEL) eq $no_part_mod) } {
      set PARTIAL_MODEL NO
    } elseif { ($array(PARTIAL_MODEL) eq $part_mod) } {
      set PARTIAL_MODEL SITES
    }
    CreateComScript crank2 crank2_script
    return $crank2_script
}

}

proc XMLParsefile { xmlfile } {
    # Global used by the XML parser
    global xmldata
    # Data structure to hold actual data
    global XMLParse 
    # Working data structure to hold temporary work data
    global XMLWork

    XmlDataReset
    array unset XMLWork
    array unset XMLParse
    set XMLWork(section_depth) 0

    # Initialise and configure the XML parser
    set parser 0
    set parser [ xml::parser ]
    $parser configure -elementstartcommand XMLElementStartHandler
    $parser configure -elementendcommand XMLElementEndHandler
    $parser configure -characterdatacommand XMLCharacterHandler
    $parser configure -ignorewhitespace true

    # Read and parse the specified file
    if { [ReadFile $xmlfile xmltext] } {
      $parser parse $xmltext
      set xmldata(XML_FILE) $xmlfile
      set xmldata(XML_LOADED) 1
    } else {
      # Couldn't load the data
      set xmldata(XML_LOADED) 0
    }
}

proc XMLElementStartHandler { name attlist } {
    global xmldata
    global XMLParse
    global XMLWork

    set section_typ [GetXmlAttributeValue $attlist "typ"]
    if { $section_typ != "" } {
      lappend XMLWork(section_full_name) "${name}=${section_typ}"
    } else {
      lappend XMLWork(section_full_name) $name
    }
    set XMLWork(section_name) $name
    set fullvarname [join $XMLWork(section_full_name) "__"]
    set last_elem [lindex $XMLWork(section_full_name) end]
    # increase the index after tag if the path exists already
    set i 2
    while { [info exists XMLParse($fullvarname)] } {
      set XMLWork(section_full_name) [lreplace $XMLWork(section_full_name) end end $last_elem$i]
      set fullvarname [join $XMLWork(section_full_name) "__"]
      incr i
    }
    set XMLWork(section_cat_name) $fullvarname
    incr XMLWork(section_depth)
}

proc XMLElementEndHandler { name } {
    global xmldata
    global XMLParse
    global XMLWork

    set XMLWork(section_full_name) [lreplace $XMLWork(section_full_name) \
					[expr [llength $XMLWork(section_full_name)] - 1] \
					[expr [llength $XMLWork(section_full_name)] - 1]]
    incr XMLWork(section_depth) -1
}

proc XMLCharacterHandler { data args } {
    global xmldata
    global XMLParse
    global XMLWork

    set data [string trim $data]
    set fullvarname $XMLWork(section_cat_name)
    if { $data != "" || ![info exists XMLParse($fullvarname)] } {
      set XMLParse($fullvarname) $data
    }
}


proc getatomname { arrayname c1 } {
    upvar #0 $arrayname array
	
    if { $array(SUBSTRUCTURE_INPUT_COORDSIN,$c1) == "" } {
	return
    }

    set input_pdb [open [GetFullFileName0 $arrayname SUBSTRUCTURE_INPUT_COORDSIN,$c1] r]
    set indata [split [read $input_pdb] "\n"]

    foreach line  $indata {
	regsub -all {\s+} $line " " line
	if { [regexp {HETATM *([0-9]*) *([A-Z]*)} $line junk number atom] || [regexp {ATOM *([0-9]*) *([A-Z]*)} $line junk number atom] } {
	    set array(CRYSTAL_ATOM_NAME,$c1) [string toupper $atom]
	    break
	}
    }
    close $input_pdb
}

proc check_all { arrayname } {
    upvar #0 $arrayname array

    #                       Crank Parameters                      
	
    if { $array(HKLIN) == "" } {
	WarningMessage "Input MTZ file not entered"
	return 0
    }
	
    if { $array(XYZOUT) == "" } {
 	WarningMessage "Output MTZ file not entered"
	return 0
    }

#    rungetstuff $arrayname 0

    #                     Crystals/Datasets                       

    if { $array(N_CRYSTALS) == 1 } {
	if { $array(DATA_ANOMALOUS,1) != 1 } {
	    WarningMessage "If only one crystal is defined, it must contain anomalous data"
	    return 0
	}
    }

    # Make sure number of protein residues is set (can be 0)
    set nresidues $array(NRESIDUES)

    if { $nresidues == "" } {
	WarningMessage "Number of residues is not set.  Please enter a value (can be zero)"
	return 0
    }

    # Make sure number of nucleotides is set (can be 0)
    set nucleotides_present $array(NUCLEOTIDES_PRESENT)
    set nnucleotides $array(NNUCLEOTIDES)

    if { $nucleotides_present && $nnucleotides == "" } {
	WarningMessage "Number of nucleotides is not set.  Please enter a value (can be zero), or hide the field with the DNA/RNA Present button"
	return 0
    }

    # Make sure (protein residues + nucleotides) > 0
    if { $nucleotides_present } {
	set total [expr $nresidues + $nnucleotides]
    } else {
	set total $nresidues
    }
	
    if { $total <= 0 } {
	WarningMessage "Number of residues + number of nucleotides must be greater than zero"
	return 0
    }

    # Loop over all crystals/datasets
    if { $array(N_CRYSTALS) > 0 } {
	set column_list {}
	for { set i 1 } { $i <= $array(N_CRYSTALS) } { incr i } {
	    set typelist {}
	    set native $array(CRYSTAL_NATIVE,${i})
            set array(CRYSTAL_ATOM_NAME,${i}) [string toupper $array(CRYSTAL_ATOM_NAME,${i})]

	    for { set m 1 } { $m <= $array(N_ATOMS,${i}) } { incr m } {
                set array(ATOM_ID,${i}_${m}) [string toupper $array(ATOM_ID,${i}_${m})]
            }


	    for { set j 1 } { $j <= $array(N_DATA,$i) } { incr j } {
		set type $array(DATA_TYPE,${i}_${j})

		for { set k 1 } { $k <= $array(N_WATOMS,$i) } { incr k } {
		    if { [info exists array(ATOM_WAVE_ID${k},${i}_${j}) ] } { 
			set array(ATOM_WAVE_ID${k},${i}_${j}) [string toupper $array(ATOM_WAVE_ID${k},${i}_${j})]
		    }
		}
				
		# If Native
		if { $native } {
		    # Check for I and SIGI columns
		} else {
		    # If non-Native
		    # Check for presence substructure atom
		    if { ![info exists array(CRYSTAL_ATOM_NAME,${i} ] } {
			if { $array(PREMADE_START) != "Substructure detection" } {
			    set array(CRYSTAL_ATOM_NAME,${i}) [string toupper $array(ATOM_WAVE_ID1,${i}_1)]
			    set array(CRYSTAL_N_ATOMS,${i}) 5
			}
		    }


		    set atomname $array(CRYSTAL_ATOM_NAME,${i})
		    if { $atomname == "" } {
			WarningMessage "No Atom Name Entered\nPlease enter an Atom Name"
			return 0
		    }
                    set atomname [string toupper $atomname]
                    set array(CRYSTAL_ATOM_NAME,${i}) $atomname
		    # Check validity of substructure atom (It must be a valid element name)
		    if { [check_atomname $arrayname $atomname] == 0 } {
			WarningMessage "Incorrect atom name ($atomname):\n\nPlease choose a valid CCP4\natom name from \$CLIBD/sfatom.lib"
			return 0
		    }

		    # Check free lavel assignment
            if { $array(INPUT_FREE) && ($array(FREE_LABEL) eq "Unassigned" || $array(FREE_LABEL) eq "") } {
              WarningMessage "Please specify an existing free reflections label (or use the option to generate a new one)"
              return 0
            }

		    # Check number of substructure atoms
#		    set natoms $array(CRYSTAL_N_ATOMS,${i})
#		    if { $natoms == "" } {
#			WarningMessage "Number of Atoms not entered\n\Please enter number of Atoms"
#			return 0
#		    }
#					
#		    if { $natoms <= 0 } {
#			WarningMessage "Must have at least one atom"
#			return 0
#		    }
#
#		    if { $natoms >= 1000 } {
#			WarningMessage "Too many atoms entered ($natoms).  Perhaps you entered the number of total atoms?"
#			return 0
#		    }

		    # Check data type
		    set data_type $array(DATA_TYPE,${i}_${j})
		    lappend typelist $data_type
		    if { $data_type == "" } {
			WarningMessage "Type of data not entered"
			return 0
		    }
					
		    # If non-anomalous
		    set data_anomalous $array(DATA_ANOMALOUS,${i}_${j})
 		    if { $array(INPUT_INTENSITY,${i}_${j}) } {
			if { $data_anomalous == 0 } {
			    if { $array(CRYSTAL_NATIVE,$i) == 0 } {
				set ii $array(DATA_I,${i}_${j})
				set sigi $array(DATA_SIGI,${i}_${j})
			    } else {
				set ii $array(DATA_I,${i})
				set sigi $array(DATA_SIGI,${i})
			    }
			    
			    lappend column_list $ii
			    lappend column_list $sigi
			
			    if { $ii == "" || [StringSame $ii "Unassigned"] } {
				WarningMessage "I column not set for crystal=$i dataset=$j"
				return 0
			    }
			    
			    if { $sigi == "" || [StringSame $sigi "Unassigned"] } {
				WarningMessage "SIGI column not set for crystal=$i dataset=$j"
				return 0
			    }
			} else {
			    # Check for presence of both I+ and I-
			    # Make sure I+ and I- are different
			    set i_plus $array(DATA_I_PLUS,${i}_${j})
			    set sigi_plus $array(DATA_SIGI_PLUS,${i}_${j})
			    set i_minus $array(DATA_I_MINUS,${i}_${j})
			    set sigi_minus $array(DATA_SIGI_MINUS,${i}_${j})

			    lappend column_list $i_plus
			    lappend column_list $sigi_plus
			    lappend column_list $i_minus
			    lappend column_list $sigi_minus
			
			    if { $i_plus == "" || [StringSame $i_plus "Unassigned"] } {
				WarningMessage "I+ column not set for crystal=$i dataset=$j"
				return 0
			    }
			
			    if { $sigi_plus == "" || [StringSame $sigi_plus "Unassigned"] } {
				WarningMessage "SIGI+ column not set for crystal=$i dataset=$j"
				return 0
			    }

			    if { $i_minus == "" || [StringSame $i_minus "Unassigned"] } {
				WarningMessage "I- column not set for crystal=$i dataset=$j"
				return 0
			    }

			    if { $sigi_minus == "" || [StringSame $sigi_minus "Unassigned"] } {
				WarningMessage "SIGI- column not set for crystal=$i dataset=$j"
				return 0
			    }

			    if { [StringSame $i_plus $i_minus] } {
				WarningMessage "You have set both the I+ and I- columnns for crystal=$i dataset=$j to ($i_plus).\n"
				return 0
			    }

			    if { [StringSame $sigi_plus $sigi_minus] } {
				WarningMessage "You have set both the SIGI+ and SIGI- columnns for crystal=$i dataset=$j to ($sigi_plus).\n"
				return 0
			    }
			}
		    } else {
			if { $data_anomalous == 0 } {
			    # If non-anomalous
			    # Check for presence of F/SIGF
			    set f $array(DATA_F,${i}_${j})
			    set sigf $array(DATA_SIGF,${i}_${j})
			
			    lappend column_list $f
			    lappend column_list $sigf
			
			    if { $f == "" || [StringSame $f "Unassigned"] } {
				WarningMessage "F column not set for crystal=$i dataset=$j"
				return 0
			    }

			    if { $sigf == "" || [StringSame $sigf "Unassigned"] } {
				WarningMessage "SIGF column not set for crystal=$i dataset=$j"
				return 0
			    }
			} else {
			    # Check for presence of both I+ and I-
			    # Make sure F+ and F- are different
			    set f_plus $array(DATA_F_PLUS,${i}_${j})
			    set sigf_plus $array(DATA_SIGF_PLUS,${i}_${j})
			    set f_minus $array(DATA_F_MINUS,${i}_${j})
			    set sigf_minus $array(DATA_SIGF_MINUS,${i}_${j})

			    lappend column_list $f_plus
			    lappend column_list $sigf_plus
			    lappend column_list $f_minus
			    lappend column_list $sigf_minus
			
			    if { $f_plus == "" || [StringSame $f_plus "Unassigned"] } {
				WarningMessage "F+ column not set for crystal=$i dataset=$j"
				return 0
			    }
			
			    if { $sigf_plus == "" || [StringSame $sigf_plus "Unassigned"] } {
				WarningMessage "SIGF+ column not set for crystal=$i dataset=$j"
				return 0
			    }

			    if { $f_minus == "" || [StringSame $f_minus "Unassigned"] } {
				WarningMessage "F- column not set for crystal=$i dataset=$j"
				return 0
			    }

			    if { $sigf_minus == "" || [StringSame $sigf_minus "Unassigned"] } {
				WarningMessage "SIGF- column not set for crystal=$i dataset=$j"
				return 0
			    }

			    if { [StringSame $f_plus $f_minus] } {
				WarningMessage "You have set both the F+ and F- columnns for crystal=$i dataset=$j to ($f_plus)."
				return 0
			    }

			    if { [StringSame $sigf_plus $sigf_minus] } {
				WarningMessage "You have set both the SIGF+ and SIGF- columnns for crystal=$i dataset=$j to ($sigf_plus).\n"
				return 0
			    }
			}
		    }
		    
		    # If "Data collected at CuKalpha"
		    if { $array(DATA_WAVELENGTH,${i}_${j}) == 1.5418 } {
			# Set wavelength to CuKalpha = 1.5418A
			set $array(DATA_WAVELENGTH,${i}_${j}) 1.5418
			# Use GetFormFactors to determine f' and f''
			set atom_name [string toupper $array(CRYSTAL_ATOM_NAME,${i})]
			set form [GetFormFactors $atom_name]
			set fprime [lindex [split $form " "] 0]
			set fprimeprime [lindex [split $form " "] 1]
			# Set array elements
			set array(ATOM_WAVE_ID1,${i}_${j}) $atom_name
			set array(DATA_FPRIME1,${i}_${j}) $fprime
			set array(DATA_FPRIMEPRIME1,${i}_${j}) $fprimeprime
			
		    } else {
			# If !"Data collected at CuKalpha"
			# Check for f', f''.  Wavelength is optional
			#
			if { $array(PREMADE_START) == "Substructure detection" } {
			    set array(N_WATOMS,$i) 1
 			    set array(ATOM_WAVE_ID1,${i}_${j}) $array(CRYSTAL_ATOM_NAME,$i)
			} 

                       for { set k 1 } { $k <= $array(N_WATOMS,$i) } { incr k } {
                            set fprime $array(DATA_FPRIME$k,${i}_${j})
                            set fprimeprime $array(DATA_FPRIMEPRIME$k,${i}_${j})
                            set name $array(ATOM_WAVE_ID$k,${i}_${j})

                            if { $name == "" } {
                                WarningMessage "ATOM ID $k not set for crystal=$i dataset=$j"
                                return 0
                            }

                            if { $fprime == "" } {
                                WarningMessage "F' (fprime) not set for crystal=$i dataset=$j atom=$k"
                                return 0
                            }
                            if { $fprimeprime == "" } {
                                WarningMessage "F'' (fprimeprime) not set for crystal=$i dataset=$j atom=$k"
                                return 0
                            }
		       }
		    }
		}
	    }
            if {$array(CELL_A,$i) == "" } {
                set array(CELL_A,$i)     $array(CELL_1)
                set array(CELL_B,$i)     $array(CELL_2) 
                set array(CELL_C,$i)     $array(CELL_3)
                set array(CELL_ALPHA,$i) $array(CELL_4)
                set array(CELL_BETA,$i)  $array(CELL_5)
                set array(CELL_GAMMA,$i) $array(CELL_6)
            }
	}

	# Check the $typelist datastructure just built to make sure there
	# is only one label of each type present.

	for { set m 0 } { $m < [expr [llength $typelist] - 1] } { incr m } {
	    for { set n [expr $m + 1] } { $n < [llength $typelist] } { incr n } {
		if { [StringSame [lindex $typelist $m] [lindex $typelist $n]] } {
		    WarningMessage "Dataset $m ([lindex $typelist $m]) and Dataset $n ([lindex $typelist $n]) have the same type.\nPlease choose a different data type for each dataset"
		    return 0
		}
	    }
	}

	#
	# Check if any dataset is specified more than once in the experimental data section.
	#
	for { set m 0 } { $m < [expr [llength $column_list] - 1] } { incr m } {
	    for { set n [expr $m + 1] } { $n < [llength $column_list] } { incr n } {
		#puts "m=($m)([lindex $column_list $m]) n=($n)([lindex $column_list $n])"
		if { [StringSame [lindex $column_list $m] [lindex $column_list $n]] } {
		    WarningMessage "Column [lindex $column_list $m]) has been specified in two different datasets.\nEach experimental column referred to must be unique"
		    return 0
		}
	    }
	}
    }

    #                Required Parameters Section                   

    if { ![info exists array(NMONOMERS)] } {
	rungetstuff $arrayname 1
	if { ![info exists array(NMONOMERS)] } {
	    WarningMessage "Number of monomers could not be automatically set - Please set manually"
	    return 0
	}
    }

    global part_mod
    if { $array(PARTIAL_MODEL) eq $part_mod && ![file exists [GetFullFileName0 $arrayname XYZIN]] } {
      WarningMessage "The XYZIN file $array(XYZIN) does not exist (check the path and permissions)."
    }

    # Make sure Solvent content is set and is between 0 and 1
    set solvent_content $array(SOLVENT_CONTENT)
    if { $solvent_content == "" } {
	WarningMessage "Please enter in the sequence or number of residues/nucleotides and the mtz file."
	return 0
    }

    if { $solvent_content < 0 } {
	WarningMessage "Solvent content is less than zero.  It must be between zero and one"
	return 0
    }

    if { $solvent_content > 1 } {
	WarningMessage "Solvent content is greater than one.  It must be be between zero and one"
	return 0
    }


    ################################################################
    #                 Other miscellaneous checks                   #
    ################################################################

    if { $array(N_PROCESS) == 0 } {
	WarningMessage "You have not added any programs to the pipeline.\nPlease add at least one program to the pipeline to run Crank"
	return 0
    }

    if { $array(DETECT_MANUAL_RESO,1)!="" && $array(DETECT_MANUAL_RESO,1) && ( ![string is double -strict $array(DETECT_HIGHRES_CUTOFF,1)] || $array(DETECT_HIGHRES_CUTOFF,1)<=0) } {
      WarningMessage "High resolution cutoff for substructure detection must be a positive real number"
      return 0
    }

    ################################################################
    #        Check for temporary program specific limitations      #
    ################################################################

    return 1
}

# 
# CCP4i - Start a Crank run
#

#------------------------------------------------------------------------------
proc crank2_pipeline_prereq { } {
#------------------------------------------------------------------------------
  if { ![file exists [FindExecutable crank2]] } {
    return 0
  }

  return 1
}

proc crank2_run { arrayname } {
    upvar #0 $arrayname array
    
    set array(INPUT_FILES) "HKLIN"
    # define loggraph files
    set job_id [expr [DbGetNJOBS] + 1]
    set array(LOGGRAPH_FILE) "${job_id}_crank2.loggraph"
    set array(DIR_LOGGRAPH_FILE) [GetDefaultDirPath]
    set array(DIR_LOGGRAPHACT_FILE) $array(DIR_LOGGRAPH_FILE)
    set array(LOGGRAPHACT_FILE) "${job_id}_crank2_act.loggraph"
    #
    # Check to make sure all fields in the interface are filled in properly
    #
    set good [check_all $arrayname]
    if { !$good } {
	return 0
    }


    # Calculate the total number of datasets for the .com files
    set total 0
    for { set i 0 } { $i < $array(N_CRYSTALS) } { incr i } {
	for { set j 0 } { $j < $array(N_DATA,$i) } { incr j } {
	    set total [expr $total + 1]
	}
    }
    set array(TOTAL_DATASETS) $total

    if { $array(LOW_RES_LIMIT) == "" } {
        set array(LOW_RES_LIMIT) 99.9
    }

    #
    #
    # Setup datastructures to output this Crank job as a database.def file
    #
    # The simple bits
    set array(CCP4DB_DATESTR) [clock format [clock seconds]]		
    set array(CCP4DB_DATE) [GetDate -format seconds]
    set array(CCP4DB_USER) [GetUserId]


    return 1
}


#
# CCP4i - Setup variables and menus at the start of a run
#
proc crank2_setup { typedefVar arrayname } {
    upvar #0 $typedefVar typedef
    upvar #0 $arrayname array

    global env
    global status

    if { ![info exists ::env(CRANK2) ] || $env(CRANK2) == "" } {
      set ccp4top_crank2 [file join $env(CCP4I_TOP) crank2]
      if { ! ([file exists [file join $ccp4top_crank2 crank2.py] ]) } {
        WarningMessage "Please set CRANK2 environment variable -  this is required."
        return 0
      } else {
        set env(CRANK2) $ccp4top_crank2
      }
    }

    if { ! ([file exists [FindExecutable gcx] ]) } {
        WarningMessage "Can not find executable gcx - please ensure it is in your path"
        return 0
    }

    global XMLParse

    global process_toggleframe_list

    global all_subframes

    set all_subframes ""

    #
    # The list of data items that will get passed to the
    # CreateToggleFrame that makes the experiment palette.
    #
    # This is necessary because some programs have pulldown
    # menus (DefineMenus) that need to have their data items already
    # set up before they are created. This is a global variable that
    # needs to get referenced and updated in the plugin _setup
    # functions.
    #

    set process_toggleframe_list \
	[list PROCESS_NAME \
	     INPUT_EXPERIMENTAL_COLUMNS \
	     INPUT_EXPERIMENTAL_COLUMNS_LIST \
	     INPUT_EXPERIMENTAL_COLUMNS_ALIAS \
	     INPUT_F_COLUMNS \
	     INPUT_F_COLUMNS_LIST \
	     INPUT_F_COLUMNS_ALIAS \
	     INPUT_I_COLUMNS \
	     INPUT_I_COLUMNS_LIST \
	     INPUT_I_COLUMNS_ALIAS \
	     INPUT_PHASE_COLUMNS \
	     INPUT_PHASE_COLUMNS_LIST \
	     INPUT_PHASE_COLUMNS_ALIAS \
	     INPUT_HL_COLUMNS \
	     INPUT_HL_COLUMNS_LIST \
	     INPUT_HL_COLUMNS_ALIAS \
	     INPUT_EA_COLUMNS \
	     INPUT_EA_COLUMNS_LIST \
	     INPUT_EA_COLUMNS_ALIAS \
	     INPUT_FA_COLUMNS \
	     INPUT_FA_COLUMNS_LIST \
	     INPUT_FA_COLUMNS_ALIAS \
	     INPUT_ALPHA_COLUMNS \
	     INPUT_ALPHA_COLUMNS_LIST \
	     INPUT_ALPHA_COLUMNS_ALIAS \
	     INPUT_FREER_COLUMNS \
	     INPUT_FREER_COLUMNS_LIST \
	     INPUT_FREER_COLUMNS_ALIAS \
	     INPUT_SUBSTRUCTURE \
	     INPUT_SUBSTRUCTURE_LIST \
	     INPUT_SUBSTRUCTURE_ALIAS \
	     INPUT_PDB \
	     INPUT_PDB_LIST \
	     INPUT_PDB_ALIAS \
	     DEFAULT_MENU \
	     DEFAULT_MENU_LIST \
	     DEFAULT_MENU_ALIAS \
	     GENERIC_KEYWORDS \
	     GENERIC_N_KEYWORDS \
	     DETECT_PROGRAMS \
	     PEAK_PROGRAMS \
	     PHASING_PROGRAMS \
	     HAND_PROGRAMS \
	     DM_PROGRAMS \
	     BUILD_PROGRAMS \
	     REFINE_PROGRAMS \
	     FA_PROGRAM  USER_FA_PROGRAM \
	     DETECT_PROGRAM  USER_DETECT_PROGRAM \
	     DETECT_MANUAL_RESO  \
	     DETECT_HIGHRES_CUTOFF  USER_DETECT_HIGHRES_CUTOFF \
	     DETECT_NUM_CYCLES  USER_DETECT_NUM_CYCLES \
	     DETECT_SPECIAL_POSITIONS  USER_DETECT_SPECIAL_POSITIONS \
	     DETECT_PATTERSON  USER_DETECT_PATTERSON \
	     DETECT_THRESHOLD_CRUNCH  USER_DETECT_THRESHOLD_CRUNCH \
	     DETECT_THRESHOLD_SHELX   USER_DETECT_THRESHOLD_SHELX \
	     PEAK_PROGRAM  USER_PEAK_PROGRAM \
	     PEAK_THRESHOLD  USER_PEAK_THRESHOLD \
	     PEAK_CYCLES  USER_PEAK_CYCLES \
	     PHASING_PROGRAM  USER_PHASING_PROGRAM \
	     PHASING_CYCLES  USER_PHASING_CYCLES \
	     HAND_DM_PROGRAM  USER_HAND_DM_PROGRAM \
	     HAND_DM_CYCLES  USER_HAND_DM_CYCLES \
	     HAND_PHASE_COMB_PROGRAM  USER_HAND_PHASE_COMB_PROGRAM \
	     PHASE_COMB_PROGRAM  USER_PHASE_COMB_PROGRAM \
	     DM_PROGRAM  USER_DM_PROGRAM \
	     DM_CYCLES  USER_DM_CYCLES \
	     DM_NCS_PARROT  USER_DM_NCS_PARROT \
	     BUILD_PROGRAM  USER_BUILD_PROGRAM \
	     BUILD_CYCLES  USER_BUILD_CYCLES \
	     BUILD_CYCLES_MAX  USER_BUILD_CYCLES_MAX \
	     BUILD_CYCLES_MIN  USER_BUILD_CYCLES_MIN \
	     BUILD_SKIP_INIT  USER_BUILD_SKIP_INIT \
	     BUILD_COMBINED  USER_BUILD_COMBINED \
	     BUILD_EXCLUDE  USER_BUILD_EXCLUDE \
	     BUILD_EXCLUDE_LAST  USER_BUILD_EXCLUDE_LAST \
	     REFINE_PROGRAM  USER_REFINE_PROGRAM \
	     REFINE_CYCLES  USER_REFINE_CYCLES \
	     REFINE_EXCLUDE  USER_REFINE_EXCLUDE
	    ]


    # The type of each dataset
#    DefineMenu _data_type [list "SAD" \
#			       "Native" \
#			       "Derivative" \
#			       "Peak" \
#			       "Inflection" \
#			       "High Remote" \
#			       "Low Remote" \
#			       "Other" ] \
#	[list SAD NATIVE SIRAS PEAK INFL HREM LREM OTHER]

#
# ***NSP
    if { ([file exists [FindExecutable shelxc]] && [file exists [FindExecutable shelxd]]) } {
	  DefineMenu _fa_progs     [list shelxc afro ecalc ] 
      if { ([file exists [FindExecutable prasa]]) } {
        DefineMenu _detect_progs [list shelxd crunch2 prasa ]
      } else {
        DefineMenu _detect_progs [list shelxd crunch2 ]
      }
 	DefineMenu _phase_progs  [list bp3 refmac shelxe ] 
    } else {
	DefineMenu _fa_progs     [list afro ecalc ] 
	DefineMenu _detect_progs [list crunch2 ] 
    }

#    DefineMenu _fa_progs               [list shelxc afro ] 
#    DefineMenu _detect_progs           [list shelxd crunch2 prasa]
    DefineMenu _peak_progs             [list refmac ] 
    DefineMenu _phase_progs            [list refmac bp3 ] 
    DefineMenu _hand_progs             [list solomon ]
    DefineMenu _hand_phase_comb_progs  [list multicomb ]
    DefineMenu _phase_comb_progs       [list refmac ]
    DefineMenu _dm_progs               [list parrot solomon ]
    DefineMenu _build_progs            [list buccaneer ]    
    DefineMenu _refine_progs           [list refmac ]
    DefineMenu _key_build_progs        [list parrot solomon refmac buccaneer ]
    DefineMenu _key_dm_progs           [list parrot solomon refmac ]
    DefineMenu _key_hand_progs         [list solomon refmac ]

    set resolve 0

#    if { ([file exists [FindExecutable resolve_giant]]) } {
#	set resolve 1
#	DefineMenu _dm_progs [list solomon parrot resolve ]
#    } else {
#	set resolve 0
# 	DefineMenu _dm_progs [list solomon parrot ] 
#    }

    if { [file exists [FindExecutable arp_warp]] } {
	set arpwarp 1
	if { ([file exists [FindExecutable cbuccaneer]]) } {
	    set buc 1
	    if { $resolve } {
		DefineMenu _build_progs [list buccaneer arpwarp resolve ] 
  	    } else {
		DefineMenu _build_progs [list buccaneer arpwarp ] 
		DefineMenu _key_build_progs   [list parrot solomon refmac buccaneer arpwarp ]
	    }
	} else {
	    set buc 0
	    if { $resolve } {
		DefineMenu _build_progs [list arpwarp resolve ] 
 	    } else {
		DefineMenu _build_progs [list arpwarp ] 
	    }
	}
    } else {
	set arpwarp 0
	if { ([file exists [FindExecutable cbuccaneer]]) } {
	    set buc 1
	    if { $resolve } {
		DefineMenu _build_progs [list resolve buccaneer ] 
 	    } else {
		DefineMenu _build_progs [list buccaneer ] 
	    }
 	} else {
	    set buc 0
	    if { $resolve } {
		DefineMenu _build_progs [list resolve ] 
	    }  	
	}
    }

    if { $arpwarp || $resolve || $buc } {
 	DefineMenu _pipeline_step [list "Substructure detection" "Substructure phasing" "Hand determination" "Density modification" "Model building" "Model refinement" ] \
 	    [list DETECT PHASE HAND DM BUILD REFINE]

    } else {
 	DefineMenu _pipeline_step [list "Substructure detection" "Substructure phasing" "Hand determination" "Density modification" "Model refinement" ] \
  	    [list DETECT PHASE HAND DM REFINE]

 	DefineMenu _model_progs [list "" ] 
 	if { [info exists array(PREMADE_END)] } {
  	    if { ($array(PREMADE_END) == "Model building" ) || ($array(PREMADE_END) == "") } {
 		set array(PREMADE_END) "Density modification"
 	    }
 	}
    }

#    DefineMenu _partial_model [list "No partial model to input" "Input partial model to find sites and build model" "Input partial model to extend"] [list NO SITES EXTEND ]

    global no_part_mod
    global part_mod
    set no_part_mod "No partial model to input"
    set part_mod "Input partial model to find sites and (re)build model"
    DefineMenu _partial_model [list $no_part_mod $part_mod] [list NO SITES ]

    DefineMenu _pipeline_start [list "Substructure detection" "Substructure phasing"] [list DETECT PHASE]

#    DefineMenu _experiment_setup [list "Single wavelength anomalous diffraction (SAD)" \
#				      "Single isomorphous replacement with anomalous scattering (SIRAS)" "Two wavelength anomalous diffraction (2W-MAD)" \
#				      "Three wavelength anomalous diffraction (3W-MAD)" "Four wavelength anomalous diffraction (4W-MAD)" "Two wavelength anomalous diffraction with native (2W-MAD-N)" \
#				      "Three wavelength anomalous diffraction with native (3W-MAD-N)" "Four wavelength anomalous diffraction with native (4W-MAD-N)"] [list SAD SIRAS 2WMAD 3WMAD \
#																		     4WMAD 2WMADN 3WMADN 4WMADN ]

    DefineMenu _experiment_setup [list "Single wavelength anomalous diffraction (SAD)" ] [list SAD ]


    DefineMenu _get_fpfpp [list "Input f' and f\" values" "Automatically determine f' and f\" values from a table"] [list USER CROSSEC]

    DefineMenu _data_input_type [list Intensities Amplitudes ] 

#    DefineMenu _data_input_type [list Amplitudes ] 

#    DefineMenu _substructure_input_type [list Pdb Manual ]

    DefineMenu _substructure_input_type [list Pdb ]

    DefineMenu _coordinate_format_type [list Fractional Orthogonal ]

    return 1
}

proc Create_nolabel_ToggleFrame { indexVar def_proc0 message title \
         add_text indexed_parameters args } {
  set arrayname [ GetSystemVar frame_array ]
  upvar #0 $arrayname array

  set counter 0
  set ndep 0
  set noaddline 0
  set depframes ""
  set children ""
  set edit_proc ""
  set anchor n

  set nargs [llength $args] ; set n 0
  while { $n < $nargs } {
    switch -regexp -- [lindex $args $n ] \
    depend {
       incr ndep
       incr n
       lappend depframes "[lindex $args $n ]"
    } child {
       incr n
       lappend children [lindex $args $n ]
    } noadd {
       set noaddline 1
    } edit_proc {
       incr n; set edit_proc [lindex $args $n ]
    } justify {
       incr n
       set justify [lindex $args $n ]
       switch -exact -- $justify {
         left {
           set anchor nw
         }
         right {
           set anchor ne
         }
         center {
           set anchor n
         }
       }
    }
    incr n
  }

  OpenSubFrame top_frame
  OpenSubFrame frame

  frame $frame.dummy -height 1
  pack $frame.dummy -side top

  append def_proc $def_proc0 _ $counter

# The following parameters are referenced by def_proc and are unique
# for each instance of the toggle frame
  set array(FRAME_$def_proc) $frame
  set array(XF_EDIT_$def_proc) ""
  set array(XF_SELECT_$def_proc) ""

# The following params are refenced bu def_proc0 and are common between all
# instances of the toggle frame
  set array(CHILD_$def_proc0) $children
  foreach child $children {
    set array(PARENT_$child) $def_proc0
  }

  set array(N_DEPFRAMES_$def_proc0) $ndep
  set array(DEPFRAMES_$def_proc0) $depframes

  set array(XF_INDEX_$def_proc0) $indexVar
  set array(FRAME_TYPE_$def_proc0) toggle
  set array(FRAME_TITLE_$def_proc0) $title
  set array(FRAME_ANCHOR_$def_proc0) $anchor
  set array(EDIT_PROC_$def_proc0) $edit_proc
  set array(HELP_$def_proc0) [GetSystemVar frame_program_help]
  set array(VARS_$def_proc0) $indexed_parameters

  if {$array(N_DEPFRAMES_$def_proc0) >= 0 && $array($indexVar) > 0 } {
    append array(UPDATE_SCRIPTS) \
   "update_toggleframe $def_proc0 0 $arrayname $indexVar 0 $array($indexVar) 0\n"
  }
  CloseSubFrame

  if { $noaddline == 0 } {
    create_nolabel_addline_command line $message $indexVar update_toggleframe0  \
         $def_proc0 0  $add_text 1
#    set array(XF_COMLINE_$def_proc) $line
  }
  CloseSubFrame
}


proc Create_nolabel_ExtendingFrame { indexVar0 def_proc0 message \
            add_text indexed_parameters args } {

  set arrayname [ GetSystemVar frame_array ]
  upvar #0 $arrayname array

  set indexVar $indexVar0
  set del_text ""
  set noaddline 0
  set ndep 0
  set depframes ""
  set edit_proc ""
  set children ""
  set counter 0

  set nargs [llength $args]
  set n 0
  while { $n < $nargs } {
    switch -regexp -- [lindex $args $n ] \
    dependent {
       incr ndep
       incr n; lappend depframes "[lindex $args $n]"
    } child {
       incr n; lappend children [lindex $args $n]
    } edit {
       incr n; lappend edit_proc [lindex $args $n]
    } noadd {
       set noaddline 1
    } delete {
       incr n; set del_text [lindex $args $n ]
    } counter {
       incr n; set counter  [lindex $args $n ]
    }
    incr n
  }

  OpenSubFrame top_frame
 
  append def_proc $def_proc0 _ $counter

  set array(XF_EDIT_$def_proc) ""
  set array(XF_SELECT_$def_proc) ""
  set array(XF_COMLINE_$def_proc) ""

  if { $counter <= 1 } {
    set array(CHILD_$def_proc0) $children
    foreach child $children {
      set array(PARENT_$child) $def_proc0
    }

    set array(N_DEPFRAMES_$def_proc0) $ndep
    set array(DEPFRAMES_$def_proc0) $depframes

    set array(XF_INDEX_$def_proc0) $indexVar
    set array(EDIT_PROC_$def_proc0) $edit_proc
    set array(FRAME_TYPE_$def_proc0) extending
    set array(FRAME_TITLE_$def_proc0) ""
    set array(HELP_$def_proc0) [GetSystemVar frame_program_help]
    set array(VARS_$def_proc0) $indexed_parameters
  }

  if { $counter > 0 } {append indexVar , $counter }

  OpenSubFrame frame

# Add a dummy line so when all other lines are deleted this one
# will determine the size of the remaining space (ie small)

  frame $frame.dummy -height 1
  pack $frame.dummy -side top

  set array(FRAME_$def_proc) $frame

  if { $array(N_DEPFRAMES_$def_proc0) >= 0 \
       && $counter == 0 && $array($indexVar) > 0 } {
#    puts "append UPDATE_SCRIPTS $def_proc0"
    append array(UPDATE_SCRIPTS) \
    "update_extendingframe $def_proc0 $counter $arrayname $indexVar \
		0 $array($indexVar) 0\n"
  }

  CloseSubFrame

  if { $noaddline == 0 } {
    set remo_text "Remove last line"
    create_nolabel_addline_command line $message $indexVar \
	update_extendingframe0 $def_proc0 $counter $add_text 1 
#    set array(XF_COMLINE_$def_proc) $line
  }

  CloseSubFrame

}

proc create_nolabel_addline_command { lineVar message c1 command def_proc0 counter \
   add_text  ifedit } {

  upvar $lineVar line
  
  set arrayname [ GetSystemVar frame_array ]
  upvar #0 $arrayname array
  append def_proc $def_proc0 _ $counter

  return
}

#
# CCP4i - Draw main Crank task window
#
proc crank2_task_window { arrayname } {
    upvar #0 $arrayname array
    global env
    global process_toggleframe_list
    global all_subframes

    if { ![CreateTaskWindow $arrayname  \
 	       "CRANK2" CRANK \
	       [list "Advanced options" ] ] }  { return 0 }

    #
    # Things saved to array(PARAM_LIST) get
    # saved to the .def file that is used to run crank in CCP4_DATABASE/1_crank.def.
    # So, we need to build up this list from the input plugin .def files, which
    # was constructed in crank_setup.
    #

    set options_folder 1
    set experiment_folder 2

    # Retrive defaults from XML file if available & requested
    source [SearchPath TOP utils xml_utils.tcl]

    # Populate the task window
    OpenFolder protocol

    # Title frame
    OpenSubFrame frame1

    # The picture, on the left
    #set cranklogo [image create photo -file [ FileJoin $env(CRANK) bin crank-logo.gif ] ]
    #set logo [label $frame1.f1 -image $cranklogo]
#    pack $logo -side left

    CreateLine line \
	message "Enter a title for this job (TITLE)" \
	label "Title" \
	widget TITLE -width 80

    CreateLine line \
	label "Type of experiment" \
	widget EXPERIMENT_SETUP -width 60 \
	-command "clear_program_defaults $arrayname; setup_experiment $arrayname; set_program_defaults $arrayname"


    CreateLine line \
 	label " " \
	message "Extending or rebuilding a partial model (eg from MR)?" \
	widget PARTIAL_MODEL \
 	-command "fix_scroll $arrayname ; add_premade_pipeline $arrayname ; rungetstuff $arrayname PARTIAL_MODEL" \
 	label "     Input protein sequence" \
	message "Give a protein sequence to be used in model building" \
	widget DOCK_SEQUENCE \
	-command "rungetstuff $arrayname DOCK_SEQUENCE" \
	label "    DNA/RNA present" \
	message "Is DNA/RNA present in this structure?" \
	widget NUCLEOTIDES_PRESENT


    OpenSubFrame frame -toggle_display PARTIAL_MODEL hide NO
    CreateInputFileLine line \
	"Enter name of file containing the partial protein model (XYZIN)" \
	"XYZ in " \
	XYZIN DIR_XYZIN \
	-command "rungetstuff $arrayname XYZIN"
    CreateLine line \
	label "Build from substructure only (will remove input protein atoms, if any)" \
	message "Build from substructure only; any protein atoms in the partial model will be removed after additional substructure atoms picking" \
	widget PARTIAL_AS_SUBSTR \
	-command "fix_scroll $arrayname ; add_premade_pipeline $arrayname ;  rungetstuff $arrayname PARTIAL_AS_SUBSTR"
    # this assumes SAD/MAD at the moment!
    OpenSubFrame frame -toggle_display CRYSTAL_ATOM_NAME,1 open SE
    CreateLine line \
	label "Replace methionines by selenomethionines (if present)" \
	message "Replace methionines by selenomethionines (if present in the input XYZ)" \
	widget REPLACE_MET_MSE \
	-command "rungetstuff $arrayname REPLACE_MET_MSE"
    CloseSubFrame
    CloseSubFrame

    OpenSubFrame frame -toggle_display DOCK_SEQUENCE open 1
    CreateInputFileLine line \
	"Enter name of file containing the protein sequence (SEQIN)" \
	"SEQ in " \
	SEQIN DIR_SEQIN \
	-command "rungetstuff $arrayname SEQIN"	
    CloseSubFrame

    OpenSubFrame frame -toggle_display DOCK_SEQUENCE open 0
    CreateLine line \
	label " " \
	message "Number of residues per monomer" \
	label "Number of residues per monomer " \
	widget NRESIDUES -oblig -width 5 \
	-command "rungetstuff $arrayname NRESIDUES" 
    CloseSubFrame

    OpenSubFrame frame -toggle_display NUCLEOTIDES_PRESENT open 1    
    CreateLine line \
	label " " \
	message "Number of nucleotides per monomer" \
	label "Number of nucleotides per monomer " \
	widget NNUCLEOTIDES -oblig -width 5 \
	-command "rungetstuff $arrayname NNUCLEOTIDES" 
    CloseSubFrame

    CreateInputFileLine line \
	"Enter input MTZ file name (HKLIN)" \
	"MTZ in" \
 	HKLIN DIR_HKLIN \
	-setlabin FREE_LABEL [list FREE FreeR FreeR_flag] \
	-setfileparam resolution_min LOW_RES_LIMIT \
	-setfileparam resolution_max HIGH_RES_LIMIT \
	-setfileparam space_group_name SPACE_GROUP_NAME \
        -setfileparam cell_1 CELL_1 \
        -setfileparam cell_2 CELL_2 \
        -setfileparam cell_3 CELL_3 \
        -setfileparam cell_4 CELL_4 \
        -setfileparam cell_5 CELL_5 \
        -setfileparam cell_6 CELL_6 \
	-setfileparam space_group_number SPACE_GROUP_NUMBER \
	-command "rungetstuff $arrayname HKLIN" \
        -fileout XYZOUT DIR_XYZOUT _crank2_

    OpenSubFrame frame -toggle_display PREMADE_START open { "HAND" "DM" "BUILD" }

    lappend all_subframes $frame

    CreateLabinLine4 line \
 	"Hendrickson-Lattman coefficients" \
 	HKLIN      "HLA" HLA {} \
 	-dependent "HLB" HLB {} \
 	-dependent "HLC" HLC {} \
 	-dependent "HLD" HLD {} 
 
    CloseSubFrame

    OpenSubFrame frame -toggle_display PARTIAL_MODEL open NO
    CreateLine line \
	label "Start the pipeline with " \
	message "Give the first step the pipeline will perform" \
	widget PREMADE_START -width 20 \
	-command "fix_scroll $arrayname ; add_premade_pipeline $arrayname ; rungetstuff $arrayname PREMADE_START" \
	label " and end with " \
	message "Give the last step the pipeline will perform" \
	widget PREMADE_END -width 20 \
	-command "fix_scroll $arrayname ; add_premade_pipeline $arrayname ; rungetstuff $arrayname PREMADE_END" 
    CloseSubFrame

    CreateOutputFileLine line \
	"Enter output PDB file name (XYZOUT)" \
	"PDB out" \
	XYZOUT DIR_XYZOUT 

    pack $line -side top

    CloseSubFrame
 
    OpenFolder file

    #
    # Experimental columns
    #

    OpenSubFrame frame_new -toggle_display TOGGLE_INPUT_EXP_COLUMNS open 1

    Create_nolabel_ToggleFrame N_CRYSTALS crystal_proc \
	"Add new Crystals/Datasets  - The experimental data you collected" \
	"Crystal #" \
	"Add new Cryst als/Datasets" \
	[list  CRYSTAL_ID \
	     N_DATA \
	     CRYSTAL_ATOM_NAME \
	     CRYSTAL_N_ATOMS \
	     USER_CRYSTAL_N_ATOMS \
	     CRYSTAL_INPUT_SUBSTRUCTURE \
	     CRYSTAL_INPUT_SUBSTRUCTURE_TYPE \
	     COORDINATE_FORMAT \
	     SUBSTRUCTURE_INPUT_COORDSIN \
	     DIR_SUBSTRUCTURE_INPUT_COORDSIN \
	     CELL_A \
	     CELL_B \
	     CELL_C \
	     CELL_ALPHA \
	     CELL_BETA \
	     CELL_GAMMA \
	     NUM_ATOMS \
	     N_ATOMS \
	     ATOM_ID \
	     ATOM_X \
	     ATOM_Y \
	     ATOM_Z \
	     ATOM_X_NOREF \
	     ATOM_Y_NOREF \
	     ATOM_Z_NOREF \
	     ATOM_OCCU \
	     ATOM_BISO \
	     ATOM_OCCU_NOREF \
	     ATOM_BISO_NOREF \
	     DATA_TYPE \
             N_WATOMS \
             ATOM_WAVE_ID1 \
             DATA_FPRIME1 \
             DATA_FPRIMEPRIME1 \
             ATOM_WAVE_ID2 \
             DATA_FPRIME2 \
             DATA_FPRIMEPRIME2 \
             ATOM_WAVE_ID3 \
             DATA_FPRIME3 \
             DATA_FPRIMEPRIME3 \
             ATOM_WAVE_ID4 \
             DATA_FPRIME4 \
             DATA_FPRIMEPRIME4 \
             ATOM_WAVE_ID5 \
             DATA_FPRIME5 \
             DATA_FPRIMEPRIME5 \
             ATOM_WAVE_ID6 \
             DATA_FPRIME6 \
             DATA_FPRIMEPRIME6 \
	     DATA_WAVELENGTH \
	     DATA_ANOMALOUS \
	     MTZIN \
	     DIR_MTZIN \
	     DATA_I \
	     DATA_SIGI \
	     DATA_I_PLUS \
	     DATA_SIGI_PLUS \
	     DATA_I_MINUS \
	     DATA_SIGI_MINUS \
	     DATA_F \
	     DATA_SIGF \
	     DATA_F_PLUS \
	     DATA_SIGF_PLUS \
	     DATA_F_MINUS \
	     DATA_SIGF_MINUS \
	    ] \
	-child data_proc \
	-child atom_proc \
	-noaddline 

    CloseSubFrame 
    

#    if { $array(FREE_LABEL) != "" && $array(FREE_LABEL) != "Unassigned" } {
#         SetLabin $arrayname HKLIN FREE_LABEL $array(FREE_LABEL)
#    } else {
#         SetLabin $arrayname HKLIN FREE_LABEL [list FREE FreeR FreeR_flag]
#    }

    OpenFolder 1 closed    

    CreateLine line \
	label "Number of amino acid residues: " \
	varlabel NRESIDUES \
 	message "Number of monomers in the asu " \
 	label "Number of monomers in the ASU" \
	widget NMONOMERS -width 3 \
	-command "rungetstuff $arrayname NMONOMERS" \
	message "Solvent Content" \
	label "Solvent Content" \
	widget SOLVENT_CONTENT \
	-command "rungetstuff $arrayname SOLVENT_CONTENT"

    CreateLine line \
	message "Click to input an R-free set contained in the input mtz" \
	widget INPUT_FREE \
	-command "rungetstuff $arrayname INPUT_FREE" \
	label "Exclude free reflections as defined in"  \
	message "Specify an existing free set of reflections that will be excluded" \
	widget FREE_LABEL -width 15  \
	-command "rungetstuff $arrayname FREE_LABEL" \
	label "    " \
	message "Click if you want to define a new free set of reflections that will be excluded" \
	widget NEW_FREE   \
	-command "rungetstuff $arrayname NEW_FREE" \
	label "Create a new free set to exclude"  \
	message "Specify the percentage of reflections to be excluded" \
	widget FREE_FRACTION -width 3  \
	-command "rungetstuff $arrayname FREE_FRACTION" \
	label "% of reflections"

    OpenSubFrame frame -toggle_display PARTIAL_SUBSTR open 0

    CreateLine line \
	message "Do not perform hand determination, assuming the hand of the actual model is correct" \
	widget SKIP_HAND \
	-command "fix_scroll $arrayname ;  add_premade_pipeline $arrayname ; rungetstuff $arrayname SKIP_HAND " \
	label "Skip hand determination (use the input hand)" \

    CloseSubFrame

#	message "B-factor - Either input a number here or obtain a value with the Guess button below" \
#	label "B-factor" \
#	widget BFACTOR

#    CreateLine line \
#	label "Matthew's coefficient: " \
#	varlabel MATTHEWS  \
#	label "Kantardjieff-Rupp probability: " \
#	varlabel KRPROB 


    CreateToggleFrame N_PROCESS experiment_proc \
	"Define Experiment" \
	"Step \#" \
	"Add Process" \
	$process_toggleframe_list \
	 -justify left \
 	message "Add the current process to the pipeline" \
 	button "Add Process" \
	-child generic_keywords \
 	-command "add_process $arrayname"

    CloseSubFrame

    if { ($array(N_CRYSTALS) == 0) } {
	setup_experiment $arrayname
    }

    if { ($array(N_PROCESS) == 0) } {
	add_premade_pipeline $arrayname
    }

    rungetstuff $arrayname WINDOW_CREATED

}

proc build_keyword_programs { arrayname counter } {
    upvar #0 $arrayname array

    if { $array(BUILD_COMBINED,$counter) } {
	DefineMenu _key_build_progs [list buccaneer refmac parrot]
    } else {
	DefineMenu _key_build_progs [list buccaneer refmac]
    }
}

proc generic_keywords { arrayname c1 c2 } {
    upvar #0 $arrayname array

    set var [string tolower $array(PROCESS_NAME,$c2)]
    set VAR [string toupper $array(PROCESS_NAME,$c2)]

    CreateLine line \
	label "Keyword for " \
	widget ${VAR}_PROGRAMS \
	widget GENERIC_KEYWORDS -width 45

}


proc detect_proc { arrayname counter } {
    upvar #0 $arrayname array

    global all_subframes 

    CreateLine line \
	label "Substructure detection process"

    CreateLine line \
	label "FA estimation " \
	widget FA_PROGRAM -width 15 \
	-command "rungetstuff $arrayname FA_PROGRAM,$counter" \
	message "Choose the program for FA estimation"

   CreateLine line \
        label "Detection " \
        widget DETECT_PROGRAM -width 15 \
	-command "rungetstuff $arrayname DETECT_PROGRAM,$counter" \
        message "Choose the program for substructure detection"

   CreateLine line \
        message "Input high resolution cut-off" \
        widget DETECT_MANUAL_RESO \
	-command "rungetstuff $arrayname DETECT_MANUAL_RESO,$counter" \
        label "Input high resolution cut-off" 

    OpenSubFrame frame -toggle_display DETECT_MANUAL_RESO,$counter open 1
       
    lappend all_subframes $frame

    CreateLine line \
	label "High resolution cutoff" \
	widget DETECT_HIGHRES_CUTOFF -width 5 \
	-command "rungetstuff $arrayname DETECT_HIGHRES_CUTOFF,$counter"

    CloseSubFrame

    OpenSubFrame frame -toggle_display DETECT_PROGRAM,$counter open "shelxd"

    CreateLine line \
        message "when the CC/weak threshold is reached, a correct solution is assumed and SHELXD is stopped" \
        label "CC/weak threshold" \
        widget DETECT_THRESHOLD_SHELX -width 5 \
	-command "rungetstuff $arrayname DETECT_THRESHOLD_SHELX,$counter" \
        message "Number of trials to perform" \
        label "   Number of trials" \
        widget DETECT_NUM_CYCLES -width 5 \
	-command "rungetstuff $arrayname DETECT_NUM_CYCLES,$counter"

    CloseSubFrame

    OpenSubFrame frame -toggle_display DETECT_PROGRAM,$counter open "crunch2"

    CreateLine line \
        message "when the FOM threshold is reached, a correct solution is assumed and CRUNCH2 is stopped" \
        label "FOM threshold" \
        widget DETECT_THRESHOLD_CRUNCH -width 5 \
	-command "rungetstuff $arrayname DETECT_THRESHOLD_CRUNCH,$counter" \
        message "Number of trials to perform" \
        label "   Number of trials" \
        widget DETECT_NUM_CYCLES -width 5 \
	-command "rungetstuff $arrayname DETECT_NUM_CYCLES,$counter"

    CloseSubFrame

    OpenSubFrame frame -toggle_display DETECT_PROGRAM,$counter open "prasa"

    CreateLine line \
        message "Number of trials to perform" \
        label "   Number of trials" \
        widget DETECT_NUM_CYCLES -width 5 \
	-command "rungetstuff $arrayname DETECT_NUM_CYCLES,$counter"

    CloseSubFrame

#    CreateLine line \
#        message "In this structure, is it possible to have heavy atoms on special positions?" \
#        label "Allow Special Positions" \
#        widget DETECT_SPECIAL_POSITIONS \
#	message "Perform Patterson seeding" \
#	label " Patterson seeding" \
#	widget DETECT_PATTERSON 

    CreateLine line \
	label "Input additional keyword(s) for detection programs" -italic

    CreateExtendingFrame GENERIC_N_KEYWORDS generic_keywords \
	"Add/remove line to define extra keyword" \
	"Add keyword" \
	[ list GENERIC_KEYWORDS DETECT_PROGRAMS PEAK_PROGRAMS \
               PHASING_PROGRAMS HAND_PROGRAMS DM_PROGRAMS \
               BUILD_PROGRAMS REFINE_PROGRAMS ] \
	-counter $counter
}

proc peak_proc { arrayname counter } {
    upvar #0 $arrayname array

    global all_subframes 
       
    CreateLine line \
	label "Finding (additional) substructure atoms from anomalous maps obtained by refinement of the inputted partial model"

    CreateLine line \
	label "Refinement program" \
	widget PEAK_PROGRAM -width 15 \
	-command "rungetstuff $arrayname PEAK_PROGRAM,$counter" \
	message "Choose the program for model refinement"

    CreateLine line \
        label "Run" \
        widget PEAK_CYCLES -width 2 \
	-command "rungetstuff $arrayname PEAK_CYCLES,$counter" \
        message "Set the number of times to iterate refinement and peak search" \
        label "iterations, each with" \
        widget REFINE_CYCLES -width 3 \
	-command "rungetstuff $arrayname REFINE_CYCLES,$counter" \
        message "Set the number of refinement cycles" \
        label "refinement cycles and picking atoms from anomalous map above RMS of" \
        widget PEAK_THRESHOLD -width 4 \
	-command "rungetstuff $arrayname PEAK_THRESHOLD,$counter" \
        message "Set the minimum RMS in gradient maps to accept a peak as a site" \


    CreateLine line \
	label "Input additional keyword(s) for detection programs" -italic

    CreateExtendingFrame GENERIC_N_KEYWORDS generic_keywords \
	"Add/remove line to define extra keyword" \
	"Add keyword" \
	[ list GENERIC_KEYWORDS DETECT_PROGRAMS PEAK_PROGRAMS \
               PHASING_PROGRAMS HAND_PROGRAMS DM_PROGRAMS \
               BUILD_PROGRAMS REFINE_PROGRAMS ] \
	-counter $counter
}

proc phasing_proc { arrayname counter } {
    upvar #0 $arrayname array

    global all_subframes

    CreateLine line \
	label "Substructure phasing and refinement process"
    
    CreateLine line \
	label "Phasing " \
	widget PHASING_PROGRAM -width 15 \
	-command "rungetstuff $arrayname PHASING_PROGRAM,$counter" \
	message "Choose the program for substructure phasing and refinement"

    CreateLine line \
        label "Number of phasing cycles: " \
        widget PHASING_CYCLES -width 5 \
	-command "rungetstuff $arrayname PHASING_CYCLES,$counter" \
        message "Set the number of cycles"

    CreateLine line \
	label "Input additional keyword(s) for phasing programs" -italic

    CreateExtendingFrame GENERIC_N_KEYWORDS generic_keywords \
	"Add/remove line to define extra keyword" \
	"Add keyword" \
	[ list GENERIC_KEYWORDS DETECT_PROGRAMS PEAK_PROGRAMS \
               PHASING_PROGRAMS HAND_PROGRAMS DM_PROGRAMS \
               BUILD_PROGRAMS REFINE_PROGRAMS ] \
	-counter $counter
}

proc hand_proc { arrayname counter } {
    upvar #0 $arrayname array

    global all_subframes

    CreateLine line \
	label "Hand determination process"

   CreateLine line \
	label "Density modification for Hand determination " \
	widget HAND_DM_PROGRAM -width 15 \
	-command "rungetstuff $arrayname HAND_DM_PROGRAM,$counter" \
	message "Choose the program for DM for hand determination purposes" 

   CreateLine line \
	label "Phase combination for Hand determination" \
	widget HAND_PHASE_COMB_PROGRAM -width 15 \
	-command "rungetstuff $arrayname HAND_PHASE_COMB_PROGRAM,$counter" \
	message "Choose the program for phase combination" 

    CreateLine line \
        label "Number of DM iterations: " \
        widget HAND_DM_CYCLES -width 5 \
	-command "rungetstuff $arrayname HAND_DM_CYCLES,$counter" \
        message "Set the number of DM cycles"

    CreateLine line \
	label "Input additional keyword(s) for hand determination programs" -italic

    CreateExtendingFrame GENERIC_N_KEYWORDS generic_keywords \
	"Add/remove line to define extra keyword" \
	"Add keyword" \
	[ list GENERIC_KEYWORDS DETECT_PROGRAMS PEAK_PROGRAMS \
               PHASING_PROGRAMS HAND_PROGRAMS DM_PROGRAMS \
               BUILD_PROGRAMS REFINE_PROGRAMS ] \
	-counter $counter
}

proc dm_proc { arrayname counter } {
    upvar #0 $arrayname array

    global all_subframes

    CreateLine line \
	label "Density modification process"

   CreateLine line \
	label "Density modification " \
        widget DM_PROGRAM -width 15 \
	-command "rungetstuff $arrayname DM_PROGRAM,$counter" \
        message "Choose the program for density modification" 

   CreateLine line \
	label "Phase combination " \
	widget PHASE_COMB_PROGRAM -width 15 \
	-command "rungetstuff $arrayname PHASE_COMB_PROGRAM,$counter" \
	message "Choose the program for phase combination" 

    CreateLine line \
        label "Number of iterations: " \
        widget DM_CYCLES -width 5 \
	-command "rungetstuff $arrayname DM_CYCLES,$counter" \
        message "Set the number of cycles"

    OpenSubFrame frame -toggle_display DM_PROGRAM,$counter open "parrot"
    OpenSubFrame frame -toggle_display NMONOMERS hide 1
    lappend all_subframes $frame
    CreateLine line \
        label "Try to determine NCS from substructure and map" \
        widget DM_NCS_PARROT  \
	-command "rungetstuff $arrayname DM_NCS_PARROT,$counter" \
        message "Try to determine NCS from the actual map and substructure (Parrot only)"
    CloseSubFrame
    CloseSubFrame

    CreateLine line \
	label "Input additional keyword(s) for density modification programs" -italic

    CreateExtendingFrame GENERIC_N_KEYWORDS generic_keywords \
	"Add/remove line to define extra keyword" \
	"Add keyword" \
	[ list GENERIC_KEYWORDS DETECT_PROGRAMS PEAK_PROGRAMS \
               PHASING_PROGRAMS HAND_PROGRAMS DM_PROGRAMS \
               BUILD_PROGRAMS REFINE_PROGRAMS ] \
	-counter $counter
}

proc build_proc { arrayname counter } {
    upvar #0 $arrayname array

    global all_subframes

    CreateLine line \
	label "Automated model building process"

    OpenSubFrame frame -toggle_display BUILD_PROGRAM,$counter open "buccaneer"
    lappend all_subframes $frame

   CreateLine line \
        widget BUILD_COMBINED \
        label "Use combined function utilizing phase, DM and MB information" \
	-command "build_keyword_programs $arrayname $counter ; rungetstuff $arrayname BUILD_COMBINED,$counter" \
        message "Use the combined function" 

    CloseSubFrame

    CreateLine line \
        label "Model building " \
        widget BUILD_PROGRAM -width 15 \
	-command "rungetstuff $arrayname BUILD_PROGRAM,$counter" \
        message "Choose the program for automated model building" 

    CreateLine line \
        label "Refinement " \
        widget REFINE_PROGRAM -width 15 \
	-command "rungetstuff $arrayname REFINE_PROGRAM,$counter" \
        message "Choose the program for model refinement"

    # combined specific gui options
    OpenSubFrame frame -toggle_display BUILD_COMBINED,$counter open 1
    OpenSubFrame frame -toggle_display BUILD_PROGRAM,$counter open "buccaneer"
       
    lappend all_subframes $frame

    CreateLine line \
        label "Density modification " \
        widget DM_PROGRAM -width 15 \
	-command "rungetstuff $arrayname DM_PROGRAM,$counter" \
        message "Choose the program for crystal density modification"

    CreateLine line \
        label "Number of model building cycles - minimum:" \
        widget BUILD_CYCLES_MIN -width 5 \
	-command "rungetstuff $arrayname BUILD_CYCLES_MIN,$counter" \
        message "Set the maximal number of model building cycles" \
        label "maximum:" \
        widget BUILD_CYCLES_MAX -width 5 \
	-command "rungetstuff $arrayname BUILD_CYCLES_MAX,$counter" \
        message "Set the minimal number of model building cycles"

    OpenSubFrame frame -toggle_display DM_PROGRAM,$counter open "parrot"
    OpenSubFrame frame -toggle_display NMONOMERS hide 1
    lappend all_subframes $frame
    CreateLine line \
        widget DM_NCS_PARROT  \
        label "Try to determine NCS from substructure and map" \
	-command "rungetstuff $arrayname DM_NCS_PARROT,$counter" \
        message "Try to determine NCS from the actual map and substructure (Parrot only)"
    CloseSubFrame
    CloseSubFrame

    CreateLine line \
        widget BUILD_SKIP_INIT  \
        label "Skip the initial model building" \
	-command "rungetstuff $arrayname BUILD_SKIP_INIT,$counter" \
        message "Skip the initial model building, performing the initial combined DM with inputted model"

    CloseSubFrame
    CloseSubFrame

    OpenSubFrame frame -toggle_display BUILD_COMBINED,$counter open 0
    lappend all_subframes $frame
    CreateLine line \
        label "Number of model building cycles" \
        widget BUILD_CYCLES -width 5 \
	-command "rungetstuff $arrayname BUILD_CYCLES,$counter" \
        message "Set the number of model building cycles"
    CloseSubFrame

    # build_combined is irelevant for arpwarp as of now thus this duplication is needed 
    # (unless there is a way to opensubframe with OR)
    OpenSubFrame frame -toggle_display BUILD_PROGRAM,$counter open "arpwarp"
    OpenSubFrame frame -toggle_display BUILD_COMBINED,$counter open 1
    lappend all_subframes $frame
    CreateLine line \
        label "Number of model building cycles" \
        widget BUILD_CYCLES -width 5 \
	-command "rungetstuff $arrayname BUILD_CYCLES,$counter" \
        message "Set the number of model building cycles"
    CloseSubFrame
    CloseSubFrame

    OpenSubFrame frame -toggle_display IS_FREE open 1
    lappend all_subframes $frame
    CreateLine line \
        widget BUILD_EXCLUDE \
        label "Exclude free reflections in model building" \
	-command "rungetstuff $arrayname BUILD_EXCLUDE,$counter" \
        message "Exclude free reflections (as specified above) in model building" 
    OpenSubFrame frame -toggle_display BUILD_COMBINED,$counter open 1
    OpenSubFrame frame -toggle_display BUILD_PROGRAM,$counter open "buccaneer"
    OpenSubFrame frame -toggle_display BUILD_EXCLUDE,$counter open 1
    lappend all_subframes $frame
    CreateLine line \
        widget BUILD_EXCLUDE_LAST \
        label "Exclude free reflections in the final model building cycles only" \
	-command "rungetstuff $arrayname BUILD_EXCLUDE_LAST,$counter" \
        message "Exclude free (as specified above) in the final model building cycles"
    CloseSubFrame
    CloseSubFrame
    CloseSubFrame
    CloseSubFrame

    CreateLine line \
	label "Input additional keyword(s) for model building programs" -italic

    CreateExtendingFrame GENERIC_N_KEYWORDS generic_keywords \
	"Add/remove line to define extra keyword" \
	"Add keyword" \
	[ list GENERIC_KEYWORDS DETECT_PROGRAMS PEAK_PROGRAMS \
               PHASING_PROGRAMS HAND_PROGRAMS DM_PROGRAMS \
               BUILD_PROGRAMS REFINE_PROGRAMS ] \
	-counter $counter
}

proc refine_proc { arrayname counter } {
    upvar #0 $arrayname array

    global all_subframes

    CreateLine line \
	label "Model refinement process"
    
    CreateLine line \
	label "Refinement " \
	widget REFINE_PROGRAM -width 15 \
	-command "rungetstuff $arrayname REFINE_PROGRAM,$counter" \
	message "Choose the program for model refinement"

    CreateLine line \
        label "Number of refinement cycles: " \
        widget REFINE_CYCLES -width 5 \
	-command "rungetstuff $arrayname REFINE_CYCLES,$counter" \
        message "Set the number of cycles"

    OpenSubFrame frame -toggle_display IS_FREE open 1
    lappend all_subframes $frame
    CreateLine line \
        widget REFINE_EXCLUDE \
        label "Exclude free reflections in refinement" \
	-command "rungetstuff $arrayname REFINE_EXCLUDE,$counter" \
        message "Exclude free reflections (specified above) in refinement"
    CloseSubFrame

    CreateLine line \
	label "Input additional keyword(s) for refinement programs" -italic

    CreateExtendingFrame GENERIC_N_KEYWORDS generic_keywords \
	"Add/remove line to define extra keyword" \
	"Add keyword" \
	[ list GENERIC_KEYWORDS DETECT_PROGRAMS PEAK_PROGRAMS \
               PHASING_PROGRAMS HAND_PROGRAMS DM_PROGRAMS \
               BUILD_PROGRAMS REFINE_PROGRAMS ] \
	-counter $counter
}
