Changeset 23fd43 for src


Ignore:
Timestamp:
Apr 6, 2012, 11:45:54 AM (13 years ago)
Author:
Frederik Heber <heber@…>
Branches:
Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
Children:
006e1e
Parents:
531f27
git-author:
Frederik Heber <heber@…> (04/06/12 10:09:07)
git-committer:
Frederik Heber <heber@…> (04/06/12 11:45:54)
Message:

FIX: TremoloParser now contains usedFields_load and _save to allow for multiple loading.

  • refactored several functions out of ::save().
  • parseAtomDataKeysLine() and isUsedField now require usedFields ref.
  • FIX: save() now erases duplicate entries still in usedFields.
  • removed setFieldsForSave(), was duplicate of setAtomData().
  • new function makeUsedFieldsUnique() to preserver order of appearance in usedFields.
  • this [closes #141].
  • FIX: made several function parameters constant that were not before.
  • FIX: Removed double readAtomDataLine().
Location:
src/Parser
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/TremoloParser.cpp

    r531f27 r23fd43  
    8181  knownKeys["GrpTypeNo"] = TremoloKey::GrpTypeNo;
    8282  knownKeys["torsion"] = TremoloKey::torsion;
     83  knownKeys[" "] = TremoloKey::noKey; // with this we can detect invalid keys
    8384
    8485  createKnownTypesByIdentity();
    85 
    86   // default behavior: use all possible keys on output
    87   for (std::map<std::string, TremoloKey::atomDataKey>::iterator iter = knownKeys.begin(); iter != knownKeys.end(); ++iter)
    88     usedFields.push_back(iter->first);
    89 
    90   // and noKey afterwards(!) such that it is not used in usedFields
    91   knownKeys[" "] = TremoloKey::noKey; // with this we can detect invalid keys
    9286
    9387  // invert knownKeys for debug output
     
    10397FormatParser< tremolo >::~FormatParser()
    10498{
    105   LOG(1, "INFO: Clearing usedFields.");
    106   usedFields.clear();
     99  usedFields_save.clear();
    107100  additionalAtomData.clear();
    108101  knownKeys.clear();
     
    120113  // reset the id maps
    121114  resetIdAssociations();
    122 
    123   LOG(1, "INFO: Clearing usedFields.");
    124   usedFields.clear();
    125115
    126116  molecule *newmol = World::getInstance().createMolecule();
     
    130120  while (file->good()) {
    131121    std::getline(*file, line, '\n');
    132     if (usedFields.empty()) {
     122    // we only parse in the first ATOMDATA line
     123    if (usedFields_load.empty()) {
    133124      location = line.find("ATOMDATA", 0);
    134125      if (location != string::npos) {
    135        parseAtomDataKeysLine(line, location + 8);
     126       parseAtomDataKeysLine(line, location + 8, usedFields_load);
    136127      }
    137128    }
     
    140131    }
    141132  }
    142   LOG(3, "usedFields after load contains: " << usedFields);
     133  LOG(3, "DEBUG: Local usedFields is: " << usedFields_load);
    143134
    144135  // refresh atom::nr and atom::name
     
    149140  adaptImprData();
    150141  adaptTorsion();
     142
     143  // append usedFields to global usedFields, is made unique on save, clear after use
     144  usedFields_save.insert(usedFields_save.end(), usedFields_load.begin(), usedFields_load.end());
     145  usedFields_load.clear();
    151146}
    152147
     
    157152 * \param atoms atoms to store
    158153 */
    159 void FormatParser< tremolo >::save(ostream* file, const std::vector<atom *> &AtomList) {
     154void FormatParser< tremolo >::save(std::ostream* file, const std::vector<atom *> &AtomList) {
    160155  LOG(0, "Saving changes to tremolo.");
    161156
    162   std::vector<atom*>::const_iterator atomIt;
    163   /*vector<string>::iterator it;*/
    164   std::vector<std::string>::iterator it = unique(usedFields.begin(), usedFields.end()); // skips all duplicates in the vector
    165 
    166   LOG(3, "INFO: usedFields before save contains: " << usedFields);
    167   //LOG(3, "INFO: additionalAtomData contains: " << additionalAtomData);
    168 
    169   // distribute continuous indices
     157  // install default usedFields if empty so far
     158  if (usedFields_save.empty()) {
     159    // default behavior: use all possible keys on output
     160    for (std::map<std::string, TremoloKey::atomDataKey>::iterator iter = knownKeys.begin();
     161        iter != knownKeys.end(); ++iter)
     162      if (iter->second != TremoloKey::noKey) // don't add noKey
     163        usedFields_save.push_back(iter->first);
     164  }
     165  // make present usedFields_save unique
     166  makeUsedFieldsUnique(usedFields_save);
     167  LOG(1, "DEBUG: Global (with unique entries) usedFields_save is: " << usedFields_save);
     168
     169  // distribute ids continuously
     170  distributeContinuousIds(AtomList);
     171
     172  // store atomdata
     173  save_AtomDataLine(file);
     174
     175  // store box
     176  save_BoxLine(file);
     177
     178  // store particles
     179  for (std::vector<atom*>::const_iterator  atomIt = AtomList.begin();
     180      atomIt != AtomList.end(); ++atomIt)
     181    saveLine(file, *atomIt);
     182}
     183
     184/** Helper function to make \given fields unique while preserving the order of first appearance.
     185 *
     186 * As std::unique only removes element if equal to predecessor, a vector is only
     187 * made unique if sorted beforehand. But sorting would destroy order of first
     188 * appearance, hence we do the sorting on a temporary field and add the unique
     189 * elements in the order as in \a fields.
     190 *
     191 * @param fields usedFields to make unique while preserving order of appearance
     192 */
     193void FormatParser< tremolo >::makeUsedFieldsUnique(usedFields_t &fields)
     194{
     195  // std::unique only removes if predecessor is equal, not over whole range, hence do it manually
     196  usedFields_t temp_fields(usedFields_save);
     197  std::sort(temp_fields.begin(), temp_fields.end());
     198  usedFields_t::iterator it =
     199      std::unique(temp_fields.begin(), temp_fields.end()); // skips all duplicates in the vector
     200  temp_fields.erase(it, temp_fields.end());
     201  usedFields_t usedfields(usedFields_save);
     202  usedFields_save.clear();
     203  usedFields_save.reserve(temp_fields.size());
     204  // now go through each usedFields entry, check if in temp_fields and remove there on first occurence
     205  for (usedFields_t::const_iterator iter = usedfields.begin();
     206      iter != usedfields.end(); ++iter) {
     207    usedFields_t::iterator uniqueiter =
     208        std::find(temp_fields.begin(), temp_fields.end(), *iter);
     209    if (uniqueiter != temp_fields.end()) {
     210      usedFields_save.push_back(*iter);
     211      // add only once to ATOMDATA
     212      temp_fields.erase(uniqueiter);
     213    }
     214  }
     215  ASSERT( temp_fields.empty(),
     216      "FormatParser< tremolo >::save() - still unique entries left in temp_fields after unique?");
     217}
     218
     219
     220/** Resets and distributes the indices continuously.
     221 *
     222 * \param atoms atoms to store
     223 */
     224void FormatParser< tremolo >::distributeContinuousIds(const std::vector<atom *> &AtomList)
     225{
    170226  resetIdAssociations();
    171227  atomId_t lastid = 0;
    172   for (atomIt = AtomList.begin(); atomIt != AtomList.end(); atomIt++) {
     228  for (std::vector<atom*>::const_iterator atomIt = AtomList.begin();
     229      atomIt != AtomList.end(); ++atomIt)
    173230    associateLocaltoGlobalId(++lastid, (*atomIt)->getId());
    174   }
    175 
    176   // store Atomdata line
     231}
     232
     233/** Store Atomdata line to \a file.
     234 *
     235 * @param file output stream
     236 */
     237void FormatParser< tremolo >::save_AtomDataLine(std::ostream* file) const
     238{
    177239  *file << "# ATOMDATA";
    178   for (it=usedFields.begin(); it < usedFields.end(); it++) {
     240  for (usedFields_t::const_iterator it=usedFields_save.begin();
     241      it != usedFields_save.end(); ++it)
    179242    *file << "\t" << *it;
    180   }
    181   *file << endl;
    182 
    183   // store Box info
     243  *file << std::endl;
     244}
     245
     246/** Store Box info to \a file
     247 *
     248 * @param file output stream
     249 */
     250void FormatParser< tremolo >::save_BoxLine(std::ostream* file) const
     251{
    184252  *file << "# Box";
    185253  const RealSpaceMatrix &M = World::getInstance().getDomain().getM();
     
    188256      *file << "\t" << M.at(i,j);
    189257  *file << std::endl;
    190 
    191   // store particles
    192   for (atomIt = AtomList.begin(); atomIt != AtomList.end(); atomIt++) {
    193     saveLine(file, *atomIt);
    194   }
    195258}
    196259
     
    225288
    226289/**
    227  * Sets the keys for which data should be written to the stream when save is
    228  * called.
    229  *
    230  * \param string of field names with the same syntax as for an ATOMDATA line
    231  *        but without the prexix "ATOMDATA"
    232  */
    233 void FormatParser< tremolo >::setFieldsForSave(std::string atomDataLine) {
    234   parseAtomDataKeysLine(atomDataLine, 0);
    235 }
    236 
    237 
    238 /**
    239290 * Writes one line of tremolo-formatted data to the provided stream.
    240291 *
     
    242293 * \param reference to the atom of which information should be written
    243294 */
    244 void FormatParser< tremolo >::saveLine(ostream* file, atom* currentAtom) {
    245   std::vector<string>::iterator it;
    246 
     295void FormatParser< tremolo >::saveLine(std::ostream* file, const atom* currentAtom)
     296{
    247297  TremoloKey::atomDataKey currentField;
    248298
    249299  LOG(4, "INFO: Saving atom " << *currentAtom << ", its father id is " << currentAtom->GetTrueFather()->getId());
    250300
    251   for (it = usedFields.begin(); it != usedFields.end(); it++) {
     301  for (usedFields_t::iterator it = usedFields_save.begin(); it != usedFields_save.end(); it++) {
    252302    currentField = knownKeys[it->substr(0, it->find("="))];
    253303    switch (currentField) {
     
    343393  }
    344394
    345   *file << endl;
     395  *file << std::endl;
    346396}
    347397
     
    355405 * \param reference to the atom of which to take the neighbor information
    356406 */
    357 void FormatParser< tremolo >::writeNeighbors(ostream* file, int numberOfNeighbors, atom* currentAtom) {
     407void FormatParser< tremolo >::writeNeighbors(std::ostream* file, const int numberOfNeighbors, const atom* currentAtom) {
    358408  const BondList& ListOfBonds = currentAtom->getListOfBonds();
    359409  // sort bonded indices
     
    373423
    374424/**
    375  * Stores keys from the ATOMDATA line.
     425 * Stores keys from the ATOMDATA line in \a fields.
    376426 *
    377427 * \param line to parse the keys from
    378  * \param with which offset the keys begin within the line
    379  */
    380 void FormatParser< tremolo >::parseAtomDataKeysLine(std::string line, int offset) {
     428 * \param offset with which offset the keys begin within the line
     429 * \param fields which usedFields to use
     430 */
     431void FormatParser< tremolo >::parseAtomDataKeysLine(
     432    const std::string &line,
     433    const int offset,
     434    usedFields_t &fields) {
    381435  std::string keyword;
    382436  std::stringstream lineStream;
    383437
    384438  lineStream << line.substr(offset);
    385   LOG(1, "INFO: Clearing usedFields in parseAtomDataKeysLine.");
    386   usedFields.clear();
    387439  while (lineStream.good()) {
    388440    lineStream >> keyword;
     
    392444      break;
    393445    }
    394     usedFields.push_back(keyword);
    395   }
    396   //LOG(1, "INFO: " << usedFields);
     446    fields.push_back(keyword);
     447  }
     448  //LOG(1, "INFO: " << fields);
    397449}
    398450
     
    400452 *  \a atomdata_string.
    401453 *
    402  *  We just call \sa  FormatParser< tremolo >::parseAtomDataKeysLine() which is left
    403  *  private.,
     454 *  We just call \sa  FormatParser< tremolo >::parseAtomDataKeysLine(), however
     455 *  we clear FormatParser< tremolo >::usedFields_save.
    404456 *
    405457 * @param atomdata_string line to parse with space-separated values
     
    407459void FormatParser< tremolo >::setAtomData(const std::string &atomdata_string)
    408460{
    409   parseAtomDataKeysLine(atomdata_string, 0);
     461  usedFields_save.clear();
     462  parseAtomDataKeysLine(atomdata_string, 0, usedFields_save);
    410463}
    411464
     
    418471 * \param *newmol molecule to add atom to
    419472 */
    420 void FormatParser< tremolo >::readAtomDataLine(std::string line, molecule *newmol = NULL) {
    421   std::vector<string>::iterator it;
     473void FormatParser< tremolo >::readAtomDataLine(const std::string &line, molecule *newmol = NULL) {
    422474  std::stringstream lineStream;
    423475  atom* newAtom = World::getInstance().createAtom();
     
    439491  tokenizer::iterator tok_iter = tokens.begin();
    440492  // then associate each token to each file
    441   for (it = usedFields.begin(); it < usedFields.end(); it++) {
     493  for (usedFields_t::const_iterator it = usedFields_load.begin(); it < usedFields_load.end(); it++) {
    442494    const std::string keyName = it->substr(0, it->find("="));
    443495    currentField = knownKeys[keyName];
     
    543595 * \param atomid world id of the atom the information belongs to
    544596 */
    545 void FormatParser< tremolo >::readNeighbors(std::stringstream* line, int numberOfNeighbors, int atomId) {
     597void FormatParser< tremolo >::readNeighbors(std::stringstream* line, const int numberOfNeighbors, const int atomId) {
    546598  int neighborId = 0;
    547599  for (int i = 0; i < numberOfNeighbors; i++) {
     
    557609
    558610/**
    559  * Checks whether the provided name is within the list of used fields.
    560  *
    561  * \param field name to check
    562  *
     611 * Checks whether the provided name is within \a fields.
     612 *
     613 * \param fields which usedFields to use
     614 * \param fieldName name to check
    563615 * \return true if the field name is used
    564616 */
    565 bool FormatParser< tremolo >::isUsedField(std::string fieldName) {
     617bool FormatParser< tremolo >::isUsedField(const usedFields_t &fields, const std::string &fieldName) const
     618{
    566619  bool fieldNameExists = false;
    567   for (std::vector<std::string>::iterator usedField = usedFields.begin(); usedField != usedFields.end(); usedField++) {
     620  for (usedFields_t::const_iterator usedField = fields.begin();
     621      usedField != fields.end(); usedField++) {
    568622    if (usedField->substr(0, usedField->find("=")) == fieldName)
    569623      fieldNameExists = true;
     
    582636 */
    583637void FormatParser< tremolo >::processNeighborInformation(const std::vector<atomId_t> &atoms) {
    584   if (!isUsedField("neighbors")) {
     638  if (!isUsedField(usedFields_load, "neighbors")) {
    585639    return;
    586640  }
     
    646700 */
    647701void FormatParser< tremolo >::adaptImprData() {
    648   if (!isUsedField("imprData")) {
     702  if (!isUsedField(usedFields_load, "imprData")) {
    649703    return;
    650704  }
     
    662716 */
    663717void FormatParser< tremolo >::adaptTorsion() {
    664   if (!isUsedField("torsion")) {
     718  if (!isUsedField(usedFields_load, "torsion")) {
    665719    return;
    666720  }
  • src/Parser/TremoloParser.hpp

    r531f27 r23fd43  
    5151  void load(std::istream* file);
    5252  void save(std::ostream* file, const std::vector<atom *> &atoms);
    53   void setFieldsForSave(std::string atomDataLine);
    5453  void setAtomData(const std::string &atomdata_string);
    5554
     
    8887
    8988private:
    90   void readAtomDataLine(std::string line);
    91   void readAtomDataLine(std::string line, molecule *newmol);
    92   void parseAtomDataKeysLine(std::string line, int offset);
    93   void readNeighbors(std::stringstream* line, int numberOfNeighbors, int atomId);
     89  //!> typedef for usedFields' vector of strings
     90  typedef std::vector<std::string> usedFields_t;
     91
     92  void readAtomDataLine(const std::string &line, molecule *newmol);
     93  void parseAtomDataKeysLine(const std::string &line, const int offset, usedFields_t &fields);
     94  void readNeighbors(std::stringstream* line, const int numberOfNeighbors, const int atomId);
    9495  void processNeighborInformation(const std::vector<atomId_t> &atoms);
    9596  void adaptImprData();
    9697  void adaptTorsion();
    9798  std::string adaptIdDependentDataString(std::string data);
    98   bool isUsedField(std::string fieldName);
    99   void writeNeighbors(std::ostream* file, int numberOfNeighbors, atom* currentAtom);
    100   void saveLine(std::ostream* file, atom* currentAtom);
     99  bool isUsedField(const usedFields_t &fields, const std::string &fieldName) const;
     100  void writeNeighbors(std::ostream* file, const int numberOfNeighbors, const atom* currentAtom);
     101  void saveLine(std::ostream* file, const atom* currentAtom);
     102  void save_AtomDataLine(std::ostream* file) const;
     103  void save_BoxLine(std::ostream* file) const;
     104  void distributeContinuousIds(const std::vector<atom *> &AtomList);
     105  void makeUsedFieldsUnique(usedFields_t &fields);
    101106
    102107  /**
     
    111116
    112117  /**
    113    * Fields used in the tremolo file.
     118   * Fields used globally when storing to a tremolo file.
    114119   */
    115   std::vector<std::string> usedFields;
     120  usedFields_t usedFields_save;
     121
     122  /**
     123   * Fields used locally when parsing in a tremolo file.
     124   */
     125  usedFields_t usedFields_load;
    116126
    117127  /**
  • src/Parser/unittests/ParserTremoloUnitTest.cpp

    r531f27 r23fd43  
    216216    atom* newAtom = World::getInstance().createAtom();
    217217    newAtom->setType(1);
    218     parser->setFieldsForSave("x=3 u=3 F stress Id neighbors=5 imprData GroupMeasureTypeNo type extType name resName chainID resSeq occupancy tempFactor segID Charge charge GrpTypeNo torsion");
     218    parser->setAtomData("x=3 u=3 F stress Id neighbors=5 imprData GroupMeasureTypeNo type extType name resName chainID resSeq occupancy tempFactor segID Charge charge GrpTypeNo torsion");
    219219    std::vector<atom *> atoms = World::getInstance().getAllAtoms();
    220220    parser->save(&output, atoms);
Note: See TracChangeset for help on using the changeset viewer.