27 #include <basic/options/option.hh>
28 #include <basic/options/keys/in.OptionKeys.gen.hh>
29 #include <basic/options/keys/run.OptionKeys.gen.hh>
32 #include <utility/tools/make_map.hh>
33 #include <numeric/xyzVector.hh>
34 #include <ObjexxFCL/string.functions.hh>
36 #include <basic/Tracer.hh>
44 #include <utility/vector1.hh>
50 static basic::Tracer
TR(
"core.io.pdb.pdb_dynamic_reader");
72 if( pdb_records.count(T.
value) ) { R = pdb_records[ T.
value ]; }
73 else { R = pdb_records[
"UNKNOW"]; }
75 for(Record::iterator p=R.begin(); p!=R.end(); p++) (*p).second.getValueFrom(s);
83 std::vector<String> r;
85 while(start < s.size()) {
86 if( s[i] ==
'\n' || s[i] ==
'\r' ) {
87 r.push_back(
String(s.begin()+
start, s.begin()+i) );
96 for(
SSize i=r.size()-1; i>=0; i--) {
97 if( r[i].
size() == 0 ) r.erase( r.begin()+i );
105 runtime_assert(!pdb.empty());
106 std::vector<String> sl =
split(pdb);
107 std::vector<Record> r( sl.size() );
124 bool read_pdb_header =
125 basic::options::option[basic::options::OptionKeys::run::preserve_header]();
126 bool read_link_records =
127 basic::options::option[basic::options::OptionKeys::in::file::read_pdb_link_records]();
131 typedef std::map<char, AtomChain> ChainMap;
135 std::vector< char > chain_list;
136 std::map<char,Size> chain_to_idx;
137 std::map<std::pair<Size,Size>,
char> modelchain_to_chain;
138 std::string chainletters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
139 for(
Size i = 0; i < chainletters.size(); ++i) {
140 modelchain_to_chain[std::pair<Size,Size>(0,i)] = chainletters[i];
141 modelchain_to_chain[std::pair<Size,Size>(1,i)] = chainletters[i];
144 bool modeltags_present =
false;
147 for(
Size i=0; i<VR.size(); i++) {
151 if (record_type ==
"MODEL " ) {
156 if(modeltags_present) {
158 for(
Size model_idx=2;model_idx*chain_to_idx.size()<chainletters.size();++model_idx) {
159 for(
Size chain_idx=1; chain_idx <= chain_to_idx.size(); ++chain_idx) {
160 TR <<
"REARRANGE CHAINS " << model_idx <<
" " << chain_idx <<
" " << (model_idx-1)*chain_to_idx.size()+chain_idx << std::endl;
161 modelchain_to_chain[std::pair<Size,Size>(model_idx,chain_idx)] = chainletters[(model_idx-1)*chain_to_idx.size()+chain_idx-1];
165 if(modelidx > 8) utility_exit_with_message(
"quitting: too many MODELs");
167 modeltags_present =
true;
173 record_type ==
"HEADER" || record_type ==
"KEYWDS" ||
174 record_type ==
"TITLE " || record_type ==
"COMPND" ||
175 record_type ==
"EXPDTA") {
176 if( read_pdb_header ){
182 }
else if (record_type ==
"LINK ") {
183 if (read_link_records) {
188 }
else if (record_type ==
"HETNAM") {
192 }
else if( record_type ==
"ATOM " || record_type ==
"HETATM") {
196 ai.
isHet = (R[
"type"].value ==
"HETATM");
197 ai.
serial = atoi( R[
"serial"].value.c_str() );
198 ai.
name = R[
"name"].value;
199 ai.
altLoc = 0;
if( R[
"altLoc"].value.size() > 0 ) ai.
altLoc = R[
"altLoc"].value[0];
200 ai.
resName = R[
"resName"].value;
202 ai.
chainID = 0;
if( R[
"chainID"].value.size() > 0 ) ai.
chainID = R[
"chainID"].value[0];
204 if( R[
"chainID"].value.size() > 0 ) {
205 char chainid = R[
"chainID"].value[0];
206 if( chain_to_idx.find(chainid) == chain_to_idx.end() ) {
207 chain_to_idx[chainid] = chain_to_idx.size()+1;
208 TR <<
"found new chain " << chainid <<
" " << chain_to_idx.size() << std::endl;
210 ai.
chainID = modelchain_to_chain[std::pair<Size,Size>(modelidx,chain_to_idx[chainid])];
214 ai.
resSeq = atoi( R[
"resSeq"].value.c_str() );
215 ai.
iCode = 0;
if( R[
"iCode"].value.size() > 0 ) ai.
iCode = R[
"iCode"].value[0];
218 bool force_no_occupancy =
false;
219 if( R[
"x"].value ==
" nan"){ai.
x =0.0;force_no_occupancy=
true;}
else { ai.
x = atof( R[
"x"].value.c_str() ); }
220 if( R[
"y"].value ==
" nan"){ai.
y =0.0;force_no_occupancy=
true;}
else { ai.
y = atof( R[
"y"].value.c_str() ); }
221 if( R[
"z"].value ==
" nan"){ai.
z =0.0;force_no_occupancy=
true;}
else { ai.
z = atof( R[
"z"].value.c_str() ); }
225 if( R[
"occupancy"].value ==
" ") ai.
occupancy = 1.0;
226 else ai.
occupancy = atof( R[
"occupancy"].value.c_str() );
227 if(force_no_occupancy) ai.
occupancy = -1.0;
229 ai.
temperature = atof( R[
"tempFactor"].value.c_str() );
230 ai.
element = R[
"element"].value;
234 if ( std::find( chain_list.begin(), chain_list.end(), ai.
chainID ) == chain_list.end() ) {
235 chain_list.push_back( ai.
chainID );
237 }
else if( record_type ==
"TER " || record_type ==
"END ") {
239 }
else if( (record_type ==
"ENDMDL") &&
241 TR.Warning <<
"hit ENDMDL, not reading anything further" << std::endl;
245 }
else if( record_type ==
"REMARK") {
247 ri.
num = atoi( VR[i][
"remarkNum"].value.c_str() ),
248 ri.
value = VR[i][
"value"].value;
254 if( read_pdb_header ) {
258 for (
Size i=0; i< chain_list.size(); ++i ) {
259 fd.
chains.push_back( m.find( chain_list[i] )->second );
277 std::vector<Record> VR(
parse(data) );
285 for(Record::const_iterator p=R.begin(); p!=R.end(); p++ ) {
286 String v = p->second.value; v.resize(p->second.end - p->second.start +1,
' ');
287 s.replace( p->second.start-1, p->second.end - p->second.start +1, v);
297 String r; r.reserve(81*VR.size());
298 for(
Size i=0; i<VR.size(); i++) {
310 lines.reserve( VR.size() );
311 for (
Size i = 0; i < VR.size(); i++ ) {
321 sprintf(&buf[0], format, I);
329 sprintf(&buf[0], format, d);
338 std::vector<Record> VR;
348 R[
"type"].
value =
"REMARK";
349 R[
"remarkNum"].value =
print_i(
"%3d", ri.num);
350 R[
"value"].value = ri.value;
359 R[
"type"].value = (ai.
isHet ?
"HETATM" :
"ATOM ");
361 R[
"name"].value = ai.
name;
362 R[
"resName"].value = ai.
resName;
364 R[
"chainID"].value = cid;
366 R[
"iCode"].value = ai.
iCode;
367 R[
"x"].value =
print_d(
"%8.3f", ai.
x);
368 R[
"y"].value =
print_d(
"%8.3f", ai.
y);
369 R[
"z"].value =
print_d(
"%8.3f", ai.
z);
370 R[
"element"].value = ai.
element;
379 T[
"type"].value =
"TER ";