diff --git a/README.md b/README.md index 8af2226..017edbd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # TNT Script used by Guoyi -This script follows MIT and part of script is from setk.run belonging to Salvador Arias (Instituto Miguel Lillo, San Miguel de Tucumán, Argentina). +The TNT script follows MIT and part of script is from setk.run belonging to Salvador Arias (Instituto Miguel Lillo, San Miguel de Tucumán, Argentina). ## Usage @@ -20,19 +20,59 @@ This script follows MIT and part of script is from setk.run belonging to Salvado - Calculate Relative Bremer support, jackknifing, and bootstrap. +- Map apomorphic characters on the consensus tree. + - Calculate TL, CI, and RI. ## Options - Results instructions are at the end of `tnt.log`. -- `trees.tre`, `con.tre` are trees with taxaname. +- `trees.tre`, `con.tre` are trees with taxname. -- `trees_no.tre`, `con_no.tre` are trees without taxaname. - -- `con_no.tre` can be put into Winclada with your tnt matrix file `filename`. +- `trees_no.tre`, `con_no.tre` are trees without taxname. - `nelsen` can be replaced by `majority`. - `xmult` and `mult` replications and hold trees number can be adjusted. +- `winclada.tre` can be transferred to the acceptable format for WinClada by tnt2winclada and the output file can be put into Winclada with your tnt matrix file `filename` for mapping apomorphic characters and homoplasy. + +# TNT2WinClada + +``` +~|~|\ |~|~ ~) | |o._ |~| _ _| _ + | | \| | /_ \/\/ || ||_|(_|(_|(_| + +MIT, Guoyi Zhang, 2023 +``` + +## Function + +Convert TNT output tree file without tags and taxname, e.g. `winclada.tre` produced by TNT script, to WinClada acceptable format tree. + +## Compile + +### Linux & Unix + +``` +g++ tnt2winclada.cpp -o tnt2winclada +``` + +or + +``` +clang++ -o tnt2winclada tnt2winclada.cpp +``` + +### Windows + +``` +cl /EHsc tnt2winclada.cpp +``` + +## Usage + +``` +tnt2winclada -i ${input_file} -o ${output_file} +``` diff --git a/guoyi.run b/guoyi.run index 2c5ca21..370a447 100644 --- a/guoyi.run +++ b/guoyi.run @@ -1,5 +1,6 @@ log tnt.log; macro=; +taxname+1000; taxname=; mxram 10240; nstates 32; @@ -22,7 +23,9 @@ quote - | Implied weighting will be estimated. |; quote - | TBR Mult and Xmult will be performed. |; quote - | Strict consensus will be used. |; quote - | Relative bremer support, jackknifing and |; -quote - | bootstrap will be shown on the svg. |; +quote - | bootstrap will be shown on the con.svg. |; +quote - | Apomorphic characters mapping will be shown |; +quote - | on the apo.svg and saved to apo*.tre. |; quote - | TL, CI and RI will be calculated finally. |; quote - \------------------------------------------------/; @@ -40,11 +43,10 @@ var: maxIts ; if (ntax<0) - quote NO HAY DATOS!; + quote There is no data; proc/; end -set gVal 1; -/** busca el valor de g **/ +/** find the value of g **/ loop 0 nchar if (!isinfo[#1]) continue; end if (!isact[#1]) continue; end @@ -54,21 +56,21 @@ loop 0 nchar set gVal 'a'-'b'; end stop -quote valor de g = 'gVal'; +quote g value: 'gVal'; set actK 10; set minK 0; -set maxK 500; /** Asume 500 como el maximo posible valor de K **/ +set maxK 500; /** Assume 500 as the maximum possible value of K **/ set maxIts 0; -/** busca el mejor valor de K **/ +/** find the best value of K **/ loop 0 1 - quote actual valor de k = 'actK'; + quote actual k value: 'actK'; set a 1-('actK'/('actK'+1)); quote 'a'; set b ('actK'/('actK'+'gVal'-1))-('actK'/('actK'+'gVal')); quote 'b'; set Nval 'a'/'b'; - quote valor de N = 'Nval'; - if (('Nval'>14.8)&&('Nval'<15.2)) endloop; end /** N esta en el rango **/ + quote N value: 'Nval'; + if (('Nval'>14.8)&&('Nval'<15.2)) endloop; end /** N is in range **/ if ('Nval'>15.2) set minK 'actK'; else @@ -77,16 +79,16 @@ loop 0 1 set a ('maxK'-'minK')/2; set actK 'minK' + 'a'; set maxIts ++; - if ('maxIts'==100) endloop; end /** salida de emergencia **/ + if ('maxIts'==100) endloop; end /** emergency exit **/ setloop 0; stop -/** Si salio de emergencia **/ +/** If out of emergency **/ if ('maxIts'==100) - quote NO SE TERMINARON LAS ITERACIONES; - quote mejor K encontrado: 'actK'; + quote Iterations are not finished; + quote Best K is 'actK'; proc /; end -quote Valor de K: 'actK' (N='Nval'); +quote K value: 'actK' (N='Nval'); piwe='actK'; /*Reopen tnt*/ @@ -130,6 +132,18 @@ export < con.tre; taxname-; export - con_no.tre; +/*Apomorphic characters*/ +export = winclada.tre; +taxname =; +ttags-; +ttags=; +apo >0; +ttags & apo.svg thickness 7 italics fontsize 15; +export < apo.tre; +taxname-; +export - apo_no.tre; +ttags-; + /*Caulculate TL/CI/RI score*/ length *; report-; @@ -164,12 +178,18 @@ quote - | The file `trees*.tre` contain |; quote - | trees found by mult and xmult |; quote - | The file `con*.tre` contain |; quote - | strict consensus tree |; +quote - | The file `apo*.tre` contain |; +quote - | tree with apomorphic character |; quote - | The file `*_no.tre` contain |; quote - | tree with `taxaname-` |; quote - | The file `con.svg` contain |; quote - | strict consensus tree with |; quote - | relative bremer, jak and boot |; quote - | support on the tree |; +quote - | The file `apo.svg` contain the |; +quote - | tree with apomorphy mapping |; +quote - | The file `winclada.tre` can be |; +quote - | converted by tnt2winclada |; quote - \----------------------------------------------/; /*Quit*/ diff --git a/tnt2winclada.cpp b/tnt2winclada.cpp new file mode 100644 index 0000000..9ff2648 --- /dev/null +++ b/tnt2winclada.cpp @@ -0,0 +1,128 @@ +#include +#include +#include +#include + +using namespace std; + +string inputFileName, outputFileName, tnt_format, winclada_format; + +void argument(int argc, char** argv); +int read_tnt(); +void showhelp(int help_num); +void parse_line(int trelen); +void add_space (string winclada, char x); +bool isNum(string strnum); + +void show_help (int help_num){ +if (help_num == 0) { + cout << "~|~|\\ |~|~ ~) | |o._ |~| _ _| _ " << endl; + cout << " | | \\| | /_ \\/\\/ || ||_|(_|(_|(_|" << endl; + cout << "TNT2WinClada MIT\nplease use -h to see more help" << endl; + } else { + cout << "~|~|\\ |~|~ ~) | |o._ |~| _ _| _ " << endl; + cout << " | | \\| | /_ \\/\\/ || ||_|(_|(_|(_|" << endl; + cout << "-h help;\n-i input: -i ${input_file};\n-o output: -o ${output_file}" << endl; + } +} + +void argument(int argc, char **argv) { + // -i -h -o option + int x=0, y = 0, z=0; + for (int i = 0; i < argc; i++) { + if (argc == 2 && string(argv[1]) == "-h") { + show_help(1); + x++; + return; + } + if (argc != 5 || string(argv[1]) != "-i" || string(argv[3]) != "-o") { + show_help(0); + return; + } + if (string(argv[i]) == "-i") { + i++; + inputFileName = argv[i]; + y++; + } + if (string(argv[i]) == "-o") { + i++; + outputFileName = argv[i]; + z++; + } + } + if (x==0 && (y==0 || z==0)) { + cout << "input or output can't be empty." << endl; + } +} + +int read_tnt() { + int trelen; + ifstream inputFile(inputFileName); + if (inputFile.is_open()) { + getline(inputFile, tnt_format); + inputFile.close(); + trelen = tnt_format.length(); + } else { + cout << "File can't be opened" << endl; + } + inputFile.close(); + return trelen; +} + +void add_space (char x) { + int i = 0; + string winclada; + for (i=0; i> buffer; + if(isNum(buffer)){ + tem = stoi(buffer)-1; + buffer = to_string(tem); + } + winclada_format=winclada_format+buffer; + } +} + +void write_winclada() { + ofstream outputFile(outputFileName); + if (outputFile.is_open()) { + outputFile << winclada_format; + } else { + cout << "File can't be written" << endl; + } + outputFile.close(); +} + +int main (int argc, char **argv){ + argument(argc, argv); + int trelen; + trelen = read_tnt(); + parse_line(trelen); + write_winclada(); + return 0; +}