コード例 #1
0
ファイル: Action_Pairwise.cpp プロジェクト: rmcgibbo/cpptraj
/** Print atoms for which the cumulative energy satisfies the given
  * cutoffs. Also create MOL2 files containing those atoms.
  */
int Action_Pairwise::PrintCutAtoms(Frame const& frame, int frameNum, EoutType ctype,
                                   Darray const& Earray, double cutIn)
{
  AtomMask CutMask;  // Hold atoms that satisfy the cutoff
  Darray CutCharges; // Hold evdw/eelec corresponding to CutMask atoms.

  if (Eout_ != 0) {
    if (nb_calcType_==COMPARE_REF)
      Eout_->Printf("\tPAIRWISE: Cumulative d%s:", CalcString[ctype]);
    else
      Eout_->Printf("\tPAIRWISE: Cumulative %s:", CalcString[ctype]);
    Eout_->Printf(" %s < %.4f, %s > %.4f\n", CalcString[ctype], -cutIn,
                 CalcString[ctype], cutIn);
  }
  for (AtomMask::const_iterator atom = Mask0_.begin(); atom != Mask0_.end(); ++atom)
  {
    if (fabs(Earray[*atom]) > cutIn)
    {
      if (Eout_ != 0) 
        Eout_->Printf("\t\t%6i@%s: %12.4f\n", *atom+1,
                    (*CurrentParm_)[*atom].c_str(), Earray[*atom]);
      CutMask.AddAtom(*atom);
      CutCharges.push_back(Earray[*atom]);
    }
  }
  // Write mol2 with atoms satisfying cutoff
  if (!mol2Prefix_.empty() && !CutMask.None()) {
    if (WriteCutFrame(frameNum, *CurrentParm_, CutMask, CutCharges, 
                      frame, mol2Prefix_ + CutName[ctype])) 
      return 1;
  }

  return 0;
}
コード例 #2
0
ファイル: Action_Matrix.cpp プロジェクト: SAMAN-64/cpptraj
// Action_Matrix::FillMassArray()
Action_Matrix::Darray Action_Matrix::FillMassArray(Topology const& currentParm, 
                                                   AtomMask const& mask) const
{
  Darray mass;
  mass.reserve( mask.Nselected() );
  for (AtomMask::const_iterator atom = mask.begin(); atom != mask.end(); ++atom) 
    mass.push_back( currentParm[ *atom ].Mass() );
  return mass;
}
コード例 #3
0
ファイル: Analysis_TI.cpp プロジェクト: Amber-MD/cpptraj
// Analysis_TI::Calc_Nskip()
int Analysis_TI::Calc_Nskip() {
  // sum: Hold the results of integration for each curve (skip value)
  Darray sum(nskip_.size(), 0.0);
  // lastSkipPoint: Points after which averages can be recorded
  Iarray lastSkipPoint;
  for (Iarray::const_iterator it = nskip_.begin(); it != nskip_.end(); ++it)
    lastSkipPoint.push_back( *it - 1 );
  // Loop over input data sets. 
  for (unsigned int idx = 0; idx != input_dsets_.size(); idx++) {
    DataSet_1D const& ds = static_cast<DataSet_1D const&>( *(input_dsets_[idx]) );
    if (CheckSet(ds)) return 1; 
    // Determine if skip values are valid for this set.
    Darray Npoints; // Number of points after skipping
    for (Iarray::const_iterator it = nskip_.begin(); it != nskip_.end(); ++it) {
      int np = (int)ds.Size() - *it;
      if (np < 1) {
        mprinterr("Error: Skipped too many points (set '%s' size is %zu)\n",ds.legend(),ds.Size());
        return 1;
      }
      Npoints.push_back((double)np);
    }
    // Calculate averages for each value of skip
    Darray avg(nskip_.size(), 0.0);
    for (int i = 0; i != (int)ds.Size(); i++) {
      for (unsigned int j = 0; j != nskip_.size(); j++)
        if (i > lastSkipPoint[j])
          avg[j] += ds.Dval( i );
    }
    // Store average DV/DL for each value of skip
    for (unsigned int j = 0; j != nskip_.size(); j++) {
      avg[j] /= Npoints[j];
      if (debug_ > 0)
        mprintf("\t%s Skip= %i <DV/DL>= %g\n", ds.legend(), nskip_[j], avg[j]);
      DataSet_Mesh& CR = static_cast<DataSet_Mesh&>( *(curve_[j]) );
      CR.AddXY(xval_[idx], avg[j]);
      if (mode_ == GAUSSIAN_QUAD)
        sum[j] += (wgt_[idx] * avg[j]);
    }
  } // END loop over input data sets
  if (mode_ == TRAPEZOID) Integrate_Trapezoid(sum);
  // Store final TI integration values.
  DataSet_Mesh& DA = static_cast<DataSet_Mesh&>( *dAout_ );
  DA.ModifyDim(Dimension::X).SetLabel("PtsSkipped");
  for (unsigned int j = 0; j != nskip_.size(); j++)
    DA.AddXY(nskip_[j], sum[j]);

  return 0;
}
コード例 #4
0
ファイル: Analysis_TI.cpp プロジェクト: jcr13/cpptraj
Analysis::RetType Analysis_TI::Analyze() {
  Darray sum(nskip_.size(), 0.0);
  DataSet_Mesh& DA = static_cast<DataSet_Mesh&>( *dAout_ );
  Iarray lastSkipPoint; // Points after which averages can be recorded
  for (Iarray::const_iterator it = nskip_.begin(); it != nskip_.end(); ++it)
    lastSkipPoint.push_back( *it - 1 );
  // Run for multiple skip values, helps test convergences.
  for (unsigned int idx = 0; idx != input_dsets_.size(); idx++) {
    DataSet_1D const& ds = static_cast<DataSet_1D const&>( *(input_dsets_[idx]) );
    if (ds.Size() < 1) {
      mprinterr("Error: Set '%s' is empty.\n", ds.legend());
      return Analysis::ERR;
    }
    // Determine if skip values are valid for this set.
    Darray Npoints; // Number of points after skipping
    for (Iarray::const_iterator it = nskip_.begin(); it != nskip_.end(); ++it) {
      int np = (int)ds.Size() - *it;
      if (np < 1) {
        mprinterr("Error: Skipped too many points (set '%s' size is %zu)\n",ds.legend(),ds.Size());
        return Analysis::ERR;
      }
      Npoints.push_back((double)np);
    }
    // Calculate averages for each value of skip
    Darray avg(nskip_.size(), 0.0);
    for (int i = 0; i != (int)ds.Size(); i++) {
      for (unsigned int j = 0; j != nskip_.size(); j++)
        if (i > lastSkipPoint[j])
          avg[j] += ds.Dval( i );
    }
    // Store average DV/DL for each value of skip
    for (unsigned int j = 0; j != nskip_.size(); j++) {
      avg[j] /= Npoints[j];
      //mprintf("\t<DV/DL>=%g\n", avg);
      DataSet_Mesh& CR = static_cast<DataSet_Mesh&>( *(curve_[j]) );
      CR.AddXY(quad_[idx], avg[j]);
      sum[j] += (wgt_[idx] * avg[j]);
    }
  }
  for (unsigned int j = 0; j != nskip_.size(); j++)
    DA.AddXY(nskip_[j], sum[j]);

  return Analysis::OK;
}
コード例 #5
0
ファイル: Analysis_TI.cpp プロジェクト: Amber-MD/cpptraj
// Analysis_TI::Calc_Increment()
int Analysis_TI::Calc_Increment() {
  // Determine max points if not given.
  int maxpts = avg_max_;
  if (maxpts == -1) {
    for (unsigned int idx = 0; idx != input_dsets_.size(); idx++) {
      DataSet_1D const& ds = static_cast<DataSet_1D const&>( *(input_dsets_[idx]) );
      if (maxpts == -1)
        maxpts = (int)ds.Size();
      else if (maxpts != (int)ds.Size()) {
        mprintf("Warning: # points in '%s' (%zu) is different than %i.\n",
                ds.legend(), ds.Size(), maxpts);
        maxpts = std::min( maxpts, (int)ds.Size() );
        mprintf("Warning:   Will only use %i points.\n", maxpts);
      }
    }
  }
  if (maxpts < 1) {
    mprinterr("Error: Max points to use is < 1.\n");
    return 1;
  }
  if (avg_skip_ >= maxpts) {
    mprinterr("Error: 'avgskip' (%i) > max (%i).\n", avg_skip_, maxpts);
    return 1;
  }
  // sum: Hold the results of integration for each curve (increment)
  Darray sum;
  // points: Hold point values at which each avg is being calculated
  Iarray points;
  // Loop over input data sets. 
  for (unsigned int idx = 0; idx != input_dsets_.size(); idx++) {
    DataSet_1D const& ds = static_cast<DataSet_1D const&>( *(input_dsets_[idx]) );
    if (CheckSet(ds)) return 1; 
    // Calculate averages for each increment
    Darray avg;
    Iarray increments;
    int count = 0;
    int endpt = maxpts -1;
    double currentSum = 0.0;
    if (debug_ > 0) mprintf("DEBUG: Lambda %g\n", xval_[idx]);
    for (int pt = avg_skip_; pt != maxpts; pt++)
    {
      currentSum += ds.Dval(pt);
      count++;
      if (count == avg_increment_ || pt == endpt) {
        avg.push_back( currentSum / ((double)(pt - avg_skip_ + 1)) );
        increments.push_back(pt+1);
        if (debug_ > 0)
          mprintf("DEBUG:\t\tAvg from %i to %i: %g\n", avg_skip_+1, pt+1, avg.back());
        count = 0;
      }
    }
    if (sum.empty()) {
      sum.resize(avg.size());
      points = increments;
    } else if (sum.size() != avg.size()) {
      mprinterr("Error: Different # of increments for set '%s'; got %zu, expected %zu.\n",
                ds.legend(), avg.size(), sum.size());
      return 1;
    }
    // Create increment curve data sets
    if (curve_.empty()) {
      MetaData md(dAout_->Meta().Name(), "TIcurve");
      for (unsigned int j = 0; j != avg.size(); j++) {
        md.SetIdx( increments[j] );
        DataSet* ds = masterDSL_->AddSet(DataSet::XYMESH, md);
        if (ds == 0) return Analysis::ERR;
        ds->ModifyDim(Dimension::X).SetLabel("Lambda");
        ds->SetLegend( md.Name() + "_Skip" + integerToString(increments[j]) );
        if (curveout_ != 0) curveout_->AddDataSet( ds );
        curve_.push_back( ds );
      }
    }
    for (unsigned int j = 0; j != avg.size(); j++) {
      DataSet_Mesh& CR = static_cast<DataSet_Mesh&>( *(curve_[j]) );
      CR.AddXY(xval_[idx], avg[j]);
      if (mode_ == GAUSSIAN_QUAD)
        sum[j] += (wgt_[idx] * avg[j]);
    }
  } // END loop over data sets
  if (mode_ == TRAPEZOID) Integrate_Trapezoid(sum);
  // Store final integration values
  DataSet_Mesh& DA = static_cast<DataSet_Mesh&>( *dAout_ );
  DA.ModifyDim(Dimension::X).SetLabel("Point");
  for (unsigned int j = 0; j != points.size(); j++)
    DA.AddXY(points[j], sum[j]);

  return 0;
}
コード例 #6
0
//  Exec_SortEnsembleData::Sort_pH_Data()
int Exec_SortEnsembleData::Sort_pH_Data(DataSetList const& setsToSort, DataSetList& OutputSets,
                                        unsigned int maxFrames)
