// Action_Distance::action() Action::RetType Action_Distance::DoAction(int frameNum, Frame* currentFrame, Frame** frameAddress) { double Dist; Matrix_3x3 ucell, recip; Vec3 a1, a2; if (useMass_) { a1 = currentFrame->VCenterOfMass( Mask1_ ); a2 = currentFrame->VCenterOfMass( Mask2_ ); } else { a1 = currentFrame->VGeometricCenter( Mask1_ ); a2 = currentFrame->VGeometricCenter( Mask2_ ); } switch ( ImageType() ) { case NONORTHO: currentFrame->BoxCrd().ToRecip(ucell, recip); Dist = DIST2_ImageNonOrtho(a1, a2, ucell, recip); break; case ORTHO: Dist = DIST2_ImageOrtho(a1, a2, currentFrame->BoxCrd()); break; case NOIMAGE: Dist = DIST2_NoImage(a1, a2); break; } Dist = sqrt(Dist); dist_->Add(frameNum, &Dist); //fprintf(outfile,"%10i %10.4lf\n",frameNum,D); return Action::OK; }
double Action_LIE::Calculate_LJ(Frame const& frameIn, Topology const& parmIn) const { double result = 0; // Loop over ligand atoms AtomMask::const_iterator mask1_end = Mask1_.end(); AtomMask::const_iterator mask2_end = Mask2_.end(); for (AtomMask::const_iterator maskatom1 = Mask1_.begin(); maskatom1 != mask1_end; maskatom1++) { int crdidx1 = (*maskatom1) * 3; // index into coordinate array Vec3 atm1 = Vec3(frameIn.CRD(crdidx1)); for (AtomMask::const_iterator maskatom2 = Mask2_.begin(); maskatom2 != mask2_end; maskatom2++) { int crdidx2 = (*maskatom2) * 3; // index into coordinate array Vec3 atm2 = Vec3(frameIn.CRD(crdidx2)); double dist2; // Get imaged distance Matrix_3x3 ucell, recip; switch( ImageType() ) { case NONORTHO: frameIn.BoxCrd().ToRecip(ucell, recip); dist2 = DIST2_ImageNonOrtho(atm1, atm2, ucell, recip); break; case ORTHO: dist2 = DIST2_ImageOrtho(atm1, atm2, frameIn.BoxCrd()); break; default: dist2 = DIST2_NoImage(atm1, atm2); } if (dist2 > cut2vdw_) continue; // Here we add to our nonbonded (VDW) energy NonbondType const& LJ = parmIn.GetLJparam(*maskatom1, *maskatom2); double r2 = 1 / dist2; double r6 = r2 * r2 * r2; result += LJ.A() * r6 * r6 - LJ.B() * r6; } } return result; }
double Action_LIE::Calculate_Elec(Frame const& frameIn) const { double result = 0; // Loop over ligand atoms AtomMask::const_iterator mask1_end = Mask1_.end(); AtomMask::const_iterator mask2_end = Mask2_.end(); for (AtomMask::const_iterator maskatom1 = Mask1_.begin(); maskatom1 != mask1_end; maskatom1++) { int crdidx1 = (*maskatom1) * 3; // index into coordinate array Vec3 atm1 = Vec3(frameIn.CRD(crdidx1)); for (AtomMask::const_iterator maskatom2 = Mask2_.begin(); maskatom2 != mask2_end; maskatom2++) { int crdidx2 = (*maskatom2) * 3; // index into coordinate array Vec3 atm2 = Vec3(frameIn.CRD(crdidx2)); double dist2; // Get imaged distance Matrix_3x3 ucell, recip; switch( ImageType() ) { case NONORTHO: frameIn.BoxCrd().ToRecip(ucell, recip); dist2 = DIST2_ImageNonOrtho(atm1, atm2, ucell, recip); break; case ORTHO: dist2 = DIST2_ImageOrtho(atm1, atm2, frameIn.BoxCrd()); break; default: dist2 = DIST2_NoImage(atm1, atm2); } if (dist2 > cut2elec_) continue; // Here we add to our electrostatic energy double qiqj = atom_charge_[*maskatom1] * atom_charge_[*maskatom2]; double shift = (1 - dist2 * onecut2_); result += qiqj / sqrt(dist2) * shift * shift; } } return result; }
double Action_Spam::Calculate_Energy(Frame *frameIn, Residue const& res) { // The first atom of the solvent residue we want the energy from double result = 0; /* Now loop through all atoms in the residue and loop through the pairlist to * get the energies */ for (int i = res.FirstAtom(); i < res.LastAtom(); i++) { Vec3 atm1 = Vec3(frameIn->XYZ(i)); for (int j = 0; j < CurrentParm_.Natom(); j++) { if (j >= res.FirstAtom() && j < res.LastAtom()) continue; Vec3 atm2 = Vec3(frameIn->XYZ(j)); double dist2; // Get imaged distance Matrix_3x3 ucell, recip; switch( ImageType() ) { case NONORTHO: frameIn->BoxCrd().ToRecip(ucell, recip); dist2 = DIST2_ImageNonOrtho(atm1, atm2, ucell, recip); break; case ORTHO: dist2 = DIST2_ImageOrtho(atm1, atm2, frameIn->BoxCrd()); break; default: dist2 = DIST2_NoImage(atm1, atm2); } if (dist2 < cut2_) { double qiqj = atom_charge_[i] * atom_charge_[j]; NonbondType const& LJ = CurrentParm_.GetLJparam(i, j); double r2 = 1 / dist2; double r6 = r2 * r2 * r2; // Shifted electrostatics: qiqj/r * (1-r/rcut)^2 + VDW double shift = (1 - dist2 * onecut2_); result += qiqj / sqrt(dist2) * shift * shift + LJ.A() * r6 * r6 - LJ.B() * r6; } } } return result; }
Action::RetType Action_DNAionTracker::DoAction(int frameNum, Frame* currentFrame, Frame** frameAddress) { Matrix_3x3 ucell, recip; double d_tmp, dval; Vec3 P1, P2, BASE; // Setup imaging info if necessary if (ImageType()==NONORTHO) currentFrame->BoxCrd().ToRecip(ucell,recip); // Get center for P1, P2, and Base if (useMass_) { P1 = currentFrame->VCenterOfMass( p1_ ); P2 = currentFrame->VCenterOfMass( p2_ ); BASE = currentFrame->VCenterOfMass( base_ ); } else { P1 = currentFrame->VGeometricCenter( p1_ ); P2 = currentFrame->VGeometricCenter( p2_ ); BASE = currentFrame->VGeometricCenter( base_ ); } // Calculate P -- P distance and centroid double d_pp = DIST2(P1.Dptr(), P2.Dptr(), ImageType(), currentFrame->BoxCrd(), ucell, recip); Vec3 pp_centroid = (P1 + P2) / 2.0; // Cutoff^2 double d_cut = d_pp*0.25 + (poffset_*poffset_); // TODO: precalc offset^2 // Calculate P -- base centroid to median point double d_pbase = DIST2(pp_centroid.Dptr(), BASE.Dptr(), ImageType(), currentFrame->BoxCrd(), ucell, recip); //double d_min = DBL_MAX; if (bintype_ == SHORTEST) dval = DBL_MAX; //d_min; else dval = 0; // Loop over ion positions for (AtomMask::const_iterator ion = ions_.begin(); ion != ions_.end(); ++ion) { const double* ionxyz = currentFrame->XYZ(*ion); double d_p1ion = DIST2(P1.Dptr(), ionxyz, ImageType(), currentFrame->BoxCrd(), ucell, recip); double d_p2ion = DIST2(P2.Dptr(), ionxyz, ImageType(), currentFrame->BoxCrd(), ucell, recip); double d_baseion = DIST2(BASE.Dptr(), ionxyz, ImageType(), currentFrame->BoxCrd(), ucell, recip); //mprintf("DEBUG: ion atom %i to P1 is %f\n", *ion+1, sqrt(d_p1ion)); //mprintf("DEBUG: ion atom %i to P2 is %f\n", *ion+1, sqrt(d_p2ion)); //mprintf("DEBUG: ion atom %i to base is %f\n", *ion+1, sqrt(d_baseion)); //mprintf("DEBUG: d_pp is %f, poffset is %f, d_cut is %f\n", sqrt(d_pp), poffset_, sqrt(d_cut)); int bound = 0; int boundLower = 0; int boundUpper = 0; if (d_p1ion < d_cut && d_p2ion < d_cut) bound = 1; if (d_baseion < d_pbase) boundLower = 1; if (bound && boundLower == 0) boundUpper = 1; //if (d_tmp > d_min) // d_min = d_tmp; switch (bintype_) { case COUNT: dval += (double)bound; break; case SHORTEST: if (d_p1ion < d_p2ion) d_tmp = d_p1ion; else d_tmp = d_p2ion; if (d_tmp > d_baseion) d_tmp = d_baseion; if (d_tmp < dval) dval = d_tmp; break; case TOPCONE: dval += (double)boundUpper; break; case BOTTOMCONE: dval += (double)boundLower; break; } } if (bintype_ == SHORTEST) dval = sqrt(dval); distance_->Add(frameNum, &dval); return Action::OK; }
void CImageEx::RotateCimage( CImage *Imgn, int nAngle ) { double alpha = nAngle*3.141592654/180; IMAGEPARAMENT P; RGBQUAD ColorTab[256]; int i, j, ww, Xd, Yd, Dx, Dy,nSize; double centerx, centery, sintheta, costheta; double X1, Y1, X2, Y2, theta, xx, yy, rr; BYTE **list, *sc; int x1, y1, x2, y2, flag; double p, q, a, b, c, d, t1, t2, t3; if (ImageType() == 2) flag = 1; //flag为标志位,当取值为1时,表示双线性内插法 ,此时图像类型为灰阶图像 else flag = 0; //0表示最近邻点法 GetImageParament(this,&P); Dx = P.nWidth; Dy = P.nHeight; nSize = 0; if (Dx < Dy) { nSize = Dy; } else { nSize = Dx; } int nLineBytes = (nSize * P.nBitCount + 31) / 32 * 4; //还有一点要修改,不然当图像高度远大于宽度时会崩溃 sc = (BYTE*) malloc(2 * nLineBytes); // * P.nBytesPerLine); //申请工作单元 // list = (BYTE**) malloc(Dy * sizeof(BYTE*)); //对原位图建立二维数组 for (i = 0; i < Dy; i++) list[i] = (BYTE*) GetPixelAddress(0, i); centerx = Dx / 2; //计算位图中心位置 centery = Dy / 2; rr = sqrt(centerx * centerx + centery *centery); //计算对角线长度 theta = atan((double) centery / (double) centerx); X1 = fabs(rr * cos(alpha + theta)) + 0.5; Y1 = fabs(rr * sin(alpha + theta)) + 0.5; X2 = fabs(rr * cos(alpha - theta)) + 0.5; Y2 = fabs(rr * sin(alpha - theta)) + 0.5; if (X2 > X1) X1 = X2; //得外接矩形宽度 if (Y2 > Y1) Y1 = Y2; //外接矩形高度 ww = (int) (2 * X1); Imgn ->Destroy(); //建立结果位图 Imgn ->Create(ww, (int) (2 * Y1), P.nBitCount,CImage::createAlphaChannel ); if (P.nBitCount == 8) { GetAllPalette(this,ColorTab); //修改一,设置目标调色板 SetAllPalette(Imgn, ColorTab); //复制调色板 } sintheta = sin(alpha); costheta = cos(alpha); for (j = (int) (centery - Y1), Yd = 0; j <= (centery + Y1); j++, Yd++) { if (P.nBitCount == 8) memset (sc, 0, ww); //256色位图像素行置背景值 else memset(sc, 0, ww * P.nBytesPerPixel); //真彩色位图像素行置背景值 for (i = (int) (centerx - X1), Xd = 0; i <= centerx + X1; i++, Xd += P.nBytesPerPixel) { xx = centerx + costheta * (i - centerx) + sintheta * (j - centery); yy = centery - sintheta * (i - centerx) + costheta * (j - centery); x1 = (int) xx; x2 = x1 + 1; p = xx - x1; y1 = (int) yy; y2 = y1 + 1; q = yy - y1; if (((x1 < 0)||(x2 >= P.nWidth )||(y1 < 0)||(y2 >= P.nHeight ))) continue; if (flag == 0) { if (q > 0.5) y1 = y2; if (p > 0.5) x1 = x2; //修改二, sc[Xd] memcpy(&sc[Xd], &list[y1][x1 * P.nBytesPerPixel], P.nBytesPerPixel); //从源位图复制像素数据 } else { // flag等于1,双线性内插法 a = (double) list[y1][x1]; //从源位图取数据 b = (double) list[y1][x2]; c = (double) list[y2][x1]; d = (double) list[y2][x2]; t1 = (1 - p) * a + p * b; //双线性内插计算 t2 = (1 - p) * c + p * d; t3 = (1 - q) * t1 + q * t2; //修改三 sc[Xd] = (BYTE) t3; } } SetRectValue(Imgn, 0, Yd, ww, 1, sc); } //png图像 if ( P.nBitCount == 32 ) { LPVOID pBitsSrc = NULL; BYTE * psrc = NULL; BITMAP stBmpInfo; HBITMAP hBmp = (HBITMAP)m_ImageClone; ::GetObject(hBmp, sizeof(BITMAP), &stBmpInfo); if (32 != stBmpInfo.bmBitsPixel || NULL == stBmpInfo.bmBits) return; psrc = (BYTE *) stBmpInfo.bmBits; for (int nPosY = 0; nPosY < abs(stBmpInfo.bmHeight); nPosY++) { for (int nPosX = stBmpInfo.bmWidth; nPosX > 0; nPosX--) { BYTE alpha = psrc[3]; psrc[0] = (BYTE)((psrc[0] * alpha) / 255); psrc[1] = (BYTE)((psrc[1] * alpha) / 255); psrc[2] = (BYTE)((psrc[2] * alpha) / 255); psrc += 4; } } } free(list); //释放工作单元 free(sc); }
// Action_Watershell::action() Action::RetType Action_Watershell::DoAction(int frameNum, ActionFrame& frm) { Matrix_3x3 ucell, recip; int nlower = 0; int nupper = 0; if (ImageType()==NONORTHO) frm.Frm().BoxCrd().ToRecip(ucell,recip); int Vidx, Uidx, Vat, currentRes; int NU = soluteMask_.Nselected(); int NV = solventMask_.Nselected(); double dist; # ifdef _OPENMP int mythread; #pragma omp parallel private(dist,Vidx,Vat,currentRes,Uidx,mythread) { mythread = omp_get_thread_num(); #pragma omp for # endif // Assume solvent mask is the larger one. // Loop over solvent atoms for (Vidx = 0; Vidx < NV; Vidx++) { // Figure out which solvent residue this is Vat = solventMask_[Vidx]; currentRes = (*CurrentParm_)[ Vat ].ResNum(); // Loop over solute atoms for (Uidx = 0; Uidx < NU; Uidx++) { // If residue is not yet marked as 1st shell, calc distance # ifdef _OPENMP if ( activeResidues_thread_[mythread][currentRes] < 2 ) # else if ( activeResidues_[currentRes] < 2 ) # endif { dist = DIST2(frm.Frm().XYZ(soluteMask_[Uidx]), frm.Frm().XYZ(Vat), ImageType(), frm.Frm().BoxCrd(), ucell, recip ); // Less than upper, 2nd shell if (dist < upperCutoff_) { # ifdef _OPENMP activeResidues_thread_[mythread][currentRes] = 1; # else activeResidues_[currentRes] = 1; # endif // Less than lower, 1st shell if (dist < lowerCutoff_) # ifdef _OPENMP activeResidues_thread_[mythread][currentRes] = 2; # else activeResidues_[currentRes] = 2; # endif } } } // End loop over solute atoms } // End loop over solvent atoms # ifdef _OPENMP } // END parallel // Combine results from each thread. for (int res = 0; res < NactiveResidues_; res++) { int shell = 0; for (int thread = 0; thread < numthreads_; thread++) { if (activeResidues_thread_[thread][res] > shell) shell = activeResidues_thread_[thread][res]; // Dont break here so we can reset counts. Could also do with a fill activeResidues_thread_[thread][res] = 0; } if (shell > 0) { ++nupper; if (shell > 1) ++nlower; } } # else // Now each residue is marked 0 (no shell), 1 (second shell), 2 (first shell) for (std::vector<int>::iterator shell = activeResidues_.begin(); shell != activeResidues_.end(); ++shell) { if ( *shell > 0 ) { ++nupper; if ( *shell > 1 ) ++nlower; } // Reset for next pass *shell = 0; } # endif lower_->Add(frameNum, &nlower); upper_->Add(frameNum, &nupper); return Action::OK; }