Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SymmData.cc
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:4;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=4 noet:
3 //
4 // This file is made available under the Rosetta Commons license.
5 // See http://www.rosettacommons.org/license
6 // (C) 199x-2007 University of Washington
7 // (C) 199x-2007 University of California Santa Cruz
8 // (C) 199x-2007 University of California San Francisco
9 // (C) 199x-2007 Johns Hopkins University
10 // (C) 199x-2007 University of North Carolina, Chapel Hill
11 // (C) 199x-2007 Vanderbilt University
12 
13 /// @brief Class to store symmetry data specified from input files
14 /// @file core/conformation/symmetry/SymmData.cc
15 /// @author Ingemar Andre
16 
17 // Unit headers
21 
22 // Project headers
23 // AUTO-REMOVED #include <core/conformation/Conformation.hh>
24 #include <basic/Tracer.hh>
25 
26 // Numeric headers
27 #include <numeric/xyz.functions.hh>
28 #include <numeric/xyz.io.hh>
29 #include <numeric/xyzTransform.hh>
30 
31 // C++ headers
32 #include <iostream>
33 
34 // Utility header
35 // AUTO-REMOVED #include <utility/io/izstream.hh>
36 #include <utility/string_util.hh>
37 
38 #include <utility/vector1.hh>
39 #include <fstream>
40 #include <iostream>
41 #include <iomanip>
42 
43 //Auto Headers
44 #include <core/kinematics/Jump.hh>
45 
46 // @details: This data structure contains all data necessary to generate a
47 // symmetrical system, score it and move it. It is used to initialize the
48 // SymmetryInfo object in SymmetricalConformation that carries the symmetry
49 // information pose need.
50 
51 namespace core {
52 namespace conformation {
53 namespace symmetry {
54 
55 using std::map;
56 using std::endl;
57 using std::string;
58 using std::pair;
59 using std::make_pair;
60 using std::vector;
61 using utility::vector1;
62 typedef numeric::xyzTransform<Real> Xform;
65 
66 //typedef vector1< Size > Clones;
67 
69 
70 static basic::Tracer TR("core.conformation.symmetry.SymmData");
71 
72 static std::string const NOPARENT = "NOPARENT";
73 
74 // @define: constructor
76  utility::pointer::ReferenceCount(),
77  subunits_( 0 ),
78  num_components_( 1 ),
79  interfaces_( 1 ),
80  score_subunit_( 1 ),
81  anchor_residue_( "1" ),
82  recenter_( false ),
83  root_( 1 ),
84  cell_a_(0),
85  cell_b_(0),
86  cell_c_(0),
87  cell_alfa_(0),
88  cell_beta_(0),
89  cell_gamma_(0)
90 {}
91 
92 // @define: constructor
94  utility::pointer::ReferenceCount(),
95  //nres_subunit_( nres ),
96  //njump_subunit_( njump ),
97  subunits_( 0 ),
98  num_components_( 1 ),
99  interfaces_( 1 ),
100  score_subunit_( 1 ),
101  anchor_residue_( "1" ),
102  recenter_( false ),
103  root_( 1 ),
104  cell_a_(0),
105  cell_b_(0),
106  cell_c_(0),
107  cell_alfa_(0),
108  cell_beta_(0),
109  cell_gamma_(0)
110 {}
111 
112 
113 // @define: constructor
114 SymmData::SymmData( SymmData const & src ) :
115  utility::pointer::ReferenceCount(),
116  //nres_subunit_( src.nres_subunit_ ),
117  //njump_subunit_( src.njump_subunit_ ),
118  symmetry_name_( src.symmetry_name_ ),
119  symmetry_type_( src.symmetry_type_ ),
120  subunits_( src.subunits_ ),
121  num_components_( src.num_components_ ),
122  interfaces_( src.interfaces_ ),
123  score_subunit_( src.score_subunit_ ),
124  anchor_residue_( src.anchor_residue_ ),
125  recenter_( src.recenter_ ),
126  root_(src.root_),
127  slide_info_(src.slide_info_),
128  slide_order_string_(src.slide_order_string_),
129  symm_transforms_( src.symm_transforms_ ),
130  rotation_matrices_( src.rotation_matrices_ ),
131  translation_matrices_( src.translation_matrices_ ),
132  virtual_coordinates_( src.virtual_coordinates_ ),
133  jump_string_to_virtual_pair_( src.jump_string_to_virtual_pair_ ),
134  jump_string_to_jump_num_( src.jump_string_to_jump_num_ ),
135  virt_id_to_virt_num_( src.virt_id_to_virt_num_ ),
136  virt_id_to_subunit_num_( src.virt_id_to_subunit_num_ ),
137  virt_id_to_subunit_chain_( src.virt_id_to_subunit_chain_ ),
138  virt_id_to_subunit_residue_( src.virt_id_to_subunit_residue_ ),
139  virt_num_to_virt_id_( src.virt_num_to_virt_id_ ),
140  subunit_num_to_virt_id_( src.subunit_num_to_virt_id_ ),
141  jump_clones_( src.jump_clones_ ),
142  dofs_( src.dofs_ ),
143  allow_virtual_( src.allow_virtual_ ),
144  score_multiply_subunit_( src.score_multiply_subunit_ ),
145  include_subunit_( src.include_subunit_ ),
146  output_subunit_( src.output_subunit_ ),
147  cell_a_(src.cell_a_),
148  cell_b_(src.cell_b_),
149  cell_c_(src.cell_c_),
150  cell_alfa_(src.cell_alfa_),
151  cell_beta_(src.cell_beta_),
152  cell_gamma_(src.cell_gamma_),
153  components_(src.components_),
154  name2component_(src.name2component_),
155  jname2components_(src.jname2components_),
156  jname2subunits_(src.jname2subunits_)
157 {}
158 
159 // @define: deep copy of SymmData
162 {
163  return new SymmData( *this );
164 }
165 
166 // Accessor functions
167 
168 //Size
169 //SymmData::get_nres_subunit() const
170 //{
171  //return nres_subunit_;
172 //}
173 
174 //Size
175 //SymmData::get_njump_subunit() const
176 //{
177  //return njump_subunit_;
178 //}
179 
180 string const &
182 {
183  return symmetry_name_;
184 }
185 
186 string const &
188 {
189  return symmetry_type_;
190 }
191 
194 {
195  return subunits_;
196 }
197 
200 {
201  return num_components_;
202 }
203 
206 {
207  return interfaces_;
208 }
209 
212 {
213  return score_subunit_;
214 }
215 
216 string const &
218 {
219  return anchor_residue_;
220 }
221 
222 bool
224 {
225  return recenter_;
226 }
227 
230 {
231  return root_;
232 }
233 
234 vector1< Size > const &
236 {
238 }
239 
240 vector1< Size > const &
242 {
243  return include_subunit_;
244 }
245 
246 vector1< Size > const &
248 {
249  return output_subunit_;
250 }
251 
252 vector< numeric::xyzMatrix< core::Real > > const &
254 {
255  return rotation_matrices_;
256 }
257 
258 vector< numeric::xyzMatrix< core::Real > > const &
260 {
261  return translation_matrices_;
262 }
263 
264 map< string, VirtualCoordinate > const &
266 {
267  return virtual_coordinates_;
268 }
269 
272 {
273  return virtual_coordinates_.size();
274 }
275 
276 map< Size, SymDof > const &
278 {
279  return dofs_;
280 }
281 
282 map< Size, WtedClones > const &
284 {
285  return jump_clones_;
286 }
287 
288 map< string, Size > const &
290 {
292 }
293 
294 map< string, Size > const &
296 {
297  return virt_id_to_virt_num_;
298 }
299 
300 map< string, Size > const &
302 {
304 }
305 
306 map< string, char > const &
308 {
310 }
311 
312 map< string, string > const &
314 {
316 }
317 
318 map< Size, string > const &
320 {
322 }
323 
324 map< Size, string > const &
326 {
327  return virt_num_to_virt_id_;
328 }
329 
330 map< string, pair< string, string > > const &
332 {
334 }
335 
336 SymSlideInfo const &
338 {
339  return slide_info_;
340 }
341 
344 {
345  return cell_a_;
346 }
347 
350 {
351  return cell_b_;
352 }
353 
356 {
357  return cell_c_;
358 }
359 
362 {
363  return cell_alfa_;
364 }
365 
368 {
369  return cell_beta_;
370 }
371 
374 {
375  return cell_gamma_;
376 }
377 
378 // Set functions
379 //void
380 //SymmData::set_nres_subunit(
381  //Size nres_subunit )
382 //{
383  //nres_subunit_ = nres_subunit;
384 //}
385 
386 //void
387 //SymmData::set_njump_subunit(
388  //Size njump_subunit )
389 //{
390  //njump_subunit_ = njump_subunit;
391 //}
392 
393 void
395  string symm_name )
396 {
397  symmetry_name_ = symm_name;
398 }
399 
400 void
402  string symm_type )
403 {
404  symmetry_type_ = symm_type;
405 }
406 
407 void
409  core::Size num_subunits )
410 {
411 subunits_ = num_subunits;
412 }
413 
414 void
416  core::Size interfaces )
417 {
418 interfaces_ = interfaces;
419 }
420 
421 void
423 {
424  anchor_residue_ = anchor;
425 }
426 
427 void
428 SymmData::set_score_multiply_subunit( vector1< Size > & score_multiply_subunit_vector )
429 {
430  score_multiply_subunit_ = score_multiply_subunit_vector;
431 }
432 
433 void
435 {
436  slide_info_ = slide_info;
437 }
438 
439 void
441  vector< numeric::xyzMatrix< core::Real > > rotation_matrices )
442 {
443  rotation_matrices_ = rotation_matrices;
444 }
445 
446 void
448  vector< numeric::xyzMatrix< core::Real > > translation_matrices )
449 {
450  translation_matrices_ = translation_matrices;
451 }
452 
453 void
455  vector< vector< string> > symm_transforms )
456 {
457  symm_transforms_ = symm_transforms;
458 }
459 
460 void
462  core::Real cell_a )
463 {
464  cell_a_ = cell_a;
465 }
466 
467 void
469  core::Real cell_b )
470 {
471  cell_b_ = cell_b;
472 }
473 
474 void
476  core::Real cell_c )
477 {
478  cell_c_ = cell_c;
479 }
480 
481 void
483  core::Real cell_alfa )
484 {
485  cell_alfa_ = cell_alfa;
486 }
487 
488 void
490 core::Real cell_beta )
491 {
492  cell_beta_ = cell_beta;
493 }
494 
495 void
497  core::Real cell_gamma )
498 {
499  cell_gamma_ = cell_gamma;
500 }
501 
502 
503 // @define: destructor
505 
506 // @define: This function can read symmetry info from a pdb file. It stores all relevant data
507 // but can't do anything useful with it yet...
508 void
510  string filename
511 )
512 {
513  std::ifstream infile( filename.c_str() );
514 
515  if (!infile.good()) {
516  utility_exit_with_message( "[ERROR] Error opening pdb file for symmetry extraction '" + filename + "'" );
517  }
518  string line;
519  int linecount( 0 );
520  int start_symm_matrices( 0 );
521  bool row1_found( false ), row2_found( false ), row3_found( false );
522  numeric::xyzMatrix < Real > smtry_rot;
523  numeric::xyzMatrix < Real > smtry_trans;
524  vector< numeric::xyzMatrix < Real > > smtry_rot_matrices;
525  vector< numeric::xyzMatrix < Real > > smtry_trans_matrices;
526  while( getline(infile,line) ) {
527  linecount++;
528  vector1< string > tokens ( utility::split( line ) );
529 
530  if( tokens.size() > 0 ) {
531  if ( tokens[1] == "REMARK" && tokens[2] == "290" ) {
532  if ( tokens.size() > 7 && tokens[6] == "SPACE" && tokens[7] == "GROUP:" )
533  {
534  string symmetry_name = "";
535  for (Size i=8; i<= tokens.size(); ++i ){
536  symmetry_name += tokens[i];
537  symmetry_name += " ";
538  }
539  }
540  if ( tokens[3] == "SYMOP" ){
541  start_symm_matrices = linecount + 2;
542  }
543  vector1< vector1< string> > matrices;
544  vector1< string> split_vector;
545  if ( linecount >= start_symm_matrices ){
546  split_vector = utility::string_split( tokens[4], ',' );
547  if ( split_vector.size() == 3 ){
548  matrices.push_back( split_vector );
549  }
550  }
551 // for (int i=0; i< matrices.size(); i++){
552 // for ( int j=0; j< matrices[i].size(); ++j){
553 // std::cout << matrices[i][j]<<",";
554 // }
555 // std::cout << endl;
556 // }
557  Vector row1, row2,row3, rowa, rowb, rowc;
558  if ( tokens[3] == "SMTRY1" ){
559  row1 = Vector ( static_cast<core::Real>( std::atof( tokens[5].c_str() ) ),
560  static_cast<core::Real>( std::atof( tokens[6].c_str() ) ),
561  static_cast<core::Real>( std::atof( tokens[7].c_str() ) ) );
562  rowa = Vector ( static_cast<core::Real>( std::atof( tokens[8].c_str() ) ),
563  0.0, 0.0 );
564  row1_found = true;
565  }
566  if ( tokens[3] == "SMTRY2" ){
567  row2 = Vector ( static_cast<core::Real>( std::atof( tokens[5].c_str() ) ),
568  static_cast<core::Real>( std::atof( tokens[6].c_str() ) ),
569  static_cast<core::Real>( std::atof( tokens[7].c_str() ) ) );
570  rowb = Vector ( 0.0, static_cast<core::Real>( std::atof( tokens[8].c_str() ) ),
571  0.0 );
572  row2_found = true;
573  }
574  if ( tokens[3] == "SMTRY3" ){
575  row3 = Vector ( static_cast<core::Real>( std::atof( tokens[5].c_str() ) ),
576  static_cast<core::Real>( std::atof( tokens[6].c_str() ) ),
577  static_cast<core::Real>( std::atof( tokens[7].c_str() ) ) );
578  rowc = Vector ( 0.0, 0.0, static_cast<core::Real>( std::atof( tokens[8].c_str() ) ) );
579  row3_found = true;
580  }
581  if ( row1_found && row2_found && row3_found ){
582  smtry_rot = Matrix::rows( row1, row2, row3 );
583  smtry_trans = Matrix::rows( rowa, rowb, rowc );
584  smtry_rot_matrices.push_back( smtry_rot );
585  smtry_trans_matrices.push_back( smtry_trans );
586  row1_found = row2_found = row3_found = false;
587  }
588  } // End REMARK 290
589  if ( tokens[1] == "CRYST1" && tokens.size() > 7){
590  cell_a_ = static_cast<core::Real>( std::atof( tokens[2].c_str() ) );
591  cell_b_ = static_cast<core::Real>( std::atof( tokens[3].c_str() ) );
592  cell_c_ = static_cast<core::Real>( std::atof( tokens[4].c_str() ) );
593  cell_alfa_ = static_cast<core::Real>( std::atof( tokens[5].c_str() ) );
594  cell_beta_ = static_cast<core::Real>( std::atof( tokens[6].c_str() ) );
595  cell_gamma_ = static_cast<core::Real>( std::atof( tokens[7].c_str() ) );
596  }
597  }
598  }
599 
600 }
601 
602 // @details: Parse symmetry information from a textfile. This function fills all data necessary to generate a
603 // symmetrical system, score it and move it.
604 void
606  string filename
607 )
608 {
609  std::ifstream infile( filename.c_str() );
610 
611  if (!infile.good()) {
612  utility_exit_with_message( "[ERROR] Error opening symmetry file '" + filename + "'" );
613  }
614 
616 }
617 
618 void
620  std::istream & infile
621 )
622 {
623  string line;
624  int linecount( 0 );
625  bool read_virtual_coords (false); // Find out when to start reading virtual coordinates
626  bool read_transforms (false); // Find out when to read symmetry transforms
627  bool start_coordinates_found (false); // Find out when start coordinates are found. Must be used
628  // with read_transform
629  bool have_virtual_coordinates( false );
630  bool read_consecutive_transforms(false);
631  bool read_subunits(false);
632  bool set_jump_numbers_from_tags(true);
633  bool connect_virtuals_specified(false);
634 
635  vector< Matrix > rot_matrix; // store rotation matrices during sym transform reading
636  vector< Vector > trans_vector; // store translation matrices during sym transform reading
637  vector< pair< Size, string > > transform_type; // store type of symmetry transform. Rotation or translation
638  Size num_transformations( 0 ); // Number of sym transforms read
639  core::Size N( 1 ); // Number of subunits in the system
640  vector1< string > score_multiply_subunit_string;
641  std::set<char> subchains;
642 
643  // Read the file
644  while( getline(infile,line) ) {
645  linecount++;
646  vector1< string > tokens ( utility::split( line ) );
647 
648  if (tokens.size() == 0) continue; // blank line
649  if (line.substr(0,1) == "#") continue; // comment
650 
651  // if we're reading a coordinate block ...
652  if (read_virtual_coords) {
653  if ( tokens[1] == "xyz" ) {
654  // Lines of virtual coordinate systems start with "xyz" and occur in
655  // virtual_coordinates_start ... virtual_coordinates_stop blocks
656  // parse the coordinate system into a VirtualCoordinate object. Need to
657  // have at least x and y axis. If no origin is specified we assume 0,0,0
658  if ( tokens.size() < 5 )
659  utility_exit_with_message("[ERROR] xyz lines in symm def file const contain an identifier and 3 coordinate vectors (X,Y,ORIG)" );
660  string identifier( tokens[2] );
661  VirtualCoordinate coord;
662  coord.add_coordinate_from_string( tokens, 3 );
663 
664  if ( virtual_coordinates_.find(identifier) != virtual_coordinates_.end() )
665  utility_exit_with_message("[ERROR] VRT identifier "+identifier+" defined twice in symmetry definition file!" );
666 
667  virtual_coordinates_[identifier] = coord;
668  Size jump_num (virtual_coordinates_.size());
669 
670  // vrt id to idx maps
671  virt_id_to_virt_num_[identifier] = jump_num;
672  virt_num_to_virt_id_[jump_num] = identifier;
673  } else if ( tokens[1] == "virtual_coordinates_stop" ) {
674  read_virtual_coords = false;
675  have_virtual_coordinates = true;
676  } else {
677  utility_exit_with_message("[ERROR] Error reading symm def file while at '"+line+"'");
678  }
679  }
680  // if we're reading a list of transforms
681  else if (read_transforms) {
682  // Read the start coordinate system upon which the first transformation operation work on.
683  // Store the value in a VirtualCoordinate system
684  if ( tokens[1] == "start" && tokens.size() >= 3 ) {
685  string identifier = "VRT0001";
686  VirtualCoordinate start_coord;
687  start_coord.add_coordinate_from_string( tokens );
688  virtual_coordinates_.insert( make_pair( identifier, start_coord ) );
689 
690  // The first one is always the master that controlls the clones
691  string tag = "BASEJUMP";
692  jump_string_to_jump_num_.insert( make_pair( tag, 1 ) );
693  jump_string_to_virtual_pair_.insert( make_pair( tag, make_pair( identifier, "SUBUNIT" ) ) );
694  virt_id_to_virt_num_.insert( make_pair( identifier, 1 ) );
695  virt_num_to_virt_id_.insert( make_pair( 1, identifier ) );
696  virt_id_to_subunit_num_.insert( make_pair( identifier, 1 ) );
697  subunit_num_to_virt_id_.insert( make_pair( 1, identifier ) );
698  start_coordinates_found = true;
699  } else if ( tokens[1] == "rot" || tokens[1] == "trans" ) {
700  if ( !start_coordinates_found ) {
701  utility_exit_with_message( "[ERROR] When specifying Rotation operations a starting coordinate must be give" );
702  }
703  // Rotation around the x-axis
704  if ( tokens[2] == "Rx" ) {
705  // Check that we have both rot, Rx and a value specifying the number of rotations
706  if ( tokens.size() != 3 ) {
707  utility_exit_with_message( "[ERROR] Need to give two arguments..." );
708  }
709  // Read the N-fold rotation
710  N = utility::string2int( tokens[2] );
711  Vector axis (1,0,0);
712  // Save the rotation matrix in the rot_matrix vector
713  rot_matrix.push_back( numeric::rotation_matrix_degrees( axis, 360.0 / N ) );
714  // We need to know what type of transformation this is
715  transform_type.push_back( make_pair( ++num_transformations, "rot") );
716  }
717  if ( tokens[2] == "Ry" ) {
718  if ( tokens.size() != 3 ) {
719  utility_exit_with_message( "[ERROR] Need to give two arguments..." );
720  }
721  N = utility::string2int( tokens[2] );
722  Vector axis (0,1,0);
723  rot_matrix.push_back( numeric::rotation_matrix_degrees( axis, 360.0 / N ) );
724  transform_type.push_back( make_pair( ++num_transformations, "rot") );
725  }
726  if ( tokens[2] == "Rz" ) {
727  if ( tokens.size() != 3 ) {
728  utility_exit_with_message( "[ERROR] Need to give two arguments..." );
729  }
730  N = utility::string2int( tokens[3] );
731  Vector axis (0,0,1);
732  rot_matrix.push_back( numeric::rotation_matrix_degrees( axis, 360.0 / N ) );
733  transform_type.push_back( make_pair( ++num_transformations, "rot") );
734  }
735  // Rotate an angle "angle" around the x-axis
736  if ( tokens[2] == "Rx_angle" ) {
737  if ( tokens.size() != 3 ) {
738  utility_exit_with_message( "[ERROR] Need to give two arguments..." );
739  }
740  Vector axis (1,0,0);
741  Real angle = static_cast<core::Real>( std::atof( tokens[3].c_str() ) );
742  rot_matrix.push_back( numeric::rotation_matrix_degrees( axis, angle ) );
743  transform_type.push_back( make_pair( ++num_transformations, "rot") );
744  }
745  if ( tokens[2] == "Ry_angle" ) {
746  if ( tokens.size() != 3 ) {
747  utility_exit_with_message( "[ERROR] Need to give two arguments..." );
748  }
749  Vector axis (0,1,0);
750  Real angle = static_cast<core::Real>( std::atof( tokens[3].c_str() ) );
751  rot_matrix.push_back( numeric::rotation_matrix_degrees( axis, angle ) );
752  transform_type.push_back( make_pair( ++num_transformations, "rot") );
753  }
754  if ( tokens[2] == "Rz_angle" ) {
755  if ( tokens.size() != 3 ) {
756  utility_exit_with_message( "[ERROR] Need to give two arguments..." );
757  }
758  Vector axis (0,0,1);
759  Real angle = static_cast<core::Real>( std::atof( tokens[3].c_str() ) );
760  rot_matrix.push_back( numeric::rotation_matrix_degrees( axis, angle ) );
761  transform_type.push_back( make_pair( ++num_transformations, "rot") );
762  }
763  // read translations. Need to give a vector
764  if ( tokens[1] == "trans" ) {
765  vector1< string> split ( utility::string_split( tokens[2], ',' ) );
766  runtime_assert( split.size() == 3 );
767  Vector trans( ( static_cast<core::Real>( std::atof( split[1].c_str() ) ) ),
768  ( static_cast<core::Real>( std::atof( split[2].c_str() ) ) ),
769  ( static_cast<core::Real>( std::atof( split[3].c_str() ) ) ) );
770  trans_vector.push_back( trans );
771  transform_type.push_back( make_pair( ++num_transformations, "trans") );
772  }
773  } else if ( tokens[1] == "virtual_transforms_stop" ) {
774  read_transforms = false;
775  // For all the subunits generate a coordinate system. Go through all the tranformation
776  // operations and operate on the previous coordinate system sequentially. The first
777  // coordinate system is the start coordinates. All transformations are acted on for
778  // virtual coordinate system. This may not make sense always, need to look at this more...
779  Size index(0);
780  Size num_rots(0), num_trans(0);
781  // First find the start coordinates. They are labelled with VRT1
782  if ( virtual_coordinates_.find( "VRT0001" ) == virtual_coordinates_.end() ) {
783  utility_exit_with_message( "[ERROR] start coordinates VRT0001 not found..." );
784  }
785  VirtualCoordinate virt_coord( virtual_coordinates_.find( "VRT0001" )->second );
786  // read transforms in a consecutive manner
787  if ( read_consecutive_transforms ) {
788  for ( Size i=1; i < subunits_; ++i ) {
789  Vector x_new( virt_coord.get_x() );
790  Vector y_new( virt_coord.get_y() );
791  Vector origin_new ( virt_coord.get_origin() );
792  Size num_rots(0), num_trans(0);
793  for ( vector< pair< Size, string > >::const_iterator it = transform_type.begin();
794  it != transform_type.end(); ++it ) {
795  if ( it->second == "rot" ) {
796  Size matrix_num ( ++num_rots );
797  x_new = rot_matrix[matrix_num -1]*x_new;
798  y_new = rot_matrix[matrix_num -1]*y_new;
799  origin_new = rot_matrix[matrix_num -1]*origin_new;
800  } else if ( it->second == "trans" ) {
801  Size vector_num ( ++num_trans );
802  origin_new = trans_vector[vector_num -1] + origin_new;
803  }
804  }
805  VirtualCoordinate coord( x_new, y_new, origin_new );
806  Size jump_num ( virtual_coordinates_.size() + 1 );
807  string tag;
808  std::ostringstream stream;
809  stream << std::setfill('0') << std::setw(4) << jump_num;
810  tag = "CLONE" + stream.str();
811  string identifier = "VRT" + stream.str();
812  virtual_coordinates_.insert( make_pair( identifier, coord ) );
813  jump_string_to_jump_num_.insert( make_pair( tag, jump_num ) );
814  jump_string_to_virtual_pair_.insert( make_pair( tag, make_pair( identifier, "SUBUNIT" ) ) );
815  virt_id_to_virt_num_.insert( make_pair( identifier, jump_num ) );
816  virt_num_to_virt_id_.insert( make_pair( jump_num, identifier ) );
817  virt_id_to_subunit_num_.insert( make_pair( identifier, virt_id_to_subunit_num_.size()+1 ) );
818  subunit_num_to_virt_id_.insert( make_pair( subunit_num_to_virt_id_.size()+1, identifier ) );
819  virt_coord = coord;
820  }
821  } else {
822  for ( Size i=1; i < subunits_; ++i ) {
823  if ( i > transform_type.size() ) {
824  index = 0;
825  num_rots = 0;
826  num_trans = 0;
827  }
828  ++index;
829  Vector x_new( virt_coord.get_x() );
830  Vector y_new( virt_coord.get_y() );
831  Vector origin_new ( virt_coord.get_origin() );
832  if ( transform_type[index-1].second == "rot" ) {
833  Size matrix_num ( ++num_rots );
834  x_new = rot_matrix[matrix_num -1]*x_new;
835  y_new = rot_matrix[matrix_num -1]*y_new;
836  origin_new = rot_matrix[matrix_num -1]*origin_new;
837  } else if ( transform_type[i-1].second == "trans" ) {
838  Size vector_num ( ++num_trans );
839  origin_new = trans_vector[vector_num -1] + origin_new;
840  }
841  VirtualCoordinate coord( x_new, y_new, origin_new );
842  Size jump_num ( virtual_coordinates_.size() + 1 );
843  string tag;
844  std::ostringstream stream;
845  stream << std::setfill('0') << std::setw(4) << jump_num;
846  tag = "CLONE" + stream.str();
847  string identifier = "VRT" + stream.str();
848  virtual_coordinates_.insert( make_pair( identifier, coord ) );
849  jump_string_to_virtual_pair_.insert( make_pair( tag, make_pair( identifier, "SUBUNIT" ) ) );
850  virt_id_to_virt_num_.insert( make_pair( identifier, jump_num ) );
851  virt_num_to_virt_id_.insert( make_pair( jump_num, identifier ) );
852  virt_id_to_subunit_num_.insert( make_pair( identifier, virt_id_to_subunit_num_.size()+1 ) );
853  subunit_num_to_virt_id_.insert( make_pair( subunit_num_to_virt_id_.size()+1, identifier ) );
854  virt_coord = coord;
855  }
856  }
857  } else {
858  utility_exit_with_message("[ERROR] Error reading symm def file while at '"+line+"'");
859  }
860  }
861  // otherwise just reading std info
862  else {
863  if ( tokens[1] == "virtual_coordinates_start" ) {
864  // Start virtual coordinate system block
865  read_virtual_coords = true;
866  } else if ( tokens[1] == "virtual_transforms_start" ) {
867  // Start transformation block
868  read_transforms = true;
869  if ( tokens.size() >= 2 && tokens[2] == "consecutive" )
870  read_consecutive_transforms = true;
871  } else if ( tokens[1] == "symmetry_name" ) {
872  // parse the name of the symmetry type. Not required
873  symmetry_name_ = tokens[2];
874  } else if ( tokens[1] == "subunits" ) {
875  // parse the number of subunits. Required.
876  subunits_ = utility::string2int( tokens[2] );
877  read_subunits = true;
878  for( Size i =1; i<=subunits_;i++) {
879  include_subunit_.push_back(i);
880  output_subunit_.push_back(i);
881  }
882  } else if ( tokens[1] == "number_of_interfaces") {
883  // parse the number of different type of interfaces. Required
884  interfaces_ = utility::string2int( tokens[2] );
885  } else if ( tokens[1] == "anchor_residue") {
886  // anchor residue id
887  anchor_residue_ = tokens[2];
888  } else if ( tokens[1] == "recenter" ) {
889  recenter_ = true;
890  } else if ( tokens[1] == "E" && tokens[2] == "=" ) {
891  // Define how the total energy should be calculated. The format is
892  // E = X*E2 + Y*E3 + ...
893  // where X and Y are integers. If not specified we assume that E = subunits_*E2.
894  // Spaces between "E", "=" and the multipliers are necessary
895  //for ( Size i = 2; i <= tokens.size(); i=i+2 ) {
896  // score_multiply_subunit_string.push_back( tokens[i] );
897  //}
898  score_multiply_subunit_string.push_back( line );
899  } else if ( tokens[1] == "connect_virtual" ) {
900  // Read information on how virtual coordinate systems are connected by jumps. Not required
901  connect_virtuals_specified = true;
902  if ( tokens.size() < 4 )
903  utility_exit_with_message( "[ERROR] You have to give jump identifier together with two virtual residue ids..." );
904  if ( jump_string_to_virtual_pair_.find( tokens[2] ) != jump_string_to_virtual_pair_.end() )
905  utility_exit_with_message( "[ERROR] jump identifiers have to be unique..." + tokens[2] + " found twice " );
906  if ( virtual_coordinates_.find( tokens[3] ) == virtual_coordinates_.end() )
907  utility_exit_with_message( "[ERROR] Virtual residue " + tokens[3] + " in jump " + tokens[2] + " not found" );
908  if ( tokens[4] != "SUBUNIT" && virtual_coordinates_.find( tokens[4] ) == virtual_coordinates_.end() )
909  utility_exit_with_message( "[ERROR] Virtual residue " + tokens[4] + " in jump " + tokens[2] + " not found" );
910 
911  jump_string_to_virtual_pair_[ tokens[2] ] = make_pair( tokens[3], tokens[4] );
912  if ( tokens[4] == "SUBUNIT" ) {
913  if( tokens.size()==4 ) {
914  if ( !read_subunits ) ++subunits_;
915  Size newId = virt_id_to_subunit_num_.size()+1;
916  virt_id_to_subunit_num_[ tokens[3] ] = newId;
917  subunit_num_to_virt_id_[ newId ] = tokens[3];
918  } else {
919  // more than one component
920  Size newId = virt_id_to_subunit_num_.size()+1;
921  virt_id_to_subunit_num_[ tokens[3] ] = newId;
922  subunit_num_to_virt_id_[ newId ] = tokens[3];
923  if(!have_virtual_coordinates) utility_exit_with_message("multicomponent symmetry not supported with virtual_transforms_start/stop!");
924  string subchain = tokens[5];
925  if( subchain.size() != 1 || subchain[0]==' ' ) utility_exit_with_message("[ERRIR] bad chain: "+subchain+" specified on SUBUNIT line:\n"+line);
926  virt_id_to_subunit_chain_[ tokens[3] ] = subchain[0];
927  subchains.insert(subchain[0]);
928  if( tokens.size() > 5 ) virt_id_to_subunit_residue_[ tokens[3] ] = tokens[6];
929  else virt_id_to_subunit_residue_[ tokens[3] ] = get_anchor_residue(); // default subanchor
930  if( tokens.size() > 6 ) utility_exit_with_message("[ERROR] extra input on SUBUNIT line:\n"+line);
931  }
932  }
933  } else if ( tokens[1] == "set_dof" ) {
934  // Store the degrees of freedom associated with a jump to a virtual residue. If not given
935  // we assume that all dofs are allowed. Format:
936  // set_dof x y z angle_x angle_x angle_y angle_z
937  // If one of these tokens are missing it is assumed that the dof is disallowed
938  // if we have no connect virtuals add connections by virtuals by default
939  if ( !connect_virtuals_specified ) {
940  for ( Size i = 2; i<= virtual_coordinates_.size(); ++i ) {
941  std::ostringstream str, str2;
942  str << std::setfill('0') << std::setw(4) << i;
943  str2 << std::setfill('0') << std::setw(4) << i-1;
944  string tag = "JUMP" + str2.str();
945  string vrt_start = "VRT" + str2.str();
946  string vrt_end = "VRT" + str.str();
947  jump_string_to_virtual_pair_.insert( make_pair( tag, make_pair( vrt_start, vrt_end ) ) );
948  }
949  }
950  // First convert jump tags to jump numbers
951  // ASSUMES ALL JUMPS ALREADY DECLARED
952  if ( set_jump_numbers_from_tags ) {
953  Size insert_pos(0);
954  map< string, pair< string, string > >::const_iterator itv_start = jump_string_to_virtual_pair_.begin();
955  map< string, pair< string, string > >::const_iterator itv_end = jump_string_to_virtual_pair_.end();
956 
957  // jumps to the subunit first
958  for ( map< string, pair< string, string > >::const_iterator itv = itv_start; itv != itv_end; ++itv ) {
959  pair< string, string > connect( itv->second );
960  string pos_id1( connect.first );
961  string pos_id2( connect.second );
962  if ( pos_id2 == "SUBUNIT" ) {
963  ++insert_pos;
964  jump_string_to_jump_num_.insert( make_pair( itv->first, insert_pos ) );
965  }
966  }
967  // then intra-VRT jumps
968  for ( map< string, pair< string, string > >::const_iterator itv = itv_start; itv != itv_end; ++itv ) {
969  pair< string, string > connect( itv->second );
970  string pos_id2( connect.second );
971  // We have already added the jumps from virtual residues to their corresponding subunits
972  if ( pos_id2 == "SUBUNIT" ) continue;
973  ++insert_pos;
974  jump_string_to_jump_num_.insert( make_pair( itv->first, insert_pos ) );
975  }
976  set_jump_numbers_from_tags = false;
977  }
978 
979  if ( tokens.size() < 3 )
980  utility_exit_with_message("[ERROR] Error reading set_dof line '"+line+"'");
981 
982  string jump_id ( tokens[2] );
983  if ( jump_string_to_jump_num_.find(jump_id) == jump_string_to_jump_num_.end() ) {
984  string error( "[ERROR] Jump id is not found..." + jump_id );
985  utility_exit_with_message( error );
986  }
987  Size jump_nbr( jump_string_to_jump_num_.find(jump_id)->second );
988  SymDof dof;
989  dof.add_dof_from_string(tokens);
990  dofs_[ jump_nbr ] = dof;
991  } else if( tokens[1] == "include_subunit" ) {
992  include_subunit_.clear();
993  for( Size i=2; i<=tokens.size();i++) {
994  core::Size j ( utility:: string2int( tokens[i] ) );
995  include_subunit_.push_back(j);
996  }
997  } else if( tokens[1] == "output_subunit" ) {
998  output_subunit_.clear();
999  for( Size i =2; i<=tokens.size();i++) {
1000  core::Size j ( utility:: string2int( tokens[i] ) );
1001  output_subunit_.push_back(j);
1002  }
1003  } else if( tokens[1] == "set_jump_group" ) {
1004  // set groups of jumps that move together
1005  int master(-1);
1006 
1007  // First convert jump tags to jump numbers
1008  // ASSUMES ALL JUMPS ALREADY DECLARED
1009  if ( set_jump_numbers_from_tags ) {
1010  Size insert_pos(0);
1011  map< string, pair< string, string > >::const_iterator itv_start = jump_string_to_virtual_pair_.begin();
1012  map< string, pair< string, string > >::const_iterator itv_end = jump_string_to_virtual_pair_.end();
1013 
1014  // jumps to the subunit first
1015  for ( map< string, pair< string, string > >::const_iterator itv = itv_start; itv != itv_end; ++itv ) {
1016  pair< string, string > connect( itv->second );
1017  string pos_id1( connect.first );
1018  string pos_id2( connect.second );
1019  if ( pos_id2 == "SUBUNIT" ) {
1020  ++insert_pos;
1021  jump_string_to_jump_num_.insert( make_pair( itv->first, insert_pos ) );
1022  }
1023  }
1024  // then intra-VRT jumps
1025  for ( map< string, pair< string, string > >::const_iterator itv = itv_start; itv != itv_end; ++itv ) {
1026  pair< string, string > connect( itv->second );
1027  string pos_id2( connect.second );
1028  // We have already added the jumps from virtual residues to their corresponding subunits
1029  if ( pos_id2 == "SUBUNIT" ) continue;
1030  ++insert_pos;
1031  jump_string_to_jump_num_.insert( make_pair( itv->first, insert_pos ) );
1032  }
1033  set_jump_numbers_from_tags = false;
1034  }
1035 
1036  // The master is the jump that has a dof line
1037  vector1< Size > jump_nums;
1038  vector1< Real > jump_wts;
1039  for ( Size i = 3; i <= tokens.size(); ++i ) {
1040  // read tags of the form 'JUMP_0_0:0.333333'
1041  // which means this jump has a weight 0.333333
1042  vector1< string > jump_split_i ( utility::string_split( tokens[i], ':' ) );
1043  core::Real wt_i = 0.0;
1044 
1045  if (jump_split_i.size() > 1) {
1046  wt_i = std::atof( jump_split_i[2].c_str() );
1047  }
1048 
1049  if ( jump_string_to_jump_num_.find( jump_split_i[1] ) == jump_string_to_jump_num_.end() )
1050  utility_exit_with_message("[ERROR] Undefined jump "+jump_split_i[1]+" in jump group '"+tokens[2]+"'");
1051 
1052  Size jump_nbr( jump_string_to_jump_num_.find( jump_split_i[1] )->second );
1053  if ( dofs_.find(jump_nbr) != dofs_.end() ) {
1054  if (master >= 0)
1055  utility_exit_with_message("[ERROR] Multiple movable jumps specified in jump group '"+tokens[2]+"'");
1056  master = jump_nbr;
1057  }
1058 
1059  jump_nums.push_back( jump_nbr );
1060  jump_wts.push_back( wt_i );
1061  }
1062 
1063  // If no dof is specified for any jump in this group just use the first group member
1064  if ( master < 0 ) {
1065  master = jump_nums[1];
1066  }
1067  runtime_assert (master >= 0);
1068 
1069  // Now set the jump group
1070  //vector1<Size> thisCloneList(0);
1071  vector1< pair<Size,Real> > thisCloneList(0);
1072  for ( Size i = 1; i <= jump_nums.size(); ++i ) {
1073  if ( (int)jump_nums[i] == master ) {
1074  if ( jump_wts[i] != 1.0 ) {
1075  TR.Warning << "Setting weight of master jump ( jump-id=" << master << " ) to 1.0 ";
1076  if (jump_wts[i] == 0.0)
1077  TR.Warning << "(was undefined)" << endl;
1078  else
1079  TR.Warning << "(was " << jump_wts[i] << ")" << endl;
1080  }
1081  } else {
1082  thisCloneList.push_back( make_pair(jump_nums[i],jump_wts[i]) );
1083  }
1084  }
1085  jump_clones_[master] = thisCloneList;
1086 
1087  if (jump_nums.size() > 1) {
1088  TR.Warning << "Setting jump_group " << tokens[2] << ": [master " << master << "] ";
1089  for ( Size i = 1; i <= jump_nums.size(); ++i ) {
1090  if ( (int)jump_nums[i] != master ) TR.Warning << " " << jump_nums[i] << ":" << jump_wts[i] << " ";
1091  }
1092  TR.Warning << endl;
1093  }
1094  } else if( tokens[1] == "slide_type" ) {
1095  if ( tokens.size() != 2 ) utility_exit_with_message("[ERROR] Error reading slide_type '"+line+"'");
1096  if ( tokens[2] == "SEQUENTIAL" ) {
1098  } else if ( tokens[2] == "ORDERED_SEQUENTIAL" ) {
1100  } else if ( tokens[2] == "RANDOM" ) {
1102  } else {
1103  utility_exit_with_message("[ERROR] Unknown slide_type '"+tokens[2]+"'");
1104  }
1105  } else if( tokens[1] == "slide_criteria_type" ) {
1106  if ( tokens.size() != 2 ) utility_exit_with_message("[ERROR] Error reading slide_criteria_type '"+line+"'");
1107  if ( tokens[2] == "CEN_DOCK_SCORE" ) {
1109  } else if ( tokens[2] == "FA_REP_SCORE" ) {
1111  } else if ( tokens[2] == "CONTACTS" ) {
1113  } else {
1114  utility_exit_with_message("[ERROR] Unknown slide_type '"+tokens[2]+"'");
1115  }
1116  } else if( tokens[1] == "slide_criteria_val" ) {
1117  if ( tokens.size() != 2 ) utility_exit_with_message("[ERROR] Error reading slide_criteria_val '"+line+"'");
1118  slide_info_.set_SlideCriteriaVal(tokens[2]);
1119  } else if( tokens[1] == "slide_order" ) {
1120  for ( Size record = 2; record <= tokens.size(); ++record ) {
1121  slide_order_string_.push_back( tokens[record] );
1122  }
1123  } else {
1124  utility_exit_with_message("[ERROR] Error reading symm def file while at '"+line+"'");
1125  }
1126  }
1127  }
1128 
1129  // postprocess multi-component related stuff // sheffler
1130  // count num subs per component, correct raw virt_id_to_subunit_num_
1131  if( virt_id_to_subunit_chain_.size() > 0 ) {
1132  vector1<char> chains(subchains.begin(),subchains.end());
1133  if(chains.size() <= 1) utility_exit_with_message("processing multicomponent symmetry, but only one chain!");
1134  std::sort(chains.begin(),chains.end());
1135  vector1<char>::const_iterator i = chains.begin();
1136  TR << "MULTICOMPONENT " << "You have specified the following chains for multi-component:";
1137  TR << " primary: " << *i;
1138  TR << ", secondary:";
1139  for(++i; i != chains.end(); ++i) TR << " " << *i;
1140  TR << std::endl;
1141  char firstchain = chains[1];
1142 
1143  if( virt_id_to_subunit_chain_.size() != virt_id_to_subunit_num_.size() ) utility_exit_with_message("missing component chains!");
1144  map<char,Size> chaincount;
1145  for(map<string,char>::const_iterator i = virt_id_to_subunit_chain_.begin(); i != virt_id_to_subunit_chain_.end(); ++i) {
1146  char const & chain = i->second;
1147  if(chaincount.count(chain)==0) chaincount[chain] = 0;
1148  chaincount[chain]++;
1149  }
1150  if( chaincount.size() == 1 ) utility_exit_with_message("For compatibility, don't use multicomponent format with only one component!!!");
1151  subunits_ = chaincount.begin()->second;
1152  num_components_ = chaincount.size();
1153  for(map<char,Size>::const_iterator i = chaincount.begin(); i != chaincount.end(); ++i) {
1154  if( i->second != subunits_ ) {
1155  for(map<char,Size>::const_iterator j = chaincount.begin(); j != chaincount.end(); ++j) {
1156  TR << "SUBUNIT " << j->first << " num subs: " << j->second << endl;
1157  }
1158  utility_exit_with_message("[ERROR] bad number of subunits");
1159  }
1160  }
1161  // compute reference xforms
1162  map<pair<char,Size>,Xform> frames;
1163  for(map<string,Size>::const_iterator i = virt_id_to_subunit_num_.begin(); i != virt_id_to_subunit_num_.end(); ++i){
1164  string const & virt_id = i->first;
1165  Size const & subnum = i->second;
1166  char const & chain = virt_id_to_subunit_chain_[virt_id];
1167  VirtualCoordinate const & vc( virtual_coordinates_[i->first] );
1168  Mat const R( Mat::cols( vc.get_x().normalized(), vc.get_y().normalized(), vc.get_x().cross(vc.get_y()).normalized() ) );
1169  Xform toframe(R,vc.get_origin());
1170  // TR << "MULTICOMPONENT " << virt_id << " " << chain << " " << subnum << endl << toframe << endl;
1171  if( vc.get_origin() .distance(toframe*Vec(0,0,0) ) > 0.0000000001 ||
1172  vc.get_x() .normalized().distance(toframe*Vec(1,0,0).normalized()) > 0.0000000001 ||
1173  vc.get_y() .normalized().distance(toframe*Vec(0,1,0).normalized()) > 0.0000000001 ||
1174  vc.get_x().cross(vc.get_y()).normalized().distance(toframe*Vec(0,0,1).normalized()) > 0.0000000001 )
1175  {
1176  std::cerr << virt_id << " " << chain << " " << subnum << " " << "orig " << vc.get_origin() << endl;
1177  std::cerr << virt_id << " " << chain << " " << subnum << " " << "xform " << toframe*Vec(0,0,0) << endl;
1178  std::cerr << virt_id << " " << chain << " " << subnum << " " << "orig " << vc.get_x() << endl;
1179  std::cerr << virt_id << " " << chain << " " << subnum << " " << "xform " << toframe*Vec(1,0,0) << endl;
1180  std::cerr << virt_id << " " << chain << " " << subnum << " " << "orig " << vc.get_y() << endl;
1181  std::cerr << virt_id << " " << chain << " " << subnum << " " << "xform " << toframe*Vec(0,1,0) << endl;
1182  std::cerr << virt_id << " " << chain << " " << subnum << " " << "orig " << vc.get_x().cross(vc.get_y()) << endl;
1183  std::cerr << virt_id << " " << chain << " " << subnum << " " << "xform " << toframe*Vec(0,0,1) << endl;
1184  utility_exit_with_message("computed frame xforms not correct!");
1185  }
1186  frames[make_pair(chain,(subnum-1)%subunits_+1)] = toframe;
1187  }
1188 
1189  // compute relative xforms
1190  map<pair<char,Size>,Xform> relxforms;
1191  for(map<string,Size>::const_iterator i = virt_id_to_subunit_num_.begin(); i != virt_id_to_subunit_num_.end(); ++i){
1192  string const & virt_id = i->first;
1193  Size const & subnum = i->second;
1194  char const & chain = virt_id_to_subunit_chain_[virt_id];
1195  relxforms[make_pair(chain,subnum)] = frames[make_pair(chain,(subnum-1)%subunits_+1)] * ~frames[make_pair(chain,1)];
1196  // TR << "MULTICOMPONENT " << chain << " " << subnum << " " << virt_id << endl << relxforms[make_pair(chain,subnum)] << endl;
1197  }
1198  // TR << "computing alignment of secondary subunits to symmetry of chain " << firstchain << endl;
1199  map<pair<char,Size>,Size> subperm;
1200  for(map<string,Size>::const_iterator i = virt_id_to_subunit_num_.begin(); i != virt_id_to_subunit_num_.end(); ++i){
1201  string const & virt_id = i->first;
1202  Size const & subnum = i->second;
1203  char const & chain = virt_id_to_subunit_chain_[virt_id];
1204  if(chain == firstchain) continue;
1205  Xform const & xform1( relxforms[make_pair(chain,subnum)] );
1206  for(map<pair<char,Size>,Xform>::const_iterator j = relxforms.begin(); j != relxforms.end(); ++j){
1207  Size const & subnum2(j->first.second);
1208  char const & chain2 (j->first.first);
1209  Xform const & xform2(j->second);
1210  if(chain2!=firstchain) continue;
1211  if( xform1.distance(xform2) < 0.000001 ){
1212  if( subperm.count(make_pair(chain,subnum)) > 0 ){
1213  utility_exit_with_message(string("multiple matching transforms for chain ")+
1214  chain+" in primary chain "+firstchain+"! probably a malformed or imprecise symmetry");
1215  }
1216  subperm[make_pair(chain,subnum)] = (subnum2-1)%subunits_+1;
1217  }
1218  }
1219  if( subperm.find(make_pair(chain,subnum)) == subperm.end() ){
1220  utility_exit_with_message(string("can't find matching transform for chain ")+
1221  chain+" in primary chain "+firstchain+"! probably a malformed or imprecise symmetry");
1222  }
1223  // TR << "MULTICOMPONENT " << "subperm " << chain << " " << (subnum-1)%subunits_+1
1224  // << " to subnum " << subperm.find(make_pair(chain,subnum))->second << endl;
1225  }
1226 
1227  // now map the extra component subunits
1228  for(map<string,Size>::const_iterator i = virt_id_to_subunit_num_.begin(); i != virt_id_to_subunit_num_.end(); ++i){
1229  string const & virt_id = i->first;
1230  Size const & subnum = i->second;
1231  char const & chain = virt_id_to_subunit_chain_[virt_id];
1232  Size newsubnum = 0;
1233  if(chain==firstchain){
1234  newsubnum = (subnum-1)%subunits_+1;
1235  TR << "MULTICOMPONENT " << "replace raw subunit "<< virt_id <<" num in primary chain " << chain << " with normalized subunit: "
1236  << virt_id_to_subunit_num_[virt_id] << " -> " << newsubnum << endl;
1237  } else {
1238  if(subperm.find(make_pair(chain,subnum)) == subperm.end()){
1239  utility_exit_with_message("error computing correct subnum for component!");
1240  }
1241  newsubnum = subperm[make_pair(chain,subnum)];
1242  TR << "MULTICOMPONENT " << "replace raw subunit "<< virt_id <<" num in secondary chain " << chain << " with correctly permuted subunit: "
1243  << virt_id_to_subunit_num_[virt_id] << " -> " << newsubnum << endl;
1244  }
1245  if(newsubnum==0) utility_exit_with_message("error computing correct subnum for component!");
1246  virt_id_to_subunit_num_[virt_id] = newsubnum;
1247  }
1248 
1249  // another sanity check
1250  map<char,string> chainres;
1251  for(map<string,char>::const_iterator i = virt_id_to_subunit_chain_.begin(); i != virt_id_to_subunit_chain_.end(); ++i) {
1252  string const & virt_id = i->first;
1253  char const & chain = i->second;
1254  // make sure [<res req>] are all same
1255  if(chainres.count(chain)==0) chainres[chain] = virt_id_to_subunit_residue_[virt_id];
1256  if( chainres[chain] != virt_id_to_subunit_residue_[virt_id] ) {
1257  std::cerr << "ERROR in chain " << chain << " " << virt_id << endl;
1258  utility_exit_with_message("SUBUNIT <chain> [<res>] must match!");
1259  }
1260  }
1261 
1262  // sanity check num subs pre component are all == num subunits (subunits_)
1263  components_ = chains;
1265  map<Size,string> jnum2dofname_;
1266  for(std::map<std::string,Size>::const_iterator i = jump_string_to_jump_num_.begin(); i != jump_string_to_jump_num_.end(); ++i) {
1267  jnum2dofname_[i->second] = i->first;
1268  }
1269 
1270  // temporary tests
1271  // for(std::map< std::string, Size >::const_iterator i = virt_id_to_virt_num_.begin();
1272  // i != virt_id_to_virt_num_.end(); ++i){
1273  // string p = i->first;
1274  // while(p != NOPARENT){
1275  // TR << "MULTICOMPONENT " << p << " <- ";
1276  // p = get_parent_virtual(p);
1277  // }
1278  // TR << "MULTICOMPONENT " << std::endl;
1279  // }
1280  // TR << "MULTICOMPONENT " << "LCA TB12 DB11 " << SymmData::get_least_common_ancertor_virtual("TB12","DB11") << std::endl;
1281  // TR << "MULTICOMPONENT " << "LCA DB12 DB11 " << SymmData::get_least_common_ancertor_virtual("DB12","DB11") << std::endl;
1282  for( map< Size, SymDof >::iterator i = dofs_.begin(); i != dofs_.end(); ++i){
1283  string dofname = jnum2dofname_[i->first];
1284  jname2components_[dofname] = components_moved_by_jump(dofname);
1285  jname2subunits_[dofname] = subunits_moved_by_jump(dofname);
1286  // vector1<string> leaves = leaves_of_jump(dofname);
1287  // TR << "MULTICOMPONENT " << "JUMP " << dofname << " is parent of these virtuals:" << std::endl;
1288  // for(vector1<string>::const_iterator j = leaves.begin(); j != leaves.end(); ++j){
1289  // TR << "MULTICOMPONENT " << " " << *j << std::endl;
1290  // }
1291  }
1292 
1293  } else { // standard symmetry, one component
1294  num_components_ = 1;
1295  }
1296  // end sheffler mods
1297 
1298  // Done parsing the symm file, now do some post-processing
1299  // 1) find root of the system.
1300  // All jumps are defined upstream to downstream.
1301  // The only virtual residue that is not a downstream jump partner is the root
1302  int root(-1);
1303  map< string, pair< string, string > >::const_iterator it_start = jump_string_to_virtual_pair_.begin();
1304  map< string, pair< string, string > >::const_iterator it_end = jump_string_to_virtual_pair_.end();
1305  map< string, pair< string, string > >::const_iterator it, it2;
1306 
1307  Size nvrt( virt_num_to_virt_id_.size() );
1308  vector1<bool> downstream_targets( nvrt, false );
1309  for ( it = it_start; it != it_end; ++it ) {
1310  pair< string, string > connect( it->second );
1311  if (connect.second == "SUBUNIT") continue;
1312  if (downstream_targets[ virt_id_to_virt_num_[ connect.second ] ])
1313  utility_exit_with_message( "[ERROR] Cycle found in connect_virtual" );
1314  downstream_targets[ virt_id_to_virt_num_[ connect.second ] ] = true;
1315  }
1316 
1317  for (int i=1; i<=(int)nvrt; ++i) {
1318  if (!downstream_targets[i]) {
1319  if (root >= 0)
1320  utility_exit_with_message( "[ERROR] Foldtree not closed ("+virt_num_to_virt_id_[root]+","+ virt_num_to_virt_id_[i]+"...");
1321  root = i;
1322  }
1323  }
1324  if (root < 0)
1325  utility_exit_with_message( "[ERROR] Cycle found in connect_virtual" );
1326  root_ = root;
1327 
1328  vector1< Size > score_multiply_subunit_vector;
1329 
1330  // Initialize the first subunit with a factor corresponding to the number of
1331  // subunits. The rest of the values are set to 0
1332  for ( Size i = 1; i<= subunits_; ++i ) {
1333  score_multiply_subunit_vector.push_back(0);
1334  }
1335  // VRTs have a multiplier of 1
1336  for ( Size i = subunits_ + 1; i<= subunits_ + virtual_coordinates_.size(); ++i ) {
1337  score_multiply_subunit_vector.push_back(1);
1338  }
1339 
1340  if (score_multiply_subunit_string.size() == 0)
1341  utility_exit_with_message( "[ERROR] No total energy line specified!" );
1342  vector1< string> split_1 = utility::string_split( score_multiply_subunit_string[1], '=' );
1343  if (split_1.size() < 2)
1344  utility_exit_with_message( "[ERROR] Error parsing line '"+score_multiply_subunit_string[1]+"'" );
1345  vector1< string> split_2 = utility::string_split( split_1[2], '+' );
1346 
1347  for ( Size i = 1; i<=split_2.size(); ++i ) {
1348  // trim whitespace
1349  utility::trim(split_2[i], " ");
1350 
1351  vector1< string> split_3 = utility::string_split( split_2[i], '*' );
1352  Size factor=1;
1353  string virtual_residues = split_3[1];
1354  if (split_3.size() > 1) {
1355  factor = utility::string2int( split_3[1] );
1356  virtual_residues = split_3[2];
1357  }
1358  utility::trim( virtual_residues, "()" );
1359  vector1< string> virtual_residues_split ( utility::string_split( virtual_residues, ':' ) );
1360 
1361  Size subunit(0);
1362  if ( virtual_residues_split.size() == 1 ) {
1363  utility::trim(virtual_residues_split[1], " ");
1364  if ( virt_id_to_subunit_num_.find( virtual_residues_split[1] ) == virt_id_to_subunit_num_.end() ) {
1365  utility_exit_with_message( "[ERROR] VRT " + virtual_residues_split[1] + " not attached to a subunit");
1366  }
1367  score_subunit_ = virt_id_to_subunit_num_.find( virtual_residues_split[1] )->second;
1368  subunit = score_subunit_;
1369  } else if ( virtual_residues_split.size() == 2 ) {
1370  utility::trim(virtual_residues_split[2], " ");
1371  if ( virt_id_to_subunit_num_.find( virtual_residues_split[2] ) == virt_id_to_subunit_num_.end() ) {
1372  utility_exit_with_message( "[ERROR] VRT " + virtual_residues_split[2] + " not attached to a subunit");
1373  }
1374  subunit = virt_id_to_subunit_num_.find( virtual_residues_split[2] )->second;
1375  } else {
1376  utility_exit_with_message( "[ERROR] Error parsing 'E =' line while at " + split_2[i] );
1377  }
1378  score_multiply_subunit_vector[subunit] = factor;
1379  }
1380  set_score_multiply_subunit( score_multiply_subunit_vector );
1381 
1382  // process slide order information
1383  vector< Size > slide_order;
1384  for ( vector< string >::iterator it = slide_order_string_.begin(); it != slide_order_string_.end(); ++it ) {
1385  string jump_id ( *it );
1386  if ( jump_string_to_jump_num_.find(jump_id) == jump_string_to_jump_num_.end() ) {
1387  string error( "[ERROR] Jump id is not found..." + jump_id );
1388  utility_exit_with_message( error );
1389  }
1390  Size jump_nbr( jump_string_to_jump_num_.find(jump_id)->second );
1391  slide_order.push_back(jump_nbr);
1392  }
1393  slide_info_.set_slide_order(slide_order);
1394  // Check that the information given makes sense and is enough to
1395  // specifiy the symmetry
1396  sanity_check();
1397  // Print data for symmetry
1398  show();
1399 }
1400 
1401 // @details function to check if input data makes sense. We need to add many more checks
1402 // so that rosetta never exits without a error message at this stage
1403 void
1405 {
1406  if ( virtual_coordinates_.size() < 1 ) {
1407  utility_exit_with_message( "[ERROR] No virtual atoms specified..." );
1408  }
1409  if ( subunits_ < 1 ) {
1410  utility_exit_with_message( "[ERROR] Need to give number of subunits..." );
1411  }
1412  if ( interfaces_ < 1 ) {
1413  utility_exit_with_message( "[ERROR] Need to give number of interfaces..." );
1414  }
1415  if ( score_multiply_subunit_.size() < 1 ) {
1416  utility_exit_with_message( "[ERROR] Need to specify how to calculate symmetrical energy..." );
1417  }
1418  Size subunits(0);
1419  map< string, pair< string, string > >::const_iterator itv_start = jump_string_to_virtual_pair_.begin();
1420  map< string, pair< string, string > >::const_iterator itv_end = jump_string_to_virtual_pair_.end();
1421  for ( map< string, pair< string, string > >::const_iterator itv = itv_start; itv != itv_end; ++itv ) {
1422  pair< string, string > connect( itv->second );
1423  if ( connect.second == "SUBUNIT" ) ++subunits;
1424  }
1425  if ( subunits != num_components_*subunits_ ) {
1426  std::cerr << "subunits from connect_virtual: " << subunits << endl;
1427  std::cerr << "subunits declared: " << subunits_ << endl;
1428  std::cerr << "num symmetric components: " << num_components_ << endl;
1429  utility_exit_with_message( "[ERROR] The number of subunits is not equal to the number of jumps from virtual residues to subunits..." );
1430  }
1431  bool nullchain = false;
1432  for(map<string,char>::const_iterator i = virt_id_to_subunit_chain_.begin(); i != virt_id_to_subunit_chain_.end(); ++i) {
1433  if( i->second == (char)0 ) nullchain = true;
1434  if( nullchain && i->second != (char)0 ) utility_exit_with_message("[ERROR] all SUBUNITs must have chain if any have chain!");
1435  }
1436 }
1437 
1438 // @details print the symmetry data that we have initialized from file
1439 void
1441 {
1442  TR << "symmetry name: " << symmetry_name_ << endl;
1443  TR << "number of subunits: " << subunits_ << endl;
1444  TR << "number of interfaces: " << interfaces_ << endl;
1445  TR << "score subunit number: " << virt_num_to_virt_id_.find( score_subunit_ )->second << endl;
1446  TR << "anchor the subunits at residue: " << anchor_residue_ << endl;
1447 
1448  map< string, VirtualCoordinate >::iterator vit;
1449  map< string, VirtualCoordinate >::iterator vit_begin = virtual_coordinates_.begin();
1450  map< string, VirtualCoordinate >::iterator vit_end = virtual_coordinates_.end();
1451 
1452  for ( vit = vit_begin; vit != vit_end; ++vit ) {
1453  string identifier( (*vit).first );
1454  VirtualCoordinate coord( (*vit).second );
1455  TR << " Virtual coordinate system " << identifier << endl;
1456  TR << "x: " << coord.get_x()(1) << " " << coord.get_x()(2) << " " << coord.get_x()(3)
1457  << endl;
1458  TR << "y: " << coord.get_y()(1) << " " << coord.get_y()(2) << " " << coord.get_y()(3)
1459  << endl;
1460  TR << "origin: " << coord.get_origin()(1) << " " << coord.get_origin()(2) << " " << coord.get_origin()(3)
1461  << endl;
1462  }
1463 
1464  map< Size, SymDof >::iterator it;
1465  map< Size, SymDof >::iterator it_begin = dofs_.begin();
1466  map< Size, SymDof >::iterator it_end = dofs_.end();
1467  for ( it = it_begin; it != it_end; ++it ) {
1468  int jump_nbr ( (*it).first );
1469  SymDof dof ( (*it).second );
1470  TR << "Dof for jump: " << jump_nbr << endl;
1471  for ( Size i=1; i<=6; ++i ) {
1472  string dir ( "n2c" );
1473  if ( dof.jump_direction(i) == -1 ) dir = "c2n";
1474  if ( i == 1 ) TR << "x ";
1475  if ( i == 2 ) TR << "y ";
1476  if ( i == 3 ) TR << "z ";
1477  if ( i == 4 ) TR << "x_angle ";
1478  if ( i == 5 ) TR << "y_angle ";
1479  if ( i == 6 ) TR << "z_angle ";
1480  TR << dof.allow_dof(i) << ":" << dof.range1_lower(i) << "," << dof.range1_upper(i) << ":" << dof.range2_lower(i) << "," << dof.range2_upper(i)
1481  << " " << dir << endl;
1482  }
1483  }
1484 
1485  map< string, pair< string, string > >::const_iterator itv_start = jump_string_to_virtual_pair_.begin();
1486  map< string, pair< string, string > >::const_iterator itv_end = jump_string_to_virtual_pair_.end();
1487  for ( map< string, pair< string, string > >::const_iterator itv = itv_start; itv != itv_end; ++itv ) {
1488  pair< string, string > connect( itv->second );
1489  string pos_id1( connect.first );
1490  string pos_id2( connect.second );
1491  TR << "Jump " << itv->first << " " << pos_id1 << " " << pos_id2 << endl;
1492  }
1493  TR << "Include subunit:";
1494  for ( vector1< Size >::iterator it = include_subunit_.begin(); it != include_subunit_.end(); ++it ) {
1495  TR << ' ' << (*it) ;
1496  }
1497  TR << endl;
1498  TR << "Output subunit:";
1499  for ( vector1< Size >::iterator it = output_subunit_.begin(); it != output_subunit_.end(); ++it ) {
1500  TR << ' ' << (*it) ;
1501  }
1502  TR << endl;
1503  TR << "SlideType: ";
1504  if ( slide_info_.get_slide_type() == SEQUENTIAL ) TR << "SEQUENTIAL" << endl;
1505  if ( slide_info_.get_slide_type() == ORDERED_SEQUENTIAL ) TR << "ORDERED_SEQUENTIAL" << endl;
1506  if ( slide_info_.get_slide_type() == RANDOM ) TR << "RANDOM" << endl;
1507  TR << "SlideCriteriaType: ";
1508  if ( slide_info_.get_SlideCriteriaType() == CEN_DOCK_SCORE ) TR << "CEN_DOCK_SCORE" << endl;
1509  if ( slide_info_.get_SlideCriteriaType() == FA_REP_SCORE ) TR << "FA_REP_SCORE" << endl;
1510  if ( slide_info_.get_SlideCriteriaType() == CONTACTS ) TR << "CONTACTS" << endl;
1511  TR << "SlideCriteriaVal: ";
1512  TR << slide_info_.get_SlideCriteriaVal() << endl;
1513  TR << "SlideOrder: ";
1514  if ( slide_order_string_.size() == 0 ) TR << "none";
1515  for ( vector< string >::iterator it = slide_order_string_.begin();
1516  it != slide_order_string_.end(); ++it ) {
1517  TR << ' ' << (*it) ;
1518  }
1519 
1520  TR << endl;
1521 }
1522 
1523 
1524 utility::vector1<char> const &
1526  return components_;
1527 }
1528 
1529 std::map<std::string,char> const &
1531  return name2component_;
1532 }
1533 std::map<std::string,utility::vector1<char> > const &
1535  return jname2components_;
1536 }
1537 
1538 std::map<std::string,utility::vector1<Size> > const &
1540  return jname2subunits_;
1541 }
1542 
1543 std::string const &
1546  utility_exit_with_message("can't find parent jump of jump"+jname);
1547  std::string upvirt = jump_string_to_virtual_pair_.find(jname)->second.first;
1548  for(map<string,pair<string,string> >::const_iterator i = jump_string_to_virtual_pair_.begin(); i != jump_string_to_virtual_pair_.end(); ++i){
1549  if(i->second.second == upvirt) return i->first;
1550  }
1551  // utility_exit_with_message("can't find parent jump of jump: "+jname);
1552  return NOPARENT;
1553 }
1554 
1555 std::string const &
1557  for(map<string,pair<string,string> >::const_iterator i = jump_string_to_virtual_pair_.begin(); i != jump_string_to_virtual_pair_.end(); ++i){
1558  if(i->second.second == vname) return i->second.first;
1559  }
1560  // utility_exit_with_message("can't find parent jump of virtual: "+vname);
1561  return NOPARENT;
1562 }
1563 
1564 bool
1566  std::string const & ancestor,
1567  std::string const & child
1568 ) const {
1569  std::string const * p(&child);
1570  while(*p != NOPARENT){
1571  if( *p == ancestor ) return true;
1572  p = &get_parent_virtual(*p);
1573  }
1574  return false;
1575 }
1576 
1577 std::string const &
1579  std::set<string> seenit;
1580  std::string const * p(&jname1);
1581  while(*p != NOPARENT){
1582  seenit.insert(*p);
1583  p = &get_parent_jump(*p);
1584  }
1585  p = &jname2;
1586  while(*p != NOPARENT){
1587  if( seenit.find(*p) != seenit.end() ) return *p;
1588  p = &get_parent_jump(*p);
1589  }
1590  return NOPARENT;
1591 }
1592 
1593 std::string const &
1595  std::set<string> seenit;
1596  std::string const * p(&vname1);
1597  while(*p != NOPARENT){
1598  seenit.insert(*p);
1599  p = &get_parent_virtual(*p);
1600  }
1601  p = &vname2;
1602  while(*p != NOPARENT){
1603  if( seenit.find(*p) != seenit.end() ) return *p;
1604  p = &get_parent_virtual(*p);
1605  }
1606  return NOPARENT;
1607 }
1608 
1612  utility_exit_with_message("unknown jump name in leaves of jump");
1613  string const & ancestor( jump_string_to_virtual_pair_.find(jname)->second.second );
1614  vector1<string> leaves;
1615  for(map<std::string,Size>::const_iterator i = virt_id_to_subunit_num_.begin(); i != virt_id_to_subunit_num_.end(); ++i){
1616  if(is_ancestor_virtual(ancestor,i->first)) leaves.push_back(i->first);
1617  }
1618  return leaves;
1619 }
1620 
1621 
1624  vector1<string> leaves = leaves_of_jump(jname);
1625  std::set<char> components;
1626  for(vector1<string>::const_iterator i = leaves.begin(); i != leaves.end(); ++i){
1627  if( virt_id_to_subunit_chain_.find(*i) == virt_id_to_subunit_chain_.end() ) break;
1628  components.insert( virt_id_to_subunit_chain_.find(*i)->second );
1629  }
1630  return vector1<char>(components.begin(),components.end());
1631 }
1632 
1635  vector1<string> leaves = leaves_of_jump(jname);
1636  std::set<Size> subunits;
1637  for(vector1<string>::const_iterator i = leaves.begin(); i != leaves.end(); ++i){
1638  if( virt_id_to_subunit_num_.find(*i) == virt_id_to_subunit_num_.end() ) break;
1639  subunits.insert( virt_id_to_subunit_num_.find(*i)->second );
1640  }
1641  return vector1<char>(subunits.begin(),subunits.end());
1642 }
1643 
1644 bool
1646  SymmData const & a,
1647  SymmData const & b
1648 ) {
1649  if(
1650  (a.symmetry_name_ != b.symmetry_name_) ||
1651  (a.symmetry_type_ != b.symmetry_type_) ||
1652  (a.subunits_ != b.subunits_) ||
1653  (a.num_components_ != b.num_components_) ||
1654  (a.interfaces_ != b.interfaces_) ||
1655  (a.score_subunit_ != b.score_subunit_) ||
1656  (a.anchor_residue_ != b.anchor_residue_) ||
1657  (a.recenter_ != b.recenter_) ||
1658  (a.root_ != b.root_) ||
1659  (a.slide_info_ != a.slide_info_) ||
1660  !std::equal(
1661  a.slide_order_string_.begin(),
1662  a.slide_order_string_.end(),
1663  b.slide_order_string_.begin()) ||
1664  !std::equal(
1665  a.rotation_matrices_.begin(),
1666  a.rotation_matrices_.end(),
1667  b.rotation_matrices_.begin()) ||
1668  !std::equal(
1669  a.translation_matrices_.begin(),
1670  a.translation_matrices_.end(),
1671  b.translation_matrices_.begin()) ||
1672  !std::equal(
1673  a.virtual_coordinates_.begin(),
1674  a.virtual_coordinates_.end(),
1675  b.virtual_coordinates_.begin()) ||
1676  !std::equal(
1677  a.jump_string_to_virtual_pair_.begin(),
1679  b.jump_string_to_virtual_pair_.begin()) ||
1680  !std::equal(
1681  a.jump_string_to_jump_num_.begin(),
1682  a.jump_string_to_jump_num_.end(),
1683  b.jump_string_to_jump_num_.begin()) ||
1684  !std::equal(
1685  a.virt_id_to_virt_num_.begin(),
1686  a.virt_id_to_virt_num_.end(),
1687  b.virt_id_to_virt_num_.begin()) ||
1688  !std::equal(
1689  a.virt_id_to_subunit_num_.begin(),
1690  a.virt_id_to_subunit_num_.end(),
1691  b.virt_id_to_subunit_num_.begin()) ||
1692  !std::equal(
1693  a.virt_id_to_subunit_chain_.begin(),
1694  a.virt_id_to_subunit_chain_.end(),
1695  b.virt_id_to_subunit_chain_.begin()) ||
1696  !std::equal(
1697  a.virt_id_to_subunit_residue_.begin(),
1699  b.virt_id_to_subunit_residue_.begin()) ||
1700  !std::equal(
1701  a.virt_num_to_virt_id_.begin(),
1702  a.virt_num_to_virt_id_.end(),
1703  b.virt_num_to_virt_id_.begin()) ||
1704  !std::equal(
1705  a.subunit_num_to_virt_id_.begin(),
1706  a.subunit_num_to_virt_id_.end(),
1707  b.subunit_num_to_virt_id_.begin()) ||
1708  !std::equal(
1709  a.dofs_.begin(),
1710  a.dofs_.end(),
1711  b.dofs_.begin()) ||
1712  !std::equal(
1713  a.allow_virtual_.begin(),
1714  a.allow_virtual_.end(),
1715  b.allow_virtual_.begin()) ||
1716  !std::equal(
1717  a.score_multiply_subunit_.begin(),
1718  a.score_multiply_subunit_.end(),
1719  b.score_multiply_subunit_.begin()) ||
1720  !std::equal(
1721  a.include_subunit_.begin(),
1722  a.include_subunit_.end(),
1723  b.include_subunit_.begin()) ||
1724  !std::equal(
1725  a.output_subunit_.begin(),
1726  a.output_subunit_.end(),
1727  b.output_subunit_.begin()) ||
1728  (a.cell_a_ != b.cell_a_) ||
1729  (a.cell_b_ != b.cell_b_) ||
1730  (a.cell_c_ != b.cell_c_) ||
1731  (a.cell_alfa_ != b.cell_alfa_) ||
1732  (a.cell_beta_ != b.cell_beta_) ||
1733  (a.cell_gamma_ != b.cell_gamma_) ||
1734  !std::equal(
1735  a.components_.begin(),
1736  a.components_.end(),
1737  b.components_.begin()) ||
1738  !std::equal(
1739  a.name2component_.begin(),
1740  a.name2component_.end(),
1741  b.name2component_.begin())){
1742  return false;
1743  }
1744 
1745  for(
1746  std::vector< std::vector< std::string > >::const_iterator
1747  ai = a.symm_transforms_.begin(), aie = a.symm_transforms_.end(),
1748  bi = b.symm_transforms_.begin();
1749  ai != aie; ++ai, ++bi){
1750  if(bi == b.symm_transforms_.end() ||
1751  !std::equal(ai->begin(), ai->end(), bi->begin())){
1752  return false;
1753  }
1754  }
1755 
1756  for(
1757  std::map< Size, WtedClones >::const_iterator
1758  ai = a.jump_clones_.begin(), aie = a.jump_clones_.end(),
1759  bi = b.jump_clones_.begin();
1760  ai != aie; ++ai, ++bi){
1761  if(bi == b.jump_clones_.end() ||
1762  !std::equal(ai->second.begin(), ai->second.end(), bi->second.begin())){
1763  return false;
1764  }
1765  }
1766 
1767  for(
1768  std::map< std::string, utility::vector1<char> >::const_iterator
1769  ai = a.jname2components_.begin(), aie = a.jname2components_.end(),
1770  bi = b.jname2components_.begin();
1771  ai != aie; ++ai, ++bi){
1772  if(bi == b.jname2components_.end() ||
1773  !std::equal(ai->second.begin(), ai->second.end(), bi->second.begin())){
1774  return false;
1775  }
1776  }
1777 
1778  for(
1779  std::map< std::string, utility::vector1<Size> >::const_iterator
1780  ai = a.jname2subunits_.begin(), aie = a.jname2subunits_.end(),
1781  bi = b.jname2subunits_.begin();
1782  ai != aie; ++ai, ++bi){
1783  if(bi == b.jname2subunits_.end() ||
1784  !std::equal(ai->second.begin(), ai->second.end(), bi->second.begin())){
1785  return false;
1786  }
1787  }
1788 
1789  return true;
1790 }
1791 
1792 } // symmetry
1793 } // conformation
1794 } // core