= Cuts = Most of this information is scattered around the manual, so if a description is too brief here, you might find more information there. This page is intended to gather everything needed to write cuts without having to study the manual for a day. == Definition == One of the harder parts of using Whizard is the setup of cuts. The general definition of the cuts object is {{{ #!bash cuts = log_class log_expr [unary_or_binary_particle_list_arg] }}} The `log_class` can be `all`, `any` or `no` and the `log_expr` something like `E <= 100 GeV` or `PDG == 15`. Note that you can combine multiple `log_expr`s as well as cut expressions with `and` or `or`. == Basic example == Let's start off with `"e+", "e-" => "e+", "e-"`. The only possible divergences are collinearities with the beam due to t-channel diagrams. So we can just avoid them with {{{ #!bash cuts = all Theta > 10 degree [incoming "e+":"e-", "e+":"e-"] }}} Here, we have used the `incoming` constructor that only selects incoming particles. You might wonder why this doesn't give always false, for the combination of incoming beam 1 with incoming beam 1, e.g.. The square bracket with two entries actually evaluates to the list of '''all possible pairs''' which do ''not overlap'', so this case is excluded. The concept of overlapping will be used heavily later on. Note that the expression above is the same as {{{ #!bash cuts = all Theta > 10 degree [incoming "e+":"e-", "e-"] and all Theta > 10 degree [incoming "e+":"e-", "e+"] }}} telling us that concatenations of particle species with `:` are expanded. This syntax should be enough to get basic examples working but for more complicated cases, we first have to understand ''subevents''. == What the hell are subevents? == Subevents are sets of particles that are extracted from an event. A subevent can be created by just putting square brackets around a particle species or alias {{{ #!bash ["e+"] [u:d:s] [charged] }}} These subevents evaluate to the set of all positrons, light quarks and charged particles in an event, respectively. In our above example, we can also construct subevents explicitely and have the same effect {{{ #!bash cuts = all Theta > 10 degree [[incoming "e+":"e-"], ["e+":"e-"]] }}} Especially to keep more complicated examples readable, it's quite useful to declare subevent variables. We can do this with the `let` construct {{{ #!bash cuts = let subevt @leptons = ["e+":"e-"] in let subevt @inc = [incoming "e+":"e-"] in all Theta > 10 degree [@inc, @leptons] }}} The `@` prefix is hereby mandatory. Now, we are only lacking more powerful commands to build subevents. == Building subevents == collect and count:: {{{ #!bash collect [particles] }}} `collect` collects all the (composite) particles in the subevent or alias `particles` into a single four-momentum. You can think of this as a contraction of the set you put in. We can check this by adding to our cut expression {{{ #!bash and count [collect [@inc]] == 2 }}} and we will get a zero cross section while demanding `== 1` results in the same result as before. Both `count` and `collect` can also take a condition {{{ #!bash count if logical_expr [particles] collect if logical_expr [particles] }}} The result for these `if`s is always the same as applying the `select` filter beforehand, see below. combine:: {{{ #!bash combine [particles1, particles2] [particles1 + particles2] }}} This allows us to make a new subevent of composite particles. The composites are generated by combining all particles from subevent `particles1` with all particles from subevent `particles2` in '''all possible combinations''' while overlapping combinations are excluded. In particular, if a composite particle in the first argument has a constituent in common with a composite particle in the second argument, the combination is dropped. So `combine [incoming lepton, lepton]` constructs all mutual pairings of an incoming lepton with an outgoing lepton, in case `lepton` is an appropriate alias. Thinking of subevents and the functions that act on them as streams, `combine` fans out the two given subevents opposed to the contraction of `collect`. Note that if `particles1` and `particles2` are one-entry subevents, `combine` and `collect` actually give the same result, which can be confusing in the beginning, but for larger subevents, the result is obviously different. `combine` also has an shorthand operator `+` that can be used multiple times, e.g. `[u + d + s]`. Finally, this can also take a `condition` {{{ #!bash combine if condition [particles1, particles2] }}} cluster:: {{{ #!bash cluster [particles] cluster if condition [particles] }}} `cluster` clusters the given subevent or alias `particles` to a new subevent using the external `FastJet` library. Variables that influence it are `jet_algorithm`, `jet_r`, `jet_p` and `jet_ycut`. select:: {{{ #!bash select if condition [particles] select if condition [particles, ref_particles] }}} `select` can be used as a simple filter mechanism. The second argument is only relevant for binary observables. Select particles if the condition is satisfied for ''all'' reference particles. extract:: {{{ #!bash extract [particles] extract index n [particles] }}} Return a one-entry subevent with either the first particle or the `n`th particle. This makes only sense on `sort`ed subevents. sort:: {{{ #!bash sort by observable [particles] sort by observable [particles, ref_particle] }}} `sort` surprisingly sorts the subevent by ''increasing'' value of the observable. So if you want the highest values first, add a minus sign in front of your `observable`. join:: {{{ #!bash join [particles, new_particles] }}} Append the particles of `new_particles` to `particles`, i.e. join the two sets. No overlapping entries will be produced. `join` has also a shorthand operator `&` with the same syntax as `+`. Of course, you can chain all of these functions. So to get, e.g. a four jet cross section, you can write {{{ #!bash cuts = count [cluster if E > 0 GeV [j]] > 3 }}} == Things to cut on == For convenience, we put here a table of observables that can also be found in the manual. All observables are either ''unary'', i.e. take one argument, or ''binary'', two arguments. ||= Observables =|| ||`M2`|| unary: invariant mass squared of the (composite) particle || || || binary: invariant mass squared of the sum of the two momenta || ||`M` || Signed square root of `M2`: positive if `M2` > 0, negative if `M2` < 0 || ||`E` || unary: energy of the particle || || || binary: energy of the sum of the two momenta || ||`Px`, `Py`, `Pz` || like `E` but returns spatial components || ||`P` || like `E` but returns absolut value of spatial vector || ||`Pt`, `Pl` || like `E` but returns transversal and longitudinal momentum || ||`Theta`|| unary: absolute polar angle in lab frame || || || binary: angular distance of two particles in lab frame || ||`Theta_star`|| binary: angular distance of two particles in rest frame of momentum sum || ||`Phi`|| unary: absolute azimuthal angle in lab frame || || || binary: Azimuthal distance of two particles in lab frame || ||`Rap`, `Eta` || unary: Rapidity / Pseudorapidity || || || binary: Rapidity / Pseudorapidity difference || ||`Dist`|| binary: `sqrt(DeltaEta^2 + DeltaPhi^2)` || ||`kT`|| binary: `2 * min(E_i^2,E_j^2)*(1-cos(Theta_{ij})` || ||`PDG`|| unary: PDG of particle (0 for composite particles) || You will note that some binary versions are only convenience variants that avoid to `collect` or `combine` momenta beforehand. So there are even more possiblities to say the same thing, which can be confusing in the beginning. == Related topics == The pleasant thing about `cuts` is that once you get the hang of it, you can easily create histograms with `analysis` or set `scale`s as it uses a similar syntax. For this, you need to chain in an `eval` {{{ #!bash eval expr [particles] eval expr [particles1, particles2] }}} So the syntax is similar to the `cuts` but this time `expr` is usually a real/floating expression instead of a logical/boolean one. With this you can, e.g., build the following histograms {{{ #!bash analysis = record pt_distribution (eval Pt [photon]) and record mval (eval M [lepton, lepton]) }}} Analogously, you can set the `scale` for `alphas` to the hardest `pt` with {{{ #!bash scale = eval Pt [sort by -Pt [colored]] }}} Finally, there is also the possibility to apply an overall `selection` before events are analyzed or written to file. This does not affect the `cuts` that are used before matrix elements are even evaluated but applies to the complete event, i.e. potentially with parton showers and hadronization: {{{ #!bash selection = all Hel == 0 ["W+":"W-"] }}}