コード例 #1
0
ファイル: Exec_CrdAction.cpp プロジェクト: drroe/cpptraj
// Exec_CrdAction::ProcessArgs()
Exec::RetType Exec_CrdAction::ProcessArgs(CpptrajState& State, ArgList& argIn) {
  std::string setname = argIn.GetStringNext();
  if (setname.empty()) {
    mprinterr("Error: %s: Specify COORDS dataset name.\n", argIn.Command());
    return CpptrajState::ERR;
  }
  DataSet_Coords* CRD = (DataSet_Coords*)State.DSL().FindCoordsSet( setname );
  if (CRD == 0) {
    mprinterr("Error: %s: No COORDS set with name %s found.\n", argIn.Command(), setname.c_str());
    return CpptrajState::ERR;
  }
  mprintf("\tUsing set '%s'\n", CRD->legend());
  // Start, stop, offset
  TrajFrameCounter frameCount;
  ArgList crdarg( argIn.GetStringKey("crdframes"), "," );
  if (frameCount.CheckFrameArgs( CRD->Size(), crdarg )) return CpptrajState::ERR;
  frameCount.PrintInfoLine(CRD->legend());
  ArgList actionargs = argIn.RemainingArgs();
  actionargs.MarkArg(0);
  Cmd const& cmd = Command::SearchTokenType( DispatchObject::ACTION, actionargs.Command() );
  if ( cmd.Empty() ) return CpptrajState::ERR;
  Action* act = (Action*)cmd.Alloc();
  if (act == 0) return CpptrajState::ERR;
  CpptrajState::RetType err = DoCrdAction(State, actionargs, CRD, act, frameCount);
  delete act;
  return err;
}
コード例 #2
0
// Exec_PermuteDihedrals::Execute()
Exec::RetType Exec_PermuteDihedrals::Execute(CpptrajState& State, ArgList& argIn) {
  debug_ = State.Debug();
  mode_ = INTERVAL;
  // Get Keywords - first determine mode
  if (argIn.hasKey("random"))
    mode_ = RANDOM;
  else if (argIn.hasKey("interval"))
    mode_ = INTERVAL;
  // Get input COORDS set
  std::string setname = argIn.GetStringKey("crdset");
  if (setname.empty()) {
    mprinterr("Error: Specify COORDS dataset name with 'crdset'.\n");
    return CpptrajState::ERR;
  }
  DataSet_Coords* CRD = (DataSet_Coords*)State.DSL().FindCoordsSet( setname );
  if (CRD == 0) {
    mprinterr("Error: Could not find COORDS set '%s'\n", setname.c_str());
    return CpptrajState::ERR;
  }
  mprintf("    PERMUTEDIHEDRALS: Using COORDS '%s'\n", CRD->legend());

  // Get residue range
  Range resRange;
  resRange.SetRange(argIn.GetStringKey("resrange"));
  if (!resRange.Empty())
    resRange.ShiftBy(-1); // User res args start from 1
  mprintf("\tPermutating dihedrals in");
  if (resRange.Empty())
    mprintf(" all solute residues.\n");
  else
    mprintf(" residue range [%s]\n", resRange.RangeArg());

  // Determine which angles to search for
  DihedralSearch dihSearch;
  dihSearch.SearchForArgs(argIn);
  // If nothing is enabled, enable all 
  dihSearch.SearchForAll();
  mprintf("\tSearching for types:");
  dihSearch.PrintTypes();
  mprintf("\n");

  // Setup output trajectory
  outframe_ = 0; 
  std::string outfilename = argIn.GetStringKey("outtraj");
  if (!outfilename.empty()) {
    mprintf("\tCoordinates output to '%s'\n", outfilename.c_str());
    Topology* outtop = State.DSL().GetTopology( argIn );
    if (outtop == 0) {
      mprinterr("Error: No topology for output traj.\n");
      return CpptrajState::ERR;
    }
    // Setup output trajectory FIXME: Correct frames for # of rotations
    if (outtraj_.PrepareTrajWrite(outfilename, argIn, CRD->TopPtr(), CRD->CoordsInfo(),
                                  CRD->Size(), TrajectoryFile::UNKNOWN_TRAJ))
      return CpptrajState::ERR;
  }

  // Setup output coords
  outfilename = argIn.GetStringKey("crdout");
  if (!outfilename.empty()) {
    mprintf("\tCoordinates saved to set '%s'\n", outfilename.c_str());
    crdout_ = (DataSet_Coords_CRD*)State.DSL().AddSet(DataSet::COORDS, outfilename);
    if (crdout_ == 0) return CpptrajState::ERR;
    crdout_->CoordsSetup( CRD->Top(), CRD->CoordsInfo() );
  }

  // Get specific mode options.
  double interval_in_deg = 60.0;
  if ( mode_ == INTERVAL ) {
    interval_in_deg = argIn.getNextDouble(60.0);
    mprintf("\tDihedrals will be rotated at intervals of %.2f degrees.\n", interval_in_deg);
  } else if (mode_ == RANDOM) {
    check_for_clashes_ = argIn.hasKey("check");
    checkAllResidues_ = argIn.hasKey("checkallresidues");
    cutoff_ = argIn.getKeyDouble("cutoff",0.8);
    rescutoff_ = argIn.getKeyDouble("rescutoff",10.0);
    backtrack_ = argIn.getKeyInt("backtrack",4);
    increment_ = argIn.getKeyInt("increment",1);
    max_factor_ = argIn.getKeyInt("maxfactor",2);
    int iseed = argIn.getKeyInt("rseed",-1);
    // Output file for # of problems
    DataFile* problemFile = State.DFL().AddDataFile(argIn.GetStringKey("out"), argIn);
    // Dataset to store number of problems
    number_of_problems_ = State.DSL().AddSet(DataSet::INTEGER, argIn.GetStringNext(),"Nprob");
    if (number_of_problems_==0) return CpptrajState::ERR;
   // Add dataset to data file list
    if (problemFile != 0) problemFile->AddDataSet(number_of_problems_);
    // Check validity of args
    if (cutoff_ < Constants::SMALL) {
      mprinterr("Error: cutoff too small.\n");
      return CpptrajState::ERR;
    }
    if (rescutoff_ < Constants::SMALL) {
      mprinterr("Error: rescutoff too small.\n");
      return CpptrajState::ERR;
    }
    if (backtrack_ < 0) {
      mprinterr("Error: backtrack value must be >= 0\n");
      return CpptrajState::ERR;
    }
    if ( increment_<1 || (360 % increment_)!=0 ) {
      mprinterr("Error: increment must be a factor of 360.\n");
      return CpptrajState::ERR;
    }
    // Calculate max increment
    max_increment_ = 360 / increment_;
    // Seed random number gen
    RN_.rn_set( iseed );
    // Print info
    mprintf("\tDihedrals will be rotated to random values.\n");
    if (iseed==-1)
      mprintf("\tRandom number generator will be seeded using time.\n");
    else
      mprintf("\tRandom number generator will be seeded using %i\n",iseed);
    if (check_for_clashes_) {
      mprintf("\tWill attempt to recover from bad steric clashes.\n");
      if (checkAllResidues_)
        mprintf("\tAll residues will be checked.\n");
      else
        mprintf("\tResidues up to the currenly rotating dihedral will be checked.\n");
      mprintf("\tAtom cutoff %.2f, residue cutoff %.2f, backtrack = %i\n",
              cutoff_, rescutoff_, backtrack_);
      mprintf("\tWhen clashes occur dihedral will be incremented by %i\n",increment_);
      mprintf("\tMax # attempted rotations = %i times number dihedrals.\n",
              max_factor_);
    }
    // Square cutoffs to compare to dist^2 instead of dist
    cutoff_ *= cutoff_;
    rescutoff_ *= rescutoff_;
    // Increment backtrack by 1 since we need to skip over current res
    ++backtrack_;
    // Initialize CheckStructure
    if (checkStructure_.SetOptions( false, false, false, State.Debug(), "*", "", 0.8, 1.15, 4.0 )) {
      mprinterr("Error: Could not set up structure check.\n");
      return CpptrajState::ERR;
    }
    // Set up CheckStructure for this parm (false = nobondcheck)
    if (checkStructure_.Setup(CRD->Top(), CRD->CoordsInfo().TrajBox()))
      return CpptrajState::ERR;
  }

  // Determine from selected mask atoms which dihedrals will be rotated.
  PermuteDihedralsType dst;
  // If range is empty (i.e. no resrange arg given) look through all 
  // solute residues.
  Range actualRange;
  if (resRange.Empty())
    actualRange = CRD->Top().SoluteResidues();
  else 
    actualRange = resRange;
  // Search for dihedrals
  if (dihSearch.FindDihedrals(CRD->Top(), actualRange))
    return CpptrajState::ERR;
  // For each found dihedral, set up mask of atoms that will move upon 
  // rotation. Also set up mask of atoms in this residue that will not
  // move, including atom2.
  if (debug_>0)
    mprintf("DEBUG: Dihedrals:\n");
  for (DihedralSearch::mask_it dih = dihSearch.begin();
                               dih != dihSearch.end(); ++dih)
  {
    dst.checkAtoms.clear();
    // Set mask of atoms that will move during dihedral rotation.
    dst.Rmask = DihedralSearch::MovingAtoms(CRD->Top(), dih->A1(), dih->A2());
    // If randomly rotating angles, check for atoms that are in the same
    // residue as A1 but will not move. They need to be checked for clashes
    // since further rotations will not help them.
    if (mode_ == RANDOM && check_for_clashes_) {
      CharMask cMask( dst.Rmask.ConvertToCharMask(), dst.Rmask.Nselected() );
      int a1res = CRD->Top()[dih->A1()].ResNum();
      for (int maskatom = CRD->Top().Res(a1res).FirstAtom();
               maskatom < CRD->Top().Res(a1res).LastAtom(); ++maskatom)
        if (!cMask.AtomInCharMask(maskatom))
          dst.checkAtoms.push_back( maskatom );
      dst.checkAtoms.push_back(dih->A1()); // TODO: Does this need to be added first?
      // Since only the second atom and atoms it is bonded to move during 
      // rotation, base the check on the residue of the second atom.
      dst.resnum = a1res;
    }
    dst.atom0 = dih->A0(); // FIXME: This duplicates info
    dst.atom1 = dih->A1();
    dst.atom2 = dih->A2();
    dst.atom3 = dih->A3();
    BB_dihedrals_.push_back(dst);
    // DEBUG: List dihedral info.
    if (debug_ > 0) {
      mprintf("\t%s-%s-%s-%s\n", 
              CRD->Top().TruncResAtomName(dih->A0()).c_str(),
              CRD->Top().TruncResAtomName(dih->A1()).c_str(),
              CRD->Top().TruncResAtomName(dih->A2()).c_str(),
              CRD->Top().TruncResAtomName(dih->A3()).c_str() );
      if (debug_ > 1 && mode_ == RANDOM && check_for_clashes_) {
        mprintf("\t\tCheckAtoms=");
        for (std::vector<int>::const_iterator ca = dst.checkAtoms.begin();
                                              ca != dst.checkAtoms.end(); ++ca)
          mprintf(" %i", *ca + 1);
        mprintf("\n");
      }
      if (debug_ > 2) {
        mprintf("\t\t");
        dst.Rmask.PrintMaskAtoms("Rmask:");
      }
    }
  }

  // Set up simple structure check. First step is coarse; check distances 
  // between a certain atom in each residue (first, COM, CA, some other atom?)
  // to see if residues are in each others neighborhood. Second step is to 
  // check the atoms in each close residue.
  if (check_for_clashes_) {
    ResidueCheckType rct;
    int res = 0;
    for (Topology::res_iterator residue = CRD->Top().ResStart();
                                residue != CRD->Top().ResEnd(); ++residue)
    {
      rct.resnum = res++;
      rct.start = residue->FirstAtom();
      rct.stop = residue->LastAtom();
      rct.checkatom = rct.start;
      ResCheck_.push_back(rct);
    }
  }

  // Perform dihedral permute
  Frame currentFrame = CRD->AllocateFrame();
  for (unsigned int set = 0; set != CRD->Size(); set++)
  {
    CRD->GetFrame(set, currentFrame);
    int n_problems = 0;
    switch (mode_) {
      case RANDOM:
        RandomizeAngles(currentFrame, CRD->Top());
        // Check the resulting structure
        n_problems = checkStructure_.CheckOverlaps( currentFrame );
        //mprintf("%i\tResulting structure has %i problems.\n",frameNum,n_problems);
        number_of_problems_->Add(set, &n_problems);
        if (outtraj_.IsInitialized()) outtraj_.WriteSingle(outframe_++, currentFrame);
        if (crdout_ != 0) crdout_->AddFrame( currentFrame );
        break;
      case INTERVAL: IntervalAngles(currentFrame, CRD->Top(), interval_in_deg); break;
    }
  }
  if (outtraj_.IsInitialized()) outtraj_.EndTraj();
  return CpptrajState::OK;
}
コード例 #3
0
ファイル: Exec_CrdAction.cpp プロジェクト: drroe/cpptraj
Exec::RetType Exec_CrdAction::DoCrdAction(CpptrajState& State, ArgList& actionargs,
                                          DataSet_Coords* CRD, Action* act,
                                          TrajFrameCounter const& frameCount) const
{
  Timer total_time;
  total_time.Start();
# ifdef MPI
  ActionInit state(State.DSL(), State.DFL(), trajComm_);
# else
  ActionInit state(State.DSL(), State.DFL());
# endif
  if ( act->Init( actionargs, state, State.Debug() ) != Action::OK )
    return CpptrajState::ERR;
  actionargs.CheckForMoreArgs();
  // Set up frame and parm for COORDS.
  ActionSetup originalSetup( CRD->TopPtr(), CRD->CoordsInfo(), CRD->Size() );
  Frame originalFrame = CRD->AllocateFrame();
  // Set up for this topology 
  Action::RetType setup_ret = act->Setup( originalSetup );
  if ( setup_ret == Action::ERR || setup_ret == Action::SKIP )
    return CpptrajState::ERR;
  // If the topology was modified, we will need a new COORDS set.
  DataSet_Coords* crdOut = 0;
  if ( setup_ret == Action::MODIFY_TOPOLOGY ) {
    // This will not work for a TRJ set.
    switch ( CRD->Type() ) {
      case DataSet::TRAJ      : mprinterr("Error: Cannot modify TRAJ data sets.\n"); break;
      case DataSet::COORDS    : crdOut = (DataSet_Coords*)new DataSet_Coords_CRD(); break;
      case DataSet::REF_FRAME : crdOut = (DataSet_Coords*)new DataSet_Coords_REF(); break;
      default: crdOut = 0; // SANITY
    }
    if (crdOut == 0) return CpptrajState::ERR;
    mprintf("Info: crdaction: COORDS set '%s' will be modified by action '%s'\n",
            CRD->legend(), actionargs.Command());
    if (frameCount.TotalReadFrames() != (int)CRD->Size())
      mprintf("Info: crdaction: Previous size= %zu, new size is %i\n",
              CRD->Size(), frameCount.TotalReadFrames());
    // Set up set, copy original metadata
    crdOut->SetMeta( CRD->Meta() );
    if (crdOut->CoordsSetup( originalSetup.Top(), originalSetup.CoordInfo() ))
      return CpptrajState::ERR;
    DataSet::SizeArray mfArray(1, frameCount.TotalReadFrames());
    if (crdOut->Allocate( mfArray )) return CpptrajState::ERR;
  }
    
  // Loop over all frames in COORDS.
  ProgressBar* progress = 0;
  if (State.ShowProgress())
    progress = new ProgressBar( frameCount.TotalReadFrames() );
  int set = 0;
  for (int frame = frameCount.Start(); frame < frameCount.Stop();
           frame += frameCount.Offset(), ++set)
  {
    // Since Frame can be modified by actions, save original and use currentFrame
    ActionFrame frm( &originalFrame, set );
    if (progress != 0) progress->Update( set );
    CRD->GetFrame( frame, originalFrame );
    Action::RetType ret = act->DoAction( set, frm );
    if (ret == Action::ERR) {
      mprinterr("Error: crdaction: Frame %i, set %i\n", frame + 1, set + 1);
      break;
    }
    // Check if frame was modified. If so, update COORDS.
    if ( ret == Action::MODIFY_COORDS ) {
      if (crdOut != 0)
        crdOut->AddFrame( frm.Frm() );
      else
        CRD->SetCRD( frame, frm.Frm() );
    }
  } 
  if (progress != 0) delete progress;
# ifdef MPI
  act->SyncAction();
# endif
  // If topology was modified, replace old set with new.
  if ( setup_ret == Action::MODIFY_TOPOLOGY ) {
    mprintf("Info: crdaction: Topology for '%s' was modified by action '%s'\n",
            CRD->legend(), actionargs.Command());
    State.DSL().RemoveSet( CRD );
    State.DSL().AddSet( crdOut );
  } 
  act->Print();
  State.MasterDataFileWrite();
  total_time.Stop();
  mprintf("TIME: Total action execution time: %.4f seconds.\n", total_time.Total());
  return CpptrajState::OK;
}
コード例 #4
0
// Exec_RotateDihedral::Execute()
Exec::RetType Exec_RotateDihedral::Execute(CpptrajState& State, ArgList& argIn) {
  // Get input COORDS set
  std::string setname = argIn.GetStringKey("crdset");
  if (setname.empty()) {
    mprinterr("Error: Specify COORDS dataset name with 'crdset'.\n");
    return CpptrajState::ERR;
  }
  DataSet_Coords* CRD = (DataSet_Coords*)State.DSL().FindCoordsSet( setname );
  if (CRD == 0) {
    mprinterr("Error: Could not find COORDS set '%s'\n", setname.c_str());
    return CpptrajState::ERR;
  }
  if (CRD->Size() < 1) {
    mprinterr("Error: COORDS set is empty.\n");
    return CpptrajState::ERR;
  }
  int frame = argIn.getKeyInt("frame", 0);
  if (frame < 0 || frame >= (int)CRD->Size()) {
    mprinterr("Error: Specified frame %i is out of range.\n", frame+1);
    return CpptrajState::ERR;
  }
  mprintf("    ROTATEDIHEDRAL: Using COORDS '%s', frame %i\n", CRD->legend(), frame+1);
  // Get target frame
  Frame FRM = CRD->AllocateFrame();
  CRD->GetFrame(frame, FRM);
  // Save as reference
  Frame refFrame = FRM;

  // Create output COORDS set if necessary
  DataSet_Coords* OUT = 0;
  int outframe = 0;
  std::string outname = argIn.GetStringKey("name");
  if (outname.empty()) {
    // This will not work for TRAJ data sets
    if (CRD->Type() == DataSet::TRAJ) {
      mprinterr("Error: Using TRAJ as input set requires use of 'name' keyword for output.\n");
      return CpptrajState::ERR;
    }
    OUT = CRD;
    outframe = frame;
  } else {
    // Create new output set with 1 empty frame.
    OUT = (DataSet_Coords*)State.DSL().AddSet( DataSet::COORDS, outname );
    if (OUT == 0) return CpptrajState::ERR;
    OUT->Allocate( DataSet::SizeArray(1, 1) );
    OUT->CoordsSetup( CRD->Top(), CRD->CoordsInfo() );
    OUT->AddFrame( CRD->AllocateFrame() );
    mprintf("\tOutput to set '%s'\n", OUT->legend());
  }

  // Determine whether we are setting or incrementing.
  enum ModeType { SET = 0, INCREMENT };
  ModeType mode = SET;
  if (argIn.Contains("value"))
    mode = SET;
  else if (argIn.Contains("increment"))
    mode = INCREMENT;
  else {
    mprinterr("Error: Specify 'value <value>' or 'increment <increment>'\n");
    return CpptrajState::ERR;
  }
  double value = argIn.getKeyDouble(ModeStr[mode], 0.0);
  switch (mode) {
    case SET: mprintf("\tDihedral will be set to %g degrees.\n", value); break;
    case INCREMENT: mprintf("\tDihedral will be incremented by %g degrees.\n", value); break;
  }
  // Convert to radians
  value *= Constants::DEGRAD;

  // Select dihedral atoms
  int A1, A2, A3, A4;
  if (argIn.Contains("type")) {
    // By type
    ArgList typeArg = argIn.GetStringKey("type");
    if (typeArg.empty()) {
      mprinterr("Error: No dihedral type specified after 'type'\n");
      return CpptrajState::ERR;
    }
    DihedralSearch dihSearch;
    dihSearch.SearchForArgs( typeArg );
    if (dihSearch.NoDihedralTokens()) {
      mprinterr("Error: Specified dihedral type not recognized.\n");
      return CpptrajState::ERR;
    }
    // Get residue
    int res = argIn.getKeyInt("res", -1);
    if (res <= 0) {
      mprinterr("Error: If 'type' specified 'res' must be specified and > 0.\n");
      return CpptrajState::ERR;
    }
    // Search for dihedrals. User residue #s start from 1.
    if (dihSearch.FindDihedrals(CRD->Top(), Range(res-1)))
      return CpptrajState::ERR;
    DihedralSearch::mask_it dih = dihSearch.begin();
    A1 = dih->A0();
    A2 = dih->A1();
    A3 = dih->A2();
    A4 = dih->A3();
  } else {
    // By masks
    AtomMask m1( argIn.GetMaskNext() );
    AtomMask m2( argIn.GetMaskNext() );
    AtomMask m3( argIn.GetMaskNext() );
    AtomMask m4( argIn.GetMaskNext() );
    if (CRD->Top().SetupIntegerMask( m1 )) return CpptrajState::ERR;
    if (CRD->Top().SetupIntegerMask( m2 )) return CpptrajState::ERR;
    if (CRD->Top().SetupIntegerMask( m3 )) return CpptrajState::ERR;
    if (CRD->Top().SetupIntegerMask( m4 )) return CpptrajState::ERR;
    if (m1.Nselected() != 1) return MaskError( m1 );
    if (m2.Nselected() != 1) return MaskError( m2 );
    if (m3.Nselected() != 1) return MaskError( m3 );
    if (m4.Nselected() != 1) return MaskError( m4 );
    A1 = m1[0];
    A2 = m2[0];
    A3 = m3[0];
    A4 = m4[0];
  }
  mprintf("\tRotating dihedral defined by atoms '%s'-'%s'-'%s'-'%s'\n",
          CRD->Top().AtomMaskName(A1).c_str(),
          CRD->Top().AtomMaskName(A2).c_str(),
          CRD->Top().AtomMaskName(A3).c_str(),
          CRD->Top().AtomMaskName(A4).c_str());
  // Set mask of atoms that will move during dihedral rotation
  AtomMask Rmask = DihedralSearch::MovingAtoms(CRD->Top(), A2, A3);
  // Calculate current value of dihedral
  double torsion = Torsion( FRM.XYZ(A1), FRM.XYZ(A2), FRM.XYZ(A3), FRM.XYZ(A4) );
  // Calculate delta needed to get to target value.
  double delta;
  switch (mode) {
    case SET:       delta = value - torsion; break;
    case INCREMENT: delta = value; break;
  }
  mprintf("\tOriginal torsion is %g, rotating by %g degrees.\n",
          torsion*Constants::RADDEG, delta*Constants::RADDEG);
  // Set axis of rotation
  Vec3 axisOfRotation = FRM.SetAxisOfRotation( A2, A3 );
  // Calculate rotation matrix for delta.
  Matrix_3x3 rotationMatrix;
  rotationMatrix.CalcRotationMatrix(axisOfRotation, delta);
  // Rotate around axis
  FRM.Rotate(rotationMatrix, Rmask);
  // RMS-fit the non-moving part of the coords back on original
  AtomMask refMask = Rmask;
  refMask.InvertMask();
  FRM.Align( refFrame, refMask );
  // Update coords
  OUT->SetCRD( outframe, FRM );

  return CpptrajState::OK;
}