go-hep.org/x/hep@v0.38.1/fads/fastjet_finder.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  	"fmt"
     9  	"math"
    10  	"reflect"
    11  	"sort"
    12  
    13  	"go-hep.org/x/hep/fastjet"
    14  	"go-hep.org/x/hep/fmom"
    15  	"go-hep.org/x/hep/fwk"
    16  )
    17  
    18  // FastJetFinder finds jets using the fastjet library
    19  type FastJetFinder struct {
    20  	fwk.TaskBase
    21  
    22  	input  string
    23  	output string
    24  	rho    string
    25  
    26  	jetDef           fastjet.JetDefinition
    27  	jetAlg           fastjet.JetAlgorithm
    28  	paramR           float64
    29  	jetPtMin         float64
    30  	coneRadius       float64
    31  	seedThreshold    float64
    32  	coneAreaFraction float64
    33  	maxIters         int
    34  	maxPairSize      int
    35  	iratch           int
    36  	adjacencyCut     int
    37  	overlapThreshold float64
    38  
    39  	// fastjet area method ---
    40  	areaDef    any
    41  	areaAlg    int
    42  	computeRho bool
    43  
    44  	// ghost based areas ---
    45  	ghostEtaMax float64
    46  	repeat      int
    47  	ghostArea   float64
    48  	gridScatter float64
    49  	ptScatter   float64
    50  	meanGhostPt float64
    51  
    52  	// voronoi areas ---
    53  	effectiveRfact float64
    54  	etaRangeMap    map[float64]float64
    55  }
    56  
    57  func (tsk *FastJetFinder) Configure(ctx fwk.Context) error {
    58  	var err error
    59  
    60  	err = tsk.DeclInPort(tsk.input, reflect.TypeOf([]Candidate{}))
    61  	if err != nil {
    62  		return err
    63  	}
    64  
    65  	err = tsk.DeclOutPort(tsk.output, reflect.TypeOf([]Candidate{}))
    66  	if err != nil {
    67  		return err
    68  	}
    69  
    70  	err = tsk.DeclOutPort(tsk.rho, reflect.TypeOf([]Candidate{}))
    71  	if err != nil {
    72  		return err
    73  	}
    74  
    75  	if tsk.jetAlg != fastjet.AntiKtAlgorithm {
    76  		return fmt.Errorf("fastjet-finder: only implemented for AntiKt")
    77  	}
    78  
    79  	if tsk.areaAlg != 0 {
    80  		return fmt.Errorf("fastjet-finder: only implemented with *NO* area-definition")
    81  	}
    82  
    83  	tsk.jetDef = fastjet.NewJetDefinition(tsk.jetAlg, tsk.paramR, fastjet.EScheme, fastjet.BestStrategy)
    84  
    85  	return err
    86  }
    87  
    88  func (tsk *FastJetFinder) StartTask(ctx fwk.Context) error {
    89  	var err error
    90  
    91  	return err
    92  }
    93  
    94  func (tsk *FastJetFinder) StopTask(ctx fwk.Context) error {
    95  	var err error
    96  
    97  	return err
    98  }
    99  
   100  func (tsk *FastJetFinder) Process(ctx fwk.Context) error {
   101  	var err error
   102  
   103  	store := ctx.Store()
   104  
   105  	v, err := store.Get(tsk.input)
   106  	if err != nil {
   107  		return err
   108  	}
   109  	input := v.([]Candidate)
   110  
   111  	output := make([]Candidate, 0)
   112  	defer func() {
   113  		err = store.Put(tsk.output, output)
   114  	}()
   115  
   116  	injets := make([]fastjet.Jet, 0, len(input))
   117  	for i := range input {
   118  		cand := &input[i]
   119  		jet := fastjet.NewJet(cand.Mom.Px(), cand.Mom.Py(), cand.Mom.Pz(), cand.Mom.E())
   120  		jet.UserInfo = i
   121  		injets = append(injets, jet)
   122  	}
   123  
   124  	// construct jets
   125  	var bldr fastjet.Builder
   126  	if tsk.areaDef != nil {
   127  		// FIXME
   128  		panic("not implemented")
   129  	} else {
   130  		bldr, err = fastjet.NewClusterSequence(injets, tsk.jetDef)
   131  		if err != nil {
   132  			return err
   133  		}
   134  	}
   135  
   136  	// compute rho and store it
   137  	if tsk.computeRho {
   138  		// FIXME
   139  		panic("not implemented")
   140  	}
   141  
   142  	outjets, err := bldr.InclusiveJets(tsk.jetPtMin)
   143  	if err != nil {
   144  		return err
   145  	}
   146  	sort.Sort(fastjet.ByPt(outjets))
   147  
   148  	detaMax := 0.0
   149  	dphiMax := 0.0
   150  	output = make([]Candidate, 0, len(outjets))
   151  	for i := range outjets {
   152  		var (
   153  			jet  = &outjets[i]
   154  			area fmom.PxPyPzE
   155  		)
   156  		if tsk.areaDef != nil {
   157  			// FIXME
   158  			panic("not implemented")
   159  			// area = jet.Area()
   160  		}
   161  
   162  		cand := Candidate{
   163  			Mom: jet.PxPyPzE,
   164  		}
   165  
   166  		time := 0.0
   167  		wtime := 0.0
   168  		csts, err := bldr.Constituents(jet)
   169  		if err != nil {
   170  			return err
   171  		}
   172  
   173  		for j := range csts {
   174  			idx := csts[j].UserInfo.(int)
   175  			cst := &input[idx]
   176  			deta := math.Abs(cand.Mom.Eta() - cst.Mom.Eta())
   177  			dphi := math.Abs(fmom.DeltaPhi(&cand.Mom, &cst.Mom))
   178  			if deta > detaMax {
   179  				detaMax = deta
   180  			}
   181  			if dphi > dphiMax {
   182  				dphiMax = dphi
   183  			}
   184  
   185  			esqrt := math.Sqrt(cst.Mom.E())
   186  			time += esqrt * cst.Pos.T()
   187  			wtime += esqrt
   188  
   189  			cand.Add(cst)
   190  		}
   191  
   192  		cand.Pos.P4.T = time / wtime
   193  		cand.Area = area
   194  		cand.DEta = detaMax
   195  		cand.DPhi = dphiMax
   196  
   197  		output = append(output, cand)
   198  	}
   199  
   200  	// fmt.Printf("%s: input=%02d outjets=%02d\n", tsk.Name(), len(input), len(output))
   201  	return err
   202  }
   203  
   204  func newFastJetFinder(typ, name string, mgr fwk.App) (fwk.Component, error) {
   205  	var err error
   206  
   207  	tsk := &FastJetFinder{
   208  		TaskBase: fwk.NewTask(typ, name, mgr),
   209  
   210  		input:  "/fads/fastjet/input",
   211  		output: "/fads/fastjet/output",
   212  		rho:    "/fads/fastjet/rho",
   213  
   214  		jetAlg:           fastjet.AntiKtAlgorithm,
   215  		paramR:           0.5,
   216  		jetPtMin:         10.0,
   217  		coneRadius:       0.5,
   218  		seedThreshold:    1.0,
   219  		coneAreaFraction: 1.0,
   220  		maxIters:         100,
   221  		maxPairSize:      2,
   222  		iratch:           1,
   223  		adjacencyCut:     2,
   224  		overlapThreshold: 0.75,
   225  
   226  		// fastjet area method ---
   227  		areaDef:    nil,
   228  		areaAlg:    0,
   229  		computeRho: false,
   230  
   231  		// ghost based areas ---
   232  		ghostEtaMax: 5.0,
   233  		repeat:      1,
   234  		ghostArea:   0.01,
   235  		gridScatter: 1.0,
   236  		ptScatter:   0.1,
   237  		meanGhostPt: 1e-100,
   238  
   239  		// voronoi areas ---
   240  		effectiveRfact: 1.0,
   241  		etaRangeMap:    make(map[float64]float64),
   242  	}
   243  
   244  	err = tsk.DeclProp("Input", &tsk.input)
   245  	if err != nil {
   246  		return nil, err
   247  	}
   248  
   249  	err = tsk.DeclProp("Rho", &tsk.rho)
   250  	if err != nil {
   251  		return nil, err
   252  	}
   253  
   254  	err = tsk.DeclProp("Output", &tsk.output)
   255  	if err != nil {
   256  		return nil, err
   257  	}
   258  
   259  	err = tsk.DeclProp("JetAlgorithm", &tsk.jetAlg)
   260  	if err != nil {
   261  		return nil, err
   262  	}
   263  
   264  	err = tsk.DeclProp("ParameterR", &tsk.paramR)
   265  	if err != nil {
   266  		return nil, err
   267  	}
   268  
   269  	err = tsk.DeclProp("JetPtMin", &tsk.jetPtMin)
   270  	if err != nil {
   271  		return nil, err
   272  	}
   273  
   274  	err = tsk.DeclProp("ConeRadius", &tsk.coneRadius)
   275  	if err != nil {
   276  		return nil, err
   277  	}
   278  
   279  	err = tsk.DeclProp("SeedThreshold", &tsk.seedThreshold)
   280  	if err != nil {
   281  		return nil, err
   282  	}
   283  
   284  	err = tsk.DeclProp("ConeAreaFraction", &tsk.coneAreaFraction)
   285  	if err != nil {
   286  		return nil, err
   287  	}
   288  
   289  	err = tsk.DeclProp("MaxIterations", &tsk.maxIters)
   290  	if err != nil {
   291  		return nil, err
   292  	}
   293  
   294  	err = tsk.DeclProp("MaxPairSize", &tsk.maxPairSize)
   295  	if err != nil {
   296  		return nil, err
   297  	}
   298  
   299  	err = tsk.DeclProp("Iratch", &tsk.iratch)
   300  	if err != nil {
   301  		return nil, err
   302  	}
   303  
   304  	err = tsk.DeclProp("AdjacencyCut", &tsk.adjacencyCut)
   305  	if err != nil {
   306  		return nil, err
   307  	}
   308  
   309  	err = tsk.DeclProp("OverlapThreshold", &tsk.overlapThreshold)
   310  	if err != nil {
   311  		return nil, err
   312  	}
   313  
   314  	err = tsk.DeclProp("AreaAlgorithm", &tsk.areaAlg)
   315  	if err != nil {
   316  		return nil, err
   317  	}
   318  
   319  	err = tsk.DeclProp("ComputeRho", &tsk.computeRho)
   320  	if err != nil {
   321  		return nil, err
   322  	}
   323  
   324  	err = tsk.DeclProp("GhostEtaMax", &tsk.ghostEtaMax)
   325  	if err != nil {
   326  		return nil, err
   327  	}
   328  
   329  	err = tsk.DeclProp("Repeat", &tsk.repeat)
   330  	if err != nil {
   331  		return nil, err
   332  	}
   333  
   334  	err = tsk.DeclProp("GhostArea", &tsk.ghostArea)
   335  	if err != nil {
   336  		return nil, err
   337  	}
   338  
   339  	err = tsk.DeclProp("GridScatter", &tsk.gridScatter)
   340  	if err != nil {
   341  		return nil, err
   342  	}
   343  
   344  	err = tsk.DeclProp("PtScatter", &tsk.ptScatter)
   345  	if err != nil {
   346  		return nil, err
   347  	}
   348  
   349  	err = tsk.DeclProp("MeanGhostPt", &tsk.meanGhostPt)
   350  	if err != nil {
   351  		return nil, err
   352  	}
   353  
   354  	err = tsk.DeclProp("EffectiveRfact", &tsk.effectiveRfact)
   355  	if err != nil {
   356  		return nil, err
   357  	}
   358  
   359  	err = tsk.DeclProp("RhoEtaRange", &tsk.etaRangeMap)
   360  	if err != nil {
   361  		return nil, err
   362  	}
   363  
   364  	return tsk, err
   365  }
   366  
   367  func init() {
   368  	fwk.Register(reflect.TypeOf(FastJetFinder{}), newFastJetFinder)
   369  }