go-hep.org/x/hep@v0.38.1/fads/cmd/fads-rivet-mc-generic/mcalg.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 main 6 7 import ( 8 "math" 9 "reflect" 10 11 "go-hep.org/x/hep/fads" 12 "go-hep.org/x/hep/fmom" 13 "go-hep.org/x/hep/fwk" 14 "go-hep.org/x/hep/hbook" 15 "go-hep.org/x/hep/hepmc" 16 "go-hep.org/x/hep/heppdt" 17 ) 18 19 // McGeneric is a simple task mimicking Rivet's MC_GENERIC analysis looking at various distributions of final state particles 20 type McGeneric struct { 21 fwk.TaskBase 22 23 mcevt string // original HepMC event 24 etamax float64 // maximum absolute eta acceptance 25 ptmin float64 // minimum pt acceptance in GeV 26 27 hsvc fwk.HistSvc // handle to the histogram service 28 hstream string // histogram output stream 29 30 hmult fwk.H1D 31 hpt fwk.H1D 32 hene fwk.H1D 33 heta fwk.H1D 34 hrap fwk.H1D 35 hphi fwk.H1D 36 37 hEtaPlus fwk.H1D 38 hEtaMinus fwk.H1D 39 hRapPlus fwk.H1D 40 hRapMinus fwk.H1D 41 42 hetaSumEt fwk.P1D 43 44 hetaPMRatio fwk.S2D 45 hrapPMRatio fwk.S2D 46 hetaChPMRatio fwk.S2D 47 hrapChPMRatio fwk.S2D 48 49 hmultCh fwk.H1D 50 hptCh fwk.H1D 51 heneCh fwk.H1D 52 hetaCh fwk.H1D 53 hrapCh fwk.H1D 54 hphiCh fwk.H1D 55 56 hEtaPlusCh fwk.H1D 57 hEtaMinusCh fwk.H1D 58 hRapPlusCh fwk.H1D 59 hRapMinusCh fwk.H1D 60 } 61 62 func (tsk *McGeneric) Configure(ctx fwk.Context) error { 63 err := tsk.DeclInPort(tsk.mcevt, reflect.TypeOf(hepmc.Event{})) 64 if err != nil { 65 return err 66 } 67 return nil 68 } 69 70 func (tsk *McGeneric) StartTask(ctx fwk.Context) error { 71 svc, err := ctx.Svc("histsvc") 72 if err != nil { 73 return err 74 } 75 76 tsk.hsvc = svc.(fwk.HistSvc) 77 78 tsk.hetaSumEt, err = tsk.hsvc.BookP1D(tsk.hstream+"/EtaSumEt", 25, 0, 5) 79 if err != nil { 80 return err 81 } 82 83 bookH1D := func(name string, nbins int, xmin, xmax float64) fwk.H1D { 84 h, e := tsk.hsvc.BookH1D(tsk.hstream+"/"+name, nbins, xmin, xmax) 85 if e != nil && err == nil { 86 err = e 87 } 88 return h 89 } 90 91 tsk.hmult = bookH1D("Mult", 100, -0.5, 199.5) 92 tsk.hpt = bookH1D("Pt", 300, 0, 30) 93 tsk.hene = bookH1D("E", 100, 0, 200) 94 tsk.heta = bookH1D("Eta", 50, -5, 5) 95 tsk.hrap = bookH1D("Rapidity", 50, -5, 5) 96 tsk.hphi = bookH1D("Phi", 50, 0, 2*math.Pi) 97 98 tsk.hmultCh = bookH1D("MultCh ", 100, -0.5, 199.5) 99 tsk.hptCh = bookH1D("PtCh ", 300, 0, 30) 100 tsk.heneCh = bookH1D("ECh ", 100, 0, 200) 101 tsk.hetaCh = bookH1D("EtaCh ", 50, -5, 5) 102 tsk.hrapCh = bookH1D("RapidityCh ", 50, -5, 5) 103 tsk.hphiCh = bookH1D("PhiCh ", 50, 0, 2*math.Pi) 104 105 // temp H1D 106 bookH1D = func(name string, nbins int, xmin, xmax float64) fwk.H1D { 107 h, e := tsk.hsvc.BookH1D("/"+name, nbins, xmin, xmax) 108 if e != nil && err == nil { 109 err = e 110 } 111 return h 112 } 113 114 tsk.hEtaPlus = bookH1D("EtaPlus", 25, 0, 5) 115 tsk.hEtaMinus = bookH1D("EtaMinus", 25, 0, 5) 116 tsk.hRapPlus = bookH1D("RapPlus", 25, 0, 5) 117 tsk.hRapMinus = bookH1D("RapMinus", 25, 0, 5) 118 119 tsk.hEtaPlusCh = bookH1D("EtaPlusCh", 25, 0, 5) 120 tsk.hEtaMinusCh = bookH1D("EtaMinusCh", 25, 0, 5) 121 tsk.hRapPlusCh = bookH1D("RapPlusCh", 25, 0, 5) 122 tsk.hRapMinusCh = bookH1D("RapMinusCh", 25, 0, 5) 123 124 bookS2D := func(name string) fwk.S2D { 125 s, e := tsk.hsvc.BookS2D(tsk.hstream + "/" + name) 126 if e != nil && err == nil { 127 err = e 128 } 129 return s 130 } 131 132 tsk.hetaPMRatio = bookS2D("EtaPMRatio") 133 tsk.hrapPMRatio = bookS2D("RapidityPMRatio") 134 tsk.hetaChPMRatio = bookS2D("EtaChPMRatio") 135 tsk.hrapChPMRatio = bookS2D("RapidityChPMRatio") 136 137 return nil 138 } 139 140 func (tsk *McGeneric) StopTask(ctx fwk.Context) error { 141 for _, h := range []*hbook.H1D{ 142 tsk.hmult.Hist, tsk.heta.Hist, tsk.hrap.Hist, tsk.hpt.Hist, tsk.hene.Hist, tsk.hphi.Hist, 143 tsk.hmultCh.Hist, tsk.hetaCh.Hist, tsk.hrapCh.Hist, tsk.hptCh.Hist, tsk.heneCh.Hist, tsk.hphiCh.Hist, 144 } { 145 f := 1 / h.Integral() 146 h.Scale(f) 147 h.Annotation()["ScaledBy"] = f 148 } 149 150 for _, v := range []struct { 151 num *hbook.H1D 152 den *hbook.H1D 153 res *hbook.S2D 154 }{ 155 {tsk.hEtaPlus.Hist, tsk.hEtaMinus.Hist, tsk.hetaPMRatio.Scatter}, 156 {tsk.hRapPlus.Hist, tsk.hRapMinus.Hist, tsk.hrapPMRatio.Scatter}, 157 {tsk.hEtaPlusCh.Hist, tsk.hEtaMinusCh.Hist, tsk.hetaChPMRatio.Scatter}, 158 {tsk.hRapPlusCh.Hist, tsk.hRapMinusCh.Hist, tsk.hrapChPMRatio.Scatter}, 159 } { 160 res, err := hbook.DivideH1D(v.num, v.den) 161 if err != nil { 162 return err 163 } 164 v.res.Fill(res.Points()...) 165 } 166 return nil 167 } 168 169 func (tsk *McGeneric) Process(ctx fwk.Context) error { 170 var ( 171 store = ctx.Store() 172 msg = ctx.Msg() 173 ) 174 175 v, err := store.Get(tsk.mcevt) 176 if err != nil { 177 return err 178 } 179 evt := v.(hepmc.Event) 180 weight := 1.0 181 if len(evt.Weights.Slice) >= 1 { 182 weight = evt.Weights.Slice[0] 183 } 184 185 msg.Debugf( 186 "event number: %d, #parts=%d #vtx=%d weight=%v\n", 187 evt.EventNumber, 188 len(evt.Particles), len(evt.Vertices), weight, 189 ) 190 191 nfsparts := 0 192 ncfsparts := 0 193 for _, p := range evt.Particles { 194 pdg := heppdt.ParticleByID(heppdt.PID(p.PdgID)) 195 if pdg == nil { 196 continue 197 } 198 199 mc := fads.Candidate{ 200 Pid: int32(p.PdgID), 201 Status: int32(p.Status), 202 M2: 1, 203 D2: 1, 204 CandCharge: int32(pdg.Charge), 205 CandMass: pdg.Mass, 206 Mom: fmom.PxPyPzE(p.Momentum), 207 } 208 if vtx := p.ProdVertex; vtx != nil { 209 mc.M1 = 1 210 mc.Pos = fmom.PxPyPzE(vtx.Position) 211 } 212 // pdgcode := p.PdgID 213 // if pdgcode < 0 { 214 // pdgcode = -pdgcode 215 // } 216 217 if p.Status != 1 { 218 continue 219 } 220 221 eta := mc.Mom.Eta() 222 abseta := math.Abs(eta) 223 if abseta >= tsk.etamax { 224 continue 225 } 226 227 if mc.Mom.Pt() <= tsk.ptmin { 228 continue 229 } 230 231 width := pdg.Resonance.Width.Value 232 if width > 1e-10 { 233 continue 234 } 235 rap := mc.Mom.Rapidity() 236 absrap := math.Abs(rap) 237 238 pt := mc.Mom.Pt() 239 ene := mc.Mom.E() 240 // hep/fmom.P4 returns phi in [-pi,pi) range. 241 // convert to [0,2pi) to match Rivet convention. 242 phi := angle0to2Pi(mc.Mom.Phi()) 243 244 tsk.hsvc.FillP1D(tsk.hetaSumEt.ID, abseta, mc.Mom.Et(), weight) 245 nfsparts++ 246 tsk.hsvc.FillH1D(tsk.heta.ID, eta, weight) 247 tsk.hsvc.FillH1D(tsk.hrap.ID, rap, weight) 248 tsk.hsvc.FillH1D(tsk.hpt.ID, pt, weight) 249 tsk.hsvc.FillH1D(tsk.hene.ID, ene, weight) 250 tsk.hsvc.FillH1D(tsk.hphi.ID, phi, weight) 251 252 switch eta > 0 { 253 case true: 254 tsk.hsvc.FillH1D(tsk.hEtaPlus.ID, abseta, weight) 255 case false: 256 tsk.hsvc.FillH1D(tsk.hEtaMinus.ID, abseta, weight) 257 } 258 259 switch rap > 0 { 260 case true: 261 tsk.hsvc.FillH1D(tsk.hRapPlus.ID, absrap, weight) 262 case false: 263 tsk.hsvc.FillH1D(tsk.hRapMinus.ID, absrap, weight) 264 } 265 266 if mc.CandCharge == 0 { 267 continue 268 } 269 270 ncfsparts++ 271 tsk.hsvc.FillH1D(tsk.hetaCh.ID, eta, weight) 272 tsk.hsvc.FillH1D(tsk.hrapCh.ID, rap, weight) 273 tsk.hsvc.FillH1D(tsk.hptCh.ID, pt, weight) 274 tsk.hsvc.FillH1D(tsk.heneCh.ID, ene, weight) 275 tsk.hsvc.FillH1D(tsk.hphiCh.ID, phi, weight) 276 277 switch eta > 0 { 278 case true: 279 tsk.hsvc.FillH1D(tsk.hEtaPlusCh.ID, abseta, weight) 280 case false: 281 tsk.hsvc.FillH1D(tsk.hEtaMinusCh.ID, abseta, weight) 282 } 283 284 switch rap > 0 { 285 case true: 286 tsk.hsvc.FillH1D(tsk.hRapPlusCh.ID, absrap, weight) 287 case false: 288 tsk.hsvc.FillH1D(tsk.hRapMinusCh.ID, absrap, weight) 289 } 290 291 } 292 293 msg.Debugf("total multiplicity = %d\n", nfsparts) 294 tsk.hsvc.FillH1D(tsk.hmult.ID, float64(nfsparts), weight) 295 296 tsk.hsvc.FillH1D(tsk.hmultCh.ID, float64(ncfsparts), weight) 297 msg.Debugf("total charged multiplicity = %d\n", ncfsparts) 298 return nil 299 } 300 301 func newMcGeneric(typ, name string, mgr fwk.App) (fwk.Component, error) { 302 tsk := &McGeneric{ 303 TaskBase: fwk.NewTask(typ, name, mgr), 304 mcevt: "/fads/McEvent", 305 etamax: 5, 306 ptmin: 0.5, // GeV 307 hstream: "/MC_GENERIC", 308 } 309 310 err := tsk.DeclProp("Input", &tsk.mcevt) 311 if err != nil { 312 return nil, err 313 } 314 315 err = tsk.DeclProp("EtaMax", &tsk.etamax) 316 if err != nil { 317 return nil, err 318 } 319 320 err = tsk.DeclProp("PtMin", &tsk.ptmin) 321 if err != nil { 322 return nil, err 323 } 324 325 err = tsk.DeclProp("Stream", &tsk.hstream) 326 if err != nil { 327 return nil, err 328 } 329 330 return tsk, nil 331 } 332 333 func init() { 334 fwk.Register(reflect.TypeOf(McGeneric{}), newMcGeneric) 335 } 336 337 const twoPi = 2 * math.Pi 338 339 func angle0to2Pi(v float64) float64 { 340 v = math.Mod(v, twoPi) 341 if v == 0 { 342 return 0 343 } 344 if v < 0 { 345 v += twoPi 346 } 347 if v == twoPi { 348 v = 0 349 } 350 return v 351 }