static void compute_avercos(int n,rvec dip[],real *dd,rvec axis,gmx_bool bPairs)
{
    int    i,j,k;
    double dc,dc1,d,n5,ddc1,ddc2,ddc3;
    rvec   xxx = { 1, 0, 0 };
    rvec   yyy = { 0, 1, 0 };
    rvec   zzz = { 0, 0, 1 };
  
    d=0;
    ddc1 = ddc2 = ddc3 = 0;
    for(i=k=0; (i<n); i++) 
    {
        ddc1 += fabs(cos_angle(dip[i],xxx));
        ddc2 += fabs(cos_angle(dip[i],yyy));
        ddc3 += fabs(cos_angle(dip[i],zzz));
        if (bPairs) 
            for(j=i+1; (j<n); j++,k++) 
            {
                dc  = cos_angle(dip[i],dip[j]);
                d  += fabs(dc);
            }
    }
    *dd  = d/k;
    axis[XX] = ddc1/n;
    axis[YY] = ddc2/n;
    axis[ZZ] = ddc3/n;
}
예제 #2
0
//******* Project Pnt Onto Line Seg ******//
vec3d proj_pnt_on_line_seg(const vec3d& line_pt1, const vec3d& line_pt2, const vec3d& pnt) 
{
  vec3d p_ln1 = pnt - line_pt1;

  if ( p_ln1.mag() <= 0.0000000001 )
	  return line_pt1;
 
  vec3d ln2_ln1 = line_pt2 - line_pt1;

  if ( cos_angle( p_ln1, ln2_ln1 ) <= 0.0 )
    return ( line_pt1 );

  vec3d p_ln2 = pnt - line_pt2;

  if ( p_ln2.mag() <= 0.0000000001 )
	  return line_pt2;

  vec3d ln1_ln2 = line_pt1 - line_pt2;
  
  if ( cos_angle( p_ln2, ln1_ln2 ) <= 0.0 )
    return ( line_pt2 );

  double denom = ln2_ln1.mag();

  if (denom <= 0.0 )
    return ( line_pt1 );

  double numer =  cos_angle( p_ln1, ln2_ln1 )*p_ln1.mag();

  return(line_pt1 + ln2_ln1*(numer/denom));

}
예제 #3
0
bool VglPlus::mergeTwolineSegmentOnALine(const vgl_line_segment_2d<double> & seg1,
                                         const vgl_line_segment_2d<double> & seg2,
                                         vgl_line_segment_2d<double> & merged_seg)
{
    double cosVal = fabs(cos_angle(seg1.direction(), seg2.direction()));
    if (cosVal < cos(5.0/180.0*vnl_math::pi)) {
        return false;
    }   
    
    double dis_max = -1.0;
    vcl_vector<vgl_point_2d<double> > pts;
    pts.push_back(seg1.point1());
    pts.push_back(seg1.point2());
    pts.push_back(seg2.point1());
    pts.push_back(seg2.point2());
    // loop all combination and choose the longest one
    for (int i = 0; i<pts.size(); i++) {
        for (int j = i+1; j<pts.size(); j++) {
            double dis = vgl_distance(pts[i], pts[j]);
            if (dis > dis_max) {
                dis_max = dis;
                merged_seg = vgl_line_segment_2d<double>(pts[i], pts[j]);
            }
        }
    }
    return true;
}
예제 #4
0
void calc_rotmatrix(rvec principal_axis, rvec targetvec, matrix rotmatrix)
{
	rvec rotvec;
	real ux,uy,uz,costheta,sintheta;
	
	costheta = cos_angle(principal_axis,targetvec);
	sintheta=sqrt(1.0-costheta*costheta); /* sign is always positive since 0<theta<pi */
                
	/* Determine rotation from cross product with target vector */
	cprod(principal_axis,targetvec,rotvec);
	unitv(rotvec,rotvec);
	printf("Aligning %g %g %g to %g %g %g : xprod  %g %g %g\n",
		principal_axis[XX],principal_axis[YY],principal_axis[ZZ],targetvec[XX],targetvec[YY],targetvec[ZZ],
		rotvec[XX],rotvec[YY],rotvec[ZZ]);
		
	ux=rotvec[XX]; 
	uy=rotvec[YY]; 
	uz=rotvec[ZZ]; 
	rotmatrix[0][0]=ux*ux + (1.0-ux*ux)*costheta;
	rotmatrix[0][1]=ux*uy*(1-costheta)-uz*sintheta;
	rotmatrix[0][2]=ux*uz*(1-costheta)+uy*sintheta;
	rotmatrix[1][0]=ux*uy*(1-costheta)+uz*sintheta;
	rotmatrix[1][1]=uy*uy + (1.0-uy*uy)*costheta;
	rotmatrix[1][2]=uy*uz*(1-costheta)-ux*sintheta;
	rotmatrix[2][0]=ux*uz*(1-costheta)-uy*sintheta;
	rotmatrix[2][1]=uy*uz*(1-costheta)+ux*sintheta;
	rotmatrix[2][2]=uz*uz + (1.0-uz*uz)*costheta;
	
	printf("Rotation matrix: \n%g %g %g\n%g %g %g\n%g %g %g\n",
		rotmatrix[0][0],rotmatrix[0][1],rotmatrix[0][2],
		rotmatrix[1][0],rotmatrix[1][1],rotmatrix[1][2],
		rotmatrix[2][0],rotmatrix[2][1],rotmatrix[2][2]);
}
예제 #5
0
double Grid<Ndim>::Beta(){
	double beta;
	if (norm2(co[XX])*norm2(co[ZZ])!=0)
		beta  = acos(cos_angle(co[XX],co[ZZ]));
	else
		beta  = 0.5*M_PI;
	return beta;
}
예제 #6
0
double Grid<Ndim>::Gamma(){
	double gamma;
	if (norm2(co[XX])*norm2(co[YY])!=0)
		gamma = acos(cos_angle(co[XX],co[YY]));
	else
		gamma = 0.5*M_PI;
	return gamma;
}
예제 #7
0
double Grid<Ndim>::Alpha(){
	double alpha;
	if (norm2(co[YY])*norm2(co[ZZ])!=0)
		alpha = acos(cos_angle(co[YY],co[ZZ]));
	else
		alpha = 0.5*M_PI;

	return alpha;
}
void control::set_elastic_force(elastic_ball* a,cylinder* c,double delta_time){
    coordinate p = c->get_nearest(a);
    coordinate direction = a->ask_position() - p;
    double proportional = a->get_radius() - direction.length();
    if(proportional<0) return;
    double v = dot(a->ask_velosity() - c->get_velosity( p ),-direction.unit());
    if(v>0 && (4 * v *delta_time> direction.length() || direction.length()<0.9*a->get_radius())){
        coordinate hforce = 2/(a->get_mass()+c->get_mass())*v*direction.unit() / delta_time;
        a->set_force(c->get_mass()*hforce);
        c->set_force(-a->get_mass()*hforce * cos_angle(c->get_axis(),c->ask_position() -p));
        c->set_moment( cross( p - c->ask_position( ), -hforce ) );
    }
    coordinate force =   proportional * a->get_stiffness() * direction.unit();
    coordinate moment = cross(p - c->ask_position(),-force);
    a->set_force(force);
    c->set_force(-force * cos_angle(c->get_axis(),c->ask_position() -p));
    a->set_force(-a->ask_velosity()*delta_time);
    c->set_force(-c->get_velosity(p)*delta_time);
    c->set_moment(-c->get_speed() *delta_time);
    c->set_moment(moment);
}
예제 #9
0
static gmx_bool chk_hbonds(int i, t_atoms *pdba, rvec x[],
                           gmx_bool ad[], gmx_bool hbond[], rvec xh,
                           real angle, real dist)
{
    gmx_bool bHB;
    int      j, aj, ri, natom;
    real     d2, dist2, a;
    rvec     nh, oh;

    natom = pdba->nr;
    bHB   = FALSE;
    ri    = pdba->atom[i].resind;
    dist2 = gmx::square(dist);
    for (j = 0; (j < natom); j++)
    {
        /* Check whether the other atom is a donor/acceptor and not i */
        if ((ad[j]) && (j != i))
        {
            /* Check whether the other atom is on the same ring as well */
            if ((pdba->atom[j].resind != ri) ||
                ((strcmp(*pdba->atomname[j], "ND1") != 0) &&
                 (strcmp(*pdba->atomname[j], "NE2") != 0)))
            {
                aj  = j;
                d2  = distance2(x[i], x[j]);
                rvec_sub(x[i], xh, nh);
                rvec_sub(x[aj], xh, oh);
                a  = RAD2DEG * acos(cos_angle(nh, oh));
                if ((d2 < dist2) && (a > angle))
                {
                    if (debug)
                    {
                        fprintf(debug,
                                "HBOND between %s%d-%s and %s%d-%s is %g nm, %g deg\n",
                                *pdba->resinfo[pdba->atom[i].resind].name,
                                pdba->resinfo[pdba->atom[i].resind].nr, *pdba->atomname[i],
                                *pdba->resinfo[pdba->atom[aj].resind].name,
                                pdba->resinfo[pdba->atom[aj].resind].nr, *pdba->atomname[aj],
                                std::sqrt(d2), a);
                    }
                    hbond[i] = TRUE;
                    bHB      = TRUE;
                }
            }
        }
    }
    return bHB;
}
void Image::skel_transform()
{
    point pt, aux;
    vect *vectmatrix;
    vect *Vaux, *Vpt;
    vect offsets[8] = {{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};
    vectmatrix = new vect[size];
    double d;
    int i;
    for (i=0; i<size; ++i) {
        if (start[i] == white) {
            (vectmatrix[i]).x = 1000; // so that distance vector is unrealistically big
            (vectmatrix[i]).y = 0;
        } else {
            (vectmatrix[i]).x = 0;
            (vectmatrix[i]).y = 0;
        }
    }
    while (!boundary_queue.empty()) {
        pt = boundary_queue.front();
        Vpt = vectmatrix + (pt - start);
        for (i=0; i<8; ++i) {
            aux= pt + offset_8neighbor[i];
            Vaux = Vpt + offset_8neighbor[i];
            if (in_range(aux))
                if (norm(*Vaux) > (d = norm(sum(*Vpt,offsets[i])))) {
                    *Vaux = sum(*Vpt,offsets[i]);
                    boundary_queue.push(aux);
                    //                *aux = floor(d);
                }
        }
        boundary_queue.pop();
    }
    for (pt = start; pt < end; ++pt)
        if (*pt == white) {
            Vpt = vectmatrix + (pt - start);
            for (i = 0; i<8; ++i) {
                Vaux = Vpt + offset_8neighbor[i];
                if (in_range(aux = pt + offset_8neighbor[i]) &&
                    cos_angle(*Vpt,*Vaux) < 0.8 &&
                    norm(dif(*Vpt,*Vaux)) > 20.0)
                    *aux = 111;
            }
        }
}
예제 #11
0
//******* Project Pnt Onto Line ******//
vec3d proj_pnt_on_line(const vec3d& line_pt1, const vec3d& line_pt2, const vec3d& pnt) 
{
  vec3d p_ln1 = pnt - line_pt1;
  vec3d ln2_ln1 = line_pt2 - line_pt1;

  vec3d p_ln2 = pnt - line_pt2;
  vec3d ln1_ln2 = line_pt1 - line_pt2;
  
  double denom = ln2_ln1.mag();

  if ( fabs(denom) <= 0.000000000012 )
    return ( line_pt1 );

  double p_ln1_mag = p_ln1.mag();
  if ( fabs(p_ln1_mag) <= 0.000000000012 )
    return ( line_pt1 );


  double numer =  cos_angle( p_ln1, ln2_ln1 )*p_ln1_mag;

  return(line_pt1 + ln2_ln1*(numer/denom));

}
예제 #12
0
void do_gkr(t_gkrbin *gb,int ncos,int *ngrp,int *molindex[],
            int mindex[],rvec x[],rvec mu[],
            int ePBC,matrix box,t_atom *atom,int *nAtom)
{
    static rvec *xcm[2] = { NULL, NULL};
    int    gi,gj,j0,j1,i,j,k,n,index,grp0,grp1;
    real   qtot,q,r2,cosa,rr,phi;
    rvec   dx;
    t_pbc  pbc;
  
    for(n=0; (n<ncos); n++) {
        if (!xcm[n])
            snew(xcm[n],ngrp[n]);
        for(i=0; (i<ngrp[n]); i++) {
            /* Calculate center of mass of molecule */
            gi = molindex[n][i];
            j0 = mindex[gi];
      
            if (nAtom[n] > 0)
                copy_rvec(x[j0+nAtom[n]-1],xcm[n][i]);
            else {
                j1 = mindex[gi+1];
                clear_rvec(xcm[n][i]);
                qtot = 0;
                for(j=j0; j<j1; j++) {
                    q = fabs(atom[j].q);
                    qtot += q;
                    for(k=0; k<DIM; k++)
                        xcm[n][i][k] += q*x[j][k];
                }
                svmul(1/qtot,xcm[n][i],xcm[n][i]);
            }
        }
    }
    set_pbc(&pbc,ePBC,box);
    grp0 = 0;
    grp1 = ncos-1;
    for(i=0; i<ngrp[grp0]; i++) {
        gi = molindex[grp0][i];
        j0 = (ncos == 2) ? 0 : i+1;
        for(j=j0; j<ngrp[grp1]; j++) {
            gj   = molindex[grp1][j];
            if ((iprod(mu[gi],mu[gi]) > 0) && (iprod(mu[gj],mu[gj]) > 0)) {
                /* Compute distance between molecules including PBC */
                pbc_dx(&pbc,xcm[grp0][i],xcm[grp1][j],dx);
                rr = norm(dx);
	
                if (gb->bPhi) {
                    rvec xi,xj,xk,xl;
                    rvec r_ij,r_kj,r_kl,mm,nn;
                    real sign;
                    int  t1,t2,t3;
	  
                    copy_rvec(xcm[grp0][i],xj);
                    copy_rvec(xcm[grp1][j],xk);
                    rvec_add(xj,mu[gi],xi);
                    rvec_add(xk,mu[gj],xl);
                    phi = dih_angle(xi,xj,xk,xl,&pbc,
                                    r_ij,r_kj,r_kl,mm,nn, /* out */
                                    &sign,&t1,&t2,&t3);
                    cosa = cos(phi);
                }
                else {
                    cosa = cos_angle(mu[gi],mu[gj]);
                    phi = 0;
                }
                if (debug || (cosa != cosa))  {
                    fprintf(debug ? debug : stderr,
                            "mu[%d] = %5.2f %5.2f %5.2f |mi| = %5.2f, mu[%d] = %5.2f %5.2f %5.2f |mj| = %5.2f rr = %5.2f cosa = %5.2f\n",
                            gi,mu[gi][XX],mu[gi][YY],mu[gi][ZZ],norm(mu[gi]),
                            gj,mu[gj][XX],mu[gj][YY],mu[gj][ZZ],norm(mu[gj]),
                            rr,cosa);
                }
	
                add2gkr(gb,rr,cosa,phi);
            }
        }
    }
}
예제 #13
0
inline double angle(double *x1, double *x2) {
  return acos(cos_angle(x1, x2));
}
/*
**  Target Detection Subroutine
**
**     contours that are passed in here have similar area to 
**     the targets and have 4 corners
*/
void Detect_Targets( CvSeq *raw_contours, CvMat *input_image )
{
   int i,j;
   float xpt[4], ypt[4], xcenter, ycenter;
   float xmin, xmax, ymin, ymax;
   float length_1, length_2;
   float aspect_ratio;
   float distance;
   float dx1, dy1, dx2, dy2;

   CvPoint *point;
   CvPoint pt1;

   int      isTarget = FALSE;

   xmax = ymax = 0.0;
   xmin = ymin = 1e20;

   float cosine1, cosine2, max_cosine;

   /*
   **
   */
   if ( raw_contours->total == 4 )
   {
      /*
      **  Determine min and max extents
      */
      for ( i = 0; i < raw_contours->total; i++)
      {
         point = CV_GET_SEQ_ELEM( CvPoint, raw_contours, i);

         xpt[i] = (float) point->x;
         ypt[i] = (float) point->y;
         xmin = MIN(xmin, xpt[i]);
         xmax = MAX(xmax, xpt[i]);
         ymin = MIN(ymin, ypt[i]);
         ymax = MAX(ymax, ypt[i]);
      }

      dx1 = fabsf(xpt[0] - xpt[1]);
      dy1 = fabsf(ypt[0] - ypt[1]);
      dx2 = fabsf(xpt[1] - xpt[2]);
      dy2 = fabsf(ypt[1] - ypt[2]);

      length_1 = sqrtf( dx1*dx1 + dy1*dy1 );

      length_2 = sqrtf( dx2*dx2 + dy2*dy2 );

      /*
      **  Look at only horizontal rectangles
      **  If the rectangle is not horizontal, it isn't a target.
      */
      if ( (MAX(dx1,dx2) < MAX(dy1,dy2)) )
      {
         return;
      }



      /*
      **  Calculate the angle of the first corner
      **   if it isn't 90 deg (+- 15 deg) then we don't have
      **   a rectangle and reject
      */
      cosine1 =  fabsf( cos_angle( xpt[0], ypt[0],  
                                  xpt[2], ypt[2],
                                  xpt[1], ypt[1] ) );
      cosine2 =  fabsf( cos_angle( xpt[1], ypt[1],  
                                  xpt[3], ypt[3],
                                  xpt[2], ypt[2] ) );
      max_cosine = MAX( cosine1, cosine2 );
      if ( max_cosine > 0.45 ) {
         return;
      }

      /* 
      **  Calculate aspect ratio
      */
      aspect_ratio = MAX( length_1/length_2, length_2/length_1);

      /*
      **  Calculate center of object
      */
      xcenter = ((xmax - xmin) / 2.0) + xmin;
      ycenter = ((ymax - ymin) / 2.0) + ymin;

      /*  
      **  check for high goal opening (3pt) target.
      **   aspect ratio = 4.5
      */
      if ( ((aspect_ratio > 4.2) && (aspect_ratio < 7.6)) )
      {
         /*
         **  Calculate distance to target
         **    the opening target 3 is 54" wide by 12" tall
         */
         distance = 0.01745 * ((MAX(length_1,length_2) / 640.0) * 48.8) / 2.0;
         distance = (54.0/2.0) / tanf(distance);

         if ( (distance/12.0) < 45 ) /* field is 54 ft long */
         {
            isTarget = TRUE;
            detected_targets[num_detect_targets].type = 3;
            detected_targets[num_detect_targets].distance = distance/12.0;
            pt1.x = xcenter+20;  pt1.y = ycenter;
         }
      }

      /*  
      **  check for high goal outside boundary (3pt) target.
      **    62" by 20"
      **   aspect ratio = 3.1
      */
     if ( ((aspect_ratio >= 2.8) && (aspect_ratio < 3.2)) ) 
      {
//  printf("outside 3 pt boundary detect\n");
         /*
         **  Calculate distance to target
         **    the outside of target 3 is 62"wide by 20" tall
         */
         distance = 0.01745 * ((MAX(length_1,length_2) / 640.0) * 48.8) / 2.0;
         distance = (62.0/2.0) / tanf(distance);

         if ( (distance/12.0) < 45 ) 
         {
            isTarget = TRUE;
            detected_targets[num_detect_targets].type = 3;
            detected_targets[num_detect_targets].distance = distance/12.0;
         }

      }

      /*  
      **  check for middle goal opening (2pt) target.
      **   54" x 21"
      **   aspect ratio = 2.6
      */
      if ( ( (aspect_ratio > 2.4) && (aspect_ratio < 2.8) )  )
//        || ((aspect_ratio >= 2.8) && (aspect_ratio < 3.3)) )
      {
         /*
         **  Calculate distance to target
         **    the opening 2pt target is 54"wide by 21" tall
         */
         distance = 0.01745 * ((MAX(length_1,length_2) / 640.0) * 48.8) / 2.0;
         distance = (54.0/2.0) / tanf(distance);

         if ( (distance/12.0) < 45 ) /* field is 54 ft long */
         {
            isTarget = TRUE;
            detected_targets[num_detect_targets].type = 2;
            detected_targets[num_detect_targets].distance = distance/12.0;
         }
      }

      /*  
      **  check for middle goal border (2pt) target.
      **    62" x 29"
      **   aspect ratio = 2.14
      **    2.27, 2.3, 2.29
      */
      if ( ( (aspect_ratio > 1.8) && (aspect_ratio <= 2.4) )  ) 
      {
         /*
         **  Calculate distance to target
         **    the outside of 2pt target is 62" wide by 29" tall
         */
         distance = 0.01745 * ((MAX(length_1,length_2) / 640.0) * 48.8) / 2.0;
         distance = (62.0/2.0) / tanf(distance);

         if ( (distance/12.0) < 45 ) 
         {
            isTarget = TRUE;
            detected_targets[num_detect_targets].type = 2;
            detected_targets[num_detect_targets].distance = distance/12.0;
         }
      }

      /*
      **  See if we determined that one of the previous conditions
      **   were met, if so (isTarget = TRUE) then save all the 
      **   target information
      */
      if ( isTarget ) 
      {
         detected_targets[num_detect_targets].aspect_ratio = aspect_ratio;
         detected_targets[num_detect_targets].xcenter = xcenter;
         detected_targets[num_detect_targets].ycenter = ycenter;

         detected_targets[num_detect_targets].xmin = xmin;
         detected_targets[num_detect_targets].ymin = ymin;
         detected_targets[num_detect_targets].xmax = xmax;
         detected_targets[num_detect_targets].ymax = ymax;

         detected_targets[num_detect_targets].time_tracked = 1;

         if ( length_1 > length_2 ) {
            detected_targets[num_detect_targets].h_length = length_1;
            detected_targets[num_detect_targets].v_length = length_2;
         } else {
            detected_targets[num_detect_targets].h_length = length_2;
            detected_targets[num_detect_targets].v_length = length_1;
         }

         for ( j = 0; j < 4; j++ ) {
            detected_targets[num_detect_targets].xpt[j] = xpt[j];
            detected_targets[num_detect_targets].ypt[j] = ypt[j];
         }

         detected_targets[num_detect_targets].area = 
             fabsf(cvContourArea( raw_contours, CV_WHOLE_SEQ, 0));
         
         detected_targets[num_detect_targets].h_angle =
              (xcenter - camera_info.h_pixels/2.0) * camera_info.h_ifov;
         detected_targets[num_detect_targets].v_angle =
              (ycenter - camera_info.v_pixels/2.0) * camera_info.v_ifov * -1;
         
         /*
         **  calculate angular size 
         */
         detected_targets[num_detect_targets].h_len_deg = 
            detected_targets[num_detect_targets].h_length * camera_info.h_ifov;
         detected_targets[num_detect_targets].v_len_deg = 
            detected_targets[num_detect_targets].v_length * camera_info.v_ifov;
           
         
         /* draw target center */

//         cross_color = CV_RGB(255,255,255);
//         draw_target_center( detected_targets[num_detect_targets],
//                             image, cross_color );

         if ( num_detect_targets < (MAX_TRACKED_TARGETS -1) )
         {
            num_detect_targets++;
         }  else {

         }

      }

#ifdef GRAPHICS
    if (isTarget) {
      cvDrawContours( input_image, raw_contours, 
                       CV_RGB(255,255,255), CV_RGB(200,255,255), 
                       0, 1, 8, cvPoint(0,0));
    }
#endif

   }

}
예제 #15
0
static void do_ac_core(int nframes,int nout,
		       real corr[],real c1[],int nrestart,
		       unsigned long mode)
{
  int     j,k,j3,jk3,m,n;
  real    ccc,cth;
  rvec    xj,xk,rr;

  if (nrestart < 1) {
    printf("WARNING: setting number of restarts to 1\n");
    nrestart = 1;
  }
  if (debug)
    fprintf(debug,
	    "Starting do_ac_core: nframes=%d, nout=%d, nrestart=%d,mode=%lu\n",
	    nframes,nout,nrestart,mode);
  
  for(j=0; (j<nout); j++)
    corr[j]=0;
  
  /* Loop over starting points. */
  for(j=0; (j<nframes); j+=nrestart) {
    j3  = DIM*j;
    
    /* Loop over the correlation length for this starting point */
    for(k=0; (k<nout) && (j+k < nframes); k++) {
      jk3 = DIM*(j+k);
      
      /* Switch over possible ACF types. 
       * It might be more efficient to put the loops inside the switch,
       * but this is more clear, and save development time!
       */      
      if (MODE(eacNormal)) {
	corr[k] += c1[j]*c1[j+k];
      }
      else if (MODE(eacCos)) {
	/* Compute the cos (phi(t)-phi(t+dt)) */
	corr[k] += cos(c1[j]-c1[j+k]);
      }
      else if (MODE(eacIden)) {
	/* Check equality (phi(t)==phi(t+dt)) */
	corr[k] += (c1[j]==c1[j+k])? 1 : 0;
      }
      else if (MODE(eacP1) || MODE(eacP2) || MODE(eacP3)) {
	for(m=0; (m<DIM); m++) {
	  xj[m] = c1[j3+m];
	  xk[m] = c1[jk3+m];
	}
	cth=cos_angle(xj,xk);
	
	if (cth-1.0 > 1.0e-15) {
	  printf("j: %d, k: %d, xj:(%g,%g,%g), xk:(%g,%g,%g)\n",
		  j,k,xj[XX],xj[YY],xj[ZZ],xk[XX],xk[YY],xk[ZZ]);
	}
	
	corr[k] += LegendreP(cth,mode);  /* 1.5*cth*cth-0.5; */
      }
      else if (MODE(eacRcross)) {
	for(m=0; (m<DIM); m++) {
	  xj[m] = c1[j3+m];
	  xk[m] = c1[jk3+m];
	}
	cprod(xj,xk,rr);
	
	corr[k] += iprod(rr,rr);
      }
      else if (MODE(eacVector)) {
	for(m=0; (m<DIM); m++) {
	  xj[m] = c1[j3+m];
	  xk[m] = c1[jk3+m];
	}
	ccc = iprod(xj,xk);
	
	corr[k] += ccc;
      }
      else
	gmx_fatal(FARGS,"\nInvalid mode (%d) in do_ac_core",mode);
    }
  }
  /* Correct for the number of points and copy results to the data array */
  for(j=0; (j<nout); j++) {
    n = (nframes-j+(nrestart-1))/nrestart;
    c1[j] = corr[j]/n;
  }
}
예제 #16
0
파일: gmx_rms.c 프로젝트: rbharath/gromacs
int gmx_rms(int argc, char *argv[])
{
    const char     *desc[] =
    {
        "[THISMODULE] compares two structures by computing the root mean square",
        "deviation (RMSD), the size-independent [GRK]rho[grk] similarity parameter",
        "([TT]rho[tt]) or the scaled [GRK]rho[grk] ([TT]rhosc[tt]), ",
        "see Maiorov & Crippen, Proteins [BB]22[bb], 273 (1995).",
        "This is selected by [TT]-what[tt].[PAR]"

        "Each structure from a trajectory ([TT]-f[tt]) is compared to a",
        "reference structure. The reference structure",
        "is taken from the structure file ([TT]-s[tt]).[PAR]",

        "With option [TT]-mir[tt] also a comparison with the mirror image of",
        "the reference structure is calculated.",
        "This is useful as a reference for 'significant' values, see",
        "Maiorov & Crippen, Proteins [BB]22[bb], 273 (1995).[PAR]",

        "Option [TT]-prev[tt] produces the comparison with a previous frame",
        "the specified number of frames ago.[PAR]",

        "Option [TT]-m[tt] produces a matrix in [TT].xpm[tt] format of",
        "comparison values of each structure in the trajectory with respect to",
        "each other structure. This file can be visualized with for instance",
        "[TT]xv[tt] and can be converted to postscript with [gmx-xpm2ps].[PAR]",

        "Option [TT]-fit[tt] controls the least-squares fitting of",
        "the structures on top of each other: complete fit (rotation and",
        "translation), translation only, or no fitting at all.[PAR]",

        "Option [TT]-mw[tt] controls whether mass weighting is done or not.",
        "If you select the option (default) and ",
        "supply a valid [TT].tpr[tt] file masses will be taken from there, ",
        "otherwise the masses will be deduced from the [TT]atommass.dat[tt] file in",
        "[TT]GMXLIB[tt]. This is fine for proteins, but not",
        "necessarily for other molecules. A default mass of 12.011 amu (carbon)",
        "is assigned to unknown atoms. You can check whether this happend by",
        "turning on the [TT]-debug[tt] flag and inspecting the log file.[PAR]",

        "With [TT]-f2[tt], the 'other structures' are taken from a second",
        "trajectory, this generates a comparison matrix of one trajectory",
        "versus the other.[PAR]",

        "Option [TT]-bin[tt] does a binary dump of the comparison matrix.[PAR]",

        "Option [TT]-bm[tt] produces a matrix of average bond angle deviations",
        "analogously to the [TT]-m[tt] option. Only bonds between atoms in the",
        "comparison group are considered."
    };
    static gmx_bool bPBC              = TRUE, bFitAll = TRUE, bSplit = FALSE;
    static gmx_bool bDeltaLog         = FALSE;
    static int      prev              = 0, freq = 1, freq2 = 1, nlevels = 80, avl = 0;
    static real     rmsd_user_max     = -1, rmsd_user_min = -1, bond_user_max = -1,
                    bond_user_min     = -1, delta_maxy = 0.0;
    /* strings and things for selecting difference method */
    enum
    {
        ewSel, ewRMSD, ewRho, ewRhoSc, ewNR
    };
    int         ewhat;
    const char *what[ewNR + 1] =
    { NULL, "rmsd", "rho", "rhosc", NULL };
    const char *whatname[ewNR] =
    { NULL, "RMSD", "Rho", "Rho sc" };
    const char *whatlabel[ewNR] =
    { NULL, "RMSD (nm)", "Rho", "Rho sc" };
    const char *whatxvgname[ewNR] =
    { NULL, "RMSD", "\\8r\\4", "\\8r\\4\\ssc\\N" };
    const char *whatxvglabel[ewNR] =
    { NULL, "RMSD (nm)", "\\8r\\4", "\\8r\\4\\ssc\\N" };
    /* strings and things for fitting methods */
    enum
    {
        efSel, efFit, efReset, efNone, efNR
    };
    int             efit;
    const char     *fit[efNR + 1] =
    { NULL, "rot+trans", "translation", "none", NULL };
    const char     *fitgraphlabel[efNR + 1] =
    { NULL, "lsq fit", "translational fit", "no fit" };
    static int      nrms          = 1;
    static gmx_bool bMassWeighted = TRUE;
    t_pargs         pa[]          =
    {
        { "-what", FALSE, etENUM,
          { what }, "Structural difference measure" },
        { "-pbc", FALSE, etBOOL,
          { &bPBC }, "PBC check" },
        { "-fit", FALSE, etENUM,
          { fit }, "Fit to reference structure" },
        { "-prev", FALSE, etINT,
          { &prev }, "Compare with previous frame" },
        { "-split", FALSE, etBOOL,
          { &bSplit }, "Split graph where time is zero" },
        { "-fitall", FALSE, etBOOL,
          { &bFitAll }, "HIDDENFit all pairs of structures in matrix" },
        { "-skip", FALSE, etINT,
          { &freq }, "Only write every nr-th frame to matrix" },
        { "-skip2", FALSE, etINT,
          { &freq2 }, "Only write every nr-th frame to matrix" },
        { "-max", FALSE, etREAL,
          { &rmsd_user_max }, "Maximum level in comparison matrix" },
        { "-min", FALSE, etREAL,
          { &rmsd_user_min }, "Minimum level in comparison matrix" },
        { "-bmax", FALSE, etREAL,
          { &bond_user_max }, "Maximum level in bond angle matrix" },
        { "-bmin", FALSE, etREAL,
          { &bond_user_min }, "Minimum level in bond angle matrix" },
        { "-mw", FALSE, etBOOL,
          { &bMassWeighted }, "Use mass weighting for superposition" },
        { "-nlevels", FALSE, etINT,
          { &nlevels }, "Number of levels in the matrices" },
        { "-ng", FALSE, etINT,
          { &nrms }, "Number of groups to compute RMS between" },
        { "-dlog", FALSE, etBOOL,
          { &bDeltaLog },
          "HIDDENUse a log x-axis in the delta t matrix" },
        { "-dmax", FALSE, etREAL,
          { &delta_maxy }, "HIDDENMaximum level in delta matrix" },
        { "-aver", FALSE, etINT,
          { &avl },
          "HIDDENAverage over this distance in the RMSD matrix" }
    };
    int             natoms_trx, natoms_trx2, natoms;
    int             i, j, k, m, teller, teller2, tel_mat, tel_mat2;
#define NFRAME 5000
    int             maxframe = NFRAME, maxframe2 = NFRAME;
    real            t, *w_rls, *w_rms, *w_rls_m = NULL, *w_rms_m = NULL;
    gmx_bool        bNorm, bAv, bFreq2, bFile2, bMat, bBond, bDelta, bMirror, bMass;
    gmx_bool        bFit, bReset;
    t_topology      top;
    int             ePBC;
    t_iatom        *iatom = NULL;

    matrix          box;
    rvec           *x, *xp, *xm = NULL, **mat_x = NULL, **mat_x2, *mat_x2_j = NULL, vec1,
                    vec2;
    t_trxstatus    *status;
    char            buf[256], buf2[256];
    int             ncons = 0;
    FILE           *fp;
    real            rlstot = 0, **rls, **rlsm = NULL, *time, *time2, *rlsnorm = NULL,
    **rmsd_mat             = NULL, **bond_mat = NULL, *axis, *axis2, *del_xaxis,
    *del_yaxis, rmsd_max, rmsd_min, rmsd_avg, bond_max, bond_min, ang;
    real       **rmsdav_mat = NULL, av_tot, weight, weight_tot;
    real       **delta      = NULL, delta_max, delta_scalex = 0, delta_scaley = 0,
    *delta_tot;
    int          delta_xsize = 0, del_lev = 100, mx, my, abs_my;
    gmx_bool     bA1, bA2, bPrev, bTop, *bInMat = NULL;
    int          ifit, *irms, ibond = 0, *ind_bond1 = NULL, *ind_bond2 = NULL, n_ind_m =
        0;
    atom_id     *ind_fit, **ind_rms, *ind_m = NULL, *rev_ind_m = NULL, *ind_rms_m =
        NULL;
    char        *gn_fit, **gn_rms;
    t_rgb        rlo, rhi;
    output_env_t oenv;
    gmx_rmpbc_t  gpbc = NULL;

    t_filenm     fnm[] =
    {
        { efTPS, NULL, NULL, ffREAD },
        { efTRX, "-f", NULL, ffREAD },
        { efTRX, "-f2", NULL, ffOPTRD },
        { efNDX, NULL, NULL, ffOPTRD },
        { efXVG, NULL, "rmsd", ffWRITE },
        { efXVG, "-mir", "rmsdmir", ffOPTWR },
        { efXVG, "-a", "avgrp", ffOPTWR },
        { efXVG, "-dist", "rmsd-dist", ffOPTWR },
        { efXPM, "-m", "rmsd", ffOPTWR },
        { efDAT, "-bin", "rmsd", ffOPTWR },
        { efXPM, "-bm", "bond", ffOPTWR }
    };
#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW
                           | PCA_BE_NICE, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL,
                           &oenv))
    {
        return 0;
    }
    /* parse enumerated options: */
    ewhat = nenum(what);
    if (ewhat == ewRho || ewhat == ewRhoSc)
    {
        please_cite(stdout, "Maiorov95");
    }
    efit   = nenum(fit);
    bFit   = efit == efFit;
    bReset = efit == efReset;
    if (bFit)
    {
        bReset = TRUE; /* for fit, reset *must* be set */
    }
    else
    {
        bFitAll = FALSE;
    }

    /* mark active cmdline options */
    bMirror = opt2bSet("-mir", NFILE, fnm); /* calc RMSD vs mirror of ref. */
    bFile2  = opt2bSet("-f2", NFILE, fnm);
    bMat    = opt2bSet("-m", NFILE, fnm);
    bBond   = opt2bSet("-bm", NFILE, fnm);
    bDelta  = (delta_maxy > 0); /* calculate rmsd vs delta t matrix from *
                                 *	your RMSD matrix (hidden option       */
    bNorm   = opt2bSet("-a", NFILE, fnm);
    bFreq2  = opt2parg_bSet("-skip2", asize(pa), pa);
    if (freq <= 0)
    {
        fprintf(stderr, "The number of frames to skip is <= 0. "
                "Writing out all frames.\n\n");
        freq = 1;
    }
    if (!bFreq2)
    {
        freq2 = freq;
    }
    else if (bFile2 && freq2 <= 0)
    {
        fprintf(stderr,
                "The number of frames to skip in second trajectory is <= 0.\n"
                "  Writing out all frames.\n\n");
        freq2 = 1;
    }

    bPrev = (prev > 0);
    if (bPrev)
    {
        prev = abs(prev);
        if (freq != 1)
        {
            fprintf(stderr, "WARNING: option -skip also applies to -prev\n");
        }
    }

    if (bFile2 && !bMat && !bBond)
    {
        fprintf(
                stderr,
                "WARNING: second trajectory (-f2) useless when not calculating matrix (-m/-bm),\n"
                "         will not read from %s\n", opt2fn("-f2", NFILE,
                                                           fnm));
        bFile2 = FALSE;
    }

    if (bDelta)
    {
        bMat = TRUE;
        if (bFile2)
        {
            fprintf(stderr,
                    "WARNING: second trajectory (-f2) useless when making delta matrix,\n"
                    "         will not read from %s\n", opt2fn("-f2",
                                                               NFILE, fnm));
            bFile2 = FALSE;
        }
    }

    bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), buf, &top, &ePBC, &xp,
                         NULL, box, TRUE);
    snew(w_rls, top.atoms.nr);
    snew(w_rms, top.atoms.nr);

    if (!bTop && bBond)
    {
        fprintf(stderr,
                "WARNING: Need a run input file for bond angle matrix,\n"
                "         will not calculate bond angle matrix.\n");
        bBond = FALSE;
    }

    if (bReset)
    {
        fprintf(stderr, "Select group for %s fit\n", bFit ? "least squares"
                : "translational");
        get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm), 1, &ifit,
                  &ind_fit, &gn_fit);
    }
    else
    {
        ifit = 0;
    }

    if (bReset)
    {
        if (bFit && ifit < 3)
        {
            gmx_fatal(FARGS, "Need >= 3 points to fit!\n" );
        }

        bMass = FALSE;
        for (i = 0; i < ifit; i++)
        {
            if (bMassWeighted)
            {
                w_rls[ind_fit[i]] = top.atoms.atom[ind_fit[i]].m;
            }
            else
            {
                w_rls[ind_fit[i]] = 1;
            }
            bMass = bMass || (top.atoms.atom[ind_fit[i]].m != 0);
        }
        if (!bMass)
        {
            fprintf(stderr, "All masses in the fit group are 0, using masses of 1\n");
            for (i = 0; i < ifit; i++)
            {
                w_rls[ind_fit[i]] = 1;
            }
        }
    }

    if (bMat || bBond)
    {
        nrms = 1;
    }

    snew(gn_rms, nrms);
    snew(ind_rms, nrms);
    snew(irms, nrms);

    fprintf(stderr, "Select group%s for %s calculation\n",
            (nrms > 1) ? "s" : "", whatname[ewhat]);
    get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm),
              nrms, irms, ind_rms, gn_rms);

    if (bNorm)
    {
        snew(rlsnorm, irms[0]);
    }
    snew(rls, nrms);
    for (j = 0; j < nrms; j++)
    {
        snew(rls[j], maxframe);
    }
    if (bMirror)
    {
        snew(rlsm, nrms);
        for (j = 0; j < nrms; j++)
        {
            snew(rlsm[j], maxframe);
        }
    }
    snew(time, maxframe);
    for (j = 0; j < nrms; j++)
    {
        bMass = FALSE;
        for (i = 0; i < irms[j]; i++)
        {
            if (bMassWeighted)
            {
                w_rms[ind_rms[j][i]] = top.atoms.atom[ind_rms[j][i]].m;
            }
            else
            {
                w_rms[ind_rms[j][i]] = 1.0;
            }
            bMass = bMass || (top.atoms.atom[ind_rms[j][i]].m != 0);
        }
        if (!bMass)
        {
            fprintf(stderr, "All masses in group %d are 0, using masses of 1\n", j);
            for (i = 0; i < irms[j]; i++)
            {
                w_rms[ind_rms[j][i]] = 1;
            }
        }
    }
    /* Prepare reference frame */
    if (bPBC)
    {
        gpbc = gmx_rmpbc_init(&top.idef, ePBC, top.atoms.nr);
        gmx_rmpbc(gpbc, top.atoms.nr, box, xp);
    }
    if (bReset)
    {
        reset_x(ifit, ind_fit, top.atoms.nr, NULL, xp, w_rls);
    }
    if (bMirror)
    {
        /* generate reference structure mirror image: */
        snew(xm, top.atoms.nr);
        for (i = 0; i < top.atoms.nr; i++)
        {
            copy_rvec(xp[i], xm[i]);
            xm[i][XX] = -xm[i][XX];
        }
    }
    if (ewhat == ewRhoSc)
    {
        norm_princ(&top.atoms, ifit, ind_fit, top.atoms.nr, xp);
    }

    /* read first frame */
    natoms_trx = read_first_x(oenv, &status, opt2fn("-f", NFILE, fnm), &t, &x, box);
    if (natoms_trx != top.atoms.nr)
    {
        fprintf(stderr,
                "\nWARNING: topology has %d atoms, whereas trajectory has %d\n",
                top.atoms.nr, natoms_trx);
    }
    natoms = min(top.atoms.nr, natoms_trx);
    if (bMat || bBond || bPrev)
    {
        snew(mat_x, NFRAME);

        if (bPrev)
        {
            /* With -prev we use all atoms for simplicity */
            n_ind_m = natoms;
        }
        else
        {
            /* Check which atoms we need (fit/rms) */
            snew(bInMat, natoms);
            for (i = 0; i < ifit; i++)
            {
                bInMat[ind_fit[i]] = TRUE;
            }
            n_ind_m = ifit;
            for (i = 0; i < irms[0]; i++)
            {
                if (!bInMat[ind_rms[0][i]])
                {
                    bInMat[ind_rms[0][i]] = TRUE;
                    n_ind_m++;
                }
            }
        }
        /* Make an index of needed atoms */
        snew(ind_m, n_ind_m);
        snew(rev_ind_m, natoms);
        j = 0;
        for (i = 0; i < natoms; i++)
        {
            if (bPrev || bInMat[i])
            {
                ind_m[j]     = i;
                rev_ind_m[i] = j;
                j++;
            }
        }
        snew(w_rls_m, n_ind_m);
        snew(ind_rms_m, irms[0]);
        snew(w_rms_m, n_ind_m);
        for (i = 0; i < ifit; i++)
        {
            w_rls_m[rev_ind_m[ind_fit[i]]] = w_rls[ind_fit[i]];
        }
        for (i = 0; i < irms[0]; i++)
        {
            ind_rms_m[i]          = rev_ind_m[ind_rms[0][i]];
            w_rms_m[ind_rms_m[i]] = w_rms[ind_rms[0][i]];
        }
        sfree(bInMat);
    }

    if (bBond)
    {
        ncons = 0;
        for (k = 0; k < F_NRE; k++)
        {
            if (IS_CHEMBOND(k))
            {
                iatom  = top.idef.il[k].iatoms;
                ncons += top.idef.il[k].nr/3;
            }
        }
        fprintf(stderr, "Found %d bonds in topology\n", ncons);
        snew(ind_bond1, ncons);
        snew(ind_bond2, ncons);
        ibond = 0;
        for (k = 0; k < F_NRE; k++)
        {
            if (IS_CHEMBOND(k))
            {
                iatom = top.idef.il[k].iatoms;
                ncons = top.idef.il[k].nr/3;
                for (i = 0; i < ncons; i++)
                {
                    bA1 = FALSE;
                    bA2 = FALSE;
                    for (j = 0; j < irms[0]; j++)
                    {
                        if (iatom[3*i+1] == ind_rms[0][j])
                        {
                            bA1 = TRUE;
                        }
                        if (iatom[3*i+2] == ind_rms[0][j])
                        {
                            bA2 = TRUE;
                        }
                    }
                    if (bA1 && bA2)
                    {
                        ind_bond1[ibond] = rev_ind_m[iatom[3*i+1]];
                        ind_bond2[ibond] = rev_ind_m[iatom[3*i+2]];
                        ibond++;
                    }
                }
            }
        }
        fprintf(stderr, "Using %d bonds for bond angle matrix\n", ibond);
        if (ibond == 0)
        {
            gmx_fatal(FARGS, "0 bonds found");
        }
    }

    /* start looping over frames: */
    tel_mat = 0;
    teller  = 0;
    do
    {
        if (bPBC)
        {
            gmx_rmpbc(gpbc, natoms, box, x);
        }

        if (bReset)
        {
            reset_x(ifit, ind_fit, natoms, NULL, x, w_rls);
        }
        if (ewhat == ewRhoSc)
        {
            norm_princ(&top.atoms, ifit, ind_fit, natoms, x);
        }

        if (bFit)
        {
            /*do the least squares fit to original structure*/
            do_fit(natoms, w_rls, xp, x);
        }

        if (teller % freq == 0)
        {
            /* keep frame for matrix calculation */
            if (bMat || bBond || bPrev)
            {
                if (tel_mat >= NFRAME)
                {
                    srenew(mat_x, tel_mat+1);
                }
                snew(mat_x[tel_mat], n_ind_m);
                for (i = 0; i < n_ind_m; i++)
                {
                    copy_rvec(x[ind_m[i]], mat_x[tel_mat][i]);
                }
            }
            tel_mat++;
        }

        /*calculate energy of root_least_squares*/
        if (bPrev)
        {
            j = tel_mat-prev-1;
            if (j < 0)
            {
                j = 0;
            }
            for (i = 0; i < n_ind_m; i++)
            {
                copy_rvec(mat_x[j][i], xp[ind_m[i]]);
            }
            if (bReset)
            {
                reset_x(ifit, ind_fit, natoms, NULL, xp, w_rls);
            }
            if (bFit)
            {
                do_fit(natoms, w_rls, x, xp);
            }
        }
        for (j = 0; (j < nrms); j++)
        {
            rls[j][teller] =
                calc_similar_ind(ewhat != ewRMSD, irms[j], ind_rms[j], w_rms, x, xp);
        }
        if (bNorm)
        {
            for (j = 0; (j < irms[0]); j++)
            {
                rlsnorm[j] +=
                    calc_similar_ind(ewhat != ewRMSD, 1, &(ind_rms[0][j]), w_rms, x, xp);
            }
        }

        if (bMirror)
        {
            if (bFit)
            {
                /*do the least squares fit to mirror of original structure*/
                do_fit(natoms, w_rls, xm, x);
            }

            for (j = 0; j < nrms; j++)
            {
                rlsm[j][teller] =
                    calc_similar_ind(ewhat != ewRMSD, irms[j], ind_rms[j], w_rms, x, xm);
            }
        }
        time[teller] = output_env_conv_time(oenv, t);

        teller++;
        if (teller >= maxframe)
        {
            maxframe += NFRAME;
            srenew(time, maxframe);
            for (j = 0; (j < nrms); j++)
            {
                srenew(rls[j], maxframe);
            }
            if (bMirror)
            {
                for (j = 0; (j < nrms); j++)
                {
                    srenew(rlsm[j], maxframe);
                }
            }
        }
    }
    while (read_next_x(oenv, status, &t, x, box));
    close_trj(status);

    if (bFile2)
    {
        snew(time2, maxframe2);

        fprintf(stderr, "\nWill read second trajectory file\n");
        snew(mat_x2, NFRAME);
        natoms_trx2 =
            read_first_x(oenv, &status, opt2fn("-f2", NFILE, fnm), &t, &x, box);
        if (natoms_trx2 != natoms_trx)
        {
            gmx_fatal(FARGS,
                      "Second trajectory (%d atoms) does not match the first one"
                      " (%d atoms)", natoms_trx2, natoms_trx);
        }
        tel_mat2 = 0;
        teller2  = 0;
        do
        {
            if (bPBC)
            {
                gmx_rmpbc(gpbc, natoms, box, x);
            }

            if (bReset)
            {
                reset_x(ifit, ind_fit, natoms, NULL, x, w_rls);
            }
            if (ewhat == ewRhoSc)
            {
                norm_princ(&top.atoms, ifit, ind_fit, natoms, x);
            }

            if (bFit)
            {
                /*do the least squares fit to original structure*/
                do_fit(natoms, w_rls, xp, x);
            }

            if (teller2 % freq2 == 0)
            {
                /* keep frame for matrix calculation */
                if (bMat)
                {
                    if (tel_mat2 >= NFRAME)
                    {
                        srenew(mat_x2, tel_mat2+1);
                    }
                    snew(mat_x2[tel_mat2], n_ind_m);
                    for (i = 0; i < n_ind_m; i++)
                    {
                        copy_rvec(x[ind_m[i]], mat_x2[tel_mat2][i]);
                    }
                }
                tel_mat2++;
            }

            time2[teller2] = output_env_conv_time(oenv, t);

            teller2++;
            if (teller2 >= maxframe2)
            {
                maxframe2 += NFRAME;
                srenew(time2, maxframe2);
            }
        }
        while (read_next_x(oenv, status, &t, x, box));
        close_trj(status);
    }
    else
    {
        mat_x2   = mat_x;
        time2    = time;
        tel_mat2 = tel_mat;
        freq2    = freq;
    }
    gmx_rmpbc_done(gpbc);

    if (bMat || bBond)
    {
        /* calculate RMS matrix */
        fprintf(stderr, "\n");
        if (bMat)
        {
            fprintf(stderr, "Building %s matrix, %dx%d elements\n",
                    whatname[ewhat], tel_mat, tel_mat2);
            snew(rmsd_mat, tel_mat);
        }
        if (bBond)
        {
            fprintf(stderr, "Building bond angle matrix, %dx%d elements\n",
                    tel_mat, tel_mat2);
            snew(bond_mat, tel_mat);
        }
        snew(axis, tel_mat);
        snew(axis2, tel_mat2);
        rmsd_max = 0;
        if (bFile2)
        {
            rmsd_min = 1e10;
        }
        else
        {
            rmsd_min = 0;
        }
        rmsd_avg = 0;
        bond_max = 0;
        bond_min = 1e10;
        for (j = 0; j < tel_mat2; j++)
        {
            axis2[j] = time2[freq2*j];
        }
        if (bDelta)
        {
            if (bDeltaLog)
            {
                delta_scalex = 8.0/log(2.0);
                delta_xsize  = (int)(log(tel_mat/2)*delta_scalex+0.5)+1;
            }
            else
            {
                delta_xsize = tel_mat/2;
            }
            delta_scaley = 1.0/delta_maxy;
            snew(delta, delta_xsize);
            for (j = 0; j < delta_xsize; j++)
            {
                snew(delta[j], del_lev+1);
            }
            if (avl > 0)
            {
                snew(rmsdav_mat, tel_mat);
                for (j = 0; j < tel_mat; j++)
                {
                    snew(rmsdav_mat[j], tel_mat);
                }
            }
        }

        if (bFitAll)
        {
            snew(mat_x2_j, natoms);
        }
        for (i = 0; i < tel_mat; i++)
        {
            axis[i] = time[freq*i];
            fprintf(stderr, "\r element %5d; time %5.2f  ", i, axis[i]);
            if (bMat)
            {
                snew(rmsd_mat[i], tel_mat2);
            }
            if (bBond)
            {
                snew(bond_mat[i], tel_mat2);
            }
            for (j = 0; j < tel_mat2; j++)
            {
                if (bFitAll)
                {
                    for (k = 0; k < n_ind_m; k++)
                    {
                        copy_rvec(mat_x2[j][k], mat_x2_j[k]);
                    }
                    do_fit(n_ind_m, w_rls_m, mat_x[i], mat_x2_j);
                }
                else
                {
                    mat_x2_j = mat_x2[j];
                }
                if (bMat)
                {
                    if (bFile2 || (i < j))
                    {
                        rmsd_mat[i][j] =
                            calc_similar_ind(ewhat != ewRMSD, irms[0], ind_rms_m,
                                             w_rms_m, mat_x[i], mat_x2_j);
                        if (rmsd_mat[i][j] > rmsd_max)
                        {
                            rmsd_max = rmsd_mat[i][j];
                        }
                        if (rmsd_mat[i][j] < rmsd_min)
                        {
                            rmsd_min = rmsd_mat[i][j];
                        }
                        rmsd_avg += rmsd_mat[i][j];
                    }
                    else
                    {
                        rmsd_mat[i][j] = rmsd_mat[j][i];
                    }
                }
                if (bBond)
                {
                    if (bFile2 || (i <= j))
                    {
                        ang = 0.0;
                        for (m = 0; m < ibond; m++)
                        {
                            rvec_sub(mat_x[i][ind_bond1[m]], mat_x[i][ind_bond2[m]], vec1);
                            rvec_sub(mat_x2_j[ind_bond1[m]], mat_x2_j[ind_bond2[m]], vec2);
                            ang += acos(cos_angle(vec1, vec2));
                        }
                        bond_mat[i][j] = ang*180.0/(M_PI*ibond);
                        if (bond_mat[i][j] > bond_max)
                        {
                            bond_max = bond_mat[i][j];
                        }
                        if (bond_mat[i][j] < bond_min)
                        {
                            bond_min = bond_mat[i][j];
                        }
                    }
                    else
                    {
                        bond_mat[i][j] = bond_mat[j][i];
                    }
                }
            }
        }
        if (bFile2)
        {
            rmsd_avg /= tel_mat*tel_mat2;
        }
        else
        {
            rmsd_avg /= tel_mat*(tel_mat - 1)/2;
        }
        if (bMat && (avl > 0))
        {
            rmsd_max = 0.0;
            rmsd_min = 0.0;
            rmsd_avg = 0.0;
            for (j = 0; j < tel_mat-1; j++)
            {
                for (i = j+1; i < tel_mat; i++)
                {
                    av_tot     = 0;
                    weight_tot = 0;
                    for (my = -avl; my <= avl; my++)
                    {
                        if ((j+my >= 0) && (j+my < tel_mat))
                        {
                            abs_my = abs(my);
                            for (mx = -avl; mx <= avl; mx++)
                            {
                                if ((i+mx >= 0) && (i+mx < tel_mat))
                                {
                                    weight      = (real)(avl+1-max(abs(mx), abs_my));
                                    av_tot     += weight*rmsd_mat[i+mx][j+my];
                                    weight_tot += weight;
                                }
                            }
                        }
                    }
                    rmsdav_mat[i][j] = av_tot/weight_tot;
                    rmsdav_mat[j][i] = rmsdav_mat[i][j];
                    if (rmsdav_mat[i][j] > rmsd_max)
                    {
                        rmsd_max = rmsdav_mat[i][j];
                    }
                }
            }
            rmsd_mat = rmsdav_mat;
        }

        if (bMat)
        {
            fprintf(stderr, "\n%s: Min %f, Max %f, Avg %f\n",
                    whatname[ewhat], rmsd_min, rmsd_max, rmsd_avg);
            rlo.r = 1; rlo.g = 1; rlo.b = 1;
            rhi.r = 0; rhi.g = 0; rhi.b = 0;
            if (rmsd_user_max != -1)
            {
                rmsd_max = rmsd_user_max;
            }
            if (rmsd_user_min != -1)
            {
                rmsd_min = rmsd_user_min;
            }
            if ((rmsd_user_max !=  -1) || (rmsd_user_min != -1))
            {
                fprintf(stderr, "Min and Max value set to resp. %f and %f\n",
                        rmsd_min, rmsd_max);
            }
            sprintf(buf, "%s %s matrix", gn_rms[0], whatname[ewhat]);
            write_xpm(opt2FILE("-m", NFILE, fnm, "w"), 0, buf, whatlabel[ewhat],
                      output_env_get_time_label(oenv), output_env_get_time_label(oenv), tel_mat, tel_mat2,
                      axis, axis2, rmsd_mat, rmsd_min, rmsd_max, rlo, rhi, &nlevels);
            /* Print the distribution of RMSD values */
            if (opt2bSet("-dist", NFILE, fnm))
            {
                low_rmsd_dist(opt2fn("-dist", NFILE, fnm), rmsd_max, tel_mat, rmsd_mat, oenv);
            }

            if (bDelta)
            {
                snew(delta_tot, delta_xsize);
                for (j = 0; j < tel_mat-1; j++)
                {
                    for (i = j+1; i < tel_mat; i++)
                    {
                        mx = i-j;
                        if (mx < tel_mat/2)
                        {
                            if (bDeltaLog)
                            {
                                mx = (int)(log(mx)*delta_scalex+0.5);
                            }
                            my             = (int)(rmsd_mat[i][j]*delta_scaley*del_lev+0.5);
                            delta_tot[mx] += 1.0;
                            if ((rmsd_mat[i][j] >= 0) && (rmsd_mat[i][j] <= delta_maxy))
                            {
                                delta[mx][my] += 1.0;
                            }
                        }
                    }
                }
                delta_max = 0;
                for (i = 0; i < delta_xsize; i++)
                {
                    if (delta_tot[i] > 0.0)
                    {
                        delta_tot[i] = 1.0/delta_tot[i];
                        for (j = 0; j <= del_lev; j++)
                        {
                            delta[i][j] *= delta_tot[i];
                            if (delta[i][j] > delta_max)
                            {
                                delta_max = delta[i][j];
                            }
                        }
                    }
                }
                fprintf(stderr, "Maximum in delta matrix: %f\n", delta_max);
                snew(del_xaxis, delta_xsize);
                snew(del_yaxis, del_lev+1);
                for (i = 0; i < delta_xsize; i++)
                {
                    del_xaxis[i] = axis[i]-axis[0];
                }
                for (i = 0; i < del_lev+1; i++)
                {
                    del_yaxis[i] = delta_maxy*i/del_lev;
                }
                sprintf(buf, "%s %s vs. delta t", gn_rms[0], whatname[ewhat]);
                fp = gmx_ffopen("delta.xpm", "w");
                write_xpm(fp, 0, buf, "density", output_env_get_time_label(oenv), whatlabel[ewhat],
                          delta_xsize, del_lev+1, del_xaxis, del_yaxis,
                          delta, 0.0, delta_max, rlo, rhi, &nlevels);
                gmx_ffclose(fp);
            }
            if (opt2bSet("-bin", NFILE, fnm))
            {
                /* NB: File must be binary if we use fwrite */
                fp = ftp2FILE(efDAT, NFILE, fnm, "wb");
                for (i = 0; i < tel_mat; i++)
                {
                    if (fwrite(rmsd_mat[i], sizeof(**rmsd_mat), tel_mat2, fp) != tel_mat2)
                    {
                        gmx_fatal(FARGS, "Error writing to output file");
                    }
                }
                gmx_ffclose(fp);
            }
        }
        if (bBond)
        {
            fprintf(stderr, "\nMin. angle: %f, Max. angle: %f\n", bond_min, bond_max);
            if (bond_user_max != -1)
            {
                bond_max = bond_user_max;
            }
            if (bond_user_min != -1)
            {
                bond_min = bond_user_min;
            }
            if ((bond_user_max !=  -1) || (bond_user_min != -1))
            {
                fprintf(stderr, "Bond angle Min and Max set to:\n"
                        "Min. angle: %f, Max. angle: %f\n", bond_min, bond_max);
            }
            rlo.r = 1; rlo.g = 1; rlo.b = 1;
            rhi.r = 0; rhi.g = 0; rhi.b = 0;
            sprintf(buf, "%s av. bond angle deviation", gn_rms[0]);
            write_xpm(opt2FILE("-bm", NFILE, fnm, "w"), 0, buf, "degrees",
                      output_env_get_time_label(oenv), output_env_get_time_label(oenv), tel_mat, tel_mat2,
                      axis, axis2, bond_mat, bond_min, bond_max, rlo, rhi, &nlevels);
        }
    }

    bAv = opt2bSet("-a", NFILE, fnm);

    /* Write the RMSD's to file */
    if (!bPrev)
    {
        sprintf(buf, "%s", whatxvgname[ewhat]);
    }
    else
    {
        sprintf(buf, "%s with frame %g %s ago", whatxvgname[ewhat],
                time[prev*freq]-time[0], output_env_get_time_label(oenv));
    }
    fp = xvgropen(opt2fn("-o", NFILE, fnm), buf, output_env_get_xvgr_tlabel(oenv),
                  whatxvglabel[ewhat], oenv);
    if (output_env_get_print_xvgr_codes(oenv))
    {
        fprintf(fp, "@ subtitle \"%s%s after %s%s%s\"\n",
                (nrms == 1) ? "" : "of ", gn_rms[0], fitgraphlabel[efit],
                bFit     ? " to " : "", bFit ? gn_fit : "");
    }
    if (nrms != 1)
    {
        xvgr_legend(fp, nrms, (const char**)gn_rms, oenv);
    }
    for (i = 0; (i < teller); i++)
    {
        if (bSplit && i > 0 &&
            abs(time[bPrev ? freq*i : i]/output_env_get_time_factor(oenv)) < 1e-5)
        {
            fprintf(fp, "&\n");
        }
        fprintf(fp, "%12.7f", time[bPrev ? freq*i : i]);
        for (j = 0; (j < nrms); j++)
        {
            fprintf(fp, " %12.7f", rls[j][i]);
            if (bAv)
            {
                rlstot += rls[j][i];
            }
        }
        fprintf(fp, "\n");
    }
    gmx_ffclose(fp);

    if (bMirror)
    {
        /* Write the mirror RMSD's to file */
        sprintf(buf, "%s with Mirror", whatxvgname[ewhat]);
        sprintf(buf2, "Mirror %s", whatxvglabel[ewhat]);
        fp = xvgropen(opt2fn("-mir", NFILE, fnm), buf, output_env_get_xvgr_tlabel(oenv),
                      buf2, oenv);
        if (nrms == 1)
        {
            if (output_env_get_print_xvgr_codes(oenv))
            {
                fprintf(fp, "@ subtitle \"of %s after lsq fit to mirror of %s\"\n",
                        gn_rms[0], gn_fit);
            }
        }
        else
        {
            if (output_env_get_print_xvgr_codes(oenv))
            {
                fprintf(fp, "@ subtitle \"after lsq fit to mirror %s\"\n", gn_fit);
            }
            xvgr_legend(fp, nrms, (const char**)gn_rms, oenv);
        }
        for (i = 0; (i < teller); i++)
        {
            if (bSplit && i > 0 && abs(time[i]) < 1e-5)
            {
                fprintf(fp, "&\n");
            }
            fprintf(fp, "%12.7f", time[i]);
            for (j = 0; (j < nrms); j++)
            {
                fprintf(fp, " %12.7f", rlsm[j][i]);
            }
            fprintf(fp, "\n");
        }
        gmx_ffclose(fp);
    }

    if (bAv)
    {
        sprintf(buf, "Average %s", whatxvgname[ewhat]);
        sprintf(buf2, "Average %s", whatxvglabel[ewhat]);
        fp = xvgropen(opt2fn("-a", NFILE, fnm), buf, "Residue", buf2, oenv);
        for (j = 0; (j < nrms); j++)
        {
            fprintf(fp, "%10d  %10g\n", j, rlstot/teller);
        }
        gmx_ffclose(fp);
    }

    if (bNorm)
    {
        fp = xvgropen("aver.xvg", gn_rms[0], "Residue", whatxvglabel[ewhat], oenv);
        for (j = 0; (j < irms[0]); j++)
        {
            fprintf(fp, "%10d  %10g\n", j, rlsnorm[j]/teller);
        }
        gmx_ffclose(fp);
    }
    do_view(oenv, opt2fn_null("-a", NFILE, fnm), "-graphtype bar");
    do_view(oenv, opt2fn("-o", NFILE, fnm), NULL);
    do_view(oenv, opt2fn_null("-mir", NFILE, fnm), NULL);
    do_view(oenv, opt2fn_null("-m", NFILE, fnm), NULL);
    do_view(oenv, opt2fn_null("-bm", NFILE, fnm), NULL);
    do_view(oenv, opt2fn_null("-dist", NFILE, fnm), NULL);

    return 0;
}
예제 #17
0
/* calculate the angle and distance between the two groups */
static void calc_angle(int ePBC,matrix box,rvec x[], atom_id index1[], 
		       atom_id index2[], int gnx1, int gnx2,
		       real *angle,      real *distance, 
		       real *distance1,  real *distance2)

