Repository: DynamicsAndNeuralSystems/catch22 (language: python)

Issue:
CO_f1ecac overestimating by 1
### Issue
Using the new method of linearly interpolating to estimate the 1/e crossing, `CO_f1ecac` gives an output that is `1` greater than expected.

Compare the _hctsa_ matlab output for `test.txt`:
```
>> a = CO_FirstCrossing((x), [], 1/exp(1))

a = 
  struct with fields:
      firstCrossing: 33
      pointOfCrossing: 32.5026
```

To the catch22 output:
```
33.50260547693646, CO_f1ecac, 0.186000
```

### Solution

Edit `CO_f1ecac()` in `CO_AutoCorr.c` to return `i + dx - 1`, or index by `i` and `i+1` (rather than `i-1` and `i`).


Also verified against a plot of the ACF for `test.txt`:
![image](https://user-images.githubusercontent.com/42064608/173233857-7e29efba-9445-4fa4-8a8d-5fc203bd96b1.png)



Discussion / hints:

Fix patch:
diff --git a/.gitignore b/.gitignore
index 13fdcea7..d7409bb7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,6 @@
 *.m~
 *.mexmaci64
 .DS_Store
+*.vscode
+*.code-workspace
+*/run_features
diff --git a/.vscode/settings.json b/.vscode/settings.json
deleted file mode 100644
index 979ab8a2..00000000
--- a/.vscode/settings.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-    "files.associations": {
-        "*.rmd": "markdown",
-        "dn_outlierinclude.h": "c"
-    }
-}
\ No newline at end of file
diff --git a/C/.DS_Store b/C/.DS_Store
deleted file mode 100644
index cf004a38..00000000
Binary files a/C/.DS_Store and /dev/null differ
diff --git a/C/CO_AutoCorr.c b/C/CO_AutoCorr.c
index 8f73976d..2b051191 100644
--- a/C/CO_AutoCorr.c
+++ b/C/CO_AutoCorr.c
@@ -195,11 +195,11 @@ double CO_f1ecac(const double y[], const int size)
     double thresh = 1.0/exp(1);
     
     double out = (double)size;
