Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SymmetryInfo.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 // This file is part of the Rosetta software suite and is made available under license.
5 // The Rosetta software is developed by the contributing members of the Rosetta Commons consortium.
6 // (C) 199x-2009 Rosetta Commons participating institutions and developers.
7 // For more information, see http://www.rosettacommons.org/.
8 
9 /// @file
10 /// @brief
11 /// @author Ingemar Andre, Phil Bradley
12 
13 // Unit Headers
15 
16 // Package headers
19 #include <core/id/types.hh>
20 #include <core/id/DOF_ID.hh>
21 #include <core/id/TorsionID.hh>
22 #include <core/id/AtomID.hh>
23 
25 
26 // Utility headers
27 #include <utility/exit.hh>
28 #include <utility/file/file_sys_util.hh>
29 #include <utility/io/izstream.hh>
30 #include <utility/io/ozstream.hh>
31 
32 // C++ headers
33 #include <cassert>
34 #include <iostream>
35 
36 // core utilities
37 #include <basic/Tracer.hh>
38 
39 #include <utility/vector1.hh>
40 
41 //Auto Headers
43 
44 using basic::T;
45 using basic::Error;
46 using basic::Warning;
47 
48 static basic::Tracer TR("core.conformation.SymmetryInfo");
49 
50 namespace core {
51 namespace conformation {
52 namespace symmetry {
53 
56 
57 
59 {
60  return ( npseudo_ == s.npseudo_ &&
61  bb_clones_ ==s.bb_clones_ &&
62  chi_clones_ == s.chi_clones_ &&
64 }
65 
67 {
68  return !( *this == s );
69 }
70 
71 SymmetryInfo::SymmetryInfo( SymmData const & symm_data, Size const nres_subunit, Size const njump_subunit )
72 {
73  Size joff = njump_subunit*symm_data.get_subunits();
74  std::map<std::string,Size> const & name2num = symm_data.get_jump_string_to_jump_num();
75  for(std::map<std::string,Size>::const_iterator i = name2num.begin(); i != name2num.end(); ++i) {
76  dofname2jnum_[i->first] = i->second+joff;
77  jnum2dofname_[i->second+joff] = i->first;
78  }
79  if ( symm_data.get_jump_clones().size() > 0 ) {
80  initialize( nres_subunit, njump_subunit,
81  symm_data.get_subunits(), symm_data.get_num_virtual(),
82  symm_data.get_jump_clones(), symm_data.get_dofs(),
83  symm_data.get_score_subunit(), symm_data.get_score_multiply_subunit(),
84  symm_data.get_slide_info(), symm_data.get_interfaces() );
85  } else {
86  initialize( nres_subunit, njump_subunit,
87  symm_data.get_subunits(), symm_data.get_num_virtual(),
88  symm_data.get_dofs(),symm_data.get_score_subunit(),
89  symm_data.get_score_multiply_subunit(), symm_data.get_slide_info(),
90  symm_data.get_interfaces() );
91  }
92  if(symm_data.get_num_components()==1) TR << *this << std::endl;
93  else TR.Debug << *this << std::endl;
94 }
95 
97  Size const nres_monomer,
98  Size const njump_monomer,
99  Size const N,
100  std::map< Size, SymDof > dofs,
101  Size const score_subunit,
102  utility::vector1< Size > score_multiply_subunit,
103  SymSlideInfo slide_info,
104  Size const num_interfaces,
105  std::string const & type
106 )
107 {
108  initialize( nres_monomer, njump_monomer, N, N, dofs, score_subunit,
109  score_multiply_subunit, slide_info, num_interfaces, type );
110 }
111 
112 ///@details make a copy of this SymmetryInfo ( allocate actual memory for it )
115 {
116  return new SymmetryInfo( *this );
117 }
118 
119 // This is an old style constructor. Should change soon...
120 void
122  Size const nres_monomer,
123  Size const njump_monomer,
124  Size const n_subunits,
125  Size const num_virtual,
126  std::map< Size, SymDof > dofs,
127  Size const score_subunit,
128  utility::vector1< Size > score_multiply_subunit,
129  SymSlideInfo slide_info,
130  Size const num_interfaces,
131  std::string const & type
132 )
133 {
134  nres_monomer_ = nres_monomer;
135 
136  // set number of interfaces
138  // store the score multiplication factors
139  set_score_multiply_from_subunit_factors(score_multiply_subunit, nres_monomer, n_subunits);
140  // store the number of monomer jumps
141  njump_monomer_ = njump_monomer;
142  // store the allowed dofs
143  dofs_ = dofs;
144  // set use symmetry
145  use_symmetry_ = true;
146  // set cp_weighting_during_minimization_ to false
148  // slide info
149  slide_info_ = slide_info;
150  // store type
151  type_ = type;
152  //scoring subunit
153  scoring_subunit_ = score_subunit;
154  // setup bb,chi clones
155  bb_clones_.clear();
156  chi_clones_.clear();
157  jump_clones_.clear();
158 
159  //check that score_monomer makes sense...
160  if ( score_subunit > n_subunits || score_subunit < 1 ) {
161  utility_exit_with_message("score_subunit must be in the range 1-N");
162  }
163 
164  //special case of no symmetry
165  if ( type == "c1" ) {
166  npseudo_ = num_virtual;
167 
168  //we need to map to an empty array in order for
169  for ( Size i=1; i<= nres_monomer; ++i ) {
170  Clones clones;
171  clones.clear();
172  bb_clones_.insert( std::make_pair( i, clones ) );
173  chi_clones_.insert( std::make_pair( i, clones ) );
174  }
175  for ( Size i=1; i<= njump_monomer; ++i ) {
176  Clones clones;
177  clones.clear();
178  jump_clones_.insert( std::make_pair( i, clones ) );
179  }
180  return;
181  }//end c1 symmetry
182 
183  for ( Size i=1; i<= nres_monomer; ++i ) {
184  Clones clones;
185  int base ( i + ( score_subunit - 1 ) * nres_monomer );
186  for ( Size k=0; k<n_subunits; ++k ) {
187  if ( k+1 != score_subunit ) {
188  clones.push_back( i + k * nres_monomer );
189  add_bb_clone( base, i + k * nres_monomer );
190  add_chi_clone( base, i + k * nres_monomer );
191  }
192  }
193  bb_clones_.insert( std::make_pair( base, clones ) );
194  chi_clones_.insert( std::make_pair( base, clones ) );
195  }
196 
197  // the N*njump_monomer internal jumps
198  for ( Size i=1; i<= njump_monomer; ++i ) {
199  //Clones clones;
200  for ( Size k=1; k<n_subunits; ++k ) {
201  //clones.push_back( i + k * njump_monomer );
202  add_jump_clone( i, i + k * njump_monomer, 0.0 );
203  }
204  //jump_clones_.insert( std::make_pair( i, clones ) );
205  }
206 
207  if ( type == "no_pseudo" ) {
208  npseudo_ = num_virtual;
209 
210  } else if ( type == "simple" ) {
211  // 1 --> N*njump_monomer : the internal jumps
212  // N*njump_monomer+1 --> N*njump_monomer+N: the pseudo-rsd--monomer jumps
213  // last N-1 jumps : jumps between pseudo-rsds
214 
215  npseudo_ = num_virtual;
216 
217  // the N jumps from pseudo-residues to monomers
218  {
219  Size const base_jump( n_subunits*njump_monomer + 1 );
220  //Clones clones;
221  for ( Size k=1; k<n_subunits; ++k ) {
222  //clones.push_back( base_jump + k );
223  add_jump_clone( base_jump, base_jump + k, 0.0 );
224  }
225  //jump_clones_.insert( std::make_pair( base_jump, clones ) );
226  }
227 
228 
229  // the N-1 jumps between pseudo-residues
230  {
231 /* Size const base_jump( N*njump_monomer + N + 1 );
232  //Clones clones;
233  for ( Size k=1; k<N-1; ++k ) {
234  //clones.push_back( base_jump + k );
235  add_jump_clone( base_jump, base_jump + k, 0.0 );
236  }
237  //jump_clones_.insert( std::make_pair( base_jump, clones ) ); */
238  }
239  } else {
240  std::cerr << "unrecognized type: " << type << std::endl;
241  utility_exit();
242  }
243 
245 }
246 
247 /// @details This is a helper function for some of the DOF_ID routines below. Really just a best guess...
248 /// this is a little tricky: the mapping from a DOF_ID to a TorsionID is not straightforward to
249 /// construct (see kinematics/util.cc:setup_dof_to_torsion_map)
250 /// So we don't really know whether a dof_id is a bb degree of freedom or a chi degree of freedom...
251 /// or even which residue it should be attached to, eg the phi of residue i might be dof_id with rsd i-1
252 /// So we take a guess based on whether id.atomno is a backbone or sidechain atom
255 {
256  if ( id::RB1 <= id.type() && id.type() <= id::RB6 ) {
257  return id::JUMP;
258  } else {
259  if ( conf.atom_is_backbone_norefold( id.rsd(), id.atomno() ) ) {
260  return id::BB;
261  } else {
262  return id::CHI;
263  }
264  }
265 }
266 
267 //
268 void
270 {
271  // compute the score_multiply_factor
273  for (int i=1; i<=(int)indep_res.size(); ++i) {
274  if (indep_res[i]) {
276  //std::cout<< "score_multiply_factor "<< score_multiply_factor_ <<std::endl;
277  break;
278  }
279  }
280 }
281 
282 // This is an old style constructor. Should change soon...
283 void
285  Size const nres_monomer,
286  Size const njump_monomer,
287  Size const n_subunits,
288  Size const num_virtual,
289  std::map< Size, WtedClones > jump_clones,
290  std::map< Size, SymDof > dofs,
291  Size const score_subunit,
292  utility::vector1< Size > score_multiply_subunit,
293  SymSlideInfo slide_info,
294  Size const num_interfaces,
295  std::string const & type
296 )
297 {
298  nres_monomer_ = nres_monomer;
299 
300  // set number of interfaces
302  // store the score multiplication factors
303  set_score_multiply_from_subunit_factors(score_multiply_subunit, nres_monomer, n_subunits);
304 
305  // store the number of monomer jumps
306  njump_monomer_ = njump_monomer;
307  // store the allowed dofs
308  dofs_ = dofs;
309  // set use symmetry
310  use_symmetry_ = true;
311  // set cp_weighting_during_minimization_ to false
313  // slide info
314  slide_info_ = slide_info;
315  // store type
316  type_ = type;
317  //scoring subunit
318  scoring_subunit_ = score_subunit;
319  // setup bb,chi clones
320  bb_clones_.clear();
321  chi_clones_.clear();
322  jump_clones_.clear();
323 
324  // 1 --> N*njump_monomer : the internal jumps
325  // N*njump_monomer+1 --> N*njump_monomer+N: the pseudo-rsd--monomer jumps
326  // last N-1 jumps : jumps between pseudo-rsds
327 
328  npseudo_ = num_virtual;
329 
330  for ( Size i=1; i<= nres_monomer; ++i ) {
331  Clones clones;
332  int base ( i + ( score_subunit - 1 ) * nres_monomer );
333  for ( Size k=0; k<n_subunits; ++k ) {
334  if ( k+1 != score_subunit ) {
335  clones.push_back( i + k * nres_monomer );
336  add_bb_clone( base, i + k * nres_monomer );
337  add_chi_clone( base, i + k * nres_monomer );
338  }
339  }
340  bb_clones_.insert( std::make_pair( base, clones ) );
341  chi_clones_.insert( std::make_pair( base, clones ) );
342  }
343 
344  // the N*njump_monomer internal jumps
345  for ( Size i=1; i<= njump_monomer; ++i ) {
346  for ( Size k=0; k<n_subunits; ++k ) {
347  if (k != ( score_subunit - 1 ) )
348  add_jump_clone( i + (score_subunit-1)*njump_monomer, i + k*njump_monomer, 0.0 );
349  }
350  //jump_clones_.insert( std::make_pair( i, clones ) );
351  }
352 
353  std::map< Size,WtedClones >::const_iterator it, it_start=jump_clones.begin(), it_end=jump_clones.end();
354  for ( it=it_start; it != it_end; ++it ) {
355  //Clones clones;
356  for ( Size i = 1; i<= it->second.size(); ++i ) {
357  //clones.push_back( it->second[i] + N*njump_monomer );
358  add_jump_clone( it->first + n_subunits*njump_monomer, it->second[i].first + n_subunits*njump_monomer, it->second[i].second );
359  }
360  //jump_clones_.insert( std::make_pair( it->first + N*njump_monomer, clones ) );
361  }
362 
363  // compute the score_multiply_factor
365 }
366 
367 /////////////////////////////////////////////////////////////////////////////
368 template< class T >
369 void
371  std::istream & is,
372  Size const nbase,
373  std::map< Size, utility::vector1< T > > & clones,
374  std::string tag=""
375 )
376 {
377  bool fail( false );
378  std::string tag0;
379  if( tag != "" ) {
380  is >> tag0;
381  if( tag0 != tag ) {
382  TR << "Input failed: tag mismatch " << tag << " " << tag0 << std::endl;
383  return;
384  }
385  }
386  for ( Size i=1; !fail && i<= nbase; ++i ) {
387  std::string jump_string;
388  is >> jump_string;
389  if ( is.fail() ) {
390  fail = true;
391  break;
392  }
393  std::replace( jump_string.begin(), jump_string.end(), ',', ' ' );
394  std::istringstream l( jump_string );
395  Size base_jump;
396  l >> base_jump;
397  if ( l.fail() ) {
398  fail = true;
399  break;
400  }
401  while ( true ) {
402  T j;
403  l >> j;
404  if ( l.fail() ) break;
405  clones[ base_jump ].push_back( j );
406  }
407  if ( clones[ base_jump ].size() < 1 ) {
408  fail = true;
409  break;
410  }
411  }
412  if ( fail ) {
413  is.setstate( std::ios_base::failbit );
414  }
415 }
416 
417 /////////////////////////////////////////////////////////////////////////////
418 template <class T>
419 void
421  std::istream & is,
422  Size const nbase,
423  std::map< Size, T > & clones,
424  std::string tag=""
425 ) {
426  bool fail( false );
427  std::string tag0;
428  if( tag != "" ) {
429  is >> tag0;
430  if( tag0 != tag ) {
431  TR << "Input failed: tag mismatch " << tag << " " << tag0 << std::endl;
432  return;
433  }
434  }
435  for ( Size i=1; !fail && i<= nbase; ++i ) {
436  std::string jump_string;
437  is >> jump_string;
438  if ( is.fail() ) {
439  fail = true;
440  break;
441  }
442  std::replace( jump_string.begin(), jump_string.end(), ',', ' ' );
443  std::istringstream l( jump_string );
444  Size base_jump;
445  l >> base_jump;
446  if ( l.fail() ) {
447  fail = true;
448  break;
449  }
450  l >> clones[ base_jump ];
451  }
452  if ( fail ) {
453  is.setstate( std::ios_base::failbit );
454  }
455 }
456 
457 /////////////////////////////////////////////////////////////////////////////
458 void
460  std::istream & is,
461  Size const nbase,
462  std::map< Size, SymDof > & clones,
463  std::string tag=""
464 )
465 {
466  bool fail( false );
467  std::string tag0;
468  if( tag != "" ) {
469  is >> tag0;
470  if( tag0 != tag ) {
471  TR << "Input failed: tag mismatch " << tag << " " << tag0 << std::endl;
472  return;
473  }
474  }
475  for ( Size i=1; !fail && i<= nbase; ++i ) {
476  std::string jump_string;
477  is >> jump_string;
478  if ( is.fail() ) {
479  fail = true;
480  break;
481  }
482  std::replace( jump_string.begin(), jump_string.end(), ',', ' ' );
483  std::istringstream l( jump_string );
484  Size base_jump;
485  l >> base_jump;
486  std::string dof_line;
487  l >> dof_line;
488  clones[base_jump].read(dof_line);
489  if ( l.fail() ) {
490  fail = true;
491  break;
492  }
493  }
494  if ( fail ) {
495  is.setstate( std::ios_base::failbit );
496  }
497 }
498 
499 /////////////////////////////////////////////////////////////////////////////
500 void
502  std::istream & is,
503  Size const nbase,
504  utility::vector1< Size > & clones,
505  std::string tag=""
506 )
507 {
508  bool fail( false );
509  std::string tag0;
510  if( tag != "" ) {
511  is >> tag0;
512  if( tag0 != tag ) {
513  TR << "Input failed: tag mismatch " << tag << " " << tag0 << std::endl;
514  return;
515  }
516  }
517 
518  std::string jump_string;
519  is >> jump_string;
520  if ( is.fail() ) fail = true;
521  std::replace( jump_string.begin(), jump_string.end(), ',', ' ' );
522  std::istringstream l( jump_string );
523  while ( true ) {
524  Size j;
525  l >> j;
526  if ( l.fail() ) break;
527  clones.push_back( j );
528  }
529  if ( clones.size() != nbase ) {
530  fail = true;
531  }
532 
533  if ( fail ) {
534  is.setstate( std::ios_base::failbit );
535  }
536 }
537 
538 /////////////////////////////////////////////////////////////////////////////
539 template<class CloneType>
541  std::ostream & out,
542  std::map< Size, utility::vector1< CloneType > > clones,
543  std::string tag=""
544 ) {
545  typename std::map< Size,utility::vector1<CloneType> >::const_iterator it;
546  if( tag != "" ) out << ' ' << tag ;
547  for ( it = clones.begin(); it != clones.end(); ++it ) {
548  out << ' ' << it->first;
549  utility::vector1< CloneType > const & l( it->second );
550  for ( Size i=1; i<= l.size(); ++i ) {
551  out << ',' << l[i];
552  }
553  }
554 }
555 
556 
557 /////////////////////////////////////////////////////////////////////////////
558 template< class CloneType >
560  std::ostream & out,
561  std::map< Size, CloneType > clones,
562  std::string tag=""
563 ) {
564  typename std::map< Size , CloneType >::const_iterator it;
565  if( tag != "" ) out << ' ' << tag ;
566  for ( it = clones.begin(); it != clones.end(); ++it ) {
567  out << ' ' << it->first << ',' << it->second ;
568  }
569 }
570 
571 /////////////////////////////////////////////////////////////////////////////
572 void
574  std::ostream & out,
575  std::map< Size, SymDof > clones,
576  std::string tag=""
577 )
578 {
579  if( tag != "" ) out << ' ' << tag ;
580  for ( std::map< Size , SymDof >::const_iterator
581  it = clones.begin(); it != clones.end(); ++it ) {
582  //Dof const & dof (it->second);
583  out << " " << it->first << "," << it->second ;
584  }
585 }
586 
587 /////////////////////////////////////////////////////////////////////////////
588 void
590  std::ostream & out,
592  std::string tag=""
593 )
594 {
595  if( tag != "" ) out << ' ' << tag ;
596  for ( Size i=1; i<= clones.size(); ++i ) {
597  if( i == 1 ) {
598  out << " " << clones[i] ;
599  } else {
600  out << ',' << clones[i] ;
601  }
602  }
603 
604 }
605 
606 /////////////////////////////////////////////////////////////////////////////
607 std::istream& operator>> ( std::istream & s, SymmetryInfo & symminfo )
608 {
609  bool fail( false );
610 
611  std::string tag;
612  Size num_bb_indep, num_chi_indep, num_jump_indep;
613  Size num_bb_dep, num_chi_dep, num_jump_dep;
614  Size num_dof, num_score_multiply;
615 
616  symminfo.set_use_symmetry(true);
617  symminfo.set_cp_weighting_during_minimization(false);
618 
619  s >> tag ;
620  if ( tag != "SYMMETRY_INFO" || s.fail() ) {
621  fail = true;
622  } else {
623  s >> tag >> tag >> tag;
624 
625  //fpd try to ensure backwards compatibility
626  bool old_stream = false;
627  if (tag == "N_RES_MONOMER") {
628  s >> symminfo.nres_monomer_
629  >> tag >> symminfo.scoring_subunit_
630  >> tag >> symminfo.njump_monomer_
631  >> tag;
632  } else {
633  old_stream = true;
634  }
635  s >> symminfo.npseudo_
636  >> tag >> symminfo.interfaces_
637  >> tag >> symminfo.type_
638  >> tag >> num_bb_indep
639  >> tag >> num_chi_indep
640  >> tag >> num_jump_indep
641  >> tag >> num_bb_dep
642  >> tag >> num_chi_dep
643  >> tag >> num_jump_dep
644  >> tag >> num_dof
645  >> tag >> num_score_multiply;
646 
647  if ( s.fail() ) fail = true;
648 
649  // clones
650  comma_strings_to_vector_map( s, num_bb_indep, symminfo.bb_clones_, "BB_CLONES" );
651  comma_strings_to_vector_map( s, num_chi_indep, symminfo.chi_clones_, "CHI_CLONES" );
652  comma_strings_to_vector_map( s, num_jump_indep, symminfo.jump_clones_, "JUMP_CLONES" );
653 
654  if (old_stream) {
655  TR << "Warning: Symmetric input stream is out of date! Trying to recover." << std::endl;
656  // set master jumps to 1; clones to 0
657  for (std::map<Size,SymmetryInfo::Clones>::const_iterator map_it=symminfo.jump_clones_.begin(),
658  map_end=symminfo.jump_clones_.end();
659  map_it != map_end; ++map_it) {
660  for (Size i=1; i<=map_it->second.size(); ++i) {
661  symminfo.jump_clone_wts_[ map_it->second[i] ] = 0;
662  }
663  }
664 
665  // guess at missing parameters
666  symminfo.nres_monomer_ = num_bb_indep;
667  std::map<Size,SymmetryInfo::Clones>::const_iterator first_bb_clone=symminfo.bb_clones_.begin();
668  symminfo.scoring_subunit_ = 1 + ((first_bb_clone->first-1) / symminfo.nres_monomer_);
669  symminfo.njump_monomer_ = 0;
670  } else {
671  comma_strings_to_map( s, num_jump_dep-num_jump_indep, symminfo.jump_clone_wts_, "JUMP_CLONE_WEIGHTS" );
672  old_stream |= (symminfo.jump_clone_wts_.size() == 0);
673  }
674 
675  // follows
676  comma_strings_to_map( s, num_bb_dep, symminfo.bb_follows_, "BB_FOLLOWS" );
677  comma_strings_to_map( s, num_chi_dep, symminfo.chi_follows_, "CHI_FOLLOWS" );
678  comma_strings_to_map( s, num_jump_dep, symminfo.jump_follows_, "JUMP_FOLLOWS" );
679 
680  // dof_
681  comma_strings_to_map( s, num_dof, symminfo.dofs_, "DOFS" );
682 
683  // score_multiply_
684  comma_strings_to_vector( s, num_score_multiply, symminfo.score_multiply_, "SCORE_MULTIPLY" );
685  symminfo.update_score_multiply_factor();
686 
687  //
688  symminfo.set_use_symmetry( true );
689 
690  if ( fail ) {
691  std::cout << "Symmetry_info operator>>: Input failed" << std::endl;
692  s.setstate( std::ios_base::failbit );
693  return s;
694  }
695  }
696 
697  return s;
698 }
699 
700 /////////////////////////////////////////////////////////////////////////////
701 std::ostream& operator<< ( std::ostream & s, const SymmetryInfo & symminfo )
702 {
703  s << "SYMMETRY_INFO " <<
704  "N " << symminfo.subunits() << ' ' <<
705  "N_RES_MONOMER " << symminfo.nres_monomer_ << ' ' <<
706  "SCORING_SUBUNIT " << symminfo.scoring_subunit_ << ' ' <<
707  "N_JUMP_MONOMER " << symminfo.njump_monomer_ << ' ' <<
708  "N_VIRT " << symminfo.npseudo_ << ' ' <<
709  "N_INTERFACE " << symminfo.num_interfaces() << ' ' <<
710  "TYPE " << symminfo.type_ << ' ' <<
711  "BB_CLONES_SIZE " << symminfo.bb_clones_.size() << ' ' <<
712  "CHI_CLONES_SIZE " << symminfo.chi_clones_.size() << ' ' <<
713  "JUMP_CLONES_SIZE " << symminfo.jump_clones_.size() << ' ' <<
714  "BB_FOLLOWS_SIZE " << symminfo.bb_follows_.size() << ' ' <<
715  "CHI_FOLLOWS_SIZE " << symminfo.chi_follows_.size() << ' ' <<
716  "JUMP_FOLLOWS_SIZE " << symminfo.jump_follows_.size() << ' ' <<
717  "DOFS_SIZE " << symminfo.dofs_.size() << ' ' <<
718  "SCORE_MULTIPLY_SIZE " << symminfo.score_multiply_.size() ;
719 
720  // clones
721  vector_map_to_comma_strings( s, symminfo.bb_clones_, "BB_CLONES" );
722  vector_map_to_comma_strings( s, symminfo.chi_clones_, "CHI_CLONES" );
723  vector_map_to_comma_strings( s, symminfo.jump_clones_, "JUMP_CLONES" );
724  map_to_comma_strings( s, symminfo.jump_clone_wts_, "JUMP_CLONE_WEIGHTS" );
725 
726  // follows
727  map_to_comma_strings( s, symminfo.bb_follows_, "BB_FOLLOWS" );
728  map_to_comma_strings( s, symminfo.chi_follows_, "CHI_FOLLOWS" );
729  map_to_comma_strings( s, symminfo.jump_follows_, "JUMP_FOLLOWS" );
730 
731  //dof
732  map_to_comma_strings( s, symminfo.dofs_, "DOFS" );
733 
734  //score_multiply_
735  vector_to_comma_strings( s, symminfo.score_multiply_, "SCORE_MULTIPLY" );
736 
737  return s;
738 }
739 
740 bool
742 std::string const & filename
743 )
744 {
745  bool success = false;
746 
747  utility::io::ozstream output;
748  if ( !utility::file::file_exists( filename ) ) {
749  output.open( filename );
750  } else {
751  output.open_append( filename );
752  }
753 
754  output << *this << '\n';
755 
756  output.close();
757 
758  success = true;
759  return success;
760 }
761 
762 
763 bool
765 std::string const & filename
766 )
767 {
768  bool success = false;
769 
770  utility::io::izstream input ( filename.c_str() );
771  std::istringstream line_stream;
772  std::string line("");
773  if ( !input ) {
774  std::cerr << "ERROR:: Unable to open symmetry info file: "
775  << filename << std::endl;
776  return success;
777  }
778 
779  while( !input.eof() ) {
780  getline(input,line);
781  line_stream.clear();
782  line_stream.str(line);
783  line_stream >> *this;
784  }
785 
786  input.close();
787 
788  success = true;
789  return success;
790 }
791 
792 bool
793 SymmetryInfo::is_virtual( Size const seqpos ) const {
794  return ( seqpos > num_total_residues_without_pseudo() );
795 }
796 
797 Size
798 SymmetryInfo::bb_follows( Size const seqpos ) const
799 {
800  std::map< Size, Size >::const_iterator it( bb_follows_.find( seqpos ) );
801  return ( it == bb_follows_.end() ? 0 : it->second );
802 }
803 
804 Size
805 SymmetryInfo::chi_follows( Size const seqpos ) const
806 {
807  std::map< Size, Size >::const_iterator it( chi_follows_.find( seqpos ) );
808  return ( it == chi_follows_.end() ? 0 : it->second );
809 }
810 
811 Size
812 SymmetryInfo::jump_follows( Size const seqpos ) const
813 {
814  std::map< Size, Size >::const_iterator it( jump_follows_.find( seqpos ) );
815  return ( it == jump_follows_.end() ? 0 : it->second );
816 }
817 
818 std::vector < std::pair < Size, Size > >
820 {
821  std::vector < std::pair < Size, Size > > map;
822  int delta ( res2 - res1 );
823  int mapped_res;
824  for ( std::vector< Size>::const_iterator
825  clone = bb_clones( res1 ).begin(),
826  clone_end = bb_clones( res1 ).end();
827  clone != clone_end; ++clone ){
828  if ( *clone + delta > num_total_residues() ) {
829  mapped_res = (*clone + delta)%num_total_residues();
830  } else {
831  mapped_res = *clone + delta;
832  }
833  if ( mapped_res < 0 )
834  mapped_res += num_independent_residues();
835  map.push_back( std::make_pair( *clone, mapped_res ) );
836  }
837  return map;
838 }
839 
840 bool
842 {
843  return bb_follows(seqpos) == 0;
844 }
845 
846 bool
848 {
849  return chi_follows(seqpos) == 0;
850 }
851 
852 bool
854 {
855  return ( bb_is_independent(seqpos) && chi_is_independent(seqpos) );
856 }
857 
858 bool
860 {
861  return jump_follows(seqpos) == 0;
862 }
863 
864 Size
866 {
867  return num_bb_clones() + 1;
868 }
869 
872 {
873  utility::vector1 < bool > residues;
874  for ( Size i=1; i <=num_total_residues_with_pseudo(); ++i ){
875  if ( bb_is_independent(i) )
876  residues.push_back(true);
877  else
878  residues.push_back(false);
879  }
880  return residues;
881 }
882 
883 Size
885 {
886  // all these lists have the same size
887  if ( bb_clones_.empty() ) {
888  return 0;
889  }
890 
891  return bb_clones_.begin()->second.size();
892 }
893 
894 Size
896 {
897  // all these lists have the same size
898  return chi_clones_.begin()->second.size();
899 }
900 
901 
902 Size
904 {
905  // all these lists have the same size
906  return jump_clones_.begin()->second.size();
907 }
908 
909 Size
911 {
912  return bb_clones_.size();
913 }
914 
915 Size
917 {
918  return num_independent_residues()*( num_bb_clones() + 1 );
919 }
920 
921 Size
923 {
924  return num_independent_residues()*( num_bb_clones() + 1 ) + npseudo_;
925 }
926 
927 Size
929 {
930  return num_independent_residues()*( num_bb_clones() + 1 );
931 }
932 
933 Size
935 {
936  return interfaces_;
937 }
938 
939 Size
941 {
942  return score_multiply_factor_;
943 }
944 
945 Size
947 {
948  return npseudo_;
949 }
950 
951 // bool
952 // SymmetryInfo::scoring_residue(Size residue ) const
953 // {
954 // if ( score_multiply( residue ) == 0 ) return false;
955 // return true;
956 // }
957 
958 SymmetryInfo::Clones const &
959 SymmetryInfo::bb_clones( Size const seqpos ) const
960 {
961  std::map< Size, Clones >::const_iterator it( bb_clones_.find( seqpos ) );
962  if ( it == bb_clones_.end() ) {
963  return empty_list;
964  }
965  return it->second;
966 }
967 
968 SymmetryInfo::Clones const &
969 SymmetryInfo::chi_clones( Size const seqpos ) const
970 {
971  std::map< Size, Clones >::const_iterator it( chi_clones_.find( seqpos ) );
972  if ( it == chi_clones_.end() ) {
973  return empty_list;
974  }
975  return it->second;
976 }
977 
978 SymmetryInfo::Clones const &
979 SymmetryInfo::jump_clones( Size const seqpos ) const
980 {
981  std::map< Size, Clones >::const_iterator it( jump_clones_.find( seqpos ) );
982  if ( it == jump_clones_.end() ) {
983  return empty_list;
984  }
985  return it->second;
986 }
987 
988 //fpd remap bb_clones/chi_clones when the ASU size changes
989 //fpd this recreates the arrays from scratch so it may be somewhat inefficient
990 void
992  if (nres_new == nres_monomer_) return; // nothing to do
993 
994  Size N = subunits();
995 
996  nres_monomer_ = nres_new;
997  bb_clones_.clear();
998  bb_follows_.clear();
999  chi_clones_.clear();
1000  chi_follows_.clear();
1001 
1002  // make empty clones array
1003  for ( Size i=1; i<= nres_monomer_; ++i ) {
1004  Clones clones;
1005  clones.clear();
1006  bb_clones_.insert( std::make_pair( i, clones ) );
1007  chi_clones_.insert( std::make_pair( i, clones ) );
1008  }
1009 
1010  for ( Size i=1; i<= nres_monomer_; ++i ) {
1011  Clones clones;
1012  int base ( i + ( scoring_subunit_ - 1 ) * nres_monomer_ );
1013  for ( Size k=0; k<N; ++k ) {
1014  if ( k+1 != scoring_subunit_ ) {
1015  clones.push_back( i + k * nres_monomer_ );
1016  add_bb_clone( base, i + k * nres_monomer_ );
1017  add_chi_clone( base, i + k * nres_monomer_ );
1018  }
1019  }
1020  bb_clones_.insert( std::make_pair( base, clones ) );
1021  chi_clones_.insert( std::make_pair( base, clones ) );
1022  }
1023 }
1024 
1025 
1026 //fpd remap jump_clones when the number of monomer jumps changes
1027 void
1029  if (njump_monomer == njump_monomer_) return; // nothing to do
1030 
1031  //std::cerr << "SymmetryInfo::update_nmonomer_jumps(" << njump_monomer << ") [old=" << njump_monomer_ << "]\n";
1032  Size N = subunits();
1033 
1034  // remember previous
1035  std::map< Size, Clones > old_jump_clones = jump_clones_;
1036  std::map< Size, Size > old_jump_follows = jump_follows_;
1037  std::map< Size, Real > old_jump_clone_weights = jump_clone_wts_;
1038  Size old_njump_monomer = njump_monomer_;
1039 
1040  njump_monomer_ = njump_monomer;
1041  jump_clones_.clear();
1042  jump_follows_.clear();
1043  jump_clone_wts_.clear();
1044 
1045  // make new monomer jumps from scratch
1046  // the N*njump_monomer internal jumps
1047  for ( Size i=1; i<= njump_monomer; ++i ) {
1048  for ( Size k=0; k<N; ++k ) {
1049  if (k != ( scoring_subunit_ - 1 ) )
1051  }
1052  //jump_clones_.insert( std::make_pair( i, clones ) );
1053  }
1054 
1055  // 1 --> N*njump_monomer : the internal jumps
1056  // N*njump_monomer+1 --> N*njump_monomer+N: the pseudo-rsd--monomer jumps
1057  // last N-1 jumps : jumps between pseudo-rsds
1058  for ( std::map<Size,Clones>::const_iterator it=old_jump_clones.begin(), it_end = old_jump_clones.end();
1059  it != it_end; it++) {
1060  Size source = it->first;
1061  Clones target = it->second;
1062 
1063  if (source > N*old_njump_monomer) {
1064  // a symm jump
1065  Size new_source = source + N*( njump_monomer - old_njump_monomer );
1066  for (Size i=1; i<=target.size(); ++i) {
1067  add_jump_clone( new_source, target[i] + N*(njump_monomer-old_njump_monomer), old_jump_clone_weights[target[i]] );
1068  //std::cerr << "Map (" << source << " , " << target[i] << ") to (" << new_source << " , " << target[i] + N*(njump_monomer-old_njump_monomer) << ")\n";
1069  }
1070  }
1071  }
1072 
1073  // dofs
1074  std::map< Size, SymDof > dofs_new;
1075  for ( std::map< Size, SymDof >::iterator it = dofs_.begin(), it_end = dofs_.end(); it!=it_end; ++it ) {
1076  dofs_new.insert( std::make_pair( it->first + N*( njump_monomer - old_njump_monomer ), it->second ) );
1077  }
1078  set_dofs( dofs_new );
1079 }
1080 
1081 void
1082 SymmetryInfo::add_bb_clone( Size const base_pos, Size const clone_pos )
1083 {
1084  if ( bb_follows_[ base_pos ] != 0 ) {
1085  std::cerr << "Error: add_bb_clone: base_pos is not independent: " <<
1086  base_pos << ' ' << bb_follows_[ base_pos ] << std::endl;
1087  utility_exit();
1088  }
1089  if ( bb_follows_[ clone_pos ] != 0 &&
1090  bb_follows_[ clone_pos ] != base_pos ) {
1091  std::cerr << "Error: add_bb_clone: clone_pos already a follower: " <<
1092  clone_pos << ' ' << bb_follows_[ clone_pos ] << ' ' << base_pos <<
1093  std::endl;
1094  utility_exit();
1095  }
1096 
1097  bb_follows_[ clone_pos ] = base_pos;
1098  bb_clones_[ base_pos ].push_back( clone_pos );
1099 }
1100 
1101 void
1102 SymmetryInfo::add_chi_clone( Size const base_pos, Size const clone_pos )
1103 {
1104  if ( chi_follows_[ base_pos ] != 0 ) {
1105  std::cerr << "Error: add_chi_clone: base_pos is not independent: " <<
1106  base_pos << ' ' << chi_follows_[ base_pos ] << std::endl;
1107  utility_exit();
1108  }
1109  if ( chi_follows_[ clone_pos ] != 0 &&
1110  chi_follows_[ clone_pos ] != base_pos ) {
1111  std::cerr << "Error: add_chi_clone: clone_pos already a follower: " <<
1112  clone_pos << ' ' << chi_follows_[ clone_pos ] << ' ' << base_pos <<
1113  std::endl;
1114  utility_exit();
1115  }
1116 
1117  chi_follows_[ clone_pos ] = base_pos;
1118  chi_clones_[ base_pos ].push_back( clone_pos );
1119 }
1120 
1121 void
1122 SymmetryInfo::add_jump_clone( Size const base_pos, Size const clone_pos, Real const jump_wt )
1123 {
1124  if ( jump_follows_[ base_pos ] != 0 ) {
1125  std::cerr << "Error: add_jump_clone: base_pos is not independent: " <<
1126  base_pos << ' ' << bb_follows_[ base_pos ] << std::endl;
1127  utility_exit();
1128  }
1129  if ( jump_follows_[ clone_pos ] != 0 &&
1130  jump_follows_[ clone_pos ] != base_pos ) {
1131  std::cerr << "Error: add_jump_clone: clone_pos already a follower: " <<
1132  clone_pos << ' ' << jump_follows_[ clone_pos ] << ' ' << base_pos <<
1133  std::endl;
1134  utility_exit();
1135  }
1136 
1137  jump_follows_[ clone_pos ] = base_pos;
1138  jump_clones_[ base_pos ].push_back( clone_pos );
1139  jump_clone_wts_[ clone_pos ] = jump_wt;
1140 }
1141 
1142 std::map< Size, SymDof > const &
1144 {
1145  return dofs_;
1146 }
1147 
1148 void
1149 SymmetryInfo::set_dofs( std::map< Size, SymDof > const & dofs )
1150 {
1151  dofs_ = dofs;
1152 }
1153 
1154 Size
1155 SymmetryInfo::score_multiply( Size const res1, Size const res2 ) const
1156 {
1157  assert ( res1 <= score_multiply_.size() && res2 <= score_multiply_.size() );
1158  assert ( res1 <= score_multiply_.size() && res2 <= score_multiply_.size() );
1159 
1160  //fpd if one of the reses is a symm vrt
1161  //fpd return score_multiply_[i] if the other is in scoring subunit
1162  //fpd return 0 otherwise (since these terms can't be properly minimized)
1163  //fpd this fixes problems with coordinate constraints
1164  if ( res1 > num_total_residues_without_pseudo() ) {
1165  return ( bb_is_independent(res2) ) ? score_multiply_[res2] : 0;
1166  } else if (res2 > num_total_residues_without_pseudo() ) {
1167  return ( bb_is_independent(res1) ) ? score_multiply_[res1] : 0;
1168  } else {
1169  return score_multiply_[ ( bb_is_independent(res1) ) ? res2 : res1 ];
1170  }
1171 }
1172 
1173 
1174 Size
1175 SymmetryInfo::interface_number( Size const res1, Size const res2 ) const
1176 {
1177  return subunit_index(bb_is_independent(res1) ? res2 : res1);
1178 }
1179 
1180 void
1181 SymmetryInfo::set_score_multiply_from_subunit_factors( utility::vector1< Size > const & score_multiply_vector_subunit, Size const nres_subunit, Size const n_subunits )
1182 {
1183  score_multiply_.clear();
1184  for ( Size i = 1; i<= n_subunits; ++i ) {
1185  for ( Size j = 1; j<= nres_subunit; ++j ) {
1186  score_multiply_.push_back( score_multiply_vector_subunit[i] );
1187  }
1188  }
1189  for ( Size i = n_subunits + 1 ; i <= score_multiply_vector_subunit.size() ; ++i ) {
1190  score_multiply_.push_back( score_multiply_vector_subunit[i] );
1191  }
1192 }
1193 
1194 void
1195 SymmetryInfo::set_score_multiply( Size const res, Size const factor )
1196 {
1197  assert ( res <= score_multiply_.size() );
1198  score_multiply_[ res ] = factor;
1199 }
1200 
1201 
1202 Size
1204 {
1205  return nres_monomer_;
1206 }
1207 
1208 Size
1210 {
1211  return njump_monomer_;
1212 }
1213 
1214 
1215 bool
1217 {
1218  return use_symmetry_;
1219 }
1220 
1221 bool
1223 {
1225 }
1226 
1227 void
1229 {
1231 }
1232 
1235 {
1236  return slide_info_;
1237 }
1238 
1239 void
1241 {
1242  use_symmetry_ = setting;
1243 }
1244 
1245 /// @details Returns set of DOF_IDs that follow a given one. Inefficient: it creates a list each time
1247 SymmetryInfo::dependent_dofs( DOF_ID const & id, Conformation const & conf ) const
1248 {
1249  if ( !dof_is_independent( id, conf ) ) {
1250  utility_exit_with_message( "SymmetryInfo::dependent_dofs: dof is not independent!" );
1251  }
1252 
1253  Size const seqpos( id.rsd() );
1254  Size const atomno( id.atomno() );
1255  id::TorsionType const type( guess_torsion_type_of_dof_id( id, conf ) );
1256  Clones const & clones( type == id::JUMP ? jump_clones( conf.fold_tree().get_jump_that_builds_residue( id.rsd() ) ):
1257  ( type == id::BB ? bb_clones( seqpos ) : chi_clones( seqpos ) ) );
1258 
1259  DOF_IDs dofs;
1260  for ( Clones::const_iterator pos= clones.begin(), epos=clones.end(); pos != epos; ++pos ) {
1261  if ( type == id::JUMP ) {
1262  dofs.push_back( DOF_ID( id::AtomID( atomno, conf.fold_tree().downstream_jump_residue( *pos ) ), id.type() ) );
1263  } else {
1264  dofs.push_back( DOF_ID( id::AtomID( atomno, *pos ), id.type() ) );
1265  }
1266  }
1267  return dofs;
1268 }
1269 
1270 ///
1271 bool
1272 SymmetryInfo::dof_is_independent( DOF_ID const & id, Conformation const & conf ) const
1273 {
1274  id::TorsionType const type( guess_torsion_type_of_dof_id( id, conf ) );
1275 
1276  switch ( type ) {
1277  case id::BB:
1278  return bb_is_independent( id.rsd() );
1279  case id::CHI:
1280  return chi_is_independent( id.rsd() );
1281  case id::JUMP:
1282  return jump_is_independent( conf.fold_tree().get_jump_that_builds_residue( id.rsd() ) );
1283  }
1284 
1285  utility_exit_with_message("dof_is_independent: unrecognized TorsionType!");
1286  return false;
1287 }
1288 
1289 // get a weight for derivative calculations
1290 // weights are 1 for indep DOFs, 0 for dependent NON-JUMP DOFs
1291 // and may be any real for dependent jump dofs
1292 core::Real
1294  id::TorsionType const type( guess_torsion_type_of_dof_id( id, conf ) );
1295 
1296  if ( type == id::BB ) {
1297  return bb_is_independent( id.rsd() ) ? 1. : 0.;
1298  } else if ( type == id::CHI ) {
1299  return chi_is_independent( id.rsd() ) ? 1. : 0.;
1300  } else if ( type == id::JUMP ) {
1301  int jumpnum = conf.fold_tree().get_jump_that_builds_residue( id.rsd() );
1302  std::map< Size, Real >::const_iterator it( jump_clone_wts_.find( jumpnum ) );
1303  return ( it == jump_clone_wts_.end() ? 1. : it->second );
1304  }
1305 
1306  utility_exit_with_message("get_dof_derivative_weight: unrecognized TorsionType!");
1307  return false;
1308 }
1309 
1310 
1311 
1312 ///
1313 bool
1315 {
1316  return ( ( id.type() == id::BB && bb_is_independent( id.rsd() ) ) ||
1317  ( id.type() == id::CHI && chi_is_independent( id.rsd() ) ) ||
1318  ( id.type() == id::JUMP && jump_is_independent( id.rsd() ) ) );
1319 }
1320 
1321 bool
1323 {
1324  return fa_is_independent( id.rsd() );
1325 }
1326 
1327 /// @details Returns set of TorsionIDs that follow a given one. Inefficient: it creates a list each time
1330 {
1331  if ( !torsion_is_independent( id ) ) {
1332  utility_exit_with_message( "SymmetryInfo::dependent_torsions: torsion is not independent!" );
1333  }
1334 
1335  Size const seqpos( id.rsd() );
1336  Clones const & seqpos_clones( id.type() == id::BB ? bb_clones( seqpos ) : chi_clones( seqpos ) );
1337 
1338 //std::cerr << " dependent_torsions( TorsionID const & ) bb=" << (id.type() == id::BB) << " chi=" << (id.type() == id::CHI) << " jump=" << (id.type() == id::JUMP) << std::endl;
1339 
1340  TorsionIDs tors;
1341  for ( Clones::const_iterator pos= seqpos_clones.begin(), epos=seqpos_clones.end(); pos != epos; ++pos ) {
1342  tors.push_back( TorsionID( *pos, id.type(), id.torsion() ) );
1343  }
1344  return tors;
1345 }
1346 
1347 /// @details Returns set of AtomIDs that follow a given one. Inefficient: it creates a list each time
1350 {
1351  if ( !atom_is_independent( id ) ) {
1352  utility_exit_with_message( "SymmetryInfo::dependent_atoms: atom is not independent!" );
1353  }
1354  Size const seqpos( id.rsd() );
1355  Clones const & seqpos_clones( bb_clones( seqpos ) );
1356 
1357  AtomIDs atoms;
1358  for ( Clones::const_iterator pos= seqpos_clones.begin(), epos=seqpos_clones.end(); pos != epos; ++pos ) {
1359  atoms.push_back( AtomID( id.atomno(), *pos ) );
1360  }
1361  return atoms;
1362 }
1363 
1364 bool
1366 {
1367  Size nres_monomer = num_independent_residues(), num_monomers = subunits() ;
1368  return ( !get_use_symmetry() || res > nres_monomer*num_monomers || res <= nres_monomer );
1369 }
1370 
1371 Size
1373 {
1374  if( res > 0 && get_use_symmetry() ) {
1375  Size nres_monomer = num_independent_residues(), num_monomers = subunits() ;
1376  return ( res > nres_monomer*num_monomers ? res - nres_monomer*(num_monomers-1) : (res-1)%nres_monomer + 1 );
1377  } else {
1378  return res;
1379  }
1380 }
1381 
1382 Size
1383 SymmetryInfo::subunit_index( Size const seqpos ) const {
1384  return ( (seqpos-1) / num_independent_residues() + 1 );
1385 }
1386 
1389  if( 0 == jnum2dofname_.count(jnum) ) utility_exit_with_message("bad jump num");
1390  return jnum2dofname_.find(jnum)->second;
1391 }
1392 
1393 Size
1395  if( 0 == dofname2jnum_.count(jname) ) utility_exit_with_message("bad jump name");
1396  return dofname2jnum_.find(jname)->second;
1397 }
1398 
1399 void
1401  jnum2dofname_[jnum] = jname;
1402  dofname2jnum_[jname] = jnum;
1403 }
1404 
1405 Size
1407  Size retval = 0;
1408  for(std::map<Size,SymDof>::const_iterator i = dofs_.begin(); i != dofs_.end(); i++) {
1409  if (i->second.allow_dof(1) || i->second.allow_dof(2) || i->second.allow_dof(3)) retval++;
1410  }
1411  return retval;
1412 }
1413 
1414 utility::vector1<char> const &
1416  if(components_.size()==0) utility_exit_with_message("function not for use in single component symmetry");
1417  return components_;
1418 }
1419 
1420 std::map<char,std::pair<Size,Size> > const &
1422  if(components_.size()==0) utility_exit_with_message("function not for use in single component symmetry");
1423  return component_bounds_;
1424 }
1425 
1426 std::map<std::string,char> const &
1428  if(components_.size()==0) utility_exit_with_message("function not for use in single component symmetry");
1429  return name2component_;
1430 }
1431 
1432 std::map<std::string,utility::vector1<char> > const &
1434  if(components_.size()==0) utility_exit_with_message("function not for use in single component symmetry");
1435  return jname2components_;
1436 }
1437 
1438 std::map<std::string,utility::vector1<Size> > const &
1440  if(components_.size()==0) utility_exit_with_message("function not for use in single component symmetry");
1441  return jname2subunits_;
1442 }
1443 std::pair<Size,Size> const &
1445  if(components_.size()==0) utility_exit_with_message("function not for use in single component symmetry");
1446  if( component_bounds_.find(c) == component_bounds_.end() ){
1447  utility_exit_with_message(std::string("no symmetry component ")+c);
1448  }
1449  return component_bounds_.find(c)->second;
1450 }
1451 Size
1453  if(components_.size()==0) utility_exit_with_message("function not for use in single component symmetry");
1454  if( component_bounds_.find(c) == component_bounds_.end() ){
1455  utility_exit_with_message(std::string("no symmetry component ")+c);
1456  }
1457  return component_bounds_.find(c)->second.first;
1458 }
1459 Size
1461  if(components_.size()==0) utility_exit_with_message("function not for use in single component symmetry");
1462  if( component_bounds_.find(c) == component_bounds_.end() ){
1463  utility_exit_with_message(std::string("no symmetry component ")+c);
1464  }
1465  return component_bounds_.find(c)->second.second;
1466 }
1467 char
1469  if(components_.size()==0) utility_exit_with_message("function not for use in single component symmetry");
1470  if( ir > num_total_residues_without_pseudo() || ir < 1 ){
1471  utility_exit_with_message(std::string("no symmetry component for residue "));
1472  }
1473  Size irindep = (ir-1)%num_independent_residues()+1;
1474  for(std::map<char,std::pair<Size,Size> >::const_iterator i = component_bounds_.begin(); i != component_bounds_.end(); ++i){
1475  char component = i->first;
1476  Size lower = i->second.first;
1477  Size upper = i->second.second;
1478  // std::cerr << component << " " << lower << " " << upper << " " << irindep << std::endl;
1479  if( lower <= irindep && irindep <= upper ) return component;
1480  }
1481  utility_exit_with_message(std::string("no symmetry component for residue "));
1482  return ' ';
1483 }
1484 char
1486  if(components_.size()==0) utility_exit_with_message("function not for use in single component symmetry");
1487  if( name2component_.find(vname) == name2component_.end() ){
1488  utility_exit_with_message(std::string("no symmetry component for ")+vname);
1489  }
1490  return name2component_.find(vname)->second;
1491 }
1492 utility::vector1<char> const &
1494  if(components_.size()==0) utility_exit_with_message("function not for use in single component symmetry");
1495  if( jname2components_.find(jname) == jname2components_.end() ){
1496  utility_exit_with_message(std::string("no symmetry component for ")+jname);
1497  }
1498  return jname2components_.find(jname)->second;
1499 }
1500 utility::vector1<Size> const &
1502  if(components_.size()==0) utility_exit_with_message("function not for use in single component symmetry");
1503  if( jname2subunits_.find(jname) == jname2subunits_.end() ){
1504  utility_exit_with_message(std::string("no symmetry component for ")+jname);
1505  }
1506  return jname2subunits_.find(jname)->second;
1507 }
1508 
1509 
1510 void
1512  utility::vector1<char> const & components,
1513  std::map<char,std::pair<Size,Size> > const & component_bounds,
1514  std::map<std::string,char> const & name2component,
1515  std::map<std::string,utility::vector1<char> > const & jname2component,
1516  std::map<std::string,utility::vector1<Size> > const & jname2subunits
1517 ){
1518  components_ = components;
1519  component_bounds_ = component_bounds;
1520  name2component_ = name2component;
1521  jname2components_ = jname2component;
1522  jname2subunits_ = jname2subunits;
1523 }
1524 
1525 
1526 } // symmetry
1527 } // conformation
1528 } // core