JHUGen MELA  v2.4.1
Matrix element calculations as used in JHUGen. MELA is an important tool that was used for the Higgs boson discovery and for precise measurements of its structure and interactions. Please see the website https://spin.pha.jhu.edu/ and papers cited there for more details, and kindly cite those papers when using this code.
mod_Misc.F90
Go to the documentation of this file.
1 MODULE modmisc
2 implicit none
3 
4 
5 INTERFACE swap
6  MODULE PROCEDURE swapi
7  MODULE PROCEDURE swapr
8  MODULE PROCEDURE swapc
9  MODULE PROCEDURE swap_mom
10  MODULE PROCEDURE swap_cmom
11 END INTERFACE swap
12 
13 INTERFACE OPERATOR (.dot.)
14  MODULE PROCEDURE minkowskyproduct
15  MODULE PROCEDURE minkowskyproductc
16  MODULE PROCEDURE minkowskyproductrc
17  MODULE PROCEDURE minkowskyproductcr
18 END INTERFACE OPERATOR (.dot.)
19 
20 INTERFACE OPERATOR (.cross.)
21  MODULE PROCEDURE vectorcross
22 END INTERFACE OPERATOR (.cross.)
23 
24 interface bublesort
25  module procedure bublesort_integerinteger,bublesort_realinteger, bublesort_stringlogical, bublesort_stringinteger, bublesort_stringreal8, bublesort_stringcomplex8, bublesort_stringstring
26 end interface bublesort
27 
28 interface reorder
29  module procedure reorder_integerinteger,reorder_integerreal
30 end interface reorder
31 
32 
33 contains
34 
35 
36 
37 FUNCTION vectorcross(p1,p2)
38 implicit none
39 real(8), intent(in) :: p1(1:3),p2(1:3)
40 real(8) :: vectorcross(1:3)
41 
42  vectorcross(1) = p1(2)*p2(3) - p1(3)*p2(2)
43  vectorcross(2) = p1(3)*p2(1) - p1(1)*p2(3)
44  vectorcross(3) = p1(1)*p2(2) - p1(2)*p2(1)
45 END FUNCTION vectorcross
46 
47 
48 
49 FUNCTION minkowskyproduct(p1,p2)
50 implicit none
51 real(8), intent(in) :: p1(1:4),p2(1:4)
52 real(8) :: minkowskyproduct
53 
54  minkowskyproduct = p1(1)*p2(1) &
55  - p1(2)*p2(2) &
56  - p1(3)*p2(3) &
57  -p1(4)*p2(4)
58 END FUNCTION minkowskyproduct
59 
60 FUNCTION minkowskyproductc(p1,p2)
61 implicit none
62 complex(8), intent(in) :: p1(1:4),p2(1:4)
63 complex(8) :: minkowskyproductc
64 
65  minkowskyproductc = p1(1)*p2(1) &
66  - p1(2)*p2(2) &
67  - p1(3)*p2(3) &
68  - p1(4)*p2(4)
69 END FUNCTION minkowskyproductc
70 
71 FUNCTION minkowskyproductrc(p1,p2)
72 implicit none
73 real(8), intent(in) :: p1(1:4)
74 complex(8), intent(in) :: p2(1:4)
75 complex(8) :: minkowskyproductrc
76 
77  minkowskyproductrc = p1(1)*p2(1) &
78  - p1(2)*p2(2) &
79  - p1(3)*p2(3) &
80  - p1(4)*p2(4)
81 END FUNCTION minkowskyproductrc
82 
83 FUNCTION minkowskyproductcr(p1,p2)
84 implicit none
85 real(8), intent(in) :: p2(1:4)
86 complex(8), intent(in) :: p1(1:4)
87 complex(8) :: minkowskyproductcr
88 
89  minkowskyproductcr = p1(1)*p2(1) &
90  - p1(2)*p2(2) &
91  - p1(3)*p2(3) &
92  - p1(4)*p2(4)
93 END FUNCTION minkowskyproductcr
94 
95 
96 function logicaltointeger(var)
97 implicit none
98 logical :: var
99 integer :: logicaltointeger
100  if (var) then
101  logicaltointeger = 1
102  else
103  logicaltointeger = 0
104  endif
105 end function
106 
107 
108 double complex function et1(e1,e2,e3,e4)
109 implicit none
110 complex(8), intent(in) :: e1(4), e2(4), e3(4), e4(4)
111  et1 = e1(1)*e2(2)*e3(3)*e4(4)-e1(1)*e2(2)*e3(4)*e4(3) &
112  -e1(1)*e2(3)*e3(2)*e4(4)+e1(1)*e2(3)*e3(4)*e4(2) &
113  +e1(1)*e2(4)*e3(2)*e4(3)-e1(1)*e2(4)*e3(3)*e4(2) &
114  -e1(2)*e2(1)*e3(3)*e4(4)+e1(2)*e2(1)*e3(4)*e4(3) &
115  +e1(2)*e2(3)*e3(1)*e4(4)-e1(2)*e2(3)*e3(4)*e4(1) &
116  -e1(2)*e2(4)*e3(1)*e4(3)+e1(2)*e2(4)*e3(3)*e4(1) &
117  +e1(3)*e2(1)*e3(2)*e4(4)-e1(3)*e2(1)*e3(4)*e4(2) &
118  -e1(3)*e2(2)*e3(1)*e4(4)+e1(3)*e2(2)*e3(4)*e4(1) &
119  +e1(3)*e2(4)*e3(1)*e4(2)-e1(3)*e2(4)*e3(2)*e4(1) &
120  -e1(4)*e2(1)*e3(2)*e4(3)+e1(4)*e2(1)*e3(3)*e4(2) &
121  +e1(4)*e2(2)*e3(1)*e4(3)-e1(4)*e2(2)*e3(3)*e4(1) &
122  -e1(4)*e2(3)*e3(1)*e4(2)+e1(4)*e2(3)*e3(2)*e4(1)
123  return
124 end function et1
125 
126 double complex function sc(q1,q2)
127 implicit none
128 complex(8), intent(in) :: q1(4)
129 complex(8), intent(in) :: q2(4)
130  sc = q1.dot.q2
131  return
132 end function sc
133 
134 double precision function scr(p1,p2)
135 implicit none
136 real(8), intent(in) :: p1(4),p2(4)
137  scr = p1.dot.p2
138  return
139 end function scr
140 
141 double complex function scrc(p1,p2)
142 implicit none
143 real(8), intent(in) :: p1(4)
144 complex(8), intent(in) :: p2(4)
145  scrc = p1.dot.p2
146  return
147 end function scrc
148 
149 
150 
151 FUNCTION get_pt(Mom)
152 implicit none
153 real(8) ::mom(1:4),get_pt
154 
155  get_pt = dsqrt( mom(2)**2 + mom(3)**2 )
156 
157 RETURN
158 END FUNCTION
159 
160 
161 FUNCTION get_pt2(Mom)
162 implicit none
163 real(8) ::mom(1:4),get_pt2
164 
165  get_pt2 = mom(2)**2 + mom(3)**2
166 
167 RETURN
168 END FUNCTION
169 
170 
171 FUNCTION get_minv(Mom)
172 implicit none
173 real(8) ::mom(1:4),get_minv
174 
175  get_minv = dsqrt( dabs(mom(1:4).dot.mom(1:4)) )
176 
177 RETURN
178 END FUNCTION
179 
180 FUNCTION get_minv2(Mom)
181 implicit none
182 real(8) ::mom(1:4),get_minv2
183 
184  get_minv2 = mom(1:4).dot.mom(1:4)
185 
186 RETURN
187 END FUNCTION
188 
189 FUNCTION get_eta(Mom)
190 implicit none
191 real(8) ::mom(1:4),get_eta
192 
193  get_eta = 0.5d0*dlog( dabs((mom(1)+mom(4)+1d-16)/(mom(1)-mom(4) +1d-16) ))
194 
195 RETURN
196 END FUNCTION
197 
198 
199 FUNCTION get_phi(Mom)
200 implicit none
201 real(8) ::mom(1:4),get_phi
202 
203  get_phi = datan2( mom(3),mom(2) )
204 
205 RETURN
206 END FUNCTION
207 
208 
209 
210 
211 FUNCTION get_cosalpha(Mom1,Mom2)
212 implicit none
213 real(8) ::mom1(1:4),mom2(1:4),get_cosalpha
214 
215  get_cosalpha = (mom1(2)*mom2(2)+mom1(3)*mom2(3)+mom1(4)*mom2(4))/dsqrt(mom1(2)**2+mom1(3)**2+mom1(4)**2)/dsqrt(mom2(2)**2+mom2(3)**2+mom2(4)**2)
216 
217 RETURN
218 END FUNCTION
219 
220 
221 FUNCTION get_costheta(Mom)! = Mom.nz/abs(Mom)
222 implicit none
223 real(8) ::mom(1:4), get_costheta
224 
225  get_costheta = mom(4)/dsqrt( mom(2)**2+mom(3)**2+mom(4)**2 +1d-16)
226 
227 RETURN
228 END FUNCTION
229 
230 
231 
232 FUNCTION get_r(Mom1,Mom2)
233 implicit none
234 real(8),parameter :: pi=3.141592653589793d0
235 real(8) :: mom1(1:4),mom2(1:4),get_r
236 real(8) :: eta1,eta2,phi1,phi2,deltaphi,r2,delphi
237 
238  eta1 = get_eta(mom1(1:4))
239  eta2 = get_eta(mom2(1:4))
240  phi1 = get_phi(mom1(1:4))
241  phi2 = get_phi(mom2(1:4))
242  deltaphi = dabs(phi1-phi2)
243  if( deltaphi.gt.pi ) deltaphi=2d0*pi-deltaphi
244  get_r = dsqrt((eta1-eta2)**2 + deltaphi**2)
245 
246 RETURN
247 END FUNCTION
248 
249 
250 
251 
252 SUBROUTINE pt_order(N,Mom)
253 implicit none
254 integer :: N
255 real(8) :: Mom(1:4,1:N),Mom_Tmp(1:4,1:N),pTList(1:N)
256 integer :: i,MomOrder(1:N)
257 
258 
259  if(n.lt.1) return
260  do i=1,n
261  ptlist(i) = get_pt(mom(1:4,i))
262  momorder(i) = i
263  enddo
264 
265  call bublesort(n,ptlist(1:n),momorder(1:n))
266 
267  mom_tmp(1:4,1:n) = mom(1:4,1:n)
268  do i=1,n
269  mom(1:4,i) = mom_tmp(1:4,momorder(i))
270  enddo
271 
272 END SUBROUTINE
273 
274 
275 
276 #define MakeBubleSort(typex, typey, name) \
277 SUBROUTINE name(N,X, IY) ;\
278 IMPLICIT NONE ;\
279 integer n ;\
280 typex :: x(1:n) ;\
281 typey :: iy(1:n) ;\
282 typex :: temp ;\
283 integer :: i, j, jmax ;\
284 typey :: itemp ;\
285 logical :: keepgoing ;\
286  ;\
287  keepgoing = .true. ;\
288  jmax=n-1 ;\
289  do i=1,n-1 ;\
290  keepgoing = .false. ;\
291  do j=1,jmax ;\
292  if(x(j).gt.x(j+1)) cycle ;\
293  keepgoing = .true. ;\
294  temp=x(j) ;\
295  x(j)=x(j+1) ;\
296  x(j+1)=temp ;\
297  itemp=iy(j) ;\
298  iy(j)=iy(j+1) ;\
299  iy(j+1)=itemp ;\
300  enddo ;\
301  if(.not.keepgoing) return ;\
302  jmax=jmax-1 ;\
303  enddo ;\
304  ;\
305 RETURN ;\
306 END SUBROUTINE
307 
308 makebublesort(integer(8), integer, BubleSort_integerinteger)
309 makebublesort(real(8), integer, BubleSort_realinteger)
310 makebublesort(character(len=100), logical, BubleSort_stringlogical)
311 makebublesort(character(len=100), integer, BubleSort_stringinteger)
312 makebublesort(character(len=100), real(8), BubleSort_stringreal8)
313 makebublesort(character(len=100), complex(8), BubleSort_stringcomplex8)
314 makebublesort(character(len=100), character(len=100), BubleSort_stringstring)
315 
316 #undef MakeBubleSort
317 
318 ! check the routine
319 ! real(8) :: x(1:10)
320 ! integer :: iy(1:10)
321 ! x(1:10) = (/3d0,62d0,2d0,78d0,32d0,87d0,1d0,199d0,4d0,73d0/)
322 ! iy(1:10) = (/1,2,3,4,5,6,7,8,9,10/)
323 ! print *, x(:)
324 ! call BubleSort(10,X(1:10), IY)
325 ! print *, x(:)
326 ! print *, iy(:)
327 ! stop
328 
329 
330 #define MakeReOrder(typey, typex, name) \
331 SUBROUTINE name(N, iy,x) ;\
332 integer :: n,i ;\
333 typex :: x(1:n) ;\
334 typey :: iy(1:n) ;\
335 typex :: temp(1:n) ;\
336  ;\
337  do i=1,n ;\
338  temp(i) = x( iy(i) ) ;\
339  enddo ;\
340  x(1:n) = temp(1:n) ;\
341  ;\
342 RETURN ;\
343 END SUBROUTINE ;\
344 
345 makereorder(integer,integer, ReOrder_integerinteger)
346 makereorder(integer, real(8), ReOrder_integerreal)
347 #undef MakeReOrder
348 
349 
350 SUBROUTINE printmom(Mom)
351 implicit none
352 real(8) :: Mom(:,:)
353 integer :: n
354 
355  do n=1,size(mom,2)
356  write (*,"(A,I2,A,1F20.16,A,1F20.16,A,1F20.16,A,1F20.16,A)") "Mom(1:4,",n,")= (/",mom(1,n),"d0,",mom(2,n),"d0,",mom(3,n),"d0,",mom(4,n),"d0 /)"
357  enddo
358 
359 RETURN
360 END SUBROUTINE
361 
362 
363 
364 
365 SUBROUTINE error(Message,ErrNum)
366 implicit none
367 character(*) :: Message
368 integer,optional :: ErrNum
369 
370  if( present(errnum) ) then
371  print *, "ERROR: ",message,errnum
372  else
373  print *, "ERROR: ",message
374  endif
375  stop 1
376 END SUBROUTINE
377 
378 
379 FUNCTION isnan(x)
380 implicit none
381 logical isnan
382 real(8) :: x
383 
384  isnan = .not.(x.eq.x)
385 
386 RETURN
387 END FUNCTION
388 
389 
390 
391 
392 SUBROUTINE swapi(i,j)
393 implicit none
394 integer :: i,j,temp
395 
396  temp=j
397  j=i
398  i=temp
399 
400 END SUBROUTINE
401 
402 SUBROUTINE swapr(i,j)
403 implicit none
404 real(8) :: i,j,temp
405 
406  temp=j
407  j=i
408  i=temp
409 
410 END SUBROUTINE
411 
412 SUBROUTINE swapc(i,j)
413 implicit none
414 complex(8) :: i,j,temp
415 
416  temp=j
417  j=i
418  i=temp
419 
420 END SUBROUTINE
421 
422 SUBROUTINE swap_mom(Mom1,Mom2)
423 implicit none
424 real(8) :: Mom1(1:4),Mom2(1:4),tmp(1:4)
425 
426  tmp(1:4) = mom2(1:4)
427  mom2(1:4) = mom1(1:4)
428  mom1(1:4) = tmp(1:4)
429 
430 RETURN
431 END SUBROUTINE
432 
433 SUBROUTINE swap_cmom(Mom1,Mom2)
434 implicit none
435 complex(8) :: Mom1(1:4),Mom2(1:4),tmp(1:4)
436 
437  tmp(1:4) = mom2(1:4)
438  mom2(1:4) = mom1(1:4)
439  mom1(1:4) = tmp(1:4)
440 
441 RETURN
442 END SUBROUTINE
443 
444 
445 
446 
447 FUNCTION leviciv(e1,e2,e3,e4)
448 implicit none
449 complex(8), intent(in) :: e1(4), e2(4), e3(4), e4(4)
450 complex(8) ::leviciv
451 
452 leviciv = e1(1)*e2(2)*e3(3)*e4(4)-e1(1)*e2(2)*e3(4)*e4(3) &
453  -e1(1)*e2(3)*e3(2)*e4(4)+e1(1)*e2(3)*e3(4)*e4(2) &
454  +e1(1)*e2(4)*e3(2)*e4(3)-e1(1)*e2(4)*e3(3)*e4(2) &
455  -e1(2)*e2(1)*e3(3)*e4(4)+e1(2)*e2(1)*e3(4)*e4(3) &
456  +e1(2)*e2(3)*e3(1)*e4(4)-e1(2)*e2(3)*e3(4)*e4(1) &
457  -e1(2)*e2(4)*e3(1)*e4(3)+e1(2)*e2(4)*e3(3)*e4(1) &
458  +e1(3)*e2(1)*e3(2)*e4(4)-e1(3)*e2(1)*e3(4)*e4(2) &
459  -e1(3)*e2(2)*e3(1)*e4(4)+e1(3)*e2(2)*e3(4)*e4(1) &
460  +e1(3)*e2(4)*e3(1)*e4(2)-e1(3)*e2(4)*e3(2)*e4(1) &
461  -e1(4)*e2(1)*e3(2)*e4(3)+e1(4)*e2(1)*e3(3)*e4(2) &
462  +e1(4)*e2(2)*e3(1)*e4(3)-e1(4)*e2(2)*e3(3)*e4(1) &
463  -e1(4)*e2(3)*e3(1)*e4(2)+e1(4)*e2(3)*e3(2)*e4(1)
464 
465 END FUNCTION
466 
467 
468 FUNCTION pol_gluon_incoming(p,hel)
469 implicit none
470 complex(8) :: pol_gluon_incoming(1:4)
471 real(8) :: p(1:4)
472 integer :: hel
473 real(8) :: pv,ct,st,cphi,sphi
474 
475 
476  pv=dsqrt(dabs(p(1)**2))
477  ct=p(4)/pv
478  st=dsqrt(abs(1.0d0-ct**2))
479 
480  if( st.le.1d-9 ) then
481  cphi=1.0d0
482  sphi=0.0d0
483  else
484  cphi= p(2)/pv/st
485  sphi= p(3)/pv/st
486  endif
487  ! -- distinguish between positive and negative energies
488 ! if ( p(1) .gt. 0.0_dp) then
489 ! hel=hel
490 ! else
491 ! hel=-hel
492 ! endif
493 
494 ! if (present(outgoing)) then
495 ! if (outgoing) pol = -pol
496 ! endif
497 
498  pol_gluon_incoming(1) = 0d0
499  pol_gluon_incoming(2) = ct*cphi - (0d0,1d0)*hel*sphi
500  pol_gluon_incoming(3) = ct*sphi + (0d0,1d0)*hel*cphi
501  pol_gluon_incoming(4) = -st
502 
503  pol_gluon_incoming(2:4) = pol_gluon_incoming(2:4)/dsqrt(2.0d0)
504 END FUNCTION
505 
506 FUNCTION pol_zff_outgoing(pf,pfbar,hel) ! does not contain the division by 1/q^2 as in pol_dk2mom
507 implicit none
508 complex(8) :: pol_zff_outgoing(4)
509 integer :: hel
510 real(8):: pf(1:4),pfbar(1:4)
511 complex(8) :: ub(1:4),v(1:4)
512  ub(1:4) = ubar_spinor(pf,hel)
513  v(1:4) = v_spinor(pfbar,-hel)
514 
515  ! This is an expression for (-i)* (-i) Ub(+/-)) Gamma^\mu V(-/+)
516  pol_zff_outgoing(1)=-(ub(2)*v(4)+v(2)*ub(4)+ub(1)*v(3)+v(1)*ub(3))
517  pol_zff_outgoing(2)=-(-ub(1)*v(4)+v(1)*ub(4)-ub(2)*v(3)+v(2)*ub(3))
518  pol_zff_outgoing(3)=-(0d0,1d0)*(ub(1)*v(4)+v(1)*ub(4)-ub(2)*v(3)-v(2)*ub(3))
519  pol_zff_outgoing(4)=-(ub(2)*v(4)-v(2)*ub(4)-ub(1)*v(3)+v(1)*ub(3))
520 RETURN
521 END FUNCTION
522 
523 
524 ! ubar spinor, massless
525 FUNCTION ubar_spinor(p,hel)
526 implicit none
527 real(8) :: p(1:4)
528 integer :: hel
529 complex(8) :: ubar_spinor(1:4)
530 complex(8) :: fc, fc2
531 
532 
533  fc2 = p(1) + p(4)
534  fc=sqrt(fc2)
535 
536  if( abs(fc2).gt.1d-9 ) then
537  if(hel.eq.1) then
538  ubar_spinor(1)=0d0
539  ubar_spinor(2)=0d0
540  ubar_spinor(3)=fc
541  ubar_spinor(4)=(p(2)-(0d0,1d0)*p(3))/fc
542  elseif (hel.eq.-1) then
543  ubar_spinor(1)=(p(2)+(0d0,1d0)*p(3))/fc
544  ubar_spinor(2)=-fc
545  ubar_spinor(3)=0d0
546  ubar_spinor(4)=0d0
547  endif
548  else
549  if(hel.eq.1) then
550  ubar_spinor(1) = 0d0
551  ubar_spinor(2) = 0d0
552  ubar_spinor(3) = 0d0
553  ubar_spinor(4) = dsqrt(2*p(1))
554  elseif (hel.eq.-1) then
555  ubar_spinor(1) = dsqrt((2*p(1)))
556  ubar_spinor(2) = 0d0
557  ubar_spinor(3) = 0d0
558  ubar_spinor(4) = 0d0
559  endif
560  endif
561 
562 RETURN
563 END FUNCTION
564 
565 ! -- v0 spinor, massless
566 FUNCTION v_spinor(p,hel)
567 implicit none
568 real(8) :: p(1:4)
569 integer :: hel
570 complex(8) :: v_spinor(1:4)
571 complex(8) :: fc2, fc
572 
573 
574  fc2 = p(1) + p(4)
575  fc=sqrt(fc2)
576 
577  if( abs(fc2).gt.1d-9 ) then
578  if(hel.eq.1) then
579  v_spinor(1)=0d0
580  v_spinor(2)=0d0
581  v_spinor(3)=(p(2)-(0d0,1d0)*p(3))/fc
582  v_spinor(4)=-fc
583  elseif (hel.eq.-1) then
584  v_spinor(1)=fc
585  v_spinor(2)=(p(2)+(0d0,1d0)*p(3))/fc
586  v_spinor(3)=0d0
587  v_spinor(4)=0d0
588  endif
589  else
590  if(hel.eq.1) then
591  v_spinor(1)=0d0
592  v_spinor(2)=0d0
593  v_spinor(3)=dsqrt(2*p(1))
594  v_spinor(4)=0d0
595  elseif (hel.eq.-1) then
596  v_spinor(1)=0d0
597  v_spinor(2)=dsqrt(2*p(1))
598  v_spinor(3)=0d0
599  v_spinor(4)=0d0
600  endif
601  endif
602 
603 RETURN
604 END FUNCTION
605 
606 function chir_weyl(sign,sp) ! Chir = sp.omega_sign = omega_sign.sp
607 implicit none
608 integer :: sign
609 double complex :: sp(1:4)
610 double complex :: chir_weyl(1:4)
611  if(sign.eq.+1) then !omega_+
612  chir_weyl(1) = sp(1)
613  chir_weyl(2) = sp(2)
614  chir_weyl(3) = 0d0
615  chir_weyl(4) = 0d0
616  else !omega_-
617  chir_weyl(1) = 0d0
618  chir_weyl(2) = 0d0
619  chir_weyl(3) = sp(3)
620  chir_weyl(4) = sp(4)
621  endif
622  return
623 end function
624 
625 FUNCTION vbqq_weyl(sp1,sp2)
626 implicit none
627 complex(8), intent(in) :: sp1(:), sp2(:)
628 integer, parameter :: dv=4
629 integer :: i
630 complex(8) :: vbqq_weyl(dv)
631 complex(8) :: rr, va(dv),sp1a(4)
632 
633  va=(0d0,0d0)
634  vbqq_weyl=(0d0,0d0)
635 
636  do i=1,dv
637  if (i.eq.1) then
638  va(1)=(1d0,0d0)
639  else
640  va(i)=(-1d0,0d0)
641  endif
642  sp1a=spb2_weyl(sp1,va)
643 
644 
645  rr=sum(sp1a(1:4)*sp2(1:4))
646  if (i.eq.1) then
647  vbqq_weyl = vbqq_weyl + rr*va
648  else
649  vbqq_weyl = vbqq_weyl - rr*va
650  endif
651  va(i)=(0d0,0d0)
652  enddo
653 
654 END FUNCTION
655 
656 function spb2_weyl(sp,v)
657 implicit none
658 complex(8), intent(in) :: sp(:),v(:)
659 complex(8) :: spb2_weyl(4)
660 complex(8) :: x0(4,4),xx(4,4),xy(4,4)
661 complex(8) :: xz(4,4),x5(4,4)
662 complex(8) :: y1,y2,y3,y4,bp,bm,cp,cm
663 integer :: i,i1,i2,i3,dv,ds,imax
664 
665  ds = 4
666  dv = 4
667  imax = ds/4
668 
669  do i=1,imax
670  i1= 1+4*(i-1)
671  i2=i1+3
672 
673  y1=sp(i1)
674  y2=sp(i1+1)
675  y3=sp(i1+2)
676  y4=sp(i1+3)
677 
678  x0(1,i)=y3
679  x0(2,i)=y4
680  x0(3,i)=y1
681  x0(4,i)=y2
682 
683  xx(1,i) = y4
684  xx(2,i) = y3
685  xx(3,i) = -y2
686  xx(4,i) = -y1
687 
688  xy(1,i)=(0d0,1d0)*y4
689  xy(2,i)=-(0d0,1d0)*y3
690  xy(3,i)=-(0d0,1d0)*y2
691  xy(4,i)=(0d0,1d0)*y1
692 
693  xz(1,i)=y3
694  xz(2,i)=-y4
695  xz(3,i)=-y1
696  xz(4,i)=y2
697 
698  x5(1,i)=y1
699  x5(2,i)=y2
700  x5(3,i)=-y3
701  x5(4,i)=-y4
702  enddo
703 
704 
705  do i=1,4
706  spb2_weyl(i)=v(1)*x0(i,1)-v(2)*xx(i,1)-v(3)*xy(i,1)-v(4)*xz(i,1)
707  enddo
708 end function
709 
710 function spi2_weyl(v,sp)
711 implicit none
712 complex(8), intent(in) :: sp(:),v(:)
713 complex(8) :: spi2_weyl(4)
714 complex(8) :: x0(4,4),xx(4,4),xy(4,4)
715 complex(8) :: xz(4,4),x5(4,4)
716 complex(8) :: y1,y2,y3,y4,bp,bm,cp,cm
717 integer :: i,i1,i2,i3,imax,dv,ds
718 
719  ds = 4
720  dv = 4
721 
722  imax = ds/4
723 
724  do i=1,imax
725  i1= 1+4*(i-1)
726  i2=i1+3
727 
728  y1=sp(i1)
729  y2=sp(i1+1)
730  y3=sp(i1+2)
731  y4=sp(i1+3)
732 
733  x0(1,i)=y3
734  x0(2,i)=y4
735  x0(3,i)=y1
736  x0(4,i)=y2
737 
738 
739  xx(1,i) = -y4
740  xx(2,i) = -y3
741  xx(3,i) = y2
742  xx(4,i) = y1
743 
744 
745  xy(1,i)=(0d0,1d0)*y4
746  xy(2,i)=-(0d0,1d0)*y3
747  xy(3,i)=-(0d0,1d0)*y2
748  xy(4,i)=(0d0,1d0)*y1
749 
750  xz(1,i)=-y3
751  xz(2,i)=y4
752  xz(3,i)=y1
753  xz(4,i)=-y2
754 
755  x5(1,i)=y1
756  x5(2,i)=y2
757  x5(3,i)=-y3
758  x5(4,i)=-y4
759  enddo
760  do i=1,4
761  spi2_weyl(i)=v(1)*x0(i,1)-v(2)*xx(i,1) -v(3)*xy(i,1)-v(4)*xz(i,1)
762  enddo
763 end function
764 
765 
766 
767 
768 function findinputfmt0(EventInfoLine)
769 implicit none
770 character(len=*) :: eventinfoline
771 character(len=150) findinputfmt0
772 integer :: i, j, fieldwidth, spaces(1:6)
773 integer :: processidcharacters, weightscaleaqedaqcdcharacters(1:4), weightscaleaqedaqcdafterdecimal(1:4)
774 character(len=40) :: formatparts(1:6)
775 
776 !find the number of spaces at the beginning
777 spaces(1) = 0
778 i = 1
779 do while (eventinfoline(i:i) .eq. " ")
780  i = i+1
781  spaces(1) = spaces(1)+1
782 end do
783 !now find the width of the number of particles, assume it's right aligned with a max of 2 digits
784 fieldwidth = 0
785 do while (eventinfoline(i:i) .ne. " ")
786  i = i+1
787  fieldwidth = fieldwidth+1
788 end do
789 spaces(1) = spaces(1) + fieldwidth - 2
790 
791 !spaces and process id.
792 !"The process ID’s are not intended to be generic" [arXiv:0109068]
793 !I will assume that however many digits they are, they're right aligned
794 
795 processidcharacters = -1 !so that it's 0 after the first space
796 spaces(2) = 1 !this is not increased, it's exactly 1
797 do while (eventinfoline(i:i) .eq. " ")
798  i = i+1
799  processidcharacters = processidcharacters+1
800 end do
801 do while (eventinfoline(i:i) .ne. " ")
802  i = i+1
803  processidcharacters = processidcharacters+1
804 end do
805 
806 !the rest of the fields (scale, alpha_QED, alpha_QCD) are decimals
807 do j=1,4
808  spaces(j+2) = 0
809  do while (eventinfoline(i:i) .eq. " ")
810  i = i+1
811  spaces(j+2) = spaces(j+2)+1
812  end do
813  if (eventinfoline(i:i) .eq. "-") then
814  i = i+1
815  weightscaleaqedaqcdcharacters(j) = 1 !we are already past the -
816  else if (spaces(j+2).eq.1) then
817  weightscaleaqedaqcdcharacters(j) = 0
818  else
819  spaces(j+2) = spaces(j+2)-1 !because the place where the - sign is supposed to go is not always a space
820  weightscaleaqedaqcdcharacters(j) = 1 !we are already past the -
821  endif
822  do while (eventinfoline(i:i) .ne. " ")
823  i = i+1
824  weightscaleaqedaqcdcharacters(j) = weightscaleaqedaqcdcharacters(j)+1
825  end do
826  weightscaleaqedaqcdafterdecimal(j) = weightscaleaqedaqcdcharacters(j)-7
827 end do
828 
829 !now we construct the format string
830 if (spaces(1).eq.0) then
831  formatparts(1) = "(I2,"
832 else
833  write(formatparts(1), "(A,I1,A)") "(", spaces(1), "X,I2,"
834 endif
835 if (processidcharacters.lt.10) then
836  write(formatparts(2), "(I1,A,I1,A)") spaces(2), "X,I", processidcharacters !the comma is at the beginning of the next part
837 else
838  write(formatparts(2), "(I1,A,I2)") spaces(2), "X,I", processidcharacters !the comma is at the beginning of the next part
839 endif
840 do j=1,4
841  if (weightscaleaqedaqcdcharacters(j).lt.10) then
842  write(formatparts(j+2), "(A,I1,A,I1,A,I1)") ",", spaces(j+2), "X,1PE", weightscaleaqedaqcdcharacters(j), ".", weightscaleaqedaqcdafterdecimal(j)
843  elseif (weightscaleaqedaqcdcharacters(j).lt.17) then
844  write(formatparts(j+2), "(A,I1,A,I2,A,I1)") ",", spaces(j+2), "X,1PE", weightscaleaqedaqcdcharacters(j), ".", weightscaleaqedaqcdafterdecimal(j)
845  else
846  write(formatparts(j+2), "(A,I1,A,I2,A,I2)") ",", spaces(j+2), "X,1PE", weightscaleaqedaqcdcharacters(j), ".", weightscaleaqedaqcdafterdecimal(j)
847  endif
848 end do
849 
850 findinputfmt0 = (trim(formatparts(1)) &
851  // trim(formatparts(2)) &
852  // trim(formatparts(3)) &
853  // trim(formatparts(4)) &
854  // trim(formatparts(5)) &
855  // trim(formatparts(6)) &
856  // ")")
857 
858 return
859 end function findinputfmt0
860 
861 
862 
863 function findinputfmt1(ParticleLine)
864 implicit none
865 character(len=*) :: particleline
866 integer :: i, j, fieldwidth, spaces(1:13)
867 character(len=150) :: findinputfmt1
868 integer :: momentumcharacters(1:5), lifetimecharacters, lifetimedigitsafterdecimal, spincharacters, spindigitsafterdecimal
869 logical :: lifetimeisexponential, spinisexponential
870 character(len=40) :: formatparts(11)
871 !first find the number of spaces at the beginning
872 i = 1
873 spaces(1) = 0
874 do while (particleline(i:i) .eq. " ")
875  i = i+1
876  spaces(1) = spaces(1)+1
877 end do
878 !now find the width of the id; assume it's right aligned.
879 fieldwidth = 0
880 do while (particleline(i:i) .ne. " ")
881  i = i+1
882  fieldwidth = fieldwidth+1
883 end do
884 spaces(1) = spaces(1) + fieldwidth - 3
885 
886 !number of spaces between the id and the status
887 spaces(2) = 0
888 do while (particleline(i:i) .eq. " ")
889  i = i+1
890  spaces(2) = spaces(2)+1
891 end do
892 !width of the status (should be -1, so width 2, but just in case)
893 fieldwidth = 0
894 do while (particleline(i:i) .ne. " ")
895  i = i+1
896  fieldwidth = fieldwidth+1
897 end do
898 spaces(2) = spaces(2) + fieldwidth - 2
899 
900 !number of spaces between the status and the first mother
901 spaces(3) = 0
902 do while (particleline(i:i) .eq. " ")
903  i = i+1
904  spaces(3) = spaces(3)+1
905 end do
906 fieldwidth = 0
907 do while (particleline(i:i) .ne. " ")
908  i = i+1
909  fieldwidth = fieldwidth+1
910 end do
911 spaces(3) = spaces(3) + fieldwidth - 2
912 
913 !number of spaces between the mothers
914 spaces(4) = 0
915 do while (particleline(i:i) .eq. " ")
916  i = i+1
917  spaces(4) = spaces(4)+1
918 end do
919 fieldwidth = 0
920 do while (particleline(i:i) .ne. " ")
921  i = i+1
922  fieldwidth = fieldwidth+1
923 end do
924 spaces(4) = spaces(4) + fieldwidth - 2
925 
926 !number of spaces between the second mother and the color
927 spaces(5) = 0
928 do while (particleline(i:i) .eq. " ")
929  i = i+1
930  spaces(5) = spaces(5)+1
931 end do
932 fieldwidth = 0
933 do while (particleline(i:i) .ne. " ")
934  i = i+1
935  fieldwidth = fieldwidth+1
936 end do
937 spaces(5) = spaces(5) + fieldwidth - 3
938 
939 !number of spaces between the color and the anticolor
940 spaces(6) = 0
941 do while (particleline(i:i) .eq. " ")
942  i = i+1
943  spaces(6) = spaces(6)+1
944 end do
945 fieldwidth = 0
946 do while (particleline(i:i) .ne. " ")
947  i = i+1
948  fieldwidth = fieldwidth+1
949 end do
950 spaces(6) = spaces(6) + fieldwidth - 3
951 
952 !From now on the alignment is simpler, every row will have the same width
953 ! except for possibly a - sign at the beginning
954 !Unfortunately now there's number formatting to worry about
955 do j=7,11 !px, py, pz, E, m
956  !spaces before the momentum component
957  spaces(j) = 0
958  do while (particleline(i:i) .eq. " ")
959  i = i+1
960  spaces(j) = spaces(j)+1
961  end do
962  if (particleline(i:i) .eq. "-") then
963  i = i+1
964  else
965  spaces(j) = spaces(j)-1 !because the place where the - sign is supposed to go is not always a space
966  endif
967  !i is now on the first actual digit (not -) of the component
968 
969  !number of characters used for the component
970  momentumcharacters(j-6) = 1 !we are already past the -
971  do while (particleline(i:i) .ne. " ")
972  i = i+1
973  momentumcharacters(j-6) = momentumcharacters(j-6)+1
974  end do
975 enddo
976 
977 !number of spaces between m and lifetime
978 !lifetime is nonnegative, so no - sign
979 !but some generators (JHUGen) write 0.00000000000E+00
980 !while some (old JHUGen, some versions of MadGraph) write 0.
981 spaces(12) = 0
982 do while (particleline(i:i) .eq. " ")
983  i = i+1
984  spaces(12) = spaces(12)+1
985 end do
986 
987 !lifetime formatting
988 lifetimecharacters = 0
989 lifetimedigitsafterdecimal = -1
990 lifetimeisexponential = .false.
991 do while (particleline(i:i) .ne. " ")
992  if ((lifetimedigitsafterdecimal .ge. 0 .and. .not.lifetimeisexponential) &
993  .or. particleline(i:i) .eq. ".") then
994  lifetimedigitsafterdecimal = lifetimedigitsafterdecimal+1
995  endif
996  if (particleline(i:i) .eq. "E" .or. particleline(i:i) .eq. "e") then
997  lifetimeisexponential = .true.
998  endif
999  i = i+1
1000  lifetimecharacters = lifetimecharacters+1
1001 enddo
1002 
1003 !number of spaces between lifetime and spin
1004 !spin has all the complications of lifetime, plus it might be negative
1005 spaces(13) = 0
1006 do while (particleline(i:i) .eq. " ")
1007  i = i+1
1008  spaces(13) = spaces(13)+1
1009 end do
1010 if (particleline(i:i) .eq. "-") then
1011  i = i+1
1012 else
1013  spaces(13) = spaces(13)-1 !because the place where the - sign is supposed to go is not always a space
1014 endif
1015 !i is now on the first digit of the spin
1016 
1017 !spin formatting
1018 spincharacters = 1 !we are already past the -
1019 spindigitsafterdecimal = -1
1020 spinisexponential = .false.
1021 do while (particleline(i:i) .ne. " ")
1022  if (spindigitsafterdecimal .ge. 0 .or. particleline(i:i) .eq. ".") then
1023  spindigitsafterdecimal = spindigitsafterdecimal+1
1024  endif
1025  if (particleline(i:i) .eq. "E" .or. particleline(i:i) .eq. "e") then
1026  spinisexponential = .true.
1027  endif
1028  i = i+1
1029  spincharacters = spincharacters+1
1030 enddo
1031 
1032 !check that spaces(i) > 0
1033 !(besides for spaces(1), before the id, which can be 0)
1034 !the only way this can happen, consistent with the definition of lhe format,
1035 ! is for a column not to leave extra space for a -
1036 do i=2,13
1037  if (spaces(i).eq.0) then
1038  spaces(i) = 1
1039  if (i.ge.7 .and. i.le.11) then !we counted the nonexistant space for - in MomentumCharacters(i-6)
1040  momentumcharacters(i-6) = momentumcharacters(i-6)-1
1041  endif
1042  if (i.eq.13) then !same
1043  spincharacters = spincharacters-1
1044  endif
1045  endif
1046 enddo
1047 
1048 !Ok, now we construct the format string
1049 !Initial spaces and id
1050 if (spaces(1).eq.0) then
1051  formatparts(1) = "(I3,"
1052 else
1053  write(formatparts(1),"(A,I1,A)") "(", spaces(1), "X,I3,"
1054 endif
1055 !spaces and status
1056 write(formatparts(2),"(I1,A)") spaces(2), "X,I2,"
1057 !spaces and mothers
1058 write(formatparts(3),"(I1,A,I1,A)") spaces(3), "X,I2,", spaces(4), "X,I2,"
1059 !spaces and colors
1060 write(formatparts(4),"(I1,A,I1,A)") spaces(5), "X,I3,", spaces(6), "X,I3,"
1061 
1062 do i=5,9
1063  !spaces and momentum components (and mass)
1064  if (momentumcharacters(i-4) .lt. 10) then
1065  write(formatparts(i),"(I1,A,I1,A,I1,A)") spaces(i+2), "X,1PE", momentumcharacters(i-4), ".", momentumcharacters(i-4)-7, ","
1066  elseif (momentumcharacters(i-4) .lt. 17) then
1067  write(formatparts(i),"(I1,A,I2,A,I1,A)") spaces(i+2), "X,1PE", momentumcharacters(i-4), ".", momentumcharacters(i-4)-7, ","
1068  else
1069  write(formatparts(i),"(I1,A,I2,A,I2,A)") spaces(i+2), "X,1PE", momentumcharacters(i-4), ".", momentumcharacters(i-4)-7, ","
1070  endif
1071 enddo
1072 
1073 !spaces and lifetime
1074 if (lifetimeisexponential) then
1075  if (lifetimecharacters .lt. 10) then
1076  write(formatparts(10),"(I1,A,I1,A,I1,A)") &
1077  spaces(12), "X,1PE",lifetimecharacters,".",lifetimedigitsafterdecimal,","
1078  elseif (lifetimedigitsafterdecimal.lt.10) then
1079  write(formatparts(10),"(I1,A,I2,A,I1,A)") &
1080  spaces(12), "X,1PE",lifetimecharacters,".",lifetimedigitsafterdecimal,","
1081  else
1082  write(formatparts(10),"(I1,A,I2,A,I2,A)") &
1083  spaces(12), "X,1PE",lifetimecharacters,".",lifetimedigitsafterdecimal,","
1084  endif
1085 else
1086  if (lifetimecharacters .lt. 10) then
1087  write(formatparts(10),"(I1,A,I1,A,I1,A)") &
1088  spaces(12), "X,1F",lifetimecharacters,".",lifetimedigitsafterdecimal,","
1089  elseif (lifetimedigitsafterdecimal.lt.10) then
1090  write(formatparts(10),"(I1,A,I2,A,I1,A)") &
1091  spaces(12), "X,1F",lifetimecharacters,".",lifetimedigitsafterdecimal,","
1092  else
1093  write(formatparts(10),"(I1,A,I2,A,I2,A)") &
1094  spaces(12), "X,1F",lifetimecharacters,".",lifetimedigitsafterdecimal,","
1095  endif
1096 endif
1097 
1098 !spaces and spin
1099 if (spinisexponential) then
1100  if (spincharacters .lt. 10) then
1101  write(formatparts(11),"(I1,A,I1,A,I1,A)") &
1102  spaces(13), "X,1PE",spincharacters,".",spindigitsafterdecimal,")"
1103  elseif (spindigitsafterdecimal.lt.10) then
1104  write(formatparts(11),"(I1,A,I2,A,I1,A)") &
1105  spaces(13), "X,1PE",spincharacters,".",spindigitsafterdecimal,")"
1106  else
1107  write(formatparts(11),"(I1,A,I2,A,I2,A)") &
1108  spaces(13), "X,1PE",spincharacters,".",spindigitsafterdecimal,")"
1109  endif
1110 else
1111  if (spincharacters .lt. 10) then
1112  write(formatparts(11),"(I1,A,I1,A,I1,A)") &
1113  spaces(13), "X,1F",spincharacters,".",spindigitsafterdecimal,")"
1114  elseif (spindigitsafterdecimal.lt.10) then
1115  write(formatparts(11),"(I1,A,I2,A,I1,A)") &
1116  spaces(13), "X,1F",spincharacters,".",spindigitsafterdecimal,")"
1117  else
1118  write(formatparts(11),"(I1,A,I2,A,I2,A)") &
1119  spaces(13), "X,1F",spincharacters,".",spindigitsafterdecimal,")"
1120  endif
1121 endif
1122 
1123 !do i=1,11
1124 ! print *, FormatParts(i)
1125 !enddo
1126 
1127 findinputfmt1 = (trim(formatparts(1)) &
1128  // trim(formatparts(2)) &
1129  // trim(formatparts(3)) &
1130  // trim(formatparts(4)) &
1131  // trim(formatparts(5)) &
1132  // trim(formatparts(6)) &
1133  // trim(formatparts(7)) &
1134  // trim(formatparts(8)) &
1135  // trim(formatparts(9)) &
1136  // trim(formatparts(10)) &
1137  // trim(formatparts(11)))
1138 return
1139 end function findinputfmt1
1140 
1141 
1142 
1143 function capitalize(InputString)
1144 implicit none
1145 character(len=150) :: inputstring
1146 character(len=150) :: capitalize
1147 character(len=26), parameter :: lower = "abcdefghijklmnopqrstuvwxyz"
1148 character(len=26), parameter :: upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1149 integer :: i, j
1150 
1151 capitalize = ""
1152 
1153 do i=1,len(trim(inputstring))
1154  j = index(lower,inputstring(i:i))
1155  if (j.ne.0) then
1156  capitalize(i:i) = upper(j:j)
1157  else
1158  capitalize(i:i) = inputstring(i:i)
1159  endif
1160 enddo
1161 return
1162 end function capitalize
1163 
1164 
1165 
1166 subroutine houseofrepresentatives(XSecArray, NumberOfSeats, TotalNumberOfSeats)
1167 !Want to generate TotalNumberOfSeats events among the partonic channels, proportional to the xsec.
1168 !But can't generate half an event, so need to round in some way.
1169 !Apparently this is a major political issue. https://en.wikipedia.org/wiki/Apportionment_paradox
1170 !The first US presidential veto was when George Washington vetoed a change in rounding scheme
1171 ! because Virginia would have lost seats in the House.
1172 !Also, if the US had used a different system, Rutherford B. Hayes wouldn't have been president.
1173 
1174 !For our case, it's much easier because we can and should distribute randomly, not deterministically
1175 ! so that if you run 1000 times with 50 events each the fluctuations average out.
1176 !Also states with small xsec like Wyoming don't get a seat.
1177 implicit none
1178 real(8) :: totalxsec, CrossSecNormalized(-5:5,-5:5), yRnd
1179 integer :: n, i, j
1180 integer, intent(in) :: TotalNumberOfSeats
1181 real(8), intent(in) :: XSecArray(-5:5,-5:5)
1182 integer(8), intent(out) :: NumberOfSeats(-5:5,-5:5)
1183  totalxsec = 0
1184  numberofseats(:,:) = 0
1185  if (totalnumberofseats.lt.1) return
1186 
1187  do i=-5,5
1188  do j=-5,5
1189  totalxsec = totalxsec+abs(xsecarray(i,j))
1190  enddo
1191  enddo
1192  if (totalxsec.eq.0d0) then
1193  print *,"HouseOfRepresentatives: Total xsec is 0. Aborting..."
1194  stop 1
1195  endif
1196  do i=-5,5
1197  do j=-5,5
1198  crosssecnormalized(i,j) = abs(xsecarray(i,j)) / totalxsec
1199  enddo
1200  enddo
1201 
1202  do n=1,totalnumberofseats
1203  do while(.true.)
1204  call random_number(yrnd)
1205  do i=-5,5
1206  do j=-5,5
1207  if (yrnd .lt. crosssecnormalized(i,j)) then
1208  numberofseats(i,j) = numberofseats(i,j)+1
1209  goto 99
1210  endif
1211  yrnd = yrnd - crosssecnormalized(i,j)
1212  enddo
1213  enddo
1214  !in case a rounding error causes sum(CrossSecNormalized) != 1
1215  print *, "HouseOfRepresentatives: Warning, rounding error, try again"
1216  enddo
1217 99 continue
1218  enddo
1219 
1220  if (sum(numberofseats(:,:)).ne.totalnumberofseats) then
1221  print *, "HouseOfRepresentatives: Wrong total number of events, shouldn't be able to happen"
1222  stop 1
1223  endif
1224 end subroutine
1225 
1226 
1227 
1228 
1229 subroutine houseofrepresentatives2(XSecArray, NumberOfSeats, TotalNumberOfSeats)
1230 !same as above with one-dim. arrays
1231 implicit none
1232 real(8), intent(in) :: XSecArray(:)
1233 real(8) :: totalxsec, CrossSecNormalized(size(XSecArray)), yRnd
1234 integer :: n,i,nchannels
1235 integer, intent(in) :: TotalNumberOfSeats
1236 integer(8), intent(out) :: NumberOfSeats(:)
1237  totalxsec = 0
1238  numberofseats(:) = 0
1239  if (totalnumberofseats.lt.1) return
1240 
1241  nchannels = size(xsecarray)
1242 
1243  do i=1,nchannels
1244  totalxsec = totalxsec+abs(xsecarray(i))
1245  enddo
1246  if (totalxsec.eq.0d0) then
1247  print *,"HouseOfRepresentatives2: Total xsec is 0. Aborting..."
1248  stop 1
1249  endif
1250  do i=1,nchannels
1251  crosssecnormalized(i) = abs(xsecarray(i)) / totalxsec
1252  enddo
1253 
1254  do n=1,totalnumberofseats
1255  do while(.true.)
1256  call random_number(yrnd)
1257  do i=1,nchannels
1258  if (yrnd .lt. crosssecnormalized(i)) then
1259  numberofseats(i) = numberofseats(i)+1
1260  goto 99
1261  endif
1262  yrnd = yrnd - crosssecnormalized(i)
1263  enddo
1264  print *, "HouseOfRepresentatives2: Warning, rounding error, try again"
1265  enddo
1266 99 continue
1267  enddo
1268 
1269  if (sum(numberofseats(:)).ne.totalnumberofseats) then
1270  print *, "HouseOfRepresentatives2: Wrong total number of events, shouldn't be able to happen"
1271  stop 1
1272  endif
1273 end subroutine
1274 
1275 
1276 
1277 
1278 !========================================================================
1279 
1280  subroutine convert_to_mcfm(p,pout)
1281  implicit none
1282 ! converts from (E,px,py,pz) to (px,py,pz,E)
1283  real(8) :: p(1:4),tmp(1:4)
1284  real(8), optional :: pout(1:4)
1285 
1286  if( present(pout) ) then
1287  pout(1)=p(2)
1288  pout(2)=p(3)
1289  pout(3)=p(4)
1290  pout(4)=p(1)
1291  else
1292  tmp(1)=p(1)
1293  tmp(2)=p(2)
1294  tmp(3)=p(3)
1295  tmp(4)=p(4)
1296 
1297  p(1)=tmp(2)
1298  p(2)=tmp(3)
1299  p(3)=tmp(4)
1300  p(4)=tmp(1)
1301  endif
1302 
1303  end subroutine convert_to_mcfm
1304 
1305 !========================================================================
1306 !borrowed from Passarino's file, some internal variable names or comments
1307 !might not be correct in this context
1308 !========================================================================
1309 
1310 SUBROUTINE evaluatespline(EvalPoint, SplineData, SplineDataLength, TheResult)
1311 !SplineData: SplineDataLength by 2 array
1312 ! SplineData(1:SplineDataLength,1) are the x values
1313 ! SplineData(1:SplineDataLength,2) are the corresponding y values
1314 
1315 IMPLICIT NONE
1316 
1317 INTEGER i,top,gdim,SplineDataLength
1318 REAL(8) u,value,EvalPoint
1319 REAL(8), intent(out) :: TheResult
1320 REAL(8), dimension(SplineDataLength) :: bc,cc,dc
1321 REAL(8) :: SplineData(1:SplineDataLength, 1:2)
1322 
1323 ! u value of M_H at which the spline is to be evaluated
1324 
1325 gdim= splinedatalength
1326 
1327 CALL hto_fmmsplinesingleht(bc,cc,dc,top,gdim,splinedata(1:splinedatalength,1),splinedata(1:splinedatalength,2))
1328 
1329 u= evalpoint
1330 CALL hto_seval3singleht(u,bc,cc,dc,top,gdim,value,xc=splinedata(1:splinedatalength,1),yc=splinedata(1:splinedatalength,2))
1331 
1332 theresult= value
1333 
1334 RETURN
1335 
1336 !-----------------------------------------------------------------------
1337 
1338 CONTAINS
1339 
1340 SUBROUTINE hto_fmmsplinesingleht(b,c,d,top,gdim,xc,yc)
1342 !---------------------------------------------------------------------------
1343 
1344 INTEGER k,n,i,top,gdim,l
1345 
1346 REAL(8), dimension(gdim) :: xc,yc
1347 REAL(8), dimension(gdim) :: x,y
1348 
1349 REAL(8), DIMENSION(gdim) :: b
1350 ! linear coeff
1351 
1352 REAL(8), DIMENSION(gdim) :: c
1353 ! quadratic coeff.
1354 
1355 REAL(8), DIMENSION(gdim) :: d
1356 ! cubic coeff.
1357 
1358 REAL(8) :: t
1359 REAL(8),PARAMETER:: ZERO=0.0, two=2.0, three=3.0
1360 
1361 ! The grid
1362 
1363 
1364 n= gdim
1365 FORALL(l=1:gdim)
1366 x(l)= xc(l)
1367 y(l)= yc(l)
1368 ENDFORALL
1369 
1370 !.....Set up tridiagonal system.........................................
1371 ! b=diagonal, d=offdiagonal, c=right-hand side
1372 
1373 d(1)= x(2)-x(1)
1374 c(2)= (y(2)-y(1))/d(1)
1375 DO k= 2,n-1
1376 d(k)= x(k+1)-x(k)
1377 b(k)= two*(d(k-1)+d(k))
1378 c(k+1)= (y(k+1)-y(k))/d(k)
1379 c(k)= c(k+1)-c(k)
1380 END DO
1381 
1382 !.....End conditions. third derivatives at x(1) and x(n) obtained
1383 ! from divided differences.......................................
1384 
1385 b(1)= -d(1)
1386 b(n)= -d(n-1)
1387 c(1)= zero
1388 c(n)= zero
1389 IF (n > 3) THEN
1390 c(1)= c(3)/(x(4)-x(2))-c(2)/(x(3)-x(1))
1391 c(n)= c(n-1)/(x(n)-x(n-2))-c(n-2)/(x(n-1)-x(n-3))
1392 c(1)= c(1)*d(1)*d(1)/(x(4)-x(1))
1393 c(n)= -c(n)*d(n-1)*d(n-1)/(x(n)-x(n-3))
1394 END IF
1395 
1396 DO k=2,n ! forward elimination
1397 t= d(k-1)/b(k-1)
1398 b(k)= b(k)-t*d(k-1)
1399 c(k)= c(k)-t*c(k-1)
1400 END DO
1401 
1402 c(n)= c(n)/b(n)
1403 
1404 ! back substitution ( makes c the sigma of text)
1405 
1406 DO k=n-1,1,-1
1407 c(k)= (c(k)-d(k)*c(k+1))/b(k)
1408 END DO
1409 
1410 !.....Compute polynomial coefficients...................................
1411 
1412 b(n)= (y(n)-y(n-1))/d(n-1)+d(n-1)*(c(n-1)+c(n)+c(n))
1413 DO k=1,n-1
1414 b(k)= (y(k+1)-y(k))/d(k)-d(k)*(c(k+1)+c(k)+c(k))
1415 d(k)= (c(k+1)-c(k))/d(k)
1416 c(k)= three*c(k)
1417 END DO
1418 c(n)= three*c(n)
1419 d(n)= d(n-1)
1420 
1421 RETURN
1422 
1423 END SUBROUTINE hto_fmmsplinesingleht
1424 
1425 !------------------------------------------------------------------------
1426 
1427 SUBROUTINE hto_seval3singleht(u,b,c,d,top,gdim,f,fp,fpp,fppp,xc,yc)
1429 ! ---------------------------------------------------------------------------
1430 
1431 REAL(8),INTENT(IN) :: u
1432 ! abscissa at which the spline is to be evaluated
1433 
1434 INTEGER j,k,n,l,top,gdim
1435 
1436 REAL(8), dimension(gdim) :: xc,yc
1437 REAL(8), dimension(gdim) :: x,y
1438 REAL(8), DIMENSION(gdim) :: b,c,d
1439 ! linear,quadratic,cubic coeff
1440 
1441 REAL(8),INTENT(OUT),OPTIONAL:: f,fp,fpp,fppp
1442 ! function, 1st,2nd,3rd deriv
1443 
1444 INTEGER, SAVE :: i=1
1445 REAL(8) :: dx
1446 REAL(8),PARAMETER:: TWO=2.0, three=3.0, six=6.0
1447 
1448 ! The grid
1449 
1450 n= gdim
1451 FORALL(l=1:gdim)
1452 x(l)= xc(l)
1453 y(l)= yc(l)
1454 ENDFORALL
1455 
1456 !.....First check if u is in the same interval found on the
1457 ! last call to Seval.............................................
1458 
1459 IF ( (i<1) .OR. (i >= n) ) i=1
1460 IF ( (u < x(i)) .OR. (u >= x(i+1)) ) THEN
1461 i=1
1462 
1463 ! binary search
1464 
1465 j= n+1
1466 DO
1467 k= (i+j)/2
1468 IF (u < x(k)) THEN
1469 j= k
1470 ELSE
1471 i= k
1472 ENDIF
1473 IF (j <= i+1) EXIT
1474 ENDDO
1475 ENDIF
1476 
1477 dx= u-x(i)
1478 
1479 ! evaluate the spline
1480 
1481 IF (Present(f)) f= y(i)+dx*(b(i)+dx*(c(i)+dx*d(i)))
1482 IF (Present(fp)) fp= b(i)+dx*(two*c(i) + dx*three*d(i))
1483 IF (Present(fpp)) fpp= two*c(i) + dx*six*d(i)
1484 IF (Present(fppp)) fppp= six*d(i)
1485 
1486 RETURN
1487 
1488 END SUBROUTINE hto_seval3singleht
1489 
1490 END SUBROUTINE evaluatespline
1491 
1492 function centerwithstars(string, totallength, align, padleft, padright)
1493 implicit none
1494 character(len=*) :: string
1495 integer :: totallength, nspaces, nleftspaces, nrightspaces
1496 integer, optional :: align, padleft, padright
1497 integer :: align2, padleft2, padright2
1498 character(len=totallength) centerwithstars
1499 
1500  align2 = 2
1501  padleft2 = 0
1502  padright2 = 0
1503  if (present(align)) align2 = align
1504  if (present(padleft)) padleft2 = padleft
1505  if (present(padright)) padright2 = padright
1506 
1507  if (len(trim(string))+padleft2+padright2 .gt. totallength-2) then
1508  call error("len(trim(string))+padleft+padright > totallength-2!")
1509  endif
1510 
1511  nspaces = totallength - len(trim(string)) - 2
1512 
1513  if (align2.eq.1) then !left
1514  nleftspaces = padleft2
1515  nrightspaces = nspaces-nleftspaces
1516  elseif (align2.eq.2) then !center
1517  nleftspaces = (nspaces+padleft2-padright2)/2
1518  nrightspaces = nspaces-nleftspaces
1519  elseif (align2.eq.3) then !right
1520  nrightspaces = padright2
1521  nleftspaces = nspaces-nrightspaces
1522  else
1523  print *, "Unknown align value", align2
1524  endif
1525 
1526  centerwithstars = "*" // repeat(" ", nleftspaces) // trim(string) // repeat(" ", nrightspaces) // "*"
1527 
1528 end function
1529 
1530 SUBROUTINE printlogo(TheUnit, title)
1532 implicit none
1533 integer :: TheUnit
1534 integer, parameter :: linelength = 89
1535 character(len=*) :: title
1536 
1537  write(theunit, *) " "
1538  write(theunit, *) " ", repeat("*", linelength)
1539  write(theunit, *) " ", centerwithstars(trim(title)//" "//trim(jhugen_version), linelength)
1540  write(theunit, *) " ", repeat("*", linelength)
1541  write(theunit, *) " ", centerwithstars("", linelength)
1542  write(theunit, *) " ", centerwithstars("Spin and parity determination of single-produced resonances at hadron colliders", linelength)
1543  write(theunit, *) " ", centerwithstars("", linelength)
1544  write(theunit, *) " ", centerwithstars("I. Anderson, S. Bolognesi, F. Caola, J. Davis, Y. Gao, A. V. Gritsan,", linelength)
1545  write(theunit, *) " ", centerwithstars("L. S. Mandacaru Guerra, Z. Guo, L. Kang, S. Kyriacou, C. B. Martin, T. Martini,", linelength)
1546  write(theunit, *) " ", centerwithstars("K. Melnikov, R. Pan, M. Panagiotou, R. Rontsch, J. Roskes, U. Sarica,", linelength)
1547  write(theunit, *) " ", centerwithstars("M. Schulze, M. V. Srivastav, N. V. Tran, A. Whitbeck, M. Xiao, Y. Zhou", linelength)
1548  write(theunit, *) " ", centerwithstars("Phys.Rev. D81 (2010) 075022; arXiv:1001.3396 [hep-ph],", linelength)
1549  write(theunit, *) " ", centerwithstars("Phys.Rev. D86 (2012) 095031; arXiv:1208.4018 [hep-ph],", linelength)
1550  write(theunit, *) " ", centerwithstars("Phys.Rev. D89 (2014) 035007; arXiv:1309.4819 [hep-ph],", linelength)
1551  write(theunit, *) " ", centerwithstars("Phys.Rev. D94 (2016) 055023; arXiv:1606.03107 [hep-ph],", linelength)
1552  write(theunit, *) " ", centerwithstars("Phys.Rev. D102 (2020) 056022; arXiv:2002.09888 [hep-ph],", linelength)
1553  write(theunit, *) " ", centerwithstars("Phys.Rev. D102 (2021) 055045; arXiv:2104.04277 [hep-ph].", linelength)
1554  write(theunit, *) " ", centerwithstars("Phys.Rev. D105 (2022) 096027; arXiv:2109.13363 [hep-ph].", linelength)
1555  write(theunit, *) " ", centerwithstars("", linelength)
1556  write(theunit, *) " ", repeat("*", linelength)
1557  write(theunit, *) " "
1558 return
1559 END SUBROUTINE
1560 
1561 
1562 real function infinity()
1563  implicit none
1564  real :: x
1565  x = 0
1566  infinity=-log(x)
1567 end function infinity
1568 
1569 function calculatesxsec(Process)
1570  implicit none
1571  integer :: process
1572  logical :: calculatesxsec
1573  calculatesxsec=.false.
1574  if (process.le.2) then
1575  calculatesxsec=.true.
1576  elseif (process.eq.50) then
1577  calculatesxsec=.false.
1578  elseif (process.ge.51 .and. process.le.52) then
1579  calculatesxsec=.false.
1580  elseif (process.eq.60) then
1581  calculatesxsec=.true.
1582  elseif (process.eq.61) then
1583  calculatesxsec=.true.
1584  elseif (process.eq.62) then
1585  calculatesxsec=.false.
1586  elseif (process.ge.66 .and. process.le.75) then
1587  calculatesxsec=.true.
1588  elseif (process.eq.80 .or. process.eq.90) then
1589  calculatesxsec=.false.
1590  elseif (process.ge.110 .and. process.le.114) then
1591  calculatesxsec=.true.
1592  elseif (process.ge.115 .and. process.le.117) then
1593  calculatesxsec=.true.
1594  else
1595  print *, "Unknown process in CalculatesXsec", process, "; setting CalculatesXsec=false."
1596  endif
1597 end function calculatesxsec
1598 
1599 END MODULE
1600 
modmisc::pol_zff_outgoing
complex(8) function, dimension(4) pol_zff_outgoing(pf, pfbar, hel)
Definition: mod_Misc.F90:507
modmisc::printlogo
subroutine printlogo(TheUnit, title)
Definition: mod_Misc.F90:1531
modmisc::get_eta
real(8) function get_eta(Mom)
Definition: mod_Misc.F90:190
modmisc::get_minv
real(8) function get_minv(Mom)
Definition: mod_Misc.F90:172
modmisc::et1
double complex function et1(e1, e2, e3, e4)
Definition: mod_Misc.F90:109
modmisc::swapr
subroutine swapr(i, j)
Definition: mod_Misc.F90:403
modmisc::infinity
real function infinity()
Definition: mod_Misc.F90:1563
modmisc::findinputfmt0
character(len=150) function findinputfmt0(EventInfoLine)
Definition: mod_Misc.F90:769
modmisc::minkowskyproductrc
complex(8) function minkowskyproductrc(p1, p2)
Definition: mod_Misc.F90:72
modmisc::get_r
real(8) function get_r(Mom1, Mom2)
Definition: mod_Misc.F90:233
modmisc::error
subroutine error(Message, ErrNum)
Definition: mod_Misc.F90:366
modmisc::sc
double complex function sc(q1, q2)
Definition: mod_Misc.F90:127
modmisc::isnan
logical function isnan(x)
Definition: mod_Misc.F90:380
modmisc::pt_order
subroutine pt_order(N, Mom)
Definition: mod_Misc.F90:253
modmisc::vectorcross
real(8) function, dimension(1:3) vectorcross(p1, p2)
Definition: mod_Misc.F90:38
modmisc::swap_cmom
subroutine swap_cmom(Mom1, Mom2)
Definition: mod_Misc.F90:434
modmisc::get_phi
real(8) function get_phi(Mom)
Definition: mod_Misc.F90:200
modmisc::evaluatespline
subroutine evaluatespline(EvalPoint, SplineData, SplineDataLength, TheResult)
Definition: mod_Misc.F90:1311
modmisc::spi2_weyl
complex(8) function, dimension(4) spi2_weyl(v, sp)
Definition: mod_Misc.F90:711
modmisc::houseofrepresentatives2
subroutine houseofrepresentatives2(XSecArray, NumberOfSeats, TotalNumberOfSeats)
Definition: mod_Misc.F90:1230
modmisc::minkowskyproduct
real(8) function minkowskyproduct(p1, p2)
Definition: mod_Misc.F90:50
modmisc::get_pt
real(8) function get_pt(Mom)
Definition: mod_Misc.F90:152
modmisc::pol_gluon_incoming
complex(8) function, dimension(1:4) pol_gluon_incoming(p, hel)
Definition: mod_Misc.F90:469
modmisc::scrc
double complex function scrc(p1, p2)
Definition: mod_Misc.F90:142
modmisc::bublesort
Definition: mod_Misc.F90:24
hto_fmmsplinesingleht
subroutine hto_fmmsplinesingleht(b, c, d, top, gdim)
Definition: CALLING_cpHTO.f:4131
modmisc::swap_mom
subroutine swap_mom(Mom1, Mom2)
Definition: mod_Misc.F90:423
modmisc::calculatesxsec
logical function calculatesxsec(Process)
Definition: mod_Misc.F90:1570
modmisc::ubar_spinor
complex(8) function, dimension(1:4) ubar_spinor(p, hel)
Definition: mod_Misc.F90:526
modmisc::vbqq_weyl
complex(8) function, dimension(dv) vbqq_weyl(sp1, sp2)
Definition: mod_Misc.F90:626
modmisc::capitalize
character(len=150) function capitalize(InputString)
Definition: mod_Misc.F90:1144
modmisc::get_minv2
real(8) function get_minv2(Mom)
Definition: mod_Misc.F90:181
modmisc::get_cosalpha
real(8) function get_cosalpha(Mom1, Mom2)
Definition: mod_Misc.F90:212
modmisc::reorder
Definition: mod_Misc.F90:28
modparameters
Definition: mod_Parameters.F90:1
modmisc::leviciv
complex(8) function leviciv(e1, e2, e3, e4)
Definition: mod_Misc.F90:448
modmisc
Definition: mod_Misc.F90:1
modmisc::v_spinor
complex(8) function, dimension(1:4) v_spinor(p, hel)
Definition: mod_Misc.F90:567
modmisc::get_pt2
real(8) function get_pt2(Mom)
Definition: mod_Misc.F90:162
modmisc::get_costheta
real(8) function get_costheta(Mom)
Definition: mod_Misc.F90:222
modmisc::minkowskyproductc
complex(8) function minkowskyproductc(p1, p2)
Definition: mod_Misc.F90:61
modmisc::printmom
subroutine printmom(Mom)
Definition: mod_Misc.F90:351
modmisc::chir_weyl
double complex function, dimension(1:4) chir_weyl(sign, sp)
Definition: mod_Misc.F90:607
modmisc::convert_to_mcfm
subroutine convert_to_mcfm(p, pout)
Definition: mod_Misc.F90:1281
modmisc::centerwithstars
character(len=totallength) function centerwithstars(string, totallength, align, padleft, padright)
Definition: mod_Misc.F90:1493
modmisc::swapc
subroutine swapc(i, j)
Definition: mod_Misc.F90:413
modmisc::logicaltointeger
integer function logicaltointeger(var)
Definition: mod_Misc.F90:97
modmisc::scr
double precision function scr(p1, p2)
Definition: mod_Misc.F90:135
hto_seval3singleht
subroutine hto_seval3singleht(u, b, c, d, top, gdim, f, fp, fpp, fppp)
Definition: CALLING_cpHTO.f:4246
modmisc::swapi
subroutine swapi(i, j)
Definition: mod_Misc.F90:393
modmisc::spb2_weyl
complex(8) function, dimension(4) spb2_weyl(sp, v)
Definition: mod_Misc.F90:657
modparameters::jhugen_version
character(len= *), parameter jhugen_version
Definition: mod_Parameters.F90:6
modmisc::houseofrepresentatives
subroutine houseofrepresentatives(XSecArray, NumberOfSeats, TotalNumberOfSeats)
Definition: mod_Misc.F90:1167
modmisc::minkowskyproductcr
complex(8) function minkowskyproductcr(p1, p2)
Definition: mod_Misc.F90:84
modmisc::findinputfmt1
character(len=150) function findinputfmt1(ParticleLine)
Definition: mod_Misc.F90:864
modmisc::swap
Definition: mod_Misc.F90:5