<commit_before>/*
 * Copyright 2009-2013 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <iostream>
#include <iomanip>
#include <fstream>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem/convenience.hpp>
#include <votca/tools/getline.h>

#ifndef HAVE_NO_CONFIG
#include <votca_config.h>
#endif

#include "dlpolytopologyreader.h"

namespace votca { namespace csg {

using namespace std;

string DLPOLYTopologyReader::_NextKeyline(ifstream &fs, const char* wsp)
{
  string line;
  size_t i_nws=0;

  do {
    getline(fs, line);
    i_nws = line.find_first_not_of(wsp);
  } while ( line.substr(i_nws,1) == "#" || line.substr(i_nws,1) == ";" );

  return line.substr(i_nws,line.size()-i_nws);
}

string DLPOLYTopologyReader::_NextKeyInt(ifstream &fs, const char* wsp, const string &word, int &ival)
{
  stringstream sl(_NextKeyline(fs,wsp));
  string line;

  sl >> line; boost::to_upper(line); // allow user not to bother about the case

  if( line.substr(0,word.size()) != word )
    throw std::runtime_error("Error: unexpected line in dlpoly file " + _fname + ", expected '" + word + "' but got '" + line + "'");

  sl >> ival;

  return sl.str();
}

bool DLPOLYTopologyReader::ReadTopology(string file, Topology &top)
{
    int  mavecs=0;
    int  mpbct=0;
    int  matoms=0;
    int  natoms=0;
    bool hasVs=false;
    bool hasFs=false;

    BoundaryCondition::eBoxtype pbc_type=BoundaryCondition::typeAuto;

    std::ifstream fl;
    boost::filesystem::path filepath(file.c_str());

    string line;
    string wsp=" \t";

    // TODO: fix residue naming / assignment - DL_POLY has no means to recognise residues!
    Residue *res = top.CreateResidue("no");

    if ( boost::filesystem::basename(filepath).size() == 0 ) {
      if (filepath.parent_path().string().size() == 0) {
        _fname="FIELD"; // DL_POLY uses fixed file names in current/working directory
      } else {
	_fname=filepath.parent_path().string() + "/FIELD";
      }
    } else {
      _fname=file;
    }

    fl.open(_fname.c_str());

    if (!fl.is_open()){
      throw std::runtime_error("Error on opening dlpoly file '" + _fname + "'");
    } else {

      getline(fl, line); //title
      getline(fl, line); //unit line

      line = _NextKeyline(fl," \t"); boost::to_upper(line);

      if( line.substr(0,4)=="NEUT" ) {
	line = _NextKeyline(fl," \t"); boost::to_upper(line);
      }

      Tokenizer tok(line, " \t"); // "MOLECules or MOLECular species/types #" - may contain a few words!
      vector<string> fields;
      tok.ToVector(fields);

      size_t i_num = line.find_first_of("0123456789");

      if( fields.size() < 2 || i_num == string::npos ) {

	throw std::runtime_error("Error: missing integer number in directive '" + line + "' in topology file '"+ _fname +"'");

      } else if (fields[0].substr(0,5) != "MOLEC") {

	throw std::runtime_error("Error: unexpected line in dlpoly file " + _fname + ", expected 'MOLEC<ULES>' but got '" + line + "'");
      }

      int nmol_types = boost::lexical_cast<int>(fields[fields.size()-1]);

      string mol_name;

      int id=0;
      for (int nmol_type=0;nmol_type<nmol_types; nmol_type++) {

	mol_name = _NextKeyline(fl," \t");
        Molecule *mi = top.CreateMolecule(mol_name);

	int nreplica = 1;
	line = _NextKeyInt(fl," \t","NUMMOL",nreplica);

#ifdef DEBUG
	cout << "Read from topology file " << _fname << " : '" << mol_name << "' - '" << line << "' - " << nreplica << endl;
#endif

	line = _NextKeyInt(fl," \t","ATOMS",natoms);

#ifdef DEBUG
	cout << "Read from topology file " << _fname << " : '" << line << "' - " << natoms << endl;
#endif

	//read molecule
	int id_map[natoms];
	for (int i=0;i<natoms;){//i is altered in repeater loop
	  string beadtype;
	  fl >> beadtype;
	  BeadType *type = top.GetOrCreateBeadType(beadtype);
	  double mass;
	  fl >> mass;
	  double charge;
	  fl >> charge;

          getline(fl,line); //rest of the atom line

          Tokenizer tok(line, " \t");
	  vector<string> fields;
	  tok.ToVector(fields);

	  int repeater=1;
	  if (fields.size() > 1) repeater=boost::lexical_cast<int>(fields[0]);

	  for(int j=0;j<repeater;j++){

	    string beadname = beadtype + "#" + boost::lexical_cast<string>(i+1);
	    Bead *bead = top.CreateBead(1, beadname, type, res->getId(), mass, charge);

            stringstream nm;
            nm << bead->getResnr() + 1 << ":" <<  top.getResidue(bead->getResnr())->getName() << ":" << bead->getName();
            mi->AddBead(bead, nm.str());
	    id_map[i]=bead->getId();
	    i++;
#ifdef DEBUG
	    cout << "Atom identification in maps '" << nm.str() << "'" << endl;
#endif
	  }
	  matoms += repeater;
	}

	while (line != "FINISH"){
	  if ((line == "BONDS")||(line == "ANGLES")||(line == "DIHEDRALS")) {
	    string type = line;
	    int count;
	    fl >> count;
	    for (int i=0;i<count;i++){
	      fl >> line; //bond/angle/dih type not used
	      int ids[4];
              Interaction *ic;
	      fl >> ids[0]; fl>>ids[1];
	      if (type == "BONDS"){
	        ic = new IBond(id_map[ids[0]-1],id_map[ids[1]-1]); // -1 due to fortran vs c
	      } else if (type == "ANGLES"){
		fl >> ids[2];
	        ic = new IAngle(id_map[ids[0]-1],id_map[ids[1]-1],id_map[ids[2]-1]); // -1 due to fortran vs c
	      } else if (type == "DIHEDRALS"){
		fl >> ids[2]; fl >> ids[3];
	        ic = new IDihedral(id_map[ids[0]-1],id_map[ids[1]-1],id_map[ids[2]-1],id_map[ids[3]-1]); // -1 due to fortran vs c
	      }
              ic->setGroup(type);
              ic->setIndex(i);
              ic->setMolecule(mi->getId());
              top.AddBondedInteraction(ic);
              mi->AddInteraction(ic);
	      getline(fl,line);
	    }
	  }
	  fl >> line; boost::to_upper(line);
	  if (fl.eof())
            throw std::runtime_error("Error: unexpected end of dlpoly file " + _fname + " while scanning for kerword 'finish'");
	}

#ifdef DEBUG
	cout << "Read from topology file " << _fname << " : '" << line << "' - done with '" << mol_name << "'" << endl;
#endif

	getline(fl, line); //rest of the FINISH line

	//replicate molecule
	for (int replica=1;replica<nreplica;replica++){
          Molecule *mi_replica = top.CreateMolecule(mol_name);
	  for(int i=0;i<mi->BeadCount();i++){
	    Bead *bead=mi->getBead(i);
	    BeadType *type = top.GetOrCreateBeadType(bead->Type()->getName());
	    string beadname=mi->getBeadName(i);
	    Bead *bead_replica = top.CreateBead(1, bead->getName(), type, res->getId(), bead->getM(), bead->getQ());
	    mi_replica->AddBead(bead_replica,beadname);
	  }
	  InteractionContainer ics=mi->Interactions();
          for(vector<Interaction *>::iterator ic=ics.begin(); ic!=ics.end(); ++ic) {
            Interaction *ic_replica;

	    //TODO: change if beads are not continous anymore - ???

	    int offset = mi_replica->getBead(0)->getId() - mi->getBead(0)->getId();
	    if ((*ic)->BeadCount() == 2) {
	      ic_replica = new IBond((*ic)->getBeadId(0)+offset,(*ic)->getBeadId(1)+offset);
	    } else if ((*ic)->BeadCount() == 3) {
	      ic_replica = new IAngle((*ic)->getBeadId(0)+offset,(*ic)->getBeadId(1)+offset,(*ic)->getBeadId(2)+offset);
	    } else if ((*ic)->BeadCount() == 4) {
	      ic_replica = new IDihedral((*ic)->getBeadId(0)+offset,(*ic)->getBeadId(1)+offset,(*ic)->getBeadId(2)+offset,(*ic)->getBeadId(3)+offset);
	    }
            ic_replica->setGroup((*ic)->getGroup());
            ic_replica->setIndex((*ic)->getIndex());
            ic_replica->setMolecule(mi_replica->getId());
            top.AddBondedInteraction(ic_replica);
            mi_replica->AddInteraction(ic_replica);
	  }
	}
      }
      top.RebuildExclusions();
    }

    getline(fl, line); //is "close" found?

#ifdef DEBUG
    if(line=="close") {
      cout << "Read from topology file " << _fname << " : '" << line << "' - done with topology" << endl;
    }
    else {
      cout << "Read from topology file " << _fname << " : 'EOF' - done with topology (directive 'close' not read!)" << endl;
    }
#endif

    //we don't need the rest
    fl.close();

    string filename;

    if ( boost::filesystem::basename(filepath).size() == 0 ) {
      if (filepath.parent_path().string().size() == 0) {
        filename="CONFIG";
      } else {
	filename=filepath.parent_path().string() + "/CONFIG";
      }
    } else {
      filename=filepath.parent_path().string()+boost::filesystem::basename(filepath)+".dlpc";
      cout << "NOTE: explicit dlpoly topology file name given '" << file << "', so trying to read boundary conditions from CONFIG file named '" << filename << "'" << endl;
    }

    fl.open(filename.c_str());

    if(fl.is_open()) {
      string line;

      getline(fl, line); //title

#ifdef DEBUG
      cout << "Read from initial configuration file : '" << line << "' - header" << endl;
#endif

      getline(fl, line); // 2nd header line

#ifdef DEBUG
      cout << "Read from initial configuration file : '" << line << "' - directives line" << endl;
#endif

      Tokenizer tok(line, " \t");
      vector<string> fields;
      tok.ToVector(fields);

      if( fields.size() < 3 )
	throw std::runtime_error("Error: too few directive switches (<3) in the initial configuration (check its 2-nd line)");

      mavecs = boost::lexical_cast<int>(fields[0]);
      mpbct  = boost::lexical_cast<int>(fields[1]);
      natoms = boost::lexical_cast<int>(fields[2]);

      hasVs = (mavecs > 0); // 1 or 2 => in DL_POLY frame velocity vector follows coords for each atom/bead
      hasFs = (mavecs > 1); // 2      => in DL_POLY frame force vector follows velocities for each atom/bead

      top.SetHasVel(hasVs);
      top.SetHasForce(hasFs);

      if(natoms != matoms)
#ifdef DEBUG
	cout << "Warning: N of atoms/beads in initial configuration & topology differ: " << natoms << " =?= " << matoms << endl;
#else
	throw std::runtime_error("Error: N of atoms/beads in initial configuration & topology differ");
#endif

      vec box_vectors[3];
      for (int i=0;i<3;i++){ // read 3 box lines
        getline(fl, line);

#ifdef DEBUG
	cout << "Read from initial configuration file : '" << line << "' - box vector # " << i+1 << " (Angs)" << endl;
#endif

        if(fl.eof())
          throw std::runtime_error("Error: unexpected EOF in dlpoly file " + filename +", when reading box vector " +
              boost::lexical_cast<string>(i));

        Tokenizer tok(line, " \t");
        vector<double> fields;
        tok.ConvertToVector<double>(fields);
        box_vectors[i]=vec(fields[0],fields[1],fields[2]);

#ifdef DEBUG
	cout << "Read from initial configuration file : '" << fixed << setprecision(10) << setw(20) << fields[0] << setw(20) << fields[1] << setw(20) << fields[2] << "' - box vector # " << i+1 << " (Angs)" << endl;
#endif
      }
      matrix box(box_vectors[0],box_vectors[1],box_vectors[2]);

      if(mpbct == 0) {
	pbc_type=BoundaryCondition::typeOpen;
      }
      else if(mpbct == 1 || mpbct == 2 ) {
	pbc_type=BoundaryCondition::typeOrthorhombic;
      }
      else if(mpbct == 3) {
	pbc_type=BoundaryCondition::typeTriclinic;
      }

      top.setBox(box,pbc_type);

      fl.close();

#ifdef DEBUG
      cout << "Read from initial configuration file : box/cell matrix - done with boundaries" << endl << endl;
#endif
    }
    else {
      cout << "NOTE: could not open dlpoly file " << filename << ", so no PBC set in topology - assuming 'open box'" << endl;
    }

    return true;
}

}}

<commit_msg>dlpolytopologyreader: redid 11f29aeda6e1<commit_after>/*
 * Copyright 2009-2013 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <iostream>
#include <iomanip>
#include <fstream>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem/convenience.hpp>
#include <votca/tools/getline.h>

#ifndef HAVE_NO_CONFIG
#include <votca_config.h>
#endif

#include "dlpolytopologyreader.h"

namespace votca { namespace csg {

using namespace std;

string DLPOLYTopologyReader::_NextKeyline(ifstream &fs, const char* wsp)
{
  string line;
  size_t i_nws=0;

  do {
    getline(fs, line);
    i_nws = line.find_first_not_of(wsp);
  } while ( line.substr(i_nws,1) == "#" || line.substr(i_nws,1) == ";" );

  return line.substr(i_nws,line.size()-i_nws);
}

string DLPOLYTopologyReader::_NextKeyInt(ifstream &fs, const char* wsp, const string &word, int &ival)
{
  stringstream sl(_NextKeyline(fs,wsp));
  string line;

  sl >> line; boost::to_upper(line); // allow user not to bother about the case

  if( line.substr(0,word.size()) != word )
    throw std::runtime_error("Error: unexpected line in dlpoly file " + _fname + ", expected '" + word + "' but got '" + line + "'");

  sl >> ival;

  return sl.str();
}

bool DLPOLYTopologyReader::ReadTopology(string file, Topology &top)
{
    int  mavecs=0;
    int  mpbct=0;
    int  matoms=0;
    int  natoms=0;
    bool hasVs=false;
    bool hasFs=false;

    BoundaryCondition::eBoxtype pbc_type=BoundaryCondition::typeAuto;

    std::ifstream fl;
    boost::filesystem::path filepath(file.c_str());

    string line;
    string wsp=" \t";

    // TODO: fix residue naming / assignment - DL_POLY has no means to recognise residues!
    Residue *res = top.CreateResidue("no");

    if ( boost::filesystem::basename(filepath).size() == 0 ) {
      if (filepath.parent_path().string().size() == 0) {
        _fname="FIELD"; // DL_POLY uses fixed file names in current/working directory
      } else {
	_fname=filepath.parent_path().string() + "/FIELD";
      }
    } else {
      _fname=file;
    }

    fl.open(_fname.c_str());

    if (!fl.is_open()){
      throw std::runtime_error("Error on opening dlpoly file '" + _fname + "'");
    } else {

      getline(fl, line); //title
      getline(fl, line); //unit line

      line = _NextKeyline(fl," \t");
      boost::to_upper(line);

      if( line.substr(0,4)=="NEUT" ) {
	line = _NextKeyline(fl," \t");
	boost::to_upper(line);
      }

      Tokenizer tok(line, " \t"); // "MOLECules or MOLECular species/types #" - may contain a few words!
      vector<string> fields;
      tok.ToVector(fields);

      size_t i_num = line.find_first_of("0123456789");

      if( fields.size() < 2 || i_num == string::npos ) {

	throw std::runtime_error("Error: missing integer number in directive '" + line + "' in topology file '"+ _fname +"'");

      } else if (fields[0].substr(0,5) != "MOLEC") {

	throw std::runtime_error("Error: unexpected line in dlpoly file " + _fname + ", expected 'MOLEC<ULES>' but got '" + line + "'");
      }

      int nmol_types = boost::lexical_cast<int>(fields[fields.size()-1]);

      string mol_name;

      int id=0;
      for (int nmol_type=0;nmol_type<nmol_types; nmol_type++) {

	mol_name = _NextKeyline(fl," \t");
        Molecule *mi = top.CreateMolecule(mol_name);

	int nreplica = 1;
	line = _NextKeyInt(fl," \t","NUMMOL",nreplica);

#ifdef DEBUG
	cout << "Read from topology file " << _fname << " : '" << mol_name << "' - '" << line << "' - " << nreplica << endl;
#endif

	line = _NextKeyInt(fl," \t","ATOMS",natoms);

#ifdef DEBUG
	cout << "Read from topology file " << _fname << " : '" << line << "' - " << natoms << endl;
#endif

	//read molecule
	int id_map[natoms];
	for (int i=0;i<natoms;){//i is altered in repeater loop
	  string beadtype;
	  fl >> beadtype;
	  BeadType *type = top.GetOrCreateBeadType(beadtype);
	  double mass;
	  fl >> mass;
	  double charge;
	  fl >> charge;

          getline(fl,line); //rest of the atom line

          Tokenizer tok(line, " \t");
	  vector<string> fields;
	  tok.ToVector(fields);

	  int repeater=1;
	  if (fields.size() > 1) repeater=boost::lexical_cast<int>(fields[0]);

	  for(int j=0;j<repeater;j++){

	    string beadname = beadtype + "#" + boost::lexical_cast<string>(i+1);
	    Bead *bead = top.CreateBead(1, beadname, type, res->getId(), mass, charge);

            stringstream nm;
            nm << bead->getResnr() + 1 << ":" <<  top.getResidue(bead->getResnr())->getName() << ":" << bead->getName();
            mi->AddBead(bead, nm.str());
	    id_map[i]=bead->getId();
	    i++;
#ifdef DEBUG
	    cout << "Atom identification in maps '" << nm.str() << "'" << endl;
#endif
	  }
	  matoms += repeater;
	}

	while (line != "FINISH"){
	  if ((line == "BONDS")||(line == "ANGLES")||(line == "DIHEDRALS")) {
	    string type = line;
	    int count;
	    fl >> count;
	    for (int i=0;i<count;i++){
	      fl >> line; //bond/angle/dih type not used
	      int ids[4];
              Interaction *ic;
	      fl >> ids[0]; fl>>ids[1];
	      if (type == "BONDS"){
	        ic = new IBond(id_map[ids[0]-1],id_map[ids[1]-1]); // -1 due to fortran vs c
	      } else if (type == "ANGLES"){
		fl >> ids[2];
	        ic = new IAngle(id_map[ids[0]-1],id_map[ids[1]-1],id_map[ids[2]-1]); // -1 due to fortran vs c
	      } else if (type == "DIHEDRALS"){
		fl >> ids[2]; fl >> ids[3];
	        ic = new IDihedral(id_map[ids[0]-1],id_map[ids[1]-1],id_map[ids[2]-1],id_map[ids[3]-1]); // -1 due to fortran vs c
	      }
              ic->setGroup(type);
              ic->setIndex(i);
              ic->setMolecule(mi->getId());
              top.AddBondedInteraction(ic);
              mi->AddInteraction(ic);
	      getline(fl,line);
	    }
	  }
	  fl >> line; boost::to_upper(line);
	  if (fl.eof())
            throw std::runtime_error("Error: unexpected end of dlpoly file " + _fname + " while scanning for kerword 'finish'");
	}

#ifdef DEBUG
	cout << "Read from topology file " << _fname << " : '" << line << "' - done with '" << mol_name << "'" << endl;
#endif

	getline(fl, line); //rest of the FINISH line

	//replicate molecule
	for (int replica=1;replica<nreplica;replica++){
          Molecule *mi_replica = top.CreateMolecule(mol_name);
	  for(int i=0;i<mi->BeadCount();i++){
	    Bead *bead=mi->getBead(i);
	    BeadType *type = top.GetOrCreateBeadType(bead->Type()->getName());
	    string beadname=mi->getBeadName(i);
	    Bead *bead_replica = top.CreateBead(1, bead->getName(), type, res->getId(), bead->getM(), bead->getQ());
	    mi_replica->AddBead(bead_replica,beadname);
	  }
	  matoms+=mi->BeadCount();
	  InteractionContainer ics=mi->Interactions();
          for(vector<Interaction *>::iterator ic=ics.begin(); ic!=ics.end(); ++ic) {
            Interaction *ic_replica;
	    int offset = mi_replica->getBead(0)->getId() - mi->getBead(0)->getId();
	    if ((*ic)->BeadCount() == 2) {
	      ic_replica = new IBond((*ic)->getBeadId(0)+offset,(*ic)->getBeadId(1)+offset);
	    } else if ((*ic)->BeadCount() == 3) {
	      ic_replica = new IAngle((*ic)->getBeadId(0)+offset,(*ic)->getBeadId(1)+offset,(*ic)->getBeadId(2)+offset);
	    } else if ((*ic)->BeadCount() == 4) {
	      ic_replica = new IDihedral((*ic)->getBeadId(0)+offset,(*ic)->getBeadId(1)+offset,(*ic)->getBeadId(2)+offset,(*ic)->getBeadId(3)+offset);
	    }
            ic_replica->setGroup((*ic)->getGroup());
            ic_replica->setIndex((*ic)->getIndex());
            ic_replica->setMolecule(mi_replica->getId());
            top.AddBondedInteraction(ic_replica);
            mi_replica->AddInteraction(ic_replica);
	  }
	}
      }
      top.RebuildExclusions();
    }

#ifdef DEBUG
    getline(fl, line); //is "close" found?
    if(line=="close") {
      cout << "Read from topology file " << _fname << " : '" << line << "' - done with topology" << endl;
    }
    else {
      cout << "Read from topology file " << _fname << " : 'EOF' - done with topology (directive 'close' not read!)" << endl;
    }
#endif

    //we don't need the rest
    fl.close();

    string filename;

    if ( boost::filesystem::basename(filepath).size() == 0 ) {
      if (filepath.parent_path().string().size() == 0) {
        filename="CONFIG";
      } else {
	filename=filepath.parent_path().string() + "/CONFIG";
      }
    } else {
      filename=filepath.parent_path().string()+boost::filesystem::basename(filepath)+".dlpc";
      cout << "NOTE: explicit dlpoly topology file name given '" << file << "', so trying to read boundary conditions from CONFIG file named '" << filename << "'" << endl;
    }

    fl.open(filename.c_str());

    if(fl.is_open()) {
      string line;

      getline(fl, line); //title

#ifdef DEBUG
      cout << "Read from initial configuration file : '" << line << "' - header" << endl;
#endif

      getline(fl, line); // 2nd header line

#ifdef DEBUG
      cout << "Read from initial configuration file : '" << line << "' - directives line" << endl;
#endif

      Tokenizer tok(line, " \t");
      vector<string> fields;
      tok.ToVector(fields);

      if( fields.size() < 3 )
	throw std::runtime_error("Error: too few directive switches (<3) in the initial configuration (check its 2-nd line)");

      mavecs = boost::lexical_cast<int>(fields[0]);
      mpbct  = boost::lexical_cast<int>(fields[1]);
      natoms = boost::lexical_cast<int>(fields[2]);

      hasVs = (mavecs > 0); // 1 or 2 => in DL_POLY frame velocity vector follows coords for each atom/bead
      hasFs = (mavecs > 1); // 2      => in DL_POLY frame force vector follows velocities for each atom/bead

      top.SetHasVel(hasVs);
      top.SetHasForce(hasFs);

      if(natoms != matoms)
#ifdef DEBUG
	cout << "Warning: N of atoms/beads in initial configuration & topology differ: " << natoms << " =?= " << matoms << endl;
#else
	throw std::runtime_error("Error: N of atoms/beads in initial configuration & topology differ " +
	    boost::lexical_cast<string>(natoms) + " vs " + boost::lexical_cast<string>(matoms));
#endif

      vec box_vectors[3];
      for (int i=0;i<3;i++){ // read 3 box lines
        getline(fl, line);

#ifdef DEBUG
	cout << "Read from initial configuration file : '" << line << "' - box vector # " << i+1 << " (Angs)" << endl;
#endif

        if(fl.eof())
          throw std::runtime_error("Error: unexpected EOF in dlpoly file " + filename +", when reading box vector " +
              boost::lexical_cast<string>(i));

        Tokenizer tok(line, " \t");
        vector<double> fields;
        tok.ConvertToVector<double>(fields);
        box_vectors[i]=vec(fields[0],fields[1],fields[2]);

#ifdef DEBUG
	cout << "Read from initial configuration file : '" << fixed << setprecision(10) << setw(20) << fields[0] << setw(20) << fields[1] << setw(20) << fields[2] << "' - box vector # " << i+1 << " (Angs)" << endl;
#endif
      }
      matrix box(box_vectors[0],box_vectors[1],box_vectors[2]);

      if(mpbct == 0) {
	pbc_type=BoundaryCondition::typeOpen;
      }
      else if(mpbct == 1 || mpbct == 2 ) {
	pbc_type=BoundaryCondition::typeOrthorhombic;
      }
      else if(mpbct == 3) {
	pbc_type=BoundaryCondition::typeTriclinic;
      }

      top.setBox(box,pbc_type);

      fl.close();

#ifdef DEBUG
      cout << "Read from initial configuration file : box/cell matrix - done with boundaries" << endl << endl;
#endif
    }
    else {
      cout << "NOTE: could not open dlpoly file " << filename << ", so no PBC set in topology - assuming 'open box'" << endl;
    }

    return true;
}

}}

<|endoftext|>


<commit_before>/*
 * Copyright 2009-2013 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <iostream>
#include <iomanip>
#include <fstream>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem/convenience.hpp>
#include <votca/tools/getline.h>

#ifndef HAVE_NO_CONFIG
#include <votca_config.h>
#endif

#include "dlpolytopologyreader.h"

namespace votca { namespace csg {

bool DLPOLYTopologyReader::ReadTopology(string file, Topology &top)
{
    int  mavecs=0;
    int  mpbct=0;
    int  matoms=0;
    int  natoms=0;
    bool hasVs=false;
    bool hasFs=false;

    BoundaryCondition::eBoxtype pbc_type=BoundaryCondition::typeAuto;

    std::ifstream fl;
    boost::filesystem::path filepath(file.c_str());

    string filename,line;

    // TODO: fix residue naming / assignment - DL_POLY has no means to recognise residues!
    Residue *res = top.CreateResidue("no");

    if ( boost::filesystem::basename(filepath).size() == 0 ) {
      if (filepath.parent_path().string().size() == 0) {
        filename="FIELD"; // DL_POLY uses fixed file names in current/working directory
      } else {
	filename=filepath.parent_path().string() + "/FIELD";
      }
    } else {
      filename=file;
    }

    fl.open(filename.c_str());

    if (!fl.is_open()){
      throw std::runtime_error("Error on opening dlpoly file '" + filename + "'");
    } else {

      getline(fl, line); //title
      getline(fl, line); //unit line

      int nmol_types;

      getline(fl, line);     // "MOLECules or MOLECular species/types #" - may contain a few words!
      boost::to_upper(line); // allow user not to bother about the case
      if (line.substr(0,5) != "MOLEC")
          throw std::runtime_error("Error: unexpected line in dlpoly file " + filename + ", expected 'MOLEC<ULES>' but got '" + line + "'");

      Tokenizer tok(line, " \t");
      vector<string> fields;
      tok.ToVector(fields);

      if( fields.size() < 2 ) {
	throw std::runtime_error("Error: missing number of molecules in directive '" + line + "' in topology file '"+ filename +"'");
      }

      nmol_types = boost::lexical_cast<int>(fields[fields.size()-1]);

      string mol_name;

      int id=0;
      for (int nmol_type=0;nmol_type<nmol_types; nmol_type++){

        getline(fl, mol_name); // molecule name might incl. spaces - so why not allow???

        Molecule *mi = top.CreateMolecule(mol_name);
        fl >> line; boost::to_upper(line); // allow user not to bother about the case

        if (line.substr(0,6) != "NUMMOL")
          throw std::runtime_error("unexpected line in dlpoly file " + filename + ", expected 'NUMMOLS' but got '" + line.substr(0,6) + "'");

	int nreplica;
	fl >> nreplica;

#ifdef DEBUG
	cout << "Read from topology file " << filename << " : '" << mol_name << "' - '" << line << "' - " << nreplica << endl;
#endif

	getline(fl, line); //rest of NUMMOLs line

	fl >> line; boost::to_upper(line);

        if (line != "ATOMS")
          throw std::runtime_error("Error: unexpected line in dlpoly file " + filename + ", expected 'ATOMS' but got '" + line + "'");

	fl >> natoms;

#ifdef DEBUG
	cout << "Read from topology file " << filename << " : '" << line << "' - " << natoms << endl;
#endif

	//read molecule
	int id_map[natoms];
	for (int i=0;i<natoms;){//i is altered in repeater loop
	  string beadtype;
	  fl >> beadtype;
	  BeadType *type = top.GetOrCreateBeadType(beadtype);
	  double mass;
	  fl >> mass;
	  double charge;
	  fl >> charge;

          getline(fl,line); //rest of the atom line

          Tokenizer tok(line, " \t");
	  vector<string> fields;
	  tok.ToVector(fields);

	  int repeater=1;
	  if (fields.size() > 1) repeater=boost::lexical_cast<int>(fields[0]);

	  for(int j=0;j<repeater;j++){

	    string beadname = beadtype + "#" + boost::lexical_cast<string>(i+1);
	    Bead *bead = top.CreateBead(1, beadname, type, res->getId(), mass, charge);

            stringstream nm;
            nm << bead->getResnr() + 1 << ":" <<  top.getResidue(bead->getResnr())->getName() << ":" << bead->getName();
            mi->AddBead(bead, nm.str());
	    id_map[i]=bead->getId();
	    i++;
#ifdef DEBUG
	    cout << "Atom identification in maps '" << nm.str() << "'" << endl;
#endif
	  }
	  matoms += repeater;
	}

	while (line != "FINISH"){
	  if ((line == "BONDS")||(line == "ANGLES")||(line == "DIHEDRALS")) {
	    string type = line;
	    int count;
	    fl >> count;
	    for (int i=0;i<count;i++){
	      fl >> line; //bond/angle/dih type not used
	      int ids[4];
              Interaction *ic;
	      fl >> ids[0]; fl>>ids[1];
	      if (type == "BONDS"){
	        ic = new IBond(id_map[ids[0]-1],id_map[ids[1]-1]); // -1 due to fortran vs c
	      } else if (type == "ANGLES"){
		fl >> ids[2];
	        ic = new IAngle(id_map[ids[0]-1],id_map[ids[1]-1],id_map[ids[2]-1]); // -1 due to fortran vs c
	      } else if (type == "DIHEDRALS"){
		fl >> ids[2]; fl >> ids[3];
	        ic = new IDihedral(id_map[ids[0]-1],id_map[ids[1]-1],id_map[ids[2]-1],id_map[ids[3]-1]); // -1 due to fortran vs c
	      }
              ic->setGroup(type);
              ic->setIndex(i);
              ic->setMolecule(mi->getId());
              top.AddBondedInteraction(ic);
              mi->AddInteraction(ic);
	      getline(fl,line);
	    }
	  }
	  fl >> line; boost::to_upper(line);
	  if (fl.eof())
            throw std::runtime_error("Error: unexpected end of dlpoly file " + filename + " while scanning for kerword 'finish'");
	}

#ifdef DEBUG
	cout << "Read from topology file " << filename << " : '" << line << "' - done with '" << mol_name << "'" << endl;
#endif

	getline(fl, line); //rest of the FINISH line

	//replicate molecule
	for (int replica=1;replica<nreplica;replica++){
          Molecule *mi_replica = top.CreateMolecule(mol_name);
	  for(int i=0;i<mi->BeadCount();i++){
	    Bead *bead=mi->getBead(i);
	    BeadType *type = top.GetOrCreateBeadType(bead->Type()->getName());
	    string beadname=mi->getBeadName(i);
	    Bead *bead_replica = top.CreateBead(1, bead->getName(), type, res->getId(), bead->getM(), bead->getQ());
	    mi_replica->AddBead(bead_replica,beadname);
	  }
	  InteractionContainer ics=mi->Interactions();
          for(vector<Interaction *>::iterator ic=ics.begin(); ic!=ics.end(); ++ic) {
            Interaction *ic_replica;

	    //TODO: change if beads are not continous anymore - ???

	    int offset = mi_replica->getBead(0)->getId() - mi->getBead(0)->getId();
	    if ((*ic)->BeadCount() == 2) {
	      ic_replica = new IBond((*ic)->getBeadId(0)+offset,(*ic)->getBeadId(1)+offset);
	    } else if ((*ic)->BeadCount() == 3) {
	      ic_replica = new IAngle((*ic)->getBeadId(0)+offset,(*ic)->getBeadId(1)+offset,(*ic)->getBeadId(2)+offset);
	    } else if ((*ic)->BeadCount() == 4) {
	      ic_replica = new IDihedral((*ic)->getBeadId(0)+offset,(*ic)->getBeadId(1)+offset,(*ic)->getBeadId(2)+offset,(*ic)->getBeadId(3)+offset);
	    }
            ic_replica->setGroup((*ic)->getGroup());
            ic_replica->setIndex((*ic)->getIndex());
            ic_replica->setMolecule(mi_replica->getId());
            top.AddBondedInteraction(ic_replica);
            mi_replica->AddInteraction(ic_replica);
	  }
	}
      }
      top.RebuildExclusions();
    }

    getline(fl, line); //is "close" found?

#ifdef DEBUG
    if(line=="close") {
      cout << "Read from topology file " << filename << " : '" << line << "' - done with topology" << endl;
    }
    else {
      cout << "Read from topology file " << filename << " : 'EOF' - done with topology (directive 'close' not read!)" << endl;
    }
#endif

    //we don't need the rest
    fl.close();

    if ( boost::filesystem::basename(filepath).size() == 0 ) {
      if (filepath.parent_path().string().size() == 0) {
        filename="CONFIG";
      } else {
	filename=filepath.parent_path().string() + "/CONFIG";
      }
    } else {
      filename=filepath.parent_path().string()+boost::filesystem::basename(filepath)+".dlpc";
      cout << "NOTE: explicit dlpoly topology file name given '" << file << "', so trying to read boundary conditions from CONFIG file named '" << filename << "'" << endl;
    }

    fl.open(filename.c_str());

    if(fl.is_open()) {
      string line;

      getline(fl, line); //title

#ifdef DEBUG
      cout << "Read from initial configuration file : '" << line << "' - header" << endl;
#endif

      getline(fl, line); // 2nd header line

#ifdef DEBUG
      cout << "Read from initial configuration file : '" << line << "' - directives line" << endl;
#endif

      Tokenizer tok(line, " \t");
      vector<string> fields;
      tok.ToVector(fields);

      if( fields.size() < 3 )
	throw std::runtime_error("Error: too few directive switches (<3) in the initial configuration (check its 2-nd line)");

      mavecs = boost::lexical_cast<int>(fields[0]);
      mpbct  = boost::lexical_cast<int>(fields[1]);
      natoms = boost::lexical_cast<int>(fields[2]);

      hasVs = (mavecs > 0); // 1 or 2 => in DL_POLY frame velocity vector follows coords for each atom/bead
      hasFs = (mavecs > 1); // 2      => in DL_POLY frame force vector follows velocities for each atom/bead

      top.SetHasVel(hasVs);
      top.SetHasForce(hasFs);

      if(natoms != matoms)
#ifdef DEBUG
	cout << "Warning: N of atoms/beads in initial configuration & topology differ: " << natoms << " =?= " << matoms << endl;
#else
	throw std::runtime_error("Error: N of atoms/beads in initial configuration & topology differ");
#endif

      vec box_vectors[3];
      for (int i=0;i<3;i++){ // read 3 box lines
        getline(fl, line);

#ifdef DEBUG
	cout << "Read from initial configuration file : '" << line << "' - box vector # " << i+1 << " (Angs)" << endl;
#endif

        if(fl.eof())
          throw std::runtime_error("Error: unexpected EOF in dlpoly file " + filename +", when reading box vector " +
              boost::lexical_cast<string>(i));

        Tokenizer tok(line, " \t");
        vector<double> fields;
        tok.ConvertToVector<double>(fields);
        box_vectors[i]=vec(fields[0],fields[1],fields[2]);

#ifdef DEBUG
	cout << "Read from initial configuration file : '" << fixed << setprecision(10) << setw(20) << fields[0] << setw(20) << fields[1] << setw(20) << fields[2] << "' - box vector # " << i+1 << " (Angs)" << endl;
#endif
      }
      matrix box(box_vectors[0],box_vectors[1],box_vectors[2]);

      if(mpbct == 0) {
	pbc_type=BoundaryCondition::typeOpen;
      }
      else if(mpbct == 1 || mpbct == 2 ) {
	pbc_type=BoundaryCondition::typeOrthorhombic;
      }
      else if(mpbct == 3) {
	pbc_type=BoundaryCondition::typeTriclinic;
      }

      top.setBox(box,pbc_type);

      fl.close();

#ifdef DEBUG
      cout << "Read from initial configuration file : box/cell matrix - done with boundaries" << endl << endl;
#endif
    }
    else {
      cout << "NOTE: could not open dlpoly file " << filename << ", so no PBC set in topology - assuming 'open box'" << endl;
    }

    return true;
}

}}

<commit_msg>dlpolytopologyreader: fixed counting of atoms for molecule replicas<commit_after>/*
 * Copyright 2009-2013 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <iostream>
#include <iomanip>
#include <fstream>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem/convenience.hpp>
#include <votca/tools/getline.h>

#ifndef HAVE_NO_CONFIG
#include <votca_config.h>
#endif

#include "dlpolytopologyreader.h"

namespace votca { namespace csg {

bool DLPOLYTopologyReader::ReadTopology(string file, Topology &top)
{
    int  mavecs=0;
    int  mpbct=0;
    int  matoms=0;
    int  natoms=0;
    bool hasVs=false;
    bool hasFs=false;

    BoundaryCondition::eBoxtype pbc_type=BoundaryCondition::typeAuto;

    std::ifstream fl;
    boost::filesystem::path filepath(file.c_str());

    string filename,line;

    // TODO: fix residue naming / assignment - DL_POLY has no means to recognise residues!
    Residue *res = top.CreateResidue("no");

    if ( boost::filesystem::basename(filepath).size() == 0 ) {
      if (filepath.parent_path().string().size() == 0) {
        filename="FIELD"; // DL_POLY uses fixed file names in current/working directory
      } else {
	filename=filepath.parent_path().string() + "/FIELD";
      }
    } else {
      filename=file;
    }

    fl.open(filename.c_str());

    if (!fl.is_open()){
      throw std::runtime_error("Error on opening dlpoly file '" + filename + "'");
    } else {

      getline(fl, line); //title
      getline(fl, line); //unit line

      int nmol_types;

      getline(fl, line);     // "MOLECules or MOLECular species/types #" - may contain a few words!
      boost::to_upper(line); // allow user not to bother about the case
      if (line.substr(0,5) != "MOLEC")
          throw std::runtime_error("Error: unexpected line in dlpoly file " + filename + ", expected 'MOLEC<ULES>' but got '" + line + "'");

      Tokenizer tok(line, " \t");
      vector<string> fields;
      tok.ToVector(fields);

      if( fields.size() < 2 ) {
	throw std::runtime_error("Error: missing number of molecules in directive '" + line + "' in topology file '"+ filename +"'");
      }

      nmol_types = boost::lexical_cast<int>(fields[fields.size()-1]);

      string mol_name;

      int id=0;
      for (int nmol_type=0;nmol_type<nmol_types; nmol_type++){

        getline(fl, mol_name); // molecule name might incl. spaces - so why not allow???

        Molecule *mi = top.CreateMolecule(mol_name);
        fl >> line; boost::to_upper(line); // allow user not to bother about the case

        if (line.substr(0,6) != "NUMMOL")
          throw std::runtime_error("unexpected line in dlpoly file " + filename + ", expected 'NUMMOLS' but got '" + line.substr(0,6) + "'");

	int nreplica;
	fl >> nreplica;

#ifdef DEBUG
	cout << "Read from topology file " << filename << " : '" << mol_name << "' - '" << line << "' - " << nreplica << endl;
#endif

	getline(fl, line); //rest of NUMMOLs line

	fl >> line; boost::to_upper(line);

        if (line != "ATOMS")
          throw std::runtime_error("Error: unexpected line in dlpoly file " + filename + ", expected 'ATOMS' but got '" + line + "'");

	fl >> natoms;

#ifdef DEBUG
	cout << "Read from topology file " << filename << " : '" << line << "' - " << natoms << endl;
#endif

	//read molecule
	int id_map[natoms];
	for (int i=0;i<natoms;){//i is altered in repeater loop
	  string beadtype;
	  fl >> beadtype;
	  BeadType *type = top.GetOrCreateBeadType(beadtype);
	  double mass;
	  fl >> mass;
	  double charge;
	  fl >> charge;

          getline(fl,line); //rest of the atom line

          Tokenizer tok(line, " \t");
	  vector<string> fields;
	  tok.ToVector(fields);

	  int repeater=1;
	  if (fields.size() > 1) repeater=boost::lexical_cast<int>(fields[0]);

	  for(int j=0;j<repeater;j++){

	    string beadname = beadtype + "#" + boost::lexical_cast<string>(i+1);
	    Bead *bead = top.CreateBead(1, beadname, type, res->getId(), mass, charge);

            stringstream nm;
            nm << bead->getResnr() + 1 << ":" <<  top.getResidue(bead->getResnr())->getName() << ":" << bead->getName();
            mi->AddBead(bead, nm.str());
	    id_map[i]=bead->getId();
	    i++;
#ifdef DEBUG
	    cout << "Atom identification in maps '" << nm.str() << "'" << endl;
#endif
	  }
	  matoms += repeater;
	}

	while (line != "FINISH"){
	  if ((line == "BONDS")||(line == "ANGLES")||(line == "DIHEDRALS")) {
	    string type = line;
	    int count;
	    fl >> count;
	    for (int i=0;i<count;i++){
	      fl >> line; //bond/angle/dih type not used
	      int ids[4];
              Interaction *ic;
	      fl >> ids[0]; fl>>ids[1];
	      if (type == "BONDS"){
	        ic = new IBond(id_map[ids[0]-1],id_map[ids[1]-1]); // -1 due to fortran vs c
	      } else if (type == "ANGLES"){
		fl >> ids[2];
	        ic = new IAngle(id_map[ids[0]-1],id_map[ids[1]-1],id_map[ids[2]-1]); // -1 due to fortran vs c
	      } else if (type == "DIHEDRALS"){
		fl >> ids[2]; fl >> ids[3];
	        ic = new IDihedral(id_map[ids[0]-1],id_map[ids[1]-1],id_map[ids[2]-1],id_map[ids[3]-1]); // -1 due to fortran vs c
	      }
              ic->setGroup(type);
              ic->setIndex(i);
              ic->setMolecule(mi->getId());
              top.AddBondedInteraction(ic);
              mi->AddInteraction(ic);
	      getline(fl,line);
	    }
	  }
	  fl >> line; boost::to_upper(line);
	  if (fl.eof())
            throw std::runtime_error("Error: unexpected end of dlpoly file " + filename + " while scanning for kerword 'finish'");
	}

#ifdef DEBUG
	cout << "Read from topology file " << filename << " : '" << line << "' - done with '" << mol_name << "'" << endl;
#endif

	getline(fl, line); //rest of the FINISH line

	//replicate molecule
	for (int replica=1;replica<nreplica;replica++){
          Molecule *mi_replica = top.CreateMolecule(mol_name);
	  for(int i=0;i<mi->BeadCount();i++){
	    Bead *bead=mi->getBead(i);
	    BeadType *type = top.GetOrCreateBeadType(bead->Type()->getName());
	    string beadname=mi->getBeadName(i);
	    Bead *bead_replica = top.CreateBead(1, bead->getName(), type, res->getId(), bead->getM(), bead->getQ());
	    mi_replica->AddBead(bead_replica,beadname);
	  }
	  matoms+=mi->BeadCount();
	  InteractionContainer ics=mi->Interactions();
          for(vector<Interaction *>::iterator ic=ics.begin(); ic!=ics.end(); ++ic) {
            Interaction *ic_replica;

	    int offset = mi_replica->getBead(0)->getId() - mi->getBead(0)->getId();
	    if ((*ic)->BeadCount() == 2) {
	      ic_replica = new IBond((*ic)->getBeadId(0)+offset,(*ic)->getBeadId(1)+offset);
	    } else if ((*ic)->BeadCount() == 3) {
	      ic_replica = new IAngle((*ic)->getBeadId(0)+offset,(*ic)->getBeadId(1)+offset,(*ic)->getBeadId(2)+offset);
	    } else if ((*ic)->BeadCount() == 4) {
	      ic_replica = new IDihedral((*ic)->getBeadId(0)+offset,(*ic)->getBeadId(1)+offset,(*ic)->getBeadId(2)+offset,(*ic)->getBeadId(3)+offset);
	    }
            ic_replica->setGroup((*ic)->getGroup());
            ic_replica->setIndex((*ic)->getIndex());
            ic_replica->setMolecule(mi_replica->getId());
            top.AddBondedInteraction(ic_replica);
            mi_replica->AddInteraction(ic_replica);
	  }
	}
      }
      top.RebuildExclusions();
    }

#ifdef DEBUG
    getline(fl, line); //is "close" found?
    if(line=="close") {
      cout << "Read from topology file " << filename << " : '" << line << "' - done with topology" << endl;
    }
    else {
      cout << "Read from topology file " << filename << " : 'EOF' - done with topology (directive 'close' not read!)" << endl;
    }
#endif

    //we don't need the rest
    fl.close();

    if ( boost::filesystem::basename(filepath).size() == 0 ) {
      if (filepath.parent_path().string().size() == 0) {
        filename="CONFIG";
      } else {
	filename=filepath.parent_path().string() + "/CONFIG";
      }
    } else {
      filename=filepath.parent_path().string()+boost::filesystem::basename(filepath)+".dlpc";
      cout << "NOTE: explicit dlpoly topology file name given '" << file << "', so trying to read boundary conditions from CONFIG file named '" << filename << "'" << endl;
    }

    fl.open(filename.c_str());

    if(fl.is_open()) {
      string line;

      getline(fl, line); //title

#ifdef DEBUG
      cout << "Read from initial configuration file : '" << line << "' - header" << endl;
#endif

      getline(fl, line); // 2nd header line

#ifdef DEBUG
      cout << "Read from initial configuration file : '" << line << "' - directives line" << endl;
#endif

      Tokenizer tok(line, " \t");
      vector<string> fields;
      tok.ToVector(fields);

      if( fields.size() < 3 )
	throw std::runtime_error("Error: too few directive switches (<3) in the initial configuration (check its 2-nd line)");

      mavecs = boost::lexical_cast<int>(fields[0]);
      mpbct  = boost::lexical_cast<int>(fields[1]);
      natoms = boost::lexical_cast<int>(fields[2]);

      hasVs = (mavecs > 0); // 1 or 2 => in DL_POLY frame velocity vector follows coords for each atom/bead
      hasFs = (mavecs > 1); // 2      => in DL_POLY frame force vector follows velocities for each atom/bead

      top.SetHasVel(hasVs);
      top.SetHasForce(hasFs);

      if(natoms != matoms)
#ifdef DEBUG
	cout << "Warning: N of atoms/beads in initial configuration & topology differ: " << natoms << " =?= " << matoms << endl;
#else
	throw std::runtime_error("Error: N of atoms/beads in initial configuration & topology differ " +
	    boost::lexical_cast<string>(natoms) + " vs " + boost::lexical_cast<string>(matoms));
#endif

      vec box_vectors[3];
      for (int i=0;i<3;i++){ // read 3 box lines
        getline(fl, line);

#ifdef DEBUG
	cout << "Read from initial configuration file : '" << line << "' - box vector # " << i+1 << " (Angs)" << endl;
#endif

        if(fl.eof())
          throw std::runtime_error("Error: unexpected EOF in dlpoly file " + filename +", when reading box vector " +
              boost::lexical_cast<string>(i));

        Tokenizer tok(line, " \t");
        vector<double> fields;
        tok.ConvertToVector<double>(fields);
        box_vectors[i]=vec(fields[0],fields[1],fields[2]);

#ifdef DEBUG
	cout << "Read from initial configuration file : '" << fixed << setprecision(10) << setw(20) << fields[0] << setw(20) << fields[1] << setw(20) << fields[2] << "' - box vector # " << i+1 << " (Angs)" << endl;
#endif
      }
      matrix box(box_vectors[0],box_vectors[1],box_vectors[2]);

      if(mpbct == 0) {
	pbc_type=BoundaryCondition::typeOpen;
      }
      else if(mpbct == 1 || mpbct == 2 ) {
	pbc_type=BoundaryCondition::typeOrthorhombic;
      }
      else if(mpbct == 3) {
	pbc_type=BoundaryCondition::typeTriclinic;
      }

      top.setBox(box,pbc_type);

      fl.close();

#ifdef DEBUG
      cout << "Read from initial configuration file : box/cell matrix - done with boundaries" << endl << endl;
#endif
    }
    else {
      cout << "NOTE: could not open dlpoly file " << filename << ", so no PBC set in topology - assuming 'open box'" << endl;
    }

    return true;
}

}}

<|endoftext|>


<commit_before>/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009-2014 Klaus Post

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "rawspeedconfig.h"
#include "decoders/DngDecoderSlices.h"
#include "common/Common.h"                          // for uint32, getThrea...
#include "common/Point.h"                           // for iPoint2D
#include "decoders/RawDecoderException.h"           // for RawDecoderException
#include "decompressors/DeflateDecompressor.h"      // for DeflateDecompressor
#include "decompressors/JpegDecompressor.h"         // for JpegDecompressor
#include "decompressors/LJpegDecompressor.h"        // for LJpegDecompressor
#include "decompressors/UncompressedDecompressor.h" // for UncompressedDeco...
#include "io/Endianness.h"                          // for Endianness::big
#include "io/IOException.h"                         // for IOException
#include "tiff/TiffEntry.h"                         // IWYU pragma: keep
#include "tiff/TiffIFD.h"                           // for getTiffEndianness
#include <algorithm>                                // for move
#include <cassert>                                  // for assert
#include <cstdio>                                   // for size_t
#include <exception>                                // for exception
#include <memory>                                   // for allocator_traits...
#include <string>                                   // for string, operator+
#include <vector>                                   // for allocator, vector

using namespace std;

namespace RawSpeed {

void *DecodeThread(void *_this) {
  auto *me = (DngDecoderThread *)_this;
  DngDecoderSlices* parent = me->parent;
  try {
    parent->decodeSlice(me);
  } catch (const std::exception &exc) {
    parent->mRaw->setError(string(
        string("DNGDEcodeThread: Caught exception: ") + string(exc.what())));
  } catch (...) {
    parent->mRaw->setError("DNGDEcodeThread: Caught unhandled exception.");
  }
  return nullptr;
}

DngDecoderSlices::DngDecoderSlices(Buffer* file, const RawImage& img,
                                   int _compression)
    : mFile(file), mRaw(img) {
  mFixLjpeg = false;
  compression = _compression;
}

void DngDecoderSlices::addSlice(std::unique_ptr<DngSliceElement>&& slice) {
  slices.emplace(move(slice));
}

void DngDecoderSlices::startDecoding() {
#ifndef HAVE_PTHREAD
  DngDecoderThread t(this);
  while (!slices.empty()) {
    t.slices.emplace(move(slices.front()));
    slices.pop();
  }
  DecodeThread(&t);
#else
  // Create threads

  nThreads = getThreadCount();
  int slicesPerThread = ((int)slices.size() + nThreads - 1) / nThreads;
//  decodedSlices = 0;
  pthread_attr_t attr;
  /* Initialize and set thread detached attribute */
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

  threads.reserve(nThreads);

  for (uint32 i = 0; i < nThreads; i++) {
    auto t = make_unique<DngDecoderThread>(this);
    for (int j = 0; j < slicesPerThread ; j++) {
      if (!slices.empty()) {
        t->slices.emplace(move(slices.front()));
        slices.pop();
      }
    }
    pthread_create(&t->threadid, &attr, DecodeThread, t.get());
    threads.emplace_back(move(t));
  }
  pthread_attr_destroy(&attr);

  void *status;
  for (auto& thread : threads) {
    pthread_join(thread->threadid, &status);
  }
  threads.clear();
