Analysis::RetType Analysis_Integrate::Analyze() { double sum; int idx = 0; for (Array1D::const_iterator DS = input_dsets_.begin(); DS != input_dsets_.end(); ++DS, ++idx) { if ( (*DS)->Size() < 1) mprintf("Warning: Set [%i] \"%s\" has no data.\n", idx, (*DS)->legend()); else { DataSet_Mesh mesh; // Set XY mesh mesh.SetMeshXY( *(*DS) ); if (outfile_ != 0) sum = mesh.Integrate_Trapezoid( *(output_dsets_[idx]) ); else sum = mesh.Integrate_Trapezoid(); mprintf("\tIntegral of %s is %g\n", (*DS)->legend(), sum); } } return Analysis::OK; }
/** For per-residue RMSD only. Setup output * file options. Calculate averages if requested. */ void Action_Rmsd::Print() { if (!perres_ || ResidueRMS_.empty()) return; // Per-residue output file if (perresout_ != 0) { // Set output file to be inverted if requested if (perresinvert_) perresout_->ProcessArgs("invert"); mprintf(" RMSD: Per-residue: Writing data for %zu residues to %s\n", ResidueRMS_.size(), perresout_->DataFilename().full()); } // Average if (perresavg_ != 0) { // Use the per residue rmsd dataset list to add one more for averaging DataSet_Mesh* PerResAvg = (DataSet_Mesh*)masterDSL_->AddSet(DataSet::XYMESH, MetaData(rmsd_->Meta().Name(), "Avg")); PerResAvg->ModifyDim(Dimension::X).SetLabel("Residue"); // another for stdev DataSet_Mesh* PerResStdev = (DataSet_Mesh*)masterDSL_->AddSet(DataSet::XYMESH, MetaData(rmsd_->Meta().Name(), "Stdev")); PerResStdev->ModifyDim(Dimension::X).SetLabel("Residue"); // Add the average and stdev datasets to the master datafile list perresavg_->AddDataSet(PerResAvg); perresavg_->AddDataSet(PerResStdev); // For each residue, get the average rmsd double stdev = 0; double avg = 0; for (perResArray::const_iterator PerRes = ResidueRMS_.begin(); PerRes != ResidueRMS_.end(); ++PerRes) { avg = PerRes->data_->Avg( stdev ); double pridx = (double)PerRes->data_->Meta().Idx(); PerResAvg->AddXY(pridx, avg); PerResStdev->AddXY(pridx, stdev); } } }
// Analysis_RemLog::Analyze() Analysis::RetType Analysis_RemLog::Analyze() { if (remlog_->Size() < 1) { mprinterr("Error: No replicas in remlog data '%s'\n", remlog_->legend()); return Analysis::ERR; } int Ndims = remlog_->DimTypes().Ndims(); mprintf("\t'%s' %i replicas, %i exchanges, %i dims.\n", remlog_->legend(), remlog_->Size(), remlog_->NumExchange(), Ndims); // Set up arrays for tracking replica stats. std::vector<RepStats> DimStats; std::vector<TripStats> DimTrips; for (int i = 0; i != Ndims; i++) { DimStats.push_back( RepStats(remlog_->Size()) ); if (calculateStats_) DimTrips.push_back( TripStats(remlog_->Size()) ); } std::vector< std::vector<int> > replicaFrac; if (calculateStats_) { replicaFrac.resize( remlog_->Size() ); // [replica][crdidx] for (std::vector< std::vector<int> >::iterator it = replicaFrac.begin(); it != replicaFrac.end(); ++it) it->resize( remlog_->Size(), 0 ); } // Variables for calculating replica lifetimes Analysis_Lifetime Lifetime; Array1D dsLifetime; std::vector< std::vector<DataSet_integer> > series; // 2D - repidx, crdidx if (calculateLifetimes_) { mprintf("\tData size used for lifetime analysis= %zu bytes.\n", remlog_->Size() * remlog_->Size() * remlog_->NumExchange() * sizeof(int)); series.resize( remlog_->Size() ); for (unsigned int i = 0; i < remlog_->Size(); i++) { series[i].resize( remlog_->Size() ); for (unsigned int j = 0; j < remlog_->Size(); j++) { series[i][j].Resize( remlog_->NumExchange() ); series[i][j].SetLegend("Rep"+integerToString(i+1)+",Crd"+integerToString(j+1)); dsLifetime.push_back( (DataSet_1D*)&(series[i][j]) ); } } if (Lifetime.ExternalSetup( dsLifetime, lifetimes_ ) == Analysis::ERR) { mprinterr("Error: Could not set up remlog lifetime analysis.\n"); return Analysis::ERR; } } DataSet_Mesh mesh; if ( calcRepFracSlope_ > 0 ) { mesh.CalculateMeshX( remlog_->Size(), 1, remlog_->Size() ); repFracSlope_->Printf("%-8s", "#Exchg"); for (int crdidx = 0; crdidx < (int)remlog_->Size(); crdidx++) repFracSlope_->Printf(" C%07i_slope C%07i_corel", crdidx + 1, crdidx + 1); repFracSlope_->Printf("\n"); } ProgressBar progress( remlog_->NumExchange() ); for (int frame = 0; frame < remlog_->NumExchange(); frame++) { progress.Update( frame ); for (int replica = 0; replica < (int)remlog_->Size(); replica++) { DataSet_RemLog::ReplicaFrame const& frm = remlog_->RepFrame( frame, replica ); int crdidx = frm.CoordsIdx() - 1; int repidx = frm.ReplicaIdx() - 1; int dim = frm.Dim(); // Exchange acceptance. // NOTE: Because currently the direction of the attempt is not always // known unless the attempt succeeds for certain remlog types, // the results will be skewed if dimension size is 2 since in that // case the left partner is the right partner. if (replica == 0) DimStats[dim].attempts_++; // Assume same # attempts for every rep in dim if (frm.Success()) { if (frm.PartnerIdx() - 1 == remlog_->ReplicaInfo()[replica][dim].RightID()) DimStats[dim].acceptUp_[replica]++; else // Assume down DimStats[dim].acceptDown_[replica]++; } if (mode_ == CRDIDX) { DataSet_integer& ds = static_cast<DataSet_integer&>( *(outputDsets_[repidx]) ); ds[frame] = frm.CoordsIdx(); } else if (mode_ == REPIDX) { DataSet_integer& ds = static_cast<DataSet_integer&>( *(outputDsets_[crdidx]) ); ds[frame] = frm.ReplicaIdx(); } if (calculateLifetimes_) series[repidx][crdidx][frame] = 1; if (calculateStats_) { TripStats& trip = static_cast<TripStats&>( DimTrips[dim] ); // Fraction spent at each replica replicaFrac[repidx][crdidx]++; // Replica round-trip calculation if (trip.status_[crdidx] == UNKNOWN) { if (remlog_->ReplicaInfo()[repidx][dim].Location() == DataSet_RemLog::BOTTOM) { trip.status_[crdidx] = HIT_BOTTOM; trip.bottom_[crdidx] = frame; } } else if (trip.status_[crdidx] == HIT_BOTTOM) { if (remlog_->ReplicaInfo()[repidx][dim].Location() == DataSet_RemLog::TOP) trip.status_[crdidx] = HIT_TOP; } else if (trip.status_[crdidx] == HIT_TOP) { if (remlog_->ReplicaInfo()[repidx][dim].Location() == DataSet_RemLog::BOTTOM) { int rtrip = frame - trip.bottom_[crdidx]; if (printIndividualTrips_) statsout_->Printf("[%i] CRDIDX %i took %i exchanges to travel" " up and down (exch %i to %i)\n", replica, crdidx+1, rtrip, trip.bottom_[crdidx]+1, frame+1); trip.roundTrip_[crdidx].AddElement( rtrip ); trip.status_[crdidx] = HIT_BOTTOM; trip.bottom_[crdidx] = frame; } } } } // END loop over replicas if (calcRepFracSlope_ > 0 && frame > 0 && (frame % calcRepFracSlope_) == 0) { repFracSlope_->Printf("%8i", frame+1); for (int crdidx = 0; crdidx < (int)remlog_->Size(); crdidx++) { for (int replica = 0; replica < (int)remlog_->Size(); replica++) mesh.SetY(replica, (double)replicaFrac[replica][crdidx] / (double)frame); double slope, intercept, correl; mesh.LinearRegression(slope, intercept, correl, true); repFracSlope_->Printf(" %14.7g %14.7g", slope * 100.0, correl); //frame+1, crdidx, slope * 100.0, intercept * 100.0, correl } repFracSlope_->Printf("\n"); } } // END loop over exchanges // Exchange acceptance calc. for (int dim = 0; dim != Ndims; dim++) { // Assume number of exchange attempts is actually /2 since in Amber // attempts alternate up/down. acceptout_->Printf("DIMENSION %i\n", dim+1); if (debug_ > 0) { for (int replica = 0; replica != (int)remlog_->Size(); replica++) mprintf("Rep %i attempts %i up %i down %i\n", replica, DimStats[dim].attempts_, DimStats[dim].acceptUp_[replica], DimStats[dim].acceptDown_[replica]); } acceptout_->Printf("%-8s %8s %8s\n", "#Replica", "%UP", "%DOWN"); double exchangeAttempts = (double)DimStats[dim].attempts_ / 2.0; for (int replica = 0; replica != (int)remlog_->Size(); replica++) acceptout_->Printf("%8i %8.3f %8.3f\n", replica+1, ((double)DimStats[dim].acceptUp_[replica] / exchangeAttempts) * 100.0, ((double)DimStats[dim].acceptDown_[replica] / exchangeAttempts) * 100.0); } if (calculateStats_) { statsout_->Printf("# %i replicas, %i exchanges.\n", remlog_->Size(), remlog_->NumExchange()); for (int dim = 0; dim != Ndims; dim++) { if (Ndims > 1) statsout_->Printf("#Dim%i Round-trip stats:\n", dim+1); else statsout_->Printf("#Round-trip stats:\n"); statsout_->Printf("#%-8s %8s %12s %12s %12s %12s\n", "CRDIDX", "RndTrips", "AvgExch.", "SD_Exch.", "Min", "Max"); unsigned int idx = 1; for (DSI_array::const_iterator rt = DimTrips[dim].roundTrip_.begin(); rt != DimTrips[dim].roundTrip_.end(); ++rt) { double stdev = 0.0; double avg = rt->Avg( stdev ); statsout_->Printf("%-8u %8i %12.4f %12.4f %12.0f %12.0f\n", idx++, rt->Size(), avg, stdev, rt->Min(), rt->Max()); } } reptime_->Printf("#Percent time spent at each replica:\n%-8s", "#Replica"); for (int crd = 0; crd < (int)remlog_->Size(); crd++) reptime_->Printf(" CRD_%04i", crd + 1); reptime_->Printf("\n"); double dframes = (double)remlog_->NumExchange(); for (int replica = 0; replica < (int)remlog_->Size(); replica++) { reptime_->Printf("%8i", replica+1); for (int crd = 0; crd < (int)remlog_->Size(); crd++) reptime_->Printf(" %8.3f", ((double)replicaFrac[replica][crd] / dframes) * 100.0); reptime_->Printf("\n"); } } if (calculateLifetimes_) { mprintf("\tCalculating remlog lifetimes:\n"); Lifetime.Analyze(); } return Analysis::OK; }
// Action_VelocityAutoCorr::Print() void Action_VelocityAutoCorr::Print() { if (Vel_.empty()) return; mprintf(" VELOCITYAUTOCORR:\n"); mprintf("\t%zu vectors have been saved, total length of each = %zu\n", Vel_.size(), Vel_[0].Size()); int maxlag; if (maxLag_ <= 0) { maxlag = (int)Vel_[0].Size() / 2; mprintf("\tSetting maximum lag to 1/2 total time (%i)\n", maxlag); } else if (maxLag_ > (int)Vel_[0].Size()) { maxlag = (int)Vel_[0].Size(); mprintf("\tSpecified maximum lag > total length, setting to %i\n", maxlag); } else maxlag = maxLag_; // DEBUG //for (VelArray::iterator vel = Vel_.begin(); vel != Vel_.end(); ++vel) { // mprintf("Vector %u:\n", vel - Vel_.begin()); // for (DataSet_Vector::iterator vec = vel->begin(); vec != vel->end(); ++vec) // mprintf("\t%u {%f %f %f}\n", vec - vel->begin(), (*vec)[0], (*vec)[1], (*vec)[2]); //} // Allocate space for output correlation function values. DataSet_double& Ct = static_cast<DataSet_double&>( *VAC_ ); Ct.Resize( maxlag ); if (!useFFT_) { // DIRECT METHOD ParallelProgress progress( maxlag ); int t; unsigned int dtmax, dt; # ifdef _OPENMP # pragma omp parallel private(t, dtmax, dt) firstprivate(progress) { progress.SetThread(omp_get_thread_num()); # pragma omp for schedule(dynamic) # endif for (t = 0; t < maxlag; ++t) { progress.Update( t ); dtmax = Vel_[0].Size() - t; for (dt = 0; dt < dtmax; ++dt) { for (VelArray::const_iterator vel = Vel_.begin(); vel != Vel_.end(); ++vel) Ct[t] += (*vel)[dt] * (*vel)[dt + t]; } Ct[t] /= (double)(dtmax * Vel_.size()); //mprintf("\tCt[%i]= %f\n", t, Ct[t]); // DEBUG } # ifdef _OPENMP } // END pragma omp parallel # endif progress.Finish(); } else { // FFT METHOD // Since FFT is cyclic, unroll vectors into a 1D array; in the resulting // transformed array after FFT, every 3rd value will be the correlation // via dot products that we want (once it is normalized). unsigned int total_length = Vel_[0].Size() * 3; CorrF_FFT pubfft; pubfft.CorrSetup( total_length ); ComplexArray data1 = pubfft.Array(); //mprintf("Complex Array Size is %i (%i actual)\n", data1.size(), data1.size()*2); ProgressBar progress( Vel_.size() ); unsigned int nvel = 0; for (VelArray::iterator vel = Vel_.begin(); vel != Vel_.end(); ++vel, ++nvel) { //mprintf("Vector %u\n", vel - Vel_.begin()); // DEBUG progress.Update( nvel ); // Place vector from each frame into 1D array unsigned int nd = 0; // Will be used to index complex data for (DataSet_Vector::const_iterator vec = vel->begin(); vec != vel->end(); ++vec, nd+=6) { //mprintf("\tFrame %u assigned to complex array %u\n", vec - vel->begin(), nd); // DEBUG data1[nd ] = (*vec)[0]; data1[nd+1] = 0.0; data1[nd+2] = (*vec)[1]; data1[nd+3] = 0.0; data1[nd+4] = (*vec)[2]; data1[nd+5] = 0.0; //mprintf("\t Complex[%u]= %f Complex[%u]= %f Complex[%u]= %f\n", // DEBUG // nd, data1[nd], nd+2, data1[nd+2], nd+4, data1[nd+4]); } data1.PadWithZero( total_length ); //mprintf("Before FFT:\n"); // DEBUG //for (unsigned int cd = 0; cd < (unsigned int)data1.size()*2; cd += 2) // mprintf("\t%u: %f + %fi\n", cd/2, data1[cd], data1[cd+1]); pubfft.AutoCorr( data1 ); //mprintf("Results of FFT:\n"); // DEBUG //for (unsigned int cd = 0; cd < (unsigned int)data1.size()*2; cd += 2) // mprintf("\t%u: %f + %fi\n", cd/2, data1[cd], data1[cd+1]); // Increment nd by 3 here so it can be used for normalization. nd = 0; for (int t = 0; t < maxlag; t++, nd += 3) { //mprintf("\tdata1[%u] = %f", nd*2, data1[nd*2]); // DEBUG //mprintf(" norm= %u", total_length - nd); // DEBUG //Ct[t] += data1[nd*2] * 3.0 / (double)(total_length - nd); Ct[t] += data1[nd*2]; //mprintf(" Ct[%i]= %f\n", t, Ct[t]); // DEBUG } } // Normalization for (int t = 0, nd = 0; t < maxlag; t++, nd += 3) Ct[t] *= ( 3.0 / (double)((total_length - nd) * Vel_.size()) ); //Ct[t] /= (double)Vel_.size(); } // Integration to get diffusion coefficient. VAC_->SetDim(Dimension::X, Dimension(1.0, tstep_, "Frame")); mprintf("\tIntegrating data set %s, step is %f\n", VAC_->legend(), VAC_->Dim(0).Step()); DataSet_Mesh mesh; mesh.SetMeshXY( static_cast<DataSet_1D const&>(*VAC_) ); double total = mesh.Integrate_Trapezoid(); const double ANG2_PS_TO_CM2_S = 10.0 / 6.0; mprintf("\t3D= %g Å^2/ps, %g x10^-5 cm^2/s\n", total, total * ANG2_PS_TO_CM2_S); mprintf("\t D= %g Å^2/ps, %g x10^-5 cm^2/s\n", total / 3.0, total * ANG2_PS_TO_CM2_S / 3.0); mprintf("\t6D= %g Å^2/ps, %g x10^-5 cm^2/s\n", total * 2.0, total * ANG2_PS_TO_CM2_S * 2.0); if (normalize_) { // Normalize VAC fn to 1.0 mprintf("\tNormalizing VAC function to 1.0, C[0]= %g\n", Ct[0]); double norm = 1.0 / Ct[0]; for (int t = 0; t < maxlag; ++t) Ct[t] *= norm; } }
int Cluster_DPeaks::ChoosePointsAutomatically() { // Right now all density values are discrete. Try to choose outliers at each // value for which there is density.; /* // For each point, calculate average distance (X,Y) to points in next and // previous density values. const double dens_cut = 3.0 * 3.0; const double dist_cut = 1.32 * 1.32; for (Carray::const_iterator point0 = Points_.begin(); point0 != Points_.end(); ++point0) { int Npts = 0; for (Carray::const_iterator point1 = Points_.begin(); point1 != Points_.end(); ++point1) { if (point0 != point1) { // Only do this for close densities double dX = (double)(point0->PointsWithinEps() - point1->PointsWithinEps()); double dX2 = dX * dX; double dY = (point0->Dist() - point1->Dist()); double dY2 = dY * dY; if (dX2 < dens_cut && dY2 < dist_cut) { Npts++; } } } mprintf("%i %i %i\n", point0->PointsWithinEps(), point0->Fnum()+1, Npts); } */ /* CpptrajFile tempOut; tempOut.OpenWrite("temp.dat"); int currentDensity = -1; double distAv = 0.0; double distSD = 0.0; double sumWts = 0.0; int nValues = 0; Carray::const_iterator lastPoint = Points_.end() + 1; for (Carray::const_iterator point = Points_.begin(); point != lastPoint; ++point) { if (point == Points_.end() || point->PointsWithinEps() != currentDensity) { if (nValues > 0) { distAv = distAv / sumWts; //(double)nValues; distSD = (distSD / sumWts) - (distAv * distAv); if (distSD > 0.0) distSD = sqrt(distSD); else distSD = 0.0; //mprintf("Density %i: %i values Avg= %g SD= %g SumWts= %g\n", currentDensity, // nValues, distAv, distSD, sumWts); tempOut.Printf("%i %g\n", currentDensity, distAv); } if (point == Points_.end()) break; currentDensity = point->PointsWithinEps(); distAv = 0.0; distSD = 0.0; sumWts = 0.0; nValues = 0; } double wt = exp(point->Dist()); double dval = point->Dist() * wt; sumWts += wt; distAv += dval; distSD += (dval * dval); nValues++; } tempOut.CloseFile(); */ // BEGIN CALCULATING WEIGHTED DISTANCE AVERAGE CpptrajFile tempOut; tempOut.OpenWrite("temp.dat"); DataSet_Mesh weightedAverage; Carray::const_iterator cp = Points_.begin(); // Skip local density of 0. //while (cp->PointsWithinEps() == 0 && cp != Points_.end()) ++cp; while (cp != Points_.end()) { int densityVal = cp->PointsWithinEps(); Carray densityArray; // Add all points of current density. while (cp->PointsWithinEps() == densityVal && cp != Points_.end()) densityArray.push_back( *(cp++) ); mprintf("Density value %i has %zu points.\n", densityVal, densityArray.size()); // Sort array by distance std::sort(densityArray.begin(), densityArray.end(), Cpoint::dist_sort()); // Take the average of the points weighted by their position. double wtDistAv = 0.0; double sumWts = 0.0; //std::vector<double> weights; //weights.reserve( densityArray.size() ); int maxPt = (int)densityArray.size() - 1; for (int ip = 0; ip != (int)densityArray.size(); ++ip) { double wt = exp( (double)(ip - maxPt) ); //mprintf("\t%10i %10u %10u %10g\n", densityVal, ip, maxPt, wt); wtDistAv += (densityArray[ip].Dist() * wt); sumWts += wt; //weights.push_back( wt ); } wtDistAv /= sumWts; // Calculate the weighted sample variance //double distSD = 0.0; //for (unsigned int ip = 0; ip != densityArray.size(); ++ip) { // double diff = densityArray[ip].Dist() - wtDistAv; // distSD += weights[ip] * (diff * diff); //} //distSD /= sumWts; weightedAverage.AddXY(densityVal, wtDistAv); //tempOut.Printf("%i %g %g %g\n", densityVal, wtDistAv, sqrt(distSD), sumWts); tempOut.Printf("%i %g %g\n", densityVal, wtDistAv, sumWts); /* // Find the median. double median, Q1, Q3; if (densityArray.size() == 1) { median = densityArray[0].Dist(); Q1 = median; Q3 = median; } else { unsigned int q3_beg; unsigned int med_idx = densityArray.size() / 2; // Always 0 <= Q1 < med_idx if ((densityArray.size() % 2) == 0) { median = (densityArray[med_idx].Dist() + densityArray[med_idx-1].Dist()) / 2.0; q3_beg = med_idx; } else { median = densityArray[med_idx].Dist(); q3_beg = med_idx + 1; } if (densityArray.size() == 2) { Q1 = densityArray[0].Dist(); Q3 = densityArray[1].Dist(); } else { // Find lower quartile unsigned int q1_idx = med_idx / 2; if ((med_idx % 2) == 0) Q1 = (densityArray[q1_idx].Dist() + densityArray[q1_idx-1].Dist()) / 2.0; else Q1 = densityArray[q1_idx].Dist(); // Find upper quartile unsigned int q3_size = densityArray.size() - q3_beg; unsigned int q3_idx = (q3_size / 2) + q3_beg; if ((q3_size %2) == 0) Q3 = (densityArray[q3_idx].Dist() + densityArray[q3_idx-1].Dist()) / 2.0; else Q3 = densityArray[q3_idx].Dist(); } } mprintf("\tMedian dist value is %g. Q1= %g Q3= %g\n", median, Q1, Q3); */ } tempOut.CloseFile(); // END CALCULATING WEIGHTED DISTANCE AVERAGE /* // TEST tempOut.OpenWrite("temp2.dat"); std::vector<double> Hist( Points_.back().PointsWithinEps()+1, 0.0 ); int gWidth = 3; double cval = 3.0; double two_c_squared = 2.0 * cval * cval; mprintf("DBG: cval= %g, Gaussian denominator is %g\n", cval, two_c_squared); for (int wtIdx = 0; wtIdx != (int)weightedAverage.Size(); wtIdx++) { int bval = weightedAverage.X(wtIdx); for (int xval = std::max(bval - gWidth, 0); xval != std::min(bval + gWidth + 1, (int)Hist.size()); xval++) { // a: height (weighted average) // b: center (density value) // c: width // x: density value in histogram //int xval = weightedAverage.X(idx); //double bval = weightedAverage.X(wtIdx); //double bval = (double)wtIdx; double diff = (double)(xval - bval); //Hist[xval] += (weightedAverage.Y(wtIdx) * exp( -( (diff * diff) / two_c_squared ) )); Hist[xval] = std::max(Hist[xval], weightedAverage.Y(wtIdx) * exp( -( (diff * diff) / two_c_squared ) )); } } for (unsigned int idx = 0; idx != Hist.size(); idx++) tempOut.Printf("%u %g\n", idx, Hist[idx]); tempOut.CloseFile(); // END TEST */ /* // TEST // Construct best-fit line segments tempOut.OpenWrite("temp2.dat"); double slope, intercept, correl; int segment_length = 3; DataSet_Mesh Segment; Segment.Allocate1D( segment_length ); for (int wtIdx = 0; wtIdx != (int)weightedAverage.Size(); wtIdx++) { Segment.Clear(); for (int idx = std::max(wtIdx - 1, 0); // TODO: use segment_length idx != std::min(wtIdx + 2, (int)weightedAverage.Size()); idx++) Segment.AddXY(weightedAverage.X(idx), weightedAverage.Y(idx)); Segment.LinearRegression(slope, intercept, correl, true); for (int idx = std::max(wtIdx - 1, 0); // TODO: use segment_length idx != std::min(wtIdx + 2, (int)weightedAverage.Size()); idx++) { double x = weightedAverage.X(idx); double y = slope * x + intercept; tempOut.Printf("%g %g %i\n", x, y, weightedAverage.X(wtIdx)); } } tempOut.CloseFile(); // END TEST */ // BEGIN WEIGHTED RUNNING AVG/SD OF DISTANCES // For each point, determine if it is greater than the average of the // weighted average distances of the previous, current, and next densities. int width = 2; int currentDensity = 0; int wtIdx = 0; double currentAvg = 0.0; double deltaSD = 0.0; double deltaAv = 0.0; int Ndelta = 0; CpptrajFile raOut; if (!rafile_.empty()) raOut.OpenWrite(rafile_); CpptrajFile raDelta; if (!radelta_.empty()) raDelta.OpenWrite(radelta_); std::vector<unsigned int> candidateIdxs; std::vector<double> candidateDeltas; cp = Points_.begin(); // Skip over points with zero density while (cp != Points_.end() && cp->PointsWithinEps() == 0) ++cp; while (weightedAverage.X(wtIdx) != cp->PointsWithinEps() && wtIdx < (int)Points_.size()) ++wtIdx; for (Carray::const_iterator point = cp; point != Points_.end(); ++point) { if (point->PointsWithinEps() != currentDensity) { //currentAvg = weightedAverage.Y(wtIdx); // New density value. Determine average. currentAvg = 0.0; // unsigned int Npt = 0; double currentWt = 0.0; for (int idx = std::max(wtIdx - width, 0); idx != std::min(wtIdx + width + 1, (int)weightedAverage.Size()); idx++) { //currentAvg += weightedAverage.Y(idx); //Npt++; double wt = weightedAverage.Y(idx); currentAvg += (weightedAverage.Y(idx) * wt); currentWt += wt; } //currentAvg /= (double)Npt; currentAvg /= currentWt; //smoothAv += currentAvg; //smoothSD += (currentAvg * currentAvg); //Nsmooth++; currentDensity = point->PointsWithinEps(); if (raOut.IsOpen()) raOut.Printf("%i %g %g\n", currentDensity, currentAvg, weightedAverage.Y(wtIdx)); wtIdx++; } double delta = (point->Dist() - currentAvg); if (delta > 0.0) { //delta *= log((double)currentDensity); if (raDelta.IsOpen()) raDelta.Printf("%8i %8.3f %8i %8.3f %8.3f\n", currentDensity, delta, point->Fnum()+1, point->Dist(), currentAvg); candidateIdxs.push_back( point - Points_.begin() ); candidateDeltas.push_back( delta ); deltaAv += delta; deltaSD += (delta * delta); Ndelta++; } } raOut.CloseFile(); deltaAv /= (double)Ndelta; deltaSD = (deltaSD / (double)Ndelta) - (deltaAv * deltaAv); if (deltaSD > 0.0) deltaSD = sqrt(deltaSD); else deltaSD = 0.0; if (raDelta.IsOpen()) raDelta.Printf("#DeltaAvg= %g DeltaSD= %g\n", deltaAv, deltaSD); raDelta.CloseFile(); int cnum = 0; for (unsigned int i = 0; i != candidateIdxs.size(); i++) { if (candidateDeltas[i] > (deltaSD)) { Points_[candidateIdxs[i]].SetCluster( cnum++ ); mprintf("\tPoint %u (frame %i, density %i) selected as candidate for cluster %i\n", candidateIdxs[i], Points_[candidateIdxs[i]].Fnum()+1, Points_[candidateIdxs[i]].PointsWithinEps(), cnum-1); } } // END WEIGHTED AVG/SD OF DISTANCES /* // Currently doing this by calculating the running average of density vs // distance, then choosing points with distance > twice the SD of the // running average. // NOTE: Store in a mesh data set for now in case we want to spline etc later. if (avg_factor_ < 1) avg_factor_ = 10; unsigned int window_size = Points_.size() / (unsigned int)avg_factor_; mprintf("\tRunning avg window size is %u\n", window_size); // FIXME: Handle case where window_size < frames DataSet_Mesh runavg; unsigned int ra_size = Points_.size() - window_size + 1; runavg.Allocate1D( ra_size ); double dwindow = (double)window_size; double sumx = 0.0; double sumy = 0.0; for (unsigned int i = 0; i < window_size; i++) { sumx += (double)Points_[i].PointsWithinEps(); sumy += Points_[i].Dist(); } runavg.AddXY( sumx / dwindow, sumy / dwindow ); for (unsigned int i = 1; i < ra_size; i++) { unsigned int nextwin = i + window_size - 1; unsigned int prevwin = i - 1; sumx = (double)Points_[nextwin].PointsWithinEps() - (double)Points_[prevwin].PointsWithinEps() + sumx; sumy = Points_[nextwin].Dist() - Points_[prevwin].Dist() + sumy; runavg.AddXY( sumx / dwindow, sumy / dwindow ); } // Write running average if (!rafile_.empty()) { CpptrajFile raOut; if (raOut.OpenWrite(rafile_)) mprinterr("Error: Could not open running avg file '%s' for write.\n", rafile_.c_str()); else { for (unsigned int i = 0; i != runavg.Size(); i++) raOut.Printf("%g %g\n", runavg.X(i), runavg.Y(i)); raOut.CloseFile(); } } double ra_sd; double ra_avg = runavg.Avg( ra_sd ); // Double stdev to use as cutoff for findning anomalously high peaks. ra_sd *= 2.0; mprintf("\tAvg of running avg set is %g, SD*2.0 (delta cutoff) is %g\n", ra_avg, ra_sd); // For each point in density vs distance plot, determine which running // average point is closest. If the difference between the point and the // running average point is > 2.0 the SD of the running average data, // consider it a 'peak'. CpptrajFile raDelta; if (!radelta_.empty()) raDelta.OpenWrite("radelta.dat"); if (raDelta.IsOpen()) raDelta.Printf("%-10s %10s %10s\n", "#Frame", "RnAvgPos", "Delta"); unsigned int ra_position = 0; // Position in the runavg DataSet unsigned int ra_end = runavg.Size() - 1; int cnum = 0; for (Carray::iterator point = Points_.begin(); point != Points_.end(); ++point) { if (ra_position != ra_end) { // Is the next running avgd point closer to this point? while (ra_position != ra_end) { double dens = (double)point->PointsWithinEps(); double diff0 = fabs( dens - runavg.X(ra_position ) ); double diff1 = fabs( dens - runavg.X(ra_position+1) ); if (diff1 < diff0) ++ra_position; // Next running avg position is closer for this point. else break; // This position is closer. } } double delta = point->Dist() - runavg.Y(ra_position); if (raDelta.IsOpen()) raDelta.Printf("%-10i %10u %10g", point->Fnum()+1, ra_position, delta); if (delta > ra_sd) { if (raDelta.IsOpen()) raDelta.Printf(" POTENTIAL CLUSTER %i", cnum); point->SetCluster(cnum++); } if (raDelta.IsOpen()) raDelta.Printf("\n"); } raDelta.CloseFile(); */ return cnum; }