1 |
mocchiut |
1.1 |
************************************************************************* |
2 |
|
|
* |
3 |
|
|
* Subroutine tricircle.f |
4 |
|
|
* |
5 |
|
|
* - find the best circle passing through npoints: compute the circle |
6 |
|
|
* passing through every combination of 3 of them and average the |
7 |
|
|
* resulting centres and radii |
8 |
|
|
* |
9 |
|
|
* output variables: |
10 |
|
|
* - angle(npoints) angle of the tangent in the input points, in degrees, range -90..+90 |
11 |
|
|
* - residual(npoints) residuals |
12 |
|
|
* - chi sum of squared residuals |
13 |
|
|
* - xc,zc,radius circle parameters |
14 |
|
|
* - eflag error flag |
15 |
|
|
* |
16 |
|
|
* to be called inside ./fitxy.f |
17 |
|
|
* |
18 |
|
|
************************************************************************* |
19 |
|
|
|
20 |
|
|
|
21 |
|
|
subroutine tricircle(npoints,dep,indep,angle,residual,chi |
22 |
|
|
$ ,xc,zc,radius,eflag) |
23 |
|
|
|
24 |
|
|
|
25 |
|
|
c------------------------------------------------------------------------ |
26 |
|
|
c |
27 |
|
|
c local variables |
28 |
|
|
c |
29 |
|
|
c------------------------------------------------------------------------ |
30 |
|
|
|
31 |
|
|
integer npoints !fit number of points |
32 |
|
|
real dep(npoints),indep(npoints) !dependent and independent variables |
33 |
|
|
|
34 |
mocchiut |
1.5 |
c real angle(npoints) !angle between the tangent line in the input points and |
35 |
|
|
c ! the independent variable axis |
36 |
|
|
c real residual(npoints) !residuals |
37 |
|
|
c real chi !sum of squared residuals |
38 |
|
|
c real xc,zc,radius !circle parameters |
39 |
|
|
double precision angle(npoints) !angle between the tangent line in the input points and |
40 |
mocchiut |
1.1 |
! the independent variable axis |
41 |
mocchiut |
1.5 |
double precision residual(npoints) !residuals EM GCC4.7 |
42 |
|
|
double precision chi !sum of squared residuals EM GCC4.7 |
43 |
|
|
double precision xc,zc,radius !circle parameters EM GCC4.7 |
44 |
mocchiut |
1.1 |
|
45 |
|
|
integer eflag !error flag =1 if the procedure fails |
46 |
|
|
|
47 |
|
|
c integer nloops !number of combinations of 3 points out of npoints |
48 |
|
|
integer index(3) !indexes of the 3 chosen points |
49 |
|
|
|
50 |
|
|
parameter(scale=1000.) |
51 |
|
|
double precision z(3),x(3),unit(3),zzxx(3) !temp variables |
52 |
|
|
double precision a(3,3),d(3,3),e(3,3),f(3,3) |
53 |
|
|
double precision ir(3) |
54 |
|
|
double precision deta,detd,dete,detf !determinants |
55 |
|
|
integer ifail !=-1 if singular matrix error, =0 if not singular |
56 |
|
|
integer jfail !=0 if determinant can be evaluated, =-1 if determinat is probably too small, =+1 if too large |
57 |
|
|
|
58 |
mocchiut |
1.5 |
integer ibig ! EM GCC4.7 |
59 |
|
|
c parameter (ibig=1.e4) !just a number greater than C(npoints,3) |
60 |
|
|
parameter (ibig=10000) !just a number greater than C(npoints,3) EM GCC 4.7 |
61 |
mocchiut |
1.4 |
double precision xxc(ibig),zzc(ibig),rrr(ibig) !centres and radii to be averaged |
62 |
mocchiut |
1.1 |
|
63 |
|
|
double precision tmp1,tmp2,tmp(npoints) !temp variables |
64 |
|
|
|
65 |
pam-fi |
1.2 |
logical DEBUG |
66 |
|
|
|
67 |
mocchiut |
1.1 |
real pigr !3.1415... |
68 |
|
|
pigr=ACOS(-1.) |
69 |
|
|
|
70 |
pam-fi |
1.2 |
|
71 |
|
|
DEBUG = .false. |
72 |
|
|
if(eflag.eq.1)DEBUG = .true. |
73 |
|
|
|
74 |
mocchiut |
1.1 |
eflag = 0 |
75 |
|
|
|
76 |
|
|
|
77 |
|
|
c------------------------------------------------------------------------ |
78 |
|
|
c choose 3 points out of npoints |
79 |
|
|
c------------------------------------------------------------------------ |
80 |
|
|
c nloops = fact(npoints) / (fact(3) * fact(npoints-3)) |
81 |
|
|
|
82 |
|
|
k=0 |
83 |
|
|
do i1=1,npoints-2 |
84 |
|
|
index(1)=i1 |
85 |
|
|
do i2=i1+1,npoints-1 |
86 |
|
|
index(2)=i2 |
87 |
|
|
do i3=i2+1,npoints |
88 |
|
|
index(3)=i3 |
89 |
|
|
|
90 |
|
|
k=k+1 !number of combinations |
91 |
|
|
c$$$ print*,' ' !??? |
92 |
|
|
c$$$ print*,'k =',k,' index =',index |
93 |
|
|
|
94 |
|
|
c------------------------------------------------------------------------ |
95 |
|
|
c build temp vectors |
96 |
|
|
c------------------------------------------------------------------------ |
97 |
|
|
do i=1,3 |
98 |
|
|
z(i)=indep(index(i))/scale !to avoid too big numbers in matrix computation |
99 |
|
|
x(i)=dep(index(i))/scale |
100 |
|
|
unit(i)=1. |
101 |
|
|
zzxx(i)=z(i)**2.+x(i)**2. |
102 |
|
|
enddo |
103 |
|
|
c$$$ print*,'z =',z,' x =',x !??? |
104 |
|
|
c$$$ print*,'unit =',unit,' zzxx =',zzxx |
105 |
|
|
|
106 |
|
|
c------------------------------------------------------------------------ |
107 |
|
|
c build the matrixes |
108 |
|
|
c------------------------------------------------------------------------ |
109 |
|
|
do i=1,3 |
110 |
|
|
a(i,1)=z(i) !A has (z x 1) as columns |
111 |
|
|
a(i,2)=x(i) |
112 |
|
|
a(i,3)=unit(i) |
113 |
|
|
d(i,1)=zzxx(i) !D has (zzxx x 1) as columns |
114 |
|
|
d(i,2)=x(i) |
115 |
|
|
d(i,3)=unit(i) |
116 |
|
|
e(i,1)=zzxx(i) !E has (zzxx z 1) as columns |
117 |
|
|
e(i,2)=z(i) |
118 |
|
|
e(i,3)=unit(i) |
119 |
|
|
f(i,1)=zzxx(i) !F has (zzxx z x) as columns |
120 |
|
|
f(i,2)=z(i) |
121 |
|
|
f(i,3)=x(i) |
122 |
|
|
enddo |
123 |
|
|
|
124 |
|
|
c$$$ print*,'matrix A:' !??? |
125 |
|
|
c$$$ do i=1,3 |
126 |
|
|
c$$$ print*,(a(i,j),j=1,3) |
127 |
|
|
c$$$ enddo |
128 |
|
|
c$$$ print*,'matrix D:' !??? |
129 |
|
|
c$$$ do i=1,3 |
130 |
|
|
c$$$ print*,(d(i,j),j=1,3) |
131 |
|
|
c$$$ enddo |
132 |
|
|
c$$$ print*,'matrix E:' !??? |
133 |
|
|
c$$$ do i=1,3 |
134 |
|
|
c$$$ print*,(e(i,j),j=1,3) |
135 |
|
|
c$$$ enddo |
136 |
|
|
c$$$ print*,'matrix F:' !??? |
137 |
|
|
c$$$ do i=1,3 |
138 |
|
|
c$$$ print*,(f(i,j),j=1,3) |
139 |
|
|
c$$$ enddo |
140 |
|
|
|
141 |
|
|
c------------------------------------------------------------------------ |
142 |
|
|
c compute the determinants of A, D, E and F matrixes |
143 |
|
|
c using DFACT (http://wwwasdoc.web.cern.ch/wwwasdoc/shortwrupsdir/f011/top.html) |
144 |
|
|
c------------------------------------------------------------------------ |
145 |
|
|
|
146 |
|
|
ifail=0 |
147 |
|
|
jfail=0 |
148 |
|
|
call DFACT(3,a,3,ir,ifail,deta,jfail) |
149 |
|
|
if(ifail.eq.-1) then |
150 |
pam-fi |
1.2 |
if(DEBUG)then |
151 |
|
|
print*,'tricircle: ERROR: singular matrix A:' |
152 |
|
|
do i=1,3 |
153 |
|
|
print*,(a(i,j),j=1,3) |
154 |
|
|
enddo |
155 |
|
|
endif |
156 |
mocchiut |
1.1 |
eflag=1 |
157 |
|
|
endif |
158 |
|
|
if(jfail.eq.-1) then |
159 |
pam-fi |
1.2 |
if(DEBUG)then |
160 |
|
|
print* |
161 |
|
|
$ ,'tricircle: ERROR: matrix A: determinant too small?' |
162 |
|
|
do i=1,3 |
163 |
|
|
print*,(d(i,j),j=1,3) |
164 |
|
|
enddo |
165 |
|
|
endif |
166 |
mocchiut |
1.1 |
eflag=1 |
167 |
|
|
elseif(jfail.eq.1) then |
168 |
pam-fi |
1.2 |
if(DEBUG)then |
169 |
|
|
print* |
170 |
mocchiut |
1.1 |
$ ,'tricircle: ERROR: matrix A: determinant too large?' |
171 |
pam-fi |
1.2 |
do i=1,3 |
172 |
|
|
print*,(d(i,j),j=1,3) |
173 |
|
|
enddo |
174 |
|
|
endif |
175 |
mocchiut |
1.1 |
eflag=1 |
176 |
|
|
endif |
177 |
|
|
|
178 |
|
|
ifail=0 |
179 |
|
|
jfail=0 |
180 |
|
|
call DFACT(3,d,3,ir,ifail,detd,jfail) |
181 |
|
|
if(ifail.eq.-1) then |
182 |
pam-fi |
1.2 |
if(DEBUG)then |
183 |
pam-fi |
1.3 |
print*,'tricircle: ERROR: singular matrix D:' |
184 |
|
|
do i=1,3 |
185 |
|
|
print*,(d(i,j),j=1,3) |
186 |
|
|
enddo |
187 |
pam-fi |
1.2 |
endif |
188 |
mocchiut |
1.1 |
eflag=1 |
189 |
pam-fi |
1.3 |
endif |
190 |
|
|
if(jfail.eq.-1) then |
191 |
|
|
if(DEBUG)then |
192 |
|
|
print* |
193 |
|
|
$ ,'tricircle: ERROR: matrix D: determinant too small?' |
194 |
|
|
do i=1,3 |
195 |
|
|
print*,(d(i,j),j=1,3) |
196 |
|
|
enddo |
197 |
pam-fi |
1.2 |
endif |
198 |
mocchiut |
1.1 |
eflag=1 |
199 |
|
|
elseif(jfail.eq.1) then |
200 |
pam-fi |
1.2 |
if(DEBUG)then |
201 |
mocchiut |
1.1 |
print* |
202 |
|
|
$ ,'tricircle: ERROR: matrix D: determinant too large?' |
203 |
|
|
do i=1,3 |
204 |
|
|
print*,(d(i,j),j=1,3) |
205 |
|
|
enddo |
206 |
pam-fi |
1.2 |
endif |
207 |
mocchiut |
1.1 |
eflag=1 |
208 |
|
|
endif |
209 |
|
|
|
210 |
|
|
ifail=0 |
211 |
|
|
jfail=0 |
212 |
|
|
call DFACT(3,e,3,ir,ifail,dete,jfail) |
213 |
|
|
if(ifail.eq.-1) then |
214 |
pam-fi |
1.2 |
if(DEBUG)then |
215 |
mocchiut |
1.1 |
print*,'tricircle: ERROR: singular matrix E:' |
216 |
|
|
do i=1,3 |
217 |
|
|
print*,(e(i,j),j=1,3) |
218 |
|
|
enddo |
219 |
pam-fi |
1.2 |
endif |
220 |
mocchiut |
1.1 |
eflag=1 |
221 |
pam-fi |
1.3 |
endif |
222 |
mocchiut |
1.1 |
if(jfail.eq.-1) then |
223 |
pam-fi |
1.2 |
if(DEBUG)then |
224 |
mocchiut |
1.1 |
print* |
225 |
|
|
$ ,'tricircle: ERROR: matrix E: determinant too small?' |
226 |
|
|
do i=1,3 |
227 |
|
|
print*,(e(i,j),j=1,3) |
228 |
|
|
enddo |
229 |
pam-fi |
1.2 |
endif |
230 |
mocchiut |
1.1 |
eflag=1 |
231 |
|
|
elseif(jfail.eq.1) then |
232 |
pam-fi |
1.2 |
if(DEBUG)then |
233 |
mocchiut |
1.1 |
print* |
234 |
|
|
$ ,'tricircle: ERROR: matrix E: determinant too large?' |
235 |
|
|
do i=1,3 |
236 |
|
|
print*,(e(i,j),j=1,3) |
237 |
|
|
enddo |
238 |
pam-fi |
1.2 |
endif |
239 |
mocchiut |
1.1 |
eflag=1 |
240 |
|
|
endif |
241 |
|
|
|
242 |
|
|
ifail=0 |
243 |
|
|
jfail=0 |
244 |
|
|
call DFACT(3,f,3,ir,ifail,detf,jfail) |
245 |
|
|
c ifail=-1 !??? |
246 |
|
|
if(ifail.eq.-1) then |
247 |
pam-fi |
1.2 |
if(DEBUG)then |
248 |
mocchiut |
1.1 |
print*,'tricircle: ERROR: singular matrix F:' |
249 |
|
|
do i=1,3 |
250 |
|
|
print*,(f(i,j),j=1,3) |
251 |
|
|
enddo |
252 |
pam-fi |
1.2 |
endif |
253 |
mocchiut |
1.1 |
eflag=1 |
254 |
|
|
endif |
255 |
|
|
if(jfail.eq.-1) then |
256 |
pam-fi |
1.2 |
if(DEBUG)then |
257 |
mocchiut |
1.1 |
print* |
258 |
|
|
$ ,'tricircle: ERROR: matrix F: determinant too small?' |
259 |
|
|
do i=1,3 |
260 |
|
|
print*,(f(i,j),j=1,3) |
261 |
|
|
enddo |
262 |
pam-fi |
1.2 |
endif |
263 |
mocchiut |
1.1 |
eflag=1 |
264 |
|
|
elseif(jfail.eq.1) then |
265 |
pam-fi |
1.2 |
if(DEBUG)then |
266 |
mocchiut |
1.1 |
print* |
267 |
|
|
$ ,'tricircle: ERROR: matrix F: determinant too large?' |
268 |
|
|
do i=1,3 |
269 |
|
|
print*,(f(i,j),j=1,3) |
270 |
|
|
enddo |
271 |
pam-fi |
1.2 |
endif |
272 |
mocchiut |
1.1 |
eflag=1 |
273 |
|
|
endif |
274 |
|
|
|
275 |
|
|
c------------------------------------------------------------------------ |
276 |
|
|
c compute the centre and radius |
277 |
|
|
c------------------------------------------------------------------------ |
278 |
|
|
detd=-detd |
279 |
|
|
detf=-detf |
280 |
|
|
|
281 |
|
|
c xxc(k)=-detd/(2.*deta) |
282 |
|
|
c zzc(k)=-dete/(2.*deta) |
283 |
|
|
xxc(k)=-dete/(2.*deta) |
284 |
|
|
zzc(k)=-detd/(2.*deta) |
285 |
|
|
rrr(k)=SQRT((detd**2+dete**2)/(4.*deta**2.)-detf/deta) |
286 |
|
|
|
287 |
|
|
c$$$ write(30,*) xxc(k)*scale !??? |
288 |
|
|
c$$$ write(31,*) zzc(k)*scale !??? |
289 |
|
|
c$$$ write(32,*) rrr(k)*scale !??? |
290 |
|
|
c$$$ print*,'xxc =',xxc(k)*scale,' zzc =',zzc(k)*scale |
291 |
|
|
c$$$ $ ,' rrr =',rrr(k)*scale !??? |
292 |
|
|
|
293 |
|
|
enddo !index loops |
294 |
|
|
enddo |
295 |
|
|
enddo |
296 |
|
|
|
297 |
|
|
|
298 |
|
|
c------------------------------------------------------------------------ |
299 |
|
|
c averages the centres and the radii |
300 |
|
|
c------------------------------------------------------------------------ |
301 |
|
|
xc=0. |
302 |
|
|
zc=0. |
303 |
|
|
radius=0. |
304 |
|
|
do i=1,k |
305 |
|
|
xc=xc+xxc(i) |
306 |
|
|
zc=zc+zzc(i) |
307 |
|
|
radius=radius+rrr(i) |
308 |
|
|
enddo |
309 |
|
|
xc=xc/k * scale !back to micrometers |
310 |
|
|
zc=zc/k * scale |
311 |
|
|
radius=radius/k * scale |
312 |
|
|
|
313 |
|
|
c$$$ c------------------------------------------------------------------------ |
314 |
|
|
c$$$ c check for small radius...!??? |
315 |
|
|
c$$$ c------------------------------------------------------------------------ |
316 |
|
|
c$$$ num=200 |
317 |
|
|
c$$$ height=ABS(indep(1)-indep(6)) |
318 |
|
|
c$$$ if(radius.lt.(num*height)) then |
319 |
|
|
c$$$ xc=0. |
320 |
|
|
c$$$ zc=0. |
321 |
|
|
c$$$ radius=0. |
322 |
|
|
c$$$ print*,'tricircle: ERROR: bad circle' |
323 |
|
|
c$$$ print*,'radius' ,radius,' < ', num,' x',height |
324 |
|
|
c$$$ c$$$ print*,dep !??? |
325 |
|
|
c$$$ c$$$ print*,indep !??? |
326 |
|
|
c$$$ eflag=1 |
327 |
|
|
c$$$ endif |
328 |
|
|
|
329 |
|
|
|
330 |
|
|
c------------------------------------------------------------------------ |
331 |
|
|
c computes residuals and chi-squared |
332 |
|
|
c------------------------------------------------------------------------ |
333 |
|
|
chi=0. |
334 |
|
|
|
335 |
|
|
c print*,xc,zc,radius !??? |
336 |
|
|
do i=1,npoints |
337 |
|
|
tmp1 = SQRT(radius**2.-(indep(i)-zc)**2.) |
338 |
|
|
tmp2 = dep(i)-xc |
339 |
|
|
if(ABS(tmp2-tmp1).le.ABS(tmp2+tmp1)) then !it chooses the right sign |
340 |
|
|
tmp(i)=tmp1 !according to residuals |
341 |
|
|
else |
342 |
|
|
tmp(i)=-tmp1 |
343 |
|
|
endif |
344 |
|
|
residual(i)=tmp2 - tmp(i) |
345 |
|
|
chi=chi + residual(i)**2. |
346 |
|
|
c print*,dep(i) !??? |
347 |
|
|
c print*,indep(i) !??? |
348 |
|
|
c print*,tmp1,tmp2,tmp(i),residual(i) !??? |
349 |
|
|
enddo |
350 |
|
|
|
351 |
|
|
c------------------------------------------------------------------------ |
352 |
|
|
c it computes the angle between the tangent to the circumference and the |
353 |
|
|
c independent variable axis |
354 |
|
|
c------------------------------------------------------------------------ |
355 |
|
|
do i=1,npoints |
356 |
|
|
angle(i)=(zc-indep(i)) / tmp(i) |
357 |
|
|
angle(i)=ATAN(angle(i)) !-pi/2 <= angle <= pi/2 |
358 |
|
|
angle(i)=angle(i)/pigr*180. |
359 |
|
|
enddo |
360 |
|
|
|
361 |
|
|
return |
362 |
|
|
end |
363 |
|
|
|
364 |
|
|
|
365 |
|
|
|
366 |
|
|
|
367 |
|
|
|
368 |
|
|
|
369 |
|
|
|
370 |
|
|
|
371 |
|
|
|
372 |
|
|
|
373 |
|
|
c------------------------------------------------------------------------ |
374 |
|
|
c------------------------------------------------------------------------ |
375 |
|
|
c------------------------------------------------------------------------ |
376 |
|
|
|
377 |
|
|
|
378 |
|
|
c$$$c------------------------------------------------------------------------ |
379 |
|
|
c$$$c Function to find the factorial value |
380 |
|
|
c$$$c------------------------------------------------------------------------ |
381 |
|
|
c$$$ |
382 |
|
|
c$$$c from http://www.digitalcoding.com/programming/fortran/tutorial/ftute10.htm |
383 |
|
|
c$$$ |
384 |
|
|
c$$$ |
385 |
|
|
c$$$ FUNCTION FACT(N) |
386 |
|
|
c$$$ FACT=1 |
387 |
|
|
c$$$ DO 10 J=2,N |
388 |
|
|
c$$$ FACT=FACT*J |
389 |
|
|
c$$$10 CONTINUE |
390 |
|
|
c$$$ RETURN |
391 |
|
|
c$$$ END |
392 |
|
|
c$$$ |
393 |
|
|
c$$$c------------------------------------------------------------------------ |