/[PAMELA software]/DarthVader/TrackerLevel2/src/F77/tricircle.f
ViewVC logotype

Annotation of /DarthVader/TrackerLevel2/src/F77/tricircle.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (hide annotations) (download)
Tue Aug 28 13:25:49 2007 UTC (17 years, 3 months ago) by pam-fi
Branch: MAIN
CVS Tags: v5r00, v4r00, v6r01, v6r00
Changes since 1.2: +13 -13 lines
minor bug in tricircle call

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

  ViewVC Help
Powered by ViewVC 1.1.23