Statistiques
| Révision :

root / src / AlignPartial.f90 @ 4

Historique | Voir | Annoter | Télécharger (5,3 ko)

1 1 equemene
subroutine AlignPartial(na, x,y,z,x2,y2,z2,ListAt,U)
2 1 equemene
  !-----------------------------------------------------------------------
3 1 equemene
  !  This subroutine calculates the least square rmsd of two coordinate
4 1 equemene
  !  sets coord1(3,n) and coord2(3,n) using a method based on quaternion.
5 1 equemene
  !  It then calculate the  rotation matrix U and the centers of coord, and uses
6 1 equemene
  ! them to align the two molecules.
7 1 equemene
  ! This new version does not use all atoms to calculate the RMSD and rotation matrix
8 1 equemene
  ! but only those which are 'true' in ListAt
9 1 equemene
  !-----------------------------------------------------------------------
10 1 equemene
  ! Input parameters:
11 1 equemene
  ! Na        : number of atoms
12 1 equemene
  ! x,y,z     : coordinates of the first geometry
13 1 equemene
  ! x2,y2,z2  : coordinates of the second geometry
14 1 equemene
  ! ListAt    : Logical, T if this atom should be considered in the RMSD calc and
15 1 equemene
  !             alignment.
16 1 equemene
  ! Debug     : True if additionnal printing is requiered
17 1 equemene
  !
18 1 equemene
  ! output parameters:
19 1 equemene
  ! U         : Real, (3x3) matrix for rotation
20 1 equemene
  ! Rmsd      : Read, the rmsd
21 1 equemene
  ! x2,y2,z2  : coordinates of the second geometry ALIGNED to the first one
22 1 equemene
  !-----------------------------------------------------------------------
23 1 equemene
24 1 equemene
  Use VarTypes
25 1 equemene
  IMPLICIT NONE
26 1 equemene
27 1 equemene
28 1 equemene
  integer(KINT) :: na, NaT
29 1 equemene
  Real(KREAL) ::  x(na),y(Na),z(Na)
30 1 equemene
  Real(KREAL) ::  x2(Na),y2(Na),z2(Na)
31 1 equemene
  Real(KREAL) ::  U(3,3), rmsd
32 1 equemene
  LOGICAL  Debug, ListAt(Na)
33 1 equemene
34 1 equemene
  REAL(KREAL) :: Coord1(3,Na), Coord2(3,Na)
35 1 equemene
  Real(KREAL) ::  xc1,yc1,zc1, xc2,yc2,zc2
36 1 equemene
37 1 equemene
38 1 equemene
  integer(KINT) :: i, j, nd, ia
39 1 equemene
  Real(KREAL) :: x_norm, y_norm, lambda
40 1 equemene
  Real(KREAL) :: Rmatrix(3,3)
41 1 equemene
  Real(KREAL) :: S(4,4), dS(4,4), q(4)
42 1 equemene
  Real(KREAL) :: tmp(3),tmp1(4),tmp2(4),EigVec(4,4), EigVal(4)
43 1 equemene
44 1 equemene
  INTERFACE
45 1 equemene
     function valid(string) result (isValid)
46 1 equemene
       CHARACTER(*), intent(in) :: string
47 1 equemene
       logical                  :: isValid
48 1 equemene
     END function VALID
49 1 equemene
  END INTERFACE
50 1 equemene
51 1 equemene
52 1 equemene
  debug=valid('CalcRmsd').OR.valid('align').OR.valid('alignpartial')
53 1 equemene
54 1 equemene
  ! calculate the barycenters, centroidal coordinates, and the norms
55 1 equemene
  x_norm = 0.0d0
56 1 equemene
  y_norm = 0.0d0
57 1 equemene
  xc1=0.
58 1 equemene
  yc1=0.
59 1 equemene
  zc1=0.
60 1 equemene
  xc2=0.
61 1 equemene
  yc2=0.
62 1 equemene
  zc2=0.
63 1 equemene
64 1 equemene
  if (debug) THEN
65 1 equemene
     WRITE(*,*) "DBG AlignPartial X2,Y2,Z2 before align"
66 1 equemene
     DO Ia=1,na
