Skip to content
This repository was archived by the owner on Feb 6, 2024. It is now read-only.

Commit 550a52d

Browse files
committed
support x:y date range, taxon list for MRCA and # for comments in date file
1 parent 4977830 commit 550a52d

File tree

2 files changed

+69
-25
lines changed

2 files changed

+69
-25
lines changed

main/timetree.cpp

Lines changed: 68 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,15 @@ typedef unordered_map<string, string> TaxonDateMap;
1818
@return converted date as a float or YYYY-MM[-DD] format
1919
*/
2020
string convertDate(string date, bool is_ISO) {
21-
if (date.empty() || !isdigit(date[0]))
21+
// check for range in x:y format
22+
if (date.find(':') != string::npos) {
23+
StrVector vec;
24+
convert_string_vec(date.c_str(), vec, ':');
25+
if (vec.size() != 2)
26+
outError("Invalid date range: " + date);
27+
return "b(" + vec[0] + "," + vec[1] + ")";
28+
}
29+
if (date.empty() || !isdigit(date[0]) || date[0] == '-')
2230
return date;
2331
DoubleVector vec;
2432
convert_double_vec(date.c_str(), vec, '-');
@@ -43,9 +51,14 @@ string convertDate(string date, bool is_ISO) {
4351
bool hasISODate(TaxonDateMap &dates) {
4452
for (auto date : dates) {
4553
DoubleVector vec;
46-
convert_double_vec(date.second.c_str(), vec, '-');
47-
if (vec.size() > 1)
48-
return true;
54+
try {
55+
convert_double_vec(date.second.c_str(), vec, '-');
56+
if (vec.size() > 1)
57+
return true;
58+
} catch (...) {
59+
// cannot parse, just do nothing
60+
continue;
61+
}
4962
}
5063
return false;
5164
}
@@ -63,6 +76,10 @@ void readDateFile(string date_file, TaxonDateMap &dates) {
6376
string line;
6477
if (!safeGetline(in, line))
6578
break;
79+
// ignore comment
80+
if (line.find('#') != string::npos)
81+
line = line.substr(0, line.find('#'));
82+
trimString(line);
6683
if (line.empty()) // ignore empty line
6784
continue;
6885
string name, date;
@@ -142,16 +159,38 @@ void writeDate(string date_file, ostream &out, StrVector &taxname) {
142159
for (int i = 0; i < taxname.size(); i++) {
143160
string name = taxname[i];
144161
string date;
145-
if (dates.find(name) == dates.end())
146-
date = "NA";
147-
else if (outgroup_set.find(name) == outgroup_set.end() || Params::getInstance().date_with_outgroup) {
162+
if (dates.find(name) == dates.end()) {
163+
if (!Params::getInstance().date_tip.empty())
164+
date = Params::getInstance().date_tip;
165+
else
166+
date = "NA";
167+
} else if (outgroup_set.find(name) == outgroup_set.end() || Params::getInstance().date_with_outgroup) {
148168
// ignore the date of the outgroup
149169
date = dates[name];
170+
}
171+
if (date != "NA") {
150172
retained_dates[name] = date;
173+
dates.erase(name);
151174
}
152175
if (verbose_mode >= VB_MED)
153176
cout << i+1 << "\t" << name << "\t" << date << endl;
154177
}
178+
179+
// add remaining ancestral dates
180+
for (auto date : dates) {
181+
if (date.first.substr(0,4) == "mrca")
182+
retained_dates[date.first] = date.second;
183+
else if (date.first.find(',') != string::npos) {
184+
retained_dates["mrca(" + date.first + ")"] = date.second;
185+
} else {
186+
retained_dates[date.first] = date.second;
187+
}
188+
}
189+
190+
if (!Params::getInstance().date_root.empty()) {
191+
retained_dates["root"] = Params::getInstance().date_root;
192+
}
193+
155194
cout << retained_dates.size() << " dates extracted" << endl;
156195
try {
157196
out << retained_dates.size() << endl;
@@ -211,18 +250,19 @@ void runLSD2(PhyloTree *tree) {
211250
out.close();
212251
cout << "Date file printed to " << date_file << endl;
213252
}
253+
} else {
254+
// input tip and root date
255+
if (Params::getInstance().date_root != "") {
256+
arg.push_back("-a");
257+
arg.push_back(Params::getInstance().date_root);
258+
}
259+
260+
if (Params::getInstance().date_tip != "") {
261+
arg.push_back("-z");
262+
arg.push_back(Params::getInstance().date_tip);
263+
}
214264
}
215-
216-
if (Params::getInstance().date_root != "") {
217-
arg.push_back("-a");
218-
arg.push_back(Params::getInstance().date_root);
219-
}
220-
221-
if (Params::getInstance().date_tip != "") {
222-
arg.push_back("-z");
223-
arg.push_back(Params::getInstance().date_tip);
224-
}
225-
265+
226266
lsd::InputOutputStream io(tree_stream.str(), outgroup_stream.str(), date_stream.str(), "");
227267

228268
if (Params::getInstance().dating_options != "") {
@@ -269,12 +309,16 @@ void runLSD2(PhyloTree *tree) {
269309
outError("Couldn't write LSD output files");
270310
}
271311

272-
cout << "LSD results written to:" << endl;
273-
cout << " LSD report: " << report_file << endl;
274-
// cout << " Time tree in nexus format: " << tree1_file << endl;
275-
cout << " Time tree in nexus format: " << tree2_file << endl;
276-
cout << " Time tree in newick format: " << tree3_file << endl;
277-
cout << endl;
312+
if (((stringstream*)io.outTree3)->str().empty()) {
313+
outError("Something went wrong, LSD could not date the tree");
314+
} else {
315+
cout << "LSD results written to:" << endl;
316+
cout << " LSD report: " << report_file << endl;
317+
// cout << " Time tree in nexus format: " << tree1_file << endl;
318+
cout << " Time tree in nexus format: " << tree2_file << endl;
319+
cout << " Time tree in newick format: " << tree3_file << endl;
320+
cout << endl;
321+
}
278322
}
279323
#endif
280324

0 commit comments

Comments
 (0)