Changes in src/Parser/TremoloParser.cpp [23fd43:ca331c]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/TremoloParser.cpp
r23fd43 rca331c 41 41 42 42 #include <algorithm> 43 #include <boost/lambda/lambda.hpp> 43 44 #include <boost/lexical_cast.hpp> 44 45 #include <boost/tokenizer.hpp> … … 47 48 #include <map> 48 49 #include <sstream> 50 #include <string> 49 51 #include <vector> 52 53 #include <boost/assign/list_of.hpp> // for 'map_list_of()' 54 #include <boost/assert.hpp> 50 55 51 56 // declare specialized static variables … … 54 59 const ParserTypes FormatParserTrait<tremolo>::type = tremolo; 55 60 61 // static instances 62 std::map<std::string, TremoloKey::atomDataKey> FormatParser<tremolo>::knownKeys = 63 boost::assign::map_list_of("x",TremoloKey::x) 64 ("u",TremoloKey::u) 65 ("F",TremoloKey::F) 66 ("stress",TremoloKey::stress) 67 ("Id",TremoloKey::Id) 68 ("neighbors",TremoloKey::neighbors) 69 ("imprData",TremoloKey::imprData) 70 ("GroupMeasureTypeNo",TremoloKey::GroupMeasureTypeNo) 71 ("type",TremoloKey::type) 72 ("extType",TremoloKey::extType) 73 ("name",TremoloKey::name) 74 ("resName",TremoloKey::resName) 75 ("chainID",TremoloKey::chainID) 76 ("resSeq",TremoloKey::resSeq) 77 ("occupancy",TremoloKey::occupancy) 78 ("tempFactor",TremoloKey::tempFactor) 79 ("segID",TremoloKey::segID) 80 ("Charge",TremoloKey::Charge) 81 ("charge",TremoloKey::charge) 82 ("GrpTypeNo",TremoloKey::GrpTypeNo) 83 ("torsion",TremoloKey::torsion) 84 (" ",TremoloKey::noKey); // with this we can detect invalid keys 85 56 86 /** 57 87 * Constructor. … … 60 90 FormatParser_common(NULL) 61 91 { 62 knownKeys["x"] = TremoloKey::x;63 knownKeys["u"] = TremoloKey::u;64 knownKeys["F"] = TremoloKey::F;65 knownKeys["stress"] = TremoloKey::stress;66 knownKeys["Id"] = TremoloKey::Id;67 knownKeys["neighbors"] = TremoloKey::neighbors;68 knownKeys["imprData"] = TremoloKey::imprData;69 knownKeys["GroupMeasureTypeNo"] = TremoloKey::GroupMeasureTypeNo;70 knownKeys["type"] = TremoloKey::type;71 knownKeys["extType"] = TremoloKey::extType;72 knownKeys["name"] = TremoloKey::name;73 knownKeys["resName"] = TremoloKey::resName;74 knownKeys["chainID"] = TremoloKey::chainID;75 knownKeys["resSeq"] = TremoloKey::resSeq;76 knownKeys["occupancy"] = TremoloKey::occupancy;77 knownKeys["tempFactor"] = TremoloKey::tempFactor;78 knownKeys["segID"] = TremoloKey::segID;79 knownKeys["Charge"] = TremoloKey::Charge;80 knownKeys["charge"] = TremoloKey::charge;81 knownKeys["GrpTypeNo"] = TremoloKey::GrpTypeNo;82 knownKeys["torsion"] = TremoloKey::torsion;83 knownKeys[" "] = TremoloKey::noKey; // with this we can detect invalid keys84 85 92 createKnownTypesByIdentity(); 86 93 … … 92 99 } 93 100 101 94 102 /** 95 103 * Destructor. … … 99 107 usedFields_save.clear(); 100 108 additionalAtomData.clear(); 101 knownKeys.clear();102 109 } 103 110 … … 182 189 } 183 190 191 struct usedFieldsWeakComparator 192 { 193 /** Special comparator regards "neighbors=4" and "neighbors=2" as equal 194 * 195 * \note This one is used for making usedFields unique, i.e. throwing out the "smaller" 196 * neighbors. 197 */ 198 bool operator()(const std::string &a, const std::string &b) const 199 { 200 // only compare up to first equality sign 201 return (a.substr(0, a.find_first_of('=')) == b.substr(0, b.find_first_of('='))); 202 } 203 }; 204 205 struct usedFieldsSpecialOrderer 206 { 207 /** Special string comparator that regards "neighbors=4" < "neighbors=2" as true and 208 * the other way round as false. 209 * 210 * Here, we implement the operator "\a < \b" in a special way to allow the 211 * above. 212 * 213 * \note This one is used for sorting usedFields in preparation for making it unique. 214 */ 215 bool operator()(const std::string &a, const std::string &b) const 216 { 217 // only compare up to first equality sign 218 size_t a_equality = a.find_first_of('='); 219 size_t b_equality = b.find_first_of('='); 220 // if key before equality is not equal, return whether it is smaller or not 221 if (a.substr(0, a_equality) != b.substr(0, b_equality)) { 222 return a.substr(0, a_equality) < b.substr(0, b_equality); 223 } else { // now we know that the key before equality is the same in either string 224 // if one of them has no equality, the one with equality must go before 225 if ((a_equality != std::string::npos) && (b_equality == std::string::npos)) 226 return true; 227 if ((a_equality == std::string::npos) && (b_equality != std::string::npos)) 228 return false; 229 // if both don't have equality (and the token before is equal), it is not "<" but "==" 230 if ((a_equality == std::string::npos) && (b_equality == std::string::npos)) 231 return false; 232 // if now both have equality sign, the larger value after it, must come first 233 return a.substr(a_equality, std::string::npos) > b.substr(b_equality, std::string::npos); 234 } 235 } 236 }; 237 184 238 /** Helper function to make \given fields unique while preserving the order of first appearance. 185 239 * … … 191 245 * @param fields usedFields to make unique while preserving order of appearance 192 246 */ 193 void FormatParser< tremolo >::makeUsedFieldsUnique(usedFields_t &fields) 247 void FormatParser< tremolo >::makeUsedFieldsUnique(usedFields_t &fields) const 194 248 { 195 249 // 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()); 250 usedFields_t temp_fields(fields); 251 usedFieldsSpecialOrderer SpecialOrderer; 252 usedFieldsWeakComparator WeakComparator; 253 std::sort(temp_fields.begin(), temp_fields.end(), SpecialOrderer); 198 254 usedFields_t::iterator it = 199 std::unique(temp_fields.begin(), temp_fields.end() ); // skips all duplicates in the vector255 std::unique(temp_fields.begin(), temp_fields.end(), WeakComparator); 200 256 temp_fields.erase(it, temp_fields.end()); 201 usedFields_t usedfields( usedFields_save);202 usedFields_save.clear();203 usedFields_save.reserve(temp_fields.size());257 usedFields_t usedfields(fields); 258 fields.clear(); 259 fields.reserve(temp_fields.size()); 204 260 // now go through each usedFields entry, check if in temp_fields and remove there on first occurence 205 261 for (usedFields_t::const_iterator iter = usedfields.begin(); … … 208 264 std::find(temp_fields.begin(), temp_fields.end(), *iter); 209 265 if (uniqueiter != temp_fields.end()) { 210 usedFields_save.push_back(*iter);266 fields.push_back(*iter); 211 267 // add only once to ATOMDATA 212 268 temp_fields.erase(uniqueiter); … … 441 497 if (knownKeys[keyword.substr(0, keyword.find("="))] == TremoloKey::noKey) { 442 498 // TODO: throw exception about unknown key 443 cout << "Unknown key: " << keyword << " is not part of the tremolo format specification." << endl; 499 cout << "Unknown key: " << keyword.substr(0, keyword.find("=")) << " is not part of the tremolo format specification." << endl; 500 throw IllegalParserKeyException(); 444 501 break; 445 502 } … … 449 506 } 450 507 508 /** 509 * Tests whether the keys from the ATOMDATA line can be read correctly. 510 * 511 * \param line to parse the keys from 512 */ 513 bool FormatParser< tremolo >::testParseAtomDataKeysLine( 514 const std::string &line) { 515 std::string keyword; 516 std::stringstream lineStream; 517 518 // check string after ATOMDATA 519 const std::string AtomData("ATOMDATA"); 520 const size_t AtomDataOffset = line.find(AtomData, 0); 521 if (AtomDataOffset == std::string::npos) 522 lineStream << line; 523 else 524 lineStream << line.substr(AtomDataOffset + AtomData.length()); 525 while (lineStream.good()) { 526 lineStream >> keyword; 527 //LOG(2, "DEBUG: Checking key " << keyword.substr(0, keyword.find("=")) << "."); 528 if (knownKeys[keyword.substr(0, keyword.find("="))] == TremoloKey::noKey) 529 return false; 530 } 531 //LOG(1, "INFO: " << fields); 532 return true; 533 } 534 535 std::string FormatParser< tremolo >::getAtomData() const 536 { 537 std::stringstream output; 538 std::for_each(usedFields_save.begin(), usedFields_save.end(), 539 output << boost::lambda::_1 << " "); 540 const std::string returnstring(output.str()); 541 return returnstring.substr(0, returnstring.find_last_of(" ")); 542 } 543 544 /** Appends the properties per atom to print to .data file by parsing line from 545 * \a atomdata_string. 546 * 547 * We just call \sa FormatParser< tremolo >::parseAtomDataKeysLine(). 548 * 549 * @param atomdata_string line to parse with space-separated values 550 */ 551 void FormatParser< tremolo >::setAtomData(const std::string &atomdata_string) 552 { 553 parseAtomDataKeysLine(atomdata_string, 0, usedFields_save); 554 } 555 451 556 /** Sets the properties per atom to print to .data file by parsing line from 452 557 * \a atomdata_string. … … 457 562 * @param atomdata_string line to parse with space-separated values 458 563 */ 459 void FormatParser< tremolo >:: setAtomData(const std::string &atomdata_string)564 void FormatParser< tremolo >::resetAtomData(const std::string &atomdata_string) 460 565 { 461 566 usedFields_save.clear();
Note:
See TracChangeset
for help on using the changeset viewer.