Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RigidLigandBuilder.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/match/downstream/RigidLigandBuilder.cc
12 /// @brief
13 /// @author Alex Zanghellini (zanghell@u.washington.edu)
14 /// @author Andrew Leaver-Fay (aleaverfay@gmail.com), porting to mini
15 /// @author Florian Richter (floric@u.washington.edu)
16 
17 /// Unit headers
19 
20 /// Package headers
25 
26 // Project headers
28 #include <core/pose/Pose.hh>
29 #include <core/pose/PDBInfo.hh>
31 #include <basic/Tracer.hh>
32 
33 // ObjexxFCL headers
34 // AUTO-REMOVED #include <ObjexxFCL/FArray2D.hh>
35 
36 // Utility headers
37 // AUTO-REMOVED #include <utility/vector1.functions.hh>
38 
40 #include <core/id/AtomID.hh>
41 #include <protocols/match/Hit.hh>
42 #include <utility/vector1.hh>
43 
44 
45 namespace protocols {
46 namespace match {
47 namespace downstream {
48 
49 static basic::Tracer TR( "protocols.match.downstream.RigidLigandBuilder" );
50 
52  parent(),
53  ignore_h_collisions_( false )
54 {
55  //TR << "Initializing RigidLigandBuilder." << std::endl;
56 }
57 
59  parent( other ),
60  downstream_restype_( other.downstream_restype_ ),
61  upstream_restype_( other.upstream_restype_ ),
62  ignore_h_collisions_( other.ignore_h_collisions_ ),
63  orientation_atoms_( other.orientation_atoms_ ),
64  atoms_123_( other.atoms_123_ ),
65  radii_123_( other.radii_123_ ),
66  atom_radii_( other.atom_radii_ ),
67  atom_required_in_active_site_( other.atom_required_in_active_site_ ),
68  non_collision_detection_atoms_reqd_in_active_site_( other.non_collision_detection_atoms_reqd_in_active_site_ ),
69  lig_conformers_( other.lig_conformers_.size() ),
70  min_sep_d2_from_upstream_atoms_( other.min_sep_d2_from_upstream_atoms_ )
71 {
72  for ( Size ii = 1; ii <= lig_conformers_.size(); ++ii ) {
74  }
75 }
76 
77 //RigidLigandBuilder::RigidLigandBuilder( RigidLigandBuilder const & other, core::chemical::ResidueTypeCOP upstream_restype ) :
78 // parent(other),
79 // downstream_restype_( other.downstream_restype_ ),
80 // upstream_restype_( upstream_restype ),
81 // ignore_h_collisions_( other.ignore_h_collisions_ ),
82 // atom_radii_( other.atom_radii_ ),
83 // atom_required_in_active_site_( other.atom_required_in_active_site_ ),
84 // non_collision_detection_atoms_reqd_in_active_site_( other.non_collision_detection_atoms_reqd_in_active_site_ ),
85 // lig_conformers_( other.lig_conformers_.size() )
86 //{
87 // for ( Size ii = 1; ii <= lig_conformers_.size(); ++ii ) {
88 // lig_conformers_[ ii ] = new LigandConformer( * other.lig_conformers_[ ii ] );
89 // //TR << "natoms " << lig_conformers_[ii]->n_collision_check_atoms() << std::endl;
90 // }
91 //
92 // initialize_upstream_residue( upstream_restype );
93 //}
94 
95 
97 
100 {
101  return new RigidLigandBuilder( *this );
102 }
103 
104 
105 std::list< Hit >
107  HTReal const & atom3_frame,
108  Size const scaffold_build_point_id,
109  Size const upstream_conf_id,
110  Size const external_geometry_id,
111  core::conformation::Residue const & upstream_residue
112 ) const
113 {
114  assert( downstream_restype_ );
115  assert( upstream_restype_ );
116  assert( bbgrid_set() );
117  assert( (& upstream_residue.type()) == upstream_restype_.get() );
118 
119  std::list< Hit > hitlist;
120 
121  //std::cout << "RigidLigandBuilder::build" << std::endl;
122  //for ( Size ii = 1; ii <= 3; ++ii ) {
123  //Vector const iiloc = atom3_frame * ats123_in_atom3_frame_[ ii ];
124  //std::cout << "Atom D" << ii << " coordinate: " << iiloc.x() << " " << iiloc.y() << " " << iiloc.z() << std::endl;
125  //}
126 
127  /// collision detection and active-site containment enforcement.
128  for ( Size ii = 1; ii <= lig_conformers_[1]->n_collision_check_atoms(); ++ii ) {
129  Size ii_restype_id = lig_conformers_[1]->collision_check_id_2_restype_id( ii );
130 
131  Vector const iiloc = lig_conformers_[1]->coordinate_in_D3_frame( ii_restype_id, atom3_frame );
132  //std::cout << " " << downstream_restype_->atom_name( at3_frame_id_2_restype_id_[ ii ] ) << " ";
133  //std::cout << iiloc.x() << " " << iiloc.y() << " " << iiloc.z() << std::endl;
134  if ( atom_radii_[ ii_restype_id ] > ZERO && bbgrid().occupied( atom_radii_[ ii_restype_id ], iiloc ) ) {
135  return hitlist;
136  }
137  if ( atom_required_in_active_site_[ ii_restype_id ] && ! active_site_grid().occupied( iiloc ) ) {
138  return hitlist;
139  }
140 
141  for ( Size jj = 1; jj <= min_sep_d2_from_upstream_atoms_[ ii_restype_id ].size(); ++jj ) {
142  if ( iiloc.distance_squared( upstream_residue.xyz( min_sep_d2_from_upstream_atoms_[ ii_restype_id ][ jj ].first ))
143  < min_sep_d2_from_upstream_atoms_[ ii_restype_id ][ jj ].second ) {
144  //std::cout << "collision between " << downstream_restype_->atom_name( at3_frame_id_2_restype_id_[ ii ] );
145  //std::cout << " on " << downstream_restype_->name() << " with ";
146  //std::cout << upstream_restype_->atom_name( min_sep_d2_from_upstream_atoms_[ ii ][ jj ].first ) << " on " << upstream_restype_->name() << std::endl;
147  return hitlist;
148  }
149  }
150  }
151 
152  /// Check the atoms we require to be in the active site, but which are not used in
153  /// collision detection
154  for ( Size ii = 1; ii <= non_collision_detection_atoms_reqd_in_active_site_.size(); ++ii ) {
156  Vector const iiloc = lig_conformers_[1]->coordinate_in_D3_frame( ii_restype_id, atom3_frame );
157 
158  if ( ! active_site_grid().occupied( iiloc ) ) {
159  return hitlist;
160  }
161  }
162 
163  Real6 global_coordinate = lig_conformers_[1]->global_orientation_from_frame3( atom3_frame );
164 
165  /// Check, if we're past the first round of hit building, that this orientation's
166  /// bin in 6D is not empty. If the bin is empty, then there is no way this
167  /// ligand placement could result in a match. Do not return this orientation as a hit.
168  //std::cout << "global coordinate: ";
169  //for ( Size ii = 1; ii <= 6; ++ii ) { std::cout << global_coordinate[ ii ] << " ";}
170  //std::cout << std::endl;
171 
172  if ( occ_space_set() && ! occ_space().match_possible_for_hit_geometry( global_coordinate ) ) {
173  return hitlist;
174  }
175 
176  /// We have a hit!
177  //std::cout << "HIT!" << std::endl;
178 
179  Hit hit;
180  hit.first()[ 1 ] = scaffold_build_point_id;
181  hit.first()[ 2 ] = upstream_conf_id;
182  hit.first()[ 3 ] = external_geometry_id;
183  hit.first()[ 4 ] = 1; // my state is always 1
184  hit.second() = global_coordinate;
185 
186 
187  hitlist.push_back( hit ); /// new called here -- otherwise, nothing has been allocated on the heap since the Dunbrack rotamers
188 
189  return hitlist;
190 }
191 
192 void
194  BumpGridCOP bbgrid
195 )
196 {
197  parent::set_bb_grid( bbgrid );
198  if ( upstream_restype_ ) {
200  }
201 }
202 
203 bool
205  Hit const & my_hit,
206  DownstreamBuilder const & other,
207  Hit const & other_hit,
208  bool //first_dispatch
209 ) const
210 {
211  return other.compatible( other_hit, *this, my_hit, false );
212 }
213 
214 /// @details RigidLigandBuilder hits are always compatible, because there is only
215 /// one ligand conformation.
216 bool
218  Hit const &, // my_hit,
219  RigidLigandBuilder const &,// other,
220  Hit const &,// other_hit,
221  bool// first_dispatch
222 ) const
223 {
224  return true;
225 }
226 
227 
228 void
230  core::id::AtomID const & id
231 )
232 {
233  runtime_assert( id.rsd() == 1 );
234  runtime_assert( id.atomno() < downstream_restype_->natoms() );
235  if ( lig_conformers_[1]->restype_id_2_collision_check_id( id.atomno() ) == 0 ) {
237  } else {
238  atom_required_in_active_site_[ id.atomno() ] = true;
239  for ( Size ii = 1; ii <= 3; ++ii ) {
240  if ( atoms_123_[ ii ] == id.atomno() ) {
241  ats123_reqd_in_active_site_[ ii ] = true;
242  break;
243  }
244  }
245  }
246 }
247 
250 {
251  assert( downstream_restype_ );
252  //return ZERO;
253  return radii_123_[ 1 ];
254 }
255 
256 
259 {
260  assert( downstream_restype_ );
261  return radii_123_[ 2 ];
262 }
263 
264 
267 {
268  assert( downstream_restype_ );
269  return radii_123_[ 3 ];
270 }
271 
272 
273 bool
275 {
276  return ats123_reqd_in_active_site_[ 1 ];
277 }
278 
279 bool
281 {
282  return ats123_reqd_in_active_site_[ 2 ];
283 }
284 
285 bool
287 {
288  return ats123_reqd_in_active_site_[ 3 ];
289 }
290 
293 {
294  assert( downstream_restype_ );
295  return lig_conformers_[1]->atom1_atom2_distance();
296 }
297 
298 
301 {
302  assert( downstream_restype_ );
303  return lig_conformers_[1]->atom2_atom3_distance();
304 }
305 
306 /// @brief Returns an angle in degrees between the three downstream atoms.
307 
310 {
311  assert( downstream_restype_ );
312  return lig_conformers_[1]->atom1_atom2_atom3_angle();
313 }
314 
315 
316 void
318  Hit const & hit,
319  utility::vector1< AtomID > const & atom_indices,
320  utility::vector1< Vector > & atom_coords
321 ) const
322 {
323  /*HTReal global_frame = frame_from_global_orientation( hit.second() );
324  for ( Size ii = 1; ii <= atom_indices.size(); ++ii ) {
325  assert( atom_indices[ ii ].rsd() == 1 );
326  atom_coords[ ii ] = global_frame * points_in_global_orintation_frame_[ atom_indices[ ii ].atomno() ];
327  }*/
328  lig_conformers_[1]->coordinates_from_orientation( hit.second(), atom_indices, atom_coords );
329 }
330 
331 
332 
335  Hit const & hit
336 ) const
337 {
338 
340 
341  HTReal global_frame = lig_conformers_[1]->frame_from_global_orientation( hit.second() );
342  for ( Size ii = 1; ii <= lig_res.natoms(); ++ii ) {
343  lig_res.set_xyz( ii, lig_conformers_[1]->coordinate_in_global_frame( ii, global_frame ) );
344  }
345 
347  pose->append_residue_by_jump( lig_res, 1 );
348 
349  //we should also set a different chain for the downstream pose
350  core::pose::PDBInfoOP pdbinf = new core::pose::PDBInfo( *pose );
351  pose->pdb_info( pdbinf );
352  pose->pdb_info()->chain( 1, 'X' );
353 
354  return pose;
355 
356 }
357 
360 {
361  return 1;
362 }
363 
364 
365 
366 void
368  Size atom1,
369  Size atom2,
370  Size atom3,
371  Size orientation_atom1,
372  Size orientation_atom2,
373  Size orientation_atom3,
374  core::conformation::Residue const & residue
375 )
376 {
377  atoms_123_[ 1 ] = atom1;
378  atoms_123_[ 2 ] = atom2;
379  atoms_123_[ 3 ] = atom3;
380 
381  orientation_atoms_[ 1 ] = orientation_atom1;
382  orientation_atoms_[ 2 ] = orientation_atom2;
383  orientation_atoms_[ 3 ] = orientation_atom3;
384 
385  Size const natoms = residue.natoms();
386  if ( natoms < 3 ) {
387  utility_exit_with_message( "ERROR in RigidLigandBuilder: cannot build a residue with fewer than three atoms" );
388  }
389  downstream_restype_ = & residue.type();
390  atom_radii_.resize( natoms );
391  atom_required_in_active_site_.resize( natoms, false );
392 
393  for ( Size ii = 1; ii <= natoms; ++ii ) {
394  atom_radii_[ ii ] = probe_radius_for_atom_type( residue.atom( ii ).type() );
395  }
396 
398  lig_conformers_[1]->ignore_h_collisions( ignore_h_collisions_ );
399  lig_conformers_[1]->initialize_from_residue( atom1, atom2, atom3,
400  orientation_atom1, orientation_atom2, orientation_atom3, residue );
401 
402  for ( Size ii = 1; ii <= 3; ++ii ) {
403  if ( ignore_h_collisions_ && residue.atom_type( atoms_123_[ ii ] ).element() == "H" ) {
404  radii_123_[ ii ] = ZERO;
405  } else {
406  radii_123_[ ii ] = probe_radius_for_atom_type( residue.atom( atoms_123_[ ii ] ).type() );
407  }
408  }
409 }
410 
411 void
413  core::chemical::ResidueTypeCOP upstream_res,
415 )
416 {
417  assert( downstream_restype_ );
418  assert( upstream_res );
419 
420  upstream_restype_ = upstream_res;
421 
422  Size const natoms = downstream_restype_->natoms();
423 
425  min_sep_d2_from_upstream_atoms_.resize( natoms );
426 
427  for ( Size ii = 1; ii <= lig_conformers_[1]->n_collision_check_atoms(); ++ii ) {
428  Size ii_restype_id = lig_conformers_[1]->collision_check_id_2_restype_id( ii );
429 
430  Size n_to_count( 0 );
431  for ( Size jj = upstream_restype_->first_sidechain_atom();
432  jj <= upstream_restype_->nheavyatoms(); ++jj ) {
433  Real weight( 1.0 );
434  Size path_dist( 0 );
435  if ( ! count_pair || ( count_pair->count( jj, ii_restype_id, weight, path_dist ) && weight == 1.0 ) ) {
436  ++n_to_count;
437  //std::cout << "Bump check " << downstream_restype_->atom_name( ii_restype_id );
438  //std::cout << " on " << downstream_restype_->name() << " with ";
439  //std::cout << upstream_restype_->atom_name( jj ) << " on " << upstream_restype_->name() << std::endl;
440  }
441  }
442  /// Now make sure that if we're within count-pair striking distance of the backbone so that we don't
443  /// reject a conformation due to this atom as registering a collision in bump_grid.occupied()
444  for ( Size jj = 1; jj < upstream_restype_->first_sidechain_atom(); ++jj ) {
445  if ( jj > upstream_restype_->natoms() ) break;
446  Real weight( 1.0 );
447  Size path_dist( 0 );
448  if ( count_pair && ( ! count_pair->count( jj, ii_restype_id, weight, path_dist ) || weight != 1.0 )) {
449  /// WITHIN STRIKING DISTANCE OF BACKBONE! DO NOT COLLISON-CHECK THIS ATOM
450  atom_radii_[ ii_restype_id ] = ZERO;
451  }
452  }
453  min_sep_d2_from_upstream_atoms_[ ii_restype_id ].resize( n_to_count );
454  n_to_count = 0;
455  for ( Size jj = upstream_restype_->first_sidechain_atom();
456  jj <= upstream_restype_->nheavyatoms(); ++jj ) {
457  Real weight( 1.0 );
458  Size path_dist( 0 );
459  if ( ! count_pair || ( count_pair->count( jj, ii_restype_id, weight, path_dist ) && weight == 1.0 ) ) {
460  min_sep_d2_from_upstream_atoms_[ ii_restype_id ][ ++n_to_count ].first = jj;
461  }
462  }
463  }
464 
465  /// Now check atoms D1, D2, and D3 and makes sure they are not within striking distance of the backbone
466  /// If they are, then set their radii to ZERO
467  for ( Size ii = 1; ii <= 3; ++ii ) {
468  if ( count_pair ) {
469  Size ii_id = atoms_123_[ ii ];
470  for ( Size jj = 1; jj < upstream_restype_->first_sidechain_atom(); ++jj ) {
471  Real weight( 1.0 );
472  Size path_dist( 0 );
473  if ( ! count_pair->count( jj, ii_id, weight, path_dist ) || weight != 1.0 ) {
474  radii_123_[ ii ] = ZERO;
475  break;
476  }
477  }
478  }
479  }
480 
481  if ( bbgrid_set() ) {
483  }
484 
485  //if ( count_pair ) {
486  // for ( Size ii = 1; ii <= upstream_restype_->n_
487  //}
488 }
489 
490 /*Real6
491 RigidLigandBuilder::global_orientation_from_frame3(
492  HTReal const & frame3
493 ) const
494 {
495  HTReal global_frame = frame3 * oframe_in_at3frame_;
496  //std::cout.precision( 12 );
497  //std::cout << "Global frame" << std::endl;
498  //std::cout << " " << global_frame.xx() << " " << global_frame.yx() << " " << global_frame.zx() << " " << global_frame.px() << std::endl;
499  //std::cout << " " << global_frame.xy() << " " << global_frame.yy() << " " << global_frame.zy() << " " << global_frame.py() << std::endl;
500  //std::cout << " " << global_frame.xz() << " " << global_frame.yz() << " " << global_frame.zz() << " " << global_frame.pz() << std::endl;
501  //std::cout.precision( 6 );
502 
503  Vector euler_angles = global_frame.euler_angles_deg();
504  for ( Size ii = 1; ii <= 3; ++ii ) if ( euler_angles( ii ) < 0 ) euler_angles( ii ) += 360.0;
505  Vector oat3_coords = global_frame.point(); //frame3 * points_in_at3_frame_[ restype_id_2_at3_frame_id_[ orientation_atoms_[ 3 ]]];
506 
507  Real6 global_coords;
508  global_coords[ 1 ] = oat3_coords( 1 );
509  global_coords[ 2 ] = oat3_coords( 2 );
510  global_coords[ 3 ] = oat3_coords( 3 );
511  global_coords[ 4 ] = euler_angles( 1 );
512  global_coords[ 5 ] = euler_angles( 2 );
513  global_coords[ 6 ] = euler_angles( 3 );
514 
515 
516 
517  if ( false ) {
518 
519  Vector oat1_coord = frame3 * oats_in_at3_frame_[ 1 ];
520  Vector oat2_coord = frame3 * oats_in_at3_frame_[ 2 ];
521  Vector oat3_coord = frame3 * oats_in_at3_frame_[ 3 ];
522  HTReal global_frame2( oat1_coord, oat2_coord, oat3_coord );
523  Vector euler_angles2 = global_frame2.euler_angles_deg();
524  std::cout << "Euler angle comparison.";
525  std::cout << " 1: " << euler_angles( 1 ) << " vs " << euler_angles2( 1 ) << " ";
526  std::cout << " 2: " << euler_angles( 2 ) << " vs " << euler_angles2( 2 ) << " ";
527  std::cout << " 3: " << euler_angles( 3 ) << " vs " << euler_angles2( 3 ) << std::endl;
528 
529  for ( Size ii = 1; ii <= points_in_atom3_frame_.size(); ++ii ) {
530  Vector ii3loc = frame3 * points_in_atom3_frame_[ ii ];
531  Vector iigloc = global_frame * points_in_global_orintation_frame_[ at3_frame_id_2_restype_id_[ ii ]];
532  for ( Size jj = 1; jj <= 3; ++jj ) {
533  std::cout << ii << " " << jj << " " << ii3loc( jj ) << " " << iigloc( jj ) << std::endl;
534  }
535  }
536 
537  HTReal global_frame3;
538  global_frame3.from_euler_angles_deg( euler_angles );
539  global_frame3.set_point( oat3_coord );
540  //std::cout.precision( 12 );
541  std::cout << "Global frame3" << std::endl;
542  std::cout << " " << global_frame3.xx() << " " << global_frame3.yx() << " " << global_frame3.zx() << " " << global_frame3.px() << std::endl;
543  std::cout << " " << global_frame3.xy() << " " << global_frame3.yy() << " " << global_frame3.zy() << " " << global_frame3.py() << std::endl;
544  std::cout << " " << global_frame3.xz() << " " << global_frame3.yz() << " " << global_frame3.zz() << " " << global_frame3.pz() << std::endl;
545  //std::cout.precision( 6 );
546  }
547 
548  return global_coords;
549 }
550 
551 RigidLigandBuilder::HTReal
552 RigidLigandBuilder::frame_from_global_orientation(
553  Real6 orientation
554 ) const
555 {
556  Vector oat3_coord(orientation[ 1 ], orientation[ 2 ], orientation[ 3 ] );
557  Vector euler_deg( orientation[ 4 ], orientation[ 5 ], orientation[ 6 ] );
558 
559  //std::cout << "oat3_coord: " << oat3_coord(1) << " " << oat3_coord(2) << " " << oat3_coord(3) << std::endl;
560  //std::cout << "euler_deg: " << euler_deg(1) << " " << euler_deg(2) << " " << euler_deg(3) << std::endl;
561 
562  HTReal oframe;
563 
564  oframe.from_euler_angles_deg( euler_deg );
565  oframe.set_point( oat3_coord );
566 
567  //std::cout.precision( 12 );
568  //std::cout << "Global frame" << std::endl;
569  //std::cout << " " << oframe.xx() << " " << oframe.yx() << " " << oframe.zx() << " " << oframe.px() << std::endl;
570  //std::cout << " " << oframe.xy() << " " << oframe.yy() << " " << oframe.zy() << " " << oframe.py() << std::endl;
571  //std::cout << " " << oframe.xz() << " " << oframe.yz() << " " << oframe.zz() << " " << oframe.pz() << std::endl;
572  //std::cout.precision( 6 );
573 
574  //Vector euler_deg2 = oframe.euler_angles_deg();
575  //std::cout << "reverse euler angles: " << euler_deg2(1) << " " << euler_deg2(2) << " " << euler_deg2(3) << std::endl;
576 
577  return oframe;
578 }
579 */
580 
581 void
583 {
584  if ( downstream_restype_ != 0 ) {
585  utility_exit_with_message( "ERROR: ignore_h_collisions_ must be set before the downstream restype is initialized" );
586  } else {
587  ignore_h_collisions_ = setting;
588  }
589 }
590 
591 
592 void
594 {
595  assert( bbgrid_set() );
596  for ( Size ii = 1; ii <= lig_conformers_[1]->n_collision_check_atoms(); ++ii ) {
597  Size ii_restype_id = lig_conformers_[1]->collision_check_id_2_restype_id( ii );
598 
599  ProbeRadius ii_rad = atom_radii_[ ii_restype_id ];
600  for ( Size jj = 1; jj <= min_sep_d2_from_upstream_atoms_[ ii_restype_id ].size(); ++jj ) {
601  Size upstream_atom_id = min_sep_d2_from_upstream_atoms_[ ii_restype_id ][ jj ].first;
602  ProbeRadius jj_rad = probe_radius_for_atom_type( upstream_restype_->atom( upstream_atom_id ).atom_type_index() );
603 
604  Real dis = bbgrid().required_separation_distance( ii_rad, jj_rad );
605  min_sep_d2_from_upstream_atoms_[ ii_restype_id ][ jj ].second = dis*dis;
606  }
607  }
608 
609 }
610 
613 {
614  return lig_conformers_[ conf_id ];
615 }
616 
617 //utility::vector1< utility::vector1< std::pair< core::Size, core::Real > > >
618 //RigidLigandBuilder::get_min_sep_d2_from_upstream_atoms() const
619 //{
620 // return min_sep_d2_from_upstream_atoms_;
621 //}
622 
625 {
626  return upstream_restype_;
627 }
628 
629 
630 }
631 }
632 }