const
{
  // Cast sets back to DataSet_PHREMD
  typedef std::vector<DataSet_PHREMD*> Parray;
  Parray PHsets;
  for (DataSetList::const_iterator ds = setsToSort.begin(); ds != setsToSort.end(); ++ds)
    PHsets.push_back( (DataSet_PHREMD*)*ds );

  // Gather initial pH data values, ensure no duplicates
  typedef std::vector<double> Darray;
  Darray pHvalues;
# ifdef MPI
  pHvalues.resize( Parallel::Ensemble_Size() );
  Darray phtmp;
  for (Parray::const_iterator ds = PHsets.begin(); ds != PHsets.end(); ++ds)
    phtmp.push_back( (*ds)->Initial_pH() );
  if (comm_.AllGather(&phtmp[0], phtmp.size(), MPI_DOUBLE, &pHvalues[0])) {
    rprinterr("Error: Gathering pH values.\n");
    return 1;
  }
# else
  for (Parray::const_iterator ds = PHsets.begin(); ds != PHsets.end(); ++ds)
    pHvalues.push_back( (*ds)->Initial_pH() );
# endif
  ReplicaInfo::Map<double> pH_map;
  if (pH_map.CreateMap( pHvalues )) {
    rprinterr("Error: Duplicate pH value detected (%.2f) in ensemble.\n", pH_map.Duplicate());
    return 1;
  }
  Darray sortedPH;
  mprintf("\tInitial pH values:");
  for (ReplicaInfo::Map<double>::const_iterator ph = pH_map.begin(); ph != pH_map.end(); ++ph)
  {
    mprintf(" %6.2f", ph->first);
    sortedPH.push_back( ph->first );
  }
  mprintf("\n");

  // Create sets to hold sorted pH values. Create a set for each pH value
  // and each residue. Final output sets will be PH0R0, PH0R1, PH1R0, ...
  // TODO check that residue info all the same
  DataSet_PHREMD::Rarray const& Residues = PHsets[0]->Residues();
  int defaultState = 0;
# ifdef MPI
  if ( PHsets[0]->Type() == DataSet::PH_IMPL)
    defaultState = -1;
# endif
  if (debug_ > 0)
    rprintf("DEBUG: Sorting %u frames for %zu sets, %zu pH values.\n",
            maxFrames, PHsets.size(), sortedPH.size());
  for (unsigned int idx = 0; idx != sortedPH.size(); idx++) {
    OutputSets.SetEnsembleNum( idx );
    for (unsigned int res = 0; res != Residues.size(); ++res) {
      MetaData md(PHsets[0]->Meta().Name(), Residues[res].Name().Truncated(), Residues[res].Num());
      DataSet_pH* out = (DataSet_pH*)OutputSets.AddSet( DataSet::PH, md );
      if (out==0) return 1;
      //out->SetLegend( "pH " + doubleToString( sortedPH[idx] ) );
      out->Set_Solvent_pH( sortedPH[idx] );
      out->SetResidueInfo( Residues[res] );
      out->SetTimeValues(PHsets[0]->Time());
      out->Resize( maxFrames, defaultState );
    }
  }

  // ---------------------------------------------
  if ( PHsets[0]->Type() == DataSet::PH_EXPL) {
    // Loop over unsorted sets
    for (Parray::const_iterator ds = PHsets.begin(); ds != PHsets.end(); ++ds)
    {
      DataSet_PHREMD_Explicit* in = (DataSet_PHREMD_Explicit*)*ds;
      unsigned int phidx = 0;
      for (unsigned int n = 0; n < maxFrames; n++)
      {
        float phval = in->pH_Values()[n];
        int setidx = pH_map.FindIndex( phval ) * Residues.size();
        //rprintf("DEBUG: %6u Set %10s pH= %6.2f going to %2i\n", n+1, in->legend(), phval, idx);
        //mflush();
        for (unsigned int res = 0; res < in->Residues().size(); res++, setidx++, phidx++)
        {
          DataSet_pH* out = (DataSet_pH*)OutputSets[setidx];
          //if (res == 0 && idx == 0) {
          //  rprintf("DEBUG: Frame %3u res %2u State %2i pH %6.2f\n", 
          //          n, res, in->Res(res).State(n), phval);
          //  mflush();
          //}
          out->SetState(n, in->ResStates()[phidx], in->RecordType(n));
        }
      }
    } // END loop over unsorted sets
#   ifdef MPI
    // Now we need to reduce down each set onto the thread where it belongs.
    if (Parallel::World().Size() > 1) {
      for (int idx = 0; idx != (int)OutputSets.size(); idx++) {
        DataSet_pH* out = (DataSet_pH*)OutputSets[idx];
        int ensembleRank = Parallel::MemberEnsCommRank( out->Meta().EnsembleNum() );
        //rprintf("DEBUG: Reduce set %s to rank %i\n", out->legend(), ensembleRank);
        out->Reduce( comm_, ensembleRank );
      }
      // Remove sets that do not belong on this rank
      for (int idx = (int)OutputSets.size() - 1; idx > -1; idx--) {
        DataSet* out = OutputSets[idx];
        int ensembleRank = Parallel::MemberEnsCommRank( out->Meta().EnsembleNum() );
        if (ensembleRank != comm_.Rank()) {
          //rprintf("DEBUG: Remove set %s (%i) from rank %i\n", out->legend(),
          //        idx, comm_.Rank());
          OutputSets.RemoveSet( out );
        }
      }
    }
#   endif
  // ---------------------------------------------
  } else if ( PHsets[0]->Type() == DataSet::PH_IMPL) {
#   ifdef MPI
    typedef std::vector<int> Iarray;
    typedef std::vector<Iarray> Iarray2;
    typedef std::vector<bool> Barray;
    // True if I have this pH value
    Barray isMyPh( sortedPH.size(), false );
    // Which rank in ensemble has which pH
    Iarray pHrank( sortedPH.size(), 0 );
    for (int phidx = 0; phidx != (int)sortedPH.size(); phidx++)
    {
      int ensembleRank = Parallel::MemberEnsCommRank( phidx );
      pHrank[phidx] = ensembleRank;
      isMyPh[phidx] = (ensembleRank == comm_.Rank());
    }
    // DEBUG
    for (unsigned int idx = 0; idx != pHrank.size(); idx++)
      mprintf("\tpH %6.2f on rank %i\n", sortedPH[idx], pHrank[idx]);
    // Hold frame-residue-state for each pH not on this rank.
    Iarray2 FrmResState( sortedPH.size() );
    // Loop over unsorted sets
    for (Parray::const_iterator ds = PHsets.begin(); ds != PHsets.end(); ++ds)
    {
      DataSet_PHREMD_Implicit* in = (DataSet_PHREMD_Implicit*)*ds;
      // Loop over frames
      for (unsigned int n = 0; n < maxFrames; n++)
      {
        DataSet_PHREMD_Implicit::Record const& Rec = in->Records()[n];
        float phval = Rec.pH();
        int phidx = pH_map.FindIndex( phval );
        if (isMyPh[phidx]) {
          // This pH belongs to me. Set value.
          int setidx = phidx * Residues.size();
          if (Rec.RecType() == Cph::FULL_RECORD) {
            // Info for all residues
            for (unsigned int res = 0; res < in->Residues().size(); res++, setidx++)
              ((DataSet_pH*)OutputSets[setidx])->SetState(n, Rec.ResStates()[res], Rec.RecType());
          } else if (Rec.RecType() > -1) {
            // Info for single residue, record type for all residues
            //rprintf("\tSetting my pH %6.2f frame %8i state %2i idx %6i res %6i '%s'\n", sortedPH[phidx], n, Rec.ResStates()[0], setidx, Rec.RecType(), OutputSets[setidx+Rec.RecType()]->legend());
            for (int res = 0; res < (int)in->Residues().size(); res++, setidx++)
              if (res == Rec.RecType())
                ((DataSet_pH*)OutputSets[setidx])->SetState(n, Rec.ResStates()[0], Rec.RecType());
              else
                ((DataSet_pH*)OutputSets[setidx])->SetRecType(n, Rec.RecType());
          }
        } else {
          // This pH belongs to another rank. Save it.
          if (Rec.RecType() > -1) {
            // Info for a single residue present
            FrmResState[phidx].push_back( n );
            FrmResState[phidx].push_back( Rec.RecType() );
            FrmResState[phidx].push_back( Rec.ResStates()[0] );
          } else {
            // Info for all residues present
            FrmResState[phidx].push_back( n );
            FrmResState[phidx].push_back( Rec.RecType() );
            for (unsigned int res = 0; res < in->Residues().size(); res++)
              FrmResState[phidx].push_back( Rec.ResStates()[res] );
          }
        }
      } // END loop over frames
    } // END loop over sets
    // DEBUG
/*
    comm_.Barrier();
    for (int rank = 0; rank < comm_.Size(); rank++)
    {
      if (rank == comm_.Rank())
      {
        for (unsigned int phidx = 0; phidx != sortedPH.size(); phidx++) {
          rprintf("DEBUG: pH %6.2f: %8s %6s %2s\n", sortedPH[phidx], "Frm", "Res", "St");
          Iarray const& FRS = FrmResState[phidx];
          unsigned int idx = 0;
          while (idx < FRS.size()) {
            int rec = FRS[idx+1];
            if (rec > -1) {
              rprintf("                  %8i %6i %2i\n", FRS[idx], rec, FRS[idx+2]);
              idx += 3;
            } else {
              rprintf("                  %8i %6i All Residues\n", FRS[idx], rec);
              idx += (2 + Residues.size());
            }
          }
        }
      }
      comm_.Barrier();
    }
*/
    // Communicate states to other ranks
    typedef std::vector<unsigned int> Uarray;
    Uarray sizeOnRank( comm_.Size() );
    for (unsigned int phidx = 0; phidx != sortedPH.size(); phidx++)
    {
      // Each rank says how many frames of this pH they have collected and
      // send to rank the pH belongs to.
      unsigned int nph = FrmResState[phidx].size();
      comm_.Gather(&nph, 1, MPI_UNSIGNED, &sizeOnRank[0], pHrank[phidx]);
      if (pHrank[phidx] == comm_.Rank())
      {
        // This pH belongs to me. I should have no frames at this pH.
        if (sizeOnRank[comm_.Rank()] > 0) {
          rprinterr("Internal Error: Rank has frames to communicate at its pH\n");
          Parallel::Abort(1);
        }
        unsigned int totalSize = 0;
        for (unsigned int idx = 0; idx != sizeOnRank.size(); idx++) {
          totalSize += sizeOnRank[idx];
          //rprintf("DEBUG: Rank %4u has %8u frames of pH %6.2f\n",
          //        idx, sizeOnRank[idx], sortedPH[phidx]);
        }
        //rprintf("DEBUG: Total incoming size: %u\n", totalSize);
        FrmResState[phidx].resize( totalSize );
        // Receive state info for this pH from other ranks
        int* frsArray = &(FrmResState[phidx][0]);
        for (int rank = 0; rank != comm_.Size(); rank++) {
          if (rank != comm_.Rank()) {
            comm_.Recv(frsArray, sizeOnRank[rank], MPI_INT, rank, 1600+rank);
            frsArray += sizeOnRank[rank];
          }
        }
      } else {
        // This pH belongs to another rank. Send my info there.
        int* frsArray = &(FrmResState[phidx][0]);
        comm_.Send(frsArray, nph, MPI_INT, pHrank[phidx], 1600+comm_.Rank());
      }
      comm_.Barrier();
    }
    // Fill in state info
    std::vector<DataSet*> ToRemove;
    for (unsigned int phidx = 0; phidx != sortedPH.size(); phidx++)
    {
      int setidx = phidx * Residues.size();
      if (pHrank[phidx] == comm_.Rank())
      {
        Iarray const& FRS = FrmResState[phidx];
        // This pH belongs to me. Fill in the information received from
        // other ranks.
        unsigned int idx = 0;
        while (idx < FRS.size()) {
          int rec = FRS[idx+1];
          if (rec > -1) {
            // Info for single residue, record type for all residues
            //rprintf("\tSetting pH %6.2f frame %8i state %2i idx %6i res %6i '%s'\n", sortedPH[phidx], FRS[idx], FRS[idx+2], setidx, rec, OutputSets[setidx+rec]->legend());
            for (int res = 0; res != (int)Residues.size(); res++) {
              DataSet_pH* out = (DataSet_pH*)OutputSets[setidx + res];
              if (rec == res)
                out->SetState( FRS[idx], FRS[idx+2], rec );
              else
                out->SetRecType( FRS[idx], rec );
            }
            idx += 3;
          } else {
            //rprintf("                  %8i %6i All Residues\n", FRS[idx], rec);
            int frm = FRS[idx];
            idx += 2;
            for (unsigned int res = 0; res != Residues.size(); res++, idx++) {
              DataSet_pH* out = (DataSet_pH*)OutputSets[setidx + res];
              out->SetState( frm, FRS[idx], rec );
            }
          }
        }
        // Fill in any remaining data. FIXME safe to assume first frame is set?
        for (unsigned int res = 0; res != Residues.size(); res++) {
          DataSet_pH* out = (DataSet_pH*)OutputSets[setidx + res];
          for (unsigned int n = 1; n < maxFrames; n++)
            if (out->State(n) == -1)
              out->SetState(n, out->State(n-1), out->RecordType(n));
        }
      } else {
        // This pH does not belong to me. Mark associated data sets to be removed.
        for (unsigned int res = 0; res != Residues.size(); res++)
          ToRemove.push_back( OutputSets[setidx + res] );
      }
    }
    // Remove data sets that do not belong to me.
    for (std::vector<DataSet*>::reverse_iterator it = ToRemove.rbegin();
                                                 it != ToRemove.rend(); ++it)
    {
      //rprintf("DEBUG: '%s' does not belong to me.\n", (*it)->legend());
      OutputSets.RemoveSet( *it );
    }
#   else /* if not MPI */
    // Loop over frames
    for (unsigned int n = 0; n < maxFrames; n++)
    {
      // Loop over unsorted sets
      for (Parray::const_iterator ds = PHsets.begin(); ds != PHsets.end(); ++ds)
      {
        DataSet_PHREMD_Implicit* in = (DataSet_PHREMD_Implicit*)*ds;
        DataSet_PHREMD_Implicit::Record const& Rec = in->Records()[n];
        float phval = Rec.pH();
        int setidx = pH_map.FindIndex( phval ) * Residues.size();
        if (Rec.RecType() == Cph::FULL_RECORD) {
          for (unsigned int res = 0; res < in->Residues().size(); res++, setidx++)
          {
            DataSet_pH* out = (DataSet_pH*)OutputSets[setidx];
            //if (res == 0 && idx == 0) {
            //  rprintf("DEBUG: Frame %3u res %2u State %2i pH %6.2f\n", 
            //          n, res, in->Res(res).State(n), phval);
            //  mflush();
            //}
            out->SetState(n, Rec.ResStates()[res], Rec.RecType());
          }
        } else {
          for (int res = 0; res < (int)in->Residues().size(); res++, setidx++)
          {
            DataSet_pH* out = (DataSet_pH*)OutputSets[setidx];
            if (res == Rec.RecType())
              out->SetState(n, Rec.ResStates()[0], Rec.RecType());
            else
              // State for this residue not recorded - use previous state.
              // Should be fine since first state always has all residues.
              out->SetState(n, out->State(n-1), Rec.RecType());
          }
        }
      } // END loop over unsorted sets
    } // END loop over frames
#   endif /* MPI */
  // ---------------------------------------------
  } else {
    return 1; // Sanity check
  }
  return 0;
}
コード例 #7
0
// Analysis_Wavelet::Analyze()
Analysis::RetType Analysis_Wavelet::Analyze() {
    // Step 1 - Create a matrix that is #atoms rows by #frames - 1 cols,
    //          where matrix(frame, atom) is the distance that atom has
    //          travelled from the previous frame.
    // TODO: Implement this in Action_Matrix()?
    mprintf("    WAVELET:\n");
    // First set up atom mask.
    if (coords_->Top().SetupIntegerMask( mask_ )) return Analysis::ERR;
    mask_.MaskInfo();
    int natoms = mask_.Nselected();
    int nframes = (int)coords_->Size();
    if (natoms < 1 || nframes < 2) {
        mprinterr("Error: Not enough frames (%i) or atoms (%i) in '%s'\n",
                  nframes, natoms, coords_->legend());
        return Analysis::ERR;
    }
    Matrix<double> d_matrix;
    mprintf("\t%i frames, %i atoms, distance matrix will require %.2f MB\n",
            (double)d_matrix.sizeInBytes(nframes, natoms) / (1024.0*1024.0));
    d_matrix.resize(nframes, natoms);
    // Get initial frame.
    Frame currentFrame, lastFrame;
    currentFrame.SetupFrameFromMask( mask_, coords_->Top().Atoms() );
    lastFrame = currentFrame;
    coords_->GetFrame( 0, lastFrame, mask_ );
    // Iterate over frames
    for (int frm = 1; frm != nframes; frm++) {
        coords_->GetFrame( frm, currentFrame, mask_ );
        int idx = frm; // Position in distance matrix; start at column 'frame'
        for (int at = 0; at != natoms; at++, idx += nframes)
            // Distance of atom in currentFrame from its position in lastFrame.
            d_matrix[idx] = sqrt(DIST2_NoImage( currentFrame.XYZ(at), lastFrame.XYZ(at) ));
        //lastFrame = currentFrame; // TODO: Re-enable?
    }
# ifdef DEBUG_WAVELET
    // DEBUG: Write matrix to file.
    CpptrajFile dmatrixOut; // DEBUG
    dmatrixOut.OpenWrite("dmatrix.dat");
    Matrix<double>::iterator mval = d_matrix.begin();
    for (int row = 0; row != natoms; row++) {
        for (int col = 0; col != nframes; col++)
            dmatrixOut.Printf("%g ", *(mval++));
        dmatrixOut.Printf("\n");
    }
    dmatrixOut.CloseFile();
# endif

    // Precompute some factors for calculating scaled wavelets.
    const double one_over_sqrt_N = 1.0 / sqrt(static_cast<double>( nframes ));
    std::vector<int> arrayK( nframes );
    arrayK[0] = -1 * (nframes/2);
    for (int i = 1; i != nframes; i++)
        arrayK[i] = arrayK[i-1] + 1;
# ifdef DEBUG_WAVELET
    mprintf("DEBUG: K:");
    for (std::vector<int>::const_iterator kval = arrayK.begin(); kval != arrayK.end(); ++kval)
        mprintf(" %i", *kval);
    mprintf("\n");
# endif

    // Step 2 - Get FFT of wavelet for each scale.
    PubFFT pubfft;
    pubfft.SetupFFTforN( nframes );
    mprintf("\tMemory required for scaled wavelet array: %.2f MB\n",
            (double)(2 * nframes * nb_ * sizeof(double)) / (1024 * 1024));
    typedef std::vector<ComplexArray> WaveletArray;
    WaveletArray FFT_of_Scaled_Wavelets;
    FFT_of_Scaled_Wavelets.reserve( nb_ );
    typedef std::vector<double> Darray;
    Darray scaleVector;
    scaleVector.reserve( nb_ );
    Darray MIN( nb_ * 2 );
    for (int iscale = 0; iscale != nb_; iscale++)
    {
        // Calculate and store scale factor.
        scaleVector.push_back( S0_ * pow(2.0, iscale * ds_) );
        // Populate MIN array
        MIN[iscale    ] = (0.00647*pow((correction_*scaleVector.back()),1.41344)+19.7527)*chival_;
        MIN[iscale+nb_] = correction_*scaleVector.back();
        // Calculate scalved wavelet
        ComplexArray scaledWavelet;
        switch (wavelet_type_) {
        case W_MORLET:
            scaledWavelet = F_Morlet(arrayK, scaleVector.back());
            break;
        case W_PAUL  :
            scaledWavelet = F_Paul(arrayK, scaleVector.back());
            break;
        case W_NONE  :
            return Analysis::ERR; // Sanity check
        }
#   ifdef DEBUG_WAVELET
        PrintComplex("wavelet_before_fft", scaledWavelet);
#   endif
        // Perform FFT
        pubfft.Forward( scaledWavelet );
        // Normalize
        scaledWavelet.Normalize( one_over_sqrt_N );
#   ifdef DEBUG_WAVELET
        PrintComplex("wavelet_after_fft", scaledWavelet);
#   endif
        FFT_of_Scaled_Wavelets.push_back( scaledWavelet );
    }
# ifdef DEBUG_WAVELET
    mprintf("DEBUG: Scaling factors:");
    for (Darray::const_iterator sval = scaleVector.begin(); sval != scaleVector.end(); ++sval)
        mprintf(" %g", *sval);
    mprintf("\n");
    mprintf("DEBUG: MIN:");
    for (int i = 0; i != nb_; i++)
        mprintf(" %g", MIN[i]);
    mprintf("\n");
# endif

    // Step 3 - For each atom, calculate the convolution of scaled wavelets
    //          with rows (atom distance vs frame) via dot product of the
    //          frequency domains, i.e. Fourier-transformed, followed by an
    //          inverse FT.
    DataSet_MatrixFlt& OUT = static_cast<DataSet_MatrixFlt&>( *output_ );
    mprintf("\tMemory required for output matrix: %.2f MB\n",
            (double)Matrix<float>::sizeInBytes(nframes, natoms)/(1024.0*1024.0));
    OUT.Allocate2D( nframes, natoms ); // Should initialize to zero
    Matrix<double> MAX;
    mprintf("\tMemory required for Max array: %.2f MB\n",
            (double)MAX.sizeInBytes(nframes, natoms)/(1024.0*1024.0));
    MAX.resize( nframes, natoms );
    Darray magnitude( nframes ); // Scratch space for calculating magnitude across rows
    for (int at = 0; at != natoms; at++) {
        ComplexArray AtomSignal( nframes ); // Initializes to zero
        // Calculate the distance variance for this atom and populate the array.
        int midx = at * nframes; // Index into d_matrix
        int cidx = 0;            // Index into AtomSignal
        double d_avg = 0.0;
        double d_var = 0.0;
        for (int frm = 0; frm != nframes; frm++, cidx += 2, midx++) {
            d_avg += d_matrix[midx];
            d_var += (d_matrix[midx] * d_matrix[midx]);
            AtomSignal[cidx] = d_matrix[midx];
        }
        d_var = (d_var - ((d_avg * d_avg) / (double)nframes)) / ((double)(nframes - 1));
#   ifdef DEBUG_WAVELET
        mprintf("VARIANCE: %g\n", d_var);
#   endif
        double var_norm = 1.0 / d_var;
        // Calculate FT of atom signal
        pubfft.Forward( AtomSignal );
#   ifdef DEBUG_WAVELET
        PrintComplex("AtomSignal", AtomSignal);
#   endif
        // Normalize
        AtomSignal.Normalize( one_over_sqrt_N );
        // Calculate dot product of atom signal with each scaled FT wavelet
        for (int iscale = 0; iscale != nb_; iscale++) {
            ComplexArray dot = AtomSignal.TimesComplexConj( FFT_of_Scaled_Wavelets[iscale] );
            // Inverse FT of dot product
            pubfft.Back( dot );
#     ifdef DEBUG_WAVELET
            PrintComplex("InverseFT_Dot", dot);
#     endif
            // Chi-squared testing
            midx = at * nframes;
            cidx = 0;
            for (int frm = 0; frm != nframes; frm++, cidx += 2, midx++) {
                magnitude[frm] = (dot[cidx]*dot[cidx] + dot[cidx+1]*dot[cidx+1]) * var_norm;
                if (magnitude[frm] < MIN[iscale])
                    magnitude[frm] = 0.0;
                if (magnitude[frm] > MAX[midx]) {
                    MAX[midx] = magnitude[frm];
                    //Indices[midx] = iscale
                    OUT[midx] = (float)(correction_ * scaleVector[iscale]);
                }
            }
#     ifdef DEBUG_WAVELET
            mprintf("DEBUG: AbsoluteValue:");
            for (Darray::const_iterator dval = magnitude.begin(); dval != magnitude.end(); ++dval)
                mprintf(" %g", *dval);
            mprintf("\n");
#     endif
        } // END loop over scales
    } // END loop over atoms
# ifdef DEBUG_WAVELET
    // DEBUG: Print MAX
    CpptrajFile maxmatrixOut; // DEBUG
    maxmatrixOut.OpenWrite("maxmatrix.dat");
    for (int col = 0; col != nframes; col++) {
        for (int row = 0; row != natoms; row++)
            maxmatrixOut.Printf("%g ", MAX.element(col, row));
        maxmatrixOut.Printf("\n");
    }
    maxmatrixOut.CloseFile();
# endif

    return Analysis::OK;
}