whizard is hosted by Hepforge, IPPP Durham
close Warning: Error with navigation contributor "BrowserModule"

Ticket #250: particles.f90

File particles.f90, 42.8 KB (added by dwiesler, 14 years ago)

additional subroutine for boosting decay momenta

Line 
1! WHIZARD 2.0.0_rc4 Wed Mar 03 2010
2!
3! (C) 1999-2010 by
4!     Wolfgang Kilian <kilian@hep.physik.uni-siegen.de>
5!     Thorsten Ohl <ohl@physik.uni-wuerzburg.de>
6!     Juergen Reuter <juergen.reuter@physik.uni-freiburg.de>
7!     with contributions by Christian Speckner, Sebastian Schmidt,
8!     Daniel Wiesler, Felix Braam
9!
10! WHIZARD is free software; you can redistribute it and/or modify it
11! under the terms of the GNU General Public License as published by
12! the Free Software Foundation; either version 2, or (at your option)
13! any later version.
14!
15! WHIZARD is distributed in the hope that it will be useful, but
16! WITHOUT ANY WARRANTY; without even the implied warranty of
17! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18! GNU General Public License for more details.
19!
20! You should have received a copy of the GNU General Public License
21! along with this program; if not, write to the Free Software
22! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23!
24!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
25! This file has been stripped of most comments.  For documentation, refer
26! to the source 'whizard.nw'
27
28module particles
29
30  use kinds, only: default !NODEP!
31  use iso_varying_string, string_t => varying_string !NODEP!
32  use file_utils !NODEP!
33  use lorentz !NODEP!
34  use prt_lists
35  use expressions
36  use models
37  use flavors
38  use colors
39  use helicities
40  use quantum_numbers
41  use state_matrices
42  use interactions
43  use evaluators
44  use polarizations
45  use event_formats
46  use hepmc_interface
47
48  implicit none
49  private
50
51  public :: particle_set_t
52  public :: particle_set_init
53  public :: particle_set_final
54  public :: particle_set_write
55  public :: particle_set_write_raw
56  public :: particle_set_read_raw
57  public :: particle_set_fill_hepeup
58  public :: particle_set_fill_hepevt
59  public :: particle_set_fill_hepmc_event
60  public :: particle_set_reset_status
61  public :: particle_set_get_n_out, particle_set_get_n_in, &
62                particle_set_get_n_tot
63  public :: particle_set_reduce
64  public :: particle_set_to_prt_list
65  public :: particles_test
66
67  integer, parameter :: PRT_UNPOLARIZED = 0
68  integer, parameter :: PRT_DEFINITE_HELICITY = 1
69  integer, parameter :: PRT_GENERIC_POLARIZATION = 2
70
71       
72  type :: particle_t
73     private
74     integer :: status = PRT_UNDEFINED
75     integer :: polarization = PRT_UNPOLARIZED
76     type(flavor_t) :: flv
77     type(color_t) :: col
78     type(helicity_t) :: hel
79     type(polarization_t) :: pol
80     type(vector4_t) :: p = vector4_null
81     real(default) :: p2 = 0
82     integer, dimension(:), allocatable :: parent
83     integer, dimension(:), allocatable :: child
84  end type particle_t
85
86  type :: particle_set_t
87     private
88     integer :: n_in  = 0
89     integer :: n_vir = 0
90     integer :: n_out = 0
91     integer :: n_tot = 0
92     type(particle_t), dimension(:), allocatable :: prt
93     type(state_matrix_t) :: correlated_state
94  end type particle_set_t
95
96
97  interface particle_init
98     module procedure particle_init_particle
99     module procedure particle_init_state
100     module procedure particle_init_hepmc
101  end interface
102
103  interface particle_set_init
104     module procedure particle_set_init_interaction
105     module procedure particle_set_init_hepmc
106  end interface
107
108
109contains
110
111  subroutine particle_init_particle (prt_out, prt_in)
112    type(particle_t), intent(out) :: prt_out
113    type(particle_t), intent(in) :: prt_in
114    prt_out%status = prt_in%status
115    prt_out%polarization = prt_in%polarization
116    prt_out%flv = prt_in%flv
117    prt_out%col = prt_in%col
118    prt_out%hel = prt_in%hel
119    prt_out%pol = prt_in%pol
120    prt_out%p = prt_in%p
121    prt_out%p2 = prt_in%p2
122  end subroutine particle_init_particle
123
124  subroutine particle_init_state (prt, state, status, mode)
125    type(particle_t), intent(out) :: prt
126    type(state_matrix_t), intent(in) :: state
127    integer, intent(in) :: status, mode
128    type(state_iterator_t) :: it
129    prt%status = status
130    call state_iterator_init (it, state)
131    prt%flv = state_iterator_get_flavor (it, 1)
132    if (flavor_is_beam_remnant (prt%flv))  prt%status = PRT_BEAM_REMNANT
133    prt%col = state_iterator_get_color (it, 1)
134    select case (mode)
135    case (FM_SELECT_HELICITY)
136       prt%hel = state_iterator_get_helicity (it, 1)
137       prt%polarization = PRT_DEFINITE_HELICITY
138    case (FM_FACTOR_HELICITY)
139       call polarization_init_state_matrix (prt%pol, state)
140       prt%polarization = PRT_GENERIC_POLARIZATION
141    end select
142  end subroutine particle_init_state
143
144  subroutine particle_init_hepmc (prt, hprt, model, polarization, barcode)
145    type(particle_t), intent(out) :: prt
146    type(hepmc_particle_t), intent(in) :: hprt
147    type(model_t), intent(in), target :: model
148    integer, intent(in) :: polarization
149    integer, dimension(:), intent(in) :: barcode
150    type(hepmc_polarization_t) :: hpol
151    integer :: n_parents, n_children
152    integer, dimension(:), allocatable :: parent_barcode, child_barcode
153    integer :: i
154    select case (hepmc_particle_get_status (hprt))
155    case (1);  prt%status = PRT_OUTGOING
156    case (2);  prt%status = PRT_RESONANT
157    case (3);  prt%status = PRT_VIRTUAL
158    end select
159    call flavor_init (prt%flv, hepmc_particle_get_pdg (hprt), model)
160    if (flavor_is_beam_remnant (prt%flv))  prt%status = PRT_BEAM_REMNANT
161    call color_init (prt%col, hepmc_particle_get_color (hprt))
162    prt%polarization = polarization
163    select case (polarization)
164    case (PRT_DEFINITE_HELICITY)
165       hpol = hepmc_particle_get_polarization (hprt)
166       call hepmc_polarization_to_hel (hpol, prt%flv, prt%hel)
167       call hepmc_polarization_final (hpol)
168    case (PRT_GENERIC_POLARIZATION)
169       hpol = hepmc_particle_get_polarization (hprt)
170       call hepmc_polarization_to_pol (hpol, prt%flv, prt%pol)
171       call hepmc_polarization_final (hpol)
172    end select
173    prt%p = hepmc_particle_get_momentum (hprt)
174    prt%p2 = hepmc_particle_get_mass_squared (hprt)
175    n_parents  = hepmc_particle_get_n_parents  (hprt)
176    n_children = hepmc_particle_get_n_children (hprt)
177    allocate (parent_barcode (n_parents),  prt%parent (n_parents))
178    allocate (child_barcode  (n_children), prt%child  (n_children))
179    parent_barcode = hepmc_particle_get_parent_barcodes (hprt)
180    child_barcode  = hepmc_particle_get_child_barcodes  (hprt)
181    do i = 1, size (barcode)
182       where (parent_barcode == barcode(i))  prt%parent = i
183       where (child_barcode  == barcode(i))  prt%child  = i
184    end do
185    if (prt%status == PRT_VIRTUAL .and. n_parents == 0) &
186         prt%status = PRT_INCOMING
187  end subroutine particle_init_hepmc
188
189  elemental subroutine particle_final (prt)
190    type(particle_t), intent(inout) :: prt
191    call polarization_final (prt%pol)
192  end subroutine particle_final
193
194  subroutine particle_write (prt, unit)
195    type(particle_t), intent(in) :: prt
196    integer, intent(in), optional :: unit
197    integer :: u
198    u = output_unit (unit);  if (u < 0)  return
199    select case (prt%status)
200    case (PRT_UNDEFINED);    write (u, "(1x, A)", advance="no")  "[-]"
201    case (PRT_BEAM);         write (u, "(1x, A)", advance="no")  "[b]"
202    case (PRT_INCOMING);     write (u, "(1x, A)", advance="no")  "[i]"
203    case (PRT_OUTGOING);     write (u, "(1x, A)", advance="no")  "[o]"
204    case (PRT_VIRTUAL);      write (u, "(1x, A)", advance="no")  "[v]"
205    case (PRT_RESONANT);     write (u, "(1x, A)", advance="no")  "[r]"
206    case (PRT_BEAM_REMNANT); write (u, "(1x, A)", advance="no")  "[x]"
207    end select
208    write (u, "(1x)", advance="no")
209    call flavor_write (prt%flv, unit)
210    call color_write (prt%col, unit)
211    select case (prt%polarization)
212    case (PRT_DEFINITE_HELICITY)
213       call helicity_write (prt%hel, unit)
214       write (u, *)
215    case (PRT_GENERIC_POLARIZATION)
216       write (u, *)
217       call polarization_write (prt%pol, unit)
218    case default
219       write (u, *)
220    end select
221    write (u, *) "Momentum:"
222    call vector4_write (prt%p, unit)
223    write (u, "(1x,A)", advance="no")  "T = "
224    write (u, *)  prt%p2
225    if (allocated (prt%parent)) then
226       if (size (prt%parent) /= 0) then
227          write (u, "(1x,A,40(1x,I0))")  "Parents: ", prt%parent
228       end if
229    end if
230    if (allocated (prt%child)) then
231       if (size (prt%child) /= 0) then
232          write (u, "(1x,A,40(1x,I0))")  "Children:", prt%child
233       end if
234    end if
235  end subroutine particle_write
236
237  subroutine particle_write_raw (prt, u)
238    type(particle_t), intent(in) :: prt
239    integer, intent(in) :: u
240    write (u) prt%status, prt%polarization
241    call flavor_write_raw (prt%flv, u)
242    call color_write_raw (prt%col, u)
243    select case (prt%polarization)
244    case (PRT_DEFINITE_HELICITY)
245       call helicity_write_raw (prt%hel, u)
246    case (PRT_GENERIC_POLARIZATION)
247       call polarization_write_raw (prt%pol, u)
248    end select
249    call vector4_write_raw (prt%p, u)
250    write (u) prt%p2
251    write (u) allocated (prt%parent)
252    if (allocated (prt%parent)) then
253       write (u) size (prt%parent)
254       write (u) prt%parent
255    end if
256    write (u) allocated (prt%child)
257    if (allocated (prt%child)) then
258       write (u) size (prt%child)
259       write (u) prt%child
260    end if
261  end subroutine particle_write_raw
262
263  subroutine particle_read_raw (prt, u, iostat)
264    type(particle_t), intent(out) :: prt
265    integer, intent(in) :: u
266    integer, intent(out), optional :: iostat
267    logical :: allocated_parent, allocated_child
268    integer :: size_parent, size_child
269    read (u, iostat=iostat) prt%status, prt%polarization
270    call flavor_read_raw (prt%flv, u, iostat=iostat)
271    call color_read_raw (prt%col, u, iostat=iostat)
272    select case (prt%polarization)
273    case (PRT_DEFINITE_HELICITY)
274       call helicity_read_raw (prt%hel, u, iostat=iostat)
275    case (PRT_GENERIC_POLARIZATION)
276       call polarization_read_raw (prt%pol, u, iostat=iostat)
277    end select
278    call vector4_read_raw (prt%p, u, iostat=iostat)
279    read (u, iostat=iostat) prt%p2
280    read (u, iostat=iostat) allocated_parent
281    if (allocated_parent) then
282       read (u, iostat=iostat) size_parent
283       allocate (prt%parent (size_parent))
284       read (u, iostat=iostat) prt%parent
285    end if
286    read (u, iostat=iostat) allocated_child
287    if (allocated_child) then
288       read (u, iostat=iostat) size_child
289       allocate (prt%child (size_child))
290       read (u, iostat=iostat) prt%child
291    end if
292  end subroutine particle_read_raw
293
294  subroutine particle_to_hepmc (prt, hprt)
295    type(particle_t), intent(in) :: prt
296    type(hepmc_particle_t), intent(out) :: hprt
297    integer :: hepmc_status
298    select case (prt%status)
299    case (PRT_UNDEFINED)
300       hepmc_status = 0
301    case (PRT_OUTGOING)
302       hepmc_status = 1
303    case (PRT_RESONANT)
304       hepmc_status = 2
305    case default
306       hepmc_status = 3
307    end select
308    call hepmc_particle_init &
309         (hprt, prt%p, flavor_get_pdg (prt%flv), hepmc_status)
310    call hepmc_particle_set_color (hprt, prt%col)
311    select case (prt%polarization)
312    case (PRT_DEFINITE_HELICITY)
313       call hepmc_particle_set_polarization (hprt, prt%hel)
314    case (PRT_GENERIC_POLARIZATION)
315       call hepmc_particle_set_polarization (hprt, prt%pol)
316    end select
317  end subroutine particle_to_hepmc
318
319  elemental subroutine particle_reset_status (prt, status)
320    type(particle_t), intent(inout) :: prt
321    integer, intent(in) :: status
322    prt%status = status
323  end subroutine particle_reset_status
324
325  elemental subroutine particle_set_momentum (prt, p)
326    type(particle_t), intent(inout) :: prt
327    type(vector4_t), intent(in) :: p
328    prt%p = p
329    prt%p2 = p ** 2
330  end subroutine particle_set_momentum
331
332  elemental subroutine particle_set_resonance_flag (prt, resonant)
333    type(particle_t), intent(inout) :: prt
334    logical, intent(in) :: resonant
335    select case (prt%status)
336    case (PRT_VIRTUAL)
337       if (resonant)  prt%status = PRT_RESONANT
338    end select
339  end subroutine particle_set_resonance_flag
340
341  subroutine particle_boost_decay_momenta (pset)
342    type(particle_set_t), intent(inout), target :: pset
343    type(particle_t), pointer :: prt, mprt
344    integer, dimension(1) :: i_mother
345    integer :: i
346    type(vector4_t) :: prest, pmother
347    real(default) :: mass
348    do i=1,pset%n_tot
349       prt => pset%prt(i)
350       if (particle_get_n_parents (prt) == 1) then
351          i_mother = particle_get_parents (prt)
352          mprt => pset%prt(i_mother(1))
353          if (mprt%status == PRT_RESONANT) then
354             prest = particle_get_momentum(prt)
355             pmother = particle_get_momentum(mprt)
356             mass = flavor_get_mass(mprt%flv)
357             prt%p = boost(pmother,mass)*prest
358          end if
359       end if
360    end do
361  end subroutine particle_boost_decay_momenta
362
363  subroutine particle_set_children (prt, idx)
364    type(particle_t), intent(inout) :: prt
365    integer, dimension(:), intent(in) :: idx
366    if (allocated (prt%child))  deallocate (prt%child)
367    allocate (prt%child (count (idx /= 0)))
368    prt%child = pack (idx, idx /= 0)
369  end subroutine particle_set_children
370
371  subroutine particle_set_parents (prt, idx)
372    type(particle_t), intent(inout) :: prt
373    integer, dimension(:), intent(in) :: idx
374    if (allocated (prt%parent))  deallocate (prt%parent)
375    allocate (prt%parent (count (idx /= 0)))
376    prt%parent = pack (idx, idx /= 0)
377  end subroutine particle_set_parents
378
379  elemental function particle_get_status (prt) result (status)
380    integer :: status
381    type(particle_t), intent(in) :: prt
382    status = prt%status
383  end function particle_get_status
384
385  elemental function particle_is_real (prt, keep_beams) result (flag)
386    logical :: flag, kb
387    type(particle_t), intent(in) :: prt
388    logical, intent(in), optional :: keep_beams
389    kb = .false.
390    if (present (keep_beams)) kb = keep_beams
391    select case (prt%status)
392    case (PRT_INCOMING, PRT_OUTGOING, PRT_RESONANT)
393       flag = .true.
394    case (PRT_BEAM)
395       flag = kb
396    case default
397       flag = .false.
398    end select
399  end function particle_is_real
400
401  elemental function particle_get_polarization_status (prt) result (status)
402    integer :: status
403    type(particle_t), intent(in) :: prt
404    status = prt%polarization
405  end function particle_get_polarization_status
406
407  elemental function particle_get_pdg (prt) result (pdg)
408    integer :: pdg
409    type(particle_t), intent(in) :: prt
410    pdg = flavor_get_pdg (prt%flv)
411  end function particle_get_pdg
412
413  function particle_get_color (prt) result (col)
414    integer, dimension(2) :: col
415    type(particle_t), intent(in) :: prt
416    col(1) = color_get_col (prt%col)
417    col(2) = color_get_acl (prt%col)
418  end function particle_get_color
419 
420  function particle_get_polarization (prt) result (pol)
421    type(polarization_t) :: pol
422    type(particle_t), intent(in) :: prt
423    pol = prt%pol
424  end function particle_get_polarization
425
426  function particle_get_helicity (prt) result (hel)
427    integer :: hel
428    integer, dimension(2) :: hel_arr
429    type(particle_t), intent(in) :: prt   
430    hel = 0
431    if (helicity_is_defined (prt%hel) .and. &
432        helicity_is_diagonal (prt%hel)) then
433        hel_arr = helicity_get (prt%hel)
434        hel = hel_arr (1)
435    end if
436  end function particle_get_helicity 
437 
438  function particle_get_n_parents (prt) result (n)
439    integer :: n
440    type(particle_t), intent(in) :: prt
441    if (allocated (prt%parent)) then
442       n = size (prt%parent)
443    else
444       n = 0
445    end if
446  end function particle_get_n_parents
447   
448  function particle_get_n_children (prt) result (n)
449    integer :: n
450    type(particle_t), intent(in) :: prt
451    if (allocated (prt%child)) then
452       n = size (prt%child)
453    else
454       n = 0
455    end if
456  end function particle_get_n_children
457   
458  function particle_get_parents (prt) result (parent)
459    type(particle_t), intent(in) :: prt
460    integer, dimension(:), allocatable :: parent
461    if (allocated (prt%parent)) then
462       allocate (parent (size (prt%parent)))
463       parent = prt%parent
464    else
465       allocate (parent (0))
466    end if
467  end function particle_get_parents
468
469  function particle_get_children (prt) result (child)
470    type(particle_t), intent(in) :: prt
471    integer, dimension(:), allocatable :: child
472    if (allocated (prt%child)) then
473       allocate (child (size (prt%child)))
474       child = prt%child
475    else
476       allocate (child (0))
477    end if
478  end function particle_get_children
479
480  function particle_get_momentum (prt) result (p)
481    type(vector4_t) :: p
482    type(particle_t), intent(in) :: prt
483    p = prt%p
484  end function particle_get_momentum
485
486  function particle_get_p2 (prt) result (p2)
487    real(default) :: p2
488    type(particle_t), intent(in) :: prt
489    p2 = prt%p2
490  end function particle_get_p2
491
492  subroutine particle_set_init_interaction &
493       (particle_set, int, int_flows, mode, x, &
494        keep_correlations, keep_virtual, n_incoming)
495    type(particle_set_t), intent(out) :: particle_set
496    type(interaction_t), intent(in), target :: int, int_flows
497    integer, intent(in) :: mode
498    real(default), dimension(2), intent(in) :: x
499    logical, intent(in) :: keep_correlations, keep_virtual
500    integer, intent(in), optional :: n_incoming
501    type(state_matrix_t), dimension(:), allocatable, target :: flavor_state
502    type(state_matrix_t), dimension(:), allocatable, target :: single_state
503    integer :: n_in, n_vir, n_out, n_tot
504    type(quantum_numbers_t), dimension(:,:), allocatable :: qn
505    integer :: i, j
506    if (present (n_incoming)) then
507       n_in  = n_incoming
508       n_vir = interaction_get_n_vir (int) - n_incoming
509    else
510       n_in  = interaction_get_n_in  (int)
511       n_vir = interaction_get_n_vir (int)
512    end if
513    n_out = interaction_get_n_out (int)
514    n_tot = interaction_get_n_tot (int)
515    particle_set%n_in  = n_in
516    particle_set%n_out = n_out
517    if (keep_virtual) then
518       particle_set%n_vir = n_vir
519       particle_set%n_tot = n_tot
520    else
521       particle_set%n_vir = 0
522       particle_set%n_tot = n_in + n_out
523    end if
524    call interaction_factorize (int, FM_IGNORE_HELICITY, x(1), flavor_state)
525    allocate (qn (n_tot,1))
526    do i = 1, n_tot
527       qn(i,:) = state_matrix_get_quantum_numbers (flavor_state(i), 1)
528    end do
529    if (keep_correlations .and. keep_virtual) then
530       call interaction_factorize (int_flows, &
531            mode, x(2), single_state, particle_set%correlated_state, qn(:,1))
532    else
533       call interaction_factorize (int_flows, &
534            mode, x(2), single_state, qn_in=qn(:,1))
535    end if
536    allocate (particle_set%prt (particle_set%n_tot))
537    j = 1
538    do i = 1, n_tot
539       if (i <= n_in) then
540          call particle_init &
541               (particle_set%prt(j), single_state(i), PRT_INCOMING, mode)
542       else if (i <= n_in + n_vir) then
543          if (.not. keep_virtual)  cycle
544          call particle_init &
545               (particle_set%prt(j), single_state(i), PRT_VIRTUAL, mode)
546       else
547          call particle_init &
548               (particle_set%prt(j), single_state(i), PRT_OUTGOING, mode)
549       end if
550       call particle_set_momentum &
551            (particle_set%prt(j), interaction_get_momentum (int, i))
552       if (keep_virtual) then
553          call particle_set_children &
554               (particle_set%prt(j), interaction_get_children (int, i))
555          call particle_set_parents &
556               (particle_set%prt(j), interaction_get_parents (int, i))
557       end if
558       j = j + 1
559    end do
560    if (keep_virtual) then
561       call particle_set_resonance_flag &
562            (particle_set%prt, interaction_get_resonance_flags (int))
563    end if
564    call particle_boost_decay_momenta (particle_set)
565    call state_matrix_final (flavor_state)
566    call state_matrix_final (single_state)
567  end subroutine particle_set_init_interaction
568
569  subroutine particle_set_init_hepmc (particle_set, evt, model, polarization)
570    type(particle_set_t), intent(out) :: particle_set
571    type(hepmc_event_t), intent(in) :: evt
572    type(model_t), intent(in), target :: model
573    integer, intent(in) :: polarization
574    type(hepmc_event_particle_iterator_t) :: it
575    type(hepmc_particle_t) :: prt
576    integer, dimension(:), allocatable :: barcode
577    integer :: n_tot, i
578    n_tot = 0
579    call hepmc_event_particle_iterator_init (it, evt)
580    do while (hepmc_event_particle_iterator_is_valid (it))
581       n_tot = n_tot + 1
582       call hepmc_event_particle_iterator_advance (it)
583    end do
584    allocate (barcode (n_tot))
585    call hepmc_event_particle_iterator_reset (it)
586    do i = 1, n_tot
587       barcode(i) = hepmc_particle_get_barcode &
588            (hepmc_event_particle_iterator_get (it))
589       call hepmc_event_particle_iterator_advance (it)
590    end do
591    allocate (particle_set%prt (n_tot))
592    call hepmc_event_particle_iterator_reset (it)
593    do i = 1, n_tot
594       prt = hepmc_event_particle_iterator_get (it)
595       call particle_init (particle_set%prt(i), &
596            prt, model, polarization, barcode)
597       call hepmc_event_particle_iterator_advance (it)
598    end do
599    call hepmc_event_particle_iterator_final (it)
600    particle_set%n_tot = n_tot
601  end subroutine particle_set_init_hepmc
602
603  subroutine particle_set_final (particle_set)
604    type(particle_set_t), intent(inout) :: particle_set
605    if (allocated (particle_set%prt))  call particle_final (particle_set%prt)
606    call state_matrix_final (particle_set%correlated_state)
607  end subroutine particle_set_final
608
609  subroutine particle_set_write (particle_set, unit)
610    type(particle_set_t), intent(in) :: particle_set
611    integer, intent(in), optional :: unit
612    integer :: u, i
613    u = output_unit (unit);  if (u < 0)  return
614    write (u, "(1x,A)") "Particle set:"
615    if (particle_set%n_tot /= 0) then
616       do i = 1, particle_set%n_tot
617          write (u, "(1x,A,1x,I0)", advance="no") "Particle", i
618          call particle_write (particle_set%prt(i), u)
619       end do
620       if (state_matrix_is_defined (particle_set%correlated_state)) then
621          write (u, *) "Correlated state density matrix:"
622          call state_matrix_write (particle_set%correlated_state, u)
623       end if
624    else
625       write (u, "(3x,A)") "[empty]"
626    end if
627  end subroutine particle_set_write
628
629  subroutine particle_set_write_raw (particle_set, u)
630    type(particle_set_t), intent(in) :: particle_set
631    integer, intent(in) :: u
632    integer :: i
633    write (u) particle_set%n_in, particle_set%n_vir, particle_set%n_out
634    write (u) particle_set%n_tot
635    do i = 1, particle_set%n_tot
636       call particle_write_raw (particle_set%prt(i), u)
637    end do
638    call state_matrix_write_raw (particle_set%correlated_state, u)
639  end subroutine particle_set_write_raw
640
641  subroutine particle_set_read_raw (particle_set, u, iostat)
642    type(particle_set_t), intent(out) :: particle_set
643    integer, intent(in) :: u
644    integer, intent(out), optional :: iostat
645    integer :: i
646    read (u, iostat=iostat) &
647         particle_set%n_in, particle_set%n_vir, particle_set%n_out
648    read (u, iostat=iostat) particle_set%n_tot
649    allocate (particle_set%prt (particle_set%n_tot))
650    do i = 1, size (particle_set%prt)
651       call particle_read_raw (particle_set%prt(i), u, iostat=iostat)
652    end do
653    call state_matrix_read_raw (particle_set%correlated_state, u, iostat=iostat)
654  end subroutine particle_set_read_raw
655
656  subroutine particle_set_fill_hepeup (particle_set)
657    type(particle_set_t), intent(in), target :: particle_set
658    type(particle_t), pointer :: prt
659    type(particle_set_t), target :: pset_reduced
660    integer :: i, n_parents
661    integer, dimension(1) :: i_mother
662    call particle_set_reduce (particle_set, pset_reduced)
663    call hepeup_init (pset_reduced%n_tot)
664    do i = 1, pset_reduced%n_tot
665       prt => pset_reduced%prt(i)
666       call hepeup_set_particle (i, &
667            particle_get_pdg (prt), &
668            particle_get_status (prt), &
669            particle_get_parents (prt), &
670            particle_get_color (prt), &
671            particle_get_momentum (prt), &
672            particle_get_p2 (prt))
673       n_parents = particle_get_n_parents (prt)
674       if (n_parents == 1) then
675          i_mother = particle_get_parents (prt)
676          select case (particle_get_polarization_status (prt))
677          case (PRT_GENERIC_POLARIZATION)
678             call hepeup_set_particle_spin (i, &
679                  particle_get_momentum (prt), &
680                  particle_get_polarization (prt), &
681                  particle_get_momentum (pset_reduced%prt(i_mother(1))))
682          end select
683       end if
684    end do
685    call particle_set_final (pset_reduced)
686  end subroutine particle_set_fill_hepeup
687
688  subroutine particle_set_fill_hepevt (particle_set, keep_beams)
689    type(particle_set_t), intent(in), target :: particle_set
690    type(particle_t), pointer :: prt
691    type(particle_set_t), target :: pset_reduced
692    logical, intent(in), optional :: keep_beams
693    logical :: kb
694    integer :: i, n_parents
695    integer, dimension(1) :: i_mother
696    kb = .false.
697    if (present (keep_beams)) kb = keep_beams
698    call particle_set_reduce (particle_set, pset_reduced, kb)
699    call hepevt_init (pset_reduced%n_tot, pset_reduced%n_out)   
700    do i = 1, pset_reduced%n_tot
701       prt => pset_reduced%prt(i)
702       call hepevt_set_particle (i, &
703            particle_get_pdg (prt), &
704            particle_get_status (prt), &
705            particle_get_parents (prt), &
706            particle_get_children (prt), &
707            particle_get_momentum (prt), &
708            particle_get_p2 (prt), &
709            particle_get_helicity (prt))
710    end do
711    call particle_set_final (pset_reduced)
712  end subroutine particle_set_fill_hepevt
713
714  subroutine particle_set_fill_hepmc_event (particle_set, evt)
715    type(particle_set_t), intent(in) :: particle_set
716    type(hepmc_event_t), intent(inout) :: evt
717    type(hepmc_vertex_t), dimension(:), allocatable :: v
718    type(hepmc_particle_t), dimension(:), allocatable :: hprt
719    integer, dimension(:), allocatable :: v_from, v_to
720    integer :: n_vertices, i
721    allocate (v_from (particle_set%n_tot), v_to (particle_set%n_tot))
722    call particle_set_assign_vertices (particle_set, v_from, v_to, n_vertices)
723    allocate (v (n_vertices))
724    do i = 1, n_vertices
725       call hepmc_vertex_init (v(i))
726       call hepmc_event_add_vertex (evt, v(i))
727    end do
728    allocate (hprt (particle_set%n_tot))
729    do i = 1, particle_set%n_tot
730       if (v_to(i) /= 0 .or. v_from(i) /= 0) then
731          call particle_to_hepmc (particle_set%prt(i), hprt(i))
732       end if
733    end do
734    do i = 1, particle_set%n_tot
735       if (v_to(i) /= 0) then
736          call hepmc_vertex_add_particle_in (v(v_to(i)), hprt(i))
737       end if
738    end do
739    do i = 1, particle_set%n_tot
740       if (v_from(i) /= 0) then
741          call hepmc_vertex_add_particle_out (v(v_from(i)), hprt(i))
742       end if
743    end do
744  end subroutine particle_set_fill_hepmc_event
745 
746  subroutine particle_set_reset_status (particle_set, index, status)
747    type(particle_set_t), intent(inout) :: particle_set
748    integer, dimension(:), intent(in) :: index
749    integer, intent(in) :: status
750    integer :: i
751    if (allocated (particle_set%prt)) then
752       do i = 1, size (index)
753          call particle_reset_status (particle_set%prt(index(i)), status)
754       end do
755    end if
756  end subroutine particle_set_reset_status
757
758  function particle_set_get_real_parents (pset, i, keep_beams) result (parent)
759    integer, dimension(:), allocatable :: parent
760    type(particle_set_t), intent(in) :: pset
761    integer, intent(in) :: i
762    logical, intent(in), optional :: keep_beams
763    logical, dimension(:), allocatable :: is_real
764    logical, dimension(:), allocatable :: is_parent, is_real_parent
765    logical :: kb
766    integer :: j, k
767    kb = .false.
768    if (present (keep_beams)) kb = keep_beams
769    allocate (is_real (pset%n_tot))
770    is_real = particle_is_real (pset%prt(i), kb)
771    allocate (is_parent (pset%n_tot), is_real_parent (pset%n_tot))
772    is_real_parent = .false.
773    is_parent = .false.
774    is_parent(particle_get_parents(pset%prt(i))) = .true.
775    do while (any (is_parent))
776       where (is_real .and. is_parent)
777          is_real_parent = .true.
778          is_parent = .false.
779       end where
780       do j = size (is_parent), 1, -1
781          if (is_parent(j)) then
782             is_parent(particle_get_parents(pset%prt(j))) = .true.
783          end if
784       end do
785    end do
786    allocate (parent (count (is_real_parent)))
787    j = 0
788    do k = 1, size (is_parent)
789       if (is_real_parent(k)) then
790          j = j + 1
791          parent(j) = k
792       end if
793    end do
794  end function particle_set_get_real_parents
795
796  function particle_set_get_real_children (pset, i, keep_beams) result (child)
797    integer, dimension(:), allocatable :: child
798    type(particle_set_t), intent(in) :: pset
799    integer, intent(in) :: i
800    logical, dimension(:), allocatable :: is_real
801    logical, dimension(:), allocatable :: is_child, is_real_child
802    logical, intent(in), optional :: keep_beams
803    integer :: j, k
804    logical :: kb
805    kb = .false.
806    if (present (keep_beams)) kb = keep_beams
807    allocate (is_real (pset%n_tot))
808    is_real = particle_is_real (pset%prt(i), kb)
809    allocate (is_child (pset%n_tot), is_real_child (pset%n_tot))
810    is_real_child = .false.
811    is_child = .false.
812    is_child(particle_get_children(pset%prt(i))) = .true.
813    do while (any (is_child))
814       where (is_real .and. is_child)
815          is_real_child = .true.
816          is_child = .false.
817       end where
818       do j = 1, size (is_child)
819          if (is_child(j)) then
820             is_child(particle_get_children(pset%prt(j))) = .true.
821          end if
822       end do
823    end do
824    allocate (child (count (is_real_child)))
825    j = 0
826    do k = 1, size (is_child)
827       if (is_real_child(k)) then
828          j = j + 1
829          child(j) = k
830       end if
831    end do
832  end function particle_set_get_real_children
833
834  function particle_set_get_n_out (pset) result (n_out)
835     type(particle_set_t), intent(in) :: pset
836     integer :: n_out
837     n_out = pset%n_out
838  end function particle_set_get_n_out
839 
840  function particle_set_get_n_in (pset) result (n_in)
841     type(particle_set_t), intent(in) :: pset
842     integer :: n_in
843     n_in = pset%n_in
844  end function particle_set_get_n_in
845
846  function particle_set_get_n_tot (pset) result (n_tot)
847     type(particle_set_t), intent(in) :: pset
848     integer :: n_tot
849     n_tot = pset%n_tot
850  end function particle_set_get_n_tot
851
852  subroutine particle_set_reduce (pset_in, pset_out, keep_beams)
853    type(particle_set_t), intent(in) :: pset_in
854    type(particle_set_t), intent(out) :: pset_out
855    logical, intent(in), optional :: keep_beams
856    integer, dimension(:), allocatable :: status, map
857    integer :: i, j
858    logical :: kb
859    kb = .false.
860    if (present (keep_beams)) kb = keep_beams
861    allocate (status (pset_in%n_tot))   
862    status = particle_get_status (pset_in%prt)
863    if (kb) then
864       pset_out%n_in  = count (status == PRT_BEAM)
865       pset_out%n_vir = count (status == PRT_INCOMING) &
866            + count (status == PRT_RESONANT)
867    else           
868       pset_out%n_in  = count (status == PRT_INCOMING)
869       pset_out%n_vir = count (status == PRT_RESONANT)
870    end if
871    pset_out%n_out = count (status == PRT_OUTGOING)
872    pset_out%n_tot = pset_out%n_in + pset_out%n_vir + pset_out%n_out
873    allocate (pset_out%prt (pset_out%n_tot))
874    allocate (map (pset_in%n_tot))
875    map = 0
876    j = 0
877    if (kb) call copy_particles (PRT_BEAM)
878    call copy_particles (PRT_INCOMING)
879    call copy_particles (PRT_RESONANT)
880    call copy_particles (PRT_OUTGOING)
881    do i = 1, pset_in%n_tot
882       if (map(i) == 0)  cycle
883! triggers nagfor bug!
884!        call particle_set_parents (pset_out%prt(map(i)), &
885!             map (particle_set_get_real_parents (pset_in, i)))
886!        call particle_set_children (pset_out%prt(map(i)), &
887!             map (particle_set_get_real_children (pset_in, i)))
888! workaround:
889       call particle_set_parents (pset_out%prt(map(i)), &
890            particle_set_get_real_parents (pset_in, i, kb))
891       call particle_set_parents (pset_out%prt(map(i)), &
892            map (pset_out%prt(map(i))%parent))
893       call particle_set_children (pset_out%prt(map(i)), &
894            particle_set_get_real_children (pset_in, i, kb))
895       call particle_set_children (pset_out%prt(map(i)), &
896            map (pset_out%prt(map(i))%child))
897    end do
898  contains
899    subroutine copy_particles (stat)
900      integer, intent(in) :: stat
901      integer :: i
902      do i = 1, pset_in%n_tot
903         if (status(i) == stat) then
904            j = j + 1
905            map(i) = j
906            call particle_init (pset_out%prt(j), pset_in%prt(i))
907         end if
908      end do
909    end subroutine copy_particles
910  end subroutine particle_set_reduce
911
912  subroutine particle_set_assign_vertices &
913       (particle_set, v_from, v_to, n_vertices)
914    type(particle_set_t), intent(in) :: particle_set
915    integer, dimension(:), intent(out) :: v_from, v_to
916    integer, intent(out) :: n_vertices
917    integer, dimension(:), allocatable :: parent, child
918    integer :: n_parents, n_children, vf, vt
919    integer :: i, j, v
920    v_from = 0
921    v_to = 0
922    vf = 0
923    vt = 0
924    do i = 1, particle_set%n_tot
925       n_parents = particle_get_n_parents (particle_set%prt(i))
926       if (n_parents /= 0) then
927          allocate (parent (n_parents))
928          parent = particle_get_parents (particle_set%prt(i))
929          SCAN_PARENTS: do j = 1, size (parent)
930             v = v_to(parent(j))
931             if (v /= 0) then
932                v_from(i) = v;  exit SCAN_PARENTS
933             end if
934          end do SCAN_PARENTS
935          if (v_from(i) == 0) then
936             vf = vf + 1;  v_from(i) = vf
937             v_to(parent) = vf
938          end if
939          deallocate (parent)
940       end if
941       n_children = particle_get_n_children (particle_set%prt(i))
942       if (n_children /= 0) then
943          allocate (child (n_children))
944          child = particle_get_children (particle_set%prt(i))
945          SCAN_CHILDREN: do j = 1, size (child)
946             v = v_from(child(j))
947             if (v /= 0) then
948                v_to(i) = v;  exit SCAN_CHILDREN
949             end if
950          end do SCAN_CHILDREN
951          if (v_to(i) == 0) then
952             vt = vt + 1;  v_to(i) = vt
953             v_from(child) = vt
954          end if
955          deallocate (child)
956       end if
957    end do
958    n_vertices = max (vf, vt)
959  end subroutine particle_set_assign_vertices
960
961  subroutine particle_set_to_prt_list (particle_set, prt_list)
962    type(particle_set_t), intent(in), target :: particle_set
963    type(prt_list_t), intent(out) :: prt_list
964    type(particle_t), pointer :: prt
965    integer :: i, k
966    call prt_list_init (prt_list)
967    call prt_list_reset (prt_list, particle_set%n_in + particle_set%n_out)
968    k = 0
969    do i = 1, particle_set%n_tot
970       prt => particle_set%prt(i)
971       select case (particle_get_status (prt))
972       case (PRT_INCOMING)
973          k = k + 1
974          call prt_list_set_incoming (prt_list, k, &
975               particle_get_pdg (prt), &
976               particle_get_momentum (prt), &
977               particle_get_p2 (prt))
978       case (PRT_OUTGOING)
979          k = k + 1
980          call prt_list_set_outgoing (prt_list, k, &
981               particle_get_pdg (prt), &
982               particle_get_momentum (prt), &
983               particle_get_p2 (prt))
984       end select
985    end do
986  end subroutine particle_set_to_prt_list
987
988  subroutine particles_test
989    use os_interface, only: os_data_t
990    type(os_data_t) :: os_data
991    type(model_t), pointer :: model
992    type(flavor_t), dimension(3) :: flv
993    type(color_t), dimension(3) :: col
994    type(helicity_t), dimension(3) :: hel
995    type(quantum_numbers_t), dimension(3) :: qn
996    type(vector4_t), dimension(3) :: p
997    type(interaction_t), target :: int1, int2
998    type(quantum_numbers_mask_t) :: qn_mask_conn, qn_rest
999    type(evaluator_t), target :: eval
1000    type(interaction_t), pointer :: int
1001    type(particle_set_t) :: particle_set1, particle_set2
1002    type(particle_set_t) :: particle_set3, particle_set4
1003    type(hepmc_event_t) :: hepmc_event
1004    type(hepmc_iostream_t) :: iostream
1005    type(prt_list_t) :: prt_list
1006    integer :: u
1007    print *, "*** Read model file"
1008    call syntax_model_file_init ()
1009    call model_list_read_model &
1010         (var_str("QCD"), var_str("test.mdl"), os_data, model)
1011    print *
1012    print *, "*** Setup production process ***"
1013    call interaction_init (int1, 2, 0, 1, set_relations=.true.)
1014    call flavor_init (flv, (/1, -1, 23/), model)
1015    call helicity_init (hel(3), 1, 1)
1016    call quantum_numbers_init (qn, flv, hel)
1017    call interaction_add_state (int1, qn, value=(0.25_default, 0._default))
1018    call helicity_init (hel(3), 1,-1)
1019    call quantum_numbers_init (qn, flv, hel)
1020    call interaction_add_state (int1, qn, value=(0._default, 0.25_default))
1021    call helicity_init (hel(3),-1, 1)
1022    call quantum_numbers_init (qn, flv, hel)
1023    call interaction_add_state (int1, qn, value=(0._default,-0.25_default))
1024    call helicity_init (hel(3),-1,-1)
1025    call quantum_numbers_init (qn, flv, hel)
1026    call interaction_add_state (int1, qn, value=(0.25_default, 0._default))
1027    call helicity_init (hel(3), 0, 0)
1028    call quantum_numbers_init (qn, flv, hel)
1029    call interaction_add_state (int1, qn, value=(0.5_default, 0._default))
1030    call interaction_freeze (int1)
1031    p(1) = vector4_moving (45._default, 45._default, 3)
1032    p(2) = vector4_moving (45._default,-45._default, 3)
1033    p(3) = p(1) + p(2)
1034    call interaction_set_momenta (int1, p)
1035    print *
1036    print *, "*** Setup decay process ***"
1037    call interaction_init (int2, 1, 0, 2, set_relations=.true.)
1038    call flavor_init (flv, (/23, 1, -1/), model)
1039    call color_init_col_acl (col, (/ 0, 501, 0 /), (/ 0, 0, 501 /))
1040    call helicity_init (hel, (/ 1, 1, 1/), (/ 1, 1, 1/))
1041    call quantum_numbers_init (qn, flv, col, hel)
1042    call interaction_add_state (int2, qn, value=(1._default, 0._default))
1043    call helicity_init (hel, (/ 1, 1, 1/), (/-1,-1,-1/))
1044    call quantum_numbers_init (qn, flv, col, hel)
1045    call interaction_add_state (int2, qn, value=(0._default, 0.1_default))
1046    call helicity_init (hel, (/-1,-1,-1/), (/ 1, 1, 1/))
1047    call quantum_numbers_init (qn, flv, col, hel)
1048    call interaction_add_state (int2, qn, value=(0._default,-0.1_default))
1049    call helicity_init (hel, (/-1,-1,-1/), (/-1,-1,-1/))
1050    call quantum_numbers_init (qn, flv, col, hel)
1051    call interaction_add_state (int2, qn, value=(1._default, 0._default))
1052    call helicity_init (hel, (/ 0, 1,-1/), (/ 0, 1,-1/))
1053    call quantum_numbers_init (qn, flv, col, hel)
1054    call interaction_add_state (int2, qn, value=(4._default, 0._default))
1055    call helicity_init (hel, (/ 0,-1, 1/), (/ 0, 1,-1/))
1056    call quantum_numbers_init (qn, flv, col, hel)
1057    call interaction_add_state (int2, qn, value=(2._default, 0._default))
1058    call helicity_init (hel, (/ 0, 1,-1/), (/ 0,-1, 1/))
1059    call quantum_numbers_init (qn, flv, col, hel)
1060    call interaction_add_state (int2, qn, value=(2._default, 0._default))
1061    call helicity_init (hel, (/ 0,-1, 1/), (/ 0,-1, 1/))
1062    call quantum_numbers_init (qn, flv, col, hel)
1063    call interaction_add_state (int2, qn, value=(4._default, 0._default))
1064    call flavor_init (flv, (/23, 2, -2/), model)
1065    call helicity_init (hel, (/ 0, 1,-1/), (/ 0, 1,-1/))
1066    call quantum_numbers_init (qn, flv, col, hel)
1067    call interaction_add_state (int2, qn, value=(0.5_default, 0._default))
1068    call helicity_init (hel, (/ 0,-1, 1/), (/ 0,-1, 1/))
1069    call quantum_numbers_init (qn, flv, col, hel)
1070    call interaction_add_state (int2, qn, value=(0.5_default, 0._default))
1071    call interaction_freeze (int2)
1072    p(2) = vector4_moving (45._default, 45._default, 2)
1073    p(3) = vector4_moving (45._default,-45._default, 2)
1074    call interaction_set_momenta (int2, p)
1075    call interaction_set_source_link (int2, 1, int1, 3)
1076    call interaction_write (int1)
1077    call interaction_write (int2)
1078    print *
1079    print *, "*** Concatenate production and decay ***"
1080    call evaluator_init_product (eval, int1, int2, qn_mask_conn, &
1081         connections_are_resonant=.true.)
1082    call evaluator_receive_momenta (eval)
1083    call evaluator_evaluate (eval)
1084    call evaluator_write (eval)
1085    print *
1086    print *, "*** Factorize as particle list (complete, polarized) ***"
1087    int => evaluator_get_int_ptr (eval)
1088    call particle_set_init &
1089         (particle_set1, int, int, FM_FACTOR_HELICITY, &
1090          (/0.2_default, 0.2_default/), .false., .true.)
1091    call particle_set_write (particle_set1)
1092    print *
1093    print *, "*** Write this to HEPEUP and print as LHEF format ***"
1094    call les_houches_events_write_header ()
1095    call heprup_init ((/2212, 2212/), (/7.e3_default, 7.e3_default/), &
1096         n_processes=1, unweighted=.true., negative_weights=.false.)
1097    call heprup_set_process_parameters (1, 1)
1098    call heprup_write_lhef ()
1099    call particle_set_fill_hepeup (particle_set1)
1100    call hepeup_write_lhef ()
1101    call les_houches_events_write_footer ()
1102    print *
1103    print *, "*** Factorize as particle list (in/out only, selected helicity) ***"
1104    int => evaluator_get_int_ptr (eval)
1105    call particle_set_init &
1106         (particle_set2, int, int, FM_SELECT_HELICITY, &
1107          (/0.9_default, 0.9_default/), .false., .false.)
1108    call particle_set_write (particle_set2)
1109    call particle_set_final (particle_set2)
1110    print *
1111    print *, "*** Factorize as particle list (complete, selected helicity) ***"
1112    int => evaluator_get_int_ptr (eval)
1113    call particle_set_init &
1114         (particle_set2, int, int, FM_SELECT_HELICITY, &
1115          (/0.7_default, 0.7_default/), .false., .true.)
1116    call particle_set_write (particle_set2)
1117    print *
1118    print *, "*** Write to HepMC, print, and output to particles_test.hepmc.dat ***"
1119    call hepmc_event_init (hepmc_event, 11, 127)
1120    call particle_set_fill_hepmc_event (particle_set2, hepmc_event)
1121    call hepmc_event_print (hepmc_event)
1122    call hepmc_iostream_open_out &
1123         (iostream , var_str ("particles_test.hepmc.dat"))
1124    call hepmc_iostream_write_event (iostream, hepmc_event)
1125    call hepmc_iostream_close (iostream)
1126    print *
1127    print *, "*** Recover from HepMC file ***"
1128    call particle_set_final (particle_set2)
1129    call hepmc_event_final (hepmc_event)
1130    call hepmc_event_init (hepmc_event)
1131    call hepmc_iostream_open_in &
1132         (iostream , var_str ("particles_test.hepmc.dat"))
1133    call hepmc_iostream_read_event (iostream, hepmc_event)
1134    call hepmc_iostream_close (iostream)
1135    call particle_set_init (particle_set2, &
1136         hepmc_event, model, PRT_DEFINITE_HELICITY)
1137    call particle_set_write (particle_set2)
1138    print *
1139    print *, "*** Factorize (complete, polarized, correlated); write and read again ***"
1140    int => evaluator_get_int_ptr (eval)
1141    call particle_set_init &
1142         (particle_set3, int, int, FM_FACTOR_HELICITY, &
1143          (/0.7_default, 0.7_default/), .true., .true.)
1144    call particle_set_write (particle_set3)
1145    u = free_unit ()
1146    open (u, action="readwrite", form="unformatted", status="scratch")
1147    call particle_set_write_raw (particle_set3, u)
1148    rewind (u)
1149    call particle_set_read_raw (particle_set4, u)
1150    close (u)
1151    print *
1152    call particle_set_write (particle_set4)
1153    print *
1154    print *, "*** Transform to a prt_list object ***"
1155    call particle_set_to_prt_list (particle_set4, prt_list)
1156    call prt_list_write (prt_list)
1157    print *
1158    print *, "*** Cleanup ***"
1159    call particle_set_final (particle_set1)
1160    call particle_set_final (particle_set2)
1161    call particle_set_final (particle_set3)
1162    call particle_set_final (particle_set4)
1163    call evaluator_final (eval)
1164    call interaction_final (int1)
1165    call interaction_final (int2)
1166    call hepmc_event_final (hepmc_event)
1167  end subroutine particles_test
1168
1169
1170end module particles