/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2010 University of Bonn. All rights reserved. * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. */ /* * TremoloParser.cpp * * Created on: Mar 2, 2010 * Author: metzler */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include "CodePatterns/Assert.hpp" #include "CodePatterns/Log.hpp" #include "CodePatterns/toString.hpp" #include "CodePatterns/Verbose.hpp" #include "TremoloParser.hpp" #include "World.hpp" #include "WorldTime.hpp" #include "atom.hpp" #include "Bond/bond.hpp" #include "element.hpp" #include "molecule.hpp" #include "periodentafel.hpp" #include "Descriptors/AtomIdDescriptor.hpp" #include #include #include #include #include using namespace std; // declare specialized static variables const std::string FormatParserTrait::name = "tremolo"; const std::string FormatParserTrait::suffix = "data"; const ParserTypes FormatParserTrait::type = tremolo; /** * Constructor. */ FormatParser< tremolo >::FormatParser() : FormatParser_common(NULL) { knownKeys["x"] = TremoloKey::x; knownKeys["u"] = TremoloKey::u; knownKeys["F"] = TremoloKey::F; knownKeys["stress"] = TremoloKey::stress; knownKeys["Id"] = TremoloKey::Id; knownKeys["neighbors"] = TremoloKey::neighbors; knownKeys["imprData"] = TremoloKey::imprData; knownKeys["GroupMeasureTypeNo"] = TremoloKey::GroupMeasureTypeNo; knownKeys["type"] = TremoloKey::type; knownKeys["extType"] = TremoloKey::extType; knownKeys["name"] = TremoloKey::name; knownKeys["resName"] = TremoloKey::resName; knownKeys["chainID"] = TremoloKey::chainID; knownKeys["resSeq"] = TremoloKey::resSeq; knownKeys["occupancy"] = TremoloKey::occupancy; knownKeys["tempFactor"] = TremoloKey::tempFactor; knownKeys["segID"] = TremoloKey::segID; knownKeys["Charge"] = TremoloKey::Charge; knownKeys["charge"] = TremoloKey::charge; knownKeys["GrpTypeNo"] = TremoloKey::GrpTypeNo; knownKeys["torsion"] = TremoloKey::torsion; createKnownTypesByIdentity(); // default behavior: use all possible keys on output for (std::map::iterator iter = knownKeys.begin(); iter != knownKeys.end(); ++iter) usedFields.push_back(iter->first); // and noKey afterwards(!) such that it is not used in usedFields knownKeys[" "] = TremoloKey::noKey; // with this we can detect invalid keys // invert knownKeys for debug output for (std::map::iterator iter = knownKeys.begin(); iter != knownKeys.end(); ++iter) knownKeyNames.insert( make_pair( iter->second, iter->first) ); additionalAtomData.clear(); } /** * Destructor. */ FormatParser< tremolo >::~FormatParser() { std::cerr << "Clearing usedFields." << std::endl; usedFields.clear(); additionalAtomData.clear(); atomIdMap.clear(); knownKeys.clear(); } /** * Loads atoms from a tremolo-formatted file. * * \param tremolo file */ void FormatParser< tremolo >::load(istream* file) { string line; string::size_type location; // reset atomIdMap, for we now get new serials atomIdMap.clear(); std::cerr << "Clearing usedFields." << std::endl; usedFields.clear(); molecule *newmol = World::getInstance().createMolecule(); newmol->ActiveFlag = true; // TODO: Remove the insertion into molecule when saving does not depend on them anymore. Also, remove molecule.hpp include World::getInstance().getMolecules()->insert(newmol); while (file->good()) { std::getline(*file, line, '\n'); if (usedFields.empty()) { location = line.find("ATOMDATA", 0); if (location != string::npos) { parseAtomDataKeysLine(line, location + 8); } } if (line.length() > 0 && line.at(0) != '#') { readAtomDataLine(line, newmol); } } // refresh atom::nr and atom::name newmol->getAtomCount(); DoLog(3) && (Log() << Verbose(3) << "usedFields after load contains: " << usedFields << std::endl); processNeighborInformation(); adaptImprData(); adaptTorsion(); } /** * Saves the \a atoms into as a tremolo file. * * \param file where to save the state * \param atoms atoms to store */ void FormatParser< tremolo >::save(ostream* file, const std::vector &AtomList) { DoLog(0) && (Log() << Verbose(0) << "Saving changes to tremolo." << std::endl); vector::const_iterator atomIt; /*vector::iterator it;*/ vector::iterator it = unique(usedFields.begin(), usedFields.end()); // skips all duplicates in the vector DoLog(3) && (Log() << Verbose(3) << "usedFields before save contains: " << usedFields << std::endl); DoLog(3) && (Log() << Verbose(3) << "additionalAtomData contains: " << additionalAtomData << std::endl); DoLog(3) && (Log() << Verbose(3) << "additionalAtomData contains: " << additionalAtomData << std::endl); *file << "# ATOMDATA"; for (it=usedFields.begin(); it < usedFields.end(); it++) { *file << "\t" << *it; } *file << endl; for (atomIt = AtomList.begin(); atomIt != AtomList.end(); atomIt++) { saveLine(file, *atomIt); } } /** Add default info, when new atom is added to World. * * @param id of atom */ void FormatParser< tremolo >::AtomInserted(atomId_t id) { std::map::iterator iter = additionalAtomData.find(id); ASSERT(iter == additionalAtomData.end(), "FormatParser< tremolo >::AtomInserted() - additionalAtomData already present for newly added atom " +toString(id)+"."); // don't add entry, as this gives a default resSeq of 0 not the molecule id // additionalAtomData.insert( std::make_pair(id, TremoloAtomInfoContainer()) ); } /** Remove additional AtomData info, when atom has been removed from World. * * @param id of atom */ void FormatParser< tremolo >::AtomRemoved(atomId_t id) { std::map::iterator iter = additionalAtomData.find(id); // as we do not insert AtomData on AtomInserted, we cannot be assured of its presence // ASSERT(iter != additionalAtomData.end(), // "FormatParser< tremolo >::AtomRemoved() - additionalAtomData is not present for atom " // +toString(id)+" to remove."); if (iter != additionalAtomData.end()) additionalAtomData.erase(iter); } /** * Sets the keys for which data should be written to the stream when save is * called. * * \param string of field names with the same syntax as for an ATOMDATA line * but without the prexix "ATOMDATA" */ void FormatParser< tremolo >::setFieldsForSave(std::string atomDataLine) { parseAtomDataKeysLine(atomDataLine, 0); } /** * Writes one line of tremolo-formatted data to the provided stream. * * \param stream where to write the line to * \param reference to the atom of which information should be written */ void FormatParser< tremolo >::saveLine(ostream* file, atom* currentAtom) { //vector::iterator it; // TODO: Is unique for FormatParser< tremolo >::usedFields still required? vector::iterator it = unique(usedFields.begin(), usedFields.end()); // skips all duplicates in the vector TremoloKey::atomDataKey currentField; DoLog(4) && (Log() << Verbose(4) << "INFO: Saving atom " << *currentAtom << ", its father id is " << currentAtom->GetTrueFather()->getId() << std::endl); for (it = usedFields.begin(); it != usedFields.end(); it++) { currentField = knownKeys[it->substr(0, it->find("="))]; switch (currentField) { case TremoloKey::x : // for the moment, assume there are always three dimensions DoLog(3) && (Log() << Verbose(3) << "Writing for type " << knownKeyNames[currentField] << ": " << currentAtom->getPosition() << std::endl); *file << currentAtom->at(0) << "\t"; *file << currentAtom->at(1) << "\t"; *file << currentAtom->at(2) << "\t"; break; case TremoloKey::u : // for the moment, assume there are always three dimensions DoLog(3) && (Log() << Verbose(3) << "Writing for type " << knownKeyNames[currentField] << ": " << currentAtom->getAtomicVelocity() << std::endl); *file << currentAtom->getAtomicVelocity()[0] << "\t"; *file << currentAtom->getAtomicVelocity()[1] << "\t"; *file << currentAtom->getAtomicVelocity()[2] << "\t"; break; case TremoloKey::type : if (additionalAtomData.count(currentAtom->getId())) { if (additionalAtomData[currentAtom->getId()].get(currentField) != "-") { DoLog(3) && (Log() << Verbose(3) << "Writing for type " << knownKeyNames[currentField] << ": " << additionalAtomData[currentAtom->getId()].get(currentField) << std::endl); *file << additionalAtomData[currentAtom->getId()].get(currentField) << "\t"; } else { DoLog(3) && (Log() << Verbose(3) << "Writing for type " << knownKeyNames[currentField] << " default value: " << currentAtom->getType()->getSymbol() << std::endl); *file << currentAtom->getType()->getSymbol() << "\t"; } } else if (additionalAtomData.count(currentAtom->GetTrueFather()->getId())) { if (additionalAtomData[currentAtom->GetTrueFather()->getId()].get(currentField) != "-") { DoLog(3) && (Log() << Verbose(3) << "Writing for type " << knownKeyNames[currentField] << " stuff from father: " << additionalAtomData[currentAtom->GetTrueFather()->getId()].get(currentField) << std::endl); *file << additionalAtomData[currentAtom->GetTrueFather()->getId()].get(currentField) << "\t"; } else { DoLog(3) && (Log() << Verbose(3) << "Writing for type " << knownKeyNames[currentField] << " default value from father: " << currentAtom->GetTrueFather()->getType()->getSymbol() << std::endl); *file << currentAtom->GetTrueFather()->getType()->getSymbol() << "\t"; } } else { DoLog(3) && (Log() << Verbose(3) << "Writing for type " << knownKeyNames[currentField] << " its default value: " << currentAtom->getType()->getSymbol() << std::endl); *file << currentAtom->getType()->getSymbol() << "\t"; } break; case TremoloKey::Id : DoLog(3) && (Log() << Verbose(3) << "Writing for type " << knownKeyNames[currentField] << ": " << currentAtom->getId()+1 << std::endl); *file << currentAtom->getId()+1 << "\t"; break; case TremoloKey::neighbors : DoLog(3) && (Log() << Verbose(3) << "Writing type " << knownKeyNames[currentField] << std::endl); writeNeighbors(file, atoi(it->substr(it->find("=") + 1, 1).c_str()), currentAtom); break; case TremoloKey::resSeq : if (additionalAtomData.count(currentAtom->getId())) { DoLog(3) && (Log() << Verbose(3) << "Writing for type " << knownKeyNames[currentField] << ": " << additionalAtomData[currentAtom->getId()].get(currentField) << std::endl); *file << additionalAtomData[currentAtom->getId()].get(currentField); } else if (currentAtom->getMolecule() != NULL) { DoLog(3) && (Log() << Verbose(3) << "Writing for type " << knownKeyNames[currentField] << " its own id: " << currentAtom->getMolecule()->getId()+1 << std::endl); *file << setw(4) << currentAtom->getMolecule()->getId()+1; } else { DoLog(3) && (Log() << Verbose(3) << "Writing for type " << knownKeyNames[currentField] << " default value: " << defaultAdditionalData.get(currentField) << std::endl); *file << defaultAdditionalData.get(currentField); } *file << "\t"; break; default : if (additionalAtomData.count(currentAtom->getId())) { DoLog(3) && (Log() << Verbose(3) << "Writing for type " << knownKeyNames[currentField] << ": " << additionalAtomData[currentAtom->getId()].get(currentField) << std::endl); *file << additionalAtomData[currentAtom->getId()].get(currentField); } else if (additionalAtomData.count(currentAtom->GetTrueFather()->getId())) { DoLog(3) && (Log() << Verbose(3) << "Writing for type " << knownKeyNames[currentField] << " stuff from father: " << additionalAtomData[currentAtom->GetTrueFather()->getId()].get(currentField) << std::endl); *file << additionalAtomData[currentAtom->GetTrueFather()->getId()].get(currentField); } else { DoLog(3) && (Log() << Verbose(3) << "Writing for type " << knownKeyNames[currentField] << " the default: " << defaultAdditionalData.get(currentField) << std::endl); *file << defaultAdditionalData.get(currentField); } *file << "\t"; break; } } *file << endl; } /** * Writes the neighbor information of one atom to the provided stream. * * Note that ListOfBonds of WorldTime::CurrentTime is used. * * \param stream where to write neighbor information to * \param number of neighbors * \param reference to the atom of which to take the neighbor information */ void FormatParser< tremolo >::writeNeighbors(ostream* file, int numberOfNeighbors, atom* currentAtom) { const BondList& ListOfBonds = currentAtom->getListOfBonds(); // sort bonded indices typedef std::set sortedIndices; sortedIndices sortedBonds; for (BondList::const_iterator iter = ListOfBonds.begin(); iter != ListOfBonds.end(); ++iter) sortedBonds.insert((*iter)->GetOtherAtom(currentAtom)->getId()); // print indices sortedIndices::const_iterator currentBond = sortedBonds.begin(); for (int i = 0; i < numberOfNeighbors; i++) { *file << (currentBond != sortedBonds.end() ? (*currentBond)+1 : 0) << "\t"; if (currentBond != sortedBonds.end()) ++currentBond; } } /** * Stores keys from the ATOMDATA line. * * \param line to parse the keys from * \param with which offset the keys begin within the line */ void FormatParser< tremolo >::parseAtomDataKeysLine(string line, int offset) { string keyword; stringstream lineStream; lineStream << line.substr(offset); std::cerr << "Clearing usedFields in parseAtomDataKeysLine." << std::endl; usedFields.clear(); while (lineStream.good()) { lineStream >> keyword; if (knownKeys[keyword.substr(0, keyword.find("="))] == TremoloKey::noKey) { // TODO: throw exception about unknown key cout << "Unknown key: " << keyword << " is not part of the tremolo format specification." << endl; break; } usedFields.push_back(keyword); } //DoLog(1) && (Log() << Verbose(1) << "INFO: " << usedFields << std::endl); } /** Sets the properties per atom to print to .data file by parsing line from * \a atomdata_string. * * We just call \sa FormatParser< tremolo >::parseAtomDataKeysLine() which is left * private., * * @param atomdata_string line to parse with space-separated values */ void FormatParser< tremolo >::setAtomData(const std::string &atomdata_string) { parseAtomDataKeysLine(atomdata_string, 0); } /** * Reads one data line of a tremolo file and interprets it according to the keys * obtained from the ATOMDATA line. * * \param line to parse as an atom * \param *newmol molecule to add atom to */ void FormatParser< tremolo >::readAtomDataLine(string line, molecule *newmol = NULL) { vector::iterator it; stringstream lineStream; atom* newAtom = World::getInstance().createAtom(); TremoloAtomInfoContainer *atomInfo = NULL; additionalAtomData[newAtom->getId()] = TremoloAtomInfoContainer(); // fill with default values atomInfo = &additionalAtomData[newAtom->getId()]; TremoloKey::atomDataKey currentField; ConvertTo toDouble; ConvertTo toInt; Vector tempVector; // setup tokenizer, splitting up white-spaced entries typedef boost::tokenizer > tokenizer; boost::char_separator whitespacesep(" \t"); tokenizer tokens(line, whitespacesep); ASSERT(tokens.begin() != tokens.end(), "FormatParser< tremolo >::readAtomDataLine - empty string, need at least ' '!"); tokenizer::iterator tok_iter = tokens.begin(); // then associate each token to each file for (it = usedFields.begin(); it < usedFields.end(); it++) { const std::string keyName = it->substr(0, it->find("=")); currentField = knownKeys[keyName]; const string word = *tok_iter; DoLog(4) && (Log() << Verbose(4) << "INFO: Parsing key " << keyName << " with remaining data " << word << std::endl); switch (currentField) { case TremoloKey::x : // for the moment, assume there are always three dimensions for (int i=0;i::readAtomDataLine() - no value for x["+toString(i)+"]!"); DoLog(4) && (Log() << Verbose(4) << "INFO: Parsing key " << keyName << " with next token " << *tok_iter << std::endl); newAtom->set(i, toDouble(*tok_iter)); tok_iter++; } break; case TremoloKey::u : // for the moment, assume there are always three dimensions for (int i=0;i::readAtomDataLine() - no value for u["+toString(i)+"]!"); DoLog(4) && (Log() << Verbose(4) << "INFO: Parsing key " << keyName << " with next token " << *tok_iter << std::endl); tempVector[i] = toDouble(*tok_iter); tok_iter++; } newAtom->setAtomicVelocity(tempVector); break; case TremoloKey::type : { ASSERT(tok_iter != tokens.end(), "FormatParser< tremolo >::readAtomDataLine() - no value for "+keyName+"!"); DoLog(4) && (Log() << Verbose(4) << "INFO: Parsing key " << keyName << " with next token " << *tok_iter << std::endl); std::string element(knownTypes[(*tok_iter)]); // put type name into container for later use atomInfo->set(currentField, *tok_iter); DoLog(4) && (Log() << Verbose(4) << "INFO: Parsing element " << (*tok_iter) << " as " << element << " according to KnownTypes." << std::endl); tok_iter++; newAtom->setType(World::getInstance().getPeriode()->FindElement(element)); ASSERT(newAtom->getType(), "Type was not set for this atom"); break; } case TremoloKey::Id : ASSERT(tok_iter != tokens.end(), "FormatParser< tremolo >::readAtomDataLine() - no value for "+keyName+"!"); DoLog(4) && (Log() << Verbose(4) << "INFO: Parsing key " << keyName << " with next token " << *tok_iter << std::endl); atomIdMap[toInt(*tok_iter)] = newAtom->getId(); tok_iter++; break; case TremoloKey::neighbors : for (int i=0;isubstr(it->find("=") + 1, 1).c_str());i++) { ASSERT(tok_iter != tokens.end(), "FormatParser< tremolo >::readAtomDataLine() - no value for "+keyName+"!"); DoLog(4) && (Log() << Verbose(4) << "INFO: Parsing key " << keyName << " with next token " << *tok_iter << std::endl); lineStream << *tok_iter << "\t"; tok_iter++; } readNeighbors(&lineStream, atoi(it->substr(it->find("=") + 1, 1).c_str()), newAtom->getId()); break; default : ASSERT(tok_iter != tokens.end(), "FormatParser< tremolo >::readAtomDataLine() - no value for "+keyName+"!"); DoLog(4) && (Log() << Verbose(4) << "INFO: Parsing key " << keyName << " with next token " << *tok_iter << std::endl); atomInfo->set(currentField, *tok_iter); tok_iter++; break; } } if (newmol != NULL) { //DoLog(0) && (Log() << Verbose(0) << "New Atom: " << *newAtom << " with type " << newAtom->getType()->getName() << std::endl); newmol->AddAtom(newAtom); } } /** * Reads neighbor information for one atom from the input. * * \param line stream where to read the information from * \param numberOfNeighbors number of neighbors to read * \param atomid world id of the atom the information belongs to */ void FormatParser< tremolo >::readNeighbors(stringstream* line, int numberOfNeighbors, int atomId) { int neighborId = 0; for (int i = 0; i < numberOfNeighbors; i++) { *line >> neighborId; // 0 is used to fill empty neighbor positions in the tremolo file. if (neighborId > 0) { DoLog(4) && (Log() << Verbose(4) << "Atom with global id " << atomId << " has neighbour with serial " << neighborId << std::endl); additionalAtomData[atomId].neighbors.push_back(neighborId); } } } /** * Checks whether the provided name is within the list of used fields. * * \param field name to check * * \return true if the field name is used */ bool FormatParser< tremolo >::isUsedField(string fieldName) { bool fieldNameExists = false; for (vector::iterator usedField = usedFields.begin(); usedField != usedFields.end(); usedField++) { if (usedField->substr(0, usedField->find("=")) == fieldName) fieldNameExists = true; } return fieldNameExists; } /** * Adds the collected neighbor information to the atoms in the world. The atoms * are found by their current ID and mapped to the corresponding atoms with the * Id found in the parsed file. */ void FormatParser< tremolo >::processNeighborInformation() { if (!isUsedField("neighbors")) { return; } for(map::iterator currentInfo = additionalAtomData.begin(); currentInfo != additionalAtomData.end(); currentInfo++ ) { if (!currentInfo->second.neighbors_processed) { for(vector::iterator neighbor = currentInfo->second.neighbors.begin(); neighbor != currentInfo->second.neighbors.end(); neighbor++ ) { // DoLog(1) && (Log() << Verbose(1) << "Creating bond between (" // << currentInfo->first // << ") and (" // << atomIdMap[*neighbor] << "|" << *neighbor << ")" << std::endl); World::getInstance().getAtom(AtomById(currentInfo->first)) ->addBond(WorldTime::getTime(), World::getInstance().getAtom(AtomById(atomIdMap[*neighbor]))); } currentInfo->second.neighbors_processed = true; } } } /** * Replaces atom IDs read from the file by the corresponding world IDs. All IDs * IDs of the input string will be replaced; expected separating characters are * "-" and ",". * * \param string in which atom IDs should be adapted * * \return input string with modified atom IDs */ std::string FormatParser< tremolo >::adaptIdDependentDataString(string data) { // there might be no IDs if (data == "-") { return "-"; } char separator; int id; stringstream line, result; line << data; line >> id; result << atomIdMap[id]; while (line.good()) { line >> separator >> id; result << separator << atomIdMap[id]; } return result.str(); } /** * Corrects the atom IDs in each imprData entry to the corresponding world IDs * as they might differ from the originally read IDs. */ void FormatParser< tremolo >::adaptImprData() { if (!isUsedField("imprData")) { return; } for(map::iterator currentInfo = additionalAtomData.begin(); currentInfo != additionalAtomData.end(); currentInfo++ ) { currentInfo->second.imprData = adaptIdDependentDataString(currentInfo->second.imprData); } } /** * Corrects the atom IDs in each torsion entry to the corresponding world IDs * as they might differ from the originally read IDs. */ void FormatParser< tremolo >::adaptTorsion() { if (!isUsedField("torsion")) { return; } for(map::iterator currentInfo = additionalAtomData.begin(); currentInfo != additionalAtomData.end(); currentInfo++ ) { currentInfo->second.torsion = adaptIdDependentDataString(currentInfo->second.torsion); } } /** Creates knownTypes as the identity, e.g. H -> H, He -> He, ... . * */ void FormatParser< tremolo >::createKnownTypesByIdentity() { // remove old mapping knownTypes.clear(); // make knownTypes the identity mapping const periodentafel *periode = World::getInstance().getPeriode(); for (periodentafel::const_iterator iter = periode->begin(); iter != periode->end(); ++iter) { knownTypes.insert( make_pair(iter->second->getSymbol(), iter->second->getSymbol()) ); } } /** Parses a .potentials file and creates from it the knownTypes file. * * @param file input stream of .potentials file */ void FormatParser< tremolo >::parseKnownTypes(std::istream &file) { const periodentafel *periode = World::getInstance().getPeriode(); // remove old mapping knownTypes.clear(); DoLog(3) && (Log() << Verbose(3) << "additionalAtomData contains: " << additionalAtomData << std::endl); // parse in file typedef boost::tokenizer > tokenizer; boost::char_separator tokensep(":\t ,;"); boost::char_separator equalitysep("\t ="); std::string line; while (file.good()) { std::getline( file, line ); DoLog(4) && (Log() << Verbose(4) << "INFO: full line of parameters is '" << line << "'" << std::endl); if (line.find("particle:") != string::npos) { DoLog(3) && (Log() << Verbose(3) << "INFO: found line '" << line << "' containing keyword 'particle:'." << std::endl); tokenizer tokens(line, tokensep); ASSERT(tokens.begin() != tokens.end(), "FormatParser< tremolo >::parseKnownTypes() - line with 'particle:' but no particles separated by comma."); // look for particle_type std::string particle_type("NULL"); std::string element_type("NULL"); for (tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter) { if ((*tok_iter).find("particle_type") != string::npos) { DoLog(3) && (Log() << Verbose(3) << "INFO: found line '" << line << "' containing keyword 'particle_type'." << std::endl); tokenizer token((*tok_iter), equalitysep); ASSERT(token.begin() != token.end(), "FormatParser< tremolo >::parseKnownTypes() - could not split particle_type by equality sign"); tokenizer::iterator particle_iter = token.begin(); particle_iter++; particle_type = *particle_iter; } if ((*tok_iter).find("element_name") != string::npos) { DoLog(3) && (Log() << Verbose(3) << "INFO: found line '" << line << "' containing keyword 'element_name'." << std::endl); tokenizer token((*tok_iter), equalitysep); ASSERT(token.begin() != token.end(), "FormatParser< tremolo >::parseKnownTypes() - could not split particle_type by equality sign"); tokenizer::iterator element_iter = token.begin(); element_iter++; element_type = *element_iter; } } if ((particle_type != "NULL") && (element_type != "NULL")) { if (periode->FindElement(element_type) != NULL) { DoLog(1) && (Log() << Verbose(1) << "INFO: Added Type " << particle_type << " as reference to element " << element_type << "." << std::endl); knownTypes.insert( make_pair (particle_type, element_type) ); } else { DoeLog(1) && (Log() << Verbose(1) << "INFO: Either Type " << particle_type << " or " << element_type << " could not be recognized." << std::endl); } } else { DoeLog(1) && (Log() << Verbose(1) << "INFO: Desired element " << element_type << " is not known." << std::endl); } } } }