Rosetta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
rna_features.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 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file
11 /// @brief
12 /// @author Rhiju, rhiju@stanford.edu
13 
14 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
15 // RNA features -- produce a huge dump of features that can be regressed against 'deep chemical profiling' data
16 // that is being collected in the Das lab. -- initially craeted on May 7, 2013 by Rhiju.
17 //
18 // Uses new RDAT 'feature' output format.
19 //
20 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
21 
22 // libRosetta headers
23 #include <core/types.hh>
24 #include <core/chemical/AA.hh>
25 #include <core/chemical/ChemicalManager.hh>
26 #include <core/chemical/VariantType.hh>
27 #include <core/conformation/Residue.hh>
28 #include <core/conformation/ResidueFactory.hh>
29 #include <core/scoring/func/HarmonicFunc.hh>
30 #include <core/chemical/rna/util.hh>
31 #include <core/scoring/ScoreFunction.hh>
32 #include <core/scoring/methods/EnergyMethodOptions.hh>
33 #include <core/scoring/sasa.hh>
34 #include <core/scoring/ScoringManager.hh>
35 #include <core/scoring/rna/RNA_LowResolutionPotential.hh>
36 #include <core/pose/rna/RNA_BaseDoubletClasses.hh>
37 #include <core/scoring/rna/RNA_CentroidInfo.hh>
38 #include <core/scoring/rna/RNA_ScoringInfo.hh>
39 #include <core/scoring/rna/data/RNA_DMS_Potential.hh>
40 #include <core/scoring/rna/data/RNA_DMS_LowResolutionPotential.hh>
41 #include <core/io/rna/RDAT.hh>
42 #include <core/scoring/hbonds/HBondSet.hh>
43 #include <core/scoring/hbonds/HBondOptions.hh>
44 #include <core/scoring/hbonds/hbonds.hh>
45 
46 #include <core/id/AtomID_Map.hh>
47 #include <core/id/AtomID.hh>
48 #include <core/id/NamedAtomID.hh>
49 #include <core/id/DOF_ID.hh>
50 #include <core/init/init.hh>
51 #include <core/io/pdb/pose_io.hh>
52 #include <core/kinematics/AtomTree.hh>
53 #include <core/kinematics/FoldTree.hh>
54 #include <core/kinematics/Jump.hh>
55 #include <core/kinematics/Stub.hh>
56 
57 #include <core/pose/Pose.hh>
58 #include <core/pose/PDBInfo.hh>
59 #include <core/pose/PDBInfo.fwd.hh>
60 #include <core/pose/util.hh>
61 #include <core/pose/rna/RNA_BasePairClassifier.hh>
62 #include <core/import_pose/import_pose.hh>
63 
64 #include <devel/init.hh>
65 
66 #include <protocols/farna/util.hh>
67 #include <protocols/viewer/viewers.hh>
68 
69 #include <basic/options/option.hh>
71 #include <basic/database/open.hh>
72 
73 #include <utility/vector1.hh>
75 #include <utility/io/ozstream.hh>
76 #include <utility/io/izstream.hh>
77 #include <utility/file/FileName.hh>
78 
79 #include <numeric/xyzVector.hh>
80 #include <numeric/xyzMatrix.hh>
81 #include <numeric/conversions.hh>
82 #include <numeric/constants.hh>
83 
84 #include <ObjexxFCL/format.hh>
85 #include <ObjexxFCL/FArray1D.hh>
86 #include <ObjexxFCL/FArray2D.hh>
88 
89 
90 // C++ headers
91 #include <fstream>
92 #include <iostream>
93 #include <string>
94 
95 //silly using/typedef
96 // option key includes
97 
98 #include <basic/options/keys/out.OptionKeys.gen.hh>
99 #include <basic/options/keys/in.OptionKeys.gen.hh>
100 #include <basic/options/keys/chemical.OptionKeys.gen.hh>
101 
102 //Auto Headers
103 #include <core/conformation/Conformation.hh>
104 #include <core/scoring/constraints/Constraint.hh>
105 #include <numeric/xyz.functions.hh>
106 
107 //Auto using namespaces
108 namespace ObjexxFCL { namespace format { } } using namespace ObjexxFCL::format; // AUTO USING NS
109 //Auto using namespaces end
110 
111 using namespace core;
112 using namespace core::conformation;
113 //using namespace protocols;
114 using namespace basic::options::OptionKeys;
115 using namespace core::chemical::rna;
116 
117 using utility::vector1;
121 using io::pdb::dump_pdb;
122 
124 
125 
126 ///////////////////////////////////////////////////////////////////////////
127 void
129  vector1< core::Real > & feature_vals,
130  Size & feature_counter,
131  std::string const & feature_name,
132  core::Real const feature_val ){
133 
134  feature_counter++;
135 
136  if ( feature_counter > feature_names.size() ) feature_names.push_back( feature_name );
137  runtime_assert( feature_counter <= feature_names.size() );
138 
139  feature_vals.push_back( feature_val );
140 }
141 
142 ///////////////////////////////////////////////////////////////////////////////
143 Size
144 rna_features_from_pose( core::io::rna::RDAT & rdat, pose::Pose & pose )
145 {
146  using namespace core::conformation;
147  using namespace core::chemical;
148  using namespace core::scoring;
149  using namespace core::scoring::rna::data;
150  using namespace core::kinematics;
151  using namespace core::id;
152  using namespace protocols::farna;
153  using namespace core::chemical::rna;
154 
155  vector1< std::string > feature_names;
157  vector1< char > seqchars;
158  vector1< int > resnums;
159  vector1< vector1< core::Real > > all_feature_vals;
160 
161  Size res_count( 0 ), num_features( 0 );
162  Size const nres = pose.total_residue();
163  core::pose::PDBInfoCOP pdb_info = pose.pdb_info();
164 
165  // sasa calculation
166  AtomID_Map< core::Real > atom_sasa;
168  core::Real const probe_radius( 1.4 );
169  scoring::calc_per_atom_sasa( pose, atom_sasa, rsd_sasa, probe_radius, true );
170 
171  RNA_DMS_Potential & rna_dms_potential = ScoringManager::get_instance()->get_RNA_DMS_Potential();
172  pose.update_residue_neighbors();
173  rna_dms_potential.initialize( pose );
174 
175  RNA_DMS_LowResolutionPotential & rna_dms_low_resolution_potential = ScoringManager::get_instance()->get_RNA_DMS_LowResolutionPotential();
176  // rna_dms_low_resolution_potential.set_careful_base_pair_classifier( false );
177  rna_dms_low_resolution_potential.initialize( pose );
178 
179  vector1< char > nt_names = utility::tools::make_vector1( 'a', 'c', 'g', 'u' );
180  Size const num_nt = nt_names.size();
181  runtime_assert( num_nt == 4 );
182 
183  for ( Size i = 1; i <= nres; i++ ) {
184 
185  Residue const & rsd = pose.residue( i );
186  if ( !rsd.is_RNA() ) continue;
187  res_count++;
188 
189  seqchars.push_back( rsd.name1() );
190  resnums.push_back( pdb_info->number( i ) );
191  chains.push_back( pdb_info->chain( i ) );
192 
193  vector1< core::Real > feature_vals;
194  Size feature_counter( 0 );
195 
196  // is_a, is_c, etc.
197  vector1< bool > is_nt;
198  vector1< std::string > is_nt_tag;
199  for ( Size m = 1; m <= num_nt; m++ ) {
200  is_nt.push_back( rsd.name1() == nt_names[m] );
201  is_nt_tag.push_back( "is_" + std::string(&nt_names[m],1) /* man, converting char to string is a pain!*/ );
202  save_feature( feature_names, feature_vals, feature_counter, is_nt_tag[m], is_nt[m] );
203  }
204 
205  // look for O2' in WC sector -- probably explains rest of DMS protections. Note that this is general, so
206  // perhaps should not be in a dms_low_resolution_potential, but instead in an rna_base_pair_info object?
207  bool wc_near_o2prime = rna_dms_low_resolution_potential.get_wc_near_o2prime( pose, i );
208 
209  // probably makes sense to explicitly take product with is_a, etc. above -- in case classifier is not
210  // smart about leveraging products of features.
211  for ( Size m = 1; m <= num_nt; m++ ) {
212  save_feature( feature_names, feature_vals, feature_counter, is_nt_tag[m]+ "_and_wc_edge_paired" ,
213  rna_dms_low_resolution_potential.wc_edge_paired()[i] * is_nt[m] );
214  save_feature( feature_names, feature_vals, feature_counter, is_nt_tag[m]+ "_and_hoog_edge_paired" ,
215  rna_dms_low_resolution_potential.hoog_edge_paired()[i] * is_nt[m]);
216  save_feature( feature_names, feature_vals, feature_counter, is_nt_tag[m]+ "_and_sugar_edge_paired",
217  rna_dms_low_resolution_potential.sugar_edge_paired()[i] * is_nt[m]);
218  save_feature( feature_names, feature_vals, feature_counter, is_nt_tag[m]+ "_and_is_bulged",
219  rna_dms_low_resolution_potential.is_bulged()[i] * is_nt[m] );
220  save_feature( feature_names, feature_vals, feature_counter, is_nt_tag[m]+ "_and_wc_near_o2prime" , wc_near_o2prime * is_nt[m] );
221  save_feature( feature_names, feature_vals, feature_counter, is_nt_tag[m]+ "_and_wc_edge_paired_or_near_o2prime",
222  ( wc_near_o2prime || rna_dms_low_resolution_potential.wc_edge_paired()[i] ) * is_nt[m] );
223  }
224 
225 
226  // What is hydrogen bonded?
227  bool ade_n1_hbonded = is_nt[1] && rna_dms_potential.check_hbonded( pose, i, " N1 ", true /*acceptor*/ );
228 
229  for ( Size m = 1; m <= num_nt; m++ ) {
230 
231  // need an instance of this nucleotide to play around with.
232  // This better have RNA residue types in it.
233  ResidueTypeSet const & rsd_set = *rsd.residue_type_set();
234  ResidueType const & rsd_type = *( rsd_set.get_representative_type_aa( core::chemical::aa_from_oneletter_code( nt_names[m] ) ) );
235 
236  // what is hydrogen bonded? Acceptors.
237  AtomIndices accpt_pos = rsd_type.accpt_pos();
238  for ( Size k = 1; k <= accpt_pos.size(); k++ ) {
239  std::string atom_name = rsd_type.atom_name( accpt_pos[ k ] );
240  bool hbonded = is_nt[m] && rna_dms_potential.check_hbonded( pose, i, atom_name, true /*acceptor*/ );
241  ObjexxFCL::strip_whitespace(atom_name);
242  save_feature( feature_names, feature_vals, feature_counter, is_nt_tag[m]+ "_and_"+atom_name+"_hbonded", hbonded);
243 
244  // special for DMS
245  if ( m==1 ) save_feature( feature_names, feature_vals, feature_counter, is_nt_tag[m]+ "_and_"+atom_name+"_hbonded"+"_and_N1_hbonded", hbonded && ade_n1_hbonded);
246  }
247 
248  if ( m == 1 ) {
249  bool ade_n1_chbonded( false );
250  if ( is_nt[1] ) ade_n1_chbonded = rna_dms_potential.check_chbonded( pose, i, " N1 " );
251  save_feature( feature_names, feature_vals, feature_counter, is_nt_tag[m]+"_and_N1_chbonded", ade_n1_chbonded );
252  save_feature( feature_names, feature_vals, feature_counter, is_nt_tag[m]+"_and_N1_hbonded_or_chbonded",
253  ade_n1_chbonded || ade_n1_hbonded );
254  }
255 
256 
257  // what is hydrogen bonded? Donor hydrogens.
258  AtomIndices Hpos_polar = rsd_type.Hpos_polar();
259  for ( Size k = 1; k <= Hpos_polar.size(); k++ ) {
260  std::string atom_name = rsd_type.atom_name( Hpos_polar[ k ] );
261  bool hbonded = is_nt[m] && rna_dms_potential.check_hbonded( pose, i, atom_name, false /*acceptor --> check for polar hydrogen names*/ );
262  ObjexxFCL::strip_whitespace(atom_name);
263  save_feature( feature_names, feature_vals, feature_counter, is_nt_tag[m]+ "_and_"+atom_name+"_hbonded", hbonded);
264 
265  // special for DMS
266  if ( m==1 ) save_feature( feature_names, feature_vals, feature_counter, is_nt_tag[m]+ "_and_"+atom_name+"_hbonded"+"_and_N1_hbonded", hbonded && ade_n1_hbonded);
267  }
268  }
269 
270 
271  //sasa
272  for ( Size m = 1; m <= num_nt; m++ ) {
273 
274  // need an instance of this nucleotide to play around with.
275  // This better have RNA residue types in it.
276  ResidueTypeSet const & rsd_set = *rsd.residue_type_set();
277  ResidueType const & rsd_type = *( rsd_set.get_representative_type_aa( core::chemical::aa_from_oneletter_code( nt_names[m] ) ) );
278  for ( Size k = 1; k <= rsd_type.nheavyatoms(); k++ ) {
279  std::string atom_name = rsd_type.atom_name( k );
280  core::Real sasa_value = 0.0;
281  if ( rsd.type().has( atom_name ) ) {
282  AtomID atom_id = pose::named_atom_id_to_atom_id( NamedAtomID( atom_name, i ), pose );
283  sasa_value = atom_sasa[ atom_id ];
284  }
285  ObjexxFCL::strip_whitespace(atom_name);
286  save_feature( feature_names, feature_vals, feature_counter, is_nt_tag[m]+ "_and_"+atom_name+"_SASA", sasa_value);
287  }
288  }
289 
290  // chi, delta
291  for ( Size m = 1; m <= num_nt; m++ ) {
292  core::Real chi = is_nt[m] ? pose.chi( i ) : 0.0;
293  save_feature( feature_names, feature_vals, feature_counter, is_nt_tag[m]+"_and_chi", chi);
294  save_feature( feature_names, feature_vals, feature_counter, is_nt_tag[m]+"_and_is_syn", (chi < 0.0) );
295  }
296  for ( Size m = 1; m <= num_nt; m++ ) {
297  core::Real delta = is_nt[m] ? pose.delta( i ) : 0.0;
298  save_feature( feature_names, feature_vals, feature_counter, is_nt_tag[m]+"_and_delta", delta);
299  save_feature( feature_names, feature_vals, feature_counter, is_nt_tag[m]+"_and_is_south", ( delta > 120.0) );
300  }
301 
302  // occlusion of pseudo-methyl at N1 -- towards fitting a potential.
303  utility::vector1< Distance > probe_dists = make_vector1( 0.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.5 );
304  utility::vector1< Distance > const shells = make_vector1( 0.0, 2.0, 4.0, 6.0, 8.0 );
305  //utility::vector1< core::Real > const shells = make_vector1( 0.0, 3.0, 6.0, 9.0 );
306  for ( Size m = 1; m <= probe_dists.size(); m++ ) {
307  utility::vector1< core::Real > occupancy_densities( (shells.size()-1), 0.0 ); // atoms per A^3.
308  core::Real const probe_dist = probe_dists[ m ];
309  if ( is_nt[ 1 ] ) {
310  core::Vector const probe_xyz = rna_dms_potential.get_probe_xyz( pose.residue( i ), probe_dist );
311  rna_dms_potential.get_occupancy_densities( occupancy_densities, pose, i /*for exclusion*/, probe_xyz, shells );
312  }
313  for ( Size k = 1; k <= occupancy_densities.size(); k++ ) {
314  std::string const tag = is_nt_tag[1]+"_and_pseudomethyldist"+F(3,1,probe_dist)+"_shell_"+I( 1, shells[k] ) + "-" + I( 1, shells[k+1]);
315  save_feature( feature_names, feature_vals, feature_counter, tag, occupancy_densities[k] );
316  }
317  }
318 
319  // actual computation of a potential around pseudo-methyl atom.
320  vector1< ScoreFunctionOP > probe_scorefxns = make_vector1( rna_dms_potential.get_probe_scorefxn( false /* soft_rep*/, false /* just_fa_atr*/ ),
321  rna_dms_potential.get_probe_scorefxn( true, false ),
322  rna_dms_potential.get_probe_scorefxn( true, true ) );
323  vector1< std::string > scorefxntags = make_vector1( "hard", "soft", "justatrrep_soft" );
324  for ( Size k = 1; k <= probe_scorefxns.size(); k++ ) {
325  core::Real pseudo_methyl_plus_oxygen_energy( 0 );
326  for ( Size m = 1; m <= probe_dists.size(); m++ ) {
327  core::Real const probe_dist = probe_dists[ m ];
328  core::Real binding_energy( 0.0 );
329  if ( is_nt[ 1 ] ) {
330  core::Vector const probe_xyz = rna_dms_potential.get_probe_xyz( pose.residue( i ), probe_dist );
331  binding_energy = rna_dms_potential.get_binding_energy( i, probe_xyz, *probe_scorefxns[k] );
332  }
333  if ( probe_dist == 3.5 || probe_dist == 5.5 ) pseudo_methyl_plus_oxygen_energy += binding_energy;
334  std::string const tag = is_nt_tag[1]+"_and_pseudomethyldist"+F(3,1,probe_dist)+"_"+scorefxntags[k]+"_energy";
335  if ( is_nt[ 1 ] ) std::cout << pose.pdb_info()->number( i ) << " " << tag << ": " << binding_energy << std::endl; // some output since this takes so long.
336  save_feature( feature_names, feature_vals, feature_counter, tag, binding_energy );
337  }
338 
339  if ( is_nt[ 1 ] ) std::cout << std::endl;
340  std::string const tag = is_nt_tag[1]+"_and_pseudomethyl_plus_oxygen_"+scorefxntags[k]+"_energy";
341  save_feature( feature_names, feature_vals, feature_counter, tag, pseudo_methyl_plus_oxygen_energy );
342  }
343 
344  if ( num_features == 0 ) num_features = feature_counter; // initialize num_features.
345  runtime_assert( feature_vals.size() == num_features ); // sanity check.
346 
347  all_feature_vals.push_back( feature_vals );
348  }
349 
350  runtime_assert( all_feature_vals.size() == res_count );
351 
352  rdat.fill_data_from_features( seqchars, resnums, feature_names, all_feature_vals );
353 
354  return res_count;
355 }
356 
357 
358 ///////////////////////////////////////////////
359 void
361 {
362  using namespace basic::options;
363  using namespace basic::options::OptionKeys;
364  using namespace core::chemical;
365  using namespace core::import_pose;
366 
367  vector1 < std::string> pdb_files( option[ in::file::s ]() );
368  std::string const file_path( option[ in::path::pdb ]( 1 ) );
369 
370  if ( option[ in::file::l ].user() ) {
371 
372  std::string const pdb_list( option[ in::file::l ](1) );
373  utility::io::izstream instream( pdb_list );
374  if ( !instream ) {
375  std::cerr << "Can't find list file " << pdb_list << std::endl;
376  utility::exit( EXIT_FAILURE, __FILE__, __LINE__);
377  //return;
378  }
379 
380  pdb_files.clear();
381  std::string pdb_file, line;
382  while ( getline( instream, line ) ) {
383  std::istringstream line_stream( line );
384  line_stream >> pdb_file;
385  pdb_files.push_back( pdb_file );
386  }
387 
388  }
389 
390  // later hope to replace this with fa_standard, which should soon include RNA, DNA, & protein.
391  ResidueTypeSetCOP rsd_set = core::chemical::ChemicalManager::get_instance()->residue_type_set( "fa_standard" );
392 
393  Size count( 0 );
394  std::string outfile;
396  Size total_residues( 0 );
397 
398  for ( Size n = 1; n <= pdb_files.size(); n++ ) {
399 
400  std::string const pdb_file = pdb_files[n];
401 
402  std::string pdb_file_load = pdb_file;
403  if ( file_path != "./" ) pdb_file_load = file_path + '/' + pdb_file;
404  pose_from_pdb( pose, *rsd_set, pdb_file_load );
405 
406  count++;
407  std::cout << "Doing input file " << I(4,count) << " ==> " << pdb_file << std::endl;
408  std::cout << "Read in pose sequence: " << pose.annotated_sequence() << std::endl;
409  pose.dump_pdb( "dump.pdb" );
410 
411  if ( option[out::file::o].user() ) outfile = option[ out::file::o ];
412  else outfile = pdb_file + ".rdat";
413 
414  io::rna::RDAT rdat;
415  rdat.fill_header_information( pose );
416  total_residues += rna_features_from_pose( rdat, pose );
417  rdat.output_rdat_to_file( outfile );
418 
419  }
420 
421  std::cout << "FINISHED ==> TOTAL RESIDUES Processed: " << total_residues << std::endl;
422 
423 }
424 
425 
426 ///////////////////////////////////////////////////////////////
427 void*
428 my_main( void* )
429 {
430  rhiju_pdbstats();
431  protocols::viewer::clear_conformation_viewers();
432  exit( 0 );
433 }
434 
435 
436 ///////////////////////////////////////////////////////////////////////////////
437 int
438 main( int argc, char * argv [] )
439 {
440 
441  try {
442  using namespace basic::options;
443 
444  core::init::init(argc, argv);
445 
446  protocols::viewer::viewer_main( my_main );
447 
448  } catch ( utility::excn::EXCN_Base const & e ) {
449  std::cout << "caught exception " << e.msg() << std::endl;
450  return -1;
451  }
452 
453 }
ocstream cerr(std::cerr)
Wrapper around std::cerr.
Definition: ocstream.hh:290
virtual std::string const msg() const
Definition: EXCN_Base.hh:70
void exit(std::string const &file, int const line, std::string const &message, int const status)
Exit with file + line + message + optional status.
Definition: exit.cc:108
void rhiju_pdbstats()
std::string & strip_whitespace(std::string &s)
Strip Whitespace from a string's Tails.
std::istream & getline(std::istream &stream, Fstring &s)
Get Line from Stream.
Definition: Fstring.cc:1610
BooleanOptionKey const user("options:user")
Definition: OptionKeys.hh:40
void save_feature(vector1< std::string > &feature_names, vector1< core::Real > &feature_vals, Size &feature_counter, std::string const &feature_name, core::Real const feature_val)
core::pose::Pose Pose
Definition: supercharge.cc:101
void * my_main(void *)
#define runtime_assert(_Expression)
Assert that the condition holds. Evaluated for both debug and release builds.
Definition: exit.hh:63
Conversions between degrees and radians.
Fast 3x3 matrix.
Functions for opening database files.
xyzVector< Real > Vector
izstream: Input file stream wrapper for uncompressed and compressed files
Definition: izstream.hh:44
Input file stream wrapper for uncompressed and compressed files.
std::vector with 1-based indexing
Definition: vector1.fwd.hh:44
File name class supporting Windows and UN*X/Linux format names.
rule< Scanner, options_closure::context_t > options
Definition: Tag.cc:377
Output file stream wrapper for uncompressed and compressed files.
double Real
Definition: types.hh:39
static char * line
Definition: Svm.cc:2683
std::string F(int const w, int const d, float const &t)
Fixed Point Format: float.
Definition: format.cc:387
numeric::xyzMatrix< core::Real > Matrix
ocstream cout(std::cout)
Wrapper around std::cout.
Definition: ocstream.hh:287
BooleanOptionKey const exit("options:exit")
Definition: OptionKeys.hh:51
vector1: std::vector with 1-based indexing
xyzMatrix: Fast 3x3 xyz matrix template
Common numeric constants in varying precisions.
xyzVector and xyzMatrix functions
void init()
set global 'init_was_called' to true
Definition: init.cc:26
Program options global and initialization function.
rule< Scanner, tag_closure::context_t > tag
Definition: Tag.cc:373
Size rna_features_from_pose(core::io::rna::RDAT &rdat, pose::Pose &pose)
Fast (x,y,z)-coordinate numeric vector.
std::string I(int const w, T const &t)
Integer Format.
Definition: format.hh:758
platform::Size Size
Definition: random.fwd.hh:30
utility::vector1< T > make_vector1(const T i0)
Definition: make_vector1.hh:24
std::set< char > chains
rule< Scanner, option_closure::context_t > option
Definition: Tag.cc:378