NAMD
FreeEnergyParse.C
Go to the documentation of this file.
1 
7 // written by David Hurwitz, March to May 1998.
8 
9 #include <ctype.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include "common.h"
13 #include "InfoStream.h"
14 #include "FreeEnergyEnums.h"
15 #include "FreeEnergyAssert.h"
16 #include "Vector.h"
17 #include "FreeEnergyVector.h"
18 #include "FreeEnergyGroup.h"
19 #include "FreeEnergyRestrain.h"
20 #include "FreeEnergyRMgr.h"
21 #include "FreeEnergyLambda.h"
22 #include "FreeEnergyLambdMgr.h"
23 
24 #include "NamdTypes.h"
25 #include "GlobalMaster.h"
26 #include "GlobalMasterFreeEnergy.h"
27 
28 #include "FreeEnergyParse.h"
29 
30 
31 void ProblemParsing(const char* Message, const char* Str, Bool_t Terminate) {
32 //----------------------------------------------------------------------------
33 // print this message if there's a problem parsing
34 //----------------------------------------------------------------------------
35  iout << "FreeEnergy: " << std::endl << endi;
36  iout << "FreeEnergy: ";
37  iout << "Problem parsing input parameters" << std::endl << endi;
38  iout << "FreeEnergy: ";
39  if (Terminate) {
40  iout << " Error: " << Message << std::endl << endi;
41  }
42  else {
43  iout << " Warning: " << Message << std::endl << endi;
44  }
45  iout << "FreeEnergy: ";
46  iout << " Read Until: " << Str << std::endl << endi;
47  iout << "FreeEnergy: " << std::endl << endi;
48  if (Terminate) {
49  NAMD_die("FreeEnergy: Fatal Parsing Error");
50  }
51 }
52 
53 
54 void CheckParentheses(const char* Str) {
55 //----------------------------------------------------------------------------
56 // check for balanced '(' ')' and '{' '}'
57 //----------------------------------------------------------------------------
58  int ParenthesesCount = 0;
59  int CurlyBracketCount = 0;
60 
61  for (unsigned int i=0; i<strlen(Str); i++) {
62  if (Str[i] == '(') {ParenthesesCount++;}
63  if (Str[i] == ')') {ParenthesesCount--;}
64  if (Str[i] == '{') {CurlyBracketCount++;}
65  if (Str[i] == '}') {CurlyBracketCount--;}
66  if ((ParenthesesCount<0) || (CurlyBracketCount<0)) {
67  ProblemParsing("Mismatched Parentheses", Str+i);
68  }
69  }
70 }
71 
72 
73 void ReadInput(char* Str, ARestraintManager& RMgr,
74  ALambdaManager& LMgr,
76  double dT) {
77 //----------------------------------------------------------------------------
78 // parse the input string. Add restraints to RMgr. Add PmfBlocks to LMgr.
79 //----------------------------------------------------------------------------
80  int Count;
81  char* OldStr=NULL; //make sure it's not equal Str to start
82  ALambdaControl PmfBlock, OldPmfBlock;
83  // Bool_t Terminate;
84 
85  // read from Str until can't read anymore
86  ToLower(Str);
87  CheckParentheses(Str);
88  Str += ReadWhite(Str);
89  while (OldStr != Str) {
90  OldStr = Str;
91  // add restraints to restraint manager
92  Str += ReadRestraints(Str, RMgr, CFE);
93  // read a single PmfBlock
94  Count = ReadPmfBlock(Str, PmfBlock, dT);
95  if (Count) {
96  Str += Count;
97  // add it to the Lambda manger
98  LMgr.Add(PmfBlock);
99  // initialize the default parameters of the next PmfBlock
100  OldPmfBlock = PmfBlock;
101  PmfBlock.Init(OldPmfBlock);
102  }
103  }
104  Str += ReadWhite(Str);
105  if (strlen(Str) > 0) {
106  ProblemParsing("Unable to Read Entire Input File", Str, /* Terminate= */ kFalse);
107  }
108 }
109 
110 
111 int ReadPmfBlock(char* Str, ALambdaControl& PmfBlock, double dT) {
112 //----------------------------------------------------------------------------
113 // if str starts with "pmf" or "mcti", read all the specs for this block
114 // and initialize PmfBlock.
115 //
116 // PmfBlock will already have default values for all parameters.
117 // The parameters that are read will be used to override the defaults.
118 // LambdaKf and LambdaRef are initialized after all parameters have been
119 // read, because the meaning of these parameters depends upon the task.
120 //
121 // If time-units (fs, ps, ns) are not specified, use ps
122 //
123 // return the number of chars to read past this block.
124 // return 0 if Str does not start with "pmf" or "mcti"
125 //----------------------------------------------------------------------------
126  int Count, Count1, Count2;
127  Bool_t Finished=kFalse;
128  char* FullString=Str;
129  char* TempStr;
130  pmf_t PmfSpec;
131  // if time-units are not specified, then they're in ps.
132  TimeUnits_t TimeUnits;
133  TimeUnits_t DefaultTimeUnits = k_ps;
134  // illegal default value. user will have to specify this.
135  feptask_t Task=kUnknownTask;
136  double Lambda=-1, LambdaT=-1, Time;
137  double Dummy;
138  int NumRepeats=-1;
139 
140  const Bool_t kPrintErrMsg=kTrue; // kNoErrMsg=kFalse;
141 
142  // if Str does not begin with "pmf" or "mcti" return 0
143  Count1 = ReadWord(Str, "pmf");
144  Count2 = ReadWord(Str, "mcti");
145  Count = Count1 + Count2;
146  if (Count==0) {
147  return(0);
148  }
149 
150  // skip past "pmf" or "mcti"
151  Str += Count;
152  // skip past "{"
153  Str += ReadChar(Str, '{');
154  // read spec's until "}" is found or can't read a spec
155  do {
156  Count = ReadNextPmfSpec(Str, PmfSpec);
157  Str += Count;
158  if (Count==0) {
159  ProblemParsing("Unable to Read PMF Specification", Str);
160  }
161  // skip past "="
162  Str += ReadChar(Str, '=');
163  switch (PmfSpec) {
164  case kTask:
165  TempStr = Str;
166  Str += ReadTaskType(Str, Task);
167  if (Str == TempStr) {
168  ProblemParsing("Can't Read Task", Str);
169  }
170  PmfBlock.SetTask(Task);
171  break;
172  case kTime:
173  Str += ReadAValue(Str, Time, kPrintErrMsg);
174  Str += ReadTimeUnits(Str, TimeUnits, DefaultTimeUnits);
175  Time = GetTime(Time, TimeUnits);
176  PmfBlock.SetNumSteps((int)(Time/dT));
177  break;
178  case kLambda:
179  Str += ReadAValue(Str, Lambda, kPrintErrMsg);
180  break;
181  case kLambdaT:
182  Str += ReadAValue(Str, LambdaT, kPrintErrMsg);
183  break;
184  case kPrint:
185  Str += ReadAValue(Str, Time, kPrintErrMsg);
186  Str += ReadTimeUnits(Str, TimeUnits, DefaultTimeUnits);
187  Time = GetTime(Time, TimeUnits);
188  PmfBlock.SetNumPrintSteps((int)(Time/dT));
189  break;
190  case kNoPrint:
191  PmfBlock.SetNumPrintSteps(-1);
192  break;
193  case kEquilTime:
194  Str += ReadAValue(Str, Time, kPrintErrMsg);
195  Str += ReadTimeUnits(Str, TimeUnits, DefaultTimeUnits);
196  Time = GetTime(Time, TimeUnits);
197  PmfBlock.SetNumEquilSteps((int)(Time/dT));
198  break;
199  case kAccumTime:
200  Str += ReadAValue(Str, Time, kPrintErrMsg);
201  Str += ReadTimeUnits(Str, TimeUnits, DefaultTimeUnits);
202  Time = GetTime(Time, TimeUnits);
203  PmfBlock.SetNumAccumSteps((int)(Time/dT));
204  break;
205  case kNumRepeats:
206  Str += ReadAValue(Str, Dummy, kPrintErrMsg);
207  NumRepeats = (int)Dummy;
208  PmfBlock.SetNumRepeats(NumRepeats);
209  break;
210  default:
211  ASSERT(kFalse);
212  }
213  Count = ReadChar(Str, '}');
214  Str += Count;
215  // if "}" was read, then we're finished
216  if (Count!=0) {Finished=kTrue;}
217  }
218  while(!Finished);
219 
220  // if Task was not specified above, then use PmfBlock's default task
221  if (Task==kUnknownTask) {
222  Task = PmfBlock.GetTask();
223  }
224  // if Task wasn't specified earlier, die.
225  if (Task==kUnknownTask) {
226  ProblemParsing("Must Specify Task", FullString);
227  }
228 
229  // set LambdaKf and LambdaRef, using Lambda and LambdaT
230  // (the former is the internal representation, the latter is the user's)
231  // there's no need to set them if they haven't been read in this routine
232  switch(Task) {
233  case kStop:
234  PmfBlock.SetLambdaKf(1.0);
235  if (Lambda >= -kALittle) {
236  PmfBlock.SetLambdaRef(Lambda);
237  }
238  break;
239  case kNoGrow:
240  if (Lambda >= -kALittle) {
241  PmfBlock.SetLambdaKf(Lambda);
242  }
243  case kGrow:
244  case kFade:
245  case kStepGrow:
246  case kStepFade:
247  if (LambdaT >= -kALittle) {
248  PmfBlock.SetLambdaRef(LambdaT);
249  }
250  break;
251  default:
252  ASSERT((Task==kUp)||(Task==kDown)||(Task==kStepUp)||(Task==kStepDown));
253  PmfBlock.SetLambdaKf(1.0);
254  break;
255  }
256 
257  return(Str-FullString);
258 }
259 
260 
261 double GetTime(double Val, TimeUnits_t Units) {
262 //----------------------------------------------------------------------------
263 // convert (Val Units) to fs, where Units is either fs, ps, or ns
264 //----------------------------------------------------------------------------
265  switch (Units) {
266  case k_fs: return(Val);
267  case k_ps: return(Val*1000);
268  case k_ns: return(Val*1000000);
269  default:
270  ASSERT(kFalse);
271  return(Val);
272  }
273 }
274 
275 
276 int ReadTimeUnits(char* Str, TimeUnits_t& Units, TimeUnits_t DefaultUnits) {
277 //----------------------------------------------------------------------------
278 // Str should start with one of:
279 // "fs", "ps", or "ns"
280 //
281 // If Str starts with one of the above, return an identifier for the above.
282 // if Str does not start with one of the above, set Units to DefaultUnits.
283 //
284 // return the number of chars to read past the time units. return 0 if
285 // Str does not start with one of the above.
286 //----------------------------------------------------------------------------
287  char* FullString=Str;
288  Bool_t FoundIt=kFalse;
289 
290  if (strncmp(Str,"fs",2)==0) {Units=k_fs; FoundIt=kTrue;}
291  if (strncmp(Str,"ps",2)==0) {Units=k_ps; FoundIt=kTrue;}
292  if (strncmp(Str,"ns",2)==0) {Units=k_ns; FoundIt=kTrue;}
293 
294  if (FoundIt) {
295  Str += ReadAlpha(Str);
296  Str += ReadWhite(Str);
297  }
298  else {
299  Units = DefaultUnits;
300  }
301  return(Str-FullString);
302 }
303 
304 
305 int ReadTaskType(char* Str, feptask_t& Task) {
306 //----------------------------------------------------------------------------
307 // Str should start with a task, one of:
308 // "up", "down", "stop", "grow", "fade", "nogrow",
309 // "stepup", "stepdown", "stepgrow", "stepfade"
310 //
311 // return an identifer for the above.
312 // return the number of chars to read past the task. return 0 if Str does
313 // not start with one of the above.
314 //----------------------------------------------------------------------------
315  char* FullString=Str;
316 
317  Task = kUnknownTask;
318  if (strncmp(Str,"up",2)==0) {Task=kUp; goto GotIt;}
319  if (strncmp(Str,"down",4)==0) {Task=kDown; goto GotIt;}
320  if (strncmp(Str,"stop",4)==0) {Task=kStop; goto GotIt;}
321  if (strncmp(Str,"grow",4)==0) {Task=kGrow; goto GotIt;}
322  if (strncmp(Str,"fade",4)==0) {Task=kFade; goto GotIt;}
323  if (strncmp(Str,"nogrow",6)==0) {Task=kNoGrow; goto GotIt;}
324  if (strncmp(Str,"stepup",6)==0) {Task=kStepUp; goto GotIt;}
325  if (strncmp(Str,"stepdown",8)==0) {Task=kStepDown; goto GotIt;}
326  if (strncmp(Str,"stepgrow",8)==0) {Task=kStepGrow; goto GotIt;}
327  if (strncmp(Str,"stepfade",8)==0) {Task=kStepFade; goto GotIt;}
328  return(0);
329 
330 GotIt:
331  Str += ReadAlpha(Str);
332  Str += ReadWhite(Str);
333  return(Str-FullString);
334 }
335 
336 
337 int ReadNextPmfSpec(char* Str, pmf_t& PmfSpec) {
338 //----------------------------------------------------------------------------
339 // Str should start with the next spec for a pmf or mcti block, one of:
340 // "task", "time", "lambda", "lambdaT", "print",
341 // "equiltime", "accumtime", "numsteps"
342 //
343 // Return an identifier of the above.
344 // Return number of characters, including trailing white space to read past
345 // this word. Return NumChars=0 if Str does not begin with one of the above.
346 //----------------------------------------------------------------------------
347  char* FullString=Str;
348 
349  PmfSpec = kUnknownPmf;
350  if (strncmp(Str,"task",4)==0) {PmfSpec=kTask; goto GotIt;}
351  if (strncmp(Str,"time",4)==0) {PmfSpec=kTime; goto GotIt;}
352  // check for lambdat first, else PmfSpec will be kLambda for "lambdat"
353  if (strncmp(Str,"lambdat",7)==0) {PmfSpec=kLambdaT; goto GotIt;}
354  if (strncmp(Str,"lambda",6)==0) {PmfSpec=kLambda; goto GotIt;}
355  if (strncmp(Str,"print",5)==0) {PmfSpec=kPrint; goto GotIt;}
356  if (strncmp(Str,"nopr",4)==0) {PmfSpec=kNoPrint; goto GotIt;}
357  if (strncmp(Str,"equil",5)==0) {PmfSpec=kEquilTime; goto GotIt;}
358  if (strncmp(Str,"accum",5)==0) {PmfSpec=kAccumTime; goto GotIt;}
359  if (strncmp(Str,"numstep",7)==0) {PmfSpec=kNumRepeats; goto GotIt;}
360  return(0);
361 
362 GotIt:
363  Str += ReadAlpha(Str);
364  Str += ReadWhite(Str);
365  return(Str-FullString);
366 }
367 
368 
369 int ReadRestraints(char* Str, ARestraintManager& AllRestraints,
370  GlobalMasterFreeEnergy& CFE) {
371 //----------------------------------------------------------------------------
372 // if Str starts with "urestr", read each restraint spec, create
373 // a restraint, and put a pointer to the restraint into AllRestraints
374 //
375 // return the number of chars to read past all restraints
376 // return 0 if Str does not start with "urestr"
377 //----------------------------------------------------------------------------
378  int Count;
379  Bool_t Finished=kFalse;
380  char* FullString=Str;
381  ARestraint* pRestraint;
382 
383  Count = ReadWord(Str, "urest");
384  // when "urestraint" is found
385  if (Count) {
386  // skip past "urest..."
387  Str += Count;
388  // skip past "{"
389  Str += ReadChar(Str, '{');
390  // read restraints until "}" is found or can't read a restraint
391  do {
392  pRestraint = GetRestraint(Str, Count, CFE);
393  Str += Count;
394  // if a restraint could not be read, then we're finished
395  if (Count==0) {Finished=kTrue;}
396  if (!Finished) {
397  AllRestraints.Add(pRestraint);
398  Count = ReadChar(Str, '}');
399  Str += Count;
400  // if "}" was read, then we're finished
401  if (Count!=0) {Finished=kTrue;}
402  }
403  }
404  while(!Finished);
405  }
406  return(Str-FullString);
407 }
408 
409 
410 ARestraint* GetRestraint(char* Str, int& NumChars, GlobalMasterFreeEnergy& CFE) {
411 //----------------------------------------------------------------------------
412 // read spec's for a restraint, from the input string.
413 // allocate space for and initialize a restraint object with these specs.
414 // note: memory is allocated here, and free'd elsewhere.
415 //
416 // return a pointer to this object.
417 // return the number of characters to read past these specs.
418 // return NumChars=0 for illegal restraint specs.
419 //----------------------------------------------------------------------------
420  AGroup Group1, Group2, Group3, Group4;
421  ARestraint* pRestraint = NULL;
422  restr_t Restraint;
423  Bound_t Bound;
424  int Count;
425  double Kf;
426  double D, D0, D1;
427  double A=0, A0=0, A1=0, A2=0;
428  AVector Pos, Pos0, Pos1;
429  char* FullStr;
430  char* TempStr;
431 
432  const Bool_t kPrintErrMsg=kTrue; // kNoErrMsg=kFalse;
433 
434  // save pointer to full string
435  FullStr = Str;
436  NumChars = 0;
437 
438  // get restraint type
439  Restraint = ReadNextRestraintType(Str, Count);
440  if (Count == 0) {
441  ProblemParsing("Can't Read Restraint Type", Str);
442  return(pRestraint);
443  }
444 
445  // skip past restraint type
446  ASSERT(Restraint != kUnknownRestr);
447  Str += Count;
448 
449  // read in appropriate number of atoms or groups-of-atoms for
450  // this restraint type, put the atoms in Group1 thru Group4
451  switch (Restraint) {
452  case kDihe: case kDiheBound: case kDihePMF:
453  Str += AddAtoms(Group4, Str, CFE);
454  case kAngle: case kAngleBound: case kAnglePMF:
455  Str += AddAtoms(Group3, Str, CFE);
456  case kDist: case kDistBound: case kDistPMF:
457  Str += AddAtoms(Group2, Str, CFE);
458  case kPosi: case kPosiBound: case kPosiPMF:
459  Str += AddAtoms(Group1, Str, CFE);
460  default: ;
461  }
462 
463  // for dihedrals, allow keywords of "barr=", "gap=", OR "kf="
464  // for other restraints, just allow "kf="
465  TempStr = Str;
466  switch(Restraint) {
467  case kDihe:
468  case kDiheBound:
469  case kDihePMF:
470  Str += ReadWord(Str, "barr");
471  Str += ReadWord(Str, "gap");
472  default:
473  Str += ReadWord(Str, "kf");
474  // make sure the word "barr", "gap", or "kf" was read
475  if (Str==TempStr) {
476  ProblemParsing("Word Missing: barr, gap, or kf", Str);
477  }
478  Str += ReadChar(Str, '=');
479  }
480  // get the Kf value
481  Str += ReadAValue(Str, Kf, kPrintErrMsg);
482 
483  // read the reference positions, distances or angles
484  switch (Restraint) {
485  case kPosi:
486  Str += ReadWord(Str, "ref", kPrintErrMsg);
487  Str += ReadChar(Str, '=');
488  Str += ReadChar(Str, '(');
489  Str += ReadAValue(Str, Pos[0], kPrintErrMsg);
490  Str += ReadAValue(Str, Pos[1], kPrintErrMsg);
491  Str += ReadAValue(Str, Pos[2], kPrintErrMsg);
492  Str += ReadChar(Str, ')');
493  break;
494  case kDist:
495  Str += ReadWord(Str, "ref", kPrintErrMsg);
496  Str += ReadChar(Str, '=');
497  Str += ReadAValue(Str, D, kPrintErrMsg);
498  break;
499  case kAngle:
500  Str += ReadWord(Str, "ref", kPrintErrMsg);
501  Str += ReadChar(Str, '=');
502  Str += ReadAValue(Str, A, kPrintErrMsg);
503  break;
504  case kDihe:
505  Str += ReadWord(Str, "ref", kPrintErrMsg);
506  Str += ReadChar(Str, '=');
507  Str += ReadAValue(Str, A, kPrintErrMsg);
508  break;
509  case kPosiBound:
510  if (ReadBound(Str, Bound) == 0) {ProblemParsing("Missing Bound", Str);}
511  Str += ReadWord(Str, "low");
512  Str += ReadWord(Str, "hi");
513  Str += ReadChar(Str, '=');
514  Str += ReadChar(Str, '(');
515  Str += ReadAValue(Str, Pos[0], kPrintErrMsg);
516  Str += ReadAValue(Str, Pos[1], kPrintErrMsg);
517  Str += ReadAValue(Str, Pos[2], kPrintErrMsg);
518  Str += ReadAValue(Str, D, kPrintErrMsg);
519  Str += ReadChar(Str, ')');
520  break;
521  case kDistBound:
522  if (ReadBound(Str, Bound) == 0) {ProblemParsing("Missing Bound", Str);}
523  Str += ReadWord(Str, "low");
524  Str += ReadWord(Str, "hi");
525  Str += ReadChar(Str, '=');
526  Str += ReadAValue(Str, D, kPrintErrMsg);
527  break;
528  case kAngleBound:
529  if (ReadBound(Str, Bound) == 0) {ProblemParsing("Missing Bound", Str);}
530  Str += ReadWord(Str, "low");
531  Str += ReadWord(Str, "hi");
532  Str += ReadChar(Str, '=');
533  Str += ReadAValue(Str, A, kPrintErrMsg);
534  break;
535  case kDiheBound:
536  Str += ReadWord(Str, "low", kPrintErrMsg);
537  Str += ReadChar(Str, '=');
538  Str += ReadAValue(Str, A0, kPrintErrMsg);
539  Str += ReadWord(Str, "hi", kPrintErrMsg);
540  Str += ReadChar(Str, '=');
541  Str += ReadAValue(Str, A1, kPrintErrMsg);
542  Str += ReadWord(Str, "delta", kPrintErrMsg);
543  Str += ReadChar(Str, '=');
544  Str += ReadAValue(Str, A2, kPrintErrMsg);
545  break;
546  case kPosiPMF:
547  Str += ReadWord(Str, "low", kPrintErrMsg);
548  Str += ReadChar(Str, '=');
549  Str += ReadChar(Str, '(');
550  Str += ReadAValue(Str, Pos0[0], kPrintErrMsg);
551  Str += ReadAValue(Str, Pos0[1], kPrintErrMsg);
552  Str += ReadAValue(Str, Pos0[2], kPrintErrMsg);
553  Str += ReadChar(Str, ')');
554  Str += ReadWord(Str, "hi", kPrintErrMsg);
555  Str += ReadChar(Str, '=');
556  Str += ReadChar(Str, '(');
557  Str += ReadAValue(Str, Pos1[0], kPrintErrMsg);
558  Str += ReadAValue(Str, Pos1[1], kPrintErrMsg);
559  Str += ReadAValue(Str, Pos1[2], kPrintErrMsg);
560  Str += ReadChar(Str, ')');
561  break;
562  case kDistPMF:
563  Str += ReadWord(Str, "low", kPrintErrMsg);
564  Str += ReadChar(Str, '=');
565  Str += ReadAValue(Str, D0, kPrintErrMsg);
566  Str += ReadWord(Str, "hi", kPrintErrMsg);
567  Str += ReadChar(Str, '=');
568  Str += ReadAValue(Str, D1, kPrintErrMsg);
569  break;
570  case kAnglePMF:
571  Str += ReadWord(Str, "low", kPrintErrMsg);
572  Str += ReadChar(Str, '=');
573  Str += ReadAValue(Str, A0, kPrintErrMsg);
574  Str += ReadWord(Str, "hi", kPrintErrMsg);
575  Str += ReadChar(Str, '=');
576  Str += ReadAValue(Str, A1, kPrintErrMsg);
577  break;
578  case kDihePMF:
579  Str += ReadWord(Str, "low", kPrintErrMsg);
580  Str += ReadChar(Str, '=');
581  Str += ReadAValue(Str, A0, kPrintErrMsg);
582  Str += ReadWord(Str, "hi", kPrintErrMsg);
583  Str += ReadChar(Str, '=');
584  Str += ReadAValue(Str, A1, kPrintErrMsg);
585  break;
586  default: ;
587  }
588 
589  // convert degrees to radians
590  A *= (kPi/180);
591  A0 *= (kPi/180);
592  A1 *= (kPi/180);
593  A2 *= (kPi/180);
594 
595  // initialize the restraint
596  switch (Restraint) {
597  case kPosi:
598  pRestraint = new AFixedPosRestraint;
599  pRestraint->SetKf(Kf);
600  pRestraint->SetGroups(Group1);
601  pRestraint->SetRefPos(Pos);
602  break;
603  case kDist:
604  pRestraint = new AFixedDistRestraint;
605  pRestraint->SetKf(Kf);
606  pRestraint->SetGroups(Group2, Group1);
607  pRestraint->SetRefDist(D);
608  break;
609  case kAngle:
610  pRestraint = new AFixedAngleRestraint;
611  pRestraint->SetKf(Kf);
612  pRestraint->SetGroups(Group3, Group2, Group1);
613  pRestraint->SetRefAngle(A);
614  break;
615  case kDihe:
616  pRestraint = new AFixedDiheRestraint;
617  pRestraint->SetKf(Kf);
618  pRestraint->SetGroups(Group4, Group3, Group2, Group1);
619  pRestraint->SetRefAngle(A);
620  break;
621  case kPosiBound:
622  pRestraint = new ABoundPosRestraint;
623  pRestraint->SetKf(Kf);
624  pRestraint->SetGroups(Group1);
625  pRestraint->SetRefPos(Pos);
626  pRestraint->SetRefDist(D);
627  pRestraint->SetBound(Bound);
628  break;
629  case kDistBound:
630  pRestraint = new ABoundDistRestraint;
631  pRestraint->SetKf(Kf);
632  pRestraint->SetGroups(Group2, Group1);
633  pRestraint->SetRefDist(D);
634  pRestraint->SetBound(Bound);
635  break;
636  case kAngleBound:
637  pRestraint = new ABoundAngleRestraint;
638  pRestraint->SetKf(Kf);
639  pRestraint->SetGroups(Group3, Group2, Group1);
640  pRestraint->SetRefAngle(A);
641  pRestraint->SetBound(Bound);
642  break;
643  case kDiheBound:
644  pRestraint = new ABoundDiheRestraint;
645  pRestraint->SetKf(Kf);
646  pRestraint->SetGroups(Group4, Group3, Group2, Group1);
647  pRestraint->SetLowerAngle(A0);
648  pRestraint->SetUpperAngle(A1);
649  pRestraint->SetIntervalAngle(A2);
650  break;
651  case kPosiPMF:
652  pRestraint = new AForcingPosRestraint;
653  pRestraint->SetKf(Kf);
654  pRestraint->SetGroups(Group1);
655  pRestraint->SetStartPos(Pos0);
656  pRestraint->SetStopPos(Pos1);
657  break;
658  case kDistPMF:
659  pRestraint = new AForcingDistRestraint;
660  pRestraint->SetKf(Kf);
661  pRestraint->SetGroups(Group2, Group1);
662  pRestraint->SetStartDist(D0);
663  pRestraint->SetStopDist(D1);
664  break;
665  case kAnglePMF:
666  pRestraint = new AForcingAngleRestraint;
667  pRestraint->SetKf(Kf);
668  pRestraint->SetGroups(Group3, Group2, Group1);
669  pRestraint->SetStartAngle(A0);
670  pRestraint->SetStopAngle(A1);
671  break;
672  case kDihePMF:
673  pRestraint = new AForcingDiheRestraint;
674  pRestraint->SetKf(Kf);
675  pRestraint->SetGroups(Group4, Group3, Group2, Group1);
676  pRestraint->SetStartAngle(A0);
677  pRestraint->SetStopAngle(A1);
678  break;
679  default: ;
680  }
681  // calc number of chars to read restraint specs
682  NumChars = Str-FullStr;
683  return(pRestraint);
684 }
685 
686 
687 int ReadBound(char* Str, Bound_t& Bound) {
688 //----------------------------------------------------------------------------
689 // Str should start with "low" or "hi". determine which it is and
690 // count the number of characters to read past this word + white-space.
691 // return NumChars=0 if Str does not start with "low" or "hi"
692 //----------------------------------------------------------------------------
693  int Count;
694 
695  Bound = kUnknownBound;
696  Count = ReadWord(Str, "low");
697  if (Count) {
698  Bound=kLower;
699  return(Count);
700  }
701 
702  Count = ReadWord(Str, "hi");
703  if (Count) {
704  Bound=kUpper;
705  return(Count);
706  }
707 
708  return(Count); // Count will be 0 if "low" or "hi" wasn't found
709 }
710 
711 
712 int ReadAValue(char* Str, double& Value, Bool_t ErrMsg) {
713 //----------------------------------------------------------------------------
714 // Str should start with a floating point number. convert it to a double.
715 // also, return the number of chars to read past the value + white-space
716 // return NumChars = 0 if Str does not start with a valid fp number.
717 // Print an error message if ErrMsg is kTrue, and no value is read.
718 //----------------------------------------------------------------------------
719  int NumChars;
720  char* NewStr;
721 
722  // read f.p. number and trailing white-space
723  Value = strtod(Str, &NewStr);
724  if (NewStr != Str) {
725  NewStr += ReadWhite(NewStr);
726  }
727  NumChars = NewStr - Str;
728 
729  // if no number was read, and ErrMsg is kTrue, print a message
730  if ((NumChars==0) && (ErrMsg)) {
731  ProblemParsing("Floating Point Number Expected", Str);
732  }
733 
734  return(NumChars);
735 }
736 
737 
738 int ReadChar(char* Str, char Char, Bool_t ErrMsg) {
739 //----------------------------------------------------------------------------
740 // Str should start with Char plus trailing white space.
741 // return the number of chars, including the white space, to read past Char
742 // return 0 if Str does not start with Char.
743 // Print an error message if ErrMsg is kTrue, and Char is not read.
744 //----------------------------------------------------------------------------
745  int NumChars;
746  char* FullString=Str;
747  char Message[64];
748 
749  // initial part of Message
750  strcpy(Message, "Character Missing: ");
751 
752  // read char and trailing white-space
753  if (Str[0] == Char) {
754  Str += 1;
755  Str += ReadWhite(Str);
756  }
757  NumChars = Str - FullString;
758 
759  // if Char was not read, and ErrMsg is kTrue, print a message
760  if ((NumChars==0) && (ErrMsg)) {
761  // add the character that's missing to Message
762  Message[strlen(Message)-1] = Char;
763  ProblemParsing(Message, Str);
764  }
765 
766  return(NumChars);
767 }
768 
769 
770 int ReadWord(const char* Str, const char* Word, Bool_t ErrMsg) {
771 //----------------------------------------------------------------------------
772 // Str should start with Word plus, perhaps, some extra alphabetic
773 // characters, plus trailing white space.
774 //
775 // (do NOT read past numeric characters which follow Word, so that
776 // this routine can be used on the following: ReadWord(Str, "="),
777 // where Str is, for example, "=123 ...")
778 //
779 // return the number of chars, including the white space, to read past Word
780 // return 0 if Str does not start with Word.
781 //
782 // Print an error message if ErrMsg is kTrue, and word is not read.
783 //----------------------------------------------------------------------------
784  const char* FullString=Str;
785  int NumChars, StrLen;
786  char Message[64];
787 
788  // initial part of message
789  strcpy(Message, "Word Missing: ");
790 
791  StrLen = strlen(Word);
792  if (strncmp(Str, Word, StrLen) == 0) {
793  Str += StrLen;
794  Str += ReadAlpha(Str);
795  Str += ReadWhite(Str);
796  }
797  NumChars = Str - FullString;
798 
799  // if Word was not read, and ErrMsg is kTrue, print a message
800  if ((NumChars==0) && (ErrMsg)) {
801  strcat(Message, Word);
802  ProblemParsing(Message, Str);
803  }
804 
805  return(NumChars);
806 }
807 
808 
809 restr_t ReadNextRestraintType(char* Str, int& NumChars) {
810 //----------------------------------------------------------------------------
811 // Str should start with the next restraint type (no leading white space),
812 // namely one of:
813 //
814 // "posi", "dist", "angle", "dihe"
815 // "posi bound", "dist bound", "angle bound", "dihe bound"
816 // "posi pmf", "dist pmf", "angle pmf", "dihe pmf"
817 //
818 // figure out which it is.
819 // also, return the number of characters, including trailing white space.
820 // return NumChars=0 for an illegal restraint-type
821 //
822 // the words "pos*", "dist*", "angle*", "dihe*", "bound*", and "pmf*"
823 // are all recognized.
824 //----------------------------------------------------------------------------
825  restr_t RestraintType=kUnknownRestr;
826  char* FullString=Str;
827 
828  // check if Str starts with "pos", "dist", "angl", or "dihe"
829  if (strncmp(Str,"pos", 3)==0) {RestraintType=kPosi; goto GotIt;}
830  if (strncmp(Str,"dist",4)==0) {RestraintType=kDist; goto GotIt;}
831  if (strncmp(Str,"angl",4)==0) {RestraintType=kAngle; goto GotIt;}
832  if (strncmp(Str,"dihe",4)==0) {RestraintType=kDihe; goto GotIt;}
833  NumChars = 0;
834  return(RestraintType);
835 
836  // skip to the end of the white space following this word
837 GotIt:
838  Str += 3;
839  Str += ReadAlphaNum(Str);
840  Str += ReadWhite(Str);
841 
842  // check if the next word is "bound", skip to the end of this word
843  if (strncmp(Str,"bound",5)==0) {
844  switch (RestraintType) {
845  case kPosi: RestraintType=kPosiBound; break;
846  case kDist: RestraintType=kDistBound; break;
847  case kAngle: RestraintType=kAngleBound; break;
848  case kDihe: RestraintType=kDiheBound; break;
849  default: break;
850  }
851  Str += 5;
852  Str += ReadAlphaNum(Str);
853  }
854 
855  // check if the next word is "pmf", skip to the end of this word
856  if (strncmp(Str,"pmf",3)==0) {
857  switch (RestraintType) {
858  case kPosi: RestraintType=kPosiPMF; break;
859  case kDist: RestraintType=kDistPMF; break;
860  case kAngle: RestraintType=kAnglePMF; break;
861  case kDihe: RestraintType=kDihePMF; break;
862  default: break;
863  }
864  Str += 3;
865  Str += ReadAlphaNum(Str);
866  }
867 
868  // skip past trailing white space, calcuate num chars string has been advanced
869  Str += ReadWhite(Str);
870  NumChars = Str-FullString;
871  return(RestraintType);
872 }
873 
874 
875 int AddAtoms(AGroup& Group, char* Str, GlobalMasterFreeEnergy& CFE) {
876 //----------------------------------------------------------------------------
877 // Str contains specifications for which atoms to add to Group.
878 // The atoms may be:
879 // a) a single atom, b) all atoms of a residue, c) a list of atoms
880 // d) all atoms in a list of residues, e) all atoms in a range of residues,
881 // e) one or more atomnames in a list of residues, or
882 // f) one or more atomnames in a range of residues
883 // Add the AtomID's for these specified atoms to Group.
884 // return the number of characters in Str that were read.
885 //----------------------------------------------------------------------------
886  int NumChars;
887  int RetNumChars = 0;
888  Bool_t GroupMode = kFalse;
889  Bool_t AtomList = kFalse;
890  Bool_t Finished = kFalse;
891  char* SavePtr = 0;
892 
893  while (!Finished) {
894  switch(ReadNextItem(Str, NumChars)) {
895  case kStartGroup:
896  GroupMode = kTrue;
897  break;
898  case kEndGroup:
899  Finished = kTrue;
900  break;
901  case kAtom:
902  AddAtom(Group, Str, CFE);
903  if (!GroupMode) {
904  Finished = kTrue;
905  }
906  break;
907  case kAtomName:
908  case kAtomNameList:
909  AtomList = kTrue;
910  SavePtr = Str;
911  break;
912  case kResidue:
913  case kResidueRange:
914  if (AtomList) {
915  AddAtomsInResidues(Group, SavePtr, Str, CFE);
916  }
917  else {
918  AddResidues(Group, Str, CFE);
919  }
920  if (!GroupMode) {
921  Finished = kTrue;
922  }
923  break;
924  default:
925  Finished = kTrue;
926  ProblemParsing("Can't Read Atoms", Str);
927  break;
928  }
929  Str += NumChars;
930  RetNumChars += NumChars;
931  }
932  RetNumChars += ReadWhite(Str);
933  return(RetNumChars);
934 }
935 
936 
937 void AddAtomsInResidues(AGroup& Group, char* AtomNames, char* ResRange,
938  GlobalMasterFreeEnergy& CFE) {
939 //-------------------------------------------------------------------
940 // Group contains a list of int's representing AtomID's.
941 // ResRange should be "(segname, resnum) to (segname, resnum)"
942 // or "(segname, resnum)"
943 // AtomNames should be "(atomname, atomname, ...):" or "atomname:"
944 // get the atomID's for each atomname in ResRange, add them to Group.
945 //-------------------------------------------------------------------
946  int Count, ArrayIndex, i;
947  char AtomNamesArray[21][30];
948 
949  // skip to start of first atomname
950  if (AtomNames[0] == '(') {
951  AtomNames++;
952  Count = ReadWhite(AtomNames);
953  AtomNames += Count;
954  }
955  // put each atomname into the array, finish when ':' or ')' is found
956  ArrayIndex = 0;
957  while ( (AtomNames[0]!=':') && (AtomNames[0]!=')') ) {
958  Count = ReadAlphaNum(AtomNames);
959  strncpy(AtomNamesArray[ArrayIndex], AtomNames, Count);
960  AtomNamesArray[ArrayIndex][Count] = '\0';
961  AtomNames += Count;
962  Count = ReadWhite(AtomNames);
963  AtomNames += Count;
964  ArrayIndex++;
965  }
966  // now add each atomname of Res to Group.
967  // if "all" is specified, add all atoms of Res to Group.
968  for (i=0; i<ArrayIndex; i++) {
969  if (strcmp(AtomNamesArray[i], "all") == 0) {
970  AddResidues(Group, ResRange, CFE);
971  }
972  else {
973  AddAtom(Group, ResRange, AtomNamesArray[i], CFE);
974  }
975  }
976 }
977 
978 
979 void AddResidues(AGroup& Group, char* ResRange, GlobalMasterFreeEnergy& CFE) {
980 //-------------------------------------------------------------------
981 // Group contains a list of int's representing AtomID's.
982 // ResRange should be "(segname, resnum) to (segname, resnum)"
983 // or "(segname, resnum)"
984 // get the atomID's for each atom of ResRange, and add them to Group.
985 //-------------------------------------------------------------------
986  char SegName[21];
987  int ResNum1, ResNum2, ResNum;
988  int i, NumAtoms, AtomID, RetVal;
989 
990  // get start and stop residue numbers
991  GetSegName(ResRange, SegName);
992  GetResRange(ResRange, ResNum1, ResNum2);
993 
994  // for each residue of residue range
995  for (ResNum=ResNum1; ResNum<=ResNum2; ResNum++) {
996  // for each atom of residue
997  NumAtoms = CFE.getNumAtoms(SegName, ResNum);
998  if (NumAtoms < 1) { ProblemParsing("No Atoms in Residue", ResRange); }
999  for (i=0; i<NumAtoms; i++) {
1000  // get atomID, register it, add it to Group
1001  AtomID = CFE.getAtomID(SegName, ResNum, i);
1002  if (AtomID < 0) { ProblemParsing("Invalid AtomID", ResRange); }
1003  RetVal = CFE.requestAtom(AtomID);
1004  if (RetVal < 0) { ProblemParsing("Unable to requestAtom", ResRange); }
1005  Group.Add(AtomID);
1006  }
1007  }
1008 }
1009 
1010 
1011 void AddAtom(AGroup& Group, char* Atom, GlobalMasterFreeEnergy& CFE) {
1012 //-------------------------------------------------------------------
1013 // Group contains a list of int's representing AtomID's.
1014 // Atom should be "(segname, resnum, atomname)"
1015 // get the atomID for Atom, and add it to Group.
1016 //-------------------------------------------------------------------
1017  char AtomName[21];
1018 
1019  GetAtomName(Atom, AtomName);
1020  AddAtom(Group, Atom, AtomName, CFE);
1021 }
1022 
1023 
1024 void AddAtom(AGroup& Group, char* ResRange, char* AtomName,
1025  GlobalMasterFreeEnergy& CFE) {
1026 //-------------------------------------------------------------------
1027 // Group contains a list of int's representing AtomID's.
1028 // ResRange should be "(segname, resnum) to (segname, resnum)"
1029 // or "(segname, resnum)"
1030 // AtomName is specified separately.
1031 // get the atomID, and add it to Group.
1032 //-------------------------------------------------------------------
1033  char SegName[21];
1034  int ResNum, ResNum1, ResNum2, AtomID, RetVal;
1035 
1036  // convert "(segname, resnum1) to (segname, resnum2)"
1037  // -> SegName, ResNum1, ResNum2
1038  GetSegName(ResRange, SegName);
1039  GetResRange(ResRange, ResNum1, ResNum2);
1040 
1041  // get atomID for each atom in the specified residue range
1042  // register it, add it to Group
1043  for (ResNum=ResNum1; ResNum<=ResNum2; ResNum++) {
1044  AtomID = CFE.getAtomID(SegName, ResNum, AtomName);
1045  if (AtomID < 0) { ProblemParsing("Invalid AtomID", ResRange); }
1046  RetVal = CFE.requestAtom(AtomID);
1047  if (RetVal < 0) { ProblemParsing("Unable to requestAtom", ResRange); }
1048  Group.Add(AtomID);
1049  }
1050 }
1051 
1052 
1053 void GetResRange(char* ResRange, int& ResNum1, int& ResNum2) {
1054 //-------------------------------------------------------------------
1055 // ResRange should be "(segname, resnum1) to (segname, resnum2)"
1056 // return ResNum1 & ResNum2
1057 // if "to" is missing, return resnum1 in both ResNum1 & ResNum2
1058 //-------------------------------------------------------------------
1059  char SegName1[21], SegName2[21];
1060 
1061  // get start residue number
1062  GetSegName(ResRange, SegName1);
1063  GetResNum(ResRange, ResNum1);
1064 
1065  // skip to where "to" should appear
1066  ResRange += ReadParentheses(ResRange);
1067  ResRange += ReadWhite(ResRange);
1068 
1069  // if "to" is found
1070  if (strncmp(ResRange, "to", 2) == 0) {
1071  //skip to next residue
1072  ResRange += ReadAlphaNum(ResRange);
1073  ResRange += ReadWhite(ResRange);
1074  // get final residue number
1075  GetSegName(ResRange, SegName2);
1076  GetResNum(ResRange, ResNum2);
1077  // do some checks
1078  if (strcmp(SegName1, SegName2)!=0) {
1079  ProblemParsing("SegNames Differ", ResRange);
1080  }
1081  if (ResNum2 < ResNum1) {
1082  ProblemParsing("Decreasing Residues", ResRange);
1083  }
1084  }
1085 
1086  // otherwise, ResNum2 = ResNum1
1087  else {
1088  ResNum2 = ResNum1;
1089  }
1090 }
1091 
1092 
1093 int GetSegName(char* Str, char* SegName) {
1094 //-------------------------------------------------------------------
1095 // Str should be (segname, resnum) or (segname, resnum, atomname)
1096 // put segname into SegName
1097 // return the number of characters from start-of-Str thru segname
1098 //-------------------------------------------------------------------
1099  int Count;
1100  char* FullString=Str;
1101 
1102  if (Str[0] != '(') {ProblemParsing("Missing (", Str);}
1103  Str += 1;
1104  Str += ReadWhite(Str);
1105  Count = ReadAlphaNum(Str);
1106  if (Count == 0) {ProblemParsing("Missing Segment Name", Str);}
1107  strncpy(SegName, Str, Count);
1108  SegName[Count] = '\0';
1109  Str += Count;
1110  return(Str-FullString);
1111 }
1112 
1113 
1114 int GetResNum(char* Str, int& ResNum) {
1115 //-------------------------------------------------------------------
1116 // Str should be (segname, resnum) or (segname, resnum, atomname)
1117 // convert resnum to an int and return it
1118 // return the number of characters from start-of-Str thru resnum
1119 //-------------------------------------------------------------------
1120  int Count;
1121  char SegName[21];
1122  char* FullString=Str;
1123 
1124  Str += GetSegName(Str, SegName);
1125  Str += ReadWhite(Str);
1126  ResNum = (int) strtol(Str, NULL, 10);
1127  Count = ReadDigits(Str);
1128  if (Count == 0) {ProblemParsing("Missing Residue Number", Str);}
1129  Str += Count;
1130  return(Str-FullString);
1131 }
1132 
1133 
1134 int GetAtomName(char* Str, char* AtomName) {
1135 //-------------------------------------------------------------------
1136 // Str should be (segname, resnum, atomname)
1137 // put atomname into AtomName
1138 // return the number of characters from start-of-Str thru ')'
1139 //-------------------------------------------------------------------
1140  int Count, ResNum;
1141  char* FullString=Str;
1142 
1143  Str += GetResNum(Str, ResNum);
1144  Str += ReadWhite(Str);
1145  Count = ReadAlphaNum(Str);
1146  if (Count == 0) {ProblemParsing("Missing Atom Name", Str);}
1147  strncpy(AtomName, Str, Count);
1148  AtomName[Count] = '\0';
1149  Str += Count;
1150  Str += ReadWhite(Str);
1151  if (Str[0] != ')') {ProblemParsing("Missing )", Str);}
1152  Str += 1;
1153  return(Str-FullString);
1154 }
1155 
1156 
1157 item_t ReadNextItem(char* Str, int& NumChars) {
1158 //-------------------------------------------------------------------
1159 // Figure out what the next item in Str is, and how many characters
1160 // long it is. The next item should be one of the following:
1161 // 1. kStartGroup: Group {
1162 // 2. kEndGroup: }
1163 // 3. kAtomName: atomname:
1164 // 4. kAtomNameList: (atomname, atomname, ... ):
1165 // 5. kAtom: (segname, resno, atomname)
1166 // 6. kResidue: (segname, resno)
1167 // 7. kResidueRange: (segname, resno) to (segname, resno)
1168 // The following assumptions may be made:
1169 // 1. Str is all lowercase
1170 // 2. There are NO leading white-char's
1171 // Return:
1172 // The length of the next item, plus the white space that follows.
1173 //-------------------------------------------------------------------
1174  int Num;
1175  item_t RetVal=kUnknownItem;
1176 
1177  Num=IsStartGroup(Str); if (Num) {RetVal=kStartGroup; goto Found;}
1178  Num=IsEndGroup(Str); if (Num) {RetVal=kEndGroup; goto Found;}
1179  Num=IsAtomName(Str); if (Num) {RetVal=kAtomName; goto Found;}
1180  Num=IsAtomNameList(Str); if (Num) {RetVal=kAtomNameList; goto Found;}
1181  Num=IsAtom(Str); if (Num) {RetVal=kAtom; goto Found;}
1182  Num=IsResidue(Str); if (Num) {RetVal=kResidue; goto Found;}
1183  Num=IsResidueRange(Str); if (Num) {RetVal=kResidueRange; goto Found;}
1184 
1185  // add the white-space after the item to the length of the item.
1186 Found:
1187  NumChars = Num;
1188  Str += NumChars;
1189  NumChars += ReadWhite(Str);
1190  return(RetVal);
1191 }
1192 
1193 
1194 int IsStartGroup(char* Str) {
1195 //-------------------------------------------------------------------
1196 // see if Str starts with "group {"
1197 // return: the number of characters, including white space.
1198 // 0, if Str does not start with "group {"
1199 //-------------------------------------------------------------------
1200  char* FullString=Str;
1201 
1202  if (strncmp(Str, "group", 5) == 0) {
1203  Str += 5;
1204  Str += ReadWhite(Str);
1205  if (Str[0] == '{') {
1206  Str += 1;
1207  return(Str-FullString);
1208  }
1209  }
1210  return(0);
1211 }
1212 
1213 
1214 int IsEndGroup(char* Str) {
1215 //-------------------------------------------------------------------
1216 // see if Str starts with "}"
1217 // return: the number of characters, including white space.
1218 // 0, if Str does not start with "}"
1219 //-------------------------------------------------------------------
1220  if (Str[0] == '}') {
1221  return(1);
1222  }
1223  return(0);
1224 }
1225 
1226 
1227 int IsAtomName(char* Str) {
1228 //-------------------------------------------------------------------
1229 // see if Str starts with "atomname:"
1230 // return: the number of characters, including white space.
1231 // 0, if Str does not start with "atomname:"
1232 //-------------------------------------------------------------------
1233  int Count;
1234  char* FullString=Str;
1235 
1236  Count = ReadAlphaNum(Str);
1237  if (Count) {
1238  Str += Count;
1239  Str += ReadWhite(Str);
1240  if (Str[0] == ':') {
1241  Str += 1;
1242  return(Str-FullString);
1243  }
1244  }
1245  return(0);
1246 }
1247 
1248 
1249 int IsAtomNameList(char* Str) {
1250 //------------------------------------------------------------------------
1251 // see if Str starts with "(atomname, atomname, ...):"
1252 // return: the number of characters, including white space.
1253 // 0, if Str does not start with "(atomname, atomname, ...):"
1254 //------------------------------------------------------------------------
1255  int Count;
1256  char* FullString=Str;
1257 
1258  // Str will be considered an atom-name-list if it contains the following:
1259  // '(', anything, ')', ':'
1260  Count = ReadParentheses(Str);
1261  if (Count > 0) {
1262  Str += Count;
1263  Str += ReadWhite(Str);
1264  if (Str[0] == ':') {
1265  Str += 1;
1266  return(Str-FullString);
1267  }
1268  }
1269  return(0);
1270 }
1271 
1272 
1273 int IsAtom(char* Str) {
1274 //------------------------------------------------------------------------
1275 // see if Str starts with "(segname, resnum, atomname)"
1276 // return: the number of characters, including white space.
1277 // 0, if Str does not start with "(segname, resnum, atomname)"
1278 //------------------------------------------------------------------------
1279  int Count;
1280  char* FullString=Str;
1281 
1282  // if char following the parentheses is ':', this isn't an atom
1283  if (IsAtomNameList(Str)) {
1284  return(0);
1285  }
1286  // Str must contain the following in sequence to be a legit atom
1287  // <ws> = optional white-space
1288  // '(', <ws>, alphanumeric, <ws>, numeric, <ws>, alphanumeric, <ws>, ')'
1289  if (Str[0] == '(') {
1290  Str += 1;
1291  Str += ReadWhite(Str);
1292  Count = ReadAlphaNum(Str);
1293  if (Count) {
1294  Str += Count;
1295  Str += ReadWhite(Str);
1296  Count = ReadDigits(Str);
1297  if (Count) {
1298  Str += Count;
1299  Str += ReadWhite(Str);
1300  Count = ReadAlphaNum(Str);
1301  if (Count) {
1302  Str += Count;
1303  Str += ReadWhite(Str);
1304  if (Str[0] == ')') {
1305  Str += 1;
1306  return(Str-FullString);
1307  }
1308  }
1309  }
1310  }
1311  }
1312  return(0);
1313 }
1314 
1315 
1316 int IsResidueRange(char* Str) {
1317 //------------------------------------------------------------------------
1318 // see if Str starts with "(segname, resnum) to (segname, resnum)"
1319 // return: the number of characters, including white space.
1320 // 0, if Str does not start with "(sn, rn) to (sn, rn)"
1321 //------------------------------------------------------------------------
1322  int Count;
1323  char* FullString=Str;
1324 
1325  // Str must contain the following in sequence to be a legit res range
1326  // <ws> = optional white-space
1327  // residue, <ws>, "to", <ws>, residue
1328  Count = IsAResidue(Str);
1329  if (Count) {
1330  Str += Count;
1331  Str += ReadWhite(Str);
1332  if (strncmp(Str, "to", 2) == 0) {
1333  Str += 2;
1334  Str += ReadWhite(Str);
1335  Count = IsAResidue(Str);
1336  if (Count) {
1337  Str += Count;
1338  return(Str-FullString);
1339  }
1340  }
1341  }
1342  return(0);
1343 }
1344 
1345 
1346 int IsResidue(char* Str) {
1347 //------------------------------------------------------------------------
1348 // see if Str starts with "(segname, resnum)"
1349 // but not "(segname, resnum) to (segname, resnum)"
1350 //------------------------------------------------------------------------
1351  int Count;
1352 
1353  Count = IsAResidue(Str);
1354  if (Count) {
1355  if (IsResidueRange(Str)) {
1356  return(0);
1357  }
1358  else {
1359  return(Count);
1360  }
1361  }
1362  return(0);
1363 }
1364 
1365 
1366 int IsAResidue(char* Str) {
1367 //------------------------------------------------------------------------
1368 // see if Str starts with "(segname, resnum)"
1369 // return: the number of characters, including white space.
1370 // 0, if Str does not start with "(segname, resnum)"
1371 //------------------------------------------------------------------------
1372  int Count;
1373  char* FullString=Str;
1374 
1375  // if char following the parentheses is ':', this isn't a residue
1376  if (IsAtomNameList(Str)) {
1377  return(0);
1378  }
1379  // Str must contain the following in sequence to be a legit residue
1380  // <ws> = optional white-space
1381  // '(', <ws>, alphanumeric, <ws>, numeric, <ws>, ')'
1382  if (Str[0] == '(') {
1383  Str += 1;
1384  Str += ReadWhite(Str);
1385  Count = ReadAlphaNum(Str);
1386  if (Count) {
1387  Str += Count;
1388  Str += ReadWhite(Str);
1389  Count = ReadDigits(Str);
1390  if (Count) {
1391  Str += Count;
1392  Str += ReadWhite(Str);
1393  if (Str[0] == ')') {
1394  Str += 1;
1395  return(Str-FullString);
1396  }
1397  }
1398  }
1399  }
1400  return(0);
1401 }
1402 
1403 
1404 int ReadParentheses(const char* Str) {
1405 //-------------------------------------------------------------------
1406 // count the number of characters from the leading '('
1407 // to the first ')' of Str (inclusive).
1408 // no leading '(' => return 0
1409 // no closing ')' => return -1
1410 //-------------------------------------------------------------------
1411  const char* Str2;
1412 
1413  if (Str[0] != '(') {
1414  return(0);
1415  }
1416  Str2 = strchr(Str, ')');
1417  if (Str2 == NULL) {
1418  return(-1);
1419  }
1420  return((Str2-Str)+1);
1421 }
1422 
1423 
1424 int ReadAlpha(const char* Str) {
1425 //-------------------------------------------------------------------
1426 // determine the leading number of alphabetic characters in Str.
1427 //-------------------------------------------------------------------
1428  int i=0;
1429 
1430  while (1) {
1431  if (isalpha(Str[i]) || Str[i]=='\'' || Str[i]=='\"' || Str[i] == '*') {
1432  i++;
1433  }
1434  else {
1435  break;
1436  }
1437  }
1438  return(i);
1439 }
1440 
1441 
1442 int ReadAlphaNum(const char* Str) {
1443 //-------------------------------------------------------------------
1444 // determine the leading number of alphanumeric characters in Str.
1445 //-------------------------------------------------------------------
1446  int i=0;
1447 
1448  while (1) {
1449  if (isalnum(Str[i]) || Str[i]=='\'' || Str[i]=='\"' || Str[i] == '*') {
1450  i++;
1451  }
1452  else {
1453  break;
1454  }
1455  }
1456  return(i);
1457 }
1458 
1459 
1460 int ReadDigits(const char* Str) {
1461 //-------------------------------------------------------------------
1462 // determine the leading number of numeric characters in Str.
1463 //-------------------------------------------------------------------
1464  int i=0;
1465 
1466  while (1) {
1467  if (isdigit(Str[i])) {
1468  i++;
1469  }
1470  else {
1471  break;
1472  }
1473  }
1474  return(i);
1475 }
1476 
1477 
1478 int ReadWhite(const char* Str) {
1479 //-------------------------------------------------------------------
1480 // determine the leading number of white characters in Str.
1481 // a white char is:
1482 // space, tab, linefeed, carriage-return, formfeed,
1483 // vertical-tab, and newline characters.
1484 // a white char is also (for the sake of this program):
1485 // comma, semi-colon, and period.
1486 //-------------------------------------------------------------------
1487  int i=0;
1488 
1489  // count the number of white-char's. break at first non-white-char.
1490  while (1) {
1491  if (
1492  (Str[i] == 9) || // tab
1493  (Str[i] == 10) || // LF
1494  (Str[i] == 11) || // vertical-tab
1495  (Str[i] == 12) || // form-feed
1496  (Str[i] == 13) || // CR
1497  (Str[i] == 32) || // space
1498  (Str[i] == ',') || // comma
1499  (Str[i] == ';') // semi-colon
1500 // (Str[i] == '.') // period (took this out in case of =.4, eg)
1501  )
1502  {
1503  i++;
1504  }
1505  else {
1506  break;
1507  }
1508  }
1509  return(i);
1510 }
1511 
1512 
1513 void ToLower(char* Str) {
1514 //-------------------------------------------------------------------
1515 // convert Str to all lower case
1516 //-------------------------------------------------------------------
1517  for (unsigned int i=0; i<strlen(Str); i++) {
1518  Str[i] = (char)tolower(Str[i]);
1519  }
1520 }
1521 
void SetNumEquilSteps(int Steps)
int IsAResidue(char *Str)
int Add(ALambdaControl &PmfBlock)
int GetAtomName(char *Str, char *AtomName)
restr_t ReadNextRestraintType(char *Str, int &NumChars)
int getAtomID(const char *segid, int resid, const char *aname)
int IsAtomNameList(char *Str)
TimeUnits_t
int AtomID
Definition: NamdTypes.h:29
const double kALittle
int ReadAlphaNum(const char *Str)
virtual void SetRefPos(AVector)
int ReadAlpha(const char *Str)
int ReadWhite(const char *Str)
void SetNumSteps(int Steps)
const BigReal A
void SetLambdaRef(double LambdaRef)
virtual void SetStopAngle(double)
virtual void SetBound(Bound_t)
void SetTask(feptask_t Task)
int ReadAValue(char *Str, double &Value, Bool_t ErrMsg)
virtual void SetIntervalAngle(double)
#define iout
Definition: InfoStream.h:87
int ReadParentheses(const char *Str)
int IsResidueRange(char *Str)
Units
Definition: ParseOptions.h:28
void AddResidues(AGroup &Group, char *ResRange, GlobalMasterFreeEnergy &CFE)
void SetLambdaKf(double LambdaKf)
int AddAtoms(AGroup &Group, char *Str, GlobalMasterFreeEnergy &CFE)
void Add(ARestraint *pRestraint)
feptask_t GetTask()
virtual void SetStopPos(AVector)
virtual void SetRefAngle(double)
virtual void SetStartDist(double)
void ProblemParsing(const char *Message, const char *Str, Bool_t Terminate)
int ReadTimeUnits(char *Str, TimeUnits_t &Units, TimeUnits_t DefaultUnits)
Bool_t
void AddAtom(AGroup &Group, char *Atom, GlobalMasterFreeEnergy &CFE)
double GetTime(double Val, TimeUnits_t Units)
item_t ReadNextItem(char *Str, int &NumChars)
#define ASSERT(E)
Bound_t
void ReadInput(char *Str, ARestraintManager &RMgr, ALambdaManager &LMgr, GlobalMasterFreeEnergy &CFE, double dT)
restr_t
feptask_t
int ReadChar(char *Str, char Char, Bool_t ErrMsg)
virtual void SetRefDist(double)
int ReadTaskType(char *Str, feptask_t &Task)
int IsAtomName(char *Str)
void SetNumPrintSteps(int Steps)
void ToLower(char *Str)
int IsAtom(char *Str)
virtual void SetStopDist(double)
const double kPi
void SetNumRepeats(int Repeats)
void NAMD_die(const char *err_msg)
Definition: common.C:83
virtual void SetStartPos(AVector)
void SetGroups(AGroup &Group1)
int GetResNum(char *Str, int &ResNum)
void CheckParentheses(const char *Str)
void SetNumAccumSteps(int Steps)
int ReadPmfBlock(char *Str, ALambdaControl &PmfBlock, double dT)
int IsStartGroup(char *Str)
item_t
void Init(ALambdaControl &PriorBlock)
void AddAtomsInResidues(AGroup &Group, char *AtomNames, char *ResRange, GlobalMasterFreeEnergy &CFE)
int ReadDigits(const char *Str)
virtual void SetStartAngle(double)
infostream & endi(infostream &s)
Definition: InfoStream.C:38
int ReadWord(const char *Str, const char *Word, Bool_t ErrMsg)
virtual void SetLowerAngle(double)
virtual void SetUpperAngle(double)
void SetKf(double Kf)
void Add(int AnInt)
int GetSegName(char *Str, char *SegName)
int ReadBound(char *Str, Bound_t &Bound)
ARestraint * GetRestraint(char *Str, int &NumChars, GlobalMasterFreeEnergy &CFE)
void GetResRange(char *ResRange, int &ResNum1, int &ResNum2)
int getNumAtoms(const char *segid, int resid)
pmf_t
int ReadNextPmfSpec(char *Str, pmf_t &PmfSpec)
int IsEndGroup(char *Str)
int IsResidue(char *Str)
int ReadRestraints(char *Str, ARestraintManager &AllRestraints, GlobalMasterFreeEnergy &CFE)