#endif
}

void DngDecoderSlices::decodeSlice(DngDecoderThread* t) {
  assert(t);
  assert(mRaw->dim.x > 0);
  assert(mRaw->dim.y > 0);
  assert(mRaw->getCpp() > 0);
  assert(mBps > 0 && mBps <= 32);

  if (compression == 1) {
    while (!t->slices.empty()) {
      auto e = move(t->slices.front());
      t->slices.pop();

      UncompressedDecompressor decompressor(*mFile, e->byteOffset, e->byteCount,
                                            mRaw);

      size_t thisTileLength = e->offY + e->height > (uint32)mRaw->dim.y
                                  ? mRaw->dim.y - e->offY
                                  : e->height;

      iPoint2D tileSize(mRaw->dim.x, thisTileLength);
      iPoint2D pos(0, e->offY);

      bool big_endian = (getTiffEndianness(mFile) == big);
      // DNG spec says that if not 8 or 16 bit/sample, always use big endian
      if (mBps != 8 && mBps != 16)
        big_endian = true;

      try {
        const int inputPitchBits = mRaw->getCpp() * mRaw->dim.x * mBps;
        assert(inputPitchBits > 0);

        const int inputPitch = inputPitchBits / 8;
        if (inputPitch == 0)
          ThrowRDE("Data input pitch is too short. Can not decode!");

        decompressor.readUncompressedRaw(tileSize, pos, inputPitch, mBps,
                                         big_endian ? BitOrder_Jpeg
                                                    : BitOrder_Plain);
      } catch (RawDecoderException& err) {
        mRaw->setError(err.what());
      } catch (IOException& err) {
        mRaw->setError(err.what());
      }
    }
  } else if (compression == 7) {
    while (!t->slices.empty()) {
      auto e = move(t->slices.front());
      t->slices.pop();
      LJpegDecompressor d(*mFile, e->byteOffset, e->byteCount, mRaw);
      try {
        d.decode(e->offX, e->offY, mFixLjpeg);
      } catch (RawDecoderException &err) {
        mRaw->setError(err.what());
      } catch (IOException &err) {
        mRaw->setError(err.what());
      }
    }
    /* Deflate compression */
  } else if (compression == 8) {
#ifdef HAVE_ZLIB
    unsigned char *uBuffer = nullptr;
    while (!t->slices.empty()) {
      auto e = move(t->slices.front());
      t->slices.pop();

      DeflateDecompressor z(*mFile, e->byteOffset, e->byteCount, mRaw,
                            mPredictor, mBps);
      try {
        z.decode(&uBuffer, e->width, e->height, e->offX, e->offY);
      } catch (RawDecoderException &err) {
        mRaw->setError(err.what());
      } catch (IOException &err) {
        mRaw->setError(err.what());
      }
    }
    delete [] uBuffer;
#else
#pragma message                                                                \
    "ZLIB is not present! Deflate compression will not be supported!"
    ThrowRDE("deflate support is disabled.");
#endif
    /* Lossy DNG */
  } else if (compression == 0x884c) {
#ifdef HAVE_JPEG
    /* Each slice is a JPEG image */
    while (!t->slices.empty()) {
      auto e = move(t->slices.front());
      t->slices.pop();
      JpegDecompressor j(*mFile, e->byteOffset, e->byteCount, mRaw);
      try {
        j.decode(e->offX, e->offY);
      } catch (RawDecoderException &err) {
        mRaw->setError(err.what());
      } catch (IOException &err) {
        mRaw->setError(err.what());
      }
    }
#else
#pragma message "JPEG is not present! Lossy JPEG DNG will not be supported!"
    ThrowRDE("jpeg support is disabled.");
#endif
  } else
    mRaw->setError("DngDecoderSlices: Unknown compression");
}