/* distance is distance between centers, distance 1 between center of plane
   and atom one of vector, distance 2 same for atom two
*/

{
  rvec 
    normal1,normal2,  	/* normals on planes of interest */
    center1,center2,  	/* center of triangle of points given to define plane,*/
                      	/* or center of vector if a vector is given */
    h1,h2,h3,h4,h5;  	/* temp. vectors */
  t_pbc pbc;

  set_pbc(&pbc,ePBC,box);

  switch(gnx1)
    {
    case 3:           /* group 1 defines plane */
      calculate_normal(index1,x,normal1,center1);
      break;
    case 2:           /* group 1 defines vector */
      rvec_sub(x[index1[0]],x[index1[1]],normal1);
      rvec_add(x[index1[0]],x[index1[1]],h1);
      svmul(0.5,h1,center1);  /* center is geometric mean */
      break;
    default:          /* group 1 does none of the above */
      gmx_fatal(FARGS,"Something wrong with contents of index file.\n");
    }

  switch(gnx2)
    {
    case 3:          /* group 2 defines plane */
      calculate_normal(index2,x,normal2,center2);
      break;
    case 2:          /* group 2 defines vector */
      rvec_sub(x[index2[0]],x[index2[1]],normal2);
      rvec_add(x[index2[0]],x[index2[1]],h2);
      svmul(0.5,h2,center2);  /* center is geometric mean */
      break;
    case 0:
      normal2[XX] = 0;
      normal2[YY] = 0;
      normal2[ZZ] = 1;
      center2[XX] = 0;
      center2[YY] = 0;
      center2[ZZ] = 0;
      break;
    default:         /* group 2 does none of the above */
      gmx_fatal(FARGS,"Something wrong with contents of index file.\n");
    }
  
  *angle = cos_angle(normal1,normal2);

  if (box)
    pbc_dx(&pbc,center1,center2,h3);
  else
    rvec_sub(center1,center2,h3); 
  *distance = norm(h3);

  if (gnx1 == 3 && gnx2 == 2) {
    if (box) {
      pbc_dx(&pbc,center1,x[index2[0]],h4);
      pbc_dx(&pbc,center1,x[index2[1]],h5);
    } else {
      rvec_sub(center1,x[index2[0]],h4);
      rvec_sub(center1,x[index2[1]],h5);
    }
    *distance1 = norm(h4);
    *distance2 = norm(h5);
  }
  else if (gnx1 == 2 && gnx2 ==3) {
    rvec_sub(center1,x[index1[0]],h4);
    rvec_sub(center1,x[index1[1]],h5);
    *distance1 = norm(h4);
    *distance2 = norm(h5);
  }
  else {
    *distance1 = 0; *distance2 = 0;
  } 
}
예제 #18
0
int gmx_helixorient(int argc, char *argv[])
{
    const char       *desc[] = {
        "[THISMODULE] calculates the coordinates and direction of the average",
        "axis inside an alpha helix, and the direction/vectors of both the",
        "C[GRK]alpha[grk] and (optionally) a sidechain atom relative to the axis.[PAR]",
        "As input, you need to specify an index group with C[GRK]alpha[grk] atoms",
        "corresponding to an [GRK]alpha[grk]-helix of continuous residues. Sidechain",
        "directions require a second index group of the same size, containing",
        "the heavy atom in each residue that should represent the sidechain.[PAR]",
        "[BB]Note[bb] that this program does not do any fitting of structures.[PAR]",
        "We need four C[GRK]alpha[grk] coordinates to define the local direction of the helix",
        "axis.[PAR]",
        "The tilt/rotation is calculated from Euler rotations, where we define",
        "the helix axis as the local [IT]x[it]-axis, the residues/C[GRK]alpha[grk] vector as [IT]y[it], and the",
        "[IT]z[it]-axis from their cross product. We use the Euler Y-Z-X rotation, meaning",
        "we first tilt the helix axis (1) around and (2) orthogonal to the residues",
        "vector, and finally apply the (3) rotation around it. For debugging or other",
        "purposes, we also write out the actual Euler rotation angles as [TT]theta[1-3].xvg[tt]"
    };

    t_topology       *top = NULL;
    real              t;
    rvec             *x = NULL;
    matrix            box;
    t_trxstatus      *status;
    int               natoms;
    real              theta1, theta2, theta3;

    int               i, j, teller = 0;
    int               iCA, iSC;
    int              *ind_CA;
    int              *ind_SC;
    char             *gn_CA;
    char             *gn_SC;
    rvec              v1, v2;
    rvec             *x_CA, *x_SC;
    rvec             *r12;
    rvec             *r23;
    rvec             *r34;
    rvec             *diff13;
    rvec             *diff24;
    rvec             *helixaxis;
    rvec             *residuehelixaxis;
    rvec             *residueorigin;
    rvec             *residuevector;
    rvec             *sidechainvector;

    rvec             *residuehelixaxis_t0;
    rvec             *residuevector_t0;
    rvec             *axis3_t0;
    rvec             *residuehelixaxis_tlast;
    rvec             *residuevector_tlast;
    rvec             *axis3_tlast;
    rvec              refaxes[3], newaxes[3];
    rvec              unitaxes[3];
    rvec              rot_refaxes[3], rot_newaxes[3];

    real              tilt, rotation;
    rvec             *axis3;
    real             *twist, *residuetwist;
    real             *radius, *residueradius;
    real             *rise, *residuerise;
    real             *residuebending;

    real              tmp;
    real              weight[3];
    t_pbc             pbc;
    matrix            A;

    FILE             *fpaxis, *fpcenter, *fptilt, *fprotation;
    FILE             *fpradius, *fprise, *fptwist;
    FILE             *fptheta1, *fptheta2, *fptheta3;
    FILE             *fpbending;
    int               ePBC;

    gmx_output_env_t *oenv;
    gmx_rmpbc_t       gpbc = NULL;

    static  gmx_bool  bSC          = FALSE;
    static gmx_bool   bIncremental = FALSE;

    static t_pargs    pa[] = {
        { "-sidechain",      FALSE, etBOOL, {&bSC},
          "Calculate sidechain directions relative to helix axis too." },
        { "-incremental",        FALSE, etBOOL, {&bIncremental},
          "Calculate incremental rather than total rotation/tilt." },
    };
#define NPA asize(pa)

    t_filenm fnm[] = {
        { efTPR, NULL, NULL, ffREAD },
        { efTRX, "-f", NULL, ffREAD },
        { efNDX, NULL, NULL, ffOPTRD },
        { efDAT, "-oaxis",    "helixaxis", ffWRITE },
        { efDAT, "-ocenter",  "center", ffWRITE },
        { efXVG, "-orise",    "rise", ffWRITE },
        { efXVG, "-oradius",  "radius", ffWRITE },
        { efXVG, "-otwist",   "twist", ffWRITE },
        { efXVG, "-obending", "bending", ffWRITE },
        { efXVG, "-otilt",    "tilt", ffWRITE },
        { efXVG, "-orot",     "rotation", ffWRITE }
    };
#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv, PCA_CAN_TIME,
                           NFILE, fnm, NPA, pa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }

    top = read_top(ftp2fn(efTPR, NFILE, fnm), &ePBC);

    for (i = 0; i < 3; i++)
    {
        weight[i] = 1.0;
    }

    /* read index files */
    printf("Select a group of Calpha atoms corresponding to a single continuous helix:\n");
    get_index(&(top->atoms), ftp2fn_null(efNDX, NFILE, fnm), 1, &iCA, &ind_CA, &gn_CA);
    snew(x_CA, iCA);
    snew(x_SC, iCA); /* sic! */

    snew(r12, iCA-3);
    snew(r23, iCA-3);
    snew(r34, iCA-3);
    snew(diff13, iCA-3);
    snew(diff24, iCA-3);
    snew(helixaxis, iCA-3);
    snew(twist, iCA);
    snew(residuetwist, iCA);
    snew(radius, iCA);
    snew(residueradius, iCA);
    snew(rise, iCA);
    snew(residuerise, iCA);
    snew(residueorigin, iCA);
    snew(residuehelixaxis, iCA);
    snew(residuevector, iCA);
    snew(sidechainvector, iCA);
    snew(residuebending, iCA);
    snew(residuehelixaxis_t0, iCA);
    snew(residuevector_t0, iCA);
    snew(axis3_t0, iCA);
    snew(residuehelixaxis_tlast, iCA);
    snew(residuevector_tlast, iCA);
    snew(axis3_tlast, iCA);
    snew(axis3, iCA);

    if (bSC)
    {
        printf("Select a group of atoms defining the sidechain direction (1/residue):\n");
        get_index(&(top->atoms), ftp2fn_null(efNDX, NFILE, fnm), 1, &iSC, &ind_SC, &gn_SC);
        if (iSC != iCA)
        {
            gmx_fatal(FARGS, "Number of sidechain atoms (%d) != number of CA atoms (%d)", iSC, iCA);
        }

    }

    natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);

    fpaxis    = gmx_ffopen(opt2fn("-oaxis", NFILE, fnm), "w");
    fpcenter  = gmx_ffopen(opt2fn("-ocenter", NFILE, fnm), "w");
    fprise    = gmx_ffopen(opt2fn("-orise", NFILE, fnm), "w");
    fpradius  = gmx_ffopen(opt2fn("-oradius", NFILE, fnm), "w");
    fptwist   = gmx_ffopen(opt2fn("-otwist", NFILE, fnm), "w");
    fpbending = gmx_ffopen(opt2fn("-obending", NFILE, fnm), "w");

    fptheta1 = gmx_ffopen("theta1.xvg", "w");
    fptheta2 = gmx_ffopen("theta2.xvg", "w");
    fptheta3 = gmx_ffopen("theta3.xvg", "w");

    if (bIncremental)
    {
        fptilt = xvgropen(opt2fn("-otilt", NFILE, fnm),
                          "Incremental local helix tilt", "Time(ps)", "Tilt (degrees)",
                          oenv);
        fprotation = xvgropen(opt2fn("-orot", NFILE, fnm),
                              "Incremental local helix rotation", "Time(ps)",
                              "Rotation (degrees)", oenv);
    }
    else
    {
        fptilt = xvgropen(opt2fn("-otilt", NFILE, fnm),
                          "Cumulative local helix tilt", "Time(ps)", "Tilt (degrees)", oenv);
        fprotation = xvgropen(opt2fn("-orot", NFILE, fnm),
                              "Cumulative local helix rotation", "Time(ps)",
                              "Rotation (degrees)", oenv);
    }

    clear_rvecs(3, unitaxes);
    unitaxes[0][0] = 1;
    unitaxes[1][1] = 1;
    unitaxes[2][2] = 1;

    gpbc = gmx_rmpbc_init(&top->idef, ePBC, natoms);

    do
    {
        /* initialisation for correct distance calculations */
        set_pbc(&pbc, ePBC, box);
        /* make molecules whole again */
        gmx_rmpbc(gpbc, natoms, box, x);

        /* copy coords to our smaller arrays */
        for (i = 0; i < iCA; i++)
        {
            copy_rvec(x[ind_CA[i]], x_CA[i]);
            if (bSC)
            {
                copy_rvec(x[ind_SC[i]], x_SC[i]);
            }
        }

        for (i = 0; i < iCA-3; i++)
        {
            rvec_sub(x_CA[i+1], x_CA[i], r12[i]);
            rvec_sub(x_CA[i+2], x_CA[i+1], r23[i]);
            rvec_sub(x_CA[i+3], x_CA[i+2], r34[i]);
            rvec_sub(r12[i], r23[i], diff13[i]);
            rvec_sub(r23[i], r34[i], diff24[i]);
            /* calculate helix axis */
            cprod(diff13[i], diff24[i], helixaxis[i]);
            svmul(1.0/norm(helixaxis[i]), helixaxis[i], helixaxis[i]);

            tmp       = cos_angle(diff13[i], diff24[i]);
            twist[i]  = 180.0/M_PI * std::acos( tmp );
            radius[i] = std::sqrt( norm(diff13[i])*norm(diff24[i]) ) / (2.0* (1.0-tmp) );
            rise[i]   = std::abs(iprod(r23[i], helixaxis[i]));

            svmul(radius[i]/norm(diff13[i]), diff13[i], v1);
            svmul(radius[i]/norm(diff24[i]), diff24[i], v2);

            rvec_sub(x_CA[i+1], v1, residueorigin[i+1]);
            rvec_sub(x_CA[i+2], v2, residueorigin[i+2]);
        }
        residueradius[0] = residuetwist[0] = residuerise[0] = 0;

        residueradius[1] = radius[0];
        residuetwist[1]  = twist[0];
        residuerise[1]   = rise[0];

        residuebending[0] = residuebending[1] = 0;
        for (i = 2; i < iCA-2; i++)
        {
            residueradius[i]  = 0.5*(radius[i-2]+radius[i-1]);
            residuetwist[i]   = 0.5*(twist[i-2]+twist[i-1]);
            residuerise[i]    = 0.5*(rise[i-2]+rise[i-1]);
            residuebending[i] = 180.0/M_PI*std::acos( cos_angle(helixaxis[i-2], helixaxis[i-1]) );
        }
        residueradius[iCA-2]  = radius[iCA-4];
        residuetwist[iCA-2]   = twist[iCA-4];
        residuerise[iCA-2]    = rise[iCA-4];
        residueradius[iCA-1]  = residuetwist[iCA-1] = residuerise[iCA-1] = 0;
        residuebending[iCA-2] = residuebending[iCA-1] = 0;

        clear_rvec(residueorigin[0]);
        clear_rvec(residueorigin[iCA-1]);

        /* average helix axes to define them on the residues.
         * Just extrapolate second first/list atom.
         */
        copy_rvec(helixaxis[0], residuehelixaxis[0]);
        copy_rvec(helixaxis[0], residuehelixaxis[1]);

        for (i = 2; i < iCA-2; i++)
        {
            rvec_add(helixaxis[i-2], helixaxis[i-1], residuehelixaxis[i]);
            svmul(0.5, residuehelixaxis[i], residuehelixaxis[i]);
        }
        copy_rvec(helixaxis[iCA-4], residuehelixaxis[iCA-2]);
        copy_rvec(helixaxis[iCA-4], residuehelixaxis[iCA-1]);

        /* Normalize the axis */
        for (i = 0; i < iCA; i++)
        {
            svmul(1.0/norm(residuehelixaxis[i]), residuehelixaxis[i], residuehelixaxis[i]);
        }

        /* calculate vector from origin to residue CA */
        fprintf(fpaxis, "%15.12g  ", t);
        fprintf(fpcenter, "%15.12g  ", t);
        fprintf(fprise, "%15.12g  ", t);
        fprintf(fpradius, "%15.12g  ", t);
        fprintf(fptwist, "%15.12g  ", t);
        fprintf(fpbending, "%15.12g  ", t);

        for (i = 0; i < iCA; i++)
        {
            if (i == 0 || i == iCA-1)
            {
                fprintf(fpaxis, "%15.12g %15.12g %15.12g       ", 0.0, 0.0, 0.0);
                fprintf(fpcenter, "%15.12g %15.12g %15.12g       ", 0.0, 0.0, 0.0);
                fprintf(fprise, "%15.12g  ", 0.0);
                fprintf(fpradius, "%15.12g  ", 0.0);
                fprintf(fptwist, "%15.12g  ", 0.0);
                fprintf(fpbending, "%15.12g  ", 0.0);
            }
            else
            {
                rvec_sub( bSC ? x_SC[i] : x_CA[i], residueorigin[i], residuevector[i]);
                svmul(1.0/norm(residuevector[i]), residuevector[i], residuevector[i]);
                cprod(residuehelixaxis[i], residuevector[i], axis3[i]);
                fprintf(fpaxis, "%15.12g %15.12g %15.12g       ", residuehelixaxis[i][0], residuehelixaxis[i][1], residuehelixaxis[i][2]);
                fprintf(fpcenter, "%15.12g %15.12g %15.12g       ", residueorigin[i][0], residueorigin[i][1], residueorigin[i][2]);

                fprintf(fprise, "%15.12g  ", residuerise[i]);
                fprintf(fpradius, "%15.12g  ", residueradius[i]);
                fprintf(fptwist, "%15.12g  ", residuetwist[i]);
                fprintf(fpbending, "%15.12g  ", residuebending[i]);
            }
        }
        fprintf(fprise, "\n");
        fprintf(fpradius, "\n");
        fprintf(fpaxis, "\n");
        fprintf(fpcenter, "\n");
        fprintf(fptwist, "\n");
        fprintf(fpbending, "\n");

        if (teller == 0)
        {
            for (i = 0; i < iCA; i++)
            {
                copy_rvec(residuehelixaxis[i], residuehelixaxis_t0[i]);
                copy_rvec(residuevector[i], residuevector_t0[i]);
                copy_rvec(axis3[i], axis3_t0[i]);
            }
        }
        else
        {
            fprintf(fptilt, "%15.12g       ", t);
            fprintf(fprotation, "%15.12g       ", t);
            fprintf(fptheta1, "%15.12g      ", t);
            fprintf(fptheta2, "%15.12g      ", t);
            fprintf(fptheta3, "%15.12g      ", t);

            for (i = 0; i < iCA; i++)
            {
                if (i == 0 || i == iCA-1)
                {
                    tilt = rotation = 0;
                }
                else
                {
                    if (!bIncremental)
                    {
                        /* Total rotation & tilt */
                        copy_rvec(residuehelixaxis_t0[i], refaxes[0]);
                        copy_rvec(residuevector_t0[i], refaxes[1]);
                        copy_rvec(axis3_t0[i], refaxes[2]);
                    }
                    else
                    {
                        /* Rotation/tilt since last step */
                        copy_rvec(residuehelixaxis_tlast[i], refaxes[0]);
                        copy_rvec(residuevector_tlast[i], refaxes[1]);
                        copy_rvec(axis3_tlast[i], refaxes[2]);
                    }
                    copy_rvec(residuehelixaxis[i], newaxes[0]);
                    copy_rvec(residuevector[i], newaxes[1]);
                    copy_rvec(axis3[i], newaxes[2]);

                    /* rotate reference frame onto unit axes */
                    calc_fit_R(3, 3, weight, unitaxes, refaxes, A);
                    for (j = 0; j < 3; j++)
                    {
                        mvmul(A, refaxes[j], rot_refaxes[j]);
                        mvmul(A, newaxes[j], rot_newaxes[j]);
                    }

                    /* Determine local rotation matrix A */
                    calc_fit_R(3, 3, weight, rot_newaxes, rot_refaxes, A);
                    /* Calculate euler angles, from rotation order y-z-x, where
                     * x is helixaxis, y residuevector, and z axis3.
                     *
                     * A contains rotation column vectors.
                     */

                    theta1 = 180.0/M_PI*std::atan2(A[0][2], A[0][0]);
                    theta2 = 180.0/M_PI*std::asin(-A[0][1]);
                    theta3 = 180.0/M_PI*std::atan2(A[2][1], A[1][1]);

                    tilt     = std::sqrt(theta1*theta1+theta2*theta2);
                    rotation = theta3;
                    fprintf(fptheta1, "%15.12g  ", theta1);
                    fprintf(fptheta2, "%15.12g  ", theta2);
                    fprintf(fptheta3, "%15.12g  ", theta3);

                }
                fprintf(fptilt, "%15.12g  ", tilt);
                fprintf(fprotation, "%15.12g  ", rotation);
            }
            fprintf(fptilt, "\n");
            fprintf(fprotation, "\n");
            fprintf(fptheta1, "\n");
            fprintf(fptheta2, "\n");
            fprintf(fptheta3, "\n");
        }

        for (i = 0; i < iCA; i++)
        {
            copy_rvec(residuehelixaxis[i], residuehelixaxis_tlast[i]);
            copy_rvec(residuevector[i], residuevector_tlast[i]);
            copy_rvec(axis3[i], axis3_tlast[i]);
        }

        teller++;
    }
    while (read_next_x(oenv, status, &t, x, box));

    gmx_rmpbc_done(gpbc);

    gmx_ffclose(fpaxis);
    gmx_ffclose(fpcenter);
    xvgrclose(fptilt);
    xvgrclose(fprotation);
    gmx_ffclose(fprise);
    gmx_ffclose(fpradius);
    gmx_ffclose(fptwist);
    gmx_ffclose(fpbending);
    gmx_ffclose(fptheta1);
    gmx_ffclose(fptheta2);
    gmx_ffclose(fptheta3);

    close_trj(status);

    return 0;
}