#!/bin/bash # # This is part of the TIMEleSS tools # http://timeless.texture.rocks/ # # Copyright (C) S. Merkel, Universite de Lille, France # # 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. # # Please cite one of the relevant TIMEleSS publications if you find that was of any use # # Number of phases nphases=2 # Name of phases (used for comments) phases=("Phase A" "Phase B") # Short name of phases (for generating file names, avoid spaces and funny characters please) # If your phase is BB, peaks will be in files peaks-BB.gve, grains in grains-BB.gve, and GrainSpotter input files in index-BB.in with additional numbers phasesShort=("phA" "phB") # Crystal symmetry codes, one per phase (used in merge grains) # Codes can be found here http://multigrain.texture.rocks/doku.php?id=processing:compare-grain-orientations crystalSymmetryCodes=(7 7) # Space groups, one per phase (used in grainspotter) spaceGroups=(245 212) # Starting GVE files, one per phase startGVEs=("phaseA.gve" "phaseB.gve") # Wavelength (in Angstrom) wavelength=0.34512 # Grain spotter parameters # For each line: # - How many times shall you run grainSpotter, parameters for phase 1, parameters for phase 2, parameters for phase 3 # - Parameter list for each phase: min_measuments min_completeness sigma_tth sigma_eta sigma_omega n_random # You can add as many lines as you want. The indexing will be longer but the script will handle it. gsPars=() gsPars+=("5, 10 0.4 0.02 1 2 10000, 10 0.4 0.02 1 2 100") # iterations 0 to 4 gsPars+=("10, 10 0.4 0.02 2 4 10000, 10 0.4 0.02 2 4 100") # iterations 5 to 14 # gsPars+=("5, 10 0.4 0.02 1 2 10000, 10 0.4 0.02 1 2 100") # iterations 15 to 19 # Example # gsPars+=("5, 10 0.4 0.02 1 2 10000, 10 0.4 0.02 1 2 100") # adds 5 iterations with # - for phase 1, 10 min_measuments, 0.4 min_completeness, 0.02 degrees sigma_tth, 1 degree sigma_eta and 2 degrees sigma_omega, 10000 random trials in GrainSpotter # - for phase 2, 10 min_measuments, 0.4 min_completeness, 0.02 degrees sigma_tth, 1 degree sigma_eta and 2 degrees sigma_omega, 100 random trials in GrainSpotter # # gsPars+=("10, 10 0.4 0.02 2 4 10000, 10 0.4 0.02 2 4 100") # adds 10 iterations with # - for phase 1, 10 min_measuments, 0.4 min_completeness, 0.02 degrees sigma_tth, 2 degrees sigma_eta and 4 degrees sigma_omega, 10000 random trials in GrainSpotter # - for phase 2, 10 min_measuments, 0.4 min_completeness, 0.02 degrees sigma_tth, 2 degrees sigma_eta and 4 degrees sigma_omega, 100 random trials in GrainSpotter # Number of indexings (number of time to repeat the full thing to test for results consistency) nIndexings=1 # Update parameters above as well as in # - create_GS_init # Location of executables GrainSpotter=/usr/local/bin/GrainSpotter.0.90 clearGVE=/usr/bin/timelessClearGVEGrains mergeGrains=/usr/bin/timelessGrainSpotterMerge extractEuler=/usr/bin/timelessExtractEulerAngles statistics=/usr/bin/timelessGSIndexingStatistics #----------------------------------------------------------------------------------------------- # # Call to create GrainSpotter input # 10 parameters # - 1: name of GrainSpotter output file # - 2: space group number # - 3: gve file # - 4: name of grain output file # - 5: min_measurments # - 6: min_completeness # - 7: sigma_tth # - 8: sigma_eta # - 9: sigma_omega # - 10: n_random # # Two theta ranges and other parameters for GrainSpotter are set by hand below. # They are identical for all phases and mostly depend on the experimental settings. # Please update according to your settings # # Other parameters are adjusted according to what was defined above in gsPars # #----------------------------------------------------------------------------------------------- create_GS_init () { cat > $1 <<- EOM spacegroup $2 ! spacegroup [space group nr] ! dsrange 0 0.34 ! dsrange [min max], d-spacing range, multiple ranges can be specified tthrange 3.5 6.95 ! tthrange [min max], multiple ranges can be specified tthrange 7.15 9.95 ! tthrange [min max], multiple ranges can be specified tthrange 10.1 12.2 ! tthrange [min max], multiple ranges can be specified tthrange 12.35 14.0 ! tthrange [min max], multiple ranges can be specified etarange 0 360 ! etarange [min max], multiple ranges can be specified domega 0.5 ! domega [stepsize] in omega, degrees omegarange -28 28 ! omegarange [min max] degrees, multiple ranges can be specified filespecs $3 $4 ! filespecs [gvecsfile grainsfile] cuts $5 $6 0.5 ! cuts [min_measuments min_completeness min_uniqueness] eulerstep 5 ! eulerstep [stepsize] : angle step size in Euler space uncertainties $7 $8 $9 ! uncertainties [sigma_tth sigma_eta sigma_omega] in degrees nsigmas 2 ! nsigmas [Nsig] : maximal deviation in sigmas ! minfracg 1 ! stop search when minfracg (0..1) of the gvectors have been assigned to grains ! Nhkls_in_indexing 15 ! Nhkls_in_indexing [Nfamilies] : use first Nfamilies in indexing random ${10} ! use randomly chosen orientation seeds #trials ! positionfit ! fit the position of the grain ! genhkl ! generate list of hkl's based on space group and cell parameters in gve file EOM } #----------------------------------------------------------------------------------------------- # # NOTHING SHOULD BE CHANGED BELOW # #----------------------------------------------------------------------------------------------- #----------------------------------------------------------------------------------------------- # # Actual indexing loop # Runs tens of GrainSpotter iterations with decreasing tolerances # Runs in the current folder # #----------------------------------------------------------------------------------------------- indexing_loop () { # Copy GVE file for each phase echo "#" echo "# Copy of starting GVE files into current working folder" echo "#" for (( i=0; i<$nphases; i++ )) do if [ ! -f "$home/${startGVEs[$i]}" ]; then echo "Error: starting GVE file ${startGVEs[$i]} does not exist in folder $home" echo "Can not go any further" exit fi cp -f $home/${startGVEs[$i]} peaks-${phasesShort[$i]}.gve cp -f $home/${startGVEs[$i]} peaks-ori-${phasesShort[$i]}.gve echo "Saved ${startGVEs[$i]} as peaks-${phasesShort[$i]}.gve and peaks-ori-${phasesShort[$i]}.gve" done echo "Done" # Loop on GrainSpotter indexings i=-1 for gsPar in "${gsPars[@]}" do # Set comma as delimiter IFS=',' # Split parameter information read -a pars <<< "$gsPar" # Number of GrainSpotter loops for this set of parameters nloops=${pars[0]} # Extracting GrainSpotter parameters for each phase parphases=() for (( j=0; j<$nphases; j++ )) do ((k = j + 1)) parphases[$j]=${pars[$k]} done # Run loop of GrainSpotter indexings for these parameters for (( loop=0; loop<$nloops; loop++ )) do ((i = i + 1)) echo "#" echo "# Running GS iteration $i. GS parameters in index-XXX-$i.ini, grains saved in grains-XXX-$i.log for each phase" echo "#" echo "#" for (( j=0; j<$nphases; j++ )) do echo "#" echo "# GS iteration $i. Parameters for ${phases[$j]}: ${parphases[$j]}" echo "#" # Splitting indexing parameters as array, otherwise it does not work IFS=' ' read -a pars <<< "${parphases[$j]}" # Creating GrainSpotter input file and running the indexing create_GS_init index-${phasesShort[$j]}-$i.ini ${spaceGroups[$j]} peaks-${phasesShort[$j]}.gve grains-${phasesShort[$j]}-$i.log ${pars[@]} $GrainSpotter index-${phasesShort[$j]}-$i.ini lastGSInput[$j]=index-${phasesShort[$j]}-$i.ini echo "#" echo "# Done with GS indexation on ${phases[$j]}." echo "# Indexing saved in grains-${phasesShort[$j]}-$i.log" echo "#" grainlists[$j]="${grainlists[$j]} grains-${phasesShort[$j]}-$i.log" echo "#" echo "# Clear indexed peaks from GVE lists" echo "#" # Removed used peaks from gve lists for (( k=0; k<$nphases; k++ )) do $clearGVE grains-${phasesShort[$j]}-$i.log peaks-${phasesShort[$k]}.gve tmp.gve mv -f tmp.gve peaks-${phasesShort[$k]}.gve echo "#" echo "# New peak list for ${phases[$k]} saved in peaks-${phasesShort[$k]}.gve" echo "#" done echo "#" echo "# Done with GS iteration $i on ${phases[$j]}" echo "#" done done done } #----------------------------------------------------------------------------------------------- # # Indexing loop, runs tens of GrainSpotter iterations with decreasing tolerances # Runs in the current folder # #----------------------------------------------------------------------------------------------- # Saving home directory home=`pwd` # Global parameter. Used to pass list of files between functions grainlists=() lastGSInput=() for (( i=0; i<$nphases; i++ )) do grainlists[$i]="" lastGSInput[$i]="" done # Make some tests to make sure all parameters have been set error=false for (( i=0; i<$nphases; i++ )) do if [ -z "${phases[$i]}" ]; then ((k = i + 1)) echo "Name of phase $k is blank. This should not happen. Check definition of \$phases variable."; error=true fi if [ -z "${phasesShort[$i]}" ]; then ((k = i + 1)) echo "Short name of phase $k is blank. This should not happen. Check definition of \$phasesShort variable."; error=true fi if [ -z "${crystalSymmetryCodes[$i]}" ]; then ((k = i + 1)) echo "Crystal symmetry code for phase $k is blank. This should not happen. Check definition of \$crystalSymmetryCodes variable."; error=true fi if [ -z "${spaceGroups[$i]}" ]; then ((k = i + 1)) echo "Space group for phase $k is blank. This should not happen. Check definition of \$spaceGroups variable."; error=true fi if [ -z "${startGVEs[$i]}" ]; then ((k = i + 1)) echo "Name of file for GVE vectors for phase $k is blank. This should not happen. Check definition of \$startGVEs variable."; error=true fi done ngs=-1 for gsPar in "${gsPars[@]}" do # Set comma as delimiter IFS=',' # Split parameter information read -a pars <<< "$gsPar" # Number of GrainSpotter loops for this set of parameters nloops=${pars[0]} ((ngs = ngs + nloops)) # Extracting GrainSpotter parameters for each phase for (( j=0; j<$nphases; j++ )) do ((k = j + 1)) if [ -z "${pars[$k]}" ]; then echo "No parameter for phase $k at line $gsPar" error=true fi done done if [ "$error" = true ]; then echo "" echo "There were errors while parsing the script parameters. See messages above." echo "" exit fi echo "# " echo "# " echo "# Multiphase multigrain indexing" echo "# " echo "# This script will run $nIndexings attemp(s) of an indexing with $nphases phases, with $ngs GrainSpotter iterations for each phase." echo "# Phase list: ${phases[@]}" echo "# Starting GVE-vectors saved in ${startGVEs[@]}" echo "# Parameters for GrainSpotter indexings" for gsPar in "${gsPars[@]}" do # Set comma as delimiter IFS=',' # Split parameter information read -a pars <<< "$gsPar" # Number of GrainSpotter loops for this set of parameters nloops=${pars[0]} echo "# - $nloops iteration(s) with" # Extracting GrainSpotter parameters for each phase for (( j=0; j<$nphases; j++ )) do ((k = j + 1)) echo "# * ${pars[$k]} for ${phases[$j]}" done done echo "#" echo "#" for (( loopIndexing=1; loopIndexing<=$nIndexings; loopIndexing++ )) do echo "#----------------------------------------------------------------------------------------" echo "#" echo "# Full indexing loop number $loopIndexing" echo "# Data saved in folder: Indexing-$loopIndexing" echo "#" echo "#----------------------------------------------------------------------------------------" echo "" folder="Indexing-$loopIndexing" \rm -rf $folder mkdir $folder cd $folder # Clear list of indexed grains for (( i=0; i<$nphases; i++ )) do grainlists[$i]="" done # Start indexing loop indexing_loop echo "" echo "#---------------------------------------" echo "# Indexing loop number $loopIndexing is finished" echo "#" # Merge grains for each phase mergeGrainFiles=() originalGVEFiles=() for (( i=0; i<$nphases; i++ )) do originalGVEFiles[$i]="peaks-ori-${phasesShort[$i]}.gve" echo "" echo "#---------------------------------------" echo "# Merging grain information for ${phases[$i]} into files starting with merge-${phasesShort[$i]}, i.e. merge-${phasesShort[$i]}-grains.log, etc" echo "#" $mergeGrains ${grainlists[$i]} -c "${crystalSymmetryCodes[$i]}" -o "merge-${phasesShort[$i]}" mergeGrainFiles[$i]="merge-${phasesShort[$i]}-grains.log" echo "" echo "#---------------------------------------" echo "# Extracting Euler angles for ${phases[$i]} into merge-${phasesShort[$i]}-grains-euler.txt" echo "#" $extractEuler -o "merge-${phasesShort[$i]}-grains-euler.txt" "merge-${phasesShort[$i]}-grains.log" echo "" echo "#---------------------------------------" echo "# Saving list of indexed g-vectors for ${phases[$i]} into gve-Indexed-${phasesShort[$i]}.gve" echo "# List of remaining g-vectors for ${phases[$i]} moved to gve-NotIndexed-${phasesShort[$i]}.gve" echo "#" $clearGVE -k gve-Indexed-${phasesShort[$i]}.gve merge-${phasesShort[$i]}-grains.log peaks-ori-${phasesShort[$i]}.gve tmp.gve rm tmp.gve mv peaks-${phasesShort[$i]}.gve gve-NotIndexed-${phasesShort[$i]}.gve done echo "" echo "#---------------------------------------" echo "# More indexing statistics" echo "#" $statistics -w $wavelength -i ${lastGSInput[@]} -l ${mergeGrainFiles[@]} -g ${originalGVEFiles[@]} cd $home echo "" echo "" echo "#----------------------------------------------------------------------------------------" echo "#" echo "# Done with indexing loop number $loopIndexing" echo "# Data saved in folder: Indexing-$loopIndexing" echo "#" echo "#----------------------------------------------------------------------------------------" echo "" echo "" done exit