int __attribute__((pure)) DngDecoderSlices::size() {
  return (int)slices.size();
}

} // namespace RawSpeed
<commit_msg>DngDecoderSlices::DngDecoderSlices(): use initialization list.<commit_after>/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009-2014 Klaus Post

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "rawspeedconfig.h"
#include "decoders/DngDecoderSlices.h"
#include "common/Common.h"                          // for uint32, getThrea...
#include "common/Point.h"                           // for iPoint2D
#include "decoders/RawDecoderException.h"           // for RawDecoderException
#include "decompressors/DeflateDecompressor.h"      // for DeflateDecompressor
#include "decompressors/JpegDecompressor.h"         // for JpegDecompressor
#include "decompressors/LJpegDecompressor.h"        // for LJpegDecompressor
#include "decompressors/UncompressedDecompressor.h" // for UncompressedDeco...
#include "io/Endianness.h"                          // for Endianness::big
#include "io/IOException.h"                         // for IOException
#include "tiff/TiffEntry.h"                         // IWYU pragma: keep
#include "tiff/TiffIFD.h"                           // for getTiffEndianness
#include <algorithm>                                // for move
#include <cassert>                                  // for assert
#include <cstdio>                                   // for size_t
#include <exception>                                // for exception
#include <memory>                                   // for allocator_traits...
#include <string>                                   // for string, operator+
#include <vector>                                   // for allocator, vector