67 1 equemene
        WRITE(*,*) x2(ia),y2(ia),z2(ia)
68 1 equemene
     END DO
69 1 equemene
  END IF
70 1 equemene
71 1 equemene
  NAt=0
72 1 equemene
  do ia=1,na
73 1 equemene
     IF (listat(ia)) THEN
74 1 equemene
        Nat=NAt+1
75 1 equemene
        xc1=xc1+x(ia)
76 1 equemene
        xc2=xc2+x2(ia)
77 1 equemene
        yc1=yc1+y(ia)
78 1 equemene
        yc2=yc2+y2(ia)
79 1 equemene
        zc1=zc1+z(ia)
80 1 equemene
        zc2=zc2+z2(ia)
81 1 equemene
        !     if (debug) WRITE(*,'(A,I5,4(1X,F10.4))') 'ia...',ia,x(ia),
82 1 equemene
        !     &                        x2(ia),xc1,xc2
83 1 equemene
     END IF
84 1 equemene
  END DO
85 1 equemene
86 1 equemene
  if (Nat.EQ.0) THEN
87 1 equemene
     WRITE(*,*) "ERROR, AlignPartial: ListAt is empty :-)"
88 1 equemene
  END IF
89 1 equemene
  xc1=xc1/dble(nat)
90 1 equemene
  yc1=yc1/dble(nat)
91 1 equemene
  zc1=zc1/dble(nat)
92 1 equemene
  xc2=xc2/dble(nat)
93 1 equemene
  yc2=yc2/dble(nat)
94 1 equemene
  zc2=zc2/dble(nat)
95 1 equemene
96 1 equemene
  IF (Debug) WRITE(*,*) 'Found :', Nat, ' atoms'
97 1 equemene
  IF (debug) WRITE(*,*) (ListAt(I),I=1,Na)
98 1 equemene
  IF (debug) WRITE(*,'(1X,A,3(1X,F10.4))') 'Center1',xc1,yc1,zc1
99 1 equemene
  IF (debug) WRITE(*,'(1X,A,3(1X,F10.4))') 'Center2',xc2,yc2,zc2
100 1 equemene
  do i=1,na
101 1 equemene
     Coord1(1,i)=x(i)-xc1
102 1 equemene
     Coord1(2,i)=y(i)-yc1
103 1 equemene
     Coord1(3,i)=z(i)-zc1
104 1 equemene
     Coord2(1,i)=x2(i)-xc2
105 1 equemene
     Coord2(2,i)=y2(i)-yc2
106 1 equemene
     Coord2(3,i)=z2(i)-zc2
107 1 equemene
     IF (ListAt(I)) THEN
108 1 equemene
        x_norm=x_norm+Coord1(1,i)**2+Coord1(2,i)**2+Coord1(3,i)**2
109 1 equemene
        y_norm=y_norm+Coord2(1,i)**2+Coord2(2,i)**2+Coord2(3,i)**2
110 1 equemene
     END IF
111 1 equemene
  end do
112 1 equemene
113 1 equemene
  ! calculate the R matrix
114 1 equemene
  do i = 1, 3
115 1 equemene
     do j = 1, 3
116 1 equemene
        Rmatrix(i,j)=0.
117 1 equemene
        do ia=1,na
118 1 equemene
           If (ListAt(ia))  Rmatrix(i,j) = Rmatrix(i,j)+Coord1(i,ia)*Coord2(j,ia)
119 1 equemene
        END DO
120 1 equemene
     end do
121 1 equemene
  end do
122 1 equemene
123 1 equemene
  IF (debug) THEN
124 1 equemene
     WRITE(*,*) "R matrix"
125 1 equemene
     DO I=1,3
126 1 equemene
        WRITE(*,*) (RMatrix(I,j),j=1,3)
127 1 equemene
     END DO
128 1 equemene
  END IF
129 1 equemene
130 1 equemene
131 1 equemene
  ! S matrix
132 1 equemene
  S(1, 1) = Rmatrix(1, 1) + Rmatrix(2, 2) + Rmatrix(3, 3)
133 1 equemene
  S(2, 1) = Rmatrix(2, 3) - Rmatrix(3, 2)
