@@ -18,7 +18,15 @@ typedef unordered_map<string, string> TaxonDateMap;
1818 @return converted date as a float or YYYY-MM[-DD] format
1919 */
2020string 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) {
4351bool 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