using namespace std;

namespace RawSpeed {

void *DecodeThread(void *_this) {
  auto *me = (DngDecoderThread *)_this;
  DngDecoderSlices* parent = me->parent;
  try {
    parent->decodeSlice(me);
  } catch (const std::exception &exc) {
    parent->mRaw->setError(string(
        string("DNGDEcodeThread: Caught exception: ") + string(exc.what())));
  } catch (...) {
    parent->mRaw->setError("DNGDEcodeThread: Caught unhandled exception.");
  }
  return nullptr;
}

DngDecoderSlices::DngDecoderSlices(Buffer* file, const RawImage& img,
                                   int _compression)
    : mFile(file), mRaw(img), mFixLjpeg(false), compression(_compression) {}

void DngDecoderSlices::addSlice(std::unique_ptr<DngSliceElement>&& slice) {
  slices.emplace(move(slice));
}

void DngDecoderSlices::startDecoding() {
#ifndef HAVE_PTHREAD
  DngDecoderThread t(this);
  while (!slices.empty()) {
    t.slices.emplace(move(slices.front()));
    slices.pop();
  }
  DecodeThread(&t);
#else
  // Create threads

  nThreads = getThreadCount();
  int slicesPerThread = ((int)slices.size() + nThreads - 1) / nThreads;
//  decodedSlices = 0;
  pthread_attr_t attr;
  /* Initialize and set thread detached attribute */
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

  threads.reserve(nThreads);

  for (uint32 i = 0; i < nThreads; i++) {
    auto t = make_unique<DngDecoderThread>(this);
    for (int j = 0; j < slicesPerThread ; j++) {
      if (!slices.empty()) {
        t->slices.emplace(move(slices.front()));
        slices.pop();
      }
    }
    pthread_create(&t->threadid, &attr, DecodeThread, t.get());
    threads.emplace_back(move(t));
  }
  pthread_attr_destroy(&attr);

  void *status;
  for (auto& thread : threads) {
    pthread_join(thread->threadid, &status);
  }
  threads.clear();
#endif
}

void DngDecoderSlices::decodeSlice(DngDecoderThread* t) {
  assert(t);
  assert(mRaw->dim.x > 0);
  assert(mRaw->dim.y > 0);
  assert(mRaw->getCpp() > 0);
  assert(mBps > 0 && mBps <= 32);

  if (compression == 1) {
    while (!t->slices.empty()) {
      auto e = move(t->slices.front());
      t->slices.pop();

      UncompressedDecompressor decompressor(*mFile, e->byteOffset, e->byteCount,
                                            mRaw);

      size_t thisTileLength = e->offY + e->height > (uint32)mRaw->dim.y
                                  ? mRaw->dim.y - e->offY
                                  : e->height;

      iPoint2D tileSize(mRaw->dim.x, thisTileLength);
      iPoint2D pos(0, e->offY);

      bool big_endian = (getTiffEndianness(mFile) == big);
      // DNG spec says that if not 8 or 16 bit/sample, always use big endian
      if (mBps != 8 && mBps != 16)
        big_endian = true;

      try {
        const int inputPitchBits = mRaw->getCpp() * mRaw->dim.x * mBps;
        assert(inputPitchBits > 0);

        const int inputPitch = inputPitchBits / 8;
        if (inputPitch == 0)
          ThrowRDE("Data input pitch is too short. Can not decode!");

        decompressor.readUncompressedRaw(tileSize, pos, inputPitch, mBps,
                                         big_endian ? BitOrder_Jpeg
                                                    : BitOrder_Plain);
      } catch (RawDecoderException& err) {
        mRaw->setError(err.what());
      } catch (IOException& err) {
        mRaw->setError(err.what());
      }
    }
  } else if (compression == 7) {
    while (!t->slices.empty()) {
      auto e = move(t->slices.front());
      t->slices.pop();
      LJpegDecompressor d(*mFile, e->byteOffset, e->byteCount, mRaw);
      try {
        d.decode(e->offX, e->offY, mFixLjpeg);
      } catch (RawDecoderException &err) {
        mRaw->setError(err.what());
      } catch (IOException &err) {
        mRaw->setError(err.what());
      }
    }
    /* Deflate compression */
  } else if (compression == 8) {
#ifdef HAVE_ZLIB
    unsigned char *uBuffer = nullptr;
    while (!t->slices.empty()) {
      auto e = move(t->slices.front());
      t->slices.pop();

      DeflateDecompressor z(*mFile, e->byteOffset, e->byteCount, mRaw,
                            mPredictor, mBps);
      try {
        z.decode(&uBuffer, e->width, e->height, e->offX, e->offY);
      } catch (RawDecoderException &err) {
        mRaw->setError(err.what());
      } catch (IOException &err) {
        mRaw->setError(err.what());
      }
    }
    delete [] uBuffer;
#else
#pragma message                                                                \
    "ZLIB is not present! Deflate compression will not be supported!"
    ThrowRDE("deflate support is disabled.");
#endif
    /* Lossy DNG */
  } else if (compression == 0x884c) {
#ifdef HAVE_JPEG
    /* Each slice is a JPEG image */
    while (!t->slices.empty()) {
      auto e = move(t->slices.front());
      t->slices.pop();
      JpegDecompressor j(*mFile, e->byteOffset, e->byteCount, mRaw);
      try {
        j.decode(e->offX, e->offY);
      } catch (RawDecoderException &err) {
        mRaw->setError(err.what());
      } catch (IOException &err) {
        mRaw->setError(err.what());
      }
    }
#else
#pragma message "JPEG is not present! Lossy JPEG DNG will not be supported!"
    ThrowRDE("jpeg support is disabled.");
#endif
  } else
    mRaw->setError("DngDecoderSlices: Unknown compression");
}

int __attribute__((pure)) DngDecoderSlices::size() {
  return (int)slices.size();
}

} // namespace RawSpeed
<|endoftext|>


