go-hep.org/x/hep@v0.38.1/fads/isolation.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 fads
     6  
     7  import (
     8  	"math"
     9  	"reflect"
    10  
    11  	"go-hep.org/x/hep/fmom"
    12  	"go-hep.org/x/hep/fwk"
    13  )
    14  
    15  type isoclassifier struct {
    16  	PtMin float64
    17  }
    18  
    19  func (iso isoclassifier) Category(track *Candidate) int {
    20  	if track.Mom.Pt() < iso.PtMin {
    21  		return -1
    22  	}
    23  	return 0
    24  }
    25  
    26  type Isolation struct {
    27  	fwk.TaskBase
    28  
    29  	candidates string
    30  	isolations string
    31  	rhos       string
    32  	output     string
    33  
    34  	deltaRMax  float64
    35  	ptRatioMax float64
    36  	ptSumMax   float64
    37  	usePtSum   bool
    38  
    39  	classifier isoclassifier
    40  }
    41  
    42  func (tsk *Isolation) Configure(ctx fwk.Context) error {
    43  	var err error
    44  
    45  	err = tsk.DeclInPort(tsk.candidates, reflect.TypeOf([]Candidate{}))
    46  	if err != nil {
    47  		return err
    48  	}
    49  
    50  	err = tsk.DeclInPort(tsk.isolations, reflect.TypeOf([]Candidate{}))
    51  	if err != nil {
    52  		return err
    53  	}
    54  
    55  	if tsk.rhos != "" {
    56  		err = tsk.DeclInPort(tsk.rhos, reflect.TypeOf([]Candidate{}))
    57  		if err != nil {
    58  			return err
    59  		}
    60  	}
    61  
    62  	err = tsk.DeclOutPort(tsk.output, reflect.TypeOf([]Candidate{}))
    63  	if err != nil {
    64  		return err
    65  	}
    66  
    67  	return err
    68  }
    69  
    70  func (tsk *Isolation) StartTask(ctx fwk.Context) error {
    71  	var err error
    72  
    73  	return err
    74  }
    75  
    76  func (tsk *Isolation) StopTask(ctx fwk.Context) error {
    77  	var err error
    78  
    79  	return err
    80  }
    81  
    82  func (tsk *Isolation) Process(ctx fwk.Context) error {
    83  	var err error
    84  
    85  	deltaRMax2 := tsk.deltaRMax * tsk.deltaRMax
    86  
    87  	store := ctx.Store()
    88  
    89  	v, err := store.Get(tsk.candidates)
    90  	if err != nil {
    91  		return err
    92  	}
    93  
    94  	candidates := v.([]Candidate)
    95  
    96  	v, err = store.Get(tsk.isolations)
    97  	if err != nil {
    98  		return err
    99  	}
   100  
   101  	isolations := v.([]Candidate)
   102  
   103  	var rhos []Candidate = nil
   104  	if tsk.rhos != "" {
   105  		v, err = store.Get(tsk.rhos)
   106  		if err != nil {
   107  			return err
   108  		}
   109  		rhos = v.([]Candidate)
   110  	}
   111  
   112  	output := make([]Candidate, 0)
   113  	defer func() {
   114  		err = store.Put(tsk.output, output)
   115  	}()
   116  
   117  	input := make([]Candidate, 0, len(isolations))
   118  	for i := range isolations {
   119  		cand := &isolations[i]
   120  		if tsk.classifier.Category(cand) < 0 {
   121  			continue
   122  		}
   123  		input = append(input, *cand)
   124  	}
   125  
   126  	if len(input) <= 0 {
   127  		return err
   128  	}
   129  
   130  	for i := range candidates {
   131  		cand := &input[i]
   132  		eta := math.Abs(cand.Mom.Eta())
   133  		sum := 0.0
   134  
   135  		for j := range input {
   136  			iso := &input[j]
   137  			if fmom.DeltaR(&cand.Mom, &iso.Mom) <= tsk.deltaRMax && !cand.Overlaps(iso) {
   138  				sum += iso.Mom.Pt()
   139  			}
   140  		}
   141  
   142  		// find rho
   143  		rho := 0.0
   144  		for j := range rhos {
   145  			obj := &rhos[j]
   146  			if eta >= obj.Edges[0] && eta < obj.Edges[1] {
   147  				rho = obj.Mom.Pt()
   148  			}
   149  		}
   150  
   151  		// correct sum for pile-up contamination
   152  		sum = sum - rho*deltaRMax2*math.Pi
   153  
   154  		ratio := sum / cand.Mom.Pt()
   155  		if (tsk.usePtSum && sum > tsk.ptSumMax) || ratio > tsk.ptRatioMax {
   156  			continue
   157  		}
   158  		output = append(output, *cand)
   159  	}
   160  	return err
   161  }
   162  
   163  func newIsolation(typ, name string, mgr fwk.App) (fwk.Component, error) {
   164  	var err error
   165  
   166  	tsk := &Isolation{
   167  		TaskBase:   fwk.NewTask(typ, name, mgr),
   168  		candidates: "InputCandidates",
   169  		isolations: "InputIsolations",
   170  		rhos:       "",
   171  		output:     "OutputIsolations",
   172  
   173  		deltaRMax:  0.5,
   174  		ptRatioMax: 0.1,
   175  		ptSumMax:   5.0,
   176  		usePtSum:   false,
   177  
   178  		classifier: isoclassifier{
   179  			PtMin: 0.5,
   180  		},
   181  	}
   182  
   183  	err = tsk.DeclProp("Candidates", &tsk.candidates)
   184  	if err != nil {
   185  		return nil, err
   186  	}
   187  
   188  	err = tsk.DeclProp("Isolations", &tsk.isolations)
   189  	if err != nil {
   190  		return nil, err
   191  	}
   192  
   193  	err = tsk.DeclProp("Rhos", &tsk.rhos)
   194  	if err != nil {
   195  		return nil, err
   196  	}
   197  
   198  	err = tsk.DeclProp("Output", &tsk.output)
   199  	if err != nil {
   200  		return nil, err
   201  	}
   202  
   203  	err = tsk.DeclProp("DeltaRMax", &tsk.deltaRMax)
   204  	if err != nil {
   205  		return nil, err
   206  	}
   207  
   208  	err = tsk.DeclProp("PtRatioMax", &tsk.ptRatioMax)
   209  	if err != nil {
   210  		return nil, err
   211  	}
   212  
   213  	err = tsk.DeclProp("PtSumMax", &tsk.ptSumMax)
   214  	if err != nil {
   215  		return nil, err
   216  	}
   217  
   218  	err = tsk.DeclProp("UsePtSum", &tsk.usePtSum)
   219  	if err != nil {
   220  		return nil, err
   221  	}
   222  
   223  	err = tsk.DeclProp("PtMin", &tsk.classifier.PtMin)
   224  	if err != nil {
   225  		return nil, err
   226  	}
   227  
   228  	return tsk, err
   229  }
   230  
   231  func init() {
   232  	fwk.Register(reflect.TypeOf(Isolation{}), newIsolation)
   233  }