go-hep.org/x/hep@v0.38.1/lcio/cluster.go (about)

     1  // Copyright ©2017 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 lcio
     6  
     7  import (
     8  	"fmt"
     9  	"strings"
    10  
    11  	"go-hep.org/x/hep/sio"
    12  )
    13  
    14  // ClusterContainer is a collection of clusters.
    15  type ClusterContainer struct {
    16  	Flags    Flags
    17  	Params   Params
    18  	Clusters []Cluster
    19  }
    20  
    21  type Cluster struct {
    22  	// Type of cluster:
    23  	//  - bits 31-16: ECAL, HCAL, COMBINED, LAT, LCAL
    24  	//  - bits 15-00: NEUTRAL, CHARGED, UNDEFINED
    25  	Type       int32
    26  	Energy     float32    // energy of the cluster
    27  	EnergyErr  float32    // energy error of the cluster
    28  	Pos        [3]float32 // center of cluster (x,y,z)
    29  	PosErr     [6]float32 // covariance matrix of position
    30  	Theta      float32    // intrinsic direction: theta at position
    31  	Phi        float32    // intrinsic direction: phi at position
    32  	DirErr     [3]float32 // covariance matrix of direct
    33  	Shape      []float32  // shape parameters, defined in collection parameter 'ShapeParameterNames'
    34  	PIDs       []ParticleID
    35  	Clusters   []*Cluster        // clusters combined into this cluster
    36  	Hits       []*CalorimeterHit // hits that made this cluster
    37  	Weights    []float32         // energy fraction of the hit that contributed to this cluster
    38  	SubDetEnes []float32         // energy observed in a particular subdetector
    39  }
    40  
    41  func (clus ClusterContainer) String() string {
    42  	o := new(strings.Builder)
    43  	fmt.Fprintf(o, "%[1]s print out of Cluster collection %[1]s\n\n", strings.Repeat("-", 15))
    44  	fmt.Fprintf(o, "  flag:  0x%x\n%v", clus.Flags, clus.Params)
    45  	fmt.Fprintf(o, "     LCIO::CLBIT_HITS : %v\n", clus.Flags.Test(BitsClHits))
    46  
    47  	o.WriteString("\n")
    48  
    49  	const (
    50  		head = " [   id   ] |type|  energy  |energyerr |      position ( x,y,z)           |  itheta  |   iphi   \n"
    51  		tail = "------------|----|----------|----------|----------------------------------|----------|----------\n"
    52  	)
    53  	o.WriteString(head)
    54  	o.WriteString(tail)
    55  	for i := range clus.Clusters {
    56  		clu := &clus.Clusters[i]
    57  		fmt.Fprintf(o,
    58  			"[%09d] |%4d|%+.3e|%+.3e|%+.3e, %+.3e, %+.3e|%+.3e|%+.3e\n",
    59  			ID(clu),
    60  			clu.Type, clu.Energy, clu.EnergyErr,
    61  			clu.Pos[0], clu.Pos[1], clu.Pos[2],
    62  			clu.Theta,
    63  			clu.Phi,
    64  		)
    65  		fmt.Fprintf(o,
    66  			"            errors (6 pos)/(3 dir): (%+.3e, %+.3e, %+.3e, %+.3e, %+.3e, %+.3e)/(%+.3e, %+.3e, %+.3e)\n",
    67  			clu.PosErr[0], clu.PosErr[1], clu.PosErr[2], clu.PosErr[3], clu.PosErr[4], clu.PosErr[5],
    68  			clu.DirErr[0], clu.DirErr[1], clu.DirErr[2],
    69  		)
    70  		o.WriteString("            clusters(e): ")
    71  		for ii, cc := range clu.Clusters {
    72  			var e float32
    73  			if cc != nil {
    74  				e = cc.Energy
    75  			}
    76  			if ii > 0 {
    77  				o.WriteString(", ")
    78  			}
    79  			fmt.Fprintf(o, "%+.3e", e)
    80  		}
    81  		o.WriteString("\n")
    82  		o.WriteString("            subdetector energies : ")
    83  		for ii, ee := range clu.SubDetEnes {
    84  			if ii > 0 {
    85  				fmt.Fprintf(o, ", ")
    86  			}
    87  			fmt.Fprintf(o, "%+.3e", ee)
    88  		}
    89  		fmt.Fprintf(o, "\n")
    90  	}
    91  	o.WriteString(tail)
    92  
    93  	return o.String()
    94  }
    95  
    96  func (*ClusterContainer) VersionSio() uint32 {
    97  	return Version
    98  }
    99  
   100  func (clus *ClusterContainer) MarshalSio(w sio.Writer) error {
   101  	enc := sio.NewEncoder(w)
   102  	enc.Encode(&clus.Flags)
   103  	enc.Encode(&clus.Params)
   104  	enc.Encode(int32(len(clus.Clusters)))
   105  	for i := range clus.Clusters {
   106  		clu := &clus.Clusters[i]
   107  		enc.Encode(&clu.Type)
   108  		enc.Encode(&clu.Energy)
   109  		enc.Encode(&clu.EnergyErr)
   110  		enc.Encode(&clu.Pos)
   111  		enc.Encode(&clu.PosErr)
   112  		enc.Encode(&clu.Theta)
   113  		enc.Encode(&clu.Phi)
   114  		enc.Encode(&clu.DirErr)
   115  		enc.Encode(&clu.Shape)
   116  		enc.Encode(int32(len(clu.PIDs)))
   117  		for i := range clu.PIDs {
   118  			pid := &clu.PIDs[i]
   119  			enc.Encode(&pid.Likelihood)
   120  			enc.Encode(&pid.Type)
   121  			enc.Encode(&pid.PDG)
   122  			enc.Encode(&pid.AlgType)
   123  			enc.Encode(&pid.Params)
   124  		}
   125  
   126  		enc.Encode(int32(len(clu.Clusters)))
   127  		for i := range clu.Clusters {
   128  			enc.Pointer(&clu.Clusters[i])
   129  		}
   130  
   131  		if clus.Flags.Test(BitsClHits) {
   132  			enc.Encode(int32(len(clu.Hits)))
   133  			for i := range clu.Hits {
   134  				enc.Pointer(&clu.Hits[i])
   135  				enc.Encode(&clu.Weights[i])
   136  			}
   137  		}
   138  		enc.Encode(&clu.SubDetEnes)
   139  
   140  		enc.Tag(clu)
   141  
   142  	}
   143  	return enc.Err()
   144  }
   145  
   146  func (clus *ClusterContainer) UnmarshalSio(r sio.Reader) error {
   147  	const NShapeOld = 6
   148  
   149  	dec := sio.NewDecoder(r)
   150  	dec.Decode(&clus.Flags)
   151  	dec.Decode(&clus.Params)
   152  	var n int32
   153  	dec.Decode(&n)
   154  	clus.Clusters = make([]Cluster, int(n))
   155  	for i := range clus.Clusters {
   156  		clu := &clus.Clusters[i]
   157  		dec.Decode(&clu.Type)
   158  		dec.Decode(&clu.Energy)
   159  		if r.VersionSio() > 1051 {
   160  			dec.Decode(&clu.EnergyErr)
   161  		}
   162  		dec.Decode(&clu.Pos)
   163  		dec.Decode(&clu.PosErr)
   164  		dec.Decode(&clu.Theta)
   165  		dec.Decode(&clu.Phi)
   166  		dec.Decode(&clu.DirErr)
   167  
   168  		var n int32 = NShapeOld
   169  		if r.VersionSio() > 1002 {
   170  			dec.Decode(&n)
   171  		}
   172  		clu.Shape = make([]float32, int(n))
   173  		for i := range clu.Shape {
   174  			dec.Decode(&clu.Shape[i])
   175  		}
   176  
   177  		if r.VersionSio() > 1002 {
   178  			var n int32
   179  			dec.Decode(&n)
   180  			clu.PIDs = make([]ParticleID, int(n))
   181  			for i := range clu.PIDs {
   182  				pid := &clu.PIDs[i]
   183  				dec.Decode(&pid.Likelihood)
   184  				dec.Decode(&pid.Type)
   185  				dec.Decode(&pid.PDG)
   186  				dec.Decode(&pid.AlgType)
   187  				dec.Decode(&pid.Params)
   188  			}
   189  		} else {
   190  			var ptype [3]float32
   191  			dec.Decode(&ptype)
   192  		}
   193  
   194  		dec.Decode(&n)
   195  		clu.Clusters = make([]*Cluster, int(n))
   196  		for i := range clu.Clusters {
   197  			dec.Pointer(&clu.Clusters[i])
   198  		}
   199  
   200  		if clus.Flags.Test(BitsClHits) {
   201  			dec.Decode(&n)
   202  			clu.Hits = make([]*CalorimeterHit, int(n))
   203  			clu.Weights = make([]float32, int(n))
   204  
   205  			for i := range clu.Hits {
   206  				dec.Pointer(&clu.Hits[i])
   207  				dec.Decode(&clu.Weights[i])
   208  			}
   209  		}
   210  		dec.Decode(&clu.SubDetEnes)
   211  
   212  		dec.Tag(clu)
   213  	}
   214  	return dec.Err()
   215  }
   216  
   217  var (
   218  	_ sio.Versioner = (*ClusterContainer)(nil)
   219  	_ sio.Codec     = (*ClusterContainer)(nil)
   220  )