<commit_before>#include <iostream>
#include <sstream>
#include <fstream>
#include <time.h>
#include <strings.h>

#include "Options.h"
#include "Json.h"
#include "xalt_config.h"
#include "capture.h"
#include "transmit.h"
#include "buildRmapT.h"
#include "run_submission.h"
#include "run_direct2db.h"

#define DATESZ 100

int main(int argc, char* argv[], char* env[])
{
  Options options(argc, argv);
  char    dateStr[DATESZ];
  time_t  time;
  char*   p;

  //*********************************************************************
  // Build the env table:
  Table envT;
  buildEnvT(env, envT);

  //*********************************************************************
  // Build userT
  Table userT;
  buildUserT(options, userT);

  //*********************************************************************
  // Extract the xalt record stored in the executable (possibly)
  Table recordT;
  extractXALTRecord(options.exec(), recordT);

  //*********************************************************************
  // Take sha1sum of the executable
  std::vector<std::string> result;
  std::string              cmd;
  cmd  = SHA1SUM " " + options.exec();
  capture(cmd, result);
  std::string sha1_exec = result[0].substr(0, result[0].find(" "));

  //*********************************************************************
  // Parse the output of ldd for this executable.
  std::vector<Libpair> libA;
  parseLDD(options.exec(), libA);

  const char * transmission = getenv("XALT_TRANSMISSION_STYLE");
  if (transmission == NULL)
    transmission = TRANSMISSION;

  if (strcasecmp(transmission, "direct2db") == 0)
    {
      std::string rmapD = ""; // must use XALT_ETC_DIR to specify where rmapD is!
      Table       rmapT;
      Vstring     xlibmapA;

      buildRmapT(rmapD, rmapT, xlibmapA);
      run_direct2db(options.confFn().c_str(), options.userCmdLine(), sha1_exec, rmapT, envT, userT, recordT, libA);
      return 0;
    }

  //*********************************************************************
  // If here then we need the json string.  So build it!

  Json    json;
  json.add_json_string("cmdlineA",options.userCmdLine());
  json.add("envT",envT);
  json.add("userT",userT);
  json.add("xaltLinkT",recordT);
  json.add("hash_id",sha1_exec);
  json.add("libA",libA);
  json.fini();

  std::string jsonStr = json.result();
  std::string fn;
  const char* resultFn = NULL;

  std::string key   = ((options.endTime() > 0.0) ? "run_fini_" : "run_strt_");
  key.append(options.uuid());

  if (strcasecmp(transmission, "file") == 0)
    {
      //*********************************************************************
      // Build file name for xalt json record.  It is only used when the
      // file transmission style is used;
      p = getenv("HOME");
      if (p != NULL)
        {
          std::string home   = p;
          std::string suffix = (options.endTime() > 0.0) ? "zzz" : "aaa";

          time = options.startTime();
          strftime(dateStr, DATESZ, "%Y_%m_%d_%H_%M_%S",localtime(&time));

          std::ostringstream sstream;
          sstream << home << "/.xalt.d/run." << options.syshost() << ".";
          sstream << dateStr << "." << suffix << "." << options.uuid() << ".json";

          fn = sstream.str();
          resultFn = fn.c_str();
        }
    }

  transmit(transmission, jsonStr, "run", key, options.syshost().c_str(), resultFn);
  return 0;
}
<commit_msg>formatting<commit_after>#include <iostream>
#include <sstream>
#include <fstream>
#include <time.h>
#include <strings.h>

