go-hep.org/x/hep@v0.38.1/hepmc/rootcnv/rootcnv.go (about)

     1  // Copyright ©2022 The go-hep Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package rootcnv provides tools to convert between HepMC2 data types
     6  // and ROOT data structures.
     7  package rootcnv // import "go-hep.org/x/hep/hepmc/rootcnv"
     8  
     9  import (
    10  	"sort"
    11  
    12  	"go-hep.org/x/hep/fmom"
    13  	"go-hep.org/x/hep/hepmc"
    14  	"go-hep.org/x/hep/sliceop"
    15  )
    16  
    17  type event struct {
    18  	SignalProcessID  int32   `groot:"Event_processID"` // id of the signal process
    19  	Event_number     int32   `groot:"Event_nbr"`       // event number
    20  	Event_mpi        int32   `groot:"Event_mpi"`       // number of multi particle interactions
    21  	Event_scale      float64 `groot:"Event_scale"`     // energy scale,
    22  	Event_alphaQCD   float64 `groot:"Event_alphaQCD"`  // QCD coupling, see hep-ph/0109068
    23  	Event_alphaQED   float64 `groot:"Event_alphaQED"`  // QED coupling, see hep-ph/0109068
    24  	Event_barcodeSPV int32   `groot:"Event_barcodeSPV"`
    25  	Event_barcodeBP1 int32   `groot:"Event_barcodeBP1"`
    26  	Event_barcodeBP2 int32   `groot:"Event_barcodeBP2"`
    27  	Event_nvtx       int32   `groot:"Event_nvtx"`
    28  	Event_npart      int32   `groot:"Event_npart"`
    29  	Event_inbcs      []int32 `groot:"Event_inbcs"`  // Event barcodes of (p-in) for each vertex
    30  	Event_outbcs     []int32 `groot:"Event_outbcs"` // Event barcodes of (p-out) for each vertex
    31  
    32  	WeightsSlice    []float64 `groot:"Weights_slice"`
    33  	WeightsMapKeys  []string  `groot:"Weights_keys"`
    34  	WeightsMapNames []int32   `groot:"Weights_names"`
    35  	RandomStates    []int64   `groot:"Random_states"`
    36  
    37  	XsectValue float64 `groot:"Xsection_value"`
    38  	XsectError float64 `groot:"Xsection_error"`
    39  
    40  	HI_ncollHard         int32   `groot:"HI_ncoll_hard"`
    41  	HI_npartProj         int32   `groot:"HI_npart_proj"`
    42  	HI_npartTarg         int32   `groot:"HI_npart_targ"`
    43  	HI_ncoll             int32   `groot:"HI_ncoll"`
    44  	HI_nnwColl           int32   `groot:"HI_nnw_coll"`
    45  	HI_nwNColl           int32   `groot:"HI_nwn_coll"`
    46  	HI_nwNwColl          int32   `groot:"HI_nwnw_coll"`
    47  	HI_spectatorNeutrons int32   `groot:"HI_spect_neutrons"`
    48  	HI_spectatorProtons  int32   `groot:"HI_spect_protons"`
    49  	HI_impactParameter   float32 `groot:"HI_impact_param"`
    50  	HI_eventPlaneAngle   float32 `groot:"HI_evt_plane_angle"`
    51  	HI_eccentricity      float32 `groot:"HI_eccentricity"`
    52  	HI_sigmaInelNN       float32 `groot:"HI_sigma_inel_nn"`
    53  
    54  	PDF_Parton1 int32   `groot:"PDF_parton1"`
    55  	PDF_Parton2 int32   `groot:"PDF_parton2"`
    56  	PDF_X1      float64 `groot:"PDF_x1"`
    57  	PDF_X2      float64 `groot:"PDF_x2"`
    58  	PDF_Q2      float64 `groot:"PDF_Q2"`
    59  	PDF_X1f     float64 `groot:"PDF_x1f"`
    60  	PDF_X2f     float64 `groot:"PDF_x2f"`
    61  	PDF_ID1     int32   `groot:"PDF_id1"`
    62  	PDF_ID2     int32   `groot:"PDF_id2"`
    63  
    64  	MomentumUnit int8 `groot:"Momentum_unit"`
    65  	LengthUnit   int8 `groot:"Length_unit"`
    66  
    67  	Vertex_x    []float64   `groot:"Vertex_x"`
    68  	Vertex_y    []float64   `groot:"Vertex_y"`
    69  	Vertex_z    []float64   `groot:"Vertex_z"`
    70  	Vertex_t    []float64   `groot:"Vertex_t"`
    71  	Vertex_id   []int32     `groot:"Vertex_id"`
    72  	Vertex_wsli [][]float64 `groot:"Vertex_wsli"`
    73  	Vertex_wkey [][]string  `groot:"Vertex_wkey"`
    74  	Vertex_wval [][]int32   `groot:"Vertex_wval"`
    75  	Vertex_bc   []int32     `groot:"Vertex_bc"`
    76  	Vertex_nin  []int32     `groot:"Vertex_nin"`
    77  	Vertex_nout []int32     `groot:"Vertex_nout"`
    78  
    79  	Particle_bc   []int32   `groot:"Particle_bc"`
    80  	Particle_pid  []int64   `groot:"Particle_pid"`
    81  	Particle_px   []float64 `groot:"Particle_px"`
    82  	Particle_py   []float64 `groot:"Particle_py"`
    83  	Particle_pz   []float64 `groot:"Particle_pz"`
    84  	Particle_ene  []float64 `groot:"Particle_ene"`
    85  	Particle_mass []float64 `groot:"Particle_mass"`
    86  	//	Particle_nflow  []int32   `groot:"Particle_nflow"`
    87  	Particle_flow   [][]int32 `groot:"Particle_flow"`
    88  	Particle_theta  []float64 `groot:"Particle_theta"`
    89  	Particle_phi    []float64 `groot:"Particle_phi"`
    90  	Particle_status []int32   `groot:"Particle_status"`
    91  	Particle_pvtx   []int32   `groot:"Particle_pvtx"`
    92  	Particle_evtx   []int32   `groot:"Particle_evtx"`
    93  
    94  	barcodes []int // work buffer
    95  }
    96  
    97  func (evt *event) write(h *hepmc.Event) error {
    98  	h.SignalProcessID = int(evt.SignalProcessID)
    99  	h.EventNumber = int(evt.Event_number)
   100  	h.Mpi = int(evt.Event_mpi)
   101  	h.Scale = evt.Event_scale
   102  	h.AlphaQCD = evt.Event_alphaQCD
   103  	h.AlphaQED = evt.Event_alphaQED
   104  	h.Vertices = make(map[int]*hepmc.Vertex, evt.Event_nvtx)
   105  	h.Particles = make(map[int]*hepmc.Particle, evt.Event_npart)
   106  
   107  	h.Weights.Slice = sliceop.Resize(h.Weights.Slice, len(evt.WeightsSlice))
   108  	copy(h.Weights.Slice, evt.WeightsSlice)
   109  	h.Weights.Map = make(map[string]int, len(evt.WeightsMapKeys))
   110  	for i, k := range evt.WeightsMapKeys {
   111  		v := evt.WeightsMapNames[i]
   112  		h.Weights.Map[k] = int(v)
   113  	}
   114  	h.RandomStates = sliceop.Resize(h.RandomStates, len(evt.RandomStates))
   115  	copy(h.RandomStates, evt.RandomStates)
   116  
   117  	switch {
   118  	case !evt.hasXSect():
   119  		h.CrossSection = nil
   120  	default:
   121  		h.CrossSection = &hepmc.CrossSection{
   122  			Value: evt.XsectValue,
   123  			Error: evt.XsectError,
   124  		}
   125  	}
   126  
   127  	switch {
   128  	case !evt.hasHI():
   129  		h.HeavyIon = nil
   130  	default:
   131  		h.HeavyIon = &hepmc.HeavyIon{
   132  			NCollHard:         int(evt.HI_ncollHard),
   133  			NPartProj:         int(evt.HI_npartProj),
   134  			NPartTarg:         int(evt.HI_npartTarg),
   135  			NColl:             int(evt.HI_ncoll),
   136  			NNwColl:           int(evt.HI_nnwColl),
   137  			NwNColl:           int(evt.HI_nwNColl),
   138  			NwNwColl:          int(evt.HI_nwNwColl),
   139  			SpectatorNeutrons: int(evt.HI_spectatorNeutrons),
   140  			SpectatorProtons:  int(evt.HI_spectatorProtons),
   141  			ImpactParameter:   evt.HI_impactParameter,
   142  			EventPlaneAngle:   evt.HI_eventPlaneAngle,
   143  			Eccentricity:      evt.HI_eccentricity,
   144  			SigmaInelNN:       evt.HI_sigmaInelNN,
   145  		}
   146  	}
   147  
   148  	if h.PdfInfo == nil {
   149  		h.PdfInfo = new(hepmc.PdfInfo)
   150  	}
   151  	h.PdfInfo.ID1 = int(evt.PDF_Parton1)
   152  	h.PdfInfo.ID2 = int(evt.PDF_Parton2)
   153  	h.PdfInfo.X1 = evt.PDF_X1
   154  	h.PdfInfo.X2 = evt.PDF_X2
   155  	h.PdfInfo.ScalePDF = evt.PDF_Q2
   156  	h.PdfInfo.Pdf1 = evt.PDF_X1f
   157  	h.PdfInfo.Pdf2 = evt.PDF_X2f
   158  	h.PdfInfo.LHAPdf1 = int(evt.PDF_ID1)
   159  	h.PdfInfo.LHAPdf2 = int(evt.PDF_ID2)
   160  
   161  	h.MomentumUnit = hepmc.MomentumUnit(evt.MomentumUnit)
   162  	h.LengthUnit = hepmc.LengthUnit(evt.LengthUnit)
   163  
   164  	// flow := evt.Particle_flow
   165  	for i := range evt.Particle_bc {
   166  		flow := evt.Particle_flow[i]
   167  		p := &hepmc.Particle{
   168  			Momentum: fmom.NewPxPyPzE(
   169  				evt.Particle_px[i],
   170  				evt.Particle_py[i],
   171  				evt.Particle_pz[i],
   172  				evt.Particle_ene[i],
   173  			),
   174  			PdgID:  evt.Particle_pid[i],
   175  			Status: int(evt.Particle_status[i]),
   176  			Flow: hepmc.Flow{
   177  				Icode: make(map[int]int, len(flow)),
   178  			},
   179  			Polarization: hepmc.Polarization{
   180  				Theta: evt.Particle_theta[i],
   181  				Phi:   evt.Particle_phi[i],
   182  			},
   183  			Barcode:       int(evt.Particle_bc[i]),
   184  			GeneratedMass: evt.Particle_mass[i],
   185  		}
   186  		p.Flow.Particle = p
   187  		for ii := 0; ii < len(flow); ii += 2 {
   188  			p.Flow.Icode[int(flow[ii])] = int(flow[ii+1])
   189  		}
   190  		h.Particles[p.Barcode] = p
   191  	}
   192  
   193  	var (
   194  		pin  = evt.Event_inbcs
   195  		pout = evt.Event_outbcs
   196  	)
   197  	for i := range evt.Vertex_bc {
   198  		wsli := evt.Vertex_wsli[i]
   199  		wkey := evt.Vertex_wkey[i]
   200  		wval := evt.Vertex_wval[i]
   201  		vtx := &hepmc.Vertex{
   202  			Position: fmom.NewPxPyPzE(
   203  				evt.Vertex_x[i],
   204  				evt.Vertex_y[i],
   205  				evt.Vertex_z[i],
   206  				evt.Vertex_t[i],
   207  			),
   208  			ParticlesIn:  make([]*hepmc.Particle, evt.Vertex_nin[i]),
   209  			ParticlesOut: make([]*hepmc.Particle, evt.Vertex_nout[i]),
   210  			ID:           int(evt.Vertex_id[i]),
   211  			Weights: hepmc.Weights{
   212  				Slice: make([]float64, len(wsli)),
   213  				Map:   make(map[string]int, len(wkey)),
   214  			},
   215  			Event:   h,
   216  			Barcode: int(evt.Vertex_bc[i]),
   217  		}
   218  		for i := range vtx.ParticlesIn {
   219  			p := h.Particles[int(pin[i])]
   220  			p.EndVertex = vtx
   221  			vtx.ParticlesIn[i] = p
   222  		}
   223  		pin = pin[len(vtx.ParticlesIn):]
   224  
   225  		for i := range vtx.ParticlesOut {
   226  			p := h.Particles[int(pout[i])]
   227  			p.ProdVertex = vtx
   228  			vtx.ParticlesOut[i] = p
   229  		}
   230  		pout = pout[len(vtx.ParticlesOut):]
   231  
   232  		copy(vtx.Weights.Slice, wsli)
   233  		for i, k := range wkey {
   234  			v := wval[i]
   235  			vtx.Weights.Map[k] = int(v)
   236  		}
   237  
   238  		h.Vertices[vtx.Barcode] = vtx
   239  	}
   240  
   241  	switch evt.Event_barcodeSPV {
   242  	case 0:
   243  		h.SignalVertex = nil
   244  	default:
   245  		h.SignalVertex = h.Vertices[int(evt.Event_barcodeSPV)]
   246  	}
   247  
   248  	switch evt.Event_barcodeBP1 {
   249  	case 0:
   250  		h.Beams[0] = nil
   251  	default:
   252  		h.Beams[0] = h.Particles[int(evt.Event_barcodeBP1)]
   253  	}
   254  
   255  	switch evt.Event_barcodeBP2 {
   256  	case 0:
   257  		h.Beams[1] = nil
   258  	default:
   259  		h.Beams[1] = h.Particles[int(evt.Event_barcodeBP2)]
   260  	}
   261  
   262  	return nil
   263  }
   264  
   265  func (evt *event) read(h *hepmc.Event) error {
   266  	evt.SignalProcessID = int32(h.SignalProcessID)
   267  	evt.Event_number = int32(h.EventNumber)
   268  	evt.Event_mpi = int32(h.Mpi)
   269  	evt.Event_scale = h.Scale
   270  	evt.Event_alphaQCD = h.AlphaQCD
   271  	evt.Event_alphaQED = h.AlphaQED
   272  	switch {
   273  	case h.SignalVertex != nil:
   274  		evt.Event_barcodeSPV = int32(h.SignalVertex.Barcode)
   275  	default:
   276  		evt.Event_barcodeSPV = 0
   277  	}
   278  	evt.Event_nvtx = int32(len(h.Vertices))
   279  	evt.Event_npart = int32(len(h.Particles))
   280  	switch {
   281  	case h.Beams[0] != nil:
   282  		evt.Event_barcodeBP1 = int32(h.Beams[0].Barcode)
   283  	default:
   284  		evt.Event_barcodeBP1 = 0
   285  	}
   286  	switch {
   287  	case h.Beams[1] != nil:
   288  		evt.Event_barcodeBP2 = int32(h.Beams[1].Barcode)
   289  	default:
   290  		evt.Event_barcodeBP2 = 0
   291  	}
   292  
   293  	evt.WeightsSlice = sliceop.Resize(evt.WeightsSlice, len(h.Weights.Slice))
   294  	copy(evt.WeightsSlice, h.Weights.Slice)
   295  	evt.WeightsMapKeys = sliceop.Resize(evt.WeightsMapKeys, len(h.Weights.Map))[:0]
   296  	evt.WeightsMapNames = sliceop.Resize(evt.WeightsMapNames, len(h.Weights.Map))[:0]
   297  	for k, v := range h.Weights.Map {
   298  		evt.WeightsMapKeys = append(evt.WeightsMapKeys, k)
   299  		evt.WeightsMapNames = append(evt.WeightsMapNames, int32(v))
   300  	}
   301  	evt.RandomStates = sliceop.Resize(evt.RandomStates, len(h.RandomStates))
   302  	copy(evt.RandomStates, h.RandomStates)
   303  
   304  	switch xsect := h.CrossSection; xsect {
   305  	case nil:
   306  		evt.XsectValue = 0
   307  		evt.XsectError = 0
   308  	default:
   309  		evt.XsectValue = h.CrossSection.Value
   310  		evt.XsectError = h.CrossSection.Error
   311  	}
   312  
   313  	switch hi := h.HeavyIon; hi {
   314  	case nil:
   315  		evt.HI_ncollHard = 0
   316  		evt.HI_npartProj = 0
   317  		evt.HI_npartTarg = 0
   318  		evt.HI_ncoll = 0
   319  		evt.HI_nnwColl = 0
   320  		evt.HI_nwNColl = 0
   321  		evt.HI_nwNwColl = 0
   322  		evt.HI_spectatorNeutrons = 0
   323  		evt.HI_spectatorProtons = 0
   324  		evt.HI_impactParameter = 0
   325  		evt.HI_eventPlaneAngle = 0
   326  		evt.HI_eccentricity = 0
   327  		evt.HI_sigmaInelNN = 0
   328  	default:
   329  		evt.HI_ncollHard = int32(hi.NCollHard)
   330  		evt.HI_npartProj = int32(hi.NPartProj)
   331  		evt.HI_npartTarg = int32(hi.NPartTarg)
   332  		evt.HI_ncoll = int32(hi.NColl)
   333  		evt.HI_nnwColl = int32(hi.NNwColl)
   334  		evt.HI_nwNColl = int32(hi.NwNColl)
   335  		evt.HI_nwNwColl = int32(hi.NwNwColl)
   336  		evt.HI_spectatorNeutrons = int32(hi.SpectatorNeutrons)
   337  		evt.HI_spectatorProtons = int32(hi.SpectatorProtons)
   338  		evt.HI_impactParameter = hi.ImpactParameter
   339  		evt.HI_eventPlaneAngle = hi.EventPlaneAngle
   340  		evt.HI_eccentricity = hi.Eccentricity
   341  		evt.HI_sigmaInelNN = hi.SigmaInelNN
   342  	}
   343  
   344  	evt.PDF_Parton1 = int32(h.PdfInfo.ID1)
   345  	evt.PDF_Parton2 = int32(h.PdfInfo.ID2)
   346  	evt.PDF_X1 = h.PdfInfo.X1
   347  	evt.PDF_X2 = h.PdfInfo.X2
   348  	evt.PDF_Q2 = h.PdfInfo.ScalePDF
   349  	evt.PDF_X1f = h.PdfInfo.Pdf1
   350  	evt.PDF_X2f = h.PdfInfo.Pdf2
   351  	evt.PDF_ID1 = int32(h.PdfInfo.LHAPdf1)
   352  	evt.PDF_ID2 = int32(h.PdfInfo.LHAPdf2)
   353  
   354  	evt.MomentumUnit = int8(h.MomentumUnit)
   355  	evt.LengthUnit = int8(h.LengthUnit)
   356  
   357  	evt.barcodes = sliceop.Resize(evt.barcodes, len(h.Vertices))[:0]
   358  	for bc := range h.Vertices {
   359  		evt.barcodes = append(evt.barcodes, bc)
   360  	}
   361  	sort.Sort(sort.Reverse(sort.IntSlice(evt.barcodes)))
   362  
   363  	n := len(h.Vertices)
   364  	evt.Vertex_x = sliceop.Resize(evt.Vertex_x, n)[:0]
   365  	evt.Vertex_y = sliceop.Resize(evt.Vertex_y, n)[:0]
   366  	evt.Vertex_z = sliceop.Resize(evt.Vertex_z, n)[:0]
   367  	evt.Vertex_t = sliceop.Resize(evt.Vertex_t, n)[:0]
   368  	evt.Vertex_id = sliceop.Resize(evt.Vertex_id, n)[:0]
   369  	evt.Vertex_wsli = sliceop.Resize(evt.Vertex_wsli, n)[:0]
   370  	evt.Vertex_wkey = sliceop.Resize(evt.Vertex_wkey, n)[:0]
   371  	evt.Vertex_wval = sliceop.Resize(evt.Vertex_wval, n)[:0]
   372  	evt.Vertex_bc = sliceop.Resize(evt.Vertex_bc, n)[:0]
   373  	evt.Vertex_nin = sliceop.Resize(evt.Vertex_nin, n)[:0]
   374  	evt.Vertex_nout = sliceop.Resize(evt.Vertex_nout, n)[:0]
   375  
   376  	for _, bc := range evt.barcodes {
   377  		vtx := h.Vertices[bc]
   378  		evt.Vertex_x = append(evt.Vertex_x, vtx.Position.X())
   379  		evt.Vertex_y = append(evt.Vertex_y, vtx.Position.Y())
   380  		evt.Vertex_z = append(evt.Vertex_z, vtx.Position.Z())
   381  		evt.Vertex_t = append(evt.Vertex_t, vtx.Position.T())
   382  		evt.Vertex_id = append(evt.Vertex_id, int32(vtx.ID))
   383  		evt.Vertex_bc = append(evt.Vertex_bc, int32(vtx.Barcode))
   384  		evt.Vertex_nin = append(evt.Vertex_nin, int32(len(vtx.ParticlesIn)))
   385  		evt.Vertex_nout = append(evt.Vertex_nout, int32(len(vtx.ParticlesOut)))
   386  		for _, p := range vtx.ParticlesIn {
   387  			evt.Event_inbcs = append(evt.Event_inbcs, int32(p.Barcode))
   388  		}
   389  		for _, p := range vtx.ParticlesOut {
   390  			evt.Event_outbcs = append(evt.Event_outbcs, int32(p.Barcode))
   391  		}
   392  
   393  		wsli := make([]float64, len(vtx.Weights.Slice))
   394  		copy(wsli, vtx.Weights.Slice)
   395  		wkey := make([]string, 0, len(vtx.Weights.Map))
   396  		wval := make([]int32, 0, len(vtx.Weights.Map))
   397  		for k, v := range vtx.Weights.Map {
   398  			wkey = append(wkey, k)
   399  			wval = append(wval, int32(v))
   400  		}
   401  		evt.Vertex_wsli = append(evt.Vertex_wsli, wsli)
   402  		evt.Vertex_wkey = append(evt.Vertex_wkey, wkey)
   403  		evt.Vertex_wval = append(evt.Vertex_wval, wval)
   404  	}
   405  
   406  	evt.barcodes = sliceop.Resize(evt.barcodes, len(h.Particles))[:0]
   407  	for bc := range h.Particles {
   408  		evt.barcodes = append(evt.barcodes, bc)
   409  	}
   410  	sort.Ints(evt.barcodes)
   411  
   412  	n = len(h.Particles)
   413  	evt.Particle_bc = sliceop.Resize(evt.Particle_bc, n)[:0]
   414  	evt.Particle_pid = sliceop.Resize(evt.Particle_pid, n)[:0]
   415  	evt.Particle_px = sliceop.Resize(evt.Particle_px, n)[:0]
   416  	evt.Particle_py = sliceop.Resize(evt.Particle_py, n)[:0]
   417  	evt.Particle_pz = sliceop.Resize(evt.Particle_pz, n)[:0]
   418  	evt.Particle_ene = sliceop.Resize(evt.Particle_ene, n)[:0]
   419  	evt.Particle_mass = sliceop.Resize(evt.Particle_mass, n)[:0]
   420  	//	evt.Particle_nflow = sliceop.Resize(evt.Particle_nflow, n)[:0]
   421  	evt.Particle_flow = sliceop.Resize(evt.Particle_flow, n)[:0]
   422  	evt.Particle_theta = sliceop.Resize(evt.Particle_theta, n)[:0]
   423  	evt.Particle_phi = sliceop.Resize(evt.Particle_phi, n)[:0]
   424  	evt.Particle_status = sliceop.Resize(evt.Particle_status, n)[:0]
   425  	evt.Particle_pvtx = sliceop.Resize(evt.Particle_pvtx, n)[:0]
   426  	evt.Particle_evtx = sliceop.Resize(evt.Particle_evtx, n)[:0]
   427  
   428  	for _, bc := range evt.barcodes {
   429  		p := h.Particles[bc]
   430  		switch vtx := p.ProdVertex; vtx {
   431  		case nil:
   432  			evt.Particle_pvtx = append(evt.Particle_pvtx, 0)
   433  		default:
   434  			evt.Particle_pvtx = append(evt.Particle_pvtx, int32(vtx.Barcode))
   435  		}
   436  
   437  		evt.Particle_bc = append(evt.Particle_bc, int32(p.Barcode))
   438  		evt.Particle_pid = append(evt.Particle_pid, p.PdgID)
   439  		evt.Particle_px = append(evt.Particle_px, p.Momentum.Px())
   440  		evt.Particle_py = append(evt.Particle_py, p.Momentum.Py())
   441  		evt.Particle_pz = append(evt.Particle_pz, p.Momentum.Pz())
   442  		evt.Particle_ene = append(evt.Particle_ene, p.Momentum.E())
   443  		evt.Particle_mass = append(evt.Particle_mass, p.GeneratedMass)
   444  		//		evt.Particle_nflow = append(evt.Particle_nflow, int32(len(p.Flow.Icode)))
   445  		flow := make([]int32, 0, 2*len(p.Flow.Icode))
   446  		for k, v := range p.Flow.Icode {
   447  			flow = append(flow, int32(k), int32(v))
   448  		}
   449  		evt.Particle_flow = append(evt.Particle_flow, flow)
   450  		evt.Particle_theta = append(evt.Particle_theta, p.Polarization.Theta)
   451  		evt.Particle_phi = append(evt.Particle_phi, p.Polarization.Phi)
   452  		evt.Particle_status = append(evt.Particle_status, int32(p.Status))
   453  		switch vtx := p.EndVertex; vtx {
   454  		case nil:
   455  			evt.Particle_evtx = append(evt.Particle_evtx, 0)
   456  		default:
   457  			evt.Particle_evtx = append(evt.Particle_evtx, int32(vtx.Barcode))
   458  		}
   459  	}
   460  
   461  	return nil
   462  }
   463  
   464  func (evt *event) reset() {
   465  	evt.Event_inbcs = evt.Event_inbcs[:0]
   466  	evt.Event_outbcs = evt.Event_outbcs[:0]
   467  	evt.WeightsSlice = evt.WeightsSlice[:0]
   468  	evt.WeightsMapKeys = evt.WeightsMapKeys[:0]
   469  	evt.WeightsMapNames = evt.WeightsMapNames[:0]
   470  	evt.RandomStates = evt.RandomStates[:0]
   471  
   472  	evt.Vertex_x = evt.Vertex_x[:0]
   473  	evt.Vertex_y = evt.Vertex_y[:0]
   474  	evt.Vertex_z = evt.Vertex_z[:0]
   475  	evt.Vertex_t = evt.Vertex_t[:0]
   476  	evt.Vertex_wsli = evt.Vertex_wsli[:0]
   477  	evt.Vertex_wkey = evt.Vertex_wkey[:0]
   478  	evt.Vertex_wval = evt.Vertex_wval[:0]
   479  	evt.Vertex_id = evt.Vertex_id[:0]
   480  	evt.Vertex_bc = evt.Vertex_bc[:0]
   481  	evt.Vertex_nin = evt.Vertex_nin[:0]
   482  	evt.Vertex_nout = evt.Vertex_nout[:0]
   483  
   484  	evt.Particle_bc = evt.Particle_bc[:0]
   485  	evt.Particle_pid = evt.Particle_pid[:0]
   486  	evt.Particle_px = evt.Particle_px[:0]
   487  	evt.Particle_py = evt.Particle_py[:0]
   488  	evt.Particle_pz = evt.Particle_pz[:0]
   489  	evt.Particle_ene = evt.Particle_ene[:0]
   490  	evt.Particle_mass = evt.Particle_mass[:0]
   491  	//	evt.Particle_nflow = evt.Particle_nflow[:0]
   492  	evt.Particle_flow = evt.Particle_flow[:0]
   493  	evt.Particle_theta = evt.Particle_theta[:0]
   494  	evt.Particle_phi = evt.Particle_phi[:0]
   495  	evt.Particle_status = evt.Particle_status[:0]
   496  	evt.Particle_pvtx = evt.Particle_pvtx[:0]
   497  	evt.Particle_evtx = evt.Particle_evtx[:0]
   498  }
   499  
   500  func (evt *event) hasXSect() bool {
   501  	return !(evt.XsectError == 0 && evt.XsectValue == 0)
   502  }
   503  
   504  func (evt *event) hasHI() bool {
   505  	return !(evt.HI_ncollHard == 0 && evt.HI_npartProj == 0 && evt.HI_npartTarg == 0 && evt.HI_ncoll == 0 &&
   506  		evt.HI_nnwColl == 0 && evt.HI_nwNColl == 0 && evt.HI_nwNwColl == 0 && evt.HI_spectatorNeutrons == 0 &&
   507  		evt.HI_spectatorProtons == 0 && evt.HI_impactParameter == 0 && evt.HI_eventPlaneAngle == 0 &&
   508  		evt.HI_eccentricity == 0 && evt.HI_sigmaInelNN == 0)
   509  }