-    for(int i = 1; i < size-1; i++){
+    for(int i = 0; i < size-2; i++){
         // printf("i=%d autocorrs_i=%1.3f\n", i, autocorrs[i]);
-        if ( autocorrs[i] < thresh ){
-            double m = autocorrs[i] - autocorrs[i-1];
-            double dy = thresh - autocorrs[i-1];
+        if ( autocorrs[i+1] < thresh ){
+            double m = autocorrs[i+1] - autocorrs[i];
+            double dy = thresh - autocorrs[i];
             double dx = dy/m;
             out = ((double)i) + dx;
             // printf("thresh=%1.3f AC(i)=%1.3f AC(i-1)=%1.3f m=%1.3f dy=%1.3f dx=%1.3f out=%1.3f\n", thresh, autocorrs[i], autocorrs[i-1], m, dy, dx, out);
diff --git a/C/main.c b/C/main.c
index 781733e8..7d44e573 100644
--- a/C/main.c
+++ b/C/main.c
@@ -24,10 +24,10 @@
 
 #include "stats.h"
 
-// check if data qualifies to be cought22
+// check if data qualifies to be caught22
 int quality_check(const double y[], const int size)
 {
-    int minSize = 40;
+    int minSize = 10;
 
     if(size < minSize)
     {
diff --git a/C/runAllTS.sh b/C/runAllTS.sh
index c09337c6..2ba8ed4a 100755
--- a/C/runAllTS.sh
+++ b/C/runAllTS.sh
@@ -1,13 +1,71 @@
-mkdir -p "featureOutputs"
+#!/bin/bash
 
-for entry in ./timeSeries/*
+help()
+{
+   echo ""
+   echo "Usage: $0 -i indir -o outdir -a append_string -s"
+   echo -e "\t-h Show this help message"
+   echo -e "\t-i Path to a directory containing input time-series files (.txt with one time series value per line). Default: './timeSeries'"
+   echo -e "\t-o Path to a directory in which to save output feature values. Default: './featureOutput'"
+   echo -e "\t-a A string (minus extension) appended to the input file names to create the output file names. Default: 'output'"
+   echo -e "\t-s A switch to evaluate catch22 (0) or catch24 (1). Default: 0"
+   exit 1
+}
+
+while getopts "i:o:a:s:h" opt
+do
+   case "$opt" in
+      i) indir="$OPTARG" ;;
+      o) outdir="$OPTARG" ;;
+      a) append="$OPTARG" ;;
+      s) catch24="$OPTARG" ;;
+      h) help ;;
+   esac
+done
+
+srcdir=$(dirname "$0}")
+
+if [ -z "$indir" ]
+then
+   indir="./timeSeries"
+fi
+
+if [ -z "$outdir" ]
+then
+   outdir="./featureOutput"
+fi
+
+if [ -z "$append" ]
+then
+   append="output"
+fi
+
+if [ -z "$catch24" ]
+then
+   catch24=0
+fi
+
+indir="$(dirname $indir)/$(basename $indir)"
+outdir="$(dirname $outdir)/$(basename $outdir)"
+mkdir -p $outdir
+
+# Loop through each file in indir and save the feature outputs
+for entry in "${indir}"/*.txt
 do
-	echo "$entry"
-	
-	filename=$(basename "$entry")
-	extension="${filename##*.}"
-	filename="${filename%.*}"
+    filename=$(basename "$entry")
+    extension="${filename##*.}"
+    filename="${filename%.*}"
+    fullfile="${outdir}/${filename}${append}.${extension}"
+    if [ "${filename: -${#append}}" != "${append}" ]
+    then
+        yes $catch24 | "${srcdir}/run_features" $entry $fullfile > /dev/null
 
-	./run_features $entry "./featureOutputs/"$filename"output.txt"
+        if [ -s $fullfile ] # Remove file if catch22 errors
+        then
+            echo "Output written to ${fullfile}"
+        else
+            rm $fullfile
+        fi
 
+    fi
 done


Test patch:
diff --git a/testData/runtests.sh b/testData/runtests.sh
new file mode 100755
index 00000000..5c9da340
--- /dev/null
+++ b/testData/runtests.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+"$(dirname -- $0)/../C/runAllTS.sh" -i "$(dirname -- $0)" -o "$(dirname -- $0)" -a "_output" -s 1 -i "$(dirname -- $0)" -o "$(dirname -- $0)" -a "_output" -s 1
diff --git a/testData/test2_output.txt b/testData/test2_output.txt
index 87d7e122..fb7426f2 100644
--- a/testData/test2_output.txt
+++ b/testData/test2_output.txt
@@ -1,23 +1,23 @@
--0.61479911484527, DN_HistogramMode_5, 0.014000
--0.78225446555221, DN_HistogramMode_10, 0.004000
-7.13507860878856, CO_Embed2_Dist_tau_d_expfit_meandiff, 0.372000
-33.00000000000000, CO_f1ecac, 0.278000
-77.00000000000000, CO_FirstMin_ac, 0.279000
-1.00638907799376, CO_HistogramAMI_even_2_5, 0.028000
-0.00001782472612, CO_trev_1_num, 0.011000
-0.40740740740741, DN_OutlierInclude_p_001_mdrmd, 0.538000
--0.23703703703704, DN_OutlierInclude_n_001_mdrmd, 0.289000
-0.84782608695652, FC_LocalSimple_mean1_tauresrat, 0.556000
-0.08029384289851, FC_LocalSimple_mean3_stderr, 0.012000
-40.00000000000000, IN_AutoMutualInfoStats_40_gaussian_fmmi, 0.133000
-0.31970260223048, MD_hrv_classic_pnn40, 0.007000
-83.00000000000000, SB_BinaryStats_diff_longstretch0, 0.006000
-88.00000000000000, SB_BinaryStats_mean_longstretch1, 0.004000
-1.21058781724385, SB_MotifThree_quantile_hh, 0.091000
-0.29545454545455, SC_FluctAnal_2_rsrangefit_50_1_logi_prop_r1, 0.260000
-0.75000000000000, SC_FluctAnal_2_dfa_50_1_2_logi_prop_r1, 0.111000
-0.99313877887424, SP_Summaries_welch_rect_area_5_1, 0.131000
-0.03681553890926, SP_Summaries_welch_rect_centroid, 0.106000
-0.08000000000000, SB_TransitionMatrix_3ac_sumdiagcov, 0.296000
-0.00000000000000, PD_PeriodicityWang_th0_01, 0.152000
+-0.23703703703704, DN_OutlierInclude_n_001_mdrmd, 0.248000
+0.40740740740741, DN_OutlierInclude_p_001_mdrmd, 0.342000
+-0.61479911484527, DN_HistogramMode_5, 0.005000
+-0.78225446555221, DN_HistogramMode_10, 0.003000
+7.13507860878856, CO_Embed2_Dist_tau_d_expfit_meandiff, 0.283000
+32.50260547693646, CO_f1ecac, 0.197000
+77.00000000000000, CO_FirstMin_ac, 0.315000
+1.00638907799376, CO_HistogramAMI_even_2_5, 0.017000
+0.00001782472612, CO_trev_1_num, 0.008000
+0.84782608695652, FC_LocalSimple_mean1_tauresrat, 0.522000
+0.08029384289851, FC_LocalSimple_mean3_stderr, 0.010000
+40.00000000000000, IN_AutoMutualInfoStats_40_gaussian_fmmi, 0.114000
+0.31970260223048, MD_hrv_classic_pnn40, 0.002000
+83.00000000000000, SB_BinaryStats_diff_longstretch0, 0.003000
+88.00000000000000, SB_BinaryStats_mean_longstretch1, 0.003000
+1.21058781724385, SB_MotifThree_quantile_hh, 0.047000
+0.29545454545455, SC_FluctAnal_2_rsrangefit_50_1_logi_prop_r1, 0.193000
+0.75000000000000, SC_FluctAnal_2_dfa_50_1_2_logi_prop_r1, 0.075000
+0.99313877887425, SP_Summaries_welch_rect_area_5_1, 0.077000
+0.03681553890926, SP_Summaries_welch_rect_centroid, 0.074000
+0.08000000000000, SB_TransitionMatrix_3ac_sumdiagcov, 0.309000
+0.00000000000000, PD_PeriodicityWang_th0_01, 0.135000
 
diff --git a/testData/testShort_output.txt b/testData/testShort_output.txt
new file mode 100644
index 00000000..6c5d5553
--- /dev/null
+++ b/testData/testShort_output.txt
@@ -0,0 +1,23 @@
+-0.58333333333333, DN_OutlierInclude_n_001_mdrmd, 0.019000
+0.75000000000000, DN_OutlierInclude_p_001_mdrmd, 0.017000
+0.02269949495805, DN_HistogramMode_5, 0.001000
+0.02269949495805, DN_HistogramMode_10, 0.001000
+0.51152503131790, CO_Embed2_Dist_tau_d_expfit_meandiff, 0.012000
+2.67524184613158, CO_f1ecac, 0.004000
+8.00000000000000, CO_FirstMin_ac, 0.004000
+1.36615884756920, CO_HistogramAMI_even_2_5, 0.003000
+0.01964378196445, CO_trev_1_num, 0.001000
+0.60000000000000, FC_LocalSimple_mean1_tauresrat, 0.008000
+0.05070841167817, FC_LocalSimple_mean3_stderr, 0.000000
+6.00000000000000, IN_AutoMutualInfoStats_40_gaussian_fmmi, 0.002000
+1.00000000000000, MD_hrv_classic_pnn40, 0.000000
+1.00000000000000, SB_BinaryStats_diff_longstretch0, 0.001000
+5.00000000000000, SB_BinaryStats_mean_longstretch1, 0.000000
+1.49903067297901, SB_MotifThree_quantile_hh, 0.004000
+0.00000000000000, SC_FluctAnal_2_rsrangefit_50_1_logi_prop_r1, 0.007000
+0.00000000000000, SC_FluctAnal_2_dfa_50_1_2_logi_prop_r1, 0.006000
+0.00000000000000, SP_Summaries_welch_rect_area_5_1, 0.004000
+0.39269908169875, SP_Summaries_welch_rect_centroid, 0.003000
+0.16666666666667, SB_TransitionMatrix_3ac_sumdiagcov, 0.006000
+0.00000000000000, PD_PeriodicityWang_th0_01, 0.013000
+
diff --git a/testData/testSinusoid_output.txt b/testData/testSinusoid_output.txt
new file mode 100644
index 00000000..9a44705f
--- /dev/null
+++ b/testData/testSinusoid_output.txt
@@ -0,0 +1,23 @@
+0.13687262547490, DN_OutlierInclude_n_001_mdrmd, 8.703000
+-0.13777244551090, DN_OutlierInclude_p_001_mdrmd, 6.593000
+1.27292807660985, DN_HistogramMode_5, 0.041000
+-1.12758575737747, DN_HistogramMode_10, 0.039000
+1.64629633438112, CO_Embed2_Dist_tau_d_expfit_meandiff, 8.099000
+119.74079600337870, CO_f1ecac, 6.009000
+2.00000000000000, CO_FirstMin_ac, 4.579000
+1.07949995567938, CO_HistogramAMI_even_2_5, 0.320000
+-0.00017509308632, CO_trev_1_num, 0.110000
+0.00625000000000, FC_LocalSimple_mean1_tauresrat, 13.819000
+0.14051134209844, FC_LocalSimple_mean3_stderr, 0.190000
+1.00000000000000, IN_AutoMutualInfoStats_40_gaussian_fmmi, 1.845000
+0.82200000000000, MD_hrv_classic_pnn40, 0.041000
+6.00000000000000, SB_BinaryStats_diff_longstretch0, 0.051000
+301.00000000000000, SB_BinaryStats_mean_longstretch1, 0.046000
+1.38225822030023, SB_MotifThree_quantile_hh, 1.417000
+0.77551020408163, SC_FluctAnal_2_rsrangefit_50_1_logi_prop_r1, 3.221000
+0.69387755102041, SC_FluctAnal_2_dfa_50_1_2_logi_prop_r1, 1.645000
+0.98817221358274, SP_Summaries_welch_rect_area_5_1, 2.410000
+0.00997087512126, SP_Summaries_welch_rect_centroid, 2.218000
+0.01005896635449, SB_TransitionMatrix_3ac_sumdiagcov, 6.992000
+628.00000000000000, PD_PeriodicityWang_th0_01, 17.879000
+
diff --git a/testData/test_output.txt b/testData/test_output.txt
index 0c719617..01e8739d 100644
--- a/testData/test_output.txt
+++ b/testData/test_output.txt
@@ -1,23 +1,23 @@
--0.61479911484527, DN_HistogramMode_5, 0.025000
--0.78225446555221, DN_HistogramMode_10, 0.047000
-7.13507860878856, CO_Embed2_Dist_tau_d_expfit_meandiff, 0.433000
-33.00000000000000, CO_f1ecac, 0.357000
-77.00000000000000, CO_FirstMin_ac, 0.402000
-1.00638907799376, CO_HistogramAMI_even_2_5, 0.077000
-0.00001782472612, CO_trev_1_num, 0.020000
-0.40740740740741, DN_OutlierInclude_p_001_mdrmd, 0.845000
--0.23703703703704, DN_OutlierInclude_n_001_mdrmd, 0.392000
-0.84782608695652, FC_LocalSimple_mean1_tauresrat, 0.635000
-0.08029384289851, FC_LocalSimple_mean3_stderr, 0.015000
-40.00000000000000, IN_AutoMutualInfoStats_40_gaussian_fmmi, 0.149000
-0.31970260223048, MD_hrv_classic_pnn40, 0.004000
-83.00000000000000, SB_BinaryStats_diff_longstretch0, 0.006000
-88.00000000000000, SB_BinaryStats_mean_longstretch1, 0.005000
-1.21058781724385, SB_MotifThree_quantile_hh, 0.099000
-0.29545454545455, SC_FluctAnal_2_rsrangefit_50_1_logi_prop_r1, 0.281000
-0.75000000000000, SC_FluctAnal_2_dfa_50_1_2_logi_prop_r1, 0.119000
-0.99313877887424, SP_Summaries_welch_rect_area_5_1, 0.139000
-0.03681553890926, SP_Summaries_welch_rect_centroid, 0.113000
-0.08000000000000, SB_TransitionMatrix_3ac_sumdiagcov, 0.325000
-0.00000000000000, PD_PeriodicityWang_th0_01, 0.161000
+-0.23703703703704, DN_OutlierInclude_n_001_mdrmd, 0.252000
+0.40740740740741, DN_OutlierInclude_p_001_mdrmd, 0.302000
+-0.61479911484527, DN_HistogramMode_5, 0.003000
+-0.78225446555221, DN_HistogramMode_10, 0.003000
+7.13507860878856, CO_Embed2_Dist_tau_d_expfit_meandiff, 0.234000
+32.50260547693646, CO_f1ecac, 0.192000
+77.00000000000000, CO_FirstMin_ac, 0.191000
+1.00638907799376, CO_HistogramAMI_even_2_5, 0.014000
+0.00001782472612, CO_trev_1_num, 0.006000
+0.84782608695652, FC_LocalSimple_mean1_tauresrat, 0.388000
+0.08029384289851, FC_LocalSimple_mean3_stderr, 0.007000
+40.00000000000000, IN_AutoMutualInfoStats_40_gaussian_fmmi, 0.086000
+0.31970260223048, MD_hrv_classic_pnn40, 0.002000
+83.00000000000000, SB_BinaryStats_diff_longstretch0, 0.002000
+88.00000000000000, SB_BinaryStats_mean_longstretch1, 0.003000
+1.21058781724385, SB_MotifThree_quantile_hh, 0.034000
+0.29545454545455, SC_FluctAnal_2_rsrangefit_50_1_logi_prop_r1, 0.169000
+0.75000000000000, SC_FluctAnal_2_dfa_50_1_2_logi_prop_r1, 0.073000
+0.99313877887425, SP_Summaries_welch_rect_area_5_1, 0.075000
+0.03681553890926, SP_Summaries_welch_rect_centroid, 0.069000
+0.08000000000000, SB_TransitionMatrix_3ac_sumdiagcov, 0.198000
+0.00000000000000, PD_PeriodicityWang_th0_01, 0.100000