134 1 equemene
  S(3, 1) = Rmatrix(3, 1) - Rmatrix(1, 3)
135 1 equemene
  S(4, 1) = Rmatrix(1, 2) - Rmatrix(2, 1)
136 1 equemene
137 1 equemene
  S(1, 2) = S(2, 1)
138 1 equemene
  S(2, 2) = Rmatrix(1, 1) - Rmatrix(2, 2) - Rmatrix(3, 3)
139 1 equemene
  S(3, 2) = Rmatrix(1, 2) + Rmatrix(2, 1)
140 1 equemene
  S(4, 2) = Rmatrix(1, 3) + Rmatrix(3, 1)
141 1 equemene
142 1 equemene
  S(1, 3) = S(3, 1)
143 1 equemene
  S(2, 3) = S(3, 2)
144 1 equemene
  S(3, 3) =-Rmatrix(1, 1) + Rmatrix(2, 2) - Rmatrix(3, 3)
145 1 equemene
  S(4, 3) = Rmatrix(2, 3) + Rmatrix(3, 2)
146 1 equemene
147 1 equemene
  S(1, 4) = S(4, 1)
148 1 equemene
  S(2, 4) = S(4, 2)
149 1 equemene
  S(3, 4) = S(4, 3)
150 1 equemene
  S(4, 4) =-Rmatrix(1, 1) - Rmatrix(2, 2) + Rmatrix(3, 3)
151 1 equemene
152 1 equemene
153 1 equemene
  ! PFL : I use my usual Jacobi diagonalisation
154 1 equemene
  ! Calculate eigenvalues and eigenvectors, and
155 1 equemene
  ! take the maximum eigenvalue lambda and the corresponding eigenvector q.
156 1 equemene
157 1 equemene
  IF (debug) THEN
158 1 equemene
     WRITE(*,*) "S matrix"
159 1 equemene
     DO I=1,4
160 1 equemene
        WRITE(*,*) (S(I,j),j=1,4)
161 1 equemene
     END DO
162 1 equemene
  END IF
163 1 equemene
164 1 equemene
  Call Jacobi(S,4,EigVal,EigVec,4)
165 1 equemene
166 1 equemene
  Call Trie(4,EigVal,EigVec,4)
167 1 equemene
168 1 equemene
  Lambda=EigVal(4)
169 1 equemene
170 1 equemene
  ! RMS Deviation
171 1 equemene
  rmsd=sqrt(max(0.0d0,((x_norm+y_norm)-2.0d0*lambda))/dble(nat))
172 1 equemene
  if (debug) WRITE(*,*) "AlignPartial rmsd:",rmsd
173 1 equemene
  Call rotation_matrix(EigVec(1,4),U)
174 1 equemene
175 1 equemene
176 1 equemene
  IF (debug) THEN
177 1 equemene
     WRITE(*,*) "U matrix"
178 1 equemene
     DO I=1,3
179 1 equemene
        WRITE(*,*) (U(I,j),j=1,3)
180 1 equemene
     END DO
181 1 equemene
  END IF
182 1 equemene
183 1 equemene
  DO I=1,na
184 1 equemene
     x2(i)=Coord2(1,i)*U(1,1)+Coord2(2,i)*U(2,1) + Coord2(3,i)*U(3,1) +xc1
185 1 equemene
     y2(i)=Coord2(1,i)*U(1,2)+Coord2(2,i)*U(2,2) + Coord2(3,i)*U(3,2) +yc1
186 1 equemene
     z2(i)=Coord2(1,i)*U(1,3)+Coord2(2,i)*U(2,3) + Coord2(3,i)*U(3,3) +zc1
187 1 equemene
  END DO
188 1 equemene
189 1 equemene
  if (debug) THEN
190 1 equemene
     WRITE(*,*) "DBG AlignPartial X2,Y2,Z2 after align"
191 1 equemene
     DO Ia=1,na
192 1 equemene
        WRITE(*,*) x2(ia),y2(ia),z2(ia)
193 1 equemene
     END DO
194 1 equemene
  END IF
195 1 equemene
196 1 equemene
197 1 equemene
END subroutine AlignPartial