6 if [[ ! $ZSH_EVAL_CONTEXT =~ :
file$ ]];
then
7 echo "Auxiliary script for running the conjugate gradient fit in zsh."
8 echo "This script should be sourced by the steering script."
12 # This script contains auxiliary functions for running the conjugate gradient fit.
13 # It should be sourced by the steering script.
14 # The steering script should provide for the method getChi2 and set the fit parameters before calling method gradient.
15 # On return, the method getChi2 should set the current value of chi2 to its first positional parameter.
16 # The second positional parameter corresponds to an option that can be used within method getChi2.
17 # The value of the option corresponds to the following cases.
18 # 0 => step wise improvement of the chi2;
19 # 1 => evaluation of the chi2 before the determination of the gradient of the chi2; and
20 # 2 => evaluation of the derivative of the chi2 to each fit parameter.
21 # The fit parameters are defined by the associative array PARAMETERS.
22 # In this, each key corresponds to a valid zsh command that can be used for changing a specific fit parameter.
23 # The command should contain the wild card '%' which is repeatedly replaced by a value, referred to as step size.
24 # The associated value is used to evaluate the derivative of chi2 per unit step size of each fit parameter.
25 # These step sizes should be tuned beforehand to yield similar absolute values of the derivatives.
27 typeset -
a CHI2 #
internal chi2 values; index [1] corresponds to best value
28 typeset -
a GRADIENT # derivative of
chi2 per unit step size of each fit parameter
29 let
"EPSILON = 5.0E-4" #
default maximal
distance to minimum
30 let
"NUMBER_OF_ITERATIONS = 1000" #
default maximum number of iterations
33 if [[ -z
"$DEBUG" ]];
then
39 # Auxiliary function to evaluate chi2 and gradient thereof at current position.
41 # The external method getChi2 is used to evaluate the chi2.
42 # The value corresponding to each key in the associative array PARAMETERS
43 # is used as unit step size for the evaluation of the derivative of the chi2.
44 # The results are stored in the internal variables CHI2[1] and GRADIENT, respectively.
54 for KEY
in ${(
k)PARAMETERS};
do
55 if (( ${#KEY} > $WIDTH ));
then
63 for KEY
in ${(ko)PARAMETERS};
do
67 VALUE=$PARAMETERS[$KEY]
69 if (( $VALUE != 0.0 ));
then
91 GRADIENT[
$i]=$(($CHI2[2] - $CHI2[3]))
97 if (( $DEBUG >= 3 ));
then
98 printf
"%-${WIDTH}s %12.5f %12.5f\n" $KEY $PARAMETERS[$KEY] $GRADIENT[
$i]
101 let
"V += $GRADIENT[$i]*$GRADIENT[$i]"
105 if (( $DEBUG >= 3 ));
then
106 printf
"%-${WIDTH}s %12s %12.5f\n" "|gradient|" "" $((sqrt($V)))
112 # Move current position along gradient by given scaling factor of the unit step sizes.
114 # \param 1 scaling factor
118 if (( $1 > 0.0 ));
then
122 for KEY
in ${(ko)PARAMETERS};
do
135 let
"i = ${#GRADIENT}"
137 for KEY
in ${(kO)PARAMETERS};
do
154 # The algorithm
is based on the conjugate gradient method.
155 # The position
is moved to the optimal value and the
final chi2 is returned.
157 # If the option
is one, the step sizes are fine-tuned according to the gradient of the
chi2.
158 # The value corresponding to each key
in the associative array PARAMETERS
is then
159 # multiplied by the corresponding element
in GRADIENT and only the
sign thereof
is maintained.
161 # \param 1 maximum number of extra steps
162 # \param 2 variable containing
final chi2 value on
return
169 if (( ${#PARAMETERS} == 0 ));
then
177 for ((
i = 1;
i <= ${#GRADIENT}; ++
i));
do
178 G[
$i]=$((-1.0 * $GRADIENT[
$i]))
183 for ((
N = 0; $N != $NUMBER_OF_ITERATIONS;
N += 1 ));
do
185 if (( $DEBUG >= 3 ));
then
186 printf
"chi2[1] %4d %12.5f\n" $N $CHI2[1]
189 # minimise chi2 in direction of gradient
194 for (( DS = 1.0, M = 0 ; $DS > 1.0e-3; ));
do
200 if (( $DEBUG >= 3 ));
then
201 printf
"chi2[4] %4d %12.5f %12.5e\n" $M $CHI2[4] $DS
204 if (( $CHI2[4] < $CHI2[3] ));
then
216 # if chi2 increases, try additional steps first to overcome possible hurdle, then try single step with reduced size
218 if (( $DS == 1.0 ));
then
220 if (( $M == 0 ));
then
224 if (( $M != $1 ));
then
232 for (( ; $M != 0; --M ));
do
242 if (( $CHI2[3] < $CHI2[2] ));
then
244 # final step based on parabolic interpolation through following points
246 # X1 = -1 * DS -> CHI2[2]
247 # X2 = 0 * DS -> CHI2[3]
248 # X3 = +1 * DS -> CHI2[4]
250 let
"F21 = $CHI2[3] - $CHI2[2]" #
F(X2) -
F(X1)
251 let "F23 = $CHI2[3] - $CHI2[4]"
# F(X2) - F(X3)
253 let
"XS = 0.5 * ($F21 - $F23) / ($F23 + $F21)"
255 move $((+1.0 * $XS * $DS))
259 if (( $CHI2[4] < $CHI2[3] ));
then
265 move $((-1.0 * $XS * $DS))
270 if (( $DEBUG >= 3 ));
then
271 printf "
chi2[3] %4
d %12.5
f %12.5e\
n" $N $CHI2[3] $DS
284 if (( fabs($CHI2[3] - $CHI2[1]) < $EPSILON * 0.5 * (fabs($CHI2[1]) + fabs($CHI2[3])) ));
then
296 for ((
i = 1;
$i <= ${#GRADIENT}; ++
i ));
do
297 let
"GG += $G[$i]*$G[$i]"
298 let
"DGG += ($GRADIENT[$i] + $G[$i]) * $GRADIENT[$i]"
301 if (( $GG == 0.0 ));
then
305 let
"GAM = $DGG / $GG"
307 for ((
i = 1;
$i <= ${#GRADIENT}; ++
i ));
do
308 G[
$i]=$((-1.0 * $GRADIENT[
$i]))
309 H[
$i]=$(($G[
$i] + $GAM * $H[
$i]))
314 if (( $DEBUG >= 3 ));
then
315 printf
"chi2[1] %4d %12.5f\n" $N $CHI2[1]
323 # Additional fit function to be called after gradient.
325 # The algorithm is based on sorting the derivatives of the chi2 and
326 # moving the position one-by-one to the optimal value.
327 # The final chi2 is returned.
329 # \param 1 variable containing final chi2 value on return
338 for KEY
in ${(
k)PARAMETERS};
do
339 if (( ${#KEY} > $WIDTH ));
then
340 let
"WIDTH = ${#KEY}"
345 for ((
N = 0; $N != $NUMBER_OF_ITERATIONS;
N += 1 ));
do
355 for KEY
in ${(ko)PARAMETERS};
do
357 VALUE=$PARAMETERS[$KEY]
361 for K1
in ${(
o)BUFFER};
do
367 for K1
in ${(O)BUFFER};
do
371 for K1
in ${(
o)BUFFER};
do
377 for K1
in ${(O)BUFFER};
do
381 if (( $DEBUG >= 3 ));
then
382 printf
"%-${WIDTH}s %12.5f %12.5f -> %+9.5f <- %+9.5f\n" $KEY $VALUE $CHI2[1] $(($CHI2[2] - $CHI2[1])) $(($CHI2[3] - $CHI2[1]))
385 # map index to derivative of chi2 and maintain sign of step
387 if (($CHI2[2] < $CHI2[1] && $CHI2[2] < $CHI2[3]));
then
389 G[
$i]=$(($CHI2[2] - $CHI2[1]))
393 elif (($CHI2[3] < $CHI2[1] && $CHI2[3] < $CHI2[2]));
then
395 G[
$i]=$(($CHI2[3] - $CHI2[1]))
399 # elif (($CHI2[3] - $CHI2[2] > 0.5*($CHI2[2] + $CHI2[3]) - $CHI2[1])); then
401 # G[$i]=$(($CHI2[2] - $CHI2[1]))
405 # elif (($CHI2[2] - $CHI2[3] > 0.5*($CHI2[2] + $CHI2[3]) - $CHI2[1])); then
407 # G[$i]=$(($CHI2[3] - $CHI2[1]))
416 if (( ${#G} == 0 ));
then
421 # sort derivatives of chi2 and optimise position one-by-one
425 for i VALUE
in `printf
"%d %12.3e\n" ${(kv)G} | sort -g -k2`;
do
427 KEY=${${(ko)PARAMETERS}[
$i]}
429 BUFFER=(${(s/;/)${(
Q)KEY}})
433 let
"DS = $GRADIENT[$i] * $PARAMETERS[$KEY]"
435 if (($DEBUG >= 3));
then
436 printf
"%-${WIDTH}s %12.5f %12.5f\n" $KEY $DS $G[
$i]
441 for ((
n = 1; ; ++
n ));
do
443 for K1
in ${(
o)BUFFER};
do
449 if (( $DEBUG >= 3 ));
then
450 printf
"chi2[4] %4d %12.5f\n" $n $CHI2[4]
453 if (( $CHI2[4] < $CHI2[3] ));
then
460 for K1
in ${(O)BUFFER};
do
464 if (( $CHI2[3] < $CHI2[2] ));
then
466 # final step based on parabolic interpolation through following points
468 # X1 = -1 * DS -> CHI2[2]
469 # X2 = 0 * DS -> CHI2[3]
470 # X3 = +1 * DS -> CHI2[4]
472 let
"F21 = $CHI2[3] - $CHI2[2]" #
F(X2) -
F(X1)
473 let "F23 = $CHI2[3] - $CHI2[4]"
# F(X2) - F(X3)
475 let
"XS = 0.5 * ($F21 - $F23) / ($F23 + $F21)"
477 for K1
in ${(
o)BUFFER};
do
483 if (( $CHI2[4] < $CHI2[3] ));
then
489 for K1
in ${(O)BUFFER};
do
495 if (( $DEBUG >= 3 ));
then
496 printf
"chi2[3] %4d %12.5f\n" $n $CHI2[3]
505 if (( fabs($CHI2[2] - $CHI2[1]) < $EPSILON * 0.5 * (fabs($CHI2[1]) + fabs($CHI2[2])) ));
then
513 if (( $DEBUG >= 3 ));
then
514 printf
"chi2[1] %4d %12.5f\n" $N $CHI2[1]
set Main(RunControl, Responder) is
then fatal No hydrophone data file $HYDROPHONE_TXT fi sort gr k
Q(UTCMax_s-UTCMin_s)-livetime_s
then usage $script[< detector identifier >< run range >]< QA/QCfile > nExample script to produce data quality plots nWhen a detector identifier and run range are data are downloaded from the database nand subsequently stored in the given QA QC file
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
o $QUALITY_ROOT d $DEBUG!CHECK_EXIT_CODE JPlot1D f
static const double H
Planck constant [eV s].
*fatal Wrong number of arguments esac JCookie sh typeset Z DETECTOR typeset Z SOURCE_RUN typeset Z TARGET_RUN set_variable PARAMETERS_FILE $WORKDIR parameters
then fatal Wrong number of arguments fi JConvertDetectorFormat a o
skip elif((BINFRAC< 1.0))
then usage $script< input file >[option[primary[working directory]]] nWhere option can be N
then JMuonMCEvt f $INPUT_FILE o $INTERMEDIATE_FILE d
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable INPUT_FILE $argv[2] eval JPrintDetector a $DETECTOR O IDENTIFIER eval JPrintDetector a $DETECTOR O SUMMARY JAcoustics sh $DETECTOR_ID source JAcousticsToolkit sh CHECK_EXIT_CODE typeset A EMITTERS get_tripods $WORKDIR tripod txt EMITTERS get_transmitters $WORKDIR transmitter txt EMITTERS for EMITTER in
then if[[!-f $DETECTOR]] then JDetector sh $DETECTOR fi cat $WORKDIR trigger_parameters txt<< EOFtrigger3DMuon.enabled=1;trigger3DMuon.numberOfHits=5;trigger3DMuon.gridAngle_deg=1;ctMin=0.0;TMaxLocal_ns=15.0;EOF set_variable TRIGGEREFFICIENCY_TRIGGERED_EVENTS_ONLY INPUT_FILES=() for((i=1;$i<=$NUMBER_OF_RUNS;++i));do JSirene.sh $DETECTOR $JPP_DATA/genhen.km3net_wpd_V2_0.evt.gz $WORKDIR/sirene_ ${i}.root JTriggerEfficiency.sh $DETECTOR $DETECTOR $WORKDIR/sirene_ ${i}.root $WORKDIR/trigger_efficiency_ ${i}.root $WORKDIR/trigger_parameters.txt $JPP_DATA/PMT_parameters.txt INPUT_FILES+=($WORKDIR/trigger_efficiency_ ${i}.root) done for ANGLE_DEG in $ANGLES_DEG[*];do set_variable SIGMA_NS 3.0 set_variable OUTLIERS 3 set_variable OUTPUT_FILE $WORKDIR/matrix\[${ANGLE_DEG}\deg\].root $JPP_DIR/examples/JReconstruction-f"$INPUT_FILES[*]"-o $OUTPUT_FILE-S ${SIGMA_NS}-A ${ANGLE_DEG}-O ${OUTLIERS}-d ${DEBUG}--!fiif[[$OPTION=="plot"]];then if((0));then for H1 in h0 h1;do JPlot1D-f"$WORKDIR/matrix["${^ANGLES_DEG}" deg].root:${H1}"-y"1 2e3"-Y-L TR-T""-\^"number of events [a.u.]"-> o chi2
int sign(const T &value)
Get sign of value.
double getChi2(const double P)
Get chi2 corresponding to given probability.
source $JPP_DIR setenv csh $JPP_DIR &dev null eval JShellParser o a A
#define DEBUG(A)
Message macros.