Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SilentFileJobOutputter.cc
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 // :noTabs=false:tabSize=4:indentSize=4:
4 //
5 // (c) Copyright Rosetta Commons Member Institutions.
6 // (c) This file is part of the Rosetta software suite and is made available under license.
7 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
8 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
9 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
10 
11 /// @file protocols/jd2/SilentFileJobOutputter.cc
12 /// @brief
13 /// @author Oliver Lange
14 
15 // MPI headers
16 #ifdef USEMPI
17 #include <mpi.h> //keep this first
18 #endif
19 
20 
23 #include <protocols/jd2/Job.hh>
24 #include <protocols/jd2/util.hh>
25 
28 #include <core/pose/Pose.hh>
29 #include <boost/foreach.hpp>
30 #define foreach BOOST_FOREACH
31 
32 ///Utility headers
33 #include <utility/file/FileName.hh>
34 #include <basic/options/option.hh>
35 #include <basic/Tracer.hh>
36 #include <basic/prof.hh>
37 
38 #include <utility/vector1.hh>
39 #include <utility/file/file_sys_util.hh>
40 
41 // option key includes
42 #include <basic/options/keys/out.OptionKeys.gen.hh>
43 #include <basic/options/keys/run.OptionKeys.gen.hh>
44 #include <basic/options/keys/jd2.OptionKeys.gen.hh>
45 
46 #include <numeric/random/random.hh>
47 
48 #include <string>
49 #include <algorithm>
50 
51 static numeric::random::RandomGenerator RG(10321155); // Magic Number
52 static basic::Tracer tr("protocols.jd2.SilentFileJobOutputter");
53 
54 namespace protocols {
55 namespace jd2 {
56 
58  set_defaults();
60 }
61 
63  //DO NOT PUT THINGS HERE - it is not guarunteed to get called - use flush below instead.
64 }
65 
68 }
69 
71  using std::pair;
72  using utility::vector1;
75 
76  typedef std::map< std::string, core::io::silent::SilentFileData > SFD_MAP;
77  typedef vector1< std::pair< SilentStructOP, FileName > >::iterator iter;
78  SFD_MAP sfds;
79  // Only write structures if the user hasn't disabled it - otherwise it totally breaks
80  // the user's expectation.
81  if( !bWriteNoStructures_ ){
82  tr.Debug << "writing " << saved_structs_.size() << " structs." << std::endl;
83  for ( iter it = saved_structs_.begin(), end = saved_structs_.end();
84  it != end; ++it
85  ) {
86  //tr.Debug << "writing struct " << ss->decoy_tag() << std::endl;
87  //tr.Debug << "writing struct " << (*it->first)->decoy_tag() << std::endl;
88  //SilentStructOP ss = it->first;
89  sfds[ it->second ].add_structure( (*it->first) );
90  }
91  for ( SFD_MAP::iterator it = sfds.begin(); it!=sfds.end(); ++it ) {
92  it->second.write_all( it->first );
93  }
94  }
95  // very important to clear after writing!
96  saved_structs_.clear();
97 
98  tr.Debug << "currently have " << saved_structs_.size() << " structs."
99  << std::endl;
100  tr.flush();
101 }
102 
104  using namespace basic::options;
105  using namespace basic::options::OptionKeys;
106 
107  silent_file_ = option[ out::file::silent ]();
108  if(silent_file_().compare("") == 0){
109  utility_exit_with_message("Please supply a file name with the -out:file:silent flag. If you specify a path the -out:path:all flag, the -out:file:silent file name will be relative to it.");
110  }
111 
112  if (! silent_file_.absolute() ) {
113  silent_file_.path( option[ out::path::all ]().path() + "/" + silent_file_.path() );
114  //FileName takes care of platform-specific path seperator, i.e., "/" or "\" ...
115  }
116  tr.Debug << "SilentFileJobOutputter setup for file " << silent_file_ << std::endl;
117 
118 #ifdef USEMPI
119  int mpi_rank;
120  MPI_Comm_rank (MPI_COMM_WORLD, &mpi_rank);/* get current process id */
121  std::string name = silent_file_;
122  // attach mpi rank to out files
123  size_t lastslash = name.find_last_of("/\\");
124  size_t lastdot = name.find_last_of('.');
125  silent_file_ = name;
126 #endif
127 
128  // dd_parser should use binary silent files as a default. but score-only
129  // silent files are also an option
130  // this is really stupid. What knowledge do you about the user's intentions
131  // that trumps the user's input via the command-line? A better idea would be
132  // to exclude certain SilentStruct types, throw a warning or error message,
133  // or do something more intelligent like that.
134  if ( option[ basic::options::OptionKeys::jd2::dd_parser ]() ) {
135  if ( option[ out::file::silent_struct_type ]() != "score")
136  option[ out::file::silent_struct_type ].value( "binary" );
137  }
138 
139  //default is 1
140  n_to_buffer_ = option[ basic::options::OptionKeys::jd2::buffer_silent_output ]();
141  random_flush_frequency_ = option[ basic::options::OptionKeys::jd2::buffer_flush_frequency ]();
142 
144  option[ run::intermediate_scorefiles ]() ||
145  option[ run::intermediate_structures ]()
146  );
147 
148  bWriteIntermediateStructures_ = option[ run::intermediate_structures ]();
149 
150  bWriteNoStructures_ = false;
151 
152  if ( option[ OptionKeys::out::file::scorefile ].user() ){
154  } else write_separate_scorefile_ = false;
155 }
156 
161  foreach( std::string & tag, silent_file_tags_ ) {
162  /// eliminate the FAILURE_ prefix so that jobs know to start from
163  /// the 'next' nstruct on restart. This is important to avoid duplicate
164  /// entries
165  if( tag.substr( 0, 8 ) == "FAILURE_" )
166  tag = tag.substr( 8, 1000 );
167  } //foreach
168  } //fi
169 }
170 
172  JobCOP job, core::pose::Pose const & pose
173 ) {
174 
176  dump_pose( silent_file_, job, pose, bWriteNoStructures_ /*this is always false */ /* bWriteScoresOnly */);
177 
178 
179  // only write a scorefile if specified by the user
180  using namespace basic::options;
181 
183  //write here to avoid 2x evaluated for same structure
185  sfd.write_silent_struct( *ss, scorefile_name(), true );
186  }
187 
188  //calling dump_pose twice means calling evaluator twice which can be expensive!!
189 
190  // if ( !bWriteNoStructures_ ) dump_pose( scorefile_name(), job, pose, true );
191  // if (bWriteNoStructures_) we have already score-only output ... don't have it redundant
192 }
193 
194 /// @brief this function is intended for saving mid-protocol poses; for example
195 /// the final centroid structure in a combined centroid/fullatom protocol.
196 /// --->these go to file silent_filename+tag
198  JobCOP job,
199  core::pose::Pose const & pose,
200  std::string const & tag,
201  int copy_count, /*default -1 */
202  bool score_only /*default false*/
203 ) {
205  filename.base( silent_file_.base() +"_"+ tag );
206 
208  if ( bWriteIntermediateFiles_ ) {
209  ss=dump_pose( filename, job, pose, !bWriteIntermediateStructures_ || score_only , copy_count );
210  }
211 
212  if ( write_separate_scorefile_ && ss ) {
213  //write here to avoid 2x evaluated for same structure
216  filename.base( scorefile_name().base() +"_"+ tag );
217  sfd.write_silent_struct( *ss, filename, true );
218  }
219 
220 
221 }
222 
225  JobCOP job,
226  core::pose::Pose const & pose_in,
227  bool bWriteScoreOnly,
228  int copy_count
229 ) {
230  PROF_START( basic::JD2_SILENT_OUTPUTTER );
232 
235  if ( bWriteScoreOnly ) {
237  } else {
239  }
240 
241  std::ostringstream tag;
242  tag << output_name( job );
243  if ( copy_count>=0 ) {
244  core::Size const replica( current_replica() );
245  if ( replica ) {
246  tag << "_" << std::setfill('0') << std::setw(3) << replica;
247  }
248  tag << '_' << std::setfill('0') << std::setw(8) << copy_count;
249  }
250  ss->fill_struct( pose_in, tag.str() );
251  add_job_data_to_ss( ss, job );
252 
253  core::pose::Pose pose( pose_in );
254  evaluate( pose, tag.str(), *ss );
255 
256 
257  add_silent_struct( ss, filename );
258  tr.Debug << "adding struct " << ss->decoy_tag() << std::endl;
259  tr.Debug << "have " << saved_structs_.size() << ", buffering " << n_to_buffer_ << std::endl;
260  core::Real rand;
261  if ( random_flush_frequency_ < 1.0 ) rand=RG.uniform();
262  else rand=0.0;
263  if ( saved_structs_.size() >= n_to_buffer_ && random_flush_frequency_ >= rand ) {
265  }
266 
267  tr.flush();
268  PROF_STOP( basic::JD2_SILENT_OUTPUTTER );
269  return ss;
270 }
271 
274  utility::file::FileName const & fn
275 ) {
276  saved_structs_.push_back( std::make_pair( ss, fn ) );
277 }
278 
279 /////////////////////////////////state of output functions/////////////////////////////////
281  using namespace basic::options;
282  using namespace basic::options::OptionKeys;
283 
284  // did we complete the job later ?
285  if ( job->completed() ) {
286  return true;
287  }
288 
289  // was the job completed beforehand ( in the silent file before the app even
290  // started ) ?
291  if ( option[ run::multiple_processes_writing_to_one_directory ].value() ) {
292  read_done_jobs(); // refresh silent_file_tags_ for parallel processes
293  }
294  CompareTags predicate( output_name(job) );
295 
296  bool const already_written(
297  find_if(silent_file_tags_.begin(), silent_file_tags_.end(), predicate) != silent_file_tags_.end()
298  );
299 
300  using std::pair;
301  using std::string;
302  using utility::vector1;
305 
306  vector1< string > tags;
307  typedef vector1< pair< SilentStructOP, FileName > >::const_iterator iter;
308  for ( iter it = saved_structs_.begin(), end = saved_structs_.end(); it != end; ++it ) {
309  tags.push_back( it->first->decoy_tag() );
310  }
311 
312  bool const already_buffered(
313  find_if( tags.begin(), tags.end(), predicate ) != tags.end()
314  );
315 
316  return ( already_written || already_buffered );
317 }
318 
319 /// @details
320 /// SilentFile tags should preserve the FULL NAME such that we don't end up with
321 /// duplicate tags. This will cause problems on BOINC if changed.
323  return affixed_numbered_name( job );
324 }
325 
326 
327 void
329  silent_file_ = name;
330  read_done_jobs(); //safer to do this again
331 }
332 
333 void
335  write_separate_scorefile_ = write_separate_scorefile;
336 }
337 
338 //CREATOR SECTION
341 {
342  return "SilentFileJobOutputter";
343 }
344 
347  return new SilentFileJobOutputter;
348 }
349 
350 } //jd2
351 } //protocols