#include "Options.h"
#include "Json.h"
#include "xalt_config.h"
#include "capture.h"
#include "transmit.h"
#include "buildRmapT.h"
#include "run_submission.h"
#include "run_direct2db.h"

#define DATESZ 100

int main(int argc, char* argv[], char* env[])
{
  Options options(argc, argv);
  char    dateStr[DATESZ];
  time_t  time;
  char*   p;

  //*********************************************************************
  // Build the env table:
  Table envT;
  buildEnvT(env, envT);

  //*********************************************************************
  // Build userT
  Table userT;
  buildUserT(options, userT);

  //*********************************************************************
  // Extract the xalt record stored in the executable (possibly)
  Table recordT;
  extractXALTRecord(options.exec(), recordT);

  //*********************************************************************
  // Take sha1sum of the executable
  std::vector<std::string> result;
  std::string              cmd;
  cmd  = SHA1SUM " " + options.exec();
  capture(cmd, result);
  std::string sha1_exec = result[0].substr(0, result[0].find(" "));

  //*********************************************************************
  // Parse the output of ldd for this executable.
  std::vector<Libpair> libA;
  parseLDD(options.exec(), libA);

  const char * transmission = getenv("XALT_TRANSMISSION_STYLE");
  if (transmission == NULL)
    transmission = TRANSMISSION;

  if (strcasecmp(transmission, "direct2db") == 0)
    {
      std::string rmapD = ""; // must use XALT_ETC_DIR to specify where rmapD is!
      Table       rmapT;
      Vstring     xlibmapA;

      buildRmapT(rmapD, rmapT, xlibmapA);
      run_direct2db(options.confFn().c_str(), options.userCmdLine(), sha1_exec, rmapT, envT, userT, recordT, libA);
      return 0;
    }

  //*********************************************************************
  // If here then we need the json string.  So build it!

  Json json;
  json.add_json_string("cmdlineA",options.userCmdLine());
  json.add("envT",envT);
  json.add("userT",userT);
  json.add("xaltLinkT",recordT);
  json.add("hash_id",sha1_exec);
  json.add("libA",libA);
  json.fini();

  std::string jsonStr = json.result();
  std::string fn;
  const char* resultFn = NULL;

  std::string key   = ((options.endTime() > 0.0) ? "run_fini_" : "run_strt_");
  key.append(options.uuid());

  if (strcasecmp(transmission, "file") == 0)
    {
      //*********************************************************************
      // Build file name for xalt json record.  It is only used when the
      // file transmission style is used;
      p = getenv("HOME");
      if (p != NULL)
        {
          std::string home   = p;
          std::string suffix = (options.endTime() > 0.0) ? "zzz" : "aaa";

          time = options.startTime();
          strftime(dateStr, DATESZ, "%Y_%m_%d_%H_%M_%S",localtime(&time));

          std::ostringstream sstream;
          sstream << home << "/.xalt.d/run." << options.syshost() << ".";
          sstream << dateStr << "." << suffix << "." << options.uuid() << ".json";

          fn = sstream.str();
          resultFn = fn.c_str();
        }
    }

  transmit(transmission, jsonStr, "run", key, options.syshost().c_str(), resultFn);
  return 0;
}
<|endoftext|>


<commit_before>//
//  xpcommands.cpp
//  xlua
//
//  Created by Benjamin Supnik on 4/12/16.
//
//	Copyright 2016, Laminar Research
//	This source code is licensed under the MIT open source license.
//	See LICENSE.txt for the full terms of the license.

#include "xpcommands.h"
#define XPLM200 1
#include <XPLMUtilities.h>
#include <XPLMProcessing.h>
#include <assert.h>
#include <string>

using std::string;

struct xlua_cmd {
	xlua_cmd() : m_next(NULL),m_cmd(NULL),m_ours(0),
		m_pre_handler(NULL),m_pre_ref(NULL),
		m_main_handler(NULL),m_main_ref(NULL),
		m_post_handler(NULL),m_post_ref(NULL) { }

	xlua_cmd *			m_next;
	string				m_name;
	XPLMCommandRef		m_cmd;
	int					m_ours;
	xlua_cmd_handler_f	m_pre_handler;
	void *				m_pre_ref;
	xlua_cmd_handler_f	m_main_handler;
	void *				m_main_ref;
	xlua_cmd_handler_f	m_post_handler;
	void *				m_post_ref;
	float				m_down_time;
};

static xlua_cmd *		s_cmds = NULL;

static int xlua_std_pre_handler(XPLMCommandRef c, XPLMCommandPhase phase, void * ref)
{
	xlua_cmd * me = (xlua_cmd *) ref;
	if(phase == xplm_CommandBegin)
		me->m_down_time = XPLMGetElapsedTime();
	if(me->m_pre_handler)
		me->m_pre_handler(me, phase, XPLMGetElapsedTime() - me->m_down_time, me->m_pre_ref);
	return 1;
}

static int xlua_std_main_handler(XPLMCommandRef c, XPLMCommandPhase phase, void * ref)
{
	xlua_cmd * me = (xlua_cmd *) ref;
	if(phase == xplm_CommandBegin)
		me->m_down_time = XPLMGetElapsedTime();
	if(me->m_main_handler)
		me->m_main_handler(me, phase, XPLMGetElapsedTime() - me->m_down_time, me->m_main_ref);
	return 0;
}

static int xlua_std_post_handler(XPLMCommandRef c, XPLMCommandPhase phase, void * ref)
{
	xlua_cmd * me = (xlua_cmd *) ref;
	if(phase == xplm_CommandBegin)
		me->m_down_time = XPLMGetElapsedTime();
	if(me->m_post_handler)
		me->m_post_handler(me, phase, XPLMGetElapsedTime() - me->m_down_time, me->m_post_ref);
	return 1;
}

xlua_cmd * xlua_find_cmd(const char * name)
{
	for(xlua_cmd * i = s_cmds; i; i = i->m_next)
	if(i->m_name == name)
		return i;

	XPLMCommandRef c = XPLMFindCommand(name);
	if(c == NULL) return NULL;

	xlua_cmd * nc = new xlua_cmd;
	nc->m_next = s_cmds;
	s_cmds = nc;
	nc->m_name = name;
	nc->m_cmd = c;
	return nc;
}

xlua_cmd * xlua_create_cmd(const char * name, const char * desc)
{
	for(xlua_cmd * i = s_cmds; i; i = i->m_next)
	if(i->m_name == name)
	{
		printf("ERROR: command already exists: %s\n", name);
		return NULL;
	}

	// Ben says: we used to try to barf on commands taken over from other plugins but
	// we can get spooked by our own shadow - if we had a command last run and the user
	// bound it to a joystick and saved prefs then...it will ALREADY exist!  So don't
	// FTFO here.

//	if(XPLMFindCommand(name) != NULL)
//	{
//		printf("ERROR: command already in use by other plugin or X-Plane: %s\n", name);
//		return NULL;
//	}

	xlua_cmd * nc = new xlua_cmd;
	nc->m_next = s_cmds;
	s_cmds = nc;
	nc->m_name = name;
	nc->m_cmd = XPLMCreateCommand(name,desc);
	nc->m_ours = 1;
	return nc;
}

void xlua_cmd_install_handler(xlua_cmd * cmd, xlua_cmd_handler_f handler, void * ref)
{
	if(cmd->m_main_handler != NULL)
	{
		printf("ERROR: there is already a main handler installed.\n");
		return;
	}
	cmd->m_main_handler = handler;
	cmd->m_main_ref = ref;
	XPLMRegisterCommandHandler(cmd->m_cmd, xlua_std_main_handler, 1, cmd);
}

void xlua_cmd_install_pre_wrapper(xlua_cmd * cmd, xlua_cmd_handler_f handler, void * ref)
{
	if(cmd->m_pre_handler != NULL)
	{
		printf("ERROR: there is already a pre handler installed.\n");
		return;
	}
	cmd->m_pre_handler = handler;
	cmd->m_pre_ref = ref;
	XPLMRegisterCommandHandler(cmd->m_cmd, xlua_std_pre_handler, 1, cmd);
}

void xlua_cmd_install_post_wrapper(xlua_cmd * cmd, xlua_cmd_handler_f handler, void * ref)
{
	if(cmd->m_post_handler != NULL)
	{
		printf("ERROR: there is already a post handler installed.\n");
		return;
	}
	cmd->m_post_handler = handler;
	cmd->m_post_ref = ref;
	XPLMRegisterCommandHandler(cmd->m_cmd, xlua_std_post_handler, 0, cmd);
}

void xlua_cmd_start(xlua_cmd * cmd)
{
	XPLMCommandBegin(cmd->m_cmd);
}
void xlua_cmd_stop(xlua_cmd * cmd)
{
	XPLMCommandEnd(cmd->m_cmd);
}

void xlua_cmd_once(xlua_cmd * cmd)
{
	XPLMCommandOnce(cmd->m_cmd);
}

void xlua_cmd_cleanup()
{
	while(s_cmds)
	{
		xlua_cmd * k = s_cmds;
		if(k->m_pre_handler)
			XPLMUnregisterCommandHandler(k->m_cmd, xlua_std_pre_handler, 1, k);
		if(k->m_main_handler)
			XPLMUnregisterCommandHandler(k->m_cmd, xlua_std_main_handler, 1, k);
		if(k->m_post_handler)
			XPLMUnregisterCommandHandler(k->m_cmd, xlua_std_post_handler, 1, k);
		s_cmds = s_cmds->m_next;
		delete k;
	}
}

<commit_msg>debugging: error on double-register command tells user what command was double-registered.<commit_after>//
//  xpcommands.cpp
//  xlua
//
//  Created by Benjamin Supnik on 4/12/16.
//
//	Copyright 2016, Laminar Research
//	This source code is licensed under the MIT open source license.
//	See LICENSE.txt for the full terms of the license.

#include "xpcommands.h"
#define XPLM200 1
#include <XPLMUtilities.h>
#include <XPLMProcessing.h>
#include <assert.h>
#include <string>

using std::string;

struct xlua_cmd {
	xlua_cmd() : m_next(NULL),m_cmd(NULL),m_ours(0),
		m_pre_handler(NULL),m_pre_ref(NULL),
		m_main_handler(NULL),m_main_ref(NULL),
		m_post_handler(NULL),m_post_ref(NULL) { }

	xlua_cmd *			m_next;
	string				m_name;
	XPLMCommandRef		m_cmd;
	int					m_ours;
	xlua_cmd_handler_f	m_pre_handler;
	void *				m_pre_ref;
	xlua_cmd_handler_f	m_main_handler;
	void *				m_main_ref;
	xlua_cmd_handler_f	m_post_handler;
	void *				m_post_ref;
	float				m_down_time;
};

static xlua_cmd *		s_cmds = NULL;

static int xlua_std_pre_handler(XPLMCommandRef c, XPLMCommandPhase phase, void * ref)
{
	xlua_cmd * me = (xlua_cmd *) ref;
	if(phase == xplm_CommandBegin)
		me->m_down_time = XPLMGetElapsedTime();
	if(me->m_pre_handler)
		me->m_pre_handler(me, phase, XPLMGetElapsedTime() - me->m_down_time, me->m_pre_ref);
	return 1;
}

static int xlua_std_main_handler(XPLMCommandRef c, XPLMCommandPhase phase, void * ref)
{
	xlua_cmd * me = (xlua_cmd *) ref;
	if(phase == xplm_CommandBegin)
		me->m_down_time = XPLMGetElapsedTime();
	if(me->m_main_handler)
		me->m_main_handler(me, phase, XPLMGetElapsedTime() - me->m_down_time, me->m_main_ref);
	return 0;
}

static int xlua_std_post_handler(XPLMCommandRef c, XPLMCommandPhase phase, void * ref)
{
	xlua_cmd * me = (xlua_cmd *) ref;
	if(phase == xplm_CommandBegin)
		me->m_down_time = XPLMGetElapsedTime();
	if(me->m_post_handler)
		me->m_post_handler(me, phase, XPLMGetElapsedTime() - me->m_down_time, me->m_post_ref);
	return 1;
}

xlua_cmd * xlua_find_cmd(const char * name)
{
	for(xlua_cmd * i = s_cmds; i; i = i->m_next)
	if(i->m_name == name)
		return i;

	XPLMCommandRef c = XPLMFindCommand(name);
	if(c == NULL) return NULL;

	xlua_cmd * nc = new xlua_cmd;
	nc->m_next = s_cmds;
	s_cmds = nc;
	nc->m_name = name;
	nc->m_cmd = c;
	return nc;
}

xlua_cmd * xlua_create_cmd(const char * name, const char * desc)
{
	for(xlua_cmd * i = s_cmds; i; i = i->m_next)
	if(i->m_name == name)
	{
		printf("ERROR: command already exists: %s\n", name);
		return NULL;
	}

	// Ben says: we used to try to barf on commands taken over from other plugins but
	// we can get spooked by our own shadow - if we had a command last run and the user
	// bound it to a joystick and saved prefs then...it will ALREADY exist!  So don't
	// FTFO here.

//	if(XPLMFindCommand(name) != NULL)
//	{
//		printf("ERROR: command already in use by other plugin or X-Plane: %s\n", name);
//		return NULL;
//	}

	xlua_cmd * nc = new xlua_cmd;
	nc->m_next = s_cmds;
	s_cmds = nc;
	nc->m_name = name;
	nc->m_cmd = XPLMCreateCommand(name,desc);
	nc->m_ours = 1;
	return nc;
}

void xlua_cmd_install_handler(xlua_cmd * cmd, xlua_cmd_handler_f handler, void * ref)
{
	if(cmd->m_main_handler != NULL)
	{
		printf("ERROR: there is already a main handler installed: %s.\n", cmd->m_name.c_str());
		return;
	}
	cmd->m_main_handler = handler;
	cmd->m_main_ref = ref;
	XPLMRegisterCommandHandler(cmd->m_cmd, xlua_std_main_handler, 1, cmd);
}

void xlua_cmd_install_pre_wrapper(xlua_cmd * cmd, xlua_cmd_handler_f handler, void * ref)
{
	if(cmd->m_pre_handler != NULL)
	{
		printf("ERROR: there is already a pre handler installed: %s.\n", cmd->m_name.c_str());
		return;
	}
	cmd->m_pre_handler = handler;
	cmd->m_pre_ref = ref;
	XPLMRegisterCommandHandler(cmd->m_cmd, xlua_std_pre_handler, 1, cmd);
}

void xlua_cmd_install_post_wrapper(xlua_cmd * cmd, xlua_cmd_handler_f handler, void * ref)
{
	if(cmd->m_post_handler != NULL)
	{
		printf("ERROR: there is already a post handler installed: %s.\n", cmd->m_name.c_str());
		return;
	}
	cmd->m_post_handler = handler;
	cmd->m_post_ref = ref;
	XPLMRegisterCommandHandler(cmd->m_cmd, xlua_std_post_handler, 0, cmd);
}

void xlua_cmd_start(xlua_cmd * cmd)
{
	XPLMCommandBegin(cmd->m_cmd);
}
void xlua_cmd_stop(xlua_cmd * cmd)
{
	XPLMCommandEnd(cmd->m_cmd);
}

void xlua_cmd_once(xlua_cmd * cmd)
{
	XPLMCommandOnce(cmd->m_cmd);
}

void xlua_cmd_cleanup()
{
	while(s_cmds)
	{
		xlua_cmd * k = s_cmds;
		if(k->m_pre_handler)
			XPLMUnregisterCommandHandler(k->m_cmd, xlua_std_pre_handler, 1, k);
		if(k->m_main_handler)
			XPLMUnregisterCommandHandler(k->m_cmd, xlua_std_main_handler, 1, k);
		if(k->m_post_handler)
			XPLMUnregisterCommandHandler(k->m_cmd, xlua_std_post_handler, 1, k);
		s_cmds = s_cmds->m_next;
		delete k;
	}
}

<|endoftext|>


<commit_before>#include <Python.h>
#include <vector>
#include <iostream>
#include <cmath>

#define file_num 2
#define threshhold 0.6
#define allowable_difference 100
using namespace std;
struct peak{
   char* chr;
   int chr_start;
   int chr_end;
   float score;
   float signal;
   float q_value;
   float error_rate;
};

static PyObject *
ens_main(PyObject *self, PyObject *args){

   PyObject *peaks_data = (PyObject*)PyList_New(0);
   PyObject *error_data = (PyObject*)PyList_New(0);

   PyObject *peak_containor[2];
   PyObject *dict_containor = (PyObject*)PyDict_New();

   double error_containor[file_num];
   std::vector<peak> peak_vec[file_num];
   peak* peak_element;

   char* chr;
   char* chr_start;
   char* chr_end;
   char* signal;
   char* q_value;
   char* score;
   char* error_rate;

   //////// Python Object to C++ Local variable /////////
   if(!PyArg_ParseTuple(args, "O!O!",&PyList_Type,&peaks_data, &PyList_Type, &error_data))
      return NULL;
   for ( int i = 0; i < file_num; i++){
      peak_containor[i] = (PyObject*)PyList_New(0);
      peak_containor[i] = PyList_GetItem(peaks_data,i);
      error_containor[i] = PyFloat_AsDouble(PyList_GetItem(error_data,i));
   }
   for ( int i = 0; i < file_num; i++){

      for ( int j = 0 ; j < PyList_Size(peak_containor[i]) ; j++){
         dict_containor = PyList_GetItem(peak_containor[i], j);
         PyArg_Parse(PyDict_GetItemString(dict_containor,"region_s"), "s", &chr_start);
         PyArg_Parse(PyDict_GetItemString(dict_containor,"region_e"), "s", &chr_end);
         PyArg_Parse(PyDict_GetItemString(dict_containor,"chr"), "s", &chr);
         PyArg_Parse(PyDict_GetItemString(dict_containor,"score"), "s", &score);
         PyArg_Parse(PyDict_GetItemString(dict_containor,"signalValue"), "s", &signal);
         PyArg_Parse(PyDict_GetItemString(dict_containor,"qValue"),"s",&q_value);

         peak_element = new peak;
         peak_element->chr = chr;
         peak_element->chr_start = atoi(chr_start);
         peak_element->chr_end = atoi(chr_end);
         peak_element->score = atof(score);
         peak_element->signal = atof(signal);
         peak_element->q_value = atof(q_value);
         peak_element->error_rate = error_containor[i];

         peak_vec[i].push_back(*peak_element);
        // printf("now parse %d`s of peak , signal = %f\n", peak_vec[i].size(), peak_element->signal);
      }
   }

   cout <<"==============================================="<<endl;
   vector<peak>::iterator it[file_num];

   for(int i=0; i <file_num; i++)
      it[i] = peak_vec[i].begin();

   double smallest_value, pct;
   int cnt=0;

   cout <<it[0]->chr<< " " <<it[1]->chr<<endl;
   smallest_value = it[0]->chr_start;
   while(it[0]->chr[3] == it[1]->chr[3]){
      for(int i=0; i <file_num; i++){
         if(abs(smallest_value - it[i]->chr_start) <allowable_difference){
            cnt++;
         }
      }

      pct = cnt / file_num;

      if(pct > threshhold){
         cout <<"=========="<<file_num << " of " <<cnt<<" files are match"<<"=========="<<endl;
         cout << it[0]->chr_start<<endl;
         cout << it[1]->chr_start<<endl;
         cout <<"===================="<<endl;
      }
      cnt = 0;
      for(int i=0; i <file_num; i++){
         if(abs(smallest_value - it[i]->chr_start) <allowable_difference){
            it[i]++;
         }
      }
      smallest_value = it[0]->chr_start < it[1]->chr_start? it[0]->chr_start : it[1]->chr_start;
   }
   //////// C++ value to Python Object /////////////////
   return Py_BuildValue("i",1);
}

static PyMethodDef ensembleMethods[] = {
   {"ensembler", ens_main, METH_VARARGS, "main flow of ensembler."},
   {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
initensemble(void){
   (void) Py_InitModule("ensemble",ensembleMethods);
}

int main(int argc, char *argv[]){
   Py_SetProgramName(argv[0]);
   Py_Initialize();
   initensemble();
   return 0;
}
<commit_msg>All chromosome<commit_after>#include <Python.h>
#include <vector>
#include <iostream>
#include <cmath>

#define file_num 2
#define threshhold 0.6
#define allowable_difference 100
using namespace std;
struct peak{
   char* chr;
   int chr_start;
   int chr_end;
   float score;
   float signal;
   float q_value;
   float error_rate;
};

static PyObject *
ens_main(PyObject *self, PyObject *args){

   PyObject *peaks_data = (PyObject*)PyList_New(0);
   PyObject *error_data = (PyObject*)PyList_New(0);

   PyObject *peak_containor[2];
   PyObject *dict_containor = (PyObject*)PyDict_New();

   double error_containor[file_num];
   std::vector<peak> peak_vec[file_num];
   peak* peak_element;

   char* chr;
   char* chr_start;
   char* chr_end;
   char* signal;
   char* q_value;
   char* score;
   char* error_rate;

   //////// Python Object to C++ Local variable /////////
   if(!PyArg_ParseTuple(args, "O!O!",&PyList_Type,&peaks_data, &PyList_Type, &error_data))
      return NULL;
   for ( int i = 0; i < file_num; i++){
      peak_containor[i] = (PyObject*)PyList_New(0);
      peak_containor[i] = PyList_GetItem(peaks_data,i);
      error_containor[i] = PyFloat_AsDouble(PyList_GetItem(error_data,i));
   }
   for ( int i = 0; i < file_num; i++){

      for ( int j = 0 ; j < PyList_Size(peak_containor[i]) ; j++){
         dict_containor = PyList_GetItem(peak_containor[i], j);
         PyArg_Parse(PyDict_GetItemString(dict_containor,"region_s"), "s", &chr_start);
         PyArg_Parse(PyDict_GetItemString(dict_containor,"region_e"), "s", &chr_end);
         PyArg_Parse(PyDict_GetItemString(dict_containor,"chr"), "s", &chr);
         PyArg_Parse(PyDict_GetItemString(dict_containor,"score"), "s", &score);
         PyArg_Parse(PyDict_GetItemString(dict_containor,"signalValue"), "s", &signal);
         PyArg_Parse(PyDict_GetItemString(dict_containor,"qValue"),"s",&q_value);

         peak_element = new peak;
         peak_element->chr = chr;
         peak_element->chr_start = atoi(chr_start);
         peak_element->chr_end = atoi(chr_end);
         peak_element->score = atof(score);
         peak_element->signal = atof(signal);
         peak_element->q_value = atof(q_value);
         peak_element->error_rate = error_containor[i];

         peak_vec[i].push_back(*peak_element);
        // printf("now parse %d`s of peak , signal = %f\n", peak_vec[i].size(), peak_element->signal);
      }
   }

   cout <<"==============================================="<<endl;
   vector<peak>::iterator it[file_num];

   for(int i=0; i <file_num; i++)
      it[i] = peak_vec[i].begin();

   double smallest_value, pct;
   int cnt=0;
   int chr_check = 0;
   char current_chr = it[0]->chr[3];

   cout <<it[0]->chr<< " " <<it[1]->chr<<endl;
   smallest_value = it[0]->chr_start;
   while(1){
      for(int i=0; i <file_num; i++){
         if(abs(smallest_value - it[i]->chr_start) <allowable_difference){
            cnt++;
         }
      }

      pct = cnt / file_num;

      if(pct > threshhold){
         cout <<"=========="<<file_num << " of " <<cnt<<" files are match"<<"=========="<<endl;
cout<< it[0]->chr <<endl;
         cout << it[0]->chr_start<<endl;
         cout << it[1]->chr_start<<endl;
         cout <<"===================="<<endl;

      }
      cnt = 0;
      for(int i=0; i <file_num; i++){
         if(abs(smallest_value - it[i]->chr_start) <allowable_difference && current_chr == it[i]->chr[3] ){
            it[i]++;
            if(it[i]==peak_vec[i].end()){
               it[i]--;
               it[i]->chr[3] = 'D';
            }
         }
      }
      chr_check=0;
      for(int i=0; i <file_num; i++){
         if(it[i]!= peak_vec[i].end() && current_chr == it[i]->chr[3])
            chr_check++;
      }
      if(double(chr_check) / double(file_num) < threshhold){
cout <<" -----------------=======================================";
         for(int i=0; i< file_num; i++){
            if(it[i]->chr[3]=='D')
                 return Py_BuildValue("i",1);
            while(it[i]->chr[3] == current_chr){
               it[i]++;
            }
         }
         current_chr = it[0]->chr[3];
      }
      smallest_value = it[0]->chr_start < it[1]->chr_start? it[0]->chr_start : it[1]->chr_start;

   }
   //////// C++ value to Python Object /////////////////
   return Py_BuildValue("i",1);
}

static PyMethodDef ensembleMethods[] = {
   {"ensembler", ens_main, METH_VARARGS, "main flow of ensembler."},
   {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
initensemble(void){
   (void) Py_InitModule("ensemble",ensembleMethods);
}

int main(int argc, char *argv[]){
   Py_SetProgramName(argv[0]);
   Py_Initialize();
   initensemble();
   return 0;
}
<|endoftext|>