Index: trunk/share/doc/manual.tex =================================================================== --- trunk/share/doc/manual.tex (revision 8413) +++ trunk/share/doc/manual.tex (revision 8414) @@ -1,17553 +1,17572 @@ \documentclass[12pt]{book} % \usepackage{feynmp} \usepackage{microtype} \usepackage{graphics,graphicx} \usepackage{color} \usepackage{amsmath,amssymb} \usepackage[colorlinks,bookmarks,bookmarksnumbered=true]{hyperref} \usepackage{thophys} \usepackage{fancyvrb} \usepackage{makeidx} \usepackage{units} \usepackage{ifpdf} %HEVEA\pdftrue \makeindex \usepackage{url} \usepackage[latin1]{inputenc} %HEVEA\@def@charset{UTF-8} %BEGIN LATEX \usepackage{supertabular,fancyvrb} \usepackage{hevea} %END LATEX \renewcommand{\topfraction}{0.9} \renewcommand{\bottomfraction}{0.8} \renewcommand{\textfraction}{0.1} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Macro section %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newcommand{\email}[2]{\thanks{\ahref{#1@{}#2}{#1@{}#2}}} \newcommand{\hepforgepage}{\url{https://whizard.hepforge.org}} \newcommand{\whizardwiki}{\url{https://whizard.hepforge.org/trac/wiki}} \tocnumber %BEGIN LATEX \DeclareMathOperator{\diag}{diag} %END LATEX %BEGIN LATEX \makeatletter \newif\if@preliminary \@preliminaryfalse \def\preliminary{\@preliminarytrue} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Changes referring to article.cls % %%% Title page \def\preprintno#1{\def\@preprintno{#1}} \def\address#1{\def\@address{#1}} \def\email#1#2{\thanks{\tt #1@{}#2}} \def\abstract#1{\def\@abstract{#1}} \newcommand\abstractname{ABSTRACT} \newlength\preprintnoskip \setlength\preprintnoskip{\textwidth\@plus -1cm} \newlength\abstractwidth \setlength\abstractwidth{\textwidth\@plus -3cm} % \@titlepagetrue \renewcommand\maketitle{\begin{titlepage}% \let\footnotesize\small \hfill\parbox{\preprintnoskip}{% \begin{flushright}\@preprintno\end{flushright}}\hspace*{1cm} \vskip 60\p@ \begin{center}% {\Large\bf\boldmath \@title \par}\vskip 1cm% {\sc\@author \par}\vskip 3mm% {\@address \par}% \if@preliminary \vskip 2cm {\large\sf PRELIMINARY DRAFT \par \@date}% \fi \end{center}\par \@thanks \vfill \begin{center}% \parbox{\abstractwidth}{\centerline{\abstractname}% \vskip 3mm% \@abstract} \end{center} \end{titlepage}% \setcounter{footnote}{0}% \let\thanks\relax\let\maketitle\relax \gdef\@thanks{}\gdef\@author{}\gdef\@address{}% \gdef\@title{}\gdef\@abstract{}\gdef\@preprintno{} }% % %%% New settings of dimensions \topmargin -1.5cm \textheight 22cm \textwidth 17cm \oddsidemargin 0cm \evensidemargin 0cm % %%% Original Latex definition of citex, except for the removal of %%% 'space' following a ','. \citerange replaces the ',' by '--'. \def\@citex[#1]#2{\if@filesw\immediate\write\@auxout{\string\citation{#2}}\fi \def\@citea{}\@cite{\@for\@citeb:=#2\do {\@citea\def\@citea{,\penalty\@m}\@ifundefined {b@\@citeb}{{\bf ?}\@warning {Citation `\@citeb' on page \thepage \space undefined}}% \hbox{\csname b@\@citeb\endcsname}}}{#1}} \def\citerange{\@ifnextchar [{\@tempswatrue\@citexr}{\@tempswafalse\@citexr[]}} \def\@citexr[#1]#2{\if@filesw\immediate\write\@auxout{\string\citation{#2}}\fi \def\@citea{}\@cite{\@for\@citeb:=#2\do {\@citea\def\@citea{--\penalty\@m}\@ifundefined {b@\@citeb}{{\bf ?}\@warning {Citation `\@citeb' on page \thepage \space undefined}}% \hbox{\csname b@\@citeb\endcsname}}}{#1}} % %%% Captions set in italics \long\def\@makecaption#1#2{% \vskip\abovecaptionskip \sbox\@tempboxa{#1: \emph{#2}}% \ifdim \wd\@tempboxa >\hsize #1: \emph{#2}\par \else \hbox to\hsize{\hfil\box\@tempboxa\hfil}% \fi \vskip\belowcaptionskip} % %%% Other useful macros \def\fmslash{\@ifnextchar[{\fmsl@sh}{\fmsl@sh[0mu]}} \def\fmsl@sh[#1]#2{% \mathchoice {\@fmsl@sh\displaystyle{#1}{#2}}% {\@fmsl@sh\textstyle{#1}{#2}}% {\@fmsl@sh\scriptstyle{#1}{#2}}% {\@fmsl@sh\scriptscriptstyle{#1}{#2}}} \def\@fmsl@sh#1#2#3{\m@th\ooalign{$\hfil#1\mkern#2/\hfil$\crcr$#1#3$}} \makeatother % Labelling command for Feynman graphs generated by package FEYNMF %\def\fmfL(#1,#2,#3)#4{\put(#1,#2){\makebox(0,0)[#3]{#4}}} %END LATEX %%%% Environment for showing user input and program response \newenvironment{interaction}% {\begingroup\small \Verbatim}% {\endVerbatim \endgroup\noindent} %BEGIN LATEX %%%% Environment for typesetting listings verbatim \newenvironment{code}% {\begingroup\footnotesize \quote \Verbatim}% {\endVerbatim \endquote \endgroup\noindent} %%%% Boxed environment for typesetting listings verbatim \newenvironment{Code}% {\begingroup\footnotesize \quote \Verbatim[frame=single]}% {\endVerbatim \endquote \endgroup\noindent} %%% Environment for displaying syntax \newenvironment{syntax}% {\begin{quote} \begin{flushleft}\tt}% {\end{flushleft} \end{quote}} \newcommand{\var}[1]{$\langle$\textit{#1}$\rangle$} %END LATEX %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Macros specific for this paper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newcommand{\ttt}[1]{\texttt{#1}} \newcommand{\whizard}{\ttt{WHIZARD}} \newcommand{\oMega}{\ttt{O'Mega}} \newcommand{\vamp}{\ttt{VAMP}} \newcommand{\vamptwo}{\ttt{VAMP2}} \newcommand{\vegas}{\ttt{VEGAS}} \newcommand{\madgraph}{\ttt{MadGraph}} \newcommand{\CalcHep}{\ttt{CalcHep}} \newcommand{\helas}{\ttt{HELAS}} \newcommand{\herwig}{\ttt{HERWIG}} \newcommand{\isajet}{\ttt{ISAJET}} \newcommand{\pythia}{\ttt{PYTHIA}} \newcommand{\pythiasix}{\ttt{PYTHIA6}} \newcommand{\pythiaeight}{\ttt{PYTHIA8}} \newcommand{\jetset}{\ttt{JETSET}} \newcommand{\comphep}{\ttt{CompHEP}} \newcommand{\circe}{\ttt{CIRCE}} \newcommand{\circeone}{\ttt{CIRCE1}} \newcommand{\circetwo}{\ttt{CIRCE2}} \newcommand{\gamelan}{\textsf{gamelan}} \newcommand{\stdhep}{\ttt{STDHEP}} \newcommand{\lcio}{\ttt{LCIO}} \newcommand{\pdflib}{\ttt{PDFLIB}} \newcommand{\lhapdf}{\ttt{LHAPDF}} \newcommand{\hepmc}{\ttt{HepMC}} \newcommand{\hepmcthree}{\ttt{HepMC3}} \newcommand{\fastjet}{\ttt{FastJet}} \newcommand{\hoppet}{\ttt{HOPPET}} \newcommand{\metapost}{\ttt{MetaPost}} \newcommand{\sarah}{\ttt{SARAH}} \newcommand{\spheno}{\ttt{SPheno}} \newcommand{\Mathematica}{\ttt{Mathematica}} \newcommand{\FeynRules}{\ttt{FeynRules}} \newcommand{\UFO}{\ttt{UFO}} \newcommand{\gosam}{\ttt{Gosam}} \newcommand{\openloops}{\ttt{OpenLoops}} \newcommand{\recola}{\ttt{Recola}} \newcommand{\collier}{\ttt{Collier}} \newcommand{\powheg}{\ttt{POWHEG}} \newcommand{\delphes}{\ttt{Delphes}} \newcommand{\geant}{\ttt{Geant}} \newcommand{\ROOT}{\ttt{ROOT}} \newcommand{\rivet}{\ttt{Rivet}} %%%%% \newcommand{\sindarin}{\ttt{SINDARIN}} \newcommand{\cpp}{\ttt{C++}} \newcommand{\fortran}{\ttt{Fortran}} \newcommand{\fortranSeventySeven}{\ttt{FORTRAN77}} \newcommand{\fortranNinetyFive}{\ttt{Fortran95}} \newcommand{\fortranOThree}{\ttt{Fortran2003}} \newcommand{\ocaml}{\ttt{OCaml}} \newcommand{\python}{\ttt{Python}} \newenvironment{commands}{\begin{quote}\tt}{\end{quote}} \newcommand{\eemm}{$e^+e^- \to \mu^+\mu^-$} %\def\~{$\sim$} \newcommand{\sgn}{\mathop{\rm sgn}\nolimits} \newcommand{\GeV}{\textrm{GeV}} \newcommand{\fb}{\textrm{fb}} \newcommand{\ab}{\textrm{ab}} \newenvironment{parameters}{% \begin{center} \begin{tabular}{lccp{65mm}} \hline Parameter & Value & Default & Description \\ \hline }{% \hline \end{tabular} \end{center} } \newenvironment{options}{% \begin{center} \begin{tabular}{llcp{80mm}} \hline Option & Long version & Value & Description \\ \hline }{% \hline \end{tabular} \end{center} } %BEGIN LATEX \renewenvironment{options}{% \begin{center} \tablehead{\hline Option & Long version & Value & Description \\ \hline } \begin{supertabular}{llcp{80mm}} }{% \hline \end{supertabular} \end{center} } %END LATEX %BEGIN LATEX \renewenvironment{parameters}{% \begin{center} \tablehead{\hline Parameter & Value & Default & Description \\ \hline } \begin{supertabular}{lccp{65mm}} }{% \hline \end{supertabular} \end{center} } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %END LATEX \newcommand{\thisversion}{2.8.3} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{document} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %BEGIN LATEX \preprintno{} %%%\preprintno{arXiv:0708.4233 (also based on LC-TOOL-2001-039 (revised))} %END LATEX \title{% %HEVEA WHIZARD 2.8 \\ %BEGIN LATEX \ttt{\huge WHIZARD 2.8} \\[\baselineskip] %END LATEX A generic \\ Monte-Carlo integration and event generation package \\ for multi-particle processes\\[\baselineskip] MANUAL \footnote{% This work is supported by Helmholtz-Alliance ``Physics at the Terascale''. In former stages this work has also been supported by the Helmholtz-Gemeinschaft VH--NG--005 \\ E-mail: \ttt{whizard@desy.de} } \\[\baselineskip] } % \def\authormail{\ttt{kilian@physik.uni-siegen.de}, % \ttt{ohl@physik.uni-wuerzburg.de}, % \ttt{juergen.reuter@desy.de}, \ttt{cnspeckn@googlemail.com}} \author{% Wolfgang Kilian,% Thorsten Ohl,% J\"urgen Reuter,% with contributions from Fabian Bach, % Simon Bra\ss, Bijan Chokouf\'{e} Nejad, % Christian Fleper, % Vincent Rothe, % Sebastian Schmidt, % Marco Sekulla, % Christian Speckner, % So Young Shim, % Florian Staub, % Christian Weiss} %BEGIN LATEX \address{% Universit\"at Siegen, Emmy-Noether-Campus, Walter-Flex-Str. 3, D--57068 Siegen, Germany \\ Universit\"at W\"urzburg, Emil-Hilb-Weg 22, D--97074 W\"urzburg, Germany \\ Deutsches Elektronen-Synchrotron DESY, Notkestr. 85, D--22603 Hamburg, Germany \\ %% \authormail \vspace{1cm} \begin{center} \includegraphics[width=4cm]{Whizard-Logo} \end{center} \mbox{} \\ \vspace{2cm} \mbox{} when using \whizard\ please cite: \\ W. Kilian, T. Ohl, J. Reuter, \\ {\em WHIZARD: Simulating Multi-Particle Processes at LHC and ILC}, \\ Eur.Phys.J.{\bf C71} (2011) 1742, arXiv: 0708.4233 [hep-ph]; \\ M. Moretti, T. Ohl, J. Reuter, \\ {\em O'Mega: An Optimizing Matrix Element Generator}, \\ arXiv: hep-ph/0102195 } %END LATEX %BEGIN LATEX \abstract{% \whizard\ is a program system designed for the efficient calculation of multi-particle scattering cross sections and simulated event samples. The generated events can be written to file in various formats (including HepMC, LHEF, STDHEP, LCIO, and ASCII) or analyzed directly on the parton or hadron level using a built-in \LaTeX-compatible graphics package. \\[\baselineskip] Complete tree-level matrix elements are generated automatically for arbitrary partonic multi-particle processes by calling the built-in matrix-element generator \oMega. Beyond hard matrix elements, \whizard\ can generate (cascade) decays with complete spin correlations. Various models beyond the SM are implemented, in particular, the MSSM is supported with an interface to the SUSY Les Houches Accord input format. Matrix elements obtained by alternative methods (e.g., including loop corrections) may be interfaced as well. \\[\baselineskip] The program uses an adaptive multi-channel method for phase space integration, which allows to calculate numerically stable signal and background cross sections and generate unweighted event samples with reasonable efficiency for processes with up to eight and more final-state particles. Polarization is treated exactly for both the initial and final states. Quark or lepton flavors can be summed over automatically where needed. \\[\baselineskip] For hadron collider physics, we ship the package with the most recent PDF sets from the MSTW/MMHT and CTEQ/CT10/CJ12/CJ15/CT14 collaborations. Furthermore, an interface to the \lhapdf\ library is provided. \\[\baselineskip] For Linear Collider physics, beamstrahlung (\circeone, \circetwo), Compton and ISR spectra are included for electrons and photons, including the most recent ILC and CLIC collider designs. Alternatively, beam-crossing events can be read directly from file. \\[\baselineskip] For parton showering and matching/merging with hard matrix elements , fragmenting and hadronizing the final state, a first version of two different parton shower algorithms are included in the \whizard\ package. This also includes infrastructure for the MLM matching and merging algorithm. For hadronization and hadronic decays, \pythia\ and \herwig\ interfaces are provided which follow the Les Houches Accord. In addition, the last and final version of (\fortran) \pythia\ is included in the package. \\[\baselineskip] The \whizard\ distribution is available at %%% \begin{center} %%% \ttt{http://whizard.event-generator.org} %%% \end{center} %%% or at \begin{center} \url{https://whizard.hepforge.org} \end{center} where also the \ttt{svn} repository is located. } %END LATEX % \maketitle %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Text %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %\begin{fmffile} \tableofcontents \newpage \chapter{Introduction} \section{Disclaimer} \emph{This is a preliminary version of the WHIZARD manual. Many parts are still missing or incomplete, and some parts will be rewritten and improved soon. To find updated versions of the manual, visit the \whizard\ website} \begin{center} \hepforgepage \end{center} \emph{or consult the current version in the \ttt{svn} repository on \hepforgepage\ directly. Note, that the most recent version of the manual might contain information about features of the current \ttt{svn} version, which are not contained in the last official release version!} \emph{For information that is not (yet) written in the manual, please consult the examples in the \whizard\ distribution. You will find these in the subdirectory \ttt{share/examples} of the main directory where \whizard\ is installed. More information about the examples can be found on the \whizard\ Wiki page} \begin{center} \whizardwiki . \end{center} %%%%% \clearpage \section{Overview} \whizard\ is a multi-purpose event generator that covers all parts of event generation (unweighted and weighted), either through intrinsic components or interfaces to external packages. Realistic collider environments are covered through sophisticated descriptions for beam structures at hadron colliders, lepton colliders, lepton-hadron colliders, both circular and linear machines. Other options include scattering processes e.g. for dark matter annihilation or particle decays. \whizard\ contains its in-house generator for (tree-level) high-multiplicity matrix elements, \oMega\, that supports the whole Standard Model (SM) of particle physics and basically all possibile extensions of it. QCD parton shower describe high-multiplicity partonic jet events that can be matched with matrix elements. At the moment, only hadron collider parton distribution functions (PDFs) and hadronization are handled by packages not written by the main authors. This manual is organized mainly along the lines of the way how to run \whizard: this is done through a command language, \sindarin\ (Scripting INtegration, Data Analysis, Results display and INterfaces.) Though this seems a complication at first glance, the user is rewarded with a large possibility, flexibility and versatility on how to steer \whizard. After some general remarks in the follow-up sections, in Chap.~\ref{chap:installation} we describe how to get the program, the package structure, the prerequisites, possible external extensions of the program and the basics of the installation (both as superuser and locally). Also, a first technical overview how to work with \whizard\ on single computer, batch clusters and farms are given. Furthermore, some rare uncommon possible build problems are discussed, and a tour through options for debugging, testing and validation is being made. A first dive into the running of the program is made in Chap.~\ref{chap:start}. This is following by an extensive, but rather technical introduction into the steering language \sindarin\ in Chap.~\ref{chap:sindarinintro}. Here, the basic elements of the language like commands, statements, control structures, expressions and variables as well as the form of warnings and error messages are explained in detail. Chap.~\ref{chap:sindarin} contains the application of the \sindarin\ command language to the main tasks in running \whizard\ in a physics framework: the defintion of particles, subevents, cuts, and event selections. The specification of a particular physics models is \begin{figure}[t] \centering \includegraphics[width=0.9\textwidth]{whizstruct} \caption{General structure of the \whizard\ package.} \end{figure} discussed, while the next sections are devoted to the setup and compilation of code for particular processes, the specification of beams, beam structure and polarization. The next step is the integration, controlling the integration, phase space, generator cuts, scales and weights, proceeding further to event generation and decays. At the end of this chapter, \whizard's internal data analysis methods and graphical visualization options are documented. The following chapters are dedicated to the physics implemented in \whizard: methods for hard matrix interactions in Chap.~\ref{chap:hardint}. Then, in Chap.~\ref{chap:physics}, implemented methods for adaptive multi-channel integration, particularly the integrator \vamp\ are explained, together with the algorithms for the generation of the phase-space in \whizard. Finally, an overview is given over the physics models implemented in \whizard\ and its matrix element generator \oMega, together with possibilities for their extension. After that, the next chapter discusses parton showering, matching and hadronization as well as options for event normalizations and supported event formats. Also weighted event generation is explained along the lines with options for negative weights. Chap.~\ref{chap:visualization} is a stand-alone documentation of GAMELAN, the interal graphics support for the visualization of data and analysis. The next chapter, Chap.~\ref{chap:userint} details user interfaces: how to use more options of the \whizard\ command on the command line, how to use \whizard\ interactively, and how to include \whizard\ as a library into the user's own program. Then, an extensive list of examples in Chap.~\ref{chap:examples} documenting physics examples from the LEP, SLC, HERA, Tevatron, and LHC colliders to future linear and circular colliders. This chapter is a particular good reference for the beginning, as the whole chain from choosing a model, setting up processes, the beam structure, the integration, and finally simulation and (graphical) analysis are explained in detail. More technical details about efficiency, tuning and advance usage of \whizard\ are collected in Chap.~\ref{chap:tuning}. Then, Chap.~\ref{chap:extmodels} shows how to set up your own new physics model with the help of external programs like \sarah\ or \FeynRules\ program or the Universal Feynrules Output, UFO, and include it into the \whizard\ event generator. In the appendices, we e.g. give an exhaustive reference list of \sindarin\ commands and built-in variables. Please report any inconsistencies, bugs, problems or simply pose open questions to our contact \url{whizard@desy.de}. %%%%% \section{Historical remarks} This section gives a historical overview over the development of \whizard\ and can be easily skipped in a (first) reading of the manual. \whizard\ has been developed in a first place as a tool for the physics at the then planned linear electron-positron collider TESLA around 1999. The intention was to have a tool at hand to describe electroweak physics of multiple weak bosons and the Higgs boson as precise as possible with full matrix elements. Hence, the acronym: \ttt{WHiZard}, which stood for $\mathbf{W}$, {\bf H}iggs, $\mathbf{Z}$, {\bf a}nd {\bf r}espective {\bf d}ecays. Several components of the \whizard\ package that are also available as independent sub-packages have been published already before the first versions of the \whizard\ generator itself: the multi-channel adaptive Monte-Carlo integration package \vamp\ has been released mid 1998~\cite{VAMP}. The dedicated packages for the simulation of linear lepton collider beamstrahlung and the option for a photon collider on Compton backscattering (\ttt{CIRCE1/2}) date back even to mid 1996~\cite{CIRCE}. Also parts of the code for \whizard's internal graphical analysis (the \gamelan\ module) came into existence already around 1998. After first inofficial versions, the official version 1 of \whizard\ was release in the year 2000. The development, improvement and incorporation of new features continued for roughly a decade. Major milestones in the development were the full support of all kinds of beyond the Standard Model (BSM) models including spin 3/2 and spin 2 particles and the inclusion of the MSSM, the NMSSM, Little Higgs models and models for anomalous couplings as well as extra-dimensional models from version 1.90 on. In the beginning, several methods for matrix elements have been used, until the in-house matrix element generator \oMega\ became available from version 1.20 on. It was included as a part of the \whizard\ package from version 1.90 on. The support for full color amplitudes came with version 1.50, but in a full-fledged version from 2.0 on. Version 1.40 brought the necessary setups for all kinds of collider environments, i.e. asymmetric beams, decay processes, and intrinsic $p_T$ in structure functions. Version 2.0 was released in April 2010 as an almost complete rewriting of the original code. It brought the construction of an internal density-matrix formalism which allowed the use of factorized production and (cascade) decay processes including complete color and spin correlations. Another big new feature was the command-line language \sindarin\ for steering all parts of the program. Also, many performance improvement have taken place in the new release series, like OpenMP parallelization, speed gain in matrix element generation etc. Version 2.2 came out in May 2014 as a major refactoring of the program internals but keeping (almost everywhere) the same user interface. New features are inclusive processes, reweighting, and more interfaces for QCD environments (BLHA/HOPPET). The following tables shows some of the major steps (physics implementation and/or technical improvements) in the development of \whizard: \begin{center} \begin{tabular}{|l|l|l|}\hline 0.99 & 08/1999 & Beta version \\\hline 1.00 & 12/2000 & First public version \\\hline 1.10 & 03/2001 & Libraries; \pythiasix\ interface \\ 1.11 & 04/2001 & PDF support; anomalous couplings \\ \hline 1.20 & 02/2002 & \oMega\ matrix elements; \ttt{CIRCE} support\\ 1.22 & 03/2002 & QED ISR; beam remnants, phase space improvements \\ 1.25 & 05/2003 & MSSM; weighted events; user-code plug-in \\ 1.28 & 04/2004 & Improved phase space; SLHA interface; signal catching \\\hline 1.30 & 09/2004 & Major technical overhaul \\\hline 1.40 & 12/2004 & Asymmetric beams; decays; $p_T$ in structure functions \\\hline 1.50 & 02/2006 & QCD support in \oMega\ (color flows); LHA format \\ 1.51 & 06/2006 & $Hgg$, $H\gamma\gamma$; Spin 3/2 + 2; BSM models \\\hline 1.90 & 11/2007 & \oMega\ included; LHAPDF support; $Z'$; $WW$ scattering \\ 1.92 & 03/2008 & LHE format; UED; parton shower beta version \\ 1.93 & 04/2009 & NMSSM; SLHA2 accord; improved color/flavor sums \\ 1.95 & 02/2010 & MLM matching; development stop in version 1 \\ 1.97 & 05/2011 & Manual for version 1 completed. \\\hline\hline %%% \end{tabular} %%% \end{center} %%% \begin{center} %%% \begin{tabular}{|l|l|l|}\hline 2.0.0 & 04/2010 & Major refactoring: automake setup; dynamic libraries \\ & & improved speed; cascades; OpenMP; \sindarin\ steering language \\ 2.0.3 & 07/2010 & QCD ISR+FSR shower; polarized beams \\ 2.0.5 & 05/2011 & Builtin PDFs; static builds; relocation scripts \\ 2.0.6 & 12/2011 & Anomalous top couplings; unit tests \\\hline 2.1.0 & 06/2012 & Analytic ISR+FSR parton shower; anomalous Higgs couplings \\\hline 2.2.0 & 05/2014 & Major technical refactoring: abstract object-orientation; THDM; \\ & & reweighting; LHE v2/3; BLHA; HOPPET interface; inclusive processes \\ 2.2.1 & 05/2014 & CJ12 PDFs; FastJet interface \\ 2.2.2 & 07/2014 & LHAPDF6 support; correlated LC beams; GuineaPig interface \\ 2.2.3 & 11/2014 & O'Mega virtual machine; lepton collider top pair threshold; Higgs singlet extension \\ 2.2.4 & 02/2015 & LCIO support; progress on NLO; many technical bug fixes \\ 2.2.7 & 08/2015 & progress on POWHEG; fixed-order NLO events; revalidation of ILC event chain \\ 2.2.8 & 11/2015 & support for quadruple precision; StdHEP included; SM dim 6 operators supported \\\hline 2.3.0 & 07/2016 & NLO: resonance mappings for FKS subtraction; more advanced cascade syntax; \\ & & GUI ($\alpha$ version); UFO support ($\alpha$ version); ILC v1.9x-v2.x final validation \\ 2.3.1 & 08/2016 & Complex mass scheme \\\hline 2.4.0 & 11/2016 & Refactoring of NLO setup \\ 2.4.1 & 03/2017 & $\alpha$ version of new VEGAS implementation \\\hline 2.5.0 & 05/2017 & Full UFO support (SM-like models) \\\hline 2.6.0 & 09/2017 & MPI parallel integration and event generation; resonance histories \\ & & for showers; RECOLA support \\ 2.6.1 & 11/2017 & EPA/ISR transverse distributions, handling of shower resonances; \\ & & more efficient (alternative) phase space generation \\ 2.6.2 & 12/2017 & $Hee$ coupling, improved resonance matching \\ 2.6.3 & 02/2018 & Partial NLO refactoring for quantum numbers, unified RECOLA 1/2 interface. \\ 2.6.4 & 08/2018 & Gridpack functionality; Bug fixes: color flows, HSExt model, MPI setup \\\hline 2.7.0 & 01/2019 & PYTHIA8 interface, process setup refactoring, RAMBO PS option; \\ & & \quad gfortran 5.0+ necessary \\\hline 2.8.0 & 08/2019 & (Almost) complete UFO support, general Lorentz structures, n-point vertices \\ 2.8.1 & 09/2019 & HepMC3, NLO QCD pp (almost) complete, b/c jet selection, photon isolation \\ 2.8.2 & 10/2019 & Support for OCaml $\geq$ 4.06.0, UFO Spin-2 support, LCIO alternative weights \\\hline \end{tabular} \end{center} \vspace{.5cm} For a detailed overview over the historical development of the code confer the \ttt{ChangeLog} file and the commit messages in our revision control system repository. %%%%% \section{About examples in this manual} Although \whizard\ has been designed as a Monte Carlo event generator for LHC physics, several elementary steps and aspects of its usage throughout the manual will be demonstrated with the famous textbook example of $e^+e^- \to \mu^+ \mu^-$. This is the same process, the textbook by Peskin/Schroeder \cite{PeskinSchroeder} uses as a prime example to teach the basics of quantum field theory. We use this example not because it is very special for \whizard\ or at the time being a relevant physics case, but simply because it is the easiest fundamental field theoretic process without the complications of structured beams (which can nevertheless be switched on like for ISR and beamstrahlung!), the need for jet definitions/algorithms and flavor sums; furthermore, it easily accomplishes a demonstration of polarized beams. After the basics of \whizard\ usage have been explained, we move on to actual physics cases from LHC (or Tevatron). \newpage \chapter{Installation} \label{chap:installation} \section{Package Structure} \whizard\ is a software package that consists of a main executable program (which is called \ttt{whizard}), libraries, auxiliary executable programs, and machine-independent data files. The whole package can be installed by the system administrator, by default, on a central location in the file system (\ttt{/usr/local} with its proper subdirectories). Alternatively, it is possible to install it in a user's home directory, without administrator privileges, or at any other location. A \whizard\ run requires a workspace, i.e., a writable directory where it can put generated code and data. There are no constraints on the location of this directory, but we recommend to use a separate directory for each \whizard\ project, or even for each \whizard\ run. Since \whizard\ generates the matrix elements for scattering and decay processes in form of \fortran\ code that is automatically compiled and dynamically linked into the running program, it requires a working \fortran\ compiler not just for the installation, but also at runtime. The previous major version \whizard1 did put more constraints on the setup. In a nutshell, not just the matrix element code was compiled at runtime, but other parts of the program as well, so the whole package was interleaved and had to be installed in user space. The workflow was controlled by \ttt{make} and PERL scripts. These constraints are gone in the present version in favor of a clean separation of installation and runtime workspace. \section{\label{sec:prerequisites}Prerequisites} \subsection{No Binary Distribution} \whizard\ is currently not distributed as a binary package, nor is it available as a debian or RPM package. This might change in the future. However, compiling from source is very simple (see below). Since the package needs a compiler also at runtime, it would not work without some development tools installed on the machine, anyway. Note, however, that we support an install script, that downloads all necessary prerequisites, and does the configuration and compilation described below automatically. This is called the ``instant WHIZARD'' and is accessible through the WHIZARD webpage from version 2.1.1 on: \url{https://whizard.hepforge.org/versions/install/install-whizard-2.X.X.sh}. Download this shell script, make it executable by \begin{interaction} chmod +x install-whizard-2.X.X.sh \end{interaction} and execute it. Note that this also involves compilation of the required \ttt{Fortran} compiler which takes 1-3 hours depending on your system. \ttt{Darwin} operating systems (a.k.a. as \ttt{Mac OS X}) have a very similar general system for all sorts of software, called \ttt{MacPorts} (\url{http://www.macports.org}). This offers to install \whizard\ as one of its software ports, and is very similar to ``instant WHIZARD'' described above. \subsection{Tarball Distribution} This is the recommended way of obtaining \whizard. You may download the current stable distribution from the \whizard\ webpage, hosted at the HepForge webpage \begin{quote} \hepforgepage \end{quote} The distribution is a single file, say \ttt{whizard-\thisversion.tgz} for version \thisversion. You need the additional prerequisites: \begin{itemize} \item GNU \ttt{tar} (or \ttt{gunzip} and \ttt{tar}) for unpacking the tarball. \item The \ttt{make} utility. Other standard Unix utilities (\ttt{sed}, \ttt{grep}, etc.) are usually installed by default. \item A modern \fortran\ compiler (see Sec.~\ref{sec:compilers} for details). \item The \ocaml\ system. \ocaml\ is a functional and object-oriented language. Version 4.02.3 or newer is required to compile all components of \whizard. The package is freely available either as a debian/RPM package on your system (it might be necessary to install it from the usual repositories), or you can obtain it directly from \begin{quote} \url{http://caml.inria.fr} \end{quote} and install it yourself. If desired, the package can be installed in user space without administrator privileges\footnote{ Unfortunately, the version of the \ocaml\ compiler from 3.12.0 broke backwards compatibility. Therefore, versions of \oMega/\whizard\ up to 2.0.2 only compile with older versions (3.11.x works). This has been fixed in versions 2.0.3 and later. See also Sec.~\ref{sec:buildproblems}. \whizard\ versions up to 2.7.1 were still backwards compatible with \ocaml\ 3.12.0}. \end{itemize} The following optional external packages are not required, but used for certain purposes. Make sure to check whether you will need any of them, before you install \whizard. \begin{itemize} \item \LaTeX\ and \metapost\ for data visualization. Both are part of the \TeX\ program family. These programs are not absolutely necessary, but \whizard\ will lack the tools for visualization without them. \item The \lhapdf\ structure-function library. See Sec.~\ref{sec:lhapdf_install}. \item The \hoppet\ structure-function matching tool. See Sec.~\ref{sec:hoppet}. \item The \hepmc\ event-format package. See Sec.~\ref{sec:hepmc}. \item The \fastjet\ jet-algorithm package. See Sec.~\ref{sec:fastjet}. \item The \lcio\ event-format package. See Sec.~\ref{sec:lcio}. \end{itemize} Until version v2.2.7 of \whizard, the event-format package \stdhep\ used to be available as an external package. As their distribution is frozen with the final version v5.06.01, and it used to be notoriously difficult to compile and link \stdhep\ into \whizard, it was decided to include \stdhep\ into \whizard. This is the case from version v2.2.8 of \whizard\ on. Linking against an external version of \stdhep\ is precluded from there on. Nevertheless, we list some explanations in Sec.~\ref{sec:stdhep}, particularly on the need to install the \ttt{libtirpc} headers for the legacy support of this event format. Once these prerequisites are met, you may unpack the package in a directory of your choice \begin{quote}\small\tt some-directory> tar xzf whizard-\thisversion.tgz \end{quote} and proceed.\footnote{Without GNU \ttt{tar}, this would read \ttt{\small gunzip -c whizard-\thisversion.tgz | tar xz -}} For using external physics models that are directly supported by \whizard\ and \oMega, the user can use tools like \sarah\ or \FeynRules. There installation and linking to \whizard\ will be explained in Chap.~\ref{chap:extmodels}. Besides this, also new models can be conveniently included via \UFO\ files, which will be explained as well in that chapter. The directory will then contain a subdirectory \ttt{whizard-\thisversion} where the complete source tree is located. To update later to a new version, repeat these steps. Each new version will unpack in a separate directory with the appropriate name. \subsection{SVN Repository Version} If you want to install the latest development version, you have to check it out from the \whizard\ SVN repository. In addition to the prerequisites listed in the previous section, you need: \begin{itemize} \item The \ttt{subversion} package (\ttt{svn}), the tool for dealing with SVN repositories. \item The \ttt{autoconf} package, part of the \ttt{autotools} development system. \ttt{automake} is needed with version \ttt{1.12.2} or newer. \item The \ttt{noweb} package, a light-weight tool for literate programming. This package is nowadays often part of Linux distributions\footnote{In Ubuntu from version 10.04 on, and in Debian since squeeze. For \ttt{Mac OS X}, \ttt{noweb} is available via the \ttt{MacPorts} system.}. You can obtain the source code from\footnote{Please, do not use any of the binary builds from this webpage. Probably all of them are quite old and broken.} \begin{quote} \url{http://www.cs.tufts.edu/~nr/noweb/} \end{quote} \end{itemize} To start, go to a directory of your choice and execute \begin{interaction} your-src-directory> svn checkout svn+ssh://vcs@phab.hepforge.org/source/whizardsvn/trunk \;\; . \end{interaction} Note that for the time being after the HepForge system modernization early September 2018, a HepForge account with a local ssl key is necessary to checkout the subversion repository. This is enforced by the phabricator framework of HepForge, and will hopefully be relaxed in the future. The SVN source tree will appear in the current directory. To update later, you just have to execute \begin{interaction} your-src-directory> svn update \end{interaction} within that directory. After checking out the sources, you first have to create \ttt{configure.ac} by executing the shell script \ttt{build\_master.sh}. In order to build the \ttt{configure} script, the \ttt{autotools} package \ttt{autoreconf} has to be run. On some \ttt{Unix} systems the \ttt{RPC} headers needed for the legacy support of the \stdhep\ event format are provided by the \ttt{TIRPC} library (cf. Sec.~\ref{sec:stdhep}). To easily check for them, \ttt{configure.ac} processed by \ttt{autoreconf} makes use of the \ttt{pkg-config} tool which needs to be installed for the developer version. So now, run\footnote{At least, version 2.65 of the \ttt{autoconf} package is required.} \begin{interaction} your-src-directory> autoreconf \end{interaction} This will generate a \ttt{configure} script. \subsection{\label{sec:compilers}Fortran Compilers} \whizard\ is written in modern \fortran. To be precise, it uses a subset of the \fortranOThree\ standard. At the time of this writing, this subset is supported by, at least, the following compilers: \begin{itemize} \item \ttt{gfortran} (GNU, Open Source). You will need version 5.1.0 or higher\footnote{Note that \whizard\ versions 2.0.0 until 2.3.1 compiled with \ttt{gfortran} 4.7.4, but the object-oriented refactoring of the \whizard\ code from 2.4.0 on until version 2.6.5 made a switch to \ttt{gfortran} 4.8.4 or higher necessary. In the same way, since version 2.7.0, \ttt{gfortran} 5.1.0 or newer is needed}. We recommend to use at least version 5.4 or higher, as especially the the early version of the \texttt{gfortran} experience some bugs. \ttt{gfortran} 6.5.0 has a severe regression and cannot be used. \item \ttt{nagfor} (NAG). You will need version 6.2 or higher. \item \ttt{ifort} (Intel). You will need version 19.0.2 or higher \end{itemize} %%%%% \subsection{LHAPDF} \label{sec:lhapdf_install} For computing scattering processes at hadron colliders such as the LHC, \whizard\ has a small set of standard structure-function parameterizations built in, cf.\ Sec.~\ref{sec:built-in-pdf}. For many applications, this will be sufficient, and you can skip this section. However, if you need structure-function parameterizations that are not in the default set (e.g. PDF error sets), you can use the \lhapdf\ structure-function library, which is an external package. It has to be linked during \whizard\ installation. For use with \whizard, version 5.3.0 or higher of the library is required\footnote{ Note that PDF sets which contain photons as partons are only supported with \whizard\ for \lhapdf\ version 5.7.1 or higher}. The \lhapdf\ package has undergone a major rewriting from \fortran\ version 5 to \ttt{C++} version 6. While still maintaining the interface for the \lhapdf\ version 5 series, from version 2.2.2 of \whizard\ on, the new release series of \lhapdf, version 6.0 and higher, is also supported. If \lhapdf\ is not yet installed on your system, you can download it from \begin{quote} \url{https://lhapdf.hepforge.org} \end{quote} for the most recent LHAPDF version 6 and newer, or \begin{quote} \url{https://lhapdf.hepforge.org/lhapdf5} \end{quote} for version 5 and older, and install it. The website contains comprehensive documentation on the configuring and installation procedure. Make sure that you have downloaded and installed not just the package, but also the data sets. Note that \lhapdf\ version 5 needs both a \fortran\ and a \ttt{C++} compiler. During \whizard\ configuration, \whizard\ looks for the script \ttt{lhapdf} (which is present in \lhapdf\ series 6) first, and then for \ttt{lhapdf-config} (which is present since \lhapdf\ version 4.1.0): if those are in an executable path (or only the latter for \lhapdf\ version 5), the environment variables for \lhapdf\ are automatically recognized by \whizard, as well as the version number. This should look like this in the \ttt{configure} output (for \lhapdf\ version 6 or newer), \begin{footnotesize} \begin{verbatim} configure: -------------------------------------------------------------- configure: --- LHAPDF --- configure: checking for lhapdf... /usr/local/bin/lhapdf checking for lhapdf-config... /usr/local/bin/lhapdf-config checking the LHAPDF version... 6.2.1 checking the major version... 6 checking the LHAPDF pdfsets path... /usr/local/share/LHAPDF checking the standard PDF sets... all standard PDF sets installed checking if LHAPDF is functional... yes checking LHAPDF... yes configure: -------------------------------------------------------------- \end{verbatim} \end{footnotesize} while for \lhapdf\ version 5 and older it looks like this: \begin{footnotesize} \begin{verbatim} configure: -------------------------------------------------------------- configure: --- LHAPDF --- configure: checking for lhapdf... no checking for lhapdf-config... /usr/local/bin/lhapdf-config checking the LHAPDF version... 5.9.1 checking the major version... 5 checking the LHAPDF pdfsets path... /usr/local/share/lhapdf/PDFsets checking the standard PDF sets... all standard PDF sets installed checking for getxminm in -lLHAPDF... yes checking for has_photon in -lLHAPDF... yes configure: -------------------------------------------------------------- \end{verbatim} \end{footnotesize} If you want to use a different \lhapdf\ (e.g. because the one installed on your system by default is an older one), the preferred way to do so is to put the \ttt{lhapdf} (and/or \ttt{lhapdf-config}) scripts in an executable path that is checked before the system paths, e.g. \ttt{/bin}. For the old series, \lhapdf\ version 5, a possible error could arise if \lhapdf\ had been compiled with a different \fortran\ compiler than \whizard, and if the run-time library of that \fortran\ compiler had not been included in the \whizard\ configure process. The output then looks like this: \begin{footnotesize} \begin{verbatim} configure: -------------------------------------------------------------- configure: --- LHAPDF --- configure: checking for lhapdf... no checking for lhapdf-config... /usr/local/bin/lhapdf-config checking the LHAPDF version... 5.9.1 checking the major version... 5 checking the LHAPDF pdfsets path... /usr/local/share/lhapdf/PDFsets checking for standard PDF sets... all standard PDF sets installed checking for getxminm in -lLHAPDF... no checking for has_photon in -lLHAPDF... no configure: -------------------------------------------------------------- \end{verbatim} \end{footnotesize} So, the \whizard\ configure found the \lhapdf\ distribution, but could not link because it could not resolve the symbols inside the library. In case of failure, for more details confer the \ttt{config.log}. If \lhapdf\ is installed in a non-default directory where \whizard\ would not find it, set the environment variable \ttt{LHAPDF\_DIR} to the correct installation path when configuring \whizard. The check for the standard PDF sets are those sets that are used in the default \whizard\ self tests in the case \lhapdf\ is enabled and correctly linked. If some of them are missing, then this test will result in a failure. They are the \ttt{CT10} set for \lhapdf\ version 6 (for version 5, \ttt{cteq61.LHpdf}, \ttt{cteq6ll.LHpdf}, \ttt{cteq5l.LHgrid}, and \ttt{GSG961.LHgrid} are demanded). If you want to use \lhapdf\ inside \whizard\ please install them such that \whizard\ could perform all its sanity checks with them. The last check is for the \ttt{has\_photon} flag, which tests whether photon PDFs are available in the found \lhapdf\ installation. %%%%% \subsection{HOPPET} \label{sec:hoppet} \hoppet\ (not Hobbit) is a tool for the QCD DGLAP evolution of PDFs for hadron colliders. It provides possibilities for matching algorithms for 4- and 5-flavor schemes, that are important for precision simulations of $b$-parton initiated processes at hadron colliders. If you are not interested in those features, you can skip this section. Note that this feature is not enabled by default (unlike e.g. \lhapdf), but has to be explicitly during the configuration (see below): \begin{interaction} your-build-directory> your-src-directory/configure --enable-hoppet \end{interaction} If you \ttt{configure} messages like the following: \begin{footnotesize} \begin{verbatim} configure: -------------------------------------------------------------- configure: --- HOPPET --- configure: checking for hoppet-config... /usr/local/bin/hoppet-config checking for hoppetAssign in -lhoppet_v1... yes checking the HOPPET version... 1.2.0 configure: -------------------------------------------------------------- \end{verbatim} \end{footnotesize} then you know that \hoppet\ has been found and was correctly linked. If that is not the case, you have to specify the location of the \hoppet\ library, e.g. by adding \begin{interaction} HOPPET=/lib \end{interaction} to the \ttt{configure} options above. For more details, please confer the \hoppet\ manual. %%%%% \subsection{HepMC} \label{sec:hepmc} With version 2.8.1, \whizard\ supports both the "classical" version 2 as well as the newly designed version 3 (release 2019). The configure step can successfully recognize the two different versions, the user do not have to specify which version is installed. \hepmc\ is a \ttt{C++} class library for handling collider scattering events. In particular, it provides a portable format for event files. If you want to use this format, you should link \whizard\ with \hepmc, otherwise you can skip this section. If it is not already installed on your system, you may obtain \hepmc\ from one of these two webpages: \begin{quote} \url{http://hepmc.web.cern.ch/hepmc/} \end{quote} or \begin{quote} \url{http://hepmc.web.cern.ch/hepmc/} \end{quote} If the \hepmc\ library is linked with the installation, \whizard\ is able to read and write files in the \hepmc\ format. Detailed information on the installation and usage can be found on the \hepmc\ homepage. We give here only some brief details relevant for the usage with \whizard: For the compilation of HepMC one needs a \ttt{C++} compiler. Then the procedure is the same as for the \whizard\ package, namely configure HepMC: \begin{interaction} configure --with-momentum=GEV --with-length=MM --prefix= \end{interaction} Note that the particle momentum and decay length flags are mandatory, and we highly recommend to set them to the values \ttt{GEV} and \ttt{MM}, respectively. After configuration, do \ttt{make}, an optional \ttt{make check} (which might sometimes fail for non-standard values of momentum and length), and finally \ttt{make install}. The latest version of \hepmc\ (2.6.10) as well as the new relase series use \texttt{cmake} for their build process. For more information, confer the \hepmc\ webpage. A \whizard\ configuration for \hepmc\ looks like this: \begin{footnotesize} \begin{verbatim} configure: -------------------------------------------------------------- configure: --- HepMC --- configure: checking for HepMC-config... no checking HepMC3 or newer... no configure: HepMC3 not found, incompatible, or HepMC-config not found configure: looking for HepMC2 instead ... checking the HepMC version... 2.06.10 checking for GenEvent class in -lHepMC... yes configure: -------------------------------------------------------------- \end{verbatim} \end{footnotesize} If \hepmc\ is installed in a non-default directory where \whizard\ would not find it, set the environment variable \ttt{HEPMC\_DIR} to the correct installation path when configuring \whizard. Furthermore, the environment variable \ttt{CXXFLAGS} allows you to set specific \ttt{C/C++} preprocessor flags, e.g. non-standard include paths for header files. A typical configuration of \hepmcthree\ will look like this: \begin{footnotesize} \begin{verbatim} configure: -------------------------------------------------------------- configure: --- ROOT --- configure: checking for root-config... /usr/local/bin/root-config checking for root... /usr/local/bin/root checking for rootcint... /usr/local/bin/rootcint checking for dlopen in -ldl... (cached) yes configure: -------------------------------------------------------------- configure: --- HepMC --- configure: checking for HepMC3-config... /usr/local/bin/HepMC3-config checking if HepMC3 is built with ROOT interface... yes checking if HepMC3 is functional... yes checking for HepMC3... yes checking the HepMC3 version... 3.02.01 configure: -------------------------------------------------------------- \end{verbatim} \end{footnotesize} As can be seen, \whizard\ will check for the \ROOT\ environment as well as whether \hepmcthree\ has been built with support for the \ROOT\ and \ttt{RootTree} writer classes. This is an easy option to use \whizard\ to write out \ROOT\ events. For more information see Sec.~\ref{sec:root}. %%%%% \subsection{PYTHIA8} \label{sec:pythia8} \emph{NOTE: This is at the moment not yet supported, but merely a stub with the only purpose to be recognized by the build system.} \pythiaeight\ is a \ttt{C++} class library for handling hadronization, showering and underlying event. If you want to use this feature (once it is fully supported in \whizard), you should link \whizard\ with \pythiaeight, otherwise you can skip this section. If it is not already installed on your system, you may obtain \pythiaeight\ from \begin{quote} \url{http://home.thep.lu.se/~torbjorn/Pythia.html} \end{quote} If the \pythiaeight\ library is linked with the installation, \whizard\ will be able to use its hadronization and showering, once this is fully supported within \whizard. To link a \pythiaeight\ installation to \whizard, you should specify the flag \begin{quote} \ttt{--enable-pythia8} \end{quote} to \ttt{configure}. If \pythiaeight\ is installed in a non-default directory where \whizard\ would not find it, specify also \begin{quote} \ttt{--with-pythia8=\emph{}} \end{quote} A successful \whizard\ configuration should produce a screen output similar to this: \begin{footnotesize} \begin{verbatim} configure: -------------------------------------------------------------- configure: --- SHOWERS PYTHIA6 PYTHIA8 MPI --- configure: [....] checking for pythia8-config... /usr/local/bin/pythia8-config checking if PYTHIA8 is functional... yes checking PYTHIA8... yes configure: WARNING: PYTHIA8 configure is for testing purposes at the moment. configure: -------------------------------------------------------------- \end{verbatim} \end{footnotesize} %%%%% \subsection{FastJet} \label{sec:fastjet} \fastjet\ is a \ttt{C++} class library for handling jet clustering. If you want to use this feature, you should link \whizard\ with \fastjet, otherwise you can skip this section. If it is not already installed on your system, you may obtain \fastjet\ from \begin{quote} \url{http://fastjet.fr} \end{quote} If the \fastjet\ library is linked with the installation, \whizard\ is able to call the jet algorithms provided by this program for the purposes of applying cuts and analysis. To link a \fastjet\ installation to \whizard, you should specify the flag \begin{quote} \ttt{--enable-fastjet} \end{quote} to \ttt{configure}. If \fastjet\ is installed in a non-default directory where \whizard\ would not find it, specify also \begin{quote} \ttt{--with-fastjet=\emph{}} \end{quote} A successful \whizard\ configuration should produce a screen output similar to this: \begin{footnotesize} \begin{verbatim} configure: -------------------------------------------------------------- configure: --- FASTJET --- configure: checking for fastjet-config... /usr/local/bin/fastjet-config checking if FastJet is functional... yes checking FastJet... yes checking the FastJet version... 3.3.0 configure: -------------------------------------------------------------- \end{verbatim} \end{footnotesize} %%%%% \subsection{STDHEP} \label{sec:stdhep} \stdhep\ is a library for handling collider scattering events~\cite{stdhep}. In particular, it provides a portable format for event files. Until version 2.2.7 of \whizard, \stdhep\ that was maintained by Fermilab, could be linked as an externally compiled library. As the \stdhep\ package is frozen in its final release v5.06.1 and no longer maintained, it has from version 2.2.8 been included \whizard. This eases many things, as it was notoriously difficult to compile and link \stdhep\ in a way compatible with \whizard. Not the full package has been included, but only the libraries for file I/O (\ttt{mcfio}, the library for the XDR conversion), while the various translation tools for \pythia, \herwig, etc. have been abandoned. Note that \stdhep\ has largely been replaced in the hadron collider community by the \hepmc\ format, and in the lepton collider community by \lcio. \whizard\ might serve as a conversion tools for all these formats, but other tools also exist, of course. Note that the \ttt{mcfio} framework makes use of the \ttt{RPC} headers. These come -- provided by \ttt{SunOS/Oracle America, Inc.} -- together with the system headers, but on some \ttt{Unix} systems (e.g. \ttt{ArchLinux}, \ttt{Fedora}) have been replaced by the \ttt{libtirpc} headers . The \ttt{configure} script searches for these headers so these have to be installed mandatorily. If the \stdhep\ library is linked with the installation, \whizard\ is able to write files in the \stdhep\ format, the corresponding configure output notifies you that \stdhep\ is always included: \begin{footnotesize} \begin{verbatim} configure: -------------------------------------------------------------- configure: --- STDHEP --- configure: checking for pkg-config... /opt/local/bin/pkg-config checking pkg-config is at least version 0.9.0... yes checking for libtirpc... no configure: for StdHEP legacy code: using SunRPC headers and library configure: StdHEP v5.06.01 is included internally configure: -------------------------------------------------------------- \end{verbatim} \end{footnotesize} %%%%% \subsection{LCIO} \label{sec:lcio} \lcio\ is a \ttt{C++} class library for handling collider scattering events. In particular, it provides a portable format for event files. If you want to use this format, you should link \whizard\ with \lcio, otherwise you can skip this section. If it is not already installed on your system, you may obtain \lcio\ from: \begin{quote} \url{http://lcio.desy.de} \end{quote} If the \lcio\ library is linked with the installation, \whizard\ is able to read and write files in the \lcio\ format. Detailed information on the installation and usage can be found on the \lcio\ homepage. We give here only some brief details relevant for the usage with \whizard: For the compilation of \lcio\ one needs a \ttt{C++} compiler. \lcio\ is based on \ttt{cmake}. For the corresponding options please confer the \lcio\ manual. A \whizard\ configuration for \lcio\ looks like this: \begin{footnotesize} \begin{verbatim} configure: -------------------------------------------------------------- configure: --- LCIO --- configure: checking the LCIO version... 2.12.1 checking for LCEventImpl class in -llcio... yes configure: -------------------------------------------------------------- \end{verbatim} \end{footnotesize} If \lcio\ is installed in a non-default directory where \whizard\ would not find it, set the environment variable \ttt{LCIO} or \ttt{LCIO\_DIR} to the correct installation path when configuring \whizard. The first one is the variable exported by the \ttt{setup.sh} script while the second one is analogous to the environment variables of other external packages. \ttt{LCIO} takes precedence over \ttt{LCIO\_DIR}. Furthermore, the environment variable \ttt{CXXFLAGS} allows you to set specific \ttt{C/C++} preprocessor flags, e.g. non-standard include paths for header files. %%%%% \section{Installation} \label{sec:installation} Once you have unpacked the source (either the tarball or the SVN version), you are ready to compile it. There are several options. \subsection{Central Installation} This is the default and recommended way, but it requires adminstrator privileges. Make sure that all prerequisites are met (Sec.~\ref{sec:prerequisites}). \begin{enumerate} \item Create a fresh directory for the \whizard\ build. It is recommended to keep this separate from the source directory. \item Go to that directory and execute \begin{interaction} your-build-directory> your-src-directory/configure \end{interaction} This will analyze your system and prepare the compilation of \whizard\ in the build directory. Make sure to set the proper options to \ttt{configure}, see Sec.~\ref{sec:configure-options} below. \item Call \ttt{make} to compile and link \whizard: \begin{interaction} your-build-directory> make \end{interaction} \item If you want to make sure that everything works, run \begin{interaction} your-build-directory> make check \end{interaction} This will take some more time. \item Become superuser and say \begin{interaction} your-build-directory> make install \end{interaction} \end{enumerate} \whizard\ should now installed in the default locations, and the executable should be available in the standard path. Try to call \ttt{whizard --help} in order to check this. \subsection{Installation in User Space} You may lack administrator privileges on your system. In that case, you can still install and run \whizard. Make sure that all prerequisites are met (Sec.~\ref{sec:prerequisites}). \begin{enumerate} \item Create a fresh directory for the \whizard\ build. It is recommended to keep this separate from the source directory. \item Reserve a directory in user space for the \whizard\ installation. It should be empty, or yet non-existent. \item Go to that directory and execute \begin{interaction} your-build-directory> your-src-directory/configure --prefix=your-install-directory \end{interaction} This will analyze your system and prepare the compilation of \whizard\ in the build directory. Make sure to set the proper additional options to \ttt{configure}, see Sec.~\ref{sec:configure-options} below. \item Call \ttt{make} to compile and link \whizard: \begin{interaction} your-build-directory> make \end{interaction} \item If you want to make sure that everything works, run \begin{interaction} your-build-directory> make check \end{interaction} This will take some more time. \item Install: \begin{interaction} your-build-directory> make install \end{interaction} \end{enumerate} \whizard\ should now be installed in the installation directory of your choice. If the installation is not in your standard search paths, you have to account for this by extending the paths appropriately, see Sec.~\ref{sec:workspace}. \subsection{Configure Options} \label{sec:configure-options} The configure script accepts environment variables and flags. They can be given as arguments to the \ttt{configure} program in arbitrary order. You may run \ttt{configure --help} for a listing; only the last part of this long listing is specific for the \whizard\ system. Here is an example: \begin{interaction} configure FC=gfortran-5.4 FCFLAGS="-g -O3" --enable-fc-openmp \end{interaction} The most important options are \begin{itemize} \item \ttt{FC} (variable): The \fortran\ compiler. This is necessary if you need a compiler different from the standard compiler on the system, e.g., if the latter is too old. \item \ttt{FCFLAGS} (variable): The flags to be given to the Fortran compiler. The main use is to control the level of optimization. \item \ttt{--prefix=\var{directory-name}}: Specify a non-default directory for installation. \item \ttt{--enable-fc-openmp}: Enable parallel executing via OpenMP on a multi-processor/multi-core machine. This works only if OpenMP is supported by the compiler (e.g., \ttt{gfortran}). When running \whizard, the number of processors that are actually requested can be controlled by the user. Without this option, \whizard\ will run in serial mode on a single core. See Sec.~\ref{sec:openmp} for further details. \item \ttt{--enable-fc-mpi}: Enable parallel executing via MPI on a single machine using several cores or several machines. This works only if a MPI library is installed (e.g. \ttt{OpenMPI}) and \ttt{FC=mpifort CC=mpicc CXX=mpic++} is set. Without this option, \whizard\ will run in serial mode on a single core. The flag can be combined with \ttt{--enable-fc-openmp}. See Sec.~\ref{sec:mpi} for further details. \item \ttt{LHADPF\_DIR} (variable): The location of the optional \lhapdf\ package, if non-default. \item \ttt{LOOPTOOLS\_DIR} (variable): The location of the optional \ttt{LOOPTOOLS} package, if non-default. \item \ttt{OPENLOOPS\_DIR} (variable): The location of the optional \openloops\ package, if non-default. \item \ttt{GOSAM\_DIR} (variable): The location of the optional \gosam\ package, if non-default. \item \ttt{HOPPET\_DIR} (variable): The location of the optional \hoppet\ package, if non-default. \item \ttt{HEPMC\_DIR} (variable): The location of the optional \hepmc\ package, if non-default. \item \ttt{LCIO}/\ttt{LCIO\_DIR} (variable): The location of the optional \lcio\ package, if non-default. \end{itemize} Other flags that might help to work around possible problems are the flags for the $C$ and $C++$ compilers as well as the \ttt{Fortran77} compiler, or the linker flags and additional libraries for the linking process. \begin{itemize} \item \ttt{CC} (variable): \ttt{C} compiler command \item \ttt{F77} (variable): \ttt{Fortran77} compiler command \item \ttt{CXX} (variable): \ttt{C++} compiler command \item \ttt{CPP} (variable): \ttt{C} preprocessor \item \ttt{CXXCPP} (variable): \ttt{C++} preprocessor \item \ttt{CFLAGS} (variable): \ttt{C} compiler flags \item \ttt{FFLAGS} (variable): \ttt{Fortran77} compiler flags \item \ttt{CXXFLAGS} (variable): \ttt{C++} compiler flags \item \ttt{LIBS} (variable): libraries to be passed to the linker as \ttt{-l{\em library}} \item \ttt{LDFLAGS} (variable): non-standard linker flags \end{itemize} For other options (like e.g. \ttt{--with-precision=...} etc.) please see the \ttt{configure --help} option. %%%%% \subsection{Details on the Configure Process} The configure process checks for the build and host system type; only if this is not detected automatically, the user would have to specify this by himself. After that system-dependent files are searched for, LaTeX and Acroread for documentation and plots, the \fortran\ compiler is checked, and finally the \ocaml\ compiler. The next step is the checks for external programs like \lhapdf\ and \ttt{HepMC}. Finally, all the Makefiles are being built. The compilation is done by invoking \ttt{make} and finally \ttt{make install}. You could also do a \ttt{make check} in order to test whether the compilation has produced sane files on your system. This is highly recommended. Be aware that there be problems for the installation if the install path or a user's home directory is part of an AFS file system. Several times problems were encountered connected with conflicts with permissions inside the OS permission environment variables and the AFS permission flags which triggered errors during the \ttt{make install} procedure. Also please avoid using \ttt{make -j} options of parallel execution of \ttt{Makefile} directives as AFS filesystems might not be fast enough to cope with this. For specific problems that might have been encountered in rare circumstances for some FORTRAN compilers confer the webpage \url{https://whizard.hepforge.org/compilers.html}. Note that the \pythia\ bundle for showering and hadronization (and some other external legacy code pieces) do still contain good old \ttt{Fortran77} code. These parts should better be compiled with the very same \ttt{Fortran2003} compiler as the \whizard\ core. There is, however, one subtlety: when the \ttt{configure} flag \ttt{FC} gets a full system path as argument, \ttt{libtool} is not able to recognize this as a valid (GNU) \ttt{Fortran77} compiler. It then searches automatically for binaries like \ttt{f77}, \ttt{g77} etc. or a standard system compiler. This might result in a compilation failure of the \ttt{Fortran77} code. A viable solution is to define an executable link and use this (not the full path!) as \ttt{FC} flag. It is possible to compile \whizard\ without the \ocaml\ parts of \oMega, namely by using the \ttt{--disable-omega} option of the configure. This will result in a built of \whizard\ with the \oMega\ Fortran library, but without the binaries for the matrix element generation. All selftests (cf. \ref{sec:selftests}) requiring \oMega\ matrix elements are thereby switched off. Note that you can install such a built (e.g. on a batch system without \ocaml\ installation), but the try to build a distribution (all \ttt{make distxxx} targets) will fail. %%%%%%%%%%% \subsection{\whizard\ self tests/checks} \label{sec:selftests} \whizard\ has a number of self-consistency checks and tests which assure that most of its features are running in the intended way. The standard procedure to invoke these self tests is to perform a \ttt{make check} from the \ttt{build} directory. If \ttt{src} and \ttt{build} directories are the same, all relevant files for these self-tests reside in the \ttt{tests} subdirectory of the main \whizard\ directory. In that case, one could in principle just call the scripts individually from the command line. Note, that if \ttt{src} and \ttt{build} directory are different as recommended, then the input files will have been installed in \ttt{prefix/share/whizard/test}, while the corresponding test shell scripts remain in the \ttt{srcdir/test} directory. As the main shell script \ttt{run\_whizard.sh} has been built in the \ttt{build} directory, one now has to copy the files over by and set the correct paths by hand, if one wishes to run the test scripts individually. \ttt{make check} still correctly performs all \whizard\ self-consistency tests. The tests itself fall into two categories, unit self test that individually test the modular structure of \whizard, and tests that are run by \sindarin\ files. In future releases of \whizard, these two categories of tests will be better separated than in the 2.2.1 release. There are additional, quite extensiv numerical tests for validation and backwards compatibility checks for SM and MSSM processes. As a standard, these extended self tests are not invoked. However, they can be enabled by executing the corresponding specific \ttt{make check} operations in the subdirectories for these extensive tests. As the new \whizard\ testsuite does very thorough and scrupulous tests of the whole \whizard\ structure, it is always possible that some tests are failing due to some weird circumstances or because of numerical fluctuations. In such a case do not panic, contact the developers (\ttt{whizard@desy.de}) and provide them with the logfiles of the failing test as well as the setup of your configuration. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \clearpage \chapter{Working with \whizard} \label{chap:start} \whizard\ can run as a stand-alone program. You (the user) can steer \whizard\ either interactively or by a script file. We will first describe the latter method, since it will be the most common way to interact with the \whizard\ system. \section{Hello World} The legacy version series 1 of the program relied on a bunch of input files that the user had to provide in some obfuscated format. This approach is sufficient for straightforward applications. However, once you get experienced with a program, you start thinking about uses that the program's authors did not foresee. In case of a Monte Carlo package, typical abuses are parameter scans, complex patterns of cuts and reweighting factors, or data analysis without recourse to external packages. This requires more flexibility. Instead of transferring control over data input to some generic scripting language like PERL or PYTHON (or even C++), which come with their own peculiarities and learning curves, we decided to unify data input and scripting in a dedicated steering language that is particularly adapted to the needs of Monte-Carlo integration, simulation, and simple analysis of the results. Thus we discovered what everybody knew anyway: that W(h)izards communicate in \sindarin, Scripting INtegration, Data Analysis, Results display and INterfaces. \sindarin\ is a DSL -- a domain-specific scripting language -- that is designed for the single purpose of steering and talking to \whizard. Now since \sindarin\ is a programming language, we honor the old tradition of starting with the famous Hello World program. In \sindarin\ this reads simply \begin{quote} \begin{verbatim} printf "Hello World!" \end{verbatim} \end{quote} Open your favorite editor, type this text, and save it into a file named \verb|hello.sin|. \begin{figure} \centering \begin{scriptsize} \begin{Verbatim}[frame=single] | Writing log to 'whizard.log' |=============================================================================| | | | WW WW WW WW WW WWWWWW WW WWWWW WWWW | | WW WW WW WW WW WW WW WWWW WW WW WW WW | | WW WW WW WW WWWWWWW WW WW WW WW WWWWW WW WW | | WWWW WWWW WW WW WW WW WWWWWWWW WW WW WW WW | | WW WW WW WW WW WWWWWW WW WW WW WW WWWW | | | | | | W | | sW | | WW | | sWW | | WWW | | wWWW | | wWWWW | | WW WW | | WW WW | | wWW WW | | wWW WW | | WW WW | | WW WW | | WW WW | | WW WW | | WW WW | | WW WW | | wwwwww WW WW | | WWWWWww WW WW | | WWWWWwwwww WW WW | | wWWWwwwwwWW WW | | wWWWWWWWWWWwWWW WW | | wWWWWW wW WWWWWWW | | WWWW wW WW wWWWWWWWwww | | WWWW wWWWWWWWwwww | | WWWW WWWW WWw | | WWWWww WWWW | | WWWwwww WWWW | | wWWWWwww wWWWWW | | WwwwwwwwwWWW | | | | | | | | by: Wolfgang Kilian, Thorsten Ohl, Juergen Reuter | | with contributions from Christian Speckner | | Contact: | | | | if you use WHIZARD please cite: | | W. Kilian, T. Ohl, J. Reuter, Eur.Phys.J.C71 (2011) 1742 | | [arXiv: 0708.4233 [hep-ph]] | | M. Moretti, T. Ohl, J. Reuter, arXiv: hep-ph/0102195 | | | |=============================================================================| | WHIZARD 2.8.3 |=============================================================================| | Reading model file '/usr/local/share/whizard/models/SM.mdl' | Preloaded model: SM | Process library 'default_lib': initialized | Preloaded library: default_lib | Reading commands from file 'hello.sin' Hello World! | WHIZARD run finished. |=============================================================================| \end{Verbatim} \end{scriptsize} \caption{Output of the \ttt{"Hello world!"} \sindarin\ script.\label{fig:helloworld}} \end{figure} Now we assume that you -- or your kind system administrator -- has installed \whizard\ in your executable path. Then you should open a command shell and execute (we will come to the meaning of the \verb|-r| option later.) \begin{verbatim} /home/user$ whizard -r hello.sin \end{verbatim} and if everything works well, you get the output (the complete output including the \whizard\ banner is shown in Fig.~\ref{fig:helloworld}) \begin{footnotesize} \begin{verbatim} | Writing log to 'whizard.log' \end{verbatim} \centerline{[... here a banner is displayed]} \begin{Verbatim} |=============================================================================| | WHIZARD 2.8.3 |=============================================================================| | Reading model file '/usr/local/share/whizard/models/SM.mdl' | Preloaded model: SM ! Process library 'default_lib': initialized ! Preloaded library: default_lib | Reading commands from file 'hello.sin' Hello World! | WHIZARD run finished. |=============================================================================| \end{Verbatim} \end{footnotesize} If this has just worked for you, you can be confident that you have a working \whizard\ installation, and you have been able to successfully run the program. \section{A Simple Calculation} You may object that \whizard\ is not exactly designed for printing out plain text. So let us demonstrate a more useful example. Looking at the Hello World output, we first observe that the program writes a log file named (by default) \verb|whizard.log|. This file receives all screen output, except for the output of external programs that are called by \whizard. You don't have to cache \whizard's screen output yourself. After the welcome banner, \whizard\ tells you that it reads a physics \emph{model}, and that it initializes and preloads a \emph{process library}. The process library is initially empty. It is ready for receiving definitions of elementary high-energy physics processes (scattering or decay) that you provide. The processes are set in the context of a definite model of high-energy physics. By default this is the Standard Model, dubbed \verb|SM|. Here is the \sindarin\ code for defining a SM physics process, computing its cross section, and generating a simulated event sample in Les Houches event format: \begin{quote} \begin{Verbatim} process ee = e1, E1 => e2, E2 sqrts = 360 GeV n_events = 10 sample_format = lhef simulate (ee) \end{Verbatim} \end{quote} As before, you save this text in a file (named, e.g., \verb|ee.sin|) which is run by \begin{verbatim} /home/user$ whizard -r ee.sin \end{verbatim} (We will come to the meaning of the \verb|-r| option later.) This produces a lot of output which looks similar to this: \begin{footnotesize} \begin{verbatim} | Writing log to 'whizard.log' [... banner ...] |=============================================================================| | WHIZARD 2.8.3 |=============================================================================| | Reading model file '/usr/local/share/whizard/models/SM.mdl' | Preloaded model: SM | Process library 'default_lib': initialized | Preloaded library: default_lib | Reading commands from file 'ee.sin' | Process library 'default_lib': recorded process 'ee' sqrts = 3.600000000000E+02 n_events = 10 \end{verbatim} \begin{verbatim} | Starting simulation for process 'ee' | Simulate: process 'ee' needs integration | Integrate: current process library needs compilation | Process library 'default_lib': compiling ... | Process library 'default_lib': writing makefile | Process library 'default_lib': removing old files rm -f default_lib.la rm -f default_lib.lo default_lib_driver.mod opr_ee_i1.mod ee_i1.lo rm -f ee_i1.f90 | Process library 'default_lib': writing driver | Process library 'default_lib': creating source code rm -f ee_i1.f90 rm -f opr_ee_i1.mod rm -f ee_i1.lo /usr/local/bin/omega_SM.opt -o ee_i1.f90 -target:whizard -target:parameter_module parameters_SM -target:module opr_ee_i1 -target:md5sum '70DB728462039A6DC1564328E2F3C3A5' -fusion:progress -scatter 'e- e+ -> mu- mu+' [1/1] e- e+ -> mu- mu+ ... allowed. [time: 0.00 secs, total: 0.00 secs, remaining: 0.00 secs] all processes done. [total time: 0.00 secs] SUMMARY: 6 fusions, 2 propagators, 2 diagrams | Process library 'default_lib': compiling sources [.....] \end{verbatim} \begin{verbatim} | Process library 'default_lib': loading | Process library 'default_lib': ... success. | Integrate: compilation done | RNG: Initializing TAO random-number generator | RNG: Setting seed for random-number generator to 9616 | Initializing integration for process ee: | ------------------------------------------------------------------------ | Process [scattering]: 'ee' | Library name = 'default_lib' | Process index = 1 | Process components: | 1: 'ee_i1': e-, e+ => mu-, mu+ [omega] | ------------------------------------------------------------------------ | Beam structure: [any particles] | Beam data (collision): | e- (mass = 5.1099700E-04 GeV) | e+ (mass = 5.1099700E-04 GeV) | sqrts = 3.600000000000E+02 GeV | Phase space: generating configuration ... | Phase space: ... success. | Phase space: writing configuration file 'ee_i1.phs' | Phase space: 2 channels, 2 dimensions | Phase space: found 2 channels, collected in 2 groves. | Phase space: Using 2 equivalences between channels. | Phase space: wood Warning: No cuts have been defined. \end{verbatim} \begin{verbatim} | Starting integration for process 'ee' | Integrate: iterations not specified, using default | Integrate: iterations = 3:1000:"gw", 3:10000:"" | Integrator: 2 chains, 2 channels, 2 dimensions | Integrator: Using VAMP channel equivalences | Integrator: 1000 initial calls, 20 bins, stratified = T | Integrator: VAMP |=============================================================================| | It Calls Integral[fb] Error[fb] Err[%] Acc Eff[%] Chi2 N[It] | |=============================================================================| 1 784 8.3282892E+02 1.68E+00 0.20 0.06* 39.99 2 784 8.3118961E+02 1.23E+00 0.15 0.04* 76.34 3 784 8.3278951E+02 1.36E+00 0.16 0.05 54.45 |-----------------------------------------------------------------------------| 3 2352 8.3211789E+02 8.01E-01 0.10 0.05 54.45 0.50 3 |-----------------------------------------------------------------------------| 4 9936 8.3331732E+02 1.22E-01 0.01 0.01* 54.51 5 9936 8.3341072E+02 1.24E-01 0.01 0.01 54.52 6 9936 8.3331151E+02 1.23E-01 0.01 0.01* 54.51 |-----------------------------------------------------------------------------| 6 29808 8.3334611E+02 7.10E-02 0.01 0.01 54.51 0.20 3 |=============================================================================| \end{verbatim} \begin{verbatim} [.....] | Simulate: integration done | Simulate: using integration grids from file 'ee_m1.vg' | RNG: Initializing TAO random-number generator | RNG: Setting seed for random-number generator to 9617 | Simulation: requested number of events = 10 | corr. to luminosity [fb-1] = 1.2000E-02 | Events: writing to LHEF file 'ee.lhe' | Events: writing to raw file 'ee.evx' | Events: generating 10 unweighted, unpolarized events ... | Events: event normalization mode '1' | ... event sample complete. | Events: closing LHEF file 'ee.lhe' | Events: closing raw file 'ee.evx' | There were no errors and 1 warning(s). | WHIZARD run finished. |=============================================================================| \end{verbatim} \end{footnotesize} %$ The final result is the desired event file, \ttt{ee.lhe}. Let us discuss the output quickly to walk you through the procedures of a \whizard\ run: after the logfile message and the banner, the reading of the physics model and the initialization of a process library, the recorded process with tag \ttt{'ee'} is recorded. Next, user-defined parameters like the center-of-mass energy and the number of demanded (unweighted) events are displayed. As a next step, \whizard\ is starting the simulation of the process with tag \ttt{'ee'}. It recognizes that there has not yet been an integration over phase space (done by an optional \ttt{integrate} command, cf. Sec.~\ref{sec:integrate}), and consequently starts the integration. It then acknowledges, that the process code for the process \ttt{'ee'} needs to be compiled first (done by an optional \ttt{compile} command, cf. Sec.~\ref{sec:compilation}). So, \whizard\ compiles the process library, writes the makefile for its steering, and as a safeguard against garbage removes possibly existing files. Then, the source code for the library and its processes are generated: for the process code, the default method -- the matrix element generator \oMega\ is called (cf. Sec.~\ref{sec:omega_me}); and the sources are being compiled. The next steps are the loading of the process library, and \whizard\ reports the completion of the integration. For the Monte-Carlo integration, a random number generator is initialized. Here, it is the default generator, TAO (for more details, cf. Sec.~\ref{sec:tao}, while the random seed is set to a value initialized by the system clock, as no seed has been provided in the \sindarin\ input file. Now, the integration for the process \ttt{'ee'} is initialized, and information about the process (its name, the name of its process library, its index inside the library, and the process components out of which it consists, cf. Sec.~\ref{sec:processcomp}) are displayed. Then, the beam structure is shown, which in that case are symmetric partonic electron and positron beams with the center-of-mass energy provided by the user (360 GeV). The next step is the generation of the phase space, for which the default phase space method \ttt{wood} (for more details cf. Sec.~\ref{sec:wood}) is selected. The integration is performed, and the result with absolute and relative error, unweighting efficiency, accuracy, $\chi^2$ quality is shown. The final step is the event generation (cf. Chap.~\ref{chap:events}). The integration grids are now being used, again the random number generator is initialized. Finally, event generation of ten unweighted events starts (\whizard\ let us know to which integrated luminosity that would correspond), and events are written both in an internal (binary) event format as well as in the demanded LHE format. This concludes the \whizard\ run. After a more comprehensive introduction into the \sindarin\ steering language in the next chapter, Chap.~\ref{chap:sindarinintro}, we will discuss all the details of the different steps of this introductory example. \clearpage \section{WHIZARD in a Computing Environment} \subsection{Working on a Single Computer} \label{sec:workspace} After installation, \whizard\ is ready for use. There is a slight complication if \whizard\ has been installed in a location that is not in your standard search paths. In that case, to successfully run \whizard, you may either \begin{itemize} \item manually add \ttt{your-install-directory/bin} to your execution PATH\\ and \ttt{your-install-directory/lib} to your library search path (LD\_LIBRARY\_PATH), or \item whenever you start a project, execute \begin{interaction} your-workspace> . your-install-directory/bin/whizard-setup.sh \end{interaction} which will enable the paths in your current environment, or \item source \ttt{whizard-setup.sh} script in your shell startup file. \end{itemize} In either case, try to call \ttt{whizard --help} in order to check whether this is done correctly. For a new \whizard\ project, you should set up a new (empty) directory. Depending on the complexity of your task, you may want to set up separate directories for each subproblem that you want to tackle, or even for each separate run. The location of the directories is arbitrary. To run, \whizard\ needs only a single input file, a \sindarin\ command script with extension \ttt{.sin} (by convention). Running \whizard\ is as simple as \begin{interaction} your-workspace> whizard your-input.sin \end{interaction} No other configuration files are needed. The total number of auxiliary and output files generated in a single run may get quite large, however, and they may clutter your workspace. This is the reason behind keeping subdirectories on a per-run basis. Basic usage of \whizard\ is explained in Chapter~\ref{chap:start}, for more details, consult the following chapters. In Sec.~\ref{sec:cmdline-options} we give an account of the command-line options that \whizard\ accepts. \subsection{Working Parallel on Several Computers} \label{sec:mpi} For integration (only VAMP2), \whizard\ supports parallel execution via MPI by communicating between parallel tasks on a single machine or distributed over several machines. During integration the calculation of channels is distributed along several workers where a master worker collects the results and adapts weights and grids. In wortwhile cases (e.g. high number of calls in one channel), the calculation of a single grid is distributed. In order to use these advancements, \whizard\ requires an installed MPI-3.1 capable library (e.g. OpenMPI) and configuration and compilation with the appropriate flags, cf.~Sec.~\ref{sec:installation}. MPI support is only active when the integration method is set to VAMP2. Additionally, to preserve the numerical properties of a single task run, it is recommended to use the RNGstream as random number generator. \begin{code} $integration_method = 'vamp2' $rng_method = 'rng_stream' \end{code} \whizard\ has then to be called by mpirun \begin{footnotesize} \begin{Verbatim}[frame=single] your-workspace> mpirun -f hostfile -np 4 --output-filename mpi.log whizard your-input.sin \end{Verbatim} \end{footnotesize} where the number of parallel tasks can be set by \ttt{-np} and a hostfile can be given by \ttt{--hostfile}. It is recommended to use \ttt{--output-filename} which lets mpirun redirect the standard (error) output to a file, for each worker separatly. \subsubsection{Notes on Parallelization with MPI} The parallelization of \whizard\ requires that all instances of the parallel run be able to write and read all files by produced \whizard\ in a network file system as the current implementation does not handle parallel I/O. Usually, high-performance clusters have support for at least one network filesystem. Furthermore, not all functions of \whizard\ are currently supported or are only supported in a limited way in parallel mode. Currently the \verb|?rebuild_| for the phase space and the matrix element library are not yet available, as well as the calculation of matrix elements with resonance history. Some features that have been missing in the very first implementation of the parallelized integration have now been made available, like the support of run IDs and the parallelization of the event generation. A final remark on the stability of the numerical results in terms of the number of workers involved. Under certain circumstances, results between different numbers of workers but using otherwise an identical \sindarin\ file can lead to slightly numerically different (but statistically compatible) results for integration or event generation This is related to the execution of the computational operations in MPI, which we use to reduce results from all workers. If the order of the numbers in the arithmetical operations changes, for example, by different setups of the workers, then the numerical results change slightly, which in turn is amplified under the influence of the adaptation. Nevertheless, the results are all statistically consistent. \subsection{Stopping and Resuming WHIZARD Jobs} On a Unix-like system, it is possible to prematurely stop running jobs by a \ttt{kill(1)} command, or by entering \ttt{Ctrl-C} on the terminal. If the system supports this, \whizard\ traps these signals. It also traps some signals that a batch operating system might issue, e.g., for exceeding a predefined execution time limit. \whizard\ tries to complete the calculation of the current event and gracefully close open files. Then, the program terminates with a message and a nonzero return code. Usually, this should not take more than a fraction of a second. If, for any reason, the program does not respond to an interrupt, it is always possible to kill it by \ttt{kill -9}. A convenient method, on a terminal, would be to suspend it first by \ttt{Ctrl-Z} and then to kill the suspended process. The program is usually able to recover after being stopped. Simply run the job again from start, with the same input, all output files generated so far left untouched. The results obtained so far will be quickly recovered or gathered from files written in the previous run, and the actual time-consuming calculation is resumed near the point where it was interrupted.\footnote{This holds for simple workflow. In case of scans and repeated integrations of the same process, there may be name clashes on the written files which prevent resuming. A future \whizard\ version will address this problem.} If the interruption happened during an integration step, it is resumed after the last complete iteration. If it was during event generation, the previous events are taken from file and event generation is continued. The same mechanism allows for efficiently redoing a calculation with similar, somewhat modified input. For instance, you might want to add a further observable to event analysis, or write the events in a different format. The time for rerunning the program is determined just by the time it takes to read the existing integration or event files, and the additional calculation is done on the recovered information. By managing various checksums on its input and output files, \whizard\ detects changes that affect further calculations, so it does a real recalculation only where it is actually needed. This applies to all steps that are potentially time-consuming: matrix-element code generation, compilation, phase-space setup, integration, and event generation. If desired, you can set command-line options or \sindarin\ parameters that explicitly discard previously generated information. \subsection{Files and Directories: default and customization} \whizard\ jobs take a small set of files as input. In many cases, this is just a single \sindarin\ script provided by the user. When running, \whizard\ can produce a set of auxiliary and output files: \begin{enumerate} \item \textbf{Job.} Files pertaining to the \whizard\ job as a whole. This is the default log file \ttt{whizard.log}. \item \textbf{Process compilation.} Files that originate from generating and compiling process code. If the default \oMega\ generator is used, these files include Fortran source code as well as compiled libraries that are dynamically linked to the running executable. The file names are derived from either the process-library name or the individual process names, as defined in the \sindarin\ input. The default library name is \ttt{default\_lib}. \item \textbf{Integration.} Files that are created by integration, i.e., when calculating the total cross section for a scattering process using the Monte-Carlo algorithm. The file names are derived from the process name. \item \textbf{Simulation.} Files that are created during simulation, i.e., generating event samples for a process or a set of processes. By default, the file names are derived from the name of the first process. Event-file formats are distinguished by appropriate file name extensions. \item \textbf{Result Analysis.} Files that are created by the internal analysis tools and written by the command \ttt{write\_analysis} (or \ttt{compile\_analysis}). The default base name is \ttt{whizard\_analysis}. \end{enumerate} A complex workflow with several processes, parameter sets, or runs, can easily lead to in file-name clashes or a messy working directory. Furthermore, running a batch job on a dedicated computing environment often requires transferring data from a user directory to the server and back. Custom directory and file names can be used to organize things and facilitate dealing with the environment, along with the available batch-system tools for coordinating file transfer. \begin{enumerate} \item \textbf{Job.} \begin{itemize} \item The \ttt{-L} option on the command line defines a custom base name for the log file. \item The \ttt{-J} option on the command line defines a job ID. For instance, this may be set to the job ID assigned by the batch system. Within the \sindarin\ script, the job ID is available as the string variable \ttt{\$job\_id} and can be used for constructing custom job-specific file and directory names, as described below. \end{itemize} \item \textbf{Process compilation.} \begin{itemize} \item The user can require the program to put all files created during the compilation step including the library to be linked, in a subdirectory of the working directory. To enable this, set the string variable \ttt{\$compile\_workspace} within the \sindarin\ script. \end{itemize} \item \textbf{Integration.} \begin{itemize} \item The value of the string variable \ttt{\$run\_id}, if set, is appended to the base name of all files created by integration, separated by dots. If the \sindarin\ script scans over parameters, varying the run ID avoids repeatedly overwriting files with identical name during the scan. \item The user can require the program to put the important files created during the integration step -- the phase-space configuration file and the \vamp\ grid files -- in a subdirectory of the working directory. To enable this, set the string variable \ttt{\$integrate\_workspace} within the \sindarin\ script. (\ttt{\$compile\_workspace} and \ttt{\$integrate\_workspace} may be set to the same value.) \end{itemize} Log files produced during the integration step are put in the working directory. \item \textbf{Simulation.} \begin{itemize} \item The value of the string variable \ttt{\$run\_id}, if set, identifies the specific integration run that is used for the event sample. It is also inserted into default event-sample file names. \item The variable \ttt{\$sample}, if set, defines an arbitrary base name for the files related to the event sample. \end{itemize} Files resulting from simulation are put in the working directory. \item \textbf{Result Analysis.} \begin{itemize} \item The variable \ttt{\$out\_file}, if set, defines an arbitrary base name for the analysis data and auxiliary files. \end{itemize} Files resulting from result analysis are put in the working directory. \end{enumerate} \subsection{Batch jobs on a different machine} It is possible to separate the tasks of process-code compilation, integration, and simulation, and execute them on different machines. To make use of this feature, the local and remote machines including all installed libraries that are relevant for \whizard, must be binary-compatible. \begin{enumerate} \item Process-code compilation may be done once on a local machine, while the time-consuming tasks of integration and event generation for specific parameter sets are delegated to a remote machine, e.g., a batch cluster. To enable this, prepare a \sindarin\ script that just produces process code (i.e., terminates with a \ttt{compile} command) for the local machine. You may define \ttt{\$compile\_workspace} such that all generated code conveniently ends up in a single subdirectory. To start the batch job, transfer the workspace subdirectory to the remote machine and start \whizard\ there. The \sindarin\ script on the remote machine must include the local script unchanged in all parts that are relevant for process definition. The program will recognize the contents of the workspace, skip compilation and instead link the process library immediately. To proceed further, the script should define the run-specific parameters and contain the appropriate commands for integration and simulation. \item Analogously, you may execute both process-code compilation and integration locally, but generate event samples on a remote machine. To this end, prepare a \sindarin\ script that produces process code and computes integrals (i.e., terminates with an \ttt{integrate} command) for the local machine. You may define \ttt{\$compile\_workspace} and \ttt{\$integrate\_workspace} (which may coincide) such that all generated code, phase-space and integration grid data conveniently end up in subdirectories. To start the batch job, transfer the workspace(s) to the remote machine and start \whizard\ there. The \sindarin\ script on the remote machine must include the local script unchanged in all parts that are relevant for process definition and integration. The program will recognize the contents of the workspace, skip compilation and integration and instead load the process library and integration results immediately. To proceed further, the script should define the sample-specific parameters and contain the appropriate commands for simulation. \end{enumerate} To simplify transferring whole directories, \whizard\ supports the \ttt{--pack} and \ttt{--unpack} options. You may specify any number of these options for a \whizard\ run. (The feature relies on the GNU version of the \ttt{tar} utility.) For instance, \begin{code} whizard script1.sin --pack my_ws \end{code} runs \whizard\ with the \sindarin\ script \ttt{script1.sin} as input, where within the script you have defined \begin{code} $compile_workspace = "my_ws" \end{code} as the target directory for process-compilation files. After completion, the program will tar and gzip the target directory as \ttt{my\_ws.tgz}. You should copy this file to the remote machine as one of the job's input files. On the remote machine, you can then run the program with \begin{code} whizard script2.sin --unpack my_ws.tgz \end{code} where \ttt{script2.sin} should include \ttt{script1.sin}, and add integration or simulation commands. The contents of \ttt{ws.tgz} will thus be unpacked and reused on the remote machine, instead of generating new process code. \subsection{Static Linkage} In its default running mode, \whizard\ compiles process-specific matrix element code on the fly and dynamically links the resulting library. On the computing server, this requires availability of the appropriate Fortran compiler, as well as the \ocaml\ compiler suite, and the dynamical linking feature. Since this may be unavailable or undesired, there is a possibility to distribute \whizard\ as a statically linked executable that contains a pre-compiled library of processes. This removes the need for the Fortran compiler, the \ocaml\ system, and extra dynamic linking. Any external libraries that are accessed (the \fortran\ runtime environment, and possibly some dynamically linked external libraries and/or the C++ runtime library, must still be available on the target system, binary-compatible. Otherwise, there is no need for transferring the complete \whizard\ installation or process-code compilation data. Generating, compiling and linking matrix element code is done in advance on a machine that can access the required tools and produces compatible libraries. This procedure is accomplished by \sindarin\ commands, explained below in Sec.~\ref{sec:static}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newpage \section{Troubleshooting} \label{sec:troubleshooting} In this section, we list known issues or problems and give advice on what can be done in case something does not work as intended. \subsection{Possible (uncommon) build problems} \label{sec:buildproblems} \subsubsection{\ocaml\ versions and \oMega\ builds} For the matrix element generator \oMega\ of \whizard\, the functional programming language \ocaml\ is used. Unfortunately, the versions of the \ocaml\ compiler from 3.12.0 on broke backwards compatibility. Therefore, versions of \oMega/\whizard\ up to v2.0.2 only compile with older versions (3.04 to 3.11 works). This has been fixed in all \whizard\ versions from 2.0.3 on. \subsubsection{Identical Build and Source directories} There is a problem that only occurred with version 2.0.0 and has been corected for all follow-up versions. It can only appear if you compile the \whizard\ sources in the source directory. Then an error like this may occur: \begin{footnotesize} \begin{Verbatim}[frame=single] ... libtool: compile: gfortran -I../misc -I../vamp -g -O2 -c processes.f90 -fPIC -o .libs/processes.o libtool: compile: gfortran -I../misc -I../vamp -g -O2 -c processes.f90 -o processes.o >/dev/null 2>&1 make[2]: *** No rule to make target `limits.lo', needed by `decays.lo'. Stop. ... make: *** [all-recursive] Error 1 \end{Verbatim} \end{footnotesize} In this case, please unpack a fresh copy of \whizard\ and configure it in a separate directory (not necessarily a subdirectory). Then the compilation will go through: \begin{footnotesize} \begin{Verbatim}[frame=single] $ zcat whizard-2.0.0.tar.gz | tar xf - $ cd whizard-2.0.0 $ mkdir _build $ cd _build $ ../configure FC=gfortran $ make \end{Verbatim} \end{footnotesize} The developers use this setup to be able to test different compilers. Therefore building in the same directory is not as thoroughly tested. This behavior has been patched from version 2.0.1 on. But note that in general it is always adviced to keep build and source directory apart from each other. %%%%% \subsection{What happens if \whizard\ throws an error?} \label{ref:errors} \subsubsection{Particle name special characters in process declarations} Trying to use a process declaration like \begin{code} process foo = e-, e+ => mu-, mu+ \end{code} will lead to a \sindarin\ syntax error: \begin{Code} process foo = e-, e+ => mu-, mu+ ^^ | Expected syntax: SEQUENCE = process '=' "mu-", "mu+"}. \subsubsection{Missing collider energy} This happens if you forgot to set the collider energy in the integration of a scattering process: \begin{Code} ****************************************************************************** ****************************************************************************** *** FATAL ERROR: Colliding beams: sqrts is zero (please set sqrts) ****************************************************************************** ****************************************************************************** \end{Code} This will solve your problem: \begin{code} sqrts = \end{code} \subsubsection{Missing process declaration} If you try to integrate or simulate a process that has not declared before (and is also not available in a library that might be loaded), \whizard\ will complain: \begin{Code} ****************************************************************************** ****************************************************************************** *** FATAL ERROR: Process library doesn't contain process 'f00' ****************************************************************************** ****************************************************************************** \end{Code} Note that this could sometimes be a simple typo, e.g. in that case an \ttt{integrate (f00)} instead of \ttt{integrate (foo)} \subsubsection{Ambiguous initial state without beam declaration} When the user declares a process with a flavor sum in the initial state, e.g. \begin{code} process qqaa = u:d, U:D => A, A sqrts = integrate (qqaa) \end{code} then a fatal error will be issued: \begin{Code} ****************************************************************************** ****************************************************************************** *** FATAL ERROR: Setting up process 'qqaa': *** -------------------------------------------- *** Inconsistent initial state. This happens if either *** several processes with non-matching initial states *** have been added, or for a single process with an *** initial state flavor sum. In that case, please set beams *** explicitly [singling out a flavor / structure function.] ****************************************************************************** ****************************************************************************** \end{Code} What now? Either a structure function providing a tensor structure in flavors has to be provided like \begin{code} beams = p, pbar => pdf_builtin \end{code} or, if the partonic process was intended, a specific flavor has to be singled out, \begin{code} beams = u, U \end{code} which would take only the up-quarks. Note that a sum over process components with varying initial states is not possible. \subsubsection{Invalid or unsupported beam structure} An error message like \begin{Code} ****************************************************************************** ****************************************************************************** *** FATAL ERROR: Beam structure: [.......] not supported ****************************************************************************** ****************************************************************************** \end{Code} This happens if you try to use a beam structure with is either not supported by \whizard\ (meaning that there is no phase-space parameterization for Monte-Carlo integration available in order to allow an efficient sampling), or you have chosen a combination of beam structure functions that do not make sense physically. Here is an example for the latter (lepton collider ISR applied to protons, then proton PDFs): \begin{code} beams = p, p => isr => pdf_builtin \end{code} \subsubsection{Mismatch in beams} Sometimes you get a rather long error output statement followed by a fatal error: \begin{Code} Evaluator product First interaction Interaction: 6 Virtual: Particle 1 [momentum undefined] [.......] State matrix: norm = 1.000000000000E+00 [f(2212)] [f(11)] [f(92) c(1 )] [f(-6) c(-1 )] => ME(1) = ( 0.000000000000E+00, 0.000000000000E+00) [.......] ****************************************************************************** ****************************************************************************** *** FATAL ERROR: Product of density matrices is empty *** -------------------------------------------- *** This happens when two density matrices are convoluted *** but the processes they belong to (e.g., production *** and decay) do not match. This could happen if the *** beam specification does not match the hard *** process. Or it may indicate a WHIZARD bug. ****************************************************************************** ****************************************************************************** \end{Code} As \whizard\ indicates, this could have happened because the hard process setup did not match the specification of the beams as in: \begin{code} process neutral_current_DIS = e1, u => e1, u beams_momentum = 27.5 GeV, 920 GeV beams = p, e => pdf_builtin, none integrate (neutral_current_DIS) \end{code} In that case, the order of the beam particles simply was wrong, exchange proton and electron (together with the structure functions) into \ttt{beams = e, p => none, pdf\_builtin}, and \whizard\ will be happy. \subsubsection{Unstable heavy beam particles} If you try to use unstable particles as beams that can potentially decay into the final state particles, you might encounter the following error message: \begin{Code} ****************************************************************************** ****************************************************************************** *** FATAL ERROR: Phase space: Initial beam particle can decay ****************************************************************************** ****************************************************************************** \end{Code} This happens basically only for processes in testing/validation (like $t \bar t \to b \bar b$). In principle, it could also happen in a real physics setup, e.g. when simulating electron pairs at a muon collider: \begin{code} process mmee = "mu-", "mu+" => "e-", "e+" \end{code} However, \whizard\ at the moment does not allow a muon width, and so \whizard\ is not able to decay a muon in a scattering process. A possibile decay of the beam particle into (part of) the final state might lead to instabilities in the phase space setup. Hence, \whizard\ do not let you perform such an integration right away. When you nevertheless encounter such a rare occasion in your setup, there is a possibility to convert this fatal error into a simple warning by setting the flag: \begin{code} ?fatal_beam_decay = false \end{code} \subsubsection{Impossible beam polarization} If you specify a beam polarization that cannot correspond to any physically allowed spin density matrix, e.g., \begin{code} beams = e1, E1 beams_pol_density = @(-1), @(1:1:.5, -1, 1:-1) \end{code} \whizard\ will throw a fatal error like this: \begin{Code} Trace of matrix square = 1.4444444444444444 Polarization: spin density matrix spin type = 2 multiplicity = 2 massive = F chirality = 0 pol.degree = 1.0000000 pure state = F @(+1: +1: ( 3.333333333333E-01, 0.000000000000E+00)) @(-1: -1: ( 6.666666666667E-01, 0.000000000000E+00)) @(-1: +1: ( 6.666666666667E-01, 0.000000000000E+00)) ****************************************************************************** ****************************************************************************** *** FATAL ERROR: Spin density matrix: not permissible as density matrix ****************************************************************************** ****************************************************************************** \end{Code} \subsubsection{Beams with crossing angle} Specifying a crossing angle (e.g. at a linear lepton collider) without explicitly setting the beam momenta, \begin{code} sqrts = 1 TeV beams = e1, E1 beams\_theta = 0, 10 degree \end{code} triggers a fatal: \begin{Code} ****************************************************************************** ****************************************************************************** *** FATAL ERROR: Beam structure: angle theta/phi specified but momentum/a p undefined ****************************************************************************** ****************************************************************************** \end{Code} In that case the single beam momenta have to be explicitly set: \begin{code} beams = e1, E1 beams\_momentum = 500 GeV, 500 GeV beams\_theta = 0, 10 degree \end{code} \subsubsection{Phase-space generation failed} Sometimes an error might be issued that \whizard\ could not generate a valid phase-space parameterization: \begin{Code} | Phase space: ... failed. Increasing phs_off_shell ... | Phase space: ... failed. Increasing phs_off_shell ... | Phase space: ... failed. Increasing phs_off_shell ... | Phase space: ... failed. Increasing phs_off_shell ... ****************************************************************************** ****************************************************************************** *** FATAL ERROR: Phase-space: generation failed ****************************************************************************** ****************************************************************************** \end{Code} You see that \whizard\ tried to increase the number of off-shell lines that are taken into account for the phase-space setup. The second most important parameter for the phase-space setup, \ttt{phs\_t\_channel}, however, is not increased automatically. Its default value is $6$, so e.g. for the process $e^+ e^- \to 8\gamma$ you will run into the problem above. Setting \begin{code} phs_off_shell = -1 \end{code} where \ttt{} is the number of final-state particles will solve the problem. \subsubsection{Non-converging process integration} There could be several reasons for this to happen. The most prominent one is that no cuts have been specified for the process (\whizard\ttt{2} does not apply default cuts), and there are singular regions in the phase space over which the integration stumbles. If cuts have been specified, it could be that they are not sufficient. E.g. in $pp \to jj$ a distance cut between the two jets prevents singular collinear splitting in their generation, but if no $p_T$ cut have been set, there is still singular collinear splitting from the beams. \subsubsection{Why is there no event file?} If no event file has been generated, \whizard\ stumled over some error and should have told you, or, you simply forgot to set a \ttt{simulate} command for your process. In case there was a \ttt{simulate} command but the process under consideration is not possible (e.g. a typo, \ttt{e1, E1 => e2, E3} instead of \ttt{e1, E1 => e3, E3}), then you get an error like that: \begin{Code} ****************************************************************************** *** ERROR: Simulate: no process has a valid matrix element. ****************************************************************************** \end{Code} \subsubsection{Why is the event file empty?} In order to get events, you need to set either a desired number of events: \begin{code} n_events = \end{code} or you have to specify a certain integrated luminosity (the default unit being inverse femtobarn: \begin{code} luminosity = / 1 fbarn \end{code} In case you set both, \whizard\ will take the one that leads to the higher number of events. \subsubsection{Parton showering fails} For BSM models containing massive stable or long-lived particles parton showering with \pythiasix\ fails: \begin{Code} Advisory warning type 3 given after 0 PYEXEC calls: (PYRESD:) Failed to decay particle 1000022 with mass 15.000 ****************************************************************************** ****************************************************************************** *** FATAL ERROR: Simulation: failed to generate valid event after 10000 tries ****************************************************************************** ****************************************************************************** \end{Code} The solution to that problem is discussed in Sec.~\ref{sec:pythia6}. \vspace{1cm} %%%%% \subsection{Debugging, testing, and validation} \subsubsection{Catching/tracking arithmetic exceptions} Catching arithmetic exceptions is not automatically supported by \fortran\ compilers. In general, flags that cause the compiler to keep track of arithmetic exceptions are diminishing the maximally possible performance, and hence they should not be used in production runs. Hence, we refrained from making these flags a default. They can be added using the \ttt{FCFLAGS = {\em }} settings during configuration. For the \ttt{NAG} \fortran\ compiler we use the flags \ttt{-C=all -nan -gline} for debugging purposes. For the \ttt{gfortran} compilers, the flags \ttt{-ffpe-trap=invalid,zero,overflow} are the corresponding debugging flags. For tests, debugging or first sanity checks on your setup, you might want to make use of these flags in order to track possible numerical exceptions in the produced code. Some compilers started to include \ttt{IEEE} exception handling support (\ttt{Fortran 2008} status), but we do not use these implementations in the \whizard\ code (yet). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Steering WHIZARD: \sindarin\ Overview} \label{chap:sindarinintro} \section{The command language for WHIZARD} A conventional physics application program gets its data from a set of input files. Alternatively, it is called as a library, so the user has to write his own code to interface it, or it combines these two approaches. \whizard~1 was built in this way: there were some input files which were written by the user, and it could be called both stand-alone or as an external library. \whizard~2 is also a stand-alone program. It comes with its own full-fledged script language, called \sindarin. All interaction between the user and the program is done in \sindarin\ expressions, commands, and scripts. Two main reasons led us to this choice: \begin{itemize} \item In any nontrivial physics study, cuts and (parton- or hadron-level) analysis are of central importance. The task of specifying appropriate kinematics and particle selection for a given process is well defined, but it is impossible to cover all possiblities in a simple format like the cut files of \whizard~1. The usual way of dealing with this problem is to write analysis driver code (often in \ttt{C++}), using external libraries for Lorentz algebra etc. However, the overhead of writing correct \ttt{C++} or \ttt{Fortran} greatly blows up problems that could be formulated in a few lines of text. \item While many problems lead to a repetitive workflow (process definition, integration, simulation), there are more involved tasks that involve parameter scans, comparisons of different processes, conditional execution, or writing output in widely different formats. This is easily done by a steering script, which should be formulated in a complete language. \end{itemize} The \sindarin\ language is built specifically around event analysis, suitably extended to support steering, including data types, loops, conditionals, and I/O. It would have been possible to use an established general-purpose language for these tasks. For instance, \ocaml\ which is a functional language would be a suitable candidate, and the matrix-element generator \oMega\ is written in that language. Another candidate would be a popular scripting language such as PYTHON. We started to support interfaces for commonly used languages: prime examples for \ttt{C}, \ttt{C++}, and PYTHON are found in the \ttt{share/interfaces} subdirectory. However, introducing a special-purpose language has the three distinct advantages: First, it is compiled and executed by the very \ttt{Fortran} code that handles data and thus accesses it without interfaces. Second, it can be designed with a syntax especially suited to the task of event handling and Monte-Carlo steering, and third, the user is not forced to learn all those features of a generic language that are of no relevance to the application he/she is interested in. \section{\sindarin\ scripts} A \sindarin\ script tells the \whizard\ program what it has to do. Typically, the script is contained in a file which you (the user) create. The file name is arbitrary; by convention, it has the extension `\verb|.sin|'. \whizard\ takes the file name as its argument on the command line and executes the contained script: \begin{verbatim} /home/user$ whizard script.sin \end{verbatim} Alternatively, you can call \whizard\ interactively and execute statements line by line; we describe this below in Sec.\ref{sec:whish}. A \sindarin\ script is a sequence of \emph{statements}, similar to the statements in any imperative language such as \ttt{Fortran} or \ttt{C}. Examples of statements are commands like \ttt{integrate}, variable declarations like \ttt{logical ?flag} or assigments like \ttt{mH = 130 GeV}. The script is free-form, i.e., indentation, extra whitespace and newlines are syntactically insignificant. In contrast to most languages, there is no statement separator. Statements simply follow each other, just separated by whitespace. \begin{code} statement1 statement2 statement3 statement4 \end{code} Nevertheless, for clarity we recommend to write one statement per line where possible, and to use proper indentation for longer statements, nested and bracketed expressions. A command may consist of a \emph{keyword}, a list of \emph{arguments} in parantheses \ttt{(}\ldots\ttt{)}, and an \emph{option} script which itself is a sequence of statements. \begin{code} command command_with_args (arg1, arg2) command_with_option { option } command_with_options (arg) { option_statement1 option_statement2 } \end{code} As a rule, parentheses \ttt{()} enclose arguments and expressions, as you would expect. Arguments enclosed in square brackets \ttt{[]} also exist. They have a special meaning, they denote subevents (collections of momenta) in event analysis. Braces \ttt{\{\}} enclose blocks of \sindarin\ code. In particular, the option script associated with a command is a block of code that may contain local parameter settings, for instance. Braces always indicate a scoping unit, so parameters will be restored their previous values when the execution of that command is completed. The script can contain comments. Comments are initiated by either a \verb|#| or a \verb|!| character and extend to the end of the current line. \begin{code} statement # This is a comment statement ! This is also a comment \end{code} %%%%%%%%%%%%%%% \section{Errors} \label{sec:errors} Before turning to proper \sindarin\ syntax, let us consider error messages. \sindarin\ distinguishes syntax errors and runtime errors. Syntax errors are recognized when the script is read and compiled, before any part is executed. Look at this example: \begin{code} process foo = u, ubar => d, dbar md = 10 integrade (foo) \end{code} \whizard\ will fail with the error message \begin{interaction} sqrts = 1 TeV integrade (foo) ^^ | Expected syntax: SEQUENCE = '=' | Found token: KEYWORD: '(' ****************************************************************************** ****************************************************************************** *** FATAL ERROR: Syntax error (at or before the location indicated above) ****************************************************************************** ****************************************************************************** WHIZARD run aborted. \end{interaction} which tells you that you have misspelled the command \verb|integrate|, so the compiler tried to interpret it as a variable. Runtime errors are categorized by their severity. A warning is simply printed: \begin{interaction} Warning: No cuts have been defined. \end{interaction} This indicates a condition that is suspicious, but may actually be intended by the user. When an error is encountered, it is printed with more emphasis \begin{interaction} ****************************************************************************** *** ERROR: Variable 'md' set without declaration ****************************************************************************** \end{interaction} and the program tries to continue. However, this usually indicates that there is something wrong. (The $d$ quark is defined massless, so \verb|md| is not a model parameter.) \whizard\ counts errors and warnings and tells you at the end \begin{interaction} | There were 1 error(s) and no warnings. \end{interaction} just in case you missed the message. Other errors are considered fatal, and execution stops at this point. \begin{interaction} ****************************************************************************** ****************************************************************************** *** FATAL ERROR: Colliding beams: sqrts is zero (please set sqrts) ****************************************************************************** ****************************************************************************** \end{interaction} Here, \whizard\ was unable to do anything sensible. But at least (in this case) it told the user what to do to resolve the problem. %%%%%%%%%%%%%%% \section{Statements} \label{sec:statements} \sindarin\ statements are executed one by one. For an overview, we list the most common statements in the order in which they typically appear in a \sindarin\ script, and quote the basic syntax and simple examples. This should give an impression on the \whizard's capabilities and on the user interface. The list is not complete. Note that there are no mandatory commands (although an empty \sindarin\ script is not really useful). The details and options are explained in later sections. \subsection{Process Configuration} \subsubsection{model} \begin{syntax} model = \var{model-name} \end{syntax} This assignment sets or resets the current physics model. The Standard Model is already preloaded, so the \ttt{model} assignment applies to non-default models. Obviously, the model must be known to \whizard. Example: \begin{code} model = MSSM \end{code} See Sec.~\ref{sec:models}. \subsubsection{alias} \begin{syntax} alias \var{alias-name} = \var{alias-definition} \end{syntax} Particles are specified by their names. For most particles, there are various equivalent names. Names containing special characters such as a \verb|+| sign have to be quoted. The \ttt{alias} assignment defines an alias for a list of particles. This is useful for setting up processes with sums over flavors, cut expressions, and more. The alias name is then used like a simple particle name. Example: \begin{syntax} alias jet = u:d:s:U:D:S:g \end{syntax} See Sec.~\ref{sec:alias}. \subsubsection{process} \begin{syntax} process \var{tag} = \var{incoming} \verb|=>| \var{outgoing} \end{syntax} Define a process. You give the process a name \var{tag} by which it is identified later, and specify the incoming and outgoing particles, and possibly options. You can define an arbitrary number of processes as long as they are distinguished by their names. Example: \begin{code} process w_plus_jets = g, g => "W+", jet, jet \end{code} See Sec.~\ref{sec:processes}. \subsubsection{sqrts} \begin{syntax} sqrts = \var{energy-value} \end{syntax} Define the center-of-mass energy for collision processes. The default setup will assume head-on central collisions of two beams. Example: \begin{code} sqrts = 500 GeV \end{code} See Sec.~\ref{sec:beam-setup}. \subsubsection{beams} \begin{syntax} beams = \var{beam-particles} \\ beams = \var{beam-particles} => \var{structure-function-setup} \end{syntax} Declare beam particles and properties. The current value of \ttt{sqrts} is used, unless specified otherwise. Example: \begin{code} beams = u:d:s, U:D:S => lhapdf \end{code} With options, the assignment allows for defining beam structure in some detail. This includes beamstrahlung and ISR for lepton colliders, precise structure function definition for hadron colliders, asymmetric beams, beam polarization, and more. See Sec.~\ref{sec:beams}. \subsection{Parameters} \subsubsection{Parameter settings} \begin{syntax} \var{parameter} = \var{value} \\ \var{type} \var{user-parameter} \\ \var{type} \var{user-parameter} = \var{value} \end{syntax} Specify a value for a parameter. There are predefined parameters that affect the behavior of a command, model-specific parameters (masses, couplings), and user-defined parameters. The latter have to be declared with a type, which may be \ttt{int} (integer), \ttt{real}, \ttt{complex}, \ttt{logical}, \ttt{string}, or \ttt{alias}. Logical parameter names begin with a question mark, string parameter names with a dollar sign. Examples: \begin{code} mb = 4.2 GeV ?rebuild_grids = true real mass_sum = mZ + mW string $message = "This is a string" \end{code} % $ The value need not be a literal, it can be an arbitrary expression of the correct type. See Sec.~\ref{sec:variables}. \subsubsection{read\_slha} \begin{syntax} read\_slha (\var{filename}) \end{syntax} This is useful only for supersymmetric models: read a parameter file in the SUSY Les Houches Accord format. The file defines parameter values and, optionally, decay widths, so this command removes the need for writing assignments for each of them. \begin{code} read_slha ("sps1a.slha") \end{code} See Sec.~\ref{sec:slha}. \subsubsection{show} \begin{syntax} show (\var{data-objects}) \end{syntax} Print the current value of some data object. This includes not just variables, but also models, libraries, cuts, etc. This is rather a debugging aid, so don't expect the output to be concise in the latter cases. Example: \begin{code} show (mH, wH) \end{code} See Sec.~\ref{sec:I/O}. \subsubsection{printf} \begin{syntax} printf \var{format-string} (\var{data-objects}) \end{syntax} Pretty-print the data objects according to the given format string. If there are no data objects, just print the format string. This command is borrowed from the \ttt{C} programming language; it is actually an interface to the system's \ttt{printf(3)} function. The conversion specifiers are restricted to \ttt{d,i,e,f,g,s}, corresponding to the output of integer, real, and string variables. Example: \begin{code} printf "The Higgs mass is %f GeV" (mH) \end{code} See Sec.~\ref{sec:I/O}. \subsection{Integration} \subsubsection{cuts} \begin{syntax} cuts = \var{logical-cut-expression} \end{syntax} The cut expression is a logical macro expression that is evaluated for each phase space point during integration and event generation. You may construct expressions out of various observables that are computed for the (partonic) particle content of the current event. If the expression evaluates to \verb|true|, the matrix element is calculated and the event is used. If it evaluates to \verb|false|, the matrix element is set zero and the event is discarded. Note that for collisions the expression is evaluated in the lab frame, while for decays it is evaluated in the rest frame of the decaying particle. In case you want to impose cuts on a factorized process, i.e. a combination of a production process and one or more decay processes, you have to use the \ttt{selection} keyword instead. Example for the keyword \ttt{cuts}: \begin{code} cuts = all Pt > 20 GeV [jet] and all mZ - 10 GeV < M < mZ + 10 GeV [lepton, lepton] and no abs (Eta) < 2 [jet] \end{code} See Sec.~\ref{sec:cuts}. \subsubsection{integrate} \begin{syntax} integrate (\var{process-tags}) \end{syntax} Compute the total cross section for a process. The command takes into account the definition of the process, the beam setup, cuts, and parameters as defined in the script. Parameters may also be specified as options to the command. Integration is necessary for each process for which you want to know total or differential cross sections, or event samples. Apart from computing a value, it sets up and adapts phase space and integration grids that are used in event generation. If you just need an event sample, you can omit an explicit \ttt{integrate} command; the \ttt{simulate} command will call it automatically. Example: \begin{code} integrate (w_plus_jets, z_plus_jets) \end{code} See Sec.~\ref{sec:integrate}. \subsubsection{?phs\_only/n\_calls\_test} \begin{syntax} integrate (\var{process-tag}) \{ ?phs\_only = true n\_calls\_test = 1000 \} \end{syntax} These are just optional settings for the \ttt{integrate} command discussed just a second ago. The \ttt{?phs\_only = true} (note that variables starting with a question mark are logicals) option tells \whizard\ to prepare a process for integration, but instead of performing the integration, just to generate a phase space parameterization. \ttt{n\_calls\_test = } evaluates the sampling function for random integration channels and random momenta. \vamp\ integration grids are neither generated nor used, so the channel selection corresponds to the first integration pass, before any grids or channel weights are adapted. The number of sampling points is given by \verb||. The output contains information about the timing, number of sampling points that passed the kinematics selection, and the number of matrix-element values that were actually evaluated. This command is useful mainly for debugging and diagnostics. Example: \begin{code} integrate (some_large_process) { ?phs_only = true n_calls_test = 1000 } \end{code} (Note that there used to be a separate command \ttt{matrix\_element\_test} until version 2.1.1 of \whizard\ which has been discarded in order to simplify the \sindarin\ syntax.) \subsection{Events} \subsubsection{histogram} \begin{syntax} histogram \var{tag} (\var{lower-bound}, \var{upper-bound}) \\ histogram \var{tag} (\var{lower-bound}, \var{upper-bound}, \var{step}) \\ \end{syntax} Declare a histogram for event analysis. The histogram is filled by an analysis expression, which is evaluated once for each event during a subsequent simulation step. Example: \begin{code} histogram pt_distribution (0, 150 GeV, 10 GeV) \end{code} See Sec.~\ref{sec:histogram}. \subsubsection{plot} \begin{syntax} plot \var{tag} \end{syntax} Declare a plot for displaying data points. The plot may be filled by an analysis expression that is evaluated for each event; this would result in a scatter plot. More likely, you will use this feature for displaying data such as the energy dependence of a cross section. Example: \begin{code} plot total_cross_section \end{code} See Sec.~\ref{sec:plot}. \subsubsection{selection} \begin{syntax} selection = \var{selection-expression} \end{syntax} The selection expression is a logical macro expression that is evaluated once for each event. It is applied to the event record, after all decays have been executed (if any). It is therefore intended e.g. for modelling detector acceptance cuts etc. For unfactorized processes the usage of \ttt{cuts} or \ttt{selection} leads to the same results. Events for which the selection expression evaluates to false are dropped; they are neither analyzed nor written to any user-defined output file. However, the dropped events are written to \whizard's native event file. For unfactorized processes it is therefore preferable to implement all cuts using the \ttt{cuts} keyword for the integration, see \ttt{cuts} above. Example: \begin{code} selection = all Pt > 50 GeV [lepton] \end{code} The syntax is generically the same as for the \ttt{cuts expression}, see Sec.~\ref{sec:cuts}. For more information see also Sec.~\ref{sec:analysis}. \subsubsection{analysis} \begin{syntax} analysis = \var{analysis-expression} \end{syntax} The analysis expression is a logical macro expression that is evaluated once for each event that passes the integration and selection cuts in a subsequent simulation step. The expression has type logical in analogy with the cut expression; however, its main use will be in side effects caused by embedded \ttt{record} expressions. The \ttt{record} expression books a value, calculated from observables evaluated for the current event, in one of the predefined histograms or plots. Example: \begin{code} analysis = record pt_distribution (eval Pt [photon]) and record mval (eval M [lepton, lepton]) \end{code} See Sec.~\ref{sec:analysis}. \subsubsection{unstable} \begin{syntax} unstable \var{particle} (\var{decay-channels}) \end{syntax} Specify that a particle can decay, if it occurs in the final state of a subsequent simulation step. (In the integration step, all final-state particles are considered stable.) The decay channels are processes which should have been declared before by a \ttt{process} command (alternatively, there are options that \whizard\ takes care of this automatically; cf. Sec.~\ref{sec:decays}). They may be integrated explicitly, otherwise the \ttt{unstable} command will take care of the integration before particle decays are generated. Example: \begin{code} unstable Z (z_ee, z_jj) \end{code} Note that the decay is an on-shell approximation. Alternatively, \whizard\ is capable of generating the final state(s) directly, automatically including the particle as an internal resonance together with irreducible background. Depending on the physical problem and on the complexity of the matrix-element calculation, either option may be more appropriate. See Sec.~\ref{sec:decays}. \subsubsection{n\_events} \begin{syntax} n\_events = \var{integer} \end{syntax} Specify the number of events that a subsequent simulation step should produce. By default, simulated events are unweighted. (Unweighting is done by a rejection operation on weighted events, so the usual caveats on event unweighting by a numerical Monte-Carlo generator do apply.) Example: \begin{code} n_events = 20000 \end{code} See Sec.~\ref{sec:simulation}. \subsubsection{simulate} \begin{syntax} simulate (\var{process-tags}) \end{syntax} Generate an event sample. The command allows for analyzing the generated events by the \ttt{analysis} expression. Furthermore, events can be written to file in various formats. Optionally, the partonic events can be showered and hadronized, partly using included external (\pythia) or truly external programs called by \whizard. Example: \begin{code} simulate (w_plus_jets) { sample_format = lhef } \end{code} See Sec.~\ref{sec:simulation} and Chapter~\ref{chap:events}. \subsubsection{graph} \begin{syntax} graph (\var{tag}) = \var{histograms-and-plots} \end{syntax} Combine existing histograms and plots into a common graph. Also useful for pretty-printing single histograms or plots. Example: \begin{code} graph comparison { $title = "$p_T$ distribution for two different values of $m_h$" } = hist1 & hist2 \end{code} % $ See Sec.~\ref{sec:graphs}. \subsubsection{write\_analysis} \begin{syntax} write\_analysis (\var{analysis-objects}) \end{syntax} Writes out data tables for the specified analysis objects (plots, graphs, histograms). If the argument is empty or absent, write all analysis objects currently available. The tables are available for feeding external programs. Example: \begin{code} write_analysis \end{code} See Sec.~\ref{sec:analysis}. \subsubsection{compile\_analysis} \begin{syntax} compile\_analysis (\var{analysis-objects}) \end{syntax} Analogous to \ttt{write\_analysis}, but the generated data tables are processed by \LaTeX\ and \gamelan, which produces Postscript and PDF versions of the displayed data. Example: \begin{code} compile_analysis \end{code} See Sec.~\ref{sec:analysis}. \section{Control Structures} Like any complete programming language, \sindarin\ provides means for branching and looping the program flow. \subsection{Conditionals} \subsubsection{if} \begin{syntax} if \var{logical\_expression} then \var{statements} \\ elsif \var{logical\_expression} then \var{statements} \\ else \var{statements} \\ endif \end{syntax} Execute statements conditionally, depending on the value of a logical expression. There may be none or multiple \ttt{elsif} branches, and the \ttt{else} branch is also optional. Example: \begin{code} if (sqrts > 2 * mtop) then integrate (top_pair_production) else printf "Top pair production is not possible" endif \end{code} The current \sindarin\ implementation puts some restriction on the statements that can appear in a conditional. For instance, process definitions must be done unconditionally. \subsection{Loops} \subsubsection{scan} \begin{syntax} scan \var{variable} = (\var{value-list}) \{ \var{statements} \} \end{syntax} Execute the statements repeatedly, once for each value of the scan variable. The statements are executed in a local context, analogous to the option statement list for commands. The value list is a comma-separated list of expressions, where each item evaluates to the value that is assigned to \ttt{\var{variable}} for this iteration. The type of the variable is not restricted to numeric, scans can be done for various object types. For instance, here is a scan over strings: \begin{code} scan string $str = ("%.3g", "%.4g", "%.5g") { printf $str (mW) } \end{code} % $ The output: \begin{interaction} [user variable] $str = "%.3g" 80.4 [user variable] $str = "%.4g" 80.42 [user variable] $str = "%.5g" 80.419 \end{interaction} % $ For a numeric scan variable in particular, there are iterators that implement the usual functionality of \ttt{for} loops. If the scan variable is of type integer, an iterator may take one of the forms \begin{syntax} \var{start-value} \verb|=>| \var{end-value} \\ \var{start-value} \verb|=>| \var{end-value} \verb|/+| \var{add-step} \\ \var{start-value} \verb|=>| \var{end-value} \verb|/-| \var{subtract-step} \\ \var{start-value} \verb|=>| \var{end-value} \verb|/*| \var{multiplicator} \\ \var{start-value} \verb|=>| \var{end-value} \verb|//| \var{divisor} \\ \end{syntax} The iterator can be put in place of an expression in the \ttt{\var{value-list}}. Here is an example: \begin{code} scan int i = (1, (3 => 5), (10 => 20 /+ 4)) \end{code} which results in the output \begin{interaction} [user variable] i = 1 [user variable] i = 3 [user variable] i = 4 [user variable] i = 5 [user variable] i = 10 [user variable] i = 14 [user variable] i = 18 \end{interaction} [Note that the \ttt{\var{statements}} part of the scan construct may be empty or absent.] For real scan variables, there are even more possibilities for iterators: \begin{syntax} \var{start-value} \verb|=>| \var{end-value} \\ \var{start-value} \verb|=>| \var{end-value} \verb|/+| \var{add-step} \\ \var{start-value} \verb|=>| \var{end-value} \verb|/-| \var{subtract-step} \\ \var{start-value} \verb|=>| \var{end-value} \verb|/*| \var{multiplicator} \\ \var{start-value} \verb|=>| \var{end-value} \verb|//| \var{divisor} \\ \var{start-value} \verb|=>| \var{end-value} \verb|/+/| \var{n-points-linear} \\ \var{start-value} \verb|=>| \var{end-value} \verb|/*/| \var{n-points-logarithmic} \\ \end{syntax} The first variant is equivalent to \ttt{/+ 1}. The \ttt{/+} and \ttt{/-} operators are intended to add or subtract the given step once for each iteration. Since in floating-point arithmetic this would be plagued by rounding ambiguities, the actual implementation first determines the (integer) number of iterations from the provided step value, then recomputes the step so that the iterations are evenly spaced with the first and last value included. The \ttt{/*} and \ttt{//} operators are analogous. Here, the initial value is intended to be multiplied by the step value once for each iteration. After determining the integer number of iterations, the actual scan values will be evenly spaced on a logarithmic scale. Finally, the \ttt{/+/} and \ttt{/*/} operators allow to specify the number of iterations (not counting the initial value) directly. The \ttt{\var{start-value}} and \ttt{\var{end-value}} are always included, and the intermediate values will be evenly spaced on a linear (\ttt{/+/}) or logarithmic (\ttt{/*/}) scale. Example: \begin{code} scan real mh = (130 GeV, (140 GeV => 160 GeV /+ 5 GeV), 180 GeV, (200 GeV => 1 TeV /*/ 10)) { integrate (higgs_decay) } \end{code} \subsection{Including Files} \subsubsection{include} \begin{syntax} include (\var{file-name}) \end{syntax} Include a \sindarin\ script from the specified file. The contents must be complete commands; they are compiled and executed as if they were part of the current script. Example: \begin{code} include ("default_cuts.sin") \end{code} \section{Expressions} \sindarin\ expressions are classified by their types. The type of an expression is verified when the script is compiled, before it is executed. This provides some safety against simple coding errors. Within expressions, grouping is done using ordinary brackets \ttt{()}. For subevent expressions, use square brackets \ttt{[]}. \subsection{Numeric} The language supports the classical numeric types \begin{itemize} \item \ttt{int} for integer: machine-default, usually 32 bit; \item \ttt{real}, usually \emph{double precision} or 64 bit; \item \ttt{complex}, consisting of real and imaginary part equivalent to a \ttt{real} each. \end{itemize} \sindarin\ supports arithmetic expressions similar to conventional languages. In arithmetic expressions, the three numeric types can be mixed as appropriate. The computation essentially follows the rules for mixed arithmetic in \ttt{Fortran}. The arithmetic operators are \verb|+|, \verb|-|, \verb|*|, \verb|/|, \verb|^|. Standard functions such as \ttt{sin}, \ttt{sqrt}, etc. are available. See Sec.~\ref{sec:real} to Sec.~\ref{sec:complex}. Numeric values can be associated with units. Units evaluate to numerical factors, and their use is optional, but they can be useful in the physics context for which \whizard\ is designed. Note that the default energy/mass unit is \verb|GeV|, and the default unit for cross sections is \verb|fbarn|. \subsection{Logical and String} The language also has the following standard types: \begin{itemize} \item \ttt{logical} (a.k.a.\ boolean). Logical variable names have a \ttt{?} (question mark) as prefix. \item \ttt{string} (arbitrary length). String variable names have a \ttt{\$} (dollar) sign as prefix. \end{itemize} There are comparisons, logical operations, string concatenation, and a mechanism for formatting objects as strings for output. \subsection{Special} Furthermore, \sindarin\ deals with a bunch of data types tailored specifically for Monte Carlo applications: \begin{itemize} \item \ttt{alias} objects denote a set of particle species. \item \ttt{subevt} objects denote a collection of particle momenta within an event. They have their uses in cut and analysis expressions. \item \ttt{process} object are generated by a \ttt{process} statement. There are no expressions involving processes, but they are referred to by \ttt{integrate} and \ttt{simulate} commands. \item \ttt{model}: There is always a current object of type and name \ttt{model}. Several models can be used concurrently by appropriately defining processes, but this happens behind the scenes. \item \ttt{beams}: Similarly, the current implementation allows only for a single object of this type at a given time, which is assigned by a \ttt{beams =} statement and used by \ttt{integrate}. \end{itemize} In the current implementation, \sindarin\ has no container data types derived from basic types, such as lists, arrays, or hashes, and there are no user-defined data types. (The \ttt{subevt} type is a container for particles in the context of events, but there is no type for an individual particle: this is represented as a one-particle \ttt{subevt}). There are also containers for inclusive processes which are however simply handled as an expansion into several components of a master process tag. \section{Variables} \label{sec:variables} \sindarin\ supports global variables, variables local to a scoping unit (the option body of a command, the body of a \ttt{scan} loop), and variables local to an expression. Some variables are predefined by the system (\emph{intrinsic variables}). They are further separated into \emph{independent} variables that can be reset by the user, and \emph{derived} or locked variables that are automatically computed by the program, but not directly user-modifiable. On top of that, the user is free to introduce his own variables (\emph{user variables}). The names of numerical variables consist of alphanumeric characters and underscores. The first character must not be a digit. Logical variable names are furthermore prefixed by a \ttt{?} (question mark) sign, while string variable names begin with a \ttt{\$} (dollar) sign. Character case does matter. In this manual we follow the convention that variable names consist of lower-case letters, digits, and underscores only, but you may also use upper-case letters if you wish. Physics models contain their own, specific set of numeric variables (masses, couplings). They are attached to the model where they are defined, so they appear and disappear with the model that is currently loaded. In particular, if two different models contain a variable with the same name, these two variables are nevertheless distinct: setting one doesn't affect the other. This feature might be called, in computer-science jargon, a \emph{mixin}. User variables -- global or local -- are declared by their type when they are introduced, and acquire an initial value upon declaration. Examples: \begin{quote} \begin{footnotesize} \begin{verbatim} int i = 3 real my_cut_value = 10 GeV complex c = 3 - 4 * I logical ?top_decay_allowed = mH > 2 * mtop string $hello = "Hello world!" alias q = d:u:s:c \end{verbatim} \end{footnotesize} \end{quote} An existing user variable can be assigned a new value without a declaration: \begin{quote} \begin{footnotesize} \begin{verbatim} i = i + 1 \end{verbatim} \end{footnotesize} \end{quote} and it may also be redeclared if the new declaration specifies the same type, this is equivalent to assigning a new value. Variables local to an expression are introduced by the \ttt{let ... in} contruct. Example: \begin{quote} \begin{footnotesize} \begin{verbatim} real a = let int n = 2 in x^n + y^n \end{verbatim} \end{footnotesize} \end{quote} The explicit \ttt{int} declaration is necessary only if the variable \ttt{n} has not been declared before. An intrinsic variable must not be declared: \ttt{let mtop = 175.3 GeV in \ldots} \ttt{let} constructs can be concatenated if several local variables need to be assigned: \ttt{let a = 3 in let b = 4 in \textit{expression}}. Variables of type \ttt{subevt} can only be defined in \ttt{let} constructs. Exclusively in the context of particle selections (event analysis), there are \emph{observables} as special numeric objects. They are used like numeric variables, but they are never declared or assigned. They get their value assigned dynamically, computed from the particle momentum configuration. Hence, they may be understood as (intrinsic and predefined) macros. By convention, observable names begin with a capital letter. Further macros are \begin{itemize} \item \ttt{cuts} and \ttt{analysis}. They are of type logical, and can be assigned an expression by the user. They are evaluated once for each event. \item \ttt{scale}, \ttt{factorization\_scale} and \ttt{renormalization\_scale} are real numeric macros which define the energy scale(s) of an event. The latter two override the former. If no scale is defined, the partonic energy is used as the process scale. \item \ttt{weight} is a real numeric macro. If it is assigned an expression, the expression is evaluated for each valid phase-space point, and the result multiplies the matrix element. \end{itemize} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{\sindarin\ in Details} \label{chap:sindarin} \section{Data and expressions} \subsection{Real-valued objects} \label{sec:real} Real literals have their usual form, mantissa and, optionally, exponent: \begin{center} \ttt{0.}\quad \ttt{3.14}\quad \ttt{-.5}\quad \ttt{2.345e-3}\quad \ttt{.890E-023} \end{center} Internally, real values are treated as double precision. The values are read by the Fortran library, so details depend on its implementation. A special feature of \sindarin\ is that numerics (real and integer) can be immediately followed by a physical unit. The supported units are presently hard-coded, they are \begin{center} \ttt{meV}\quad \ttt{eV}\quad \ttt{keV}\quad \ttt{MeV}\quad \ttt{GeV}\quad \ttt{TeV} \\ \ttt{nbarn}\quad \ttt{pbarn}\quad \ttt{fbarn}\quad \ttt{abarn} \\ \ttt{rad}\quad \ttt{mrad}\quad \ttt{degree} \\ \ttt{\%} \end{center} If a number is followed by a unit, it is automatically normalized to the corresponding default unit: \ttt{14.TeV} is transformed into the real number \ttt{14000.} Default units are \ttt{GeV}, \ttt{fbarn}, and \ttt{rad}. The \ttt{\%} sign after a number has the effect that the number is multiplied by $0.01$. Note that no checks for consistency of units are done, so you can add \ttt{1 meV + 3 abarn} if you absolutely wish to. Omitting units is always allowed, in that case, the default unit is assumed. Units are not treated as variables. In particular, you can't write \ttt{theta / degree}, the correct form is \ttt{theta / 1 degree}. There is a single predefined real constant, namely $\pi$ which is referred to by the keyword \ttt{pi}. In addition, there is a single predefined complex constant, which is the complex unit $i$, being referred to by the keyword \ttt{I}. The arithmetic operators are \begin{center} \verb|+| \verb|-| \verb|*| \verb|/| \verb|^| \end{center} with their obvious meaning and the usual precedence rules. \sindarin\ supports a bunch of standard numerical functions, mostly equivalent to their Fortran counterparts: \begin{center} \ttt{abs}\quad \ttt{conjg}\quad \ttt{sgn}\quad \ttt{mod}\quad \ttt{modulo} \\ \ttt{sqrt}\quad \ttt{exp}\quad \ttt{log}\quad \ttt{log10} \\ \ttt{sin}\quad \ttt{cos}\quad \ttt{tan}\quad \ttt{asin}\quad \ttt{acos}\quad \ttt{atan} \\ \ttt{sinh}\quad \ttt{cosh}\quad \ttt{tanh} \end{center} (Unlike Fortran, the \ttt{sgn} function takes only one argument and returns $1.$, or $-1.$) The function argument is enclosed in brackets: \ttt{sqrt (2.)}, \ttt{tan (11.5 degree)}. There are two functions with two real arguments: \begin{center} \ttt{max}\quad \ttt{min} \end{center} Example: \verb|real lighter_mass = min (mZ, mH)| The following functions of a real convert to integer: \begin{center} \ttt{int}\quad \ttt{nint}\quad \ttt{floor}\quad \ttt{ceiling} %% \; . \end{center} and this converts to complex type: \begin{center} \ttt{complex} \end{center} Real values can be compared by the following operators, the result is a logical value: \begin{center} \verb|==|\quad \verb|<>| \\ \verb|>|\quad \verb|<|\quad \verb|>=|\quad \verb|<=| \end{center} In \sindarin, it is possible to have more than two operands in a logical expressions. The comparisons are done from left to right. Hence, \begin{center} \verb|115 GeV < mH < 180 GeV| \end{center} is valid \sindarin\ code and evaluates to \ttt{true} if the Higgs mass is in the given range. Tests for equality and inequality with machine-precision real numbers are notoriously unreliable and should be avoided altogether. To deal with this problem, \sindarin\ has the possibility to make the comparison operators ``fuzzy'' which should be read as ``equal (unequal) up to an absolute tolerance'', where the tolerance is given by the real-valued intrinsic variable \ttt{tolerance}. This variable is initially zero, but can be set to any value (for instance, \ttt{tolerance = 1.e-13} by the user. Note that for non-zero tolerance, operators like \verb|==| and \verb|<>| or \verb|<| and \verb|>| are not mutually exclusive\footnote{In older versions of \whizard, until v2.1.1, there used to be separate comparators for the comparisons up to a tolerance, namely \ttt{==\~{}} and \ttt{<>\~{}}. These have been discarded from v2.2.0 on in order to simplify the syntax.}. %%%%%%%%%%%%%%% \subsection{Integer-valued objects} \label{sec:integer} Integer literals are obvious: \begin{center} \ttt{1}\quad \ttt{-98765}\quad \ttt{0123} \end{center} Integers are always signed. Their range is the default-integer range as determined by the \fortran\ compiler. Like real values, integer values can be followed by a physical unit: \ttt{1 TeV}, \ttt{30 degree}. This actually transforms the integer into a real. Standard arithmetics is supported: \begin{center} \verb|+| \verb|-| \verb|*| \verb|/| \verb|^| \end{center} It is important to note that there is no fraction datatype, and pure integer arithmetics does not convert to real. Hence \ttt{3/4} evaluates to \ttt{0}, but \ttt{3 GeV / 4 GeV} evaluates to \ttt{0.75}. Since all arithmetics is handled by the underlying \fortran\ library, integer overflow is not detected. If in doubt, do real arithmetics. Integer functions are more restricted than real functions. We support the following: \begin{center} \ttt{abs}\quad \ttt{sgn}\quad \ttt{mod}\quad \ttt{modulo} \\ \ttt{max}\quad \ttt{min} \end{center} and the conversion functions \begin{center} \ttt{real}\quad \ttt{complex} \end{center} Comparisons of integers among themselves and with reals are possible using the same set of comparison operators as for real values. This includes the operators with a finite tolerance. %%%%%%%%%%%%%%%% \subsection{Complex-valued objects} \label{sec:complex} Complex variables and values are currently not yet used by the physics models implemented in \whizard. There complex input coupling constants are always split into their real and imaginary parts (or modulus and phase). They are exclusively available for arithmetic calculations. There is no form for complex literals. Complex values must be created via an arithmetic expression, \begin{center} \ttt{complex c = 1 + 2 * I} \end{center} where the imaginary unit \ttt{I} is predefined as a constant. The standard arithmetic operations are supported (also mixed with real and integer). Support for functions is currently still incomplete, among the supported functions there are \ttt{sqrt}, \ttt{log}, \ttt{exp}. \subsection{Logical-valued objects} There are two predefined logical constants, \ttt{true} and \ttt{false}. Logicals are \emph{not} equivalent to integers (like in C) or to strings (like in PERL), but they make up a type of their own. Only in \verb|printf| output, they are treated as strings, that is, they require the \verb|%s| conversion specifier. The names of logical variables begin with a question mark \ttt{?}. Here is the declaration of a logical user variable: \begin{quote} \begin{footnotesize} \begin{footnotesize} \begin{verbatim} logical ?higgs_decays_into_tt = mH > 2 * mtop \end{verbatim} \end{footnotesize} \end{footnotesize} \end{quote} Logical expressions use the standard boolean operations \begin{center} \ttt{or}\quad \ttt{and}\quad \ttt{not} \end{center} The results of comparisons (see above) are logicals. There is also a special logical operator with lower priority, concatenation by a semicolon: \begin{center} \ttt{\textit{lexpr1} ; \textit{lexpr2}} \end{center} This evaluates \textit{lexpr1} and throws its result away, then evaluates \textit{lexpr2} and returns that result. This feature is to used with logical expressions that have a side effect, namely the \ttt{record} function within analysis expressions. The primary use for intrinsic logicals are flags that change the behavior of commands. For instance, \ttt{?unweighted = true} and \ttt{?unweighted = false} switch the unweighting of simulated event samples on and off. \subsection{String-valued objects and string operations} \label{sec:sprintf} String literals are enclosed in double quotes: \ttt{"This is a string."} The empty string is \ttt{""}. String variables begin with the dollar sign: \verb|$|. There is only one string operation, concatenation \begin{quote} \begin{footnotesize} \begin{verbatim} string $foo = "abc" & "def" \end{verbatim} \end{footnotesize} \end{quote} However, it is possible to transform variables and values to a string using the \ttt{sprintf} function. This function is an interface to the system's \ttt{C} function \ttt{sprintf} with some restrictions and modifications. The allowed conversion specifiers are \begin{center} \verb|%d|\quad \verb|%i| (integer) \\ \verb|%e|\quad \verb|%f|\quad \verb|%g|\quad \verb|%E|\quad \verb|%F|\quad \verb|%G| (real) \\ \verb|%s| (string and logical) \end{center} The conversions can use flag parameter, field width, and precision, but length modifiers are not supported since they have no meaning for the application. (See also Sec.~\ref{sec:I/O}.) The \ttt{sprintf} function has the syntax \begin{center} \ttt{sprintf} \textit{format-string} \ttt{(}\textit{arg-list}\ttt{)} \end{center} This is an expression that evaluates to a string. The format string contains the mentioned conversion specifiers. The argument list is optional. The arguments are separated by commas. Allowed arguments are integer, real, logical, and string variables, and numeric expressions. Logical and string expressions can also be printed, but they have to be dressed as \emph{anonymous variables}. A logical anonymous variable has the form \ttt{?(}\textit{logical\_expr}\ttt{)} (example: \ttt{?(mH > 115 GeV)}). A string anonymous variable has the form \ttt{\$(}\textit{string-expr}\ttt{)}. Example: \begin{quote} \begin{footnotesize} \begin{verbatim} string $unit = "GeV" string $str = sprintf "mW = %f %s" (mW, $unit) \end{verbatim} \end{footnotesize} \end{quote} The related \ttt{printf} command with the same syntax prints the formatted string to standard output\footnote{In older versions of \whizard, until v2.1.1, there also used to be a \ttt{sprintd} function and a \ttt{printd} command for default formats without a format string. They have been discarded in order to simplify the syntax from version v2.2.0 on.}. \section{Particles and (sub)events} \subsection{Particle aliases} \label{sec:alias} A particle species is denoted by its name as a string: \verb|"W+"|. Alternatively, it can be addressed by an \ttt{alias}. For instance, the $W^+$ boson has the alias \ttt{Wp}. Aliases are used like variables in a context where a particle species is expected, and the user can specify his/her own aliases. An alias may either denote a single particle species or a class of particles species. A colon \ttt{:} concatenates particle names and aliases to yield multi-species aliases: \begin{quote} \begin{footnotesize} \begin{verbatim} alias quark = u:d:s alias wboson = "W+":"W-" \end{verbatim} \end{footnotesize} \end{quote} Such aliases are used for defining processes with summation over flavors, and for defining classes of particles for analysis. Each model files define both names and (single-particle) aliases for all particles it contains. Furthermore, it defines the class aliases \verb|colored| and \verb|charged| which are particularly useful for event analysis. \subsection{Subevents} Subevents are sets of particles, extracted from an event. The sets are unordered by default, but may be ordered by appropriate functions. Obviously, subevents are meaningful only in a context where an event is available. The possible context may be the specification of a cut, weight, scale, or analysis expression. To construct a simple subevent, we put a particle alias or an expression of type particle alias into square brackets: \begin{quote} \begin{footnotesize} \verb|["W+"]|\quad \verb|[u:d:s]|\quad \verb|[colored]| \end{footnotesize} \end{quote} These subevents evaluate to the set of all $W^+$ bosons (to be precise, their four-momenta), all $u$, $d$, or $s$ quarks, and all colored particles, respectively. A subevent can contain pseudoparticles, i.e., particle combinations. That is, the four-momenta of distinct particles are combined (added conmponent-wise), and the results become subevent elements just like ordinary particles. The (pseudo)particles in a subevent are non-overlapping. That is, for any of the particles in the original event, there is at most one (pseudo)particle in the subevent in which it is contained. Sometimes, variables (actually, named constants) of type subevent are useful. Subevent variables are declared by the \ttt{subevt} keyword, and their names carry the prefix \verb|@|. Subevent variables exist only within the scope of a \verb|cuts| (or \verb|scale|, \verb|analysis|, etc.) macro, which is evaluated in the presence of an actual event. In the macro body, they are assigned via the \ttt{let} construct: \begin{quote} \begin{footnotesize} \begin{verbatim} cuts = let subevt @jets = select if Pt > 10 GeV [colored] in all Theta > 10 degree [@jets, @jets] \end{verbatim} \end{footnotesize} \end{quote} In this expression, we first define \verb|@jets| to stand for the set of all colored partons with $p_T>10\;\mathrm{GeV}$. This abbreviation is then used in a logical expression, which evaluates to true if all relative angles between distinct jets are greater than $10$ degree. We note that the example also introduces pairs of subevents: the square bracket with two entries evaluates to the list of all possible pairs which do not overlap. The objects within square brackets can be either subevents or alias expressions. The latter are transformed into subevents before they are used. As a special case, the original event is always available as the predefined subevent \verb|@evt|. \subsection{Subevent functions} There are several functions that take a subevent (or an alias) as an argument and return a new subevent. Here we describe them: \subsubsection{collect} \begin{quote} \begin{footnotesize} \ttt{collect [\textit{particles}]} \\ \ttt{collect if \textit{condition} [\textit{particles}]} \\ \ttt{collect if \textit{condition} [\textit{particles}, \textit{ref\_particles}]} \end{footnotesize} \end{quote} First version: collect all particle momenta in the argument and combine them to a single four-momentum. The \textit{particles} argument may either be a \ttt{subevt} expression or an \ttt{alias} expression. The result is a one-entry \ttt{subevt}. In the second form, only those particles are collected which satisfy the \textit{condition}, a logical expression. Example: \ttt{collect if Pt > 10 GeV [colored]} The third version is useful if you want to put binary observables (i.e., observables constructed from two different particles) in the condition. The \textit{ref\_particles} provide the second argument for binary observables in the \textit{condition}. A particle is taken into account if the condition is true with respect to all reference particles that do not overlap with this particle. Example: \ttt{collect if Theta > 5 degree [photon, charged]}: combine all photons that are separated by 5 degrees from all charged particles. \subsubsection{cluster} \begin{quote} \begin{footnotesize} \ttt{cluster [\textit{particles}]} \\ \ttt{cluster if \textit{condition} [\textit{particles}]} \\ \end{footnotesize} \end{quote} First version: collect all particle momenta in the argument and cluster them to a set of jets. The \textit{particles} argument may either be a \ttt{subevt} expression or an \ttt{alias} expression. The result is a one-entry \ttt{subevt}. In the second form, only those particles are clustered which satisfy the \textit{condition}, a logical expression. Example: \ttt{cluster if Pt > 10 GeV [colored]} % The third version is usefule if you want to put binary observables (i.e., % observables constructed from two different particles) in the condition. The % \textit{ref\_particles} provide the second argument for binary observables in % the \textit{condition}. A particle is taken into account if the condition is % true with respect to all reference particles that do not overlap with this % particle. Example: \ttt{cluster if Theta > 5 degree [photon, charged]}: % combine all photons that are separated by 5 degrees from all charged % particles. This command is available from \whizard\ version 2.2.1 on, and only if the \fastjet\ package has been installed and linked with \whizard\ (cf. Sec.\ref{sec:fastjet}); in a future version of \whizard\ it is foreseen to have also an intrinsic clustering package inside \whizard\ which will be able to support some of the clustering algorithms below. To use it in an analysis, you have to set the variable \ttt{jet\_algorithm} to one of the predefined jet-algorithm values (integer constants): \begin{quote} \begin{footnotesize} \ttt{kt\_algorithm}\\ \ttt{cambridge\_algorithm}\\ \ttt{antikt\_algorithm}\\ \ttt{genkt\_algorithm}\\ \ttt{cambridge\_for\_passive\_algorithm}\\ \ttt{genkt\_for\_passive\_algorithm}\\ \ttt{ee\_kt\_algorithm}\\ \ttt{ee\_genkt\_algorithm}\\ \ttt{plugin\_algorithm} \end{footnotesize} \end{quote} and the variable \ttt{jet\_r} to the desired $R$ parameter value, as appropriate for the analysis and the jet algorithm. Example: \begin{quote} \begin{footnotesize} \begin{verbatim} jet_algorithm = antikt_algorithm jet_r = 0.7 cuts = all Pt > 15 GeV [cluster if Pt > 5 GeV [colored]] \end{verbatim} \end{footnotesize} \end{quote} \subsubsection{select\_b\_jet, select\_non\_b\_jet, select\_c\_jet, select\_light\_jet} This command is available from \whizard\ version 2.8.1 on, and it only generates anything non-trivial if the \fastjet\ package has been installed and linked with \whizard\ (cf. Sec.\ref{sec:fastjet}). It only returns sensible results when it is applied to subevents after the \ttt{cluster} command (cf. the paragraph before). It is similar to the \ttt{select} command, and accepts a logical expression as a possible condition. The four commands \ttt{select\_b\_jet}, \ttt{select\_non\_b\_jet}, \ttt{select\_c\_jet}, and \ttt{select\_light\_jet} select $b$ jets, non-$b$ jets (anything lighter than $b$s), $c$ jets (neither $b$ nor light) and light jets (anything besides $b$ and $c$), respectively. An example looks like this: \begin{quote} \begin{footnotesize} \begin{verbatim} alias lightjet = u:U:d:D:s:S:c:C:gl alias jet = b:B:lightjet process eebbjj = e1, E1 => b, B, lightjet, lightjet jet_algorithm = antikt_algorithm jet_r = 0.5 cuts = let subevt @clustered_jets = cluster [jet] in let subevt @bjets = select_b_jet [@clustered_jets] in ..... \end{verbatim} \end{footnotesize} \end{quote} \subsubsection{photon\_isolation} This command is available from \whizard\ version 2.8.1 on. It provides isolation of photons from hadronic (and possibly electromagnetic) activity in the event to define a (especially) NLO cross section that is completely perturbative. The isolation criterion according to Frixione, cf.~\cite{Frixione:1998jh}, removes the non-perturbative contribution from the photon fragmentation function. This command can in principle be applied to elementary hard process partons (and leptons), but generates something sensible only if the \fastjet\ package has been installed and linked with \whizard\ (cf. Sec.\ref{sec:fastjet}). There are three parameters which allow to tune the isolation, \ttt{photon\_iso\_r0}, which is the radius $R^0_\gamma$ of the isolation cone, \ttt{photon\_iso\_eps}, which is the fraction $\epsilon_\gamma$ of the photon (transverse) energy that enters the isolation criterion, and the exponent of the isolation cone, \ttt{photon\_iso\_n}, $n^\gamma$. For more information cf.~\cite{Frixione:1998jh}. The command allows also a conditional cut on the photon which is applied before the isolation takes place. The first argument are the photons in the event, the second the particles from which they should be isolated. If also the electromagnetic activity is to be isolated, photons need to be isolated from themselves and must be included in the second argument. This is mandatory if leptons appear in the second argument. Two examples look like this: \begin{quote} \begin{footnotesize} \begin{verbatim} alias jet = u:U:d:D:s:S:c:C:gl process eeaajj = e1, E1 => A, A, jet, jet jet_algorithm = antikt_algorithm jet_r = 0.5 cuts = photon_isolation if Pt > 10 GeV [A, jet] .... cuts = let subevt @jets = cluster [jet] in photon_isolation if Pt > 10 GeV [A, @jets] ..... process eeajmm = e1, E1 => A, jet, e2, E2 cuts = let subevt @jets = cluster [jet] in let subevt @iso = join [@jets, A:e2:E2] photon_isolation [A, @iso] \end{verbatim} \end{footnotesize} \end{quote} \subsubsection{combine} \begin{quote} \begin{footnotesize} \ttt{combine [\textit{particles\_1}, \textit{particles\_2}]} \\ \ttt{combine if \textit{condition}} [\textit{particles\_1}, \textit{particles\_2}] \end{footnotesize} \end{quote} Make a new subevent of composite particles. The composites are generated by combining all particles from subevent \textit{particles\_1} with all particles from subevent \textit{particles\_2} in all possible combinations. Overlapping combinations are excluded, however: 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. In particular, this applies if the particles are identical. If a \textit{condition} is provided, the combination is done only when the logical expression, applied to the particle pair in question, returns true. For instance, here we reconstruct intermediate $W^-$ bosons: \begin{quote} \begin{footnotesize} \begin{verbatim} let @W_candidates = combine if 70 GeV < M < 80 GeV ["mu-", "numubar"] in ... \end{verbatim} \end{footnotesize} \end{quote} Note that the combination may fail, so the resulting subevent could be empty. \subsubsection{operator +} If there is no condition, the $+$ operator provides a convenient shorthand for the \verb|combine| command. In particular, it can be used if there are several particles to combine. Example: \begin{quote} \begin{footnotesize} \begin{verbatim} cuts = any 170 GeV < M < 180 GeV [b + lepton + invisible] \end{verbatim} \end{footnotesize} \end{quote} \subsubsection{select} \begin{quote} \begin{footnotesize} \ttt{select if \textit{condition} [\textit{particles}]} \\ \ttt{select if \textit{condition} [\textit{particles}, \textit{ref\_particles}]} \end{footnotesize} \end{quote} One argument: select all particles in the argument that satisfy the \textit{condition} and drop the rest. Two arguments: the \textit{ref\_particles} provide a second argument for binary observables. Select particles if the condition is satisfied for all reference particles. \subsubsection{extract} \begin{quote} \begin{footnotesize} \ttt{extract [\textit{particles}]} \\ \ttt{extract index \textit{index-value} [\textit{particles}]} \end{footnotesize} \end{quote} Return a single-particle subevent. In the first version, it contains the first particle in the subevent \textit{particles}. In the second version, the particle with index \textit{index-value} is returned, where \textit{index-value} is an integer expression. If its value is negative, the index is counted from the end of the subevent. The order of particles in an event or subevent is not always well-defined, so you may wish to sort the subevent before applying the \textit{extract} function to it. \subsubsection{sort} \begin{quote} \begin{footnotesize} \ttt{sort [\textit{particles}]} \\ \ttt{sort by \textit{observable} [\textit{particles}]} \\ \ttt{sort by \textit{observable} [\textit{particles}, \textit{ref\_particle}]} \end{footnotesize} \end{quote} Sort the subevent according to some criterion. If no criterion is supplied (first version), the subevent is sorted by increasing PDG code (first particles, then antiparticles). In the second version, the \textit{observable} is a real expression which is evaluated for each particle of the subevent in turn. The subevent is sorted by increasing value of this expression, for instance: \begin{quote} \begin{footnotesize} \begin{verbatim} let @sorted_evt = sort by Pt [@evt] in ... \end{verbatim} \end{footnotesize} \end{quote} In the third version, a reference particle is provided as second argument, so the sorting can be done for binary observables. It doesn't make much sense to have several reference particles at once, so the \ttt{sort} function uses only the first entry in the subevent \textit{ref-particle}, if it has more than one. \subsubsection{join} \begin{quote} \begin{footnotesize} \ttt{join [\textit{particles}, \textit{new\_particles}]} \\ \ttt{join if \textit{condition} [\textit{particles}, \textit{new\_particles}]} \end{footnotesize} \end{quote} This commands appends the particles in subevent \textit{new\_particles} to the subevent \textit{particles}, i.e., it joins the two particle sets. To be precise, a (pseudo)particle from \textit{new\_particles} is only appended if it does not overlap with any of the (pseudo)particles present in \textit{particles}, so the function will not produce overlapping entries. In the second version, each particle from \textit{new\_particles} is also checked with all particles in the first set whether \textit{condition} is fulfilled. If yes, and there is no overlap, it is appended, otherwise it is dropped. \subsubsection{operator \&} Subevents can also be concatenated by the operator \verb|&|. This effectively applies \ttt{join} to all operands in turn. Example: \begin{quote} \begin{footnotesize} \begin{verbatim} let @visible = select if Pt > 10 GeV and E > 5 GeV [photon] & select if Pt > 20 GeV and E > 10 GeV [colored] & select if Pt > 10 GeV [lepton] in ... \end{verbatim} \end{footnotesize} \end{quote} \subsection{Calculating observables} Observables (invariant mass \ttt{M}, energy \ttt{E}, \ldots) are used in expressions just like ordinary numeric variables. By convention, their names start with a capital letter. They are computed using a particle momentum (or two particle momenta) which are taken from a subsequent subevent argument. We can extract the value of an observable for an event and make it available for computing the \ttt{scale} value, or for histogramming etc.: \subsubsection{eval} \begin{quote} \begin{footnotesize} \ttt{eval \textit{expr} [\textit{particles}]} \\ \ttt{eval \textit{expr} [\textit{particles\_1}, \textit{particles\_2}]} \end{footnotesize} \end{quote} The function \ttt{eval} takes an expression involving observables and evaluates it for the first momentum (or momentum pair) of the subevent (or subevent pair) in square brackets that follows the expression. For example, \begin{quote} \begin{footnotesize} \begin{verbatim} eval Pt [colored] \end{verbatim} \end{footnotesize} \end{quote} evaluates to the transverse momentum of the first colored particle, \begin{quote} \begin{footnotesize} \begin{verbatim} eval M [@jets, @jets] \end{verbatim} \end{footnotesize} \end{quote} evaluates to the invariant mass of the first distinct pair of jets (assuming that \verb|@jets| has been defined in a \ttt{let} construct), and \begin{quote} \begin{footnotesize} \begin{verbatim} eval E - M [combine [e1, N1]] \end{verbatim} \end{footnotesize} \end{quote} evaluates to the difference of energy and mass of the combination of the first electron-neutrino pair in the event. The last example illustrates why observables are treated like variables, even though they are functions of particles: the \ttt{eval} construct with the particle reference in square brackets after the expression allows to compute derived observables -- observables which are functions of new observables -- without the need for hard-coding them as new functions. \subsection{Cuts and event selection} \label{sec:cuts} Instead of a numeric value, we can use observables to compute a logical value. \subsubsection{all} \begin{quote} \begin{footnotesize} \ttt{all \textit{logical\_expr} [\textit{particles}]} \\ \ttt{all \textit{logical\_expr} [\textit{particles\_1}, \textit{particles\_2}]} \end{footnotesize} \end{quote} The \ttt{all} construct expects a logical expression and one or two subevent arguments in square brackets. \begin{quote} \begin{footnotesize} \begin{verbatim} all Pt > 10 GeV [charged] all 80 GeV < M < 100 GeV [lepton, antilepton] \end{verbatim} \end{footnotesize} \end{quote} In the second example, \ttt{lepton} and \ttt{antilepton} should be aliases defined in a \ttt{let} construct. (Recall that aliases are promoted to subevents if they occur within square brackets.) This construction defines a cut. The result value is \ttt{true} if the logical expression evaluates to \ttt{true} for all particles in the subevent in square brackets. In the two-argument case it must be \ttt{true} for all non-overlapping combinations of particles in the two subevents. If one of the arguments is the empty subevent, the result is also \ttt{true}. \subsubsection{any} \begin{quote} \begin{footnotesize} \ttt{any \textit{logical\_expr} [\textit{particles}]} \\ \ttt{any \textit{logical\_expr} [\textit{particles\_1}, \textit{particles\_2}]} \end{footnotesize} \end{quote} The \ttt{any} construct is true if the logical expression is true for at least one particle or non-overlapping particle combination: \begin{quote} \begin{footnotesize} \begin{verbatim} any E > 100 GeV [photon] \end{verbatim} \end{footnotesize} \end{quote} This defines a trigger or selection condition. If a subevent argument is empty, it evaluates to \ttt{false} \subsubsection{no} \begin{quote} \begin{footnotesize} \ttt{no \textit{logical\_expr} [\textit{particles}]} \\ \ttt{no \textit{logical\_expr} [\textit{particles\_1}, \textit{particles\_2}]} \end{footnotesize} \end{quote} The \ttt{no} construct is true if the logical expression is true for no single one particle or non-overlapping particle combination: \begin{quote} \begin{footnotesize} \begin{verbatim} no 5 degree < Theta < 175 degree ["e-":"e+"] \end{verbatim} \end{footnotesize} \end{quote} This defines a veto condition. If a subevent argument is empty, it evaluates to \ttt{true}. It is equivalent to \ttt{not any\ldots}, but included for notational convenience. \subsection{More particle functions} \subsubsection{count} \begin{quote} \begin{footnotesize} \ttt{count [\textit{particles}]} \\ \ttt{count [\textit{particles\_1}, \textit{particles\_2}]} \\ \ttt{count if \textit{logical-expr} [\textit{particles}]} \\ \ttt{count if \textit{logical-expr} [\textit{particles}, \textit{ref\_particles}]} \end{footnotesize} \end{quote} This counts the number of events in a subevent, the result is of type \ttt{int}. If there is a conditional expression, it counts the number of \ttt{particle} in the subevent that pass the test. If there are two arguments, it counts the number of non-overlapping particle pairs (that pass the test, if any). \subsubsection{Predefined observables} The following real-valued observables are available in \sindarin\ for use in \ttt{eval}, \ttt{all}, \ttt{any}, \ttt{no}, and \ttt{count} constructs. The argument is always the subevent or alias enclosed in square brackets. \begin{itemize} \item \ttt{M2} \begin{itemize} \item One argument: Invariant mass squared of the (composite) particle in the argument. \item Two arguments: Invariant mass squared of the sum of the two momenta. \end{itemize} \item \ttt{M} \begin{itemize} \item Signed square root of \ttt{M2}: positive if $\ttt{M2}>0$, negative if $\ttt{M2}<0$. \end{itemize} \item \ttt{E} \begin{itemize} \item One argument: Energy of the (composite) particle in the argument. \item Two arguments: Sum of the energies of the two momenta. \end{itemize} \item \ttt{Px}, \ttt{Py}, \ttt{Pz} \begin{itemize} \item Like \ttt{E}, but returning the spatial momentum components. \end{itemize} \item \ttt{P} \begin{itemize} \item Like \ttt{E}, returning the absolute value of the spatial momentum. \end{itemize} \item \ttt{Pt}, \ttt{Pl} \begin{itemize} \item Like \ttt{E}, returning the transversal and longitudinal momentum, respectively. \end{itemize} \item \ttt{Theta} \begin{itemize} \item One argument: Absolute polar angle in the lab frame \item Two arguments: Angular distance of two particles in the lab frame. \end{itemize} \item \ttt{Theta\_star} Only with two arguments, gives the relative polar angle of the two momenta in the rest system of the momentum sum (i.e. mother particle). \item \ttt{Phi} \begin{itemize} \item One argument: Absolute azimuthal angle in the lab frame \item Two arguments: Azimuthal distance of two particles in the lab frame \end{itemize} \item \ttt{Rap}, \ttt{Eta} \begin{itemize} \item One argument: rapidity / pseudorapidity \item Two arguments: rapidity / pseudorapidity difference \end{itemize} \item \ttt{Dist} \begin{itemize} \item Two arguments: Distance on the $\eta$-$\phi$ cylinder, i.e., $\sqrt{\Delta\eta^2 + \Delta\phi^2}$ \end{itemize} \item \ttt{kT} \begin{itemize} \item Two arguments: $k_T$ jet clustering variable: $2 \min (E_{j1}^2, E_{j2}^2) / Q^2 \times (1 - \cos\theta_{j1,j2})$. At the moment, $Q^2 = 1$ GeV$^2$. \end{itemize} \end{itemize} There are also integer-valued observables: \begin{itemize} \item \ttt{PDG} \begin{itemize} \item One argument: PDG code of the particle. For a composite particle, the code is undefined (value 0). For flavor sums in the \ttt{cuts} statement, this observable always returns the same flavor, i.e. the first one from the flavor list. It is thus only sensible to use it in an \ttt{analysis} or \ttt{selection} statement when simulating events. \end{itemize} \item \ttt{Ncol} \begin{itemize} \item One argument: Number of open color lines. Only count color lines, not anticolor lines. This is defined only if the global flag \ttt{?colorize\_subevt} is true. \end{itemize} \item \ttt{Nacl} \begin{itemize} \item One argument: Number of open anticolor lines. Only count anticolor lines, not color lines. This is defined only if the global flag \ttt{?colorize\_subevt} is true. \end{itemize} \end{itemize} %%%%%%%%%%%%%%% \section{Physics Models} \label{sec:models} A physics model is a combination of particles, numerical parameters (masses, couplings, widths), and Feynman rules. Many physics analyses are done in the context of the Standard Model (SM). The SM is also the default model for \whizard. Alternatively, you can choose a subset of the SM (QED or QCD), variants of the SM (e.g., with or without nontrivial CKM matrix), or various extensions of the SM. The complete list is displayed in Table~\ref{tab:models}. The model definitions are contained in text files with filename extension \ttt{.mdl}, e.g., \ttt{SM.mdl}, which are located in the \ttt{share/models} subdirectory of the \whizard\ installation. These files are easily readable, so if you need details of a model implementation, inspect their contents. The model file contains the complete particle and parameter definitions as well as their default values. It also contains a list of vertices. This is used only for phase-space setup; the vertices used for generating amplitudes and the corresponding Feynman rules are stored in different files within the \oMega\ source tree. In a \sindarin\ script, a model is a special object of type \ttt{model}. There is always a \emph{current} model. Initially, this is the SM, so on startup \whizard\ reads the \ttt{SM.mdl} model file and assigns its content to the current model object. (You can change the default model by the \ttt{--model} option on the command line. Also the preloading of a model can be switched off with the \ttt{--no-model} option) Once the model has been loaded, you can define processes for the model, and you have all independent model parameters at your disposal. As noted before, these are intrinsic parameters which need not be declared when you assign them a value, for instance: \begin{quote} \begin{footnotesize} \begin{verbatim} mW = 80.33 GeV wH = 243.1 MeV \end{verbatim} \end{footnotesize} \end{quote} Other parameters are \emph{derived}. They can be used in expressions like any other parameter, they are also intrinsic, but they cannot be modified directly at all. For instance, the electromagnetic coupling \ttt{ee} is a derived parameter. If you change either \ttt{GF} (the Fermi constant), \ttt{mW} (the $W$ mass), or \ttt{mZ} (the $Z$ mass), this parameter will reflect the change, but setting it directly is an error. In other words, the SM is defined within \whizard\ in the $G_F$-$m_W$-$m_Z$ scheme. (While this scheme is unusual for loop calculations, it is natural for a tree-level event generator where the $Z$ and $W$ poles have to be at their experimentally determined location\footnote{In future versions of \whizard\ it is foreseen to implement other electroweak schemes.}.) The model also defines the particle names and aliases that you can use for defining processes, cuts, or analyses. If you would like to generate a SUSY process instead, for instance, you can assign a different model (cf.\ Table~\ref{tab:models}) to the current model object: \begin{quote} \begin{footnotesize} \begin{verbatim} model = MSSM \end{verbatim} \end{footnotesize} \end{quote} This assignment has the consequence that the list of SM parameters and particles is replaced by the corresponding MSSM list (which is much longer). The MSSM contains essentially all SM parameters by the same name, but in fact they are different parameters. This is revealed when you say \begin{quote} \begin{footnotesize} \begin{verbatim} model = SM mb = 5.0 GeV model = MSSM show (mb) \end{verbatim} \end{footnotesize} \end{quote} After the model is reassigned, you will see the MSSM value of $m_b$ which still has its default value, not the one you have given. However, if you revert to the SM later, \begin{quote} \begin{footnotesize} \begin{verbatim} model = SM show (mb) \end{verbatim} \end{footnotesize} \end{quote} you will see that your modification of the SM's $m_b$ value has been remembered. If you want both mass values to agree, you have to set them separately in the context of their respective model. Although this might seem cumbersome at first, it is nevertheless a sensible procedure since the parameters defined by the user might anyhow not be defined or available for all chosen models. When using two different models which need an SLHA input file, these {\em have} to be provided for both models. Within a given scope, there is only one current model. The current model can be reset permanently as above. It can also be temporarily be reset in a local scope, i.e., the option body of a command or the body of a \ttt{scan} loop. It is thus possible to use several models within the same script. For instance, you may define a SUSY signal process and a pure-SM background process. Each process depends only on the respective model's parameter set, and a change to a parameter in one of the models affects only the corresponding process. \section{Processes} \label{sec:processes} The purpose of \whizard\ is the integration and simulation of high-energy physics processes: scatterings and decays. Hence, \ttt{process} objects play the central role in \sindarin\ scripts. A \sindarin\ script may contain an arbitrary number of process definitions. The initial states need not agree, and the processes may belong to different physics models. \subsection{Process definition} \label{sec:procdef} A process object is defined in a straightforward notation. The definition syntax is straightforward: \begin{quote} \begin{footnotesize} \ttt{process \textit{process-id} = \textit{incoming-particles}} \verb|=>| \ttt{\textit{outgoing-particles}} \end{footnotesize} \end{quote} Here are typical examples: \begin{quote} \begin{footnotesize} \begin{verbatim} process w_pair_production = e1, E1 => "W+", "W-" process zdecay = Z => u, ubar \end{verbatim} \end{footnotesize} \end{quote} Throughout the program, the process will be identified by its \textit{process-id}, so this is the name of the process object. This identifier is arbitrary, chosen by the user. It follows the rules for variable names, so it consists of alphanumeric characters and underscores, where the first character is not numeric. As a special rule, it must not contain upper-case characters. The reason is that this name is used for identifying the process not just within the script, but also within the \fortran\ code that the matrix-element generator produces for this process. After the equals sign, there follow the lists of incoming and outgoing particles. The number of incoming particles is either one or two: scattering processes and decay processes. The number of outgoing particles should be two or larger (as $2\to 1$ processes are proportional to a $\delta$ function they can only be sensibly integrated when using a structure function like a hadron collider PDF or a beamstrahlung spectrum.). There is no hard upper limit; the complexity of processes that \whizard\ can handle depends only on the practical computing limitations (CPU time and memory). Roughly speaking, one can assume that processes up to $2\to 6$ particles are safe, $2\to 8$ processes are feasible given sufficient time for reaching a stable integration, while more complicated processes are largely unexplored. We emphasize that in the default setup, the matrix element of a physics process is computed exactly in leading-order perturbation theory, i.e., at tree level. There is no restriction of intermediate states, the result always contains the complete set of Feynman graphs that connect the initial with the final state. If the result would actually be expanded in Feynman graphs (which is not done by the \oMega\ matrix element generator that \whizard\ uses), the number of graphs can easily reach several thousands, depending on the complexity of the process and on the physics model. More details about the different methods for quantum field-theoretical matrix elements can be found in Chap.~\ref{chap:hardint}. In the following, we will discuss particle names, options for processes like restrictions on intermediate states, parallelization, flavor sums and process components for inclusive event samples (process containers). \subsection{Particle names} The particle names are taken from the particle definition in the current model file. Looking at the SM, for instance, the electron entry in \ttt{share/models/SM.mdl} reads \begin{quote} \begin{footnotesize} \begin{verbatim} particle E_LEPTON 11 spin 1/2 charge -1 isospin -1/2 name "e-" e1 electron e anti "e+" E1 positron tex_name "e^-" tex_anti "e^+" mass me \end{verbatim} \end{footnotesize} \end{quote} This tells that you can identify an electron either as \verb|"e-"|, \verb|e1|, \verb|electron|, or simply \verb|e|. The first version is used for output, but needs to be quoted, because otherwise \sindarin\ would interpret the minus sign as an operator. (Technically, unquoted particle identifiers are aliases, while the quoted versions -- you can say either \verb|e1| or \verb|"e1"| -- are names. On input, this makes no difference.) The alternative version \verb|e1| follows a convention, inherited from \comphep~\cite{Boos:2004kh}, that particles are indicated by lower case, antiparticles by upper case, and for leptons, the generation index is appended: \verb|e2| is the muon, \verb|e3| the tau. These alternative names need not be quoted because they contain no special characters. In Table~\ref{tab:SM-particles}, we list the recommended names as well as mass and width parameters for all SM particles. For other models, you may look up the names in the corresponding model file. \begin{table}[p] \begin{center} \begin{tabular}{|l|l|l|l|cc|} \hline & Particle & Output name & Alternative names & Mass & Width\\ \hline\hline Leptons &$e^-$ & \verb|e-| & \ttt{e1}\quad\ttt{electron} & \ttt{me} & \\ &$e^+$ & \verb|e+| & \ttt{E1}\quad\ttt{positron} & \ttt{me} & \\ \hline &$\mu^-$ & \verb|mu-| & \ttt{e2}\quad\ttt{muon} & \ttt{mmu} & \\ &$\mu^+$ & \verb|mu+| & \ttt{E2} & \ttt{mmu} & \\ \hline &$\tau^-$ & \verb|tau-| & \ttt{e3}\quad\ttt{tauon} & \ttt{mtau} & \\ &$\tau^+$ & \verb|tau+| & \ttt{E3} & \ttt{mtau} & \\ \hline\hline Neutrinos &$\nu_e$ & \verb|nue| & \ttt{n1} & & \\ &$\bar\nu_e$ & \verb|nuebar| & \ttt{N1} & & \\ \hline &$\nu_\mu$ & \verb|numu| & \ttt{n2} & & \\ &$\bar\nu_\mu$ & \verb|numubar| & \ttt{N2} & & \\ \hline &$\nu_\tau$ & \verb|nutau| & \ttt{n3} & & \\ &$\bar\nu_\tau$ & \verb|nutaubar| & \ttt{N3} & & \\ \hline\hline Quarks &$d$ & \verb|d| & \ttt{down} & & \\ &$\bar d$ & \verb|dbar| & \ttt{D} & & \\ \hline &$u$ & \verb|u| & \ttt{up} & & \\ &$\bar u$ & \verb|ubar| & \ttt{U} & & \\ \hline &$s$ & \verb|s| & \ttt{strange} & \ttt{ms} & \\ &$\bar s$ & \verb|sbar| & \ttt{S} & \ttt{ms} & \\ \hline &$c$ & \verb|c| & \ttt{charm} & \ttt{mc} & \\ &$\bar c$ & \verb|cbar| & \ttt{C} & \ttt{mc} & \\ \hline &$b$ & \verb|b| & \ttt{bottom} & \ttt{mb} & \\ &$\bar b$ & \verb|bbar| & \ttt{B} & \ttt{mb} & \\ \hline &$t$ & \verb|t| & \ttt{top} & \ttt{mtop} & \ttt{wtop} \\ &$\bar t$ & \verb|tbar| & \ttt{T} & \ttt{mtop} & \ttt{wtop} \\ \hline\hline Vector bosons &$g$ & \verb|gl| & \ttt{g}\quad\ttt{G}\quad\ttt{gluon} & & \\ \hline &$\gamma$ & \verb|A| & \ttt{gamma}\quad\ttt{photon} & & \\ \hline &$Z$ & \verb|Z| & & \ttt{mZ} & \ttt{wZ} \\ \hline &$W^+$ & \verb|W+| & \ttt{Wp} & \ttt{mW} & \ttt{wW} \\ &$W^-$ & \verb|W-| & \ttt{Wm} & \ttt{mW} & \ttt{wW} \\ \hline\hline Scalar bosons &$H$ & \verb|H| & \ttt{h}\quad \ttt{Higgs} & \ttt{mH} & \ttt{wH} \\ \hline \end{tabular} \end{center} \caption{\label{tab:SM-particles} Names that can be used for SM particles. Also shown are the intrinsic variables that can be used to set mass and width, if applicable.} \end{table} Where no mass or width parameters are listed in the table, the particle is assumed to be massless or stable, respectively. This is obvious for particles such as the photon. For neutrinos, the mass is meaningless to particle physics collider experiments, so it is zero. For quarks, the $u$ or $d$ quark mass is unobservable directly, so we also set it zero. For the heavier quarks, the mass may play a role, so it is kept. (The $s$ quark is borderline; one may argue that its mass is also unobservable directly.) On the other hand, the electron mass is relevant, e.g., in photon radiation without cuts, so it is not zero by default. It pays off to set particle masses to zero, if the approximation is justified, since fewer helicity states will contribute to the matrix element. Switching off one of the helicity states of an external fermion speeds up the calculation by a factor of two. Therefore, script files will usually contain the assignments \begin{quote} \begin{footnotesize} \begin{verbatim} me = 0 mmu = 0 ms = 0 mc = 0 \end{verbatim} \end{footnotesize} \end{quote} unless they deal with processes where this simplification is phenomenologically unacceptable. Often $m_\tau$ and $m_b$ can also be neglected, but this excludes processes where the Higgs couplings of $\tau$ or $b$ are relevant. Setting fermion masses to zero enables, furthermore, the possibility to define multi-flavor aliases \begin{quote} \begin{footnotesize} \begin{verbatim} alias q = d:u:s:c alias Q = D:U:S:C \end{verbatim} \end{footnotesize} \end{quote} and handle processes such as \begin{quote} \begin{footnotesize} \begin{verbatim} process two_jets_at_ilc = e1, E1 => q, Q process w_pairs_at_lhc = q, Q => Wp, Wm \end{verbatim} \end{footnotesize} \end{quote} where a sum over all allowed flavor combination is automatically included. For technical reasons, such flavor sums are possible only for massless particles (or more general for mass-degenerate particles). If you want to generate inclusive processes with sums over particles of different masses (e.g. summing over $W/Z$ in the final state etc.), confer below the section about process components, Sec.~\ref{sec:processcomp}. Assignments of masses, widths and other parameters are actually in effect when a process is integrated, not when it is defined. So, these assignments may come before or after the process definition, with no significant difference. However, since flavor summation requires masses to be zero, the assignments may be put before the alias definition which is used in the process. The muon, tau, and the heavier quarks are actually unstable. However, the width is set to zero because their decay is a macroscopic effect and, except for the muon, affected by hadron physics, so it is not described by \whizard. (In the current \whizard\ setup, all decays occur at the production vertex. A future version may describe hadronic physics and/or macroscopic particle propagation, and this restriction may be eventually removed.) \subsection{Options for processes} \label{sec:process options} The \ttt{process} definition may contain an optional argument: \begin{quote} \begin{footnotesize} \ttt{process \textit{process-id} = \textit{incoming-particles}} \verb|=>| \ttt{\textit{outgoing-particles}} \ttt{\{\textit{options\ldots}\}} \end{footnotesize} \end{quote} The \textit{options} are a \sindarin\ script that is executed in a context local to the \ttt{process} command. The assignments it contains apply only to the process that is defined. In the following, we describe the set of potentially useful options (which all can be also set globally): \subsubsection{Model reassignment} It is possible to locally reassign the model via a \ttt{model =} statment, permitting the definition of process using a model other than the globally selected model. The process will retain this association during integration and event generation. \subsubsection{Restrictions on matrix elements} \label{subsec:restrictions} Another useful option is the setting \begin{quote} \begin{footnotesize} \verb|$restrictions =| \ttt{\textit{string}} \end{footnotesize} \end{quote} This option allows to select particular classes of Feynman graphs for the process when using the \oMega\ matrix element generator. The \verb|$restrictions| string specifies e.g. propagators that the graph must contain. Here is an example: \begin{code} process zh_invis = e1, E1 => n1:n2:n3, N1:N2:N3, H { $restrictions = "1+2 ~ Z" } \end{code} The complete process $e^-e^+ \to \nu\bar\nu H$, summed over all neutrino generations, contains both $ZH$ pair production (Higgs-strahlung) and $W^+W^-\to H$ fusion. The restrictions string selects the Higgs-strahlung graph where the initial electrons combine to a $Z$ boson. Here, the particles in the process are consecutively numbered, starting with the initial particles. An alternative for the same selection would be \verb|$restrictions = "3+4 ~ Z"|. Restrictions can be combined using \verb|&&|, for instance \begin{code} $restrictions = "1+2 ~ Z && 3 + 4 ~ Z" \end{code} which is redundant here, however. The restriction keeps the full energy dependence in the intermediate propagator, so the Breit-Wigner shape can be observed in distributions. This breaks gauge invariance, in particular if the intermediate state is off shell, so you should use the feature only if you know the implications. For more details, cf. the Chap.~\ref{chap:hardint} and the \oMega\ manual. Other restrictions that can be combined with the restrictions above on intermediate propagators allow to exclude certain particles from intermediate propagators, or to exclude certain vertices from the matrix elements. For example, \begin{code} process eemm = e1, E1 => e2, E2 { $restrictions = "!A" } \end{code} would exclude all photon propagators from the matrix element and leaves only the $Z$ exchange here. In the same way, \verb|$restrictions = "!gl"| would exclude all gluon exchange. This exclusion of internal propagators works also for lists of particles, like \begin{code} $restrictions = "!Z:H" \end{code} excludes all $Z$ and $H$ propagators from the matrix elements. Besides excluding certain particles as internal lines, it is also possible to exclude certain vertices using the restriction command \begin{code} process eeww = e1, E1 => Wp, Wm { $restrictions = "^[W+,W-,Z]" } \end{code} This would generate the matrix element for the production of two $W$ bosons at LEP without the non-Abelian vertex $W^+W^-Z$. Again, these restrictions are able to work on lists, so \begin{code} $restrictions = "^[W+,W-,A:Z]" \end{code} would exclude all triple gauge boson vertices from the above process and leave only the $t$-channel neutrino exchange. It is also possible to exlude vertices by their coupling constants, e.g. the photon exchange in the process $e^+ e^- \to \mu^+ \mu^-$ can also be removed by the following restriction: \begin{code} $restrictions = "^qlep" \end{code} Here, \ttt{qlep} is the \fortran\ variable for the coupling constant of the electron-positron-photon vertex. \begin{table} \begin{center} \begin{tabular}{|l|l|} \hline \verb|3+4~Z| & external particles 3 and 4 must come from intermediate $Z$ \\\hline \verb| && | & logical ``and'', e.g. in \verb| 3+5~t && 4+6~tbar| \\\hline \verb| !A | & exclude all $\gamma$ propagators \\\hline \verb| !e+:nue | & exclude a list of propagators, here $\gamma$, $\nu_e$ \\\hline \verb|^qlep:gnclep| & exclude all vertices with \ttt{qlep},\ttt{gnclep} coupling constants \\\hline \verb|^[A:Z,W+,W-]| & exclude all vertices $W^+W^-Z$, $W^+W^-\gamma$ \\\hline \verb|^c1:c2:c3[H,H,H]| & exclude all triple Higgs couplings with $c_i$ constants \\\hline \end{tabular} \end{center} \caption{List of possible restrictions that can be applied to \oMega\ matrix elements.} \label{tab:restrictions} \end{table} The Tab.~\ref{tab:restrictions} gives a list of options that can be applied to the \oMega\ matrix elements. \subsubsection{Other options} There are some further options that the \oMega\ matrix-element generator can take. If desired, any string of options that is contained in this variable \begin{quote} \begin{footnotesize} \verb|$omega_flags =| \ttt{\textit{string}} \end{footnotesize} \end{quote} will be copied verbatim to the \oMega\ call, after all other options. One important application is the scheme of treating the width of unstable particles in the $t$-channel. This is modified by the \verb|model:| class of \oMega\ options. It is well known that for some processes, e.g., single $W$ production from photon-$W$ fusion, gauge invariance puts constraints on the treatment of the unstable-particle width. By default, \oMega\ puts a nonzero width in the $s$ channel only. This correctly represents the resummed Dyson series for the propagator, but it violates QED gauge invariance, although the effect is only visible if the cuts permit the photon to be almost on-shell. An alternative is \begin{quote} \begin{footnotesize} \verb|$omega_flags = "-model:fudged_width"| -\end{footnotesize} +\end{footnotesize}, \end{quote} which puts zero width in the matrix element, so that gauge cancellations hold, and reinstates the $s$-channel width in the appropriate places by an overall factor that multiplies the whole matrix element. - +Note that the fudged width option only applies to charged unstable particles, such as the $W$ boson or top quark. Another possibility is \begin{quote} \begin{footnotesize} \verb|$omega_flags = "-model:constant_width"| -\end{footnotesize} +\end{footnotesize}, \end{quote} -which puts the width both in the $s$ and in the $t$ channel everywhere. - -Note that both options apply only to charged unstable particles, such as the -$W$ boson. +which puts the width both in the $s$- and in the $t$-channel like diagrams. +A third option is provided by the running width scheme +\begin{quote} + \begin{footnotesize} + \verb|$omega_flags = "-model:running_width"| + \end{footnotesize}, +\end{quote} +which applies the width only for $s$-channel like diagrams and multiplies it by a factor of $p^2 / M^2$. +The additional $p^2$-dependent factor mimicks the momentum dependence of the imaginary part of a vacuum polarization for a particle decaying into massles decay products. +It is noted that none of the above options preserves gauge invariance. +For a gauge preserving approach (at least at tree level), \oMega\ provides the complex-mass scheme +\begin{quote} + \begin{footnotesize} + \verb|$omega_flags = "-model:cms_width| + \end{footnotesize}. +\end{quote} +However, in this case, one also has to modify the model in usage. +For example, the parameter setting for the Standard Model can be changed by, +\begin{quote} + \begin{footnotesize} + \verb|model = SM (Complex_Mass_Scheme)| + \end{footnotesize}. +\end{quote} \subsubsection{Multithreaded calculation of helicity sums via OpenMP} \label{sec:openmp} On multicore and / or multiprocessor systems, it is possible to speed up the calculation by using multiple threads to perform the helicity sum in the matrix element calculation. As the processing time used by \whizard\ is not used up solely in the matrix element, the speedup thus achieved varies greatly depending on the process under consideration; while simple processes without flavor sums do not profit significantly from this parallelization, the computation time for processes involving flavor sums with four or more particles in the final state is typically reduced by a factor between two and three when utilizing four parallel threads. The parallization is implemented using \ttt{OpenMP} and requires \whizard\ to be compiled with an \ttt{OpenMP} aware compiler and the appropiate compiler flags This is done in the configuration step, cf.\ Sec.~\ref{sec:installation}. As with all \ttt{OpenMP} programs, the default number of threads used at runtime is up to the compiler runtime support and typically set to the number of independent hardware threads (cores / processors / hyperthreads) available in the system. This default can be adjusted by setting the \ttt{OMP\_NUM\_THREADS} environment variable prior to calling WHIZARD. Alternatively, the available number of threads can be reset anytime by the \sindarin\ parameter \ttt{openmp\_num\_threads}. Note however that the total number of threads that can be sensibly used is limited by the number of nonvanishing helicity combinations. %%%%%%%%%%%%%%% \subsection{Process components} \label{sec:processcomp} It was mentioned above that processes with flavor sums (in the initial or final state or both) have to be mass-degenerate (in most cases massless) in all particles that are summed over at a certain position. This condition is necessary in order to use the same phase-space parameterization and integration for the flavor-summed process. However, in many applications the user wants to handle inclusive process definitions, e.g. by defining inclusive decays, inclusive SUSY samples at hadron colliders (gluino pairs, squark pairs, gluino-squark associated production), or maybe lepton-inclusive samples where the tau and muon mass should be kept at different values. In \whizard\, from version v2.2.0 on, there is the possibility to define such inclusive process containers. The infrastructure for this feature is realized via so-called process components: processes are allowed to contain several process components. Those components need not be provided by the same matrix element generator, e.g. internal matrix elements, \oMega\ matrix elements, external matrix element (e.g. from a one-loop program, OLP) can be mixed. The very same infrastructure can also be used for next-to-leading order (NLO) calculations, containing the born with real emission, possible subtraction terms to make the several components infrared- and collinear finite, as well as the virtual corrections. Here, we want to discuss the use for inclusive particle samples. There are several options, the simplest of which to add up different final states by just using the \ttt{+} operator in \sindarin, e.g.: \begin{quote} \begin{footnotesize} \begin{verbatim} process multi_comp = e1, E1 => (e2, E2) + (e3, E3) + (A, A) \end{verbatim} \end{footnotesize} \end{quote} The brackets are not only used for a better grouping of the expressions, they are not mandatory for \whizard\ to interpret the sum correctly. When integrating, \whizard\ tells you that this a process with three different components: \begin{footnotesize} \begin{Verbatim} | Initializing integration for process multi_comp_1_p1: | ------------------------------------------------------------------------ | Process [scattering]: 'multi_comp' | Library name = 'default_lib' | Process index = 1 | Process components: | 1: 'multi_comp_i1': e-, e+ => m-, m+ [omega] | 2: 'multi_comp_i2': e-, e+ => t-, t+ [omega] | 3: 'multi_comp_i3': e-, e+ => A, A [omega] | ------------------------------------------------------------------------ \end{Verbatim} \end{footnotesize} A different phase-space setup is used for each different component. The integration for each different component is performed separately, and displayed on screen. At the end, a sum of all components is shown. All files that depend on the components are being attached an \ttt{\_i{\em }} where \ttt{{\em }} is the number of the process component that appears in the list above: the \fortran\ code for the matrix element, the \ttt{.phs} file for the phase space parameterization, and the grid files for the \vamp\ Monte-Carlo integration (or any other integration method). However, there will be only one event file for the inclusive process, into which a mixture of events according to the size of the individual process component cross section enter. More options are to specify additive lists of particles. \whizard\ then expands the final states according to tensor product algebra: \begin{quote} \begin{footnotesize} \begin{verbatim} process multi_tensor = e1, E1 => e2 + e3 + A, E2 + E3 + A \end{verbatim} \end{footnotesize} \end{quote} This gives the same three process components as above, but \whizard\ recognized that e.g. $e^- e^+ \to \mu^- \gamma$ is a vanishing process, hence the numbering is different: \begin{footnotesize} \begin{Verbatim} | Process component 'multi_tensor_i2': matrix element vanishes | Process component 'multi_tensor_i3': matrix element vanishes | Process component 'multi_tensor_i4': matrix element vanishes | Process component 'multi_tensor_i6': matrix element vanishes | Process component 'multi_tensor_i7': matrix element vanishes | Process component 'multi_tensor_i8': matrix element vanishes | ------------------------------------------------------------------------ | Process [scattering]: 'multi_tensor' | Library name = 'default_lib' | Process index = 1 | Process components: | 1: 'multi_tensor_i1': e-, e+ => m-, m+ [omega] | 5: 'multi_tensor_i5': e-, e+ => t-, t+ [omega] | 9: 'multi_tensor_i9': e-, e+ => A, A [omega] | ------------------------------------------------------------------------ \end{Verbatim} \end{footnotesize} Identical copies of the same process that would be created by expanding the tensor product of final states are eliminated and appear only once in the final sum of process components. Naturally, inclusive process definitions are also available for decays: \begin{quote} \begin{footnotesize} \begin{Verbatim} process multi_dec = Wp => E2 + E3, n2 + n3 \end{Verbatim} \end{footnotesize} \end{quote} This yields: \begin{footnotesize} \begin{Verbatim} | Process component 'multi_dec_i2': matrix element vanishes | Process component 'multi_dec_i3': matrix element vanishes | ------------------------------------------------------------------------ | Process [decay]: 'multi_dec' | Library name = 'default_lib' | Process index = 2 | Process components: | 1: 'multi_dec_i1': W+ => mu+, numu [omega] | 4: 'multi_dec_i4': W+ => tau+, nutau [omega] | ------------------------------------------------------------------------ \end{Verbatim} \end{footnotesize} %%%%%%%%%%%%%%% \subsection{Compilation} \label{sec:compilation} Once processes have been set up, to make them available for integration they have to be compiled. More precisely, the matrix-element generator \oMega\ (and it works similarly if a different matrix element method is chosen) is called to generate matrix element code, the compiler is called to transform this \fortran\ code into object files, and the linker is called to collect this in a dynamically loadable library. Finally, this library is linked to the program. From version v2.2.0 of \whizard\ this is no longer done by system calls of the OS but steered via process library Makefiles. Hence, the user can execute and manipulate those Makefiles in order to manually intervene in the particular steps, if he/she wants to do so. All this is done automatically when an \ttt{integrate}, \ttt{unstable}, or \ttt{simulate} command is encountered for the first time. You may also force compilation explicitly by the command \begin{quote} \begin{footnotesize} \begin{verbatim} compile \end{verbatim} \end{footnotesize} \end{quote} which performs all steps as listed above, including loading the generated library. The \fortran\ part of the compilation will be done using the \fortran\ compiler specified by the string variable \verb|$fc| and the compiler flags specified as \verb|$fcflags|. The default settings are those that have been used for compiling \whizard\ itself during installation. For library compatibility, you should stick to the compiler. The flags may be set differently. They are applied in the compilation and loading steps, and they are processed by \ttt{libtool}, so \ttt{libtool}-specific flags can also be given. \whizard\ has some precautions against unnecessary repetitions. Hence, when a \ttt{compile} command is executed (explicitly, or implicitly by the first integration), the program checks first whether the library is already loaded, and whether source code already exists for the requested processes. If yes, this code is used and no calls to \oMega\ (or another matrix element method) or to the compiler are issued. Otherwise, it will detect any modification to the process configuration and regenerate the matrix element or recompile accordingly. Thus, a \sindarin\ script can be executed repeatedly without rebuilding everything from scratch, and you can safely add more processes to a script in a subsequent run without having to worry about the processes that have already been treated. This default behavior can be changed. By setting \begin{quote} \begin{footnotesize} \begin{verbatim} ?rebuild_library = true \end{verbatim} \end{footnotesize} \end{quote} code will be re-generated and re-compiled even if \whizard\ would think that this is unncessary. The same effect is achieved by calling \whizard\ with a command-line switch, \begin{quote} \begin{footnotesize} \begin{verbatim} /home/user$ whizard --rebuild_library \end{verbatim} \end{footnotesize} \end{quote} There are further \ttt{rebuild} switches which are described below. If everything is to be rebuilt, you can set a master switch \ttt{?rebuild} or the command line option \verb|--rebuild|. The latter can be abbreviated as a short command-line option: \begin{quote} \begin{footnotesize} \begin{verbatim} /home/user$ whizard -r \end{verbatim} \end{footnotesize} \end{quote} Setting this switch is always a good idea when starting a new project, just in case some old files clutter the working directory. When re-running the same script, possibly modified, the \verb|-r| switch should be omitted, so the existing files can be reused. \subsection{Process libraries} Processes are collected in \emph{libraries}. A script may use more than one library, although for most applications a single library will probably be sufficient. The default library is \ttt{default\_lib}. If you do not specify anything else, the processes you compile will be collected by a driver file \ttt{default\_lib.f90} which is compiled together with the process code and combined as a libtool archive \ttt{default\_lib.la}, which is dynamically linked to the running \whizard\ process. Once in a while, you work on several projects at once, and you didn't care about opening a new working directory for each. If the \verb|-r| option is given, a new run will erase the existing library, which may contain processes needed for the other project. You could omit \verb|-r|, so all processes will be collected in the same library (this does not hurt), but you may wish to cleanly separate the projects. In that case, you should open a separate library for each project. Again, there are two possibilities. You may start the script with the specification \begin{quote} \begin{footnotesize} \begin{verbatim} library = "my_lhc_proc" \end{verbatim} \end{footnotesize} \end{quote} to open a library \verb|my_lhc_proc| in place of the default library. Repeating the command with different arguments, you may introduce several libraries in the script. The active library is always the one specified last. It is possible to issue this command locally, so a particular process goes into its own library. Alternatively, you may call \whizard\ with the option \begin{quote} \begin{footnotesize} \begin{verbatim} /home/user$ whizard --library=my_lhc_proc \end{verbatim} \end{footnotesize} \end{quote} If several libraries are open simultaneously, the \ttt{compile} command will compile all libraries that the script has referenced so far. If this is not intended, you may give the command an argument, \begin{quote} \begin{footnotesize} \begin{verbatim} compile ("my_lhc_proc", "my_other_proc") \end{verbatim} \end{footnotesize} \end{quote} to compile only a specific subset. The command \begin{quote} \begin{footnotesize} \begin{verbatim} show (library) \end{verbatim} \end{footnotesize} \end{quote} will display the contents of the actually loaded library together with a status code which indicates the status of the library and the processes within. %%%%%%%%%%%%%%% \subsection{Stand-alone \whizard\ with precompiled processes} \label{sec:static} Once you have set up a process library, it is straightforward to make a special stand-alone \whizard\ executable which will have this library preloaded on startup. This is a matter of convenience, and it is also useful if you need a statically linked executable for reasons of profiling, batch processing, etc. For this task, there is a variant of the \ttt{compile} command: \begin{quote} \begin{footnotesize} \begin{verbatim} compile as "my_whizard" () \end{verbatim} \end{footnotesize} \end{quote} which produces an executable \verb|my_whizard|. You can omit the library argument if you simply want to include everything. (Note that this command will \emph{not} load a library into the current process, it is intended for creating a separate program that will be started independently.) As an example, the script \begin{quote} \begin{footnotesize} \begin{verbatim} process proc1 = e1, E1 => e1, E1 process proc2 = e1, E1 => e2, E2 process proc3 = e1, E1 => e3, E3 compile as "whizard-leptons" () \end{verbatim} \end{footnotesize} \end{quote} will make a new executable program \verb|whizard-leptons|. This program behaves completely identical to vanilla \whizard, except for the fact that the processes \ttt{proc1}, \ttt{proc2}, and \ttt{proc3} are available without configuring them or loading any library. % This feature is particularly useful when compiling with the \ttt{-static} % flag. As long as the architecture is compatible, the resulting binary may be % run on a different computer where no \whizard\ libraries are present. (The % program will still need to find its model files, however.) \section{Beams} \label{sec:beams} Before processes can be integrated and simulated, the program has to know about the collider properties. They can be specified by the \ttt{beams} statement. In the command script, it is irrelevant whether a \ttt{beams} statement comes before or after process specification. The \ttt{integrate} or \ttt{simulate} commands will use the \ttt{beams} statement that was issued last. \subsection{Beam setup} \label{sec:beam-setup} If the beams have no special properties, and the colliding particles are the incoming particles in the process themselves, there is no need for a \ttt{beams} statement at all. You only \emph{must} specify the center-of-momentum energy of the collider by setting the value of $\sqrt{s}$, for instance \begin{quote} \begin{footnotesize} \begin{verbatim} sqrts = 14 TeV \end{verbatim} \end{footnotesize} \end{quote} The \ttt{beams} statement comes into play if \begin{itemize} \item the beams have nontrivial structure, e.g., parton structure in hadron collision or photon radiation in lepton collision, or \item the beams have non-standard properties: polarization, asymmetry, crossing angle. \end{itemize} Note that some of the abovementioned beam properties had not yet been reimplemented in the \whizard\ttt{2} release series. From version v2.2.0 on all options of the legacy series \whizard\ttt{1} are available again. From version v2.1 to version v2.2 of \whizard\ there has also been a change in possible options to the \ttt{beams} statement: in the early versions of \whizard\ttt{2} (v2.0/v2.1), local options could be specified within the beam settings, e.g. \ttt{beams = p, p { sqrts = 14 TeV } => pdf\_builtin}. These possibility has been abandoned from version v2.2 on, and the \ttt{beams} command does not allow for {\em any} optional arguments any more. Hence, beam parameters can -- with the exception of the specification of structure functions -- be specified only globally: \begin{quote} \begin{footnotesize} \begin{verbatim} sqrts = 14 TeV beams = p, p => lhapdf \end{verbatim} \end{footnotesize} \end{quote} It does not make any difference whether the value of \ttt{sqrts} is set before or after the \ttt{beams} statement, the last value found before an \ttt{integrate} or \ttt{simulate} is the relevant one. This in particularly allows to specify the beam structure, and then after that perform a loop or scan over beam energies, beam parameters, or structure function settings. The \ttt{beams} statement also applies to particle decay processes, where there is only a single beam. Here, it is usually redundant because no structure functions are possible, and the energy is fixed to the decaying particle's mass. However, it is needed for computing polarized decay, e.g. \begin{quote} \begin{footnotesize} \begin{verbatim} beams = Z beams_pol_density = @(0) \end{verbatim} \end{footnotesize} \end{quote} where for a boson at rest, the polarization axis is defined to be the $z$ axis. Beam polarization is described in detail below in Sec.~\ref{sec:polarization}. Note also that future versions of \whizard\ might give support for single-beam events, where structure functions for single particles indeed do make sense. In the following sections we list the available options for structure functions or spectra inside \whizard\ and explain their usage. More about the physics of the implemented structure functions can be found in Chap.~\ref{chap:hardint}. %%%%%%%%%%%%%%% \subsection{Asymmetric beams and Crossing angles} \label{sec:asymmetricbeams} \whizard\ not only allows symmetric beam collisions, but basically arbitrary collider setups. In the case there are two different beam energies, the command \begin{quote} \begin{footnotesize} \ttt{beams\_momentum = {\em }, {\em }} \end{footnotesize} \end{quote} allows to specify the momentum (or as well energies for massless particles) for the beams. Note that for scattering processes both values for the beams must be present. So the following to setups for 14 TeV LHC proton-proton collisions are equivalent: \begin{quote} \begin{footnotesize} \ttt{beams = p, p => pdf\_builtin} \newline \ttt{sqrts = 14 TeV} \end{footnotesize} \end{quote} and \begin{quote} \begin{footnotesize} \ttt{beams = p, p => pdf\_builtin} \newline \ttt{beams\_momentum = 7 TeV, 7 TeV} \end{footnotesize} \end{quote} Asymmetric setups can be set by using different values for the two beam momenta, e.g. in a HERA setup: \begin{quote} \begin{footnotesize} \ttt{beams = e, p => none, pdf\_builtin} \ttt{beams\_momentum = 27.5 GeV, 920 GeV} \end{footnotesize} \end{quote} or for the BELLE experiment at the KEKB accelerator: \begin{quote} \begin{footnotesize} \ttt{beams = e1, E1} \ttt{beams\_momentum = 8 GeV, 3.5 GeV} \end{footnotesize} \end{quote} \whizard\ lets you know about the beam structure and calculates for you that the center of mass energy corresponds to 10.58 GeV: \begin{quote} \begin{footnotesize} \begin{Verbatim} | Beam structure: e-, e+ | momentum = 8.000000000000E+00, 3.500000000000E+00 | Beam data (collision): | e- (mass = 5.1099700E-04 GeV) | e+ (mass = 5.1099700E-04 GeV) | sqrts = 1.058300530253E+01 GeV | Beam structure: lab and c.m. frame differ \end{Verbatim} \end{footnotesize} \end{quote} It is also possible to specify beams for decaying particles, where \ttt{beams\_momentum} then only has a single argument, e.g.: \begin{quote} \begin{footnotesize} \ttt{process zee = Z => "e-", "e+"} \\ \ttt{beams = Z} \\ \ttt{beams\_momentum = 500 GeV} \\ \ttt{simulate (zee) \{ n\_events = 100 \} } \end{footnotesize} \end{quote} This would corresponds to a beam of $Z$ bosons with a momentum of 500 GeV. Note, however, that \whizard\ will always do the integration of the particle width in the particle's rest frame, while the moving beam is then only taken into account for the frame of reference for the simulation. Further options then simply having different beam energies describe a non-vanishing between the two incoming beams. Such concepts are quite common e.g. for linear colliders to improve the beam properties in the collimation region at the beam interaction points. Such crossing angles can be specified in the beam setup, too, using the \ttt{beams\_theta} command: \begin{quote} \begin{footnotesize} \ttt{beams = e1, E1} \\ \ttt{beams\_momentum = 500 GeV, 500 GeV} \\ \ttt{beams\_theta = 0, 10 degree} \end{footnotesize} \end{quote} It is important that when a crossing angle is being specified, and the collision system consequently never is the center-of-momentum system, the beam momenta have to explicitly set. Besides a planar crossing angle, one is even able to rotate an azimuthal distance: \begin{quote} \begin{footnotesize} \ttt{beams = e1, E1} \\ \ttt{beams\_momentum = 500 GeV, 500 GeV} \\ \ttt{beams\_theta = 0, 10 degree} \\ \ttt{beams\_phi = 0, 45 degree} \end{footnotesize} \end{quote} %%%%%%%%%%%%%%% \subsection{LHAPDF} \label{sec:lhapdf} For incoming hadron beams, the \ttt{beams} statement specifies which structure functions are used. The simplest example is the study of parton-parton scattering processes at a hadron-hadron collider such as LHC or Tevatron. The \lhapdf\ structure function set is selected by a syntax similar to the process setup, namely the example already shown above: \begin{quote} \begin{footnotesize} \begin{verbatim} beams = p, p => lhapdf \end{verbatim} \end{footnotesize} \end{quote} Note that there are slight differences in using the \lhapdf\ release series 6 and the older \fortran\ \lhapdf\ release series 5, at least concerning the naming conventions for the PDF sets~\footnote{Until \whizard\ version 2.2.1 including, only the \lhapdf\ series 5 was supported, while from version 2.2.2 on also the \lhapdf\ release series 6 has been supported.}. The above \ttt{beams} statement selects a default \lhapdf\ structure-function set for both proton beams (which is the \ttt{CT10} central set for \lhapdf\ 6, and \ttt{cteq6ll.LHpdf} central set for \lhapdf 5). The structure function will apply for all quarks, antiquarks, and the gluon as far as supported by the particular \lhapdf\ set. Choosing a different set is done by adding the filename as a local option to the \ttt{lhapdf} keyword: \begin{quote} \begin{footnotesize} \begin{verbatim} beams = p, p => lhapdf $lhapdf_file = "MSTW2008lo68cl" \end{verbatim} \end{footnotesize} \end{quote} for the actual \lhapdf\ 6 series, and \begin{quote} \begin{footnotesize} \begin{verbatim} beams = p, p => lhapdf $lhapdf_file = "MSTW2008lo68cl.LHgrid" \end{verbatim} \end{footnotesize} \end{quote} for \lhapdf 5.Similarly, a member within the set is selected by the numeric variable \verb|lhapdf_member| (for both release series of \lhapdf). In some cases, different structure functions have to be chosen for the two beams. For instance, we may look at $ep$ collisions: \begin{quote} \begin{footnotesize} \begin{verbatim} beams = "e-", p => none, lhapdf \end{verbatim} \end{footnotesize} \end{quote} Here, there is a list of two independent structure functions (each with its own option set, if applicable) which applies to the two beams. Another mixed case is $p\gamma$ collisions, where the photon is to be resolved as a hadron. The simple assignment \begin{quote} \begin{footnotesize} \begin{verbatim} beams = p, gamma => lhapdf, lhapdf_photon \end{verbatim} \end{footnotesize} \end{quote} will be understood as follows: \whizard\ selects the appropriate default structure functions (here we are using \lhapdf\ 5 as an example as the support of photon and pion PDFs in \lhapdf\ 6 has been dropped), \ttt{cteq6ll.LHpdf} for the proton and \ttt{GSG960.LHgrid} for the photon. The photon case has an additional integer-valued parameter \verb|lhapdf_photon_scheme|. (There are also pion structure functions available.) For modifying the default, you have to specify separate structure functions \begin{quote} \begin{footnotesize} \begin{verbatim} beams = p, gamma => lhapdf, lhapdf_photon $lhapdf_file = ... $lhapdf_photon_file = ... \end{verbatim} \end{footnotesize} \end{quote} Finally, the scattering of elementary photons on partons is described by \begin{quote} \begin{footnotesize} \begin{verbatim} beams = p, gamma => lhapdf, none \end{verbatim} \end{footnotesize} \end{quote} Note that for \lhapdf\ version 5.7.1 or higher and for PDF sets which support it, photons can be used as partons. There is one more option for the \lhapdf\ PDFs, namely to specify the path where the \lhapdf\ PDF sets reside: this is done with the string variable \ttt{\$lhapdf\_dir = "{\em }"}. Usually, it is not necessary to set this because \whizard\ detects this path via the \ttt{lhapdf-config} script during configuration, but in the case paths have been moved, or special files/special locations are to be used, the user can specify this location explicitly. %%%%%%%%%%%%%%% \subsection{Built-in PDFs} \label{sec:built-in-pdf} In addition to the possibility of linking against \lhapdf, \whizard\ comes with a couple of built-in PDFs which are selected via the \verb?pdf_builtin? keyword % \begin{quote} \begin{footnotesize} \begin{verbatim} beams = p, p => pdf_builtin \end{verbatim} \end{footnotesize} \end{quote} % The default PDF set is CTEQ6L, but other choices are also available by setting the string variable \verb?$pdf_builtin_set? to an appropiate value. E.g, modifying the above setup to % \begin{quote} \begin{footnotesize} \begin{verbatim} beams = p, p => pdf_builtin $pdf_builtin_set = "mrst2004qedp" \end{verbatim} \end{footnotesize} \end{quote} % would select the proton PDF from the MRST2004QED set. A list of all currently available PDFs can be found in Table~\ref{tab:pdfs}. % \begin{table} \centerline{\begin{tabular}{|l||l|p{0.2\textwidth}|l|} \hline Tag & Name & Notes & References \\\hline\hline % \ttt{cteq6l} & CTEQ6L & \mbox{}\hfill---\hfill\mbox{} & \cite{Pumplin:2002vw} \\\hline \ttt{cteq6l1} & CTEQ6L1 & \mbox{}\hfill---\hfill\mbox{} & \cite{Pumplin:2002vw} \\\hline \ttt{cteq6d} & CTEQ6D & \mbox{}\hfill---\hfill\mbox{} & \cite{Pumplin:2002vw} \\\hline \ttt{cteq6m} & CTEQ6M & \mbox{}\hfill---\hfill\mbox{} & \cite{Pumplin:2002vw} \\\hline \hline \ttt{mrst2004qedp} & MRST2004QED (proton) & includes photon & \cite{Martin:2004dh} \\\hline \hline \ttt{mrst2004qedn} & MRST2004QED (neutron) & includes photon & \cite{Martin:2004dh} \\\hline \hline \ttt{mstw2008lo} & MSTW2008LO & \mbox{}\hfill---\hfill\mbox{} & \cite{Martin:2009iq} \\\hline \ttt{mstw2008nlo} & MSTW2008NLO & \mbox{}\hfill---\hfill\mbox{} & \cite{Martin:2009iq} \\\hline \ttt{mstw2008nnlo} & MSTW2008NNLO & \mbox{}\hfill---\hfill\mbox{} & \cite{Martin:2009iq} \\\hline \hline \ttt{ct10} & CT10 & \mbox{}\hfill---\hfill\mbox{} & \cite{Lai:2010vv} \\\hline \hline \ttt{CJ12\_max} & CJ12\_max & \mbox{}\hfill---\hfill\mbox{} & \cite{Owens:2012bv} \\\hline \ttt{CJ12\_mid} & CJ12\_mid & \mbox{}\hfill---\hfill\mbox{} & \cite{Owens:2012bv} \\\hline \ttt{CJ12\_min} & CJ12\_min & \mbox{}\hfill---\hfill\mbox{} & \cite{Owens:2012bv} \\\hline \hline \ttt{CJ15LO} & CJ15LO & \mbox{}\hfill---\hfill\mbox{} & \cite{Accardi:2016qay} \\\hline \ttt{CJ15NLO} & CJ15NLO & \mbox{}\hfill---\hfill\mbox{} & \cite{Accardi:2016qay} \\\hline \hline \ttt{mmht2014lo} & MMHT2014LO & \mbox{}\hfill---\hfill\mbox{} & \cite{Harland-Lang:2014zoa} \\\hline \ttt{mmht2014nlo} & MMHT2014NLO & \mbox{}\hfill---\hfill\mbox{} & \cite{Harland-Lang:2014zoa} \\\hline \ttt{mmht2014nnlo} & MMHT2014NNLO & \mbox{}\hfill---\hfill\mbox{} & \cite{Harland-Lang:2014zoa} \\\hline \hline \ttt{CT14LL} & CT14LLO & \mbox{}\hfill---\hfill\mbox{} & \cite{Dulat:2015mca} \\\hline \ttt{CT14L} & CT14LO & \mbox{}\hfill---\hfill\mbox{} & \cite{Dulat:2015mca} \\\hline \ttt{CT14N} & CT1414NLO & \mbox{}\hfill---\hfill\mbox{} & \cite{Dulat:2015mca} \\\hline \ttt{CT14NN} & CT14NNLO & \mbox{}\hfill---\hfill\mbox{} & \cite{Dulat:2015mca} \\\hline \hline % \end{tabular}} \caption{All PDF sets available as builtin sets. The two MRST2004QED sets also contain a photon.} \label{tab:pdfs} \end{table} The two MRST2004QED sets also contain the photon as a parton, which can be used in the same way as for \lhapdf\ from v5.7.1 on. Note, however, that there is no builtin PDF that contains a photon structure function. There is a \ttt{beams} structure function specifier \ttt{pdf\_builtin\_photon}, but at the moment this throws an error. It just has been implemented for the case that in future versions of \whizard\ a photon structure function might be included. Note that in general only the data sets for the central values of the different PDFs ship with \whizard. Using the error sets is possible, i.e. it is supported in the syntax of the code, but you have to download the corresponding data sets from the web pages of the PDF fitting collaborations. %%%%%%%%%%%%%%% \subsection{HOPPET $b$ parton matching} When the \hoppet\ tool~\cite{Salam:2008qg} for hadron-collider PDF structure functions and their manipulations are correctly linked to \whizard, it can be used for advanced calculations and simulations of hadron collider physics. Its main usage inside \whizard\ is for matching schemes between 4-flavor and 5-flavor schemes in $b$-parton initiated processes at hadron colliders. Note that in versions 2.2.0 and 2.2.1 it only worked together with \lhapdf\ version 5, while with the \lhapdf\ version 6 interface from version 2.2.2 on it can be used also with the modern version of PDFs from \lhapdf. Furthermore, from version 2.2.2, the \hoppet\ $b$ parton matching also works for the builtin PDFs. It depends on the corresponding process and the energy scales involved whether it is a better description to use the $g\to b\bar b$ splitting from the DGLAP evolution inside the PDF and just take the $b$ parton content of a PDF, e.g. in BSM Higgs production for large $\tan\beta$: $pp \to H$ with a partonic subprocess $b\bar b \to H$, or directly take the gluon PDFs and use $pp \to b\bar b H$ with a partonic subprocess $gg \to b \bar b H$. Elaborate schemes for a proper matching between the two prescriptions have been developed and have been incorporated into the \hoppet\ interface. Another prime example for using these matching schemes is single top production at hadron colliders. Let us consider the following setup: \begin{quote} \begin{footnotesize} \begin{Verbatim} process proc1 = b, u => t, d process proc2 = u, b => t, d process proc3 = g, u => t, d, B { $restrictions = "2+4 ~ W+" } process proc4 = u, g => t, d, B { $restrictions = "1+4 ~ W+" } beams = p,p => pdf_builtin sqrts = 14 TeV ?hoppet_b_matching = true $sample = "single_top_matched" luminosity = 1 / 1 fbarn simulate (proc1, proc2, proc3, proc4) \end{Verbatim} \end{footnotesize}%$ \end{quote} The first two processes are single top production from $b$ PDFs, the last two processes contain an explicit $g\to b\bar b$ splitting (the restriction, cf. Sec.~\ref{sec:process options} has been placed in order to single out the single top production signal process). PDFs are then chosen from the default builtin PDF (which is \ttt{CTEQ6L}), and the \hoppet\ matching routines are switched on by the flag \ttt{?hoppet\_b\_matching}. %%%%%%%%%%%%%%% \subsection{Lepton Collider ISR structure functions} \label{sec:lepton_isr} Initial state QED radiation off leptons is an important feature at all kinds of lepton colliders: the radiative return to the $Z$ resonance by ISR radiation was in fact the largest higher-order effect for the SLC and LEP I colliders. The soft-collinear and soft photon radiation can indeed be resummed/exponentiated to all orders in perturbation theory~\cite{Gribov:1972rt}, while higher orders in hard-collinear photons have to be explicitly calculated order by order~\cite{Kuraev:1985hb,Skrzypek:1990qs}. \whizard\ has an intrinsic implementation of the lepton ISR structure function that includes all orders of soft and soft-collinear photons as well as up to the third order in hard-collinear photons. It can be switched on by the following statement: \begin{quote} \begin{footnotesize} \begin{Verbatim} beams = e1, E1 => isr \end{Verbatim} \end{footnotesize} \end{quote} As the ISR structure function is a single-beam structure function, this expression is synonymous for \begin{quote} \begin{footnotesize} \begin{Verbatim} beams = e1, E1 => isr, isr \end{Verbatim} \end{footnotesize} \end{quote} The ISR structure function can again be applied to only one of the two beams, e.g. in a HERA-like setup: \begin{quote} \begin{footnotesize} \begin{Verbatim} beams = e1, p => isr, pdf_builtin \end{Verbatim} \end{footnotesize} \end{quote} Their are several options for the lepton-collider ISR structure function that are summarized in the following: \vspace{2mm} \centerline{\begin{tabular}{|l|l|l|}\hline Parameter & Default & Meaning \\\hline\hline \ttt{isr\_alpha} & \ttt{0}/intrinsic & value of $\alpha_{QED}$ for ISR \\\hline \ttt{isr\_order} & \ttt{3} & max. order of hard-collinear photon emission \\\hline \ttt{isr\_mass} & \ttt{0}/intrinsic & mass of the radiating lepton \\\hline \ttt{isr\_q\_max} & \ttt{0}/$\sqrt{s}$ & upper cutoff for ISR \\\hline \hline \ttt{?isr\_recoil} & \ttt{false} & flag to switch on recoil/$p_T$ (\emph{deprecated})\\\hline \ttt{?isr\_keep\_energy} & \ttt{false} & recoil flag: conserve energy in splitting (\emph{deprecated}) \\\hline \end{tabular}}\mbox{} The maximal order of the hard-collinear photon emission taken into account by \whizard\ is set by the integer variable \ttt{isr\_order}; the default is the maximally available order of three. With the variable \ttt{isr\_alpha}, the value of the QED coupling constant $\alpha_{QED}$ used in the ISR structure function can be set. The default is taken from the active physics model. The mass of the radiating lepton (in most cases the electron) is set by \ttt{isr\_mass}; again the default is taken from the active physics model. Furthermore, the upper integration border for the ISR structure function which acts roughly as an upper hardness cutoff for the emitted photons, can be set through \ttt{isr\_q\_max}; if not set, the collider energy (possibly after beamstrahlung, cf. Sec.~\ref{sec:beamstrahlung}) $\sqrt{s}$ (or $\sqrt{\widehat{s}}$) is taken. Note that \whizard\ accounts for the exclusive effects of ISR radiation at the moment by a single (hard, resolved) photon in the event; a more realistic treatment of exclusive ISR photons in simulation is foreseen for a future version. While the ISR structure function is evaluated in the collinear limit, it is possible to generate transverse momentum for both the radiated photons and the recoiling partonic system. We recommend to stick to the collinear approximation for the integration step. Integration cuts should be set up such that they do not significantly depend on photon transverse momentum. In a subsequent simulation step, it is possible to transform the events with collinear ISR radiation into more realistic events with non-collinear radiation. To this end, \whizard\ provides a separate ISR photon handler which can be activated in the simulation step. The algorithm operates on the partonic event: it takes the radiated photons and the partons entering the hard process, and applies a $p_T$ distribution to those particles and their interaction products, i.e., all outgoing particles. Cuts that depend on photon $p_T$ may be applied to the modified events. For details on the ISR photon handler, cf.\ Sec.~\ref{sec:isr-photon-handler}. {\footnotesize The flag \ttt{?isr\_recoil} switches on $p_T$ recoil of the emitting lepton against photon radiation during integration; per default it is off. The flag \ttt{?isr\_keep\_energy} controls the mode of on-shell projection for the splitting process with $p_T$. Note that this feature is kept for backwards compatibility, but should not be used for new simulations. The reason is as follows: For a fraction of events, $p_T$ will become significant, and (i) energy/momentum non-conservation, applied to both beams separately, can lead to unexpected and unphysical effects, and (ii) the modified momenta enter the hard process, so the collinear approximation used in the ISR structure function computation does not hold. } %%%%%%%%%%%%%%% \subsection{Lepton Collider Beamstrahlung} \label{sec:beamstrahlung} At linear lepton colliders, the macroscopic electromagnetic interaction of the bunches leads to a distortion of the spectrum of the bunches that is important for an exact simulation of the beam spectrum. There are several methods to account for these effects. The most important tool to simulate classical beam-beam interactions in lepton-collider physics is \ttt{GuineaPig++}~\cite{Schulte:1998au,Schulte:1999tx,Schulte:2007zz}. A direct interface between this tool \ttt{GuineaPig++} and \whizard\ had existed as an inofficial add-on to the legacy branch \whizard\ttt{1}, but is no longer applicable in \whizard\ttt{2}. A \whizard-internal interface is foreseen for the very near future, most probably within this v2.2 release. Other options are to use parameterizations of the beam spectrum that have been included in the package \circeone~\cite{CIRCE} which has been interfaced to \whizard\ since version v1.20 and been included in the \whizard\ttt{2} release series. Another option is to generate a beam spectrum externally and then read it in as an ASCII data file, cf. Sec.~\ref{sec:beamevents}. More about this can be found in a dedicated section on lepton collider spectra, Sec.~\ref{sec:beamspectra}. In this section, we discuss the usage of beamstrahlung spectra by means of the \circeone\ package. The beamstrahlung spectra are true spectra, so they have to be applied to pairs of beams, and an application to only one beam is meaningless. They are switched on by this \ttt{beams} statement including structure functions: \begin{quote} \begin{footnotesize} \begin{Verbatim} beams = e1, E1 => circe1 \end{Verbatim} \end{footnotesize} \end{quote} It is important to note that the parameterization of the beamstrahlung spectra within \circeone\ contain also processes where $e\to\gamma$ conversions have been taking place, i.e. also hard processes with one (or two) initial photons can be simulated with beamstrahlung switched on. In that case, the explicit photon flags, \ttt{?circe1\_photon1} and \ttt{?circe1\_photon2}, for the two beams have to be properly set, e.g. (ordering in the final state does not play a role): \begin{quote} \begin{footnotesize} \begin{Verbatim} process proc1 = A, e1 => A, e1 sqrts = 500 GeV beams = e1, E1 => circe1 ?circe1_photon1 = true integrate (proc1) process proc2 = e1, A => A, e1 sqrts = 1000 GeV beams = e1, A => circe1 ?circe1_photon2 = true \end{Verbatim} \end{footnotesize} \end{quote} or \begin{quote} \begin{footnotesize} \begin{Verbatim} process proc1 = A, A => Wp, Wm sqrts = 200 GeV beams = e1, E1 => circe1 ?circe1_photon1 = true ?circe1_photon2 = true ?circe1_generate = false \end{Verbatim} \end{footnotesize} \end{quote} In all cases (one or both beams with photon conversion) the beam spectrum applies to both beams simultaneously. In the last example ($\gamma\gamma\to W^+W^-$) the default \circeone\ generator mode was turned off by unsetting \verb|?circe1_generate|. In the other examples this flag is set, by default. For standard use cases, \circeone\ implements a beam-event generator inside the \whizard\ generator, which provides beam-event samples with correctly distributed probability. For electrons, the beamstrahlung spectrum sharply peaks near maximum energy. This distribution is most efficiently handled by the generator mode. By contrast, in the $\gamma\gamma$ mode, the beam-event c.m.\ energy is concentrated at low values. For final states with low invariant mass, which are typically produced by beamstrahlung photons, the generator mode is appropriate. However, the $W^+W^-$ system requires substantial energy, and such events will be very rare in the beam-event sample. Switching off the \circeone\ generator mode solves this problem. This is an overview over all options and flags for the \circeone\ setup for lepton collider beamstrahlung: \vspace{2mm} \centerline{\begin{tabular}{|l|l|l|}\hline Parameter & Default & Meaning \\\hline\hline \ttt{?circe1\_photon1} & \ttt{false} & $e\to\gamma$ conversion for beam 1 \\\hline \ttt{?circe1\_photon2} & \ttt{false} & $e\to\gamma$ conversion for beam 2 \\\hline \ttt{circe1\_sqrts} & $\sqrt{s}$ & collider energy for the beam spectrum \\\hline \ttt{?circe1\_generate} & \ttt{true} & flag for the \circeone\ generator mode \\\hline \ttt{?circe1\_map} & \ttt{true} & flag to apply special phase-space mapping \\\hline \ttt{circe1\_mapping\_slope} & \ttt{2.} & value of PS mapping exponent \\\hline \ttt{circe1\_eps} & \ttt{1E-5} & parameter for mapping of spectrum peak position \\\hline \ttt{circe1\_ver} & \ttt{0} & internal version of \circeone\ package \\\hline \ttt{circe1\_rev} & \ttt{0}/most recent & internal revision of \circeone\ \\\hline \ttt{\$circe1\_acc} & \ttt{SBAND} & accelerator type \\\hline \ttt{circe1\_chat} & \ttt{0} & chattiness/verbosity of \circeone \\\hline \end{tabular}}\mbox{} The collider energy relevant for the beamstrahlung spectrum is set by \ttt{circe1\_sqrts}. As a default, this is always the value of \ttt{sqrts} set in the \sindarin\ script. However, sometimes these values do not match, e.g. the user wants to simulate $t\bar t h$ at \ttt{sqrts = 550 GeV}, but the only available beam spectrum is for 500 GeV. In that case, \ttt{circe1\_sqrts = 500 GeV} has to be set to use the closest possible available beam spectrum. As mentioned in the discussion of the examples above, in \circeone\ there are two options to use the beam spectra for beamstrahlung: intrinsic semi-analytic approximation formulae for the spectra, or a Monte-Carlo sampling of the sampling. The second possibility always give a better description of the spectra, and is the default for \whizard. It can, however, be switched off by setting the flag \ttt{?circe1\_generate} to \ttt{false}. As the beamstrahlung spectra are sharply peaked at the collider energy, but still having long tails, a mapping of the spectra for an efficient phase-space sampling is almost mandatory. This is the default in \whizard, which can be changed by the flag \ttt{?circe1\_map}. Also, the default exponent for the mapping can be changed from its default value \ttt{2.} with the variable \ttt{circe1\_mapping\_slope}. It is important to efficiently sample the peak position of the spectrum; the effective ratio of the peak to the whole sampling interval can be set by the parameter \ttt{circe1\_eps}. The integer parameter \ttt{circe1\_chat} sets the chattiness or verbosity of the \circeone\ package, i.e. how many messages and warnings from the beamstrahlung generation/sampling will be issued. The actual internal version and revision of the \circeone\ package are set by the two integer parameters \ttt{circe1\_ver} and \ttt{circe1\_rev}. The default is in any case always the newest version and revision, while older versions are still kept for backwards compatibility and regression testing. Finally, the geometry and design of the accelerator type is set with the string variable \ttt{\$circe1\_acc}: it contains the possible options for the old \ttt{"SBAND"} and \ttt{"XBAND"} setups, as well as the \ttt{"TESLA"} and JLC/NLC SLAC design \ttt{"JLCNLC"}. The setups for the most important energies of the ILC as they are summarized in the ILC TDR~\cite{Behnke:2013xla,Baer:2013cma,Adolphsen:2013jya,Adolphsen:2013kya} are available as \ttt{ILC}. Beam spectra for the CLIC~\cite{Aicheler:2012bya,Lebrun:2012hj,Linssen:2012hp} linear collider are much more demanding to correctly simulate (due to the drive beam concept; only the low-energy modes where the drive beam is off can be simulated with the same setup as the abovementioned machines). Their setup will be supported soon in one of the upcoming \whizard\ versions within the \circetwo\ package. An example of how to generate beamstrahlung spectra with the help of the package \circetwo\ (that is also a part of \whizard) is this: \begin{quote} \begin{footnotesize} \begin{Verbatim} process eemm = e1, E1 => e2, E2 sqrts = 500 GeV beams = e1, E1 => circe2 $circe2_file = "ilc500.circe" $circe2_design = "ILC" ?circe_polarized = false \end{Verbatim} \end{footnotesize}%$ \end{quote} Here, the ILC design is used for a beamstrahlung spectrum at 500 GeV nominal energy, with polarization averaged (hence, the setting of polarization to \ttt{false}). A list of all available options can be found in Sec.~\ref{sec:photoncoll}. More technical details about the simulation of beamstrahlung spectra see the documented source code of the \circeone\ package, as well as Chap.~\ref{chap:hardint}. In the next section, we discuss how to read in beam spectra from external files. %%%%%%%%%%%%%%% \subsection{Beam events} \label{sec:beamevents} As mentioned in the previous section, beamstrahlung is one of the crucial ingredients for a realistic simulation of linear lepton colliders. One option is to take a pre-generated beam spectrum for such a machine, and make it available for simulation within \whizard\ as an external ASCII data file. Such files basically contain only pairs of energy fractions of the nominal collider energy $\sqrt{s}$ ($x$ values). In \whizard\ they can be used in simulation with the following \ttt{beams} statement: \begin{quote} \begin{footnotesize} \begin{Verbatim} beams = e1, E1 => beam_events $beam_events_file = "" \end{Verbatim} \end{footnotesize}%$ \end{quote} Note that beam spectra must always be pair spectra, i.e. they are automatically applied to both beam simultaneously. Beam spectra via external files are expected to reside in the current working directory. Alternatively, \whizard\ searches for them in the install directory of \whizard\ in \ttt{share/beam-sim}. There you can find an example file, \ttt{uniform\_spread\_2.5\%.dat} for such a beam spectrum. The only possible parameter that can be set is the flag \ttt{?beam\_events\_warn\_eof} whose default is \ttt{true}. This triggers the issuing of a warning when the end of file of an external beam spectrum file is reached. In such a case, \whizard\ starts to reuse the same file again from the beginning. If the available data points in the beam events file are not big enough, this could result in an insufficient sampling of the beam spectrum. %%%%%%%%%%%%%%% \subsection{Gaussian beam-energy spread} \label{sec:gaussian} Real beams have a small energy spread. If beamstrahlung is small, the spread may be approximately described as Gaussian. As a replacement for the full simulation that underlies \ttt{CIRCE2} spectra, it is possible to impose a Gaussian distributed beam energy, separately for each beam. \begin{quote} \begin{footnotesize} \begin{Verbatim} beams = e1, E1 => gaussian gaussian_spread1 = 0.1\% gaussian_spread2 = 0.2\% \end{Verbatim} \end{footnotesize}%$ \end{quote} (Note that the \% sign means multiplication by 0.01, as it should.) The spread values are defined as the $\sigma$ value of the Gaussian distribution, i.e., $2/3$ of the events are within $\pm 1\sigma$ for each beam, respectively. %%%%%%%%%%%%%%%% \subsection{Equivalent photon approximation} \label{sec:epa} The equivalent photon approximation (EPA) uses an on-shell approximation for the $e \to e\gamma$ collinear splitting to allow the simulation of photon-induced backgrounds in lepton collider physics. The original concept is that of the Weizs\"acker-Williams approximation~\cite{vonWeizsacker:1934sx,Williams:1934ad,Budnev:1974de}. This is a single-beam structure function that can be applied to both beams, or also to one beam only. Usually, there are some simplifications being made in the derivation. The formula which is implemented here and seems to be the best for the QCD background for low-$p_T$ hadrons, corresponds to Eq.~(6.17) of Ref.~\cite{Budnev:1974de}. As this reference already found, this leads to an "overshooting" of accuracy, and especially in the high-$x$ (high-energy) region to wrong results. This formula corresponds to \begin{equation} \label{eq:budnev_617} f(x) = \frac{\alpha}{\pi} \frac{1}{x} \biggl[ \left( \bar{x} + \frac{x^2}{2} \right) \log \frac{Q^2_{\text{max}}}{Q^2_{\text{min}}} - \left( 1 - \frac{x}{2} \right)^2 \log \frac{x^2 + \tfrac{Q^2_{\text{max}}}{E^2}}{x^2 + \tfrac{Q^2_{\text{min}}}{E^2}} - \frac{m_e^2 x^2}{Q^2_{\text{min}}} \left( 1 - \frac{Q^2_{\text{min}}}{Q^2_{\text{max}}} \right) \biggr] \qquad . \end{equation} Here, $x$ is the ratio of the photon energy (called frequency $\omega$ in~\cite{Budnev:1974de} over the original electron (or positron) beam energy $E$. The energy of the electron (or positron) after the splitting is given by $\bar{x} = 1-x$. The simplified version is the one that corresponds to many publications about the EPA during SLC and LEP times, and corresponds to the $q^2$ integration of Eq.~(6.16e) in~\cite{Budnev:1974de}, where $q^2$ is the virtuality or momentum transfer of the photon in the EPA: \begin{equation} \label{eq:budnev_616e} f(x) = \frac{\alpha}{\pi} \frac{1}{x} \biggl[ \left( \bar{x} + \frac{x^2}{2} \right) \log \frac{Q^2_{\text{max}}}{Q^2_{\text{min}}} - \frac{m_e^2 x^2}{Q^2_{\text{min}}} \left( 1 - \frac{Q^2_{\text{min}}}{Q^2_{\text{max}}} \right) \biggr] \qquad . \end{equation} While Eq.~(\ref{eq:budnev_617}) is supposed to be the better choice for simulating hadronic background like low-$p_T$ hadrons and should be applied for the low-$x$ region of the EPA, Eq.~(\ref{eq:budnev_616e}) seems better suited for high-$x$ simulations like the photoproduction of BSM resonances etc. Note that the first term in Eqs.~(\ref{eq:budnev_617}) and (\ref{eq:budnev_616e}) is the standard Altarelli-Parisi QED splitting function of electron, $P_{e\to e\gamma}(x) \propto 1 + (1-x)^2$, while the last term in both equations is the default power correction. The two parameters $Q^2_{\text{max}}$ and $Q^2_{\text{min}}$ are the integration boundaries of the photon virtuality integration. Usually, they are given by the kinematic limits: \begin{equation} Q^2_{\text{min}} = \frac{m_e^2 x^2}{\bar{x}} \qquad\qquad Q^2_{\text{max}} = 4 E^2 \bar{x} = s \bar{x} \qquad . \end{equation} For low-$p_T$ hadron simulations, it is not a good idea to take the kinematic limit as an upper limit, but one should cut the simulation off at a hadronic scale like e.g. a multiple of the $\rho$ mass. The user can switch between the two different options using the setting \begin{quote} \begin{footnotesize} \begin{Verbatim} $epa_mode = "default" \end{Verbatim} \end{footnotesize} \end{quote} or \begin{quote} \begin{footnotesize} \begin{Verbatim} $epa_mode = "Budnev_617" \end{Verbatim} \end{footnotesize} \end{quote} for Eq.~(\ref{eq:budnev_617}), while Eq.~(\ref{eq:budnev_616e}) can be chosen with \begin{quote} \begin{footnotesize} \begin{Verbatim} $epa_mode = "Budnev_616e" \end{Verbatim} \end{footnotesize} \end{quote} Note that a thorough study for high-energy $e^+e^-$ colliders regarding the suitability of different EPA options is still lacking. For testing purposes also three more variants or simplifications of Eq.~(\ref{eq:budnev_616e}) are implemented: the first, steered by \ttt{\$epa\_mode = log\_power} uses simply $Q^2_{\text{max}} = s$. This is also the case for the two other method. But the switch \ttt{\$epa\_mode = log\_simple} uses just \ttt{epa\_mass} (cf. below) as $Q^2_{\text{min}}$. The final simplification is to drop the power correction, which can be chosen with \ttt{\$epa\_mode = log}. This corresponds to the simple formula: \begin{equation} f(x) = \frac{\alpha}{2\pi} \frac{1}{x} \, \log\frac{s}{m^2} \qquad . \end{equation} Examples for the application of the EPA in \whizard\ are: \begin{quote} \begin{footnotesize} \begin{Verbatim} beams = e1, E1 => epa \end{Verbatim} \end{footnotesize} \end{quote} or for a single beam: \begin{quote} \begin{footnotesize} \begin{Verbatim} beams = e1, p => epa, pdf_builtin \end{Verbatim} \end{footnotesize} \end{quote} The last process allows the reaction of (quasi-) on-shell photons with protons. In the following, we collect the parameters and flags that can be adjusted when using the EPA inside \whizard: \vspace{2mm} \centerline{\begin{tabular}{|l|l|l|}\hline Parameter & Default & Meaning \\\hline\hline \ttt{epa\_alpha} & \ttt{0}/intrinsic & value of $\alpha_{QED}$ for EPA \\\hline \ttt{epa\_x\_min} & \ttt{0.} & soft photon cutoff in $x$ (mandatory) \\\hline \ttt{epa\_q\_min} & \ttt{0.} & minimal $\gamma$ momentum transfer \\\hline \ttt{epa\_mass} & \ttt{0}/intrinsic & mass of the radiating fermion (mandatory) \\\hline \ttt{epa\_q\_max} & \ttt{0}/$\sqrt{s}$ & upper cutoff for EPA \\\hline \ttt{?epa\_recoil} & \ttt{false} & flag to switch on recoil/$p_T$ \\\hline \ttt{?epa\_keep\_energy} & \ttt{false} & recoil flag to conserve energy in splitting \\\hline \end{tabular}}\mbox{} The adjustable parameters are partially similar to the parameters in the QED initial-state radiation (ISR), cf. Sec.~\ref{sec:lepton_isr}: the parameter \ttt{epa\_alpha} sets the value of the electromagnetic coupling constant, $\alpha_{QED}$ used in the EPA structure function. If not set, this is taken from the value inside the active physics model. The same is true for the mass of the particle that radiates the photon of the hard interaction, which can be reset by the user with the variable \ttt{epa\_mass}. There are two dimensionful scale parameters, the minimal momentum transfer to the photon, \ttt{epa\_q\_min}, which must not be zero, and the upper momentum-transfer cutoff for the EPA structure function, \ttt{epa\_q\_max}. The default for the latter value is the collider energy, $\sqrt{s}$, or the energy reduced by another structure function like e.g. beamstrahlung, $\sqrt{\hat{s}}$. Furthermore, there is a soft-photon regulator for the splitting function in $x$ space, \ttt{epa\_x\_min}, which also has to be explicitly set different from zero. Hence, a minimal viable scenario that will be accepted by \whizard\ looks like this: \begin{quote} \begin{footnotesize} \begin{Verbatim} beams = e1, E1 => epa epa_q_min = 5 GeV epa_x_min = 0.01 \end{Verbatim} \end{footnotesize} \end{quote} Finally, like the ISR case in Sec.~\ref{sec:lepton_isr}, there is a flag to consider the recoil of the photon against the radiating electron by setting \ttt{?epa\_recoil} to \ttt{true} (default: \ttt{false}). Though in principle processes like $e^+ e^- \to e^+ e^- \gamma \gamma$ where the two photons have been created almost collinearly and then initiate a hard process could be described by exact matrix elements and exact kinematics. However, the numerical stability in the very far collinear kinematics is rather challenging, such that the use of the EPA is very often an acceptable trade-off between quality of the description on the one hand and numerical stability and speed on the other hand. In the case, the EPA is set after a second structure function like a hadron collider PDF, there is a flavor summation over the quark constituents inside the proton, which are then the radiating fermions for the EPA. Here, the masses of all fermions have to be identical. More about the physics of the equivalent photon approximation can be found in Chap.~\ref{chap:hardint}. %%%%%%%%%%%%%%% \subsection{Effective $W$ approximation} \label{sec:ewa} An approach similar to the equivalent photon approximation (EPA) discussed in the previous section Sec.~\ref{sec:epa}, is the usage of a collinear splitting function for the radiation of massive electroweak vector bosons $W$/$Z$, the effective $W$ approximation (EWA). It has been developed for the description of high-energy weak vector-boson fusion and scattering processes at hadron colliders, particularly the Superconducting Super-Collider (SSC). This was at a time when the simulation of $2\to 4$ processes war still very challenging and $2\to 6$ processes almost impossible, such that this approximation was the only viable solution for the simulation of processes like $pp \to jjVV$ and subsequent decays of the bosons $V \equiv W, Z$. Unlike the EPA, the EWA is much more involved as the structure functions do depend on the isospin of the radiating fermions, and are also different for transversal and longitudinal polarizations. Also, a truely collinear kinematics is never possible due to the finite $W$ and $Z$ boson masses, which start becoming more and more negligible for energies larger than the nominal LHC energy of 14 TeV. Though in principle all processes for which the EWA might be applicable are technically feasible in \whizard\ to be generated also via full matrix elements, the EWA has been implemented in \whizard\ for testing purposes, backwards compatibility and comparison with older simulations. Like the EPA, it is a single-beam structure function that can be applied to one or both beams. We only give an example for both beams here, this is for a 3 TeV CLIC collider: \begin{quote} \begin{footnotesize} \begin{Verbatim} sqrts = 3 TeV beams = e1, E1 => ewa \end{Verbatim} \end{footnotesize} \end{quote} And this is for LHC or a higher-energy follow-up collider (which also shows the concatenation of the single-beam structure functions, applied to both beams consecutively, cf. Sec.~\ref{sec:concatenation}: \begin{quote} \begin{footnotesize} \begin{Verbatim} sqrts = 14 TeV beams = p, p => pdf_builtin => ewa \end{Verbatim} \end{footnotesize} \end{quote} Again, we list all the options, parameters and flags that can be adapted for the EWA: \vspace{2mm} \centerline{\begin{tabular}{|l|l|l|}\hline Parameter & Default & Meaning \\\hline\hline \ttt{ewa\_x\_min} & \ttt{0.} & soft $W$/$Z$ cutoff in $x$ (mandatory) \\\hline \ttt{ewa\_mass} & \ttt{0}/intrinsic & mass of the radiating fermion \\\hline \ttt{ewa\_pt\_max} & \ttt{0}/$\sqrt{\hat{s}}$ & upper cutoff for EWA \\\hline \ttt{?ewa\_recoil} & \ttt{false} & recoil switch \\\hline \ttt{?ewa\_keep\_energy} & \ttt{false} & energy conservation for recoil in splitting \\\hline \end{tabular}}\mbox{} First of all, all coupling constants are taken from the active physics model as they have to be consistent with electroweak gauge invariance. Like for EPA, there is a soft $x$ cutoff for the $f \to f V$ splitting, \ttt{ewa\_x\_min}, that has to be set different from zero by the user. Again, the mass of the radiating fermion can be set explicitly by the user; and, also again, the masses for the flavor sum of quarks after a PDF as radiators of the electroweak bosons have to be identical. Also for the EWA, there is an upper cutoff for the $p_T$ of the electroweak boson, that can be set via \ttt{eta\_pt\_max}. Indeed, the transversal $W$/$Z$ structure function is logarithmically divergent in that variable. If it is not set by the user, it is estimated from $\sqrt{s}$ and the splitting kinematics. For the EWA, there is a flag to switch on a recoil for the electroweak boson against the radiating fermion, \ttt{?ewa\_recoil}. Note that this is an experimental feature that is not completely tested. In any case, the non-collinear kinematics violates 4-four momentum conservation, so there are two choices: either to conserve the energy (\ttt{?ewa\_keep\_energy = true}) or to conserve 3-momentum (\ttt{?ewa\_keep\_energy = false}). Momentum conservation for the kinematics is the default. This is due to the fact that for energy conservation, there will be a net total momentum in the event including the beam remnants (ISR/EPA/EWA radiated particles) that leeds to unexpected or unphysical features in the energy distributions of the beam remnants recoiling against the rest of the event. More details about the physics can be found in Chap.~\ref{chap:hardint}. %%%%%%%%%%%%%%% \subsection{Energy scans using structure functions} In \whizard, there is an implementation of a pair spectrum, \ttt{energy\_scan}, that allows to scan the energy dependence of a cross section without actually scanning over the collider energies. Instead, only a single integration at the upper end of the scan interval over the process with an additional pair spectrum structure function performed. The structure function is chosen in such a way, that the distribution of $x$ values of the energy scan pair spectrum translates in a plot over the energy of the final state in an energy scan from \ttt{0} to \ttt{sqrts} for the process under consideration. The simplest example is the $1/s$ fall-off with the $Z$ resonance in $e^+e^- \to \mu^+ \mu^-$, where the syntax is very easy: \begin{quote} \begin{footnotesize} \begin{Verbatim} process eemm = e1, E1 => e2, E2 sqrts = 500 GeV cuts = sqrts_hat > 50 beams = e1, E1 => energy_scan integrate (eemm) \end{Verbatim} \end{footnotesize} \end{quote} The value of \ttt{sqrts = 500 GeV} gives the upper limit for the scan, while the cut effectively let the scan start at 50 GeV. There are no adjustable parameters for this structure function. How to plot the invariant mass distribution of the final-state muon pair to show the energy scan over the cross section, will be explained in Sec.~\ref{sec:analysis}. More details can be found in Chap.~\ref{chap:hardint}. %%%%%%%%%%%%%%% \subsection{Photon collider spectra} \label{sec:photoncoll} One option that has been discussed as an alternative possibility for a high-energy linear lepton collider is to convert the electron and positron beam via Compton backscattering off intense laser beams into photon beams~\cite{Ginzburg:1981vm,Telnov:1989sd,Telnov:1995hc}. Naturally, due to the production of the photon beams and the inherent electron spectrum, the photon beams have a characteristic spectrum. The simulation of such spectra is possible within \whizard\ by means of the subpackage \circetwo, which have been mentioned already in Sec.~\ref{sec:beamstrahlung}. It allows to give a much more elaborate description of a linear lepton collider environment than \circeone\ (which, however, is not in all cases necessary, as the ILC beamspectra for electron/positrons can be perfectly well described with \circeone). Here is a typical photon collider setup where we take a photon-initiated process: \begin{quote} \begin{footnotesize} \begin{Verbatim} process aaww = A, A => Wp, Wm beams = A, A => circe2 $circe2_file = "teslagg_500_polavg.circe" $circe2_design = "TESLA/GG" ?circe2_polarized = false \end{Verbatim} \end{footnotesize}%$ \end{quote} Here, the photons are the initial states initiating the hard scattering. The structure function is \ttt{circe2} which always is a pair spectrum. The list of available options are: \vspace{2mm} \centerline{\begin{tabular}{|l|l|l|}\hline Parameter & Default & Meaning \\\hline\hline \ttt{?circe2\_polarized} & \ttt{true} & spectrum respects polarization info \\\hline \ttt{\$circe2\_file} & -- & name of beam spectrum data file \\\hline \ttt{\$circe2\_design} & \ttt{"*"} & collider design \\\hline \end{tabular}}\mbox{} The only logical flag \ttt{?circe2\_polarized} let \whizard\ know whether it should keep polarization information in the beam spectra or average over polarizations. Naturally, because of the Compton backscattering generation of the photons, photon spectra are always polarized. The collider design can be specified by the string variable \ttt{\$circe2\_design}, where the default setting \ttt{"*"} corresponds to the default of \circetwo\ (which is the TESLA 500 GeV machine as discussed in the TESLA Technical Design Report~\cite{AguilarSaavedra:2001rg,Richard:2001qm}). Note that up to now there have not been any setups for a photon collider option for the modern linear collider concepts like ILC and CLIC. The string variable \ttt{\$circe2\_file} then allows to give the name of the file containing the actual beam spectrum; all files that ship with \whizard\ are stored in the directory \ttt{circe2/share/data}. More details about the subpackage \circetwo\ and the physics it covers, can be found in its own manual and the chapter Chap.~\ref{chap:hardint}. %%%%%%%%%%%%%%% \subsection{Concatenation of several structure functions} \label{sec:concatenation} As has been shown already in Sec.~\ref{sec:epa} and Sec.~\ref{sec:ewa}, it is possible within \whizard\ to concatenate more than one structure function, irrespective of the fact, whether the structure functions are single-beam structure functions or pair spectra. One important thing is whether there is a phase-space mapping for these structure functions. Also, there are some combinations which do not make sense from the physics point of view, for example using lepton-collider ISR for protons, and then afterwards switching on PDFs. Such combinations will be vetoed by \whizard, and you will find an error message like (cf. also Sec.~\ref{sec:errors}): \begin{interaction} ****************************************************************************** ****************************************************************************** *** FATAL ERROR: Beam structure: [....] not supported ****************************************************************************** ****************************************************************************** \end{interaction} Common examples for the concatenation of structure functions are linear collider applications, where beamstrahlung (macroscopic electromagnetic beam-beam interactions) and electron QED initial-state radiation are both switched on: \begin{code} beams = e1, E1 => circe1 => isr \end{code} Another possibility is the simulation of photon-induced backgrounds at ILC or CLIC, using beamstrahlung and equivalent photon approximation (EPA): \begin{code} beams = e1, E1 => circe1 => epa \end{code} or with beam events from a data file: \begin{code} beams = e1, E1 => beam_events => isr \end{code} In hadron collider physics, parton distribution functions (PDFs) are basically always switched on, while afterwards the user could specify to use the effective $W$ approximation (EWA) to simulate high-energy vector boson scattering: \begin{code} sqrts = 100 TeV beams = p, p => pdf_builtin => ewa \end{code} Note that this last case involves a flavor sum over the five active quark (and anti-quark) species $u$, $d$, $c$, $s$, $b$ in the proton, all of which act as radiators for the electroweak vector bosons in the EWA. This would be an example with three structure functions: \begin{code} beams = e1, E1 => circe1 => isr => epa \end{code} %%%%%%%%%%%%%%% \section{Polarization} \label{sec:polarization} %%%%% \subsection{Initial state polarization} \label{sec:initialpolarization} \whizard\ supports polarizing the inital state fully or partially by assigning a nontrivial density matrix in helicity space. Initial state polarization requires a beam setup and is initialized by means of the \ttt{beams\_pol\_density} statement\footnote{Note that the syntax for the specification of beam polarization has changed from version v2.1 to v2.2 and is incompatible between the two release series. The old syntax \ttt{beam\_polarization} with its different polarization constructors has been discarded in favor of a unified syntax.}: \begin{quote} \begin{footnotesize} \begin{verbatim} beams_pol_density = @([]), @([]) \end{verbatim} \end{footnotesize} \end{quote} The command \ttt{beams\_pol\_fraction} gives the degree of polarization of the two beams: \begin{quote} \begin{footnotesize} \begin{verbatim} beams_pol_fraction = , \end{verbatim} \end{footnotesize} \end{quote} Both commands in the form written above apply to scattering processes, where the polarization of both beams must be specified. The \ttt{beams\_pol\_density} and \ttt{beams\_pol\_fraction} are possible with a single beam declaration if a decay process is considered, but only then. While the syntax for the command \ttt{beams\_pol\_fraction} is pretty obvious, the syntax for the actual specification of the beam polarization is more intricate. We start with the polarization fraction: for each beam there is a real number between zero (unpolarized) and one (complete polarization) that can be specified either as a floating point number like \ttt{0.4} or with a percentage: \ttt{40 \%}. Note that the actual arithmetics is sometimes counterintuitive: 80 \% left-handed electron polarization means that 80 \% of the electron beam are polarized, 20 \% are unpolarized, i.e. 20 \% have half left- and half right-handed polarization each. Hence, 90 \% of the electron beam is left-handed, 10 \% is right-handed. How does the specification of the polarization work? If there are no entries at all in the polarization constructor, \ttt{@()}, the beam is unpolarized, and the spin density matrix is proportional to the unit/identity matrix. Placing entries into the \ttt{@()} constructor follows the concept of sparse matrices, i.e. the entries that have been specified will be present, while the rest remains zero. Single numbers do specify entries for that particular helicity on the main diagonal of the spin density matrix, e.g. for an electron \ttt{@(-1)} means (100\%) left-handed polarization. Different entries are separated by commas: \ttt{@(1,-1)} sets the two diagonal entries at positions $(1,1)$ and $(-1,-1)$ in the density matrix both equal to one. Two remarks are in order already here. First, note that you do not have to worry about the correct normalization of the spin density matrix, \whizard\ is taking care of this automatically. Second, in the screen output for the beam data, only those entries of the spin density matrix that have been specified by the user, will be displayed. If a \ttt{beams\_pol\_fraction} statement appears, other components will be non-zero, but might not be shown. E.g. ILC-like, 80 \% polarization of the electrons, 30 \% positron polarization will be specified like this for left-handed electrons and right-handed positrons: \begin{code} beams = e1, E1 beams_pol_density = @(-1), @(+1) beams_pol_fraction = 80%, 30% \end{code} The screen output will be like this: \begin{code} | ------------------------------------------------------------------------ | Beam structure: e-, e+ | polarization (beam 1): | @(-1: -1: ( 1.000000000000E+00, 0.000000000000E+00)) | polarization (beam 2): | @(+1: +1: ( 1.000000000000E+00, 0.000000000000E+00)) | polarization degree = 0.8000000, 0.3000000 | Beam data (collision): | e- (mass = 0.0000000E+00 GeV) polarized | e+ (mass = 0.0000000E+00 GeV) polarized \end{code} But because of the fraction of unpolarized electrons and positrons, the spin density matrices for electrons and positrons are: \[ \rho(e^-) = \diag \left ( 0.10, 0.90 \right) \qquad \rho(e^+) = \diag \left ( 0.65, 0.35 \right) \quad , \] respectively. So, in general, only the entries due to the polarized fraction will be displayed on screen. We will come back to more examples below. Again, the setting of a single entry, e.g. \ttt{@($\pm m$)}, which always sets the diagonal component $(\pm m, \pm m)$ of the spin density matrix equal to one. Here $m$ can have the following values for the different spins (in parentheses are entries that exist only for massive particles): \vspace{1mm} \begin{center} \begin{tabular}{|l|l|l|}\hline Spin $j$ & Particle type & possible $m$ values \\\hline 0 & Scalar boson & 0 \\ 1/2 & Spinor & +1, -1 \\ 1 & (Massive) Vector boson & +1, (0), -1 \\ 3/2 & (Massive) Vectorspinor & +2, (+1), (-1), -2 \\ 2 & (Massive) Tensor & +2, (+1), (0), (-1), -2 \\\hline \end{tabular} \end{center} \vspace{1mm} Off-diagonal entries that are equal to one (up to the normalization) of the spin-density matrix can be specified simply by the position, namely: \ttt{@($m$:$m'$, $m''$)}. This would result in a spin density matrix with diagonal entry $1$ for the position $(m'', m'')$, and an entry of $1$ for the off-diagonal position $(m,m')$. Furthermore, entries in the density matrix different from $1$ with a numerical value \ttt{{\em }} can be specified, separated by another colon: \ttt{@($m$:$m'$:{\em })}. Here, it does not matter whether $m$ and $m'$ are different or not. For $m = m'$ also diagonal spin density matrix entries different from one can be specified. Note that because spin density matrices have to be Hermitian, only the entry $(m,m')$ has to be set, while the complex conjugate entry at the transposed position $(m',m)$ is set automatically by \whizard. We will give some general density matrices now, and after that a few more definite examples. In the general setups below, we always give the expression for the spin density matrix only for one single beam. % { \newcommand{\cssparse}[4]{% \begin{pmatrix} #1 & 0 & \cdots & \cdots & #3 \\ 0 & 0 & \ddots & & 0 \\ \vdots & \ddots & \ddots & \ddots & \vdots \\ 0 & & \ddots & 0 & 0 \\ #4 & \cdots & \cdots & 0 & #2 \end{pmatrix}% } % \begin{itemize} \item {\bf Unpolarized:} \begin{center} \begin{footnotesize} \ttt{beams\_pol\_density = @()} \end{footnotesize} \end{center} % \newline This has the same effect as not specifying any polarization at all and is the only constructor available for scalars and fermions declared as left- or right-handed (like the neutrino). Density matrix: \[ \rho = \frac{1}{|m|}\mathbb{I} \] ($|m|$: particle multiplicity which is 2 for massless, $2j + 1$ for massive particles). % \item {\bf Circular polarization:} \begin{center} \begin{footnotesize} \ttt{beams\_pol\_density = @($\pm j$) \qquad beams\_pol\_fraction = $f$} \end{footnotesize} \end{center} A fraction $f$ (parameter range $f \in \left[0\;;\;1\right]$) of the particles are in the maximum / minimum helicity eigenstate $\pm j$, the remainder is unpolarized. For spin $\frac{1}{2}$ and massless particles of spin $>0$, only the maximal / minimal entries of the density matrix are populated, and the density matrix looks like this: \[ \rho = \diag\left(\frac{1\pm f}{2}\;,\;0\;,\;\dots\;,\;0\;, \frac{1\mp f}{2}\right) \] % \item {\bf Longitudinal polarization (massive):} \begin{center} \begin{footnotesize} \ttt{beams\_pol\_density = @(0) \qquad beams\_pol\_fraction = $f$} \end{footnotesize} \end{center} We consider massive particles with maximal spin component $j$, a fraction $f$ of which having longitudinal polarization, the remainder is unpolarized. Longitudinal polarization is (obviously) only available for massive bosons of spin $>0$. Again, the parameter range for the fraction is: $f \in \left[0\;;\;1\right]$. The density matrix has the form: \[ \rho = \diag\left(\frac{1-f}{|m|}\;,\;\dots\;,\;\frac{1-f}{|m|}\;,\; \frac{1+f \left(|m| - 1\right)}{|m|}\;,\;\frac{1-f}{|m|}\;, \;\dots\;,\;\frac{1-f}{|m|}\right) \] ($|m| = 2j+1 $: particle multiplicity) % \item {\bf Transverse polarization (along an axis):} \begin{center} \begin{footnotesize} \ttt{beams\_pol\_density = @(j, -j, j:-j:exp(-I*phi)) \qquad beams\_pol\_fraction = $f$} \end{footnotesize} \end{center} This so called transverse polarization is a polarization along an arbitrary direction in the $x-y$ plane, with $\phi=0$ being the positive $x$ direction and $\phi=90^\circ$ the positive $y$ direction. Note that the value of \ttt{phi} has either to be set inside the beam polarization expression explicitly or by a statement \ttt{real phi = {\em val} degree} before. A fraction $f$ of the particles are polarized, the remainder is unpolarized. Note that, although this yields a valid density matrix for all particles with multiplicity $>1$ (in which the only the highest and lowest helicity states are populated), it is meaningful only for spin $\frac{1}{2}$ particles and massless bosons of spin $>0$. The range of the parameters are: $f \in \left[0\;;\;1\right]$ and $\phi \in \mathbb{R}$. This yields a density matrix: \[ \rho = \cssparse{1}{1} {\frac{f}{2}\,e^{-i\phi}} {\frac{f}{2}\,e^{i\phi}} \] (for antiparticles, the matrix is conjugated). % \item {\bf Polarization along arbitrary axis $\left(\theta, \phi\right)$:} \begin{center} \begin{footnotesize} \ttt{beams\_pol\_density = @(j:j:1-cos(theta), j:-j:sin(theta)*exp(-I*phi), -j:-j:1+cos(theta))} \qquad\quad\qquad \ttt{beams\_pol\_fraction = $f$} \end{footnotesize} \end{center} This example describes polarization along an arbitrary axis in polar coordinates (polar axis in positive $z$ direction, polar angle $\theta$, azimuthal angle $\phi$). A fraction $f$ of the particles are polarized, the remainder is unpolarized. Note that, although axis polarization defines a valid density matrix for all particles with multiplicity $>1$, it is meaningful only for particles with spin $\frac{1}{2}$. Valid ranges for the parameters are $f \in \left[0\;;\;1\right]$, $\theta \in \mathbb{R}$, $\phi \in \mathbb{R}$. The density matrix then has the form: \[ \rho = \frac{1}{2}\cdot \cssparse{1 - f\cos\theta}{1 + f\cos\theta} {f\sin\theta\, e^{-i\phi}}{f\sin\theta\, e^{i\phi}} \] % \item {\bf Diagonal density matrix:} \begin{center} \begin{footnotesize} \ttt{beams\_pol\_density = @(j:j:$h_j$, j-1:j-1:$h_{j-1}$, $\ldots$, -j:-j:$h_{-j}$)} \end{footnotesize} \end{center} This defines an arbitrary diagonal density matrix with entries $\rho_{j,j}\,,\,\dots\,,\,\rho_{-j,-j}$. % \item {\bf Arbitrary density matrix:} \begin{center} \begin{footnotesize} \ttt{beams\_pol\_density = @($\{m:m':x_{m,m'}\}$)}: \end{footnotesize} \end{center} Here, \ttt{$\{m:m':x_{m,m'}\}$} denotes a selection of entries at various positions somewhere in the spin density matrix. \whizard\ will check whether this is a valid spin density matrix, but it does e.g. not have to correspond to a pure state. % \end{itemize} } % The beam polarization statements can be used both globally directly with the \ttt{beams} specification, or locally inside the \ttt{integrate} or \ttt{simulate} command. Some more specific examples are in order to show how initial state polarization works: % \begin{itemize} \item \begin{quote} \begin{footnotesize} \begin{verbatim} beams = A, A beams_pol_density = @(+1), @(1, -1, 1:-1:-I) \end{verbatim} \end{footnotesize} \end{quote} This declares the initial state to be composed of two incoming photons, where the first photon is right-handed, and the second photon has transverse polarization in $y$ direction. % \item \begin{quote} \begin{footnotesize} \begin{verbatim} beams = A, A beams_pol_density = @(+1), @(1, -1, 1:-1:-1) \end{verbatim} \end{footnotesize} \end{quote} Same as before, but this time the second photon has transverse polarization in $x$ direction. % \item \begin{quote} \begin{footnotesize} \begin{verbatim} beams = "W+" beams_pol\_density = @(0) \end{verbatim} \end{footnotesize} \end{quote} This example sets up the decay of a longitudinal vector boson. % \item \begin{quote} \begin{footnotesize} \begin{verbatim} beams = E1, e1 scan int hel_ep = (-1, 1) { scan int hel_em = (-1, 1) { beams_pol_density = @(hel_ep), @(hel_em) integrate (eeww) } } integrate (eeww) \end{verbatim} \end{footnotesize} \end{quote} This example loops over the different positron and electron helicity combinations and calculates the respective integrals. The \ttt{beams\_pol\_density} statement is local to the scan loop(s) and, therefore, the last \ttt{integrate} calculates the unpolarized integral. \end{itemize} % Although beam polarization should be straightforward to use, some pitfalls exist for the unwary: \begin{itemize} \item Once \ttt{beams\_pol\_density} is set globally, it persists and is applied every time \ttt{beams} is executed (unless it is reset). In particular, this means that code like \begin{quote} \begin{footnotesize} \begin{verbatim} process wwaa = Wp, Wm => A, A process zee = Z => e1, E1 sqrts = 200 GeV beams_pol_density = @(1, -1, 1:-1:-1), @() beams = Wp, Wm integrate (wwaa) beams = Z integrate (zee) beams_pol_density = @(0) \end{verbatim} \end{footnotesize} \end{quote} will throw an error, because \whizard\ complains that the spin density matrix has the wrong dimensionality for the second (the decay) process. This kind of trap can be avoided be using \ttt{beams\_pol\_density} only locally in \ttt{integrate} or \ttt{simulate} statements. % \item On-the-fly integrations executed by \ttt{simulate} use the beam setup found at the point of execution. This implies that any polarization settings you have previously done affect the result of the integration. % \item The \ttt{unstable} command also requires integrals of the selected decay processes, and will compute them on-the-fly if they are unavailable. Here, a polarized integral is not meaningful at all. Therefore, this command ignores the current \ttt{beam} setting and issues a warning if a previous polarized integral is available; this will be discarded. \end{itemize} \subsection{Final state polarization} Final state polarization is available in \whizard\ in the sense that the polarization of real final state particles can be retained when generating simulated events. In order for the polarization of a particle to be retained, it must be declared as polarized via the \ttt{polarized} statement \begin{quote} \begin{footnotesize} \begin{verbatim} polarized particle [, particle, ...] \end{verbatim} \end{footnotesize} \end{quote} The effect of \ttt{polarized} can be reversed with the \ttt{unpolarized} statement which has the same syntax. For example, \begin{quote} \begin{footnotesize} \begin{verbatim} polarized "W+", "W-", Z \end{verbatim} \end{footnotesize} \end{quote} will cause the polarization of all final state $W$ and $Z$ bosons to be retained, while \begin{quote} \begin{footnotesize} \begin{verbatim} unpolarized "W+", "W-", Z \end{verbatim} \end{footnotesize} \end{quote} will reverse the effect and cause the polarization to be summed over again. Note that \ttt{polarized} and \ttt{unpolarized} are global statements which cannot be used locally as command arguments and if you use them e.g. in a loop, the effects will persist beyond the loop body. Also, a particle cannot be \ttt{polarized} and \ttt{unstable} at the same time (this restriction might be loosened in future versions of \whizard). After toggling the polarization flag, the generation of polarized events can be requested by using the \ttt{?polarized\_events} option of the \ttt{simulate} command, e.g. \begin{quote} \begin{footnotesize} \begin{verbatim} simulate (eeww) { ?polarized_events = true } \end{verbatim} \end{footnotesize} \end{quote} When \ttt{simulate} is run in this mode, helicity information for final state particles that have been toggled as \ttt{polarized} is written to the event file(s) (provided that polarization is supported by the selected event file format(s) ) and can also be accessed in the analysis by means of the \ttt{Hel} observable. For example, an analysis definition like \begin{quote} \begin{footnotesize} \begin{verbatim} analysis = if (all Hel == -1 ["W+"] and all Hel == -1 ["W-"] ) then record cta_nn (eval cos (Theta) ["W+"]) endif; if (all Hel == -1 ["W+"] and all Hel == 0 ["W-"] ) then record cta_nl (eval cos (Theta) ["W+"]) endif \end{verbatim} \end{footnotesize} \end{quote} can be used to histogram the angular distribution for the production of polarized $W$ pairs (obviously, the example would have to be extended to cover all possible helicity combinations). Note, however, that helicity information is not available in the integration step; therefore, it is not possible to use \ttt{Hel} as a cut observable. While final state polarization is straightforward to use, there is a caveat when used in combination with flavor products. If a particle in a flavor product is defined as \ttt{polarized}, then all particles ``originating'' from the product will act as if they had been declared as \ttt{polarized} --- their polarization will be recorded in the generated events. E.g., the example \begin{quote} \begin{footnotesize} \begin{verbatim} process test = u:d, ubar:dbar => d:u, dbar:ubar, u, ubar ! insert compilation, cuts and integration here polarized d, dbar simulate (test) {?polarized_events = true} \end{verbatim} \end{footnotesize} \end{quote} will generate events including helicity information for all final state $d$ and $\overline{d}$ quarks, but only for part of the final state $u$ and $\overline{u}$ quarks. In this case, if you had wanted to keep the helicity information also for all $u$ and $\overline{u}$, you would have had to explicitely include them into the \ttt{polarized} statement. \section{Cross sections} Integrating matrix elements over phase space is the core of \whizard's activities. For any process where we want the cross section, distributions, or event samples, the cross section has to be determined first. This is done by a doubly adaptive multi-channel Monte-Carlo integration. The integration, in turn, requires a \emph{phase-space setup}, i.e., a collection of phase-space \emph{channels}, which are mappings of the unit hypercube onto the complete space of multi-particle kinematics. This phase-space information is encoded in the file \emph{xxx}\ttt{.phs}, where \emph{xxx} is the process tag. \whizard\ generates the phase-space file on the fly and can reuse it in later integrations. For each phase-space channel, the unit hypercube is binned in each dimension. The bin boundaries are allowed to move during a sequence of iterations, each with a fixed number of sampled phase-space points, so they adapt to the actual phase-space density as far as possible. In addition to this \emph{intrinsic} adaptation, the relative channel weights are also allowed to vary. All these steps are done automatically when the \ttt{integrate} command is executed. At the end of the iterative adaptation procedure, the program has obtained an estimate for the integral of the matrix element over phase space, together with an error estimate, and a set of integration \emph{grids} which contains all information on channel weights and bin boundaries. This information is stored in a file \emph{xxx}\ttt{.vg}, where \emph{xxx} is the process tag, and is used for event generation by the \ttt{simulate} command. \subsection{Integration} \label{sec:integrate} Since everything can be handled automatically using default parameters, it often suffices to write the command \begin{quote} \begin{footnotesize} \begin{verbatim} integrate (proc1) \end{verbatim} \end{footnotesize} \end{quote} for integrating the process with name tag \ttt{proc1}, and similarly \begin{quote} \begin{footnotesize} \begin{verbatim} integrate (proc1, proc2, proc3) \end{verbatim} \end{footnotesize} \end{quote} for integrating several processes consecutively. Options to the integrate command are specified, if not globally, by a local option string \begin{quote} \begin{footnotesize} \begin{verbatim} integrate (proc1, proc2, proc3) { mH = 200 GeV } \end{verbatim} \end{footnotesize} \end{quote} (It is possible to place a \ttt{beams} statement inside the option string, if desired.) If the process is configured but not compiled, compilation will be done automatically. If it is not available at all, integration will fail. The integration method can be specified by the string variable \begin{quote} \begin{footnotesize} \ttt{\$integration\_method = "{\em }"} \end{footnotesize} \end{quote} %$ The default method is called \ttt{"vamp"} and uses the \vamp\ algorithm and code. (At the moment, there is only a single simplistic alternative, using the midpoint rule or rectangle method for integration, \ttt{"midpoint"}. This is mainly for testing purposes. In future versions of \whizard, more methods like e.g. Gauss integration will be made available). \vamp, however, is clearly the main integration method. It is done in several \emph{passes} (usually two), and each pass consists of several \emph{iterations}. An iteration consists of a definite number of \emph{calls} to the matrix-element function. For each iteration, \whizard\ computes an estimate of the integral and an estimate of the error, based on the binned sums of matrix element values and squares. It also computes an estimate of the rejection efficiency for generating unweighted events, i.e., the ratio of the average sampling function value over the maximum value of this function. After each iteration, both the integration grids (the binnings) and the relative weights of the integration channels can be adapted to minimize the variance estimate of the integral. After each pass of several iterations, \whizard\ computes an average of the iterations within the pass, the corresponding error estimate, and a $\chi^2$ value. The integral, error, efficiency and $\chi^2$ value computed for the most recent integration pass, together with the most recent integration grid, are used for any subsequent calculation that involves this process, in particular for event generation. In the default setup, during the first pass(es) both grid binnings and channel weights are adapted. In the final (usually second) pass, only binnings are further adapted. Roughly speaking, the final pass is the actual calculation, while the previous pass(es) are used for ``warming up'' the integration grids, without using the numerical results. Below, in the section about the specification of the iterations, Sec.~\ref{sec:iterations}, we will explain how it is possible to change the behavior of adapting grids and weights. Here is an example of the integration output, which illustrates these properties. The \sindarin\ script describes the process $e^+e^-\to q\bar q q\bar q$ with $q$ being any light quark, i.e., $W^+W^-$ and $ZZ$ production and hadronic decay together will any irreducible background. We cut on $p_T$ and energy of jets, and on the invariant mass of jet pairs. Here is the script: \begin{quote} \begin{footnotesize} \begin{verbatim} alias q = d:u:s:c alias Q = D:U:S:C process proc_4f = e1, E1 => q, Q, q, Q ms = 0 mc = 0 sqrts = 500 GeV cuts = all (Pt > 10 GeV and E > 10 GeV) [q:Q] and all M > 10 GeV [q:Q, q:Q] integrate (proc_4f) \end{verbatim} \end{footnotesize} \end{quote} After the run is finished, the integration output looks like \begin{quote} \begin{footnotesize} \begin{verbatim} | Process library 'default_lib': loading | Process library 'default_lib': ... success. | Integrate: compilation done | RNG: Initializing TAO random-number generator | RNG: Setting seed for random-number generator to 12511 | Initializing integration for process proc_4f: | ------------------------------------------------------------------------ | Process [scattering]: 'proc_4f' | Library name = 'default_lib' | Process index = 1 | Process components: | 1: 'proc_4f_i1': e-, e+ => d:u:s:c, dbar:ubar:sbar:cbar, | d:u:s:c, dbar:ubar:sbar:cbar [omega] | ------------------------------------------------------------------------ | Beam structure: [any particles] | Beam data (collision): | e- (mass = 5.1099700E-04 GeV) | e+ (mass = 5.1099700E-04 GeV) | sqrts = 5.000000000000E+02 GeV | Phase space: generating configuration ... | Phase space: ... success. | Phase space: writing configuration file 'proc_4f_i1.phs' | Phase space: 123 channels, 8 dimensions | Phase space: found 123 channels, collected in 15 groves. | Phase space: Using 195 equivalences between channels. | Phase space: wood | Applying user-defined cuts. | OpenMP: Using 8 threads | Starting integration for process 'proc_4f' | Integrate: iterations not specified, using default | Integrate: iterations = 10:10000:"gw", 5:20000:"" | Integrator: 15 chains, 123 channels, 8 dimensions | Integrator: Using VAMP channel equivalences | Integrator: 10000 initial calls, 20 bins, stratified = T | Integrator: VAMP |=============================================================================| | It Calls Integral[fb] Error[fb] Err[%] Acc Eff[%] Chi2 N[It] | |=============================================================================| 1 9963 2.3797857E+03 3.37E+02 14.15 14.13* 4.02 2 9887 2.8307603E+03 9.58E+01 3.39 3.37* 4.31 3 9815 3.0132091E+03 5.10E+01 1.69 1.68* 8.37 4 9754 2.9314937E+03 3.64E+01 1.24 1.23* 10.65 5 9704 2.9088284E+03 3.40E+01 1.17 1.15* 12.99 6 9639 2.9725788E+03 3.53E+01 1.19 1.17 15.34 7 9583 2.9812484E+03 3.10E+01 1.04 1.02* 17.97 8 9521 2.9295139E+03 2.88E+01 0.98 0.96* 22.27 9 9435 2.9749262E+03 2.94E+01 0.99 0.96 20.25 10 9376 2.9563369E+03 3.01E+01 1.02 0.99 21.10 |-----------------------------------------------------------------------------| 10 96677 2.9525019E+03 1.16E+01 0.39 1.22 21.10 1.15 10 |-----------------------------------------------------------------------------| 11 19945 2.9599072E+03 2.13E+01 0.72 1.02 15.03 12 19945 2.9367733E+03 1.99E+01 0.68 0.96* 12.68 13 19945 2.9487747E+03 2.03E+01 0.69 0.97 11.63 14 19945 2.9777794E+03 2.03E+01 0.68 0.96* 11.19 15 19945 2.9246612E+03 1.95E+01 0.67 0.94* 10.34 |-----------------------------------------------------------------------------| 15 99725 2.9488622E+03 9.04E+00 0.31 0.97 10.34 1.05 5 |=============================================================================| | Time estimate for generating 10000 events: 0d:00h:00m:51s | Creating integration history display proc_4f-history.ps and proc_4f-history.pdf \end{verbatim} \end{footnotesize} \end{quote} Each row shows the index of a single iteration, the number of matrix element calls for that iteration, and the integral and error estimate. Note that the number of calls displayed are the real calls to the matrix elements after all cuts and possible rejections. The error should be viewed as the $1\sigma$ uncertainty, computed on a statistical \begin{figure} \centering \includegraphics[width=.56\textwidth]{proc_4f-history} \caption{\label{fig:inthistory} Graphical output of the convergence of the adaptation during the integration of a \whizard\ process.} \end{figure} basis. The next two columns display the error in percent, and the \emph{accuracy} which is the same error normalized by $\sqrt{n_{\rm calls}}$. The accuracy value has the property that it is independent of $n_{\rm calls}$, it describes the quality of adaptation of the current grids. Good-quality grids have a number of order one, the smaller the better. The next column is the estimate for the rejection efficiency in percent. Here, the value should be as high as possible, with $100\,\%$ being the possible maximum. In the example, the grids are adapted over ten iterations, after which the accuracy and efficiency have saturated at about $1.0$ and $10\,\%$, respectively. The asterisk in the accuracy column marks those iterations where an improvement over the previous iteration is seen. The average over these iterations exhibits an accuracy of $1.22$, corresponding to $0.39\,\%$ error, and a $\chi^2$ value of $1.15$, which is just right: apparently, the phase-space for this process and set of cuts is well-behaved. The subsequent five iterations are used for obtaining the final integral, which has an accuracy below one (error $0.3\,\%$), while the efficiency settles at about $10\,\%$. In this example, the final $\chi^2$ value happens to be quite small, i.e., the individual results are closer together than the error estimates would suggest. One should nevertheless not scale down the error, but rather scale it up if the $\chi^2$ result happens to be much larger than unity: this often indicates sub-optimally adapted grids, which insufficiently map some corner of phase space. One should note that all values are subject to statistical fluctuations, since the number of calls within each iterations is finite. Typically, fluctuations in the efficiency estimate are considerably larger than fluctuations in the error/accuracy estimate. Two subsequent runs of the same script should yield statistically independent results which may differ in all quantities, within the error estimates, since the seed of the random-number generator will differ by default. It is possible to get exactly reproducible results by setting the random-number seed explicitly, e.g., \begin{quote} \begin{footnotesize} \begin{verbatim} seed = 12345 \end{verbatim} \end{footnotesize} \end{quote} at any point in the \sindarin\ script. \ttt{seed} is a predefined intrinsic variable. The value can be any 32bit integer. Two runs with different seeds can be safely taken as statistically independent. In the example above, no seed has been set, and the seed has therefore been determined internally by \whizard\ from the system clock. The concluding line with the time estimate applies to a subsequent simulation step with unweighted events, which is not actually requested in the current example. It is based on the timing and efficiency estimate of the most recent iteration. As a default, a graphical output of the integration history will be produced (if both \LaTeX\ and \metapost\ have been available during configuration). Fig.~\ref{fig:inthistory} shows how this looks like, and demonstrates how a proper convergence of the integral during the adaptation looks like. The generation of these graphical history files can be switched off using the command \ttt{?vis\_history = false}. %%%%% \subsection{Integration run IDs} A single \sindarin\ script may contain multiple calls to the \ttt{integrate} command with different parameters. By default, files generated for the same process in a subsequent integration will overwrite the previous ones. This is undesirable when the script is re-run: all results that have been overwritten have to be recreated. To avoid this, the user may identify a specific run by a string-valued ID, e.g. \begin{quote} \begin{footnotesize} \begin{verbatim} integrate (foo) { $run_id = "first" } \end{verbatim} \end{footnotesize} \end{quote} This ID will become part of the file name for all files that are created specifically for this run. Often it is useful to create a run ID from a numerical value using \ttt{sprintf}, e.g., in this scan: \begin{quote} \begin{footnotesize} \begin{verbatim} scan real mh = (100 => 200 /+ 10) { $run_id = sprintf "%e" (mh) integrate (h_production) } \end{verbatim} \end{footnotesize} \end{quote} With unique run IDs, a subsequent run of the same \sindarin\ script will be able to reuse all previous results, even if there is more than a single integration per process. \subsection{Controlling iterations} \label{sec:iterations} \whizard\ has some predefined numbers of iterations and calls for the first and second integration pass, respectively, which depend on the number of initial and final-state particles. They are guesses for values that yield good-quality grids and error values in standard situations, where no exceptionally strong peaks or loose cuts are present in the integrand. Actually, the large number of warmup iterations in the previous example indicates some safety margin in that respect. It is possible, and often advisable, to adjust the iteration and call numbers to the particular situation. One may reduce the default numbers to short-cut the integration, if either less accuracy is needed, or CPU time is to be saved. Otherwise, if convergence is bad, the number of iterations or calls might be increased. To set iterations manually, there is the \ttt{iterations} command: \begin{quote} \begin{footnotesize} \begin{verbatim} iterations = 5:50000, 3:100000 \end{verbatim} \end{footnotesize} \end{quote} This is a comma-separated list. Each pair of values corresponds to an integration pass. The value before the colon is the number of iterations for this pass, the other number is the number of calls per iteration. While the default number of passes is two (one for warmup, one for the final result), you may specify a single pass \begin{quote} \begin{footnotesize} \begin{verbatim} iterations = 5:100000 \end{verbatim} \end{footnotesize} \end{quote} where the relative channel weights will \emph{not} be adjusted (because this is the final pass). This is appropriate for well-behaved integrands where weight adaptation is not necessary. You can also define more than two passes. That might be useful when reusing a previous grid file with insufficient quality: specify the previous passes as-is, so the previous results will be read in, and then a new pass for further adaptation. In the final pass, the default behavior is to not adapt grids and weights anymore. Otherwise, different iterations would be correlated, and a final reliable error estimate would not be possible. For all but the final passes, the user can decide whether to adapt grids and weights by attaching a string specifier to the number of iterations: \ttt{"g"} does adapt grids, but not weights, \ttt{"w"} the other way round. \ttt{"gw"} or \ttt{"wg"} does adapt both. By the setting \ttt{""}, all adaptations are switched off. An example looks like this: \begin{code} iterations = 2:10000:"gw", 3:5000 \end{code} Since it is often not known beforehand how many iterations the grid adaptation will need, it is generally a good idea to give the first pass a large number of iterations. However, in many cases these turn out to be not necessary. To shortcut iterations, you can set any of \begin{quote} \begin{footnotesize} \begin{verbatim} accuracy_goal error_goal relative_error_goal \end{verbatim} \end{footnotesize} \end{quote} to a positive value. If this is done, \whizard\ will skip warmup iterations once all of the specified goals are reached by the current iteration. The final iterations (without weight adaptation) are always performed. \subsection{Phase space} Before \ttt{integrate} can start its work, it must have a phase-space configuration for the process at hand. The method for the phase-space parameterization is determined by the string variable \ttt{\$phs\_method}. At the moment there are only two options, \ttt{"single"}, for testing purposes, that is mainly used internally, and \whizard's traditional method, \ttt{"wood"}. This parameterization is particularly adapted and fine-tuned for electroweak processes and might not be the ideal for for pure jet cross sections. In future versions of \whizard, more options for phase-space parameterizations will be made available, e.g. the \ttt{RAMBO} algorithm and its massive cousin, and phase-space parameterizations that take care of the dipole-like emission structure in collinear QCD (or QED) splittings. For the standard method, the phase-space parameterization is laid out in an ASCII file \ttt{\textit{\_}i\textit{}.phs}. Here, \ttt{{\em }} is the process name chosen by the user while \ttt{{\em }} is the number of the process component of the corresponding process. This immediately shows that different components of processes are getting different phase space setups. This is necessary for inclusive processes, e.g. the sum of $pp \to Z + nj$ and $pp \to W + nj$, or in future versions of \whizard\ for NLO processes, where one component is the interference between the virtual and the Born matrix element, and another one is the subtraction terms. Normally, you do not have to deal with this file, since \whizard\ will generate one automatically if it does not find one. (\whizard\ is careful to check for consistency of process definition and parameters before using an existing file.) Experts might find it useful to generate a phase-space file and inspect and/or modify it before proceeding further. To this end, there is the parameter \verb|?phs_only|. If you set this \ttt{true}, \whizard\ skips the actual integration after the phase-space file has been generated. There is also a parameter \verb|?vis_channels| which can be set independently; if this is \ttt{true}, \whizard\ will generate a graphical visualization of the phase-space parameterizations encoded in the phase-space file. This file has to be taken with a grain of salt because phase space channels are represented by sample Feynman diagrams for the corresponding channel. This does however {\em not} mean that in the matrix element other Feynman diagrams are missing (the default matrix element method, \oMega, is not using Feynman-diagrammatic amplitudes at all). Things might go wrong with the default phase-space generation, or manual intervention might be necessary to improve later performance. There are a few parameters that control the algorithm of phase-space generation. To understand their meaning, you should realize that phase-space parameterizations are modeled after (dominant) Feynman graphs for the current process. \subsubsection{The main phase space setup {\em wood}} For the main phase-space parameterization of \whizard, which is called \ttt{"wood"}, there are many different parameters and flags that allow to tune and customize the phase-space setup for every certain process: The parameter \verb|phs_off_shell| controls the number of off-shell lines in those graphs, not counting $s$-channel resonances and logarithmically enhanced $s$- and $t$-channel lines. The default value is $2$. Setting it to zero will drop everything that is not resonant or logarithmically enhanced. Increasing it will include more subdominant graphs. (\whizard\ increases the value automatically if the default value does not work.) There is a similar parameter \verb|phs_t_channel| which controls multiperipheral graphs in the parameterizations. The default value is $6$, so graphs with up to $6$ $t/u$-channel lines are considered. In particular cases, such as $e^+e^-\to n\gamma$, all graphs are multiperipheral, and for $n>7$ \whizard\ would find no parameterizations in the default setup. Increasing the value of \verb|phs_t_channel| solves this problem. (This is presently not done automatically.) There are two numerical parameters that describe whether particles are treated like massless particles in particular situations. The value of \verb|phs_threshold_s| has the default value $50\;\GeV$. Hence, $W$ and $Z$ are considered massive, while $b$ quarks are considered massless. This categorization is used for deciding whether radiation of $b$ quarks can lead to (nearly) singular behavior, i.e., logarithmic enhancement, in the infrared and collinear regions. If yes, logarithmic mappings are applied to phase space. Analogously, \verb|phs_threshold_t| decides about potential $t$-channel singularities. Here, the default value is $100\;\GeV$, so amplitudes with $W$ and $Z$ in the $t$-channel are considered as logarithmically enhanced. For a high-energy hadron collider of 40 or 100 TeV energy, also $W$ and $Z$ in $s$-channel like situations might be necessary to be considered massless. Such logarithmic mappings need a dimensionful scale as parameter. There are three such scales, all with default value $10\;\GeV$: \verb|phs_e_scale| (energy), \verb|phs_m_scale| (invariant mass), and \verb|phs_q_scale| (momentum transfer). If cuts and/or masses are such that energies, invariant masses of particle pairs, and momentum transfer values below $10\;\GeV$ are excluded or suppressed, the values can be kept. In special cases they should be changed: for instance, if you want to describe $\gamma^*\to\mu^+\mu^-$ splitting well down to the muon mass, no cuts, you may set \verb|phs_m_scale = mmu|. The convergence of the Monte-Carlo integration result will be considerably faster. There are more flags. These and more details about the phase space parameterization will be described in Sec.~\ref{sec:wood}. \subsection{Cuts} \whizard~2 does not apply default cuts to the integrand. Therefore, processes with massless particles in the initial, intermediate, or final states may not have a finite cross section. This fact will manifest itself in an integration that does not converge, or is unstable, or does not yield a reasonable error or reweighting efficiency even for very large numbers of iterations or calls per iterations. When doing any calculation, you should verify first that the result that you are going to compute is finite on physical grounds. If not, you have to apply cuts that make it finite. A set of cuts is defined by the \ttt{cuts} statement. Here is an example \begin{quote} \begin{footnotesize} \begin{verbatim} cuts = all Pt > 20 GeV [colored] \end{verbatim} \end{footnotesize} \end{quote} This implies that events are kept only (for integration and simulation) if the transverse momenta of all colored particles are above $20\;\GeV$. Technically, \ttt{cuts} is a special object, which is unique within a given scope, and is defined by the logical expression on the right-hand side of the assignment. It may be defined in global scope, so it is applied to all subsequent processes. It may be redefined by another \ttt{cuts} statement. This overrides the first cuts setting: the \ttt{cuts} statement is not cumulative. Multiple cuts should be specified by the logical operators of \sindarin, for instance \begin{quote} \begin{footnotesize} \begin{verbatim} cuts = all Pt > 20 GeV [colored] and all E > 5 GeV [photon] \end{verbatim} \end{footnotesize} \end{quote} Cuts may also be defined local to an \ttt{integrate} command, i.e., in the options in braces. They will apply only to the processes being integrated, overriding any global cuts. The right-hand side expression in the \ttt{cuts} statement is evaluated at the point where it is used by an \ttt{integrate} command (which could be an implicit one called by \ttt{simulate}). Hence, if the logical expression contains parameters, such as \begin{quote} \begin{footnotesize} \begin{verbatim} mH = 120 GeV cuts = all M > mH [b, bbar] mH = 150 GeV integrate (myproc) \end{verbatim} \end{footnotesize} \end{quote} the Higgs mass value that is inserted is the value in place when \ttt{integrate} is evaluated, $150\;\GeV$ in this example. This same value will also be used when the process is called by a subsequent \ttt{simulate}; it is \ttt{integrate} which compiles the cut expression and stores it among the process data. This behavior allows for scanning over parameters without redefining the cuts every time. The cut expression can make use of all variables and constructs that are defined at the point where it is evaluated. In particular, it can make use of the particle content and kinematics of the hard process, as in the example above. In addition to the predefined variables and those defined by the user, there are the following variables which depend on the hard process: \begin{quote} \begin{tabular}{ll} integer: & \ttt{n\_in}, \ttt{n\_out}, \ttt{n\_tot} \\ real: & \ttt{sqrts}, \ttt{sqrts\_hat} \end{tabular} \end{quote} Example: \begin{quote} \begin{footnotesize} \begin{verbatim} cuts = sqrts_hat > 150 GeV \end{verbatim} \end{footnotesize} \end{quote} The constants \ttt{n\_in} etc.\ are sometimes useful if a generic set of cuts is defined, which applies to various processes simultaneously. The user is encouraged to define his/her own set of cuts, if possible in a process-independent manner, even if it is not required. The \ttt{include} command allows for storing a set of cuts in a separate \sindarin\ script which may be read in anywhere. As an example, the system directories contain a file \verb|default_cuts.sin| which may be invoked by \begin{quote} \begin{footnotesize} \begin{verbatim} include ("default_cuts.sin") \end{verbatim} \end{footnotesize} \end{quote} \subsection{QCD scale and coupling} \whizard\ treats all physical parameters of a model, the coefficients in the Lagrangian, as constants. As a leading-order program, \whizard\ does not make use of running parameters as they are described by renormalization theory. For electroweak interactions where the perturbative expansion is sufficiently well behaved, this is a consistent approach. As far as QCD is concerned, this approach does not yield numerically reliable results, even on the validity scale of the tree approximation. In \whizard\ttt{2}, it is therefore possible to replace the fixed value of $\alpha_s$ (which is accessible as the intrinsic model variable \verb|alphas|), by a function of an energy scale $\mu$. This is controlled by the parameter \verb|?alphas_is_fixed|, which is \ttt{true} by default. Setting it to \ttt{false} enables running~$\alpha_s$. The user has then to decide how $\alpha_s$ is calculated. One option is to set \verb|?alphas_from_lhapdf| (default \ttt{false}). This is recommended if the \lhapdf\ library is used for including structure functions, but it may also be set if \lhapdf\ is not invoked. \whizard\ will then use the $\alpha_s$ formula and value that matches the active \lhapdf\ structure function set and member. In the very same way, the $\alpha_s$ running from the PDFs implemented intrinsically in \whizard\ can be taken by setting \verb|?alphas_from_pdf_builtin| to \ttt{true}. This is the same running then the one from \lhapdf, if the intrinsic PDF coincides with a PDF chosen from \lhapdf. If this is not appropriate, there are again two possibilities. If \verb|?alphas_from_mz| is \ttt{true}, the user input value \verb|alphas| is interpreted as the running value $\alpha_s(m_Z)$, and for the particular event, the coupling is evolved to the appropriate scale $\mu$. The formula is controlled by the further parameters \verb|alphas_order| (default $0$, meaning leading-log; maximum $2$) and \verb|alphas_nf| (default $5$). Otherwise there is the option to set \verb|?alphas_from_lambda_qcd = true| in order to evaluate $\alpha_s$ from the scale $\Lambda_{\rm QCD}$, represented by the intrinsic variable \verb|lambda_qcd|. The reference value for the QCD scale is $\Lambda\_{\rm QCD} = 200$ MeV. \verb|alphas_order| and \verb|alphas_nf| apply analogously. Note that for using one of the running options for $\alpha_s$, always \ttt{?alphas\_is\_fixed = false} has to be invoked. In any case, if $\alpha_s$ is not fixed, each event has to be assigned an energy scale. By default, this is $\sqrt{\hat s}$, the partonic invariant mass of the event. This can be replaced by a user-defined scale, the special object \ttt{scale}. This is assigned and used just like the \ttt{cuts} object. The right-hand side is a real-valued expression. Here is an example: \begin{quote} \begin{footnotesize} \begin{verbatim} scale = eval Pt [sort by -Pt [colored]] \end{verbatim} \end{footnotesize} \end{quote} This selects the $p_T$ value of the first entry in the list of colored particles sorted by decreasing $p_T$, i.e., the $p_T$ of the hardest jet. The \ttt{scale} definition is used not just for running $\alpha_s$ (if enabled), but it is also the factorization scale for the \lhapdf\ structure functions. These two values can be set differently by specifying \ttt{factorization\_scale} for the scale at which the PDFs are evaluated. Analogously, there is a variable \ttt{renormalization\_scale} that sets the scale value for the running $\alpha_s$. Whenever any of these two values is set, it supersedes the \ttt{scale} value. Just like the \ttt{cuts} expression, the expressions for \ttt{scale}, \ttt{factorization\_scale} and also \ttt{renormalization\_scale} are evaluated at the point where it is read by an explicit or implicit \ttt{integrate} command. \subsection{Reweighting factor} It is possible to reweight the integrand by a user-defined function of the event kinematics. This is done by specifying a \ttt{weight} expression. Syntax and usage is exactly analogous to the \ttt{scale} expression. Example: \begin{quote} \begin{footnotesize} \begin{verbatim} weight = eval (1 + cos (Theta) ^ 2) [lepton] \end{verbatim} \end{footnotesize} \end{quote} We should note that the phase-space setup is not aware of this reweighting, so in complicated cases you should not expect adaptation to achieve as accurate results as for plain cross sections. Needless to say, the default \ttt{weight} is unity. \section{Events} After the cross section integral of a scattering process is known (or the partial-width integral of a decay process), \whizard\ can generate event samples. There are two limiting cases or modes of event generation: \begin{enumerate} \item For a physics simulation, one needs \emph{unweighted} events, so the probability of a process and a kinematical configuration in the event sample is given by its squared matrix element. \item Monte-Carlo integration yields \emph{weighted} events, where the probability (without any grid adaptation) is uniformly distributed over phase space, while the weight of the event is given by its squared matrix element. \end{enumerate} The choice of parameterizations and the iterative adaptation of the integration grids gradually shift the generation mode from option 2 to option 1, which obviously is preferred since it simulates the actual outcome of an experiment. Unfortunately, this adaptation is perfect only in trivial cases, such that the Monte-Carlo integration yields non-uniform probability still with weighted events. Unweighted events are obtained by rejection, i.e., accepting an event with a probability equal to its own weight divided by the maximal possible weight. Furthermore, the maximal weight is never precisely known, so this probability can only be estimated. The default generation mode of \whizard\ is unweighted. This is controlled by the parameter \verb|?unweighted| with default value \ttt{true}. Unweighted events are easy to interpret and can be directly compared with experiment, if properly interfaced with detector simulation and analysis. However, when applying rejection to generate unweighted events, the generator discards information, and for a single event it needs, on the average, $1/\epsilon$ calls, where the efficiency $\epsilon$ is the ratio of the average weight over the maximal weight. If \verb|?unweighted| is \ttt{false}, all events are kept and assigned their respective weights in histograms or event files. \subsection{Simulation} \label{sec:simulation} The \ttt{simulate} command generates an event sample. The number of events can be set either by specifying the integer variable \verb|n_events|, or by the real variable \verb|luminosity|. (This holds for unweighted events. If weighted events are requested, the luminosity value is ignored.) The luminosity is measured in femtobarns, but other units can be used, too. Since the cross sections for the processes are known at that point, the number of events is determined as the luminosity multiplied by the cross section. As usual, both parameters can be set either as global or as local parameters: \begin{quote} \begin{footnotesize} \begin{verbatim} n_events = 10000 simulate (proc1) simulate (proc2, proc3) { luminosity = 100 / 1 pbarn } \end{verbatim} \end{footnotesize} \end{quote} In the second example, both \verb|n_events| and \verb|luminosity| are set. In that case, \whizard\ chooses whatever produces the larger number of events. If more than one process is specified in the argument of \ttt{simulate}, events are distributed among the processes with fractions proportional to their cross section values. The processes are mixed randomly, as it would be the case for real data. The raw event sample is written to a file which is named after the first process in the argument of \ttt{simulate}. If the process name is \ttt{proc1}, the file will be named \ttt{proc1.evx}. You can choose another basename by the string variable \verb|$sample|. For instance, \begin{quote} \begin{footnotesize} \begin{verbatim} simulate (proc1) { n_events = 4000 $sample = "my_events" } \end{verbatim} \end{footnotesize} \end{quote} will produce an event file \verb|my_events.evx| which contains $4000$ events. This event file is in a machine-dependent binary format, so it is not of immediate use. Its principal purpose is to serve as a cache: if you re-run the same script, before starting simulation, it will look for an existing event file that matches the input. If nothing has changed, it will find the file previously generated and read in the events, instead of generating them. Thus you can modify the analysis or any further steps without repeating the time-consuming task of generating a large event sample. If you change the number of events to generate, the program will make use of the existing event sample and generate further events only when it is used up. If necessary, you can suppress the writing/reading of the raw event file by the parameters \verb|?write_raw| and \verb|?read_raw|. If you try to reuse an event file that has been written by a previous version of \whizard, you may run into an incompatibility, which will be detected as an error. If this happens, you may enforce a compatibility mode (also for writing) by setting \ttt{\$event\_file\_version} to the appropriate version string, e.g., \verb|"2.0"|. Be aware that this may break some more recent features in the event analysis. Generating an event sample can serve several purposes. First of all, it can be analyzed directly, by \whizard's built-in capabilities, to produce tables, histograms, or calculate inclusive observables. The basic analysis features of \whizard\ are described below in Sec.~\ref{sec:analysis}. It can be written to an external file in a standard format that a human or an external program can understand. In Chap.~\ref{chap:events}, you will find a more thorough discussion of event generation with \whizard, which also covers in detail the available event-file formats. Finally, \whizard\ can rescan an existing event sample. The event sample may either be the result of a previous \ttt{simulate} run or, under certain conditions, an external event sample produced by another generator or reconstructed from data. \begin{quote} \begin{footnotesize} \begin{verbatim} rescan "my_events" (proc1) { $pdf_builtin_set = "MSTW2008LO" } \end{verbatim} \end{footnotesize} \end{quote} The rescanning may apply different parameters and recalculate the matrix element, it may apply a different event selection, it may reweight the events by a different PDF set (as above). The modified event sample can again be analyzed or written to file. For more details, cf.\ Sec.~\ref{sec:rescan}. %%%%%%%%%%%%%%% \subsection{Decays} \label{sec:decays} Normally, the events generated by the \ttt{simulate} command will be identical in structure to the events that the \ttt{integrate} command generates. This implies that for a process such as $pp\to W^+W^-$, the final-state particles are on-shell and stable, so they appear explicitly in the generated event files. If events are desired where the decay products of the $W$ bosons appear, one has to generate another process, e.g., $pp\to u\bar d\bar ud$. In this case, the intermediate vector bosons, if reconstructed, are off-shell as dictated by physics, and the process contains all intermediate states that are possible. In this example, the matrix element contains also $ZZ$, photon, and non-resonant intermediate states. (This can be restricted via the \verb|$restrictions| option, cf.\ \ref{sec:process options}. Another approach is to factorize the process in production (of $W$ bosons) and decays ($W\to q\bar q$). This is actually the traditional approach, since it is much less computing-intensive. The factorization neglects all off-shell effects and irreducible background diagrams that do not have the decaying particles as an intermediate resonance. While \whizard\ is able to deal with multi-particle processes without factorization, the needed computing resources rapidly increase with the number of external particles. Particularly, it is the phase space integration that becomes the true bottleneck for a high multiplicity of final state particles. In order to use the factorized approach, one has to specify particles as \ttt{unstable}. (Also, the \ttt{?allow\_decays} switch must be \ttt{true}; this is however its default value.) We give an example for a $pp \to Wj$ final state: \begin{code} process wj = u, gl => d, Wp process wen = Wp => E1, n1 integrate (wen) sqrts = 7 TeV beams = p, p => pdf_builtin unstable Wp (wen) simulate (wj) { n_events = 1 } \end{code} This defines a $2 \to 2$ hard scattering process of $W + j$ production at the 7 TeV LHC 2011 run. The $W^+$ is marked as unstable, with its decay process being $W^+ \to e^+ \nu_e$. In the \ttt{simulate} command both processes, the production process \ttt{wj} and the decay process \ttt{wen} will be integrated, while the $W$ decays become effective only in the final event sample. This event sample will contain final states with multiplicity $3$, namely $e^+ \nu_e d$. Note that here only one decay process is given, hence the branching ratio for the decay will be taken to be $100 \%$ by \whizard. A natural restriction of the factorized approach is the implied narrow-width approximation. Theoretically, this restriction is necessary since whenever the width plays an important role, the usage of the factorized approach will not be fully justified. In particular, all involved matrix elements must be evaluated on-shell, or otherwise gauge-invariance issues could spoil the calculation. (There are plans for a future \whizard\ version to also include Breit-Wigner or Gaussian distributions when using the factorized approach.) Decays can be concatenated, e.g. for top pair production and decay, $e^+ e^- \to t \bar t$ with decay $t \to W^+ b$, and subsequent leptonic decay of the $W$ as in $W^+ \to \mu^+ \nu_\mu$: \begin{code} process eett = e1, E1 => t, tbar process t_dec = t => Wp, b process W_dec = Wp => E2, n2 unstable t (t_dec) unstable Wp (W_dec) sqrts = 500 simulate (eett) { n_events = 1 } \end{code} Note that in this case the final state in the event file will consist of $\bar t b \mu^+ \nu_\mu$ because the anti-top is not decayed. If more than one decay process is being specified like in \begin{code} process eeww = e1, E1 => Wp, Wm process w_dec1 = Wp => E2, n2 process w_dec2 = Wp => E3, n3 unstable Wp (w_dec1, w_dec2) sqrts = 500 simulate (eeww) { n_events = 100 } \end{code} then \whizard\ takes the integrals of the specified decay processes and distributes the decays statistically according to the calculated branching ratio. Note that this might not be the true branching ratios if decay processes are missing, or loop corrections to partial widths give large(r) deviations. In the calculation of the code above, \whizard\ will issue an output like \begin{code} | Unstable particle W+: computed branching ratios: | w_dec1: 5.0018253E-01 mu+, numu | w_dec2: 4.9981747E-01 tau+, nutau | Total width = 4.5496085E-01 GeV (computed) | = 2.0490000E+00 GeV (preset) | Decay options: helicity treated exactly \end{code} So in this case, \whizard\ uses 50 \% muonic and 50 \% tauonic decays of the positively charged $W$, while the $W^-$ appears directly in the event file. \whizard\ shows the difference between the preset $W$ width from the physics model file and the value computed from the two decay channels. Note that a particle in a \sindarin\ input script can be also explictly marked as being stable, using the \begin{code} stable \end{code} constructor for the particle \ttt{}. \subsubsection{Resetting branching fractions} \label{sec:br-reset} As described above, decay processes that appear in a simulation must first be integrated by the program, either explicitly via the \verb|integrate| command, or implicitly by \verb|unstable|. In either case, \whizard\ will use the computed partial widths in order to determine branching fractions. In the spirit of a purely leading-order calculation, this is consistent. However, it may be desired to rather use different branching-fraction values for the decays of a particle, for instance, NLO-corrected values. In fact, after \whizard\ has integrated any process, the integration result becomes available as an ordinary \sindarin\ variable. For instance, if a decay process has the ID \verb|h_bb|, the integral of this process -- the partial width, in this case -- becomes the variable \verb|integral(h_bb)|. This variable may be reset just like any other variable: \begin{code} integral(h_bb) = 2.40e-3 GeV \end{code} The new value will be used for all subsequent Higgs branching-ratio calculations and decays, if an unstable Higgs appears in a process for simulation. \subsubsection{Spin correlations in decays} \label{sec:spin-correlations} By default, \whizard\ applies full spin and color correlations to the factorized processes, so it keeps both color and spin coherence between productions and decays. Correlations between decay products of distinct unstable particles in the same event are also fully retained. The program sums over all intermediate quantum numbers. Although this approach obviously yields the optimal description with the limits of production-decay factorization, there is support for a simplified handling of particle decays. Essentially, there are four options, taking a decay \ttt{W\_ud}: $W^-\to \bar u d$ as an example: \begin{enumerate} \item Full spin correlations: \verb|unstable Wp (W_ud)| \item Isotropic decay: \verb|unstable Wp (W_ud) { ?isotropic_decay = true }| \item Diagonal decay matrix: \verb|unstable Wp (W_ud) { ?diagonal_decay = true }| \item Project onto specific helicity: \verb|unstable Wp (W_ud) { decay_helicity = -1 }| \end{enumerate} Here, the isotropic option completely eliminates spin correlations. The diagonal-decays option eliminates just the off-diagonal entries of the $W$ spin-density matrix. This is equivalent to a measurement of spin before the decay. As a result, spin correlations are still present in the classical sense, while quantum coherence is lost. The definite-helicity option is similar and additional selects only the specified helicity component for the decaying particle, so its decay distribution assumes the shape for an accordingly polarized particle. All options apply in the rest frame of the decaying particle, with the particle's momentum as the quantization axis. \subsubsection{Automatic decays} A convenient option is if the user did not have to specify the decay mode by hand, but if they were generated automatically. \whizard\ does have this option: the flag \ttt{?auto\_decays} can be set to \ttt{true}, and is taking care of that. In that case the list for the decay processes of the particle marked as unstable is left empty (we take a $W^-$ again as example): \begin{code} unstable Wm () { ?auto_decays = true } \end{code} \whizard\ then inspects at the local position within the \sindarin\ input file where that \ttt{unstable} statement appears the masses of all the particles of the active physics model in order to determine which decays are possible. It then calculates their partial widths. There are a few options to customize the decays. The integer variable \ttt{auto\_decays\_multiplicity} allows to set the maximal multiplicity of the final states considered in the auto decay option. The defaul value of that variable is \ttt{2}; please be quite careful when setting this to values larger than that. If you do so, the flag \ttt{?auto\_decays\_radiative} allows to specify whether final states simply containing additional resolved gluons or photons are taken into account or not. For the example above, you almost hit the PDG value for the $W$ total width: \begin{code} | Unstable particle W-: computed branching ratios: | decay_a24_1: 3.3337068E-01 d, ubar | decay_a24_2: 3.3325864E-01 s, cbar | decay_a24_3: 1.1112356E-01 e-, nuebar | decay_a24_4: 1.1112356E-01 mu-, numubar | decay_a24_5: 1.1112356E-01 tau-, nutaubar | Total width = 2.0478471E+00 GeV (computed) | = 2.0490000E+00 GeV (preset) | Decay options: helicity treated exactly \end{code} \subsubsection{Future shorter notation for decays} {\color{red} In an upcoming \whizard\ version there will be a shorter and more concise notation already in the process definition for such decays, which, however, is current not yet implemented. The two first examples above will then be shorter and have this form:} \begin{code} process wj = u, gl => (Wp => E1, n1), d \end{code} {\color{red} as well as } \begin{code} process eett = e1, E1 => (t => (Wp => E2, n2), b), tbar \end{code} %%%%% \subsection{Event formats} As mentioned above, the internal \whizard\ event format is a machine-dependent event format. There are a series of human-readable ASCII event formats that are supported: very verbose formats intended for debugging, formats that have been agreed upon during the Les Houches workshops like LHA and LHEF, or formats that are steered through external packages like HepMC. More details about event formats can be found in Sec.~\ref{sec:eventformats}. %%%%%%%%%%%%%%% \section{Analysis and Visualization} \label{sec:analysis} \sindarin\ natively supports basic methods of data analysis and visualization which are frequently used in high-energy physics studies. Data generated during script execution, in particular simulated event samples, can be analyzed to evaluate further observables, fill histograms, and draw two-dimensional plots. So the user does not have to rely on his/her own external graphical analysis method (like e.g. \ttt{gnuplot} or \ttt{ROOT} etc.), but can use methods that automatically ship with \whizard. In many cases, the user, however, clearly will use his/her own analysis machinery, especially experimental collaborations. In the following sections, we first summarize the available data structures, before we consider their graphical display. \subsection{Observables} Analyses in high-energy physics often involve averages of quantities other than a total cross section. \sindarin\ supports this by its \ttt{observable} objects. An \ttt{observable} is a container that collects a single real-valued variable with a statistical distribution. It is declared by a command of the form \begin{quote} \begin{footnotesize} \ttt{observable \emph{analysis-tag}} \end{footnotesize} \end{quote} where \ttt{\emph{analysis-tag}} is an identifier that follows the same rules as a variable name. Once the observable has been declared, it can be filled with values. This is done via the \ttt{record} command: \begin{quote} \begin{footnotesize} \ttt{record \emph{analysis-tag} (\emph{value})} \end{footnotesize} \end{quote} To make use of this, after values have been filled, we want to perform the actual analysis and display the results. For an observable, these are the mean value and the standard deviation. There is the command \ttt{write\_analysis}: \begin{quote} \begin{footnotesize} \ttt{write\_analysis (\emph{analysis-tag})} \end{footnotesize} \end{quote} Here is an example: \begin{quote} \begin{footnotesize} \begin{verbatim} observable obs record obs (1.2) record obs (1.3) record obs (2.1) record obs (1.4) write_analysis (obs) \end{verbatim} \end{footnotesize} \end{quote} The result is displayed on screen: \begin{quote} \begin{footnotesize} \begin{verbatim} ############################################################################### # Observable: obs average = 1.500000000000E+00 error[abs] = 2.041241452319E-01 error[rel] = 1.360827634880E-01 n_entries = 4 \end{verbatim} \end{footnotesize} \end{quote} \subsection{The analysis expression} \label{subsec:analysis} The most common application is the computation of event observables -- for instance, a forward-backward asymmetry -- during simulation. To this end, there is an \ttt{analysis} expression, which behaves very similar to the \ttt{cuts} expression. It is defined either globally \begin{quote} \begin{footnotesize} \ttt{analysis = \emph{logical-expr}} \end{footnotesize} \end{quote} or as a local option to the \ttt{simulate} or \ttt{rescan} commands which generate and handle event samples. If this expression is defined, it is not evaluated immediately, but it is evaluated once for each event in the sample. In contrast to the \ttt{cuts} expression, the logical value of the \ttt{analysis} expression is discarded; the expression form has been chosen just by analogy. To make this useful, there is a variant of the \ttt{record} command, namely a \ttt{record} function with exactly the same syntax. As an example, here is a calculation of the forward-backward symmetry in a process \ttt{ee\_mumu} with final state $\mu^+\mu^-$: \begin{quote} \begin{footnotesize} \begin{verbatim} observable a_fb analysis = record a_fb (eval sgn (Pz) ["mu-"]) simulate (ee_mumu) { luminosity = 1 / 1 fbarn } \end{verbatim} \end{footnotesize} \end{quote} The logical return value of \ttt{record} -- which is discarded here -- is \ttt{true} if the recording was successful. In case of histograms (see below) it is true if the value falls within bounds, false otherwise. Note that the function version of \ttt{record} can be used anywhere in expressions, not just in the \ttt{analysis} expression. When \ttt{record} is called for an observable or histogram in simulation mode, the recorded value is weighted appropriately. If \ttt{?unweighted} is true, the weight is unity, otherwise it is the event weight. The \ttt{analysis} expression can involve any other construct that can be expressed as an expression in \sindarin. For instance, this records the energy of the 4th hardest jet in a histogram \ttt{pt\_dist}, if it is in the central region: \begin{quote} \begin{footnotesize} \begin{verbatim} analysis = record pt_dist (eval E [extract index 4 [sort by - Pt [select if -2.5 < Eta < 2.5 [colored]]]]) \end{verbatim} \end{footnotesize} \end{quote} Here, if there is no 4th jet in the event which satisfies the criterion, the result will be an undefined value which is not recorded. In that case, \ttt{record} evaluates to \ttt{false}. Selection cuts can be part of the analysis expression: \begin{code} analysis = if any Pt > 50 GeV [lepton] then record jet_energy (eval E [collect [jet]]) endif \end{code} Alternatively, we can specify a separate selection expression: \begin{code} selection = any Pt > 50 GeV [lepton] analysis = record jet_energy (eval E [collect [jet]]) \end{code} The former version writes all events to file (if requested), but applies the analysis expression only to the selected events. This allows for the simultaneous application of different selections to a single event sample. The latter version applies the selection to all events before they are analyzed or written to file. The analysis expression can make use of all variables and constructs that are defined at the point where it is evaluated. In particular, it can make use of the particle content and kinematics of the hard process, as in the example above. In addition to the predefined variables and those defined by the user, there are the following variables which depend on the hard process. Some of them are constants, some vary event by event: \begin{quote} \begin{tabular}{ll} integer: &\ttt{event\_index} \\ integer: &\ttt{process\_num\_id} \\ string: &\ttt{\$process\_id} \\ integer: &\ttt{n\_in}, \ttt{n\_out}, \ttt{n\_tot} \\ real: &\ttt{sqrts}, \ttt{sqrts\_hat} \\ real: &\ttt{sqme}, \ttt{sqme\_ref} \\ real: &\ttt{event\_weight}, \ttt{event\_excess} \end{tabular} \end{quote} The \ttt{process\_num\_id} is the numeric ID as used by external programs, while the process index refers to the current library. By default, the two are identical. The process index itself is not available as a predefined observable. The \ttt{sqme} and \ttt{sqme\_ref} values indicate the squared matrix element and the reference squared matrix element, respectively. The latter applies when comparing with a reference sample (the \ttt{rescan} command). \ttt{record} evaluates to a logical, so several \ttt{record} functions may be concatenated by the logical operators \ttt{and} or \ttt{or}. However, since usually the further evaluation should not depend on the return value of \ttt{record}, it is more advisable to concatenate them by the semicolon (\ttt{;}) operator. This is an operator (\emph{not} a statement separator or terminator) that connects two logical expressions and evaluates both of them in order. The lhs result is discarded, the result is the value of the rhs: \begin{quote} \begin{footnotesize} \begin{verbatim} analysis = record hist_pt (eval Pt [lepton]) ; record hist_ct (eval cos (Theta) [lepton]) \end{verbatim} \end{footnotesize} \end{quote} \subsection{Histograms} \label{sec:histogram} In \sindarin, a histogram is declared by the command \begin{quote} \begin{footnotesize} \ttt{histogram \emph{analysis-tag} (\emph{lower-bound}, \emph{upper-bound})} \end{footnotesize} \end{quote} This creates a histogram data structure for an (unspecified) observable. The entries are organized in bins between the real values \ttt{\emph{lower-bound}} and \ttt{\emph{upper-bound}}. The number of bins is given by the value of the intrinsic integer variable \ttt{n\_bins}, the default value is 20. The \ttt{histogram} declaration supports an optional argument, so the number of bins can be set locally, for instance \begin{quote} \begin{footnotesize} \ttt{histogram pt\_distribution (0 GeV, 500 GeV) \{ n\_bins = 50 \}} \end{footnotesize} \end{quote} Sometimes it is more convenient to set the bin width directly. This can be done in a third argument to the \ttt{histogram} command. \begin{quote} \begin{footnotesize} \ttt{histogram pt\_distribution (0 GeV, 500 GeV, 10 GeV)} \end{footnotesize} \end{quote} If the bin width is specified this way, it overrides the setting of \ttt{n\_bins}. The \ttt{record} command or function fills histograms. A single call \begin{quote} \begin{footnotesize} \ttt{record (\emph{real-expr})} \end{footnotesize} \end{quote} puts the value of \ttt{\emph{real-expr}} into the appropriate bin. If the call is issued during a simulation where \ttt{unweighted} is false, the entry is weighted appropriately. If the value is outside the range specified in the histogram declaration, it is put into one of the special underflow and overflow bins. The \ttt{write\_analysis} command prints the histogram contents as a table in blank-separated fixed columns. The columns are: $x$ (bin midpoint), $y$ (bin contents), $\Delta y$ (error), excess weight, and $n$ (number of entries). The output also contains comments initiated by a \verb|#| sign, and following the histogram proper, information about underflow and overflow as well as overall contents is added. \subsection{Plots} \label{sec:plot} While a histogram stores only summary information about a data set, a \ttt{plot} stores all data as $(x,y)$ pairs, optionally with errors. A plot declaration is as simple as \begin{quote} \begin{footnotesize} \ttt{plot \emph{analysis-tag}} \end{footnotesize} \end{quote} Like observables and histograms, plots are filled by the \ttt{record} command or expression. To this end, it can take two arguments, \begin{quote} \begin{footnotesize} \ttt{record (\emph{x-expr}, \emph{y-expr})} \end{footnotesize} \end{quote} or up to four: \begin{quote} \begin{footnotesize} \ttt{record (\emph{x-expr}, \emph{y-expr}, \emph{y-error})} \\ \ttt{record (\emph{x-expr}, \emph{y-expr}, \emph{y-error-expr}, \emph{x-error-expr})} \end{footnotesize} \end{quote} Note that the $y$ error comes first. This is because applications will demand errors for the $y$ value much more often than $x$ errors. The plot output, again written by \ttt{write\_analysis} contains the four values for each point, again in the ordering $x,y,\Delta y, \Delta x$. \subsection{Analysis Output} There is a default format for piping information into observables, histograms, and plots. In older versions of \whizard\ there was a first version of a custom format, which was however rather limited. A more versatile custom output format will be coming soon. \begin{enumerate} \item By default, the \ttt{write\_analysis} command prints all data to the standard output. The data are also written to a default file with the name \ttt{whizard\_analysis.dat}. Output is redirected to a file with a different name if the variable \ttt{\$out\_file} has a nonempty value. If the file is already open, the output will be appended to the file, and it will be kept open. If the file is not open, \ttt{write\_analysis} will open the output file by itself, overwriting any previous file with the same name, and close it again after data have been written. The command is able to print more than one dataset, following the syntax \begin{quote} \begin{footnotesize} \ttt{write\_analysis (\emph{analysis-tag1}, \emph{analysis-tag2}, \ldots) \{ \emph{options} \}} \end{footnotesize} \end{quote} The argument in brackets may also be empty or absent; in this case, all currently existing datasets are printed. The default data format is suitable for compiling analysis data by \whizard's built-in \gamelan\ graphics driver (see below and particularly Chap.~\ref{chap:visualization}). Data are written in blank-separated fixed columns, headlines and comments are initiated by the \verb|#| sign, and each data set is terminated by a blank line. However, external programs often require special formatting. The internal graphics driver \gamelan\ of \whizard\ is initiated by the \ttt{compile\_analysis} command. Its syntax is the same, and it contains the \ttt{write\_analysis} if that has not been separately called (which is unnecessary). For more details about the \gamelan\ graphics driver and data visualization within \whizard, confer Chap.~\ref{chap:visualization}. \item Custom format. Not yet (re-)implemented in a general form. \end{enumerate} \section{Custom Input/Output} \label{sec:I/O} \whizard\ is rather chatty. When you run examples or your own scripts, you will observe that the program echoes most operations (assignments, commands, etc.) on the standard output channel, i.e., on screen. Furthermore, all screen output is copied to a log file which by default is named \ttt{whizard.log}. For each integration run, \whizard\ writes additional process-specific information to a file \ttt{\var{tag}.log}, where \ttt{\var{tag}} is the process name. Furthermore, the \ttt{write\_analysis} command dumps analysis data -- tables for histograms and plots -- to its own set of files, cf.\ Sec.~\ref{sec:analysis}. However, there is the occasional need to write data to extra files in a custom format. \sindarin\ deals with that in terms of the following commands: \subsection{Output Files} \subsubsection{open\_out} \begin{syntax} open\_out (\var{filename}) \\ open\_out (\var{filename}) \{ \var{options} \} \end{syntax} Open an external file for writing. If the file exists, it is overwritten without warning, otherwise it is created. Example: \begin{code} open_out ("my_output.dat") \end{code} \subsubsection{close\_out} \begin{syntax} close\_out (\var{filename}) \\ close\_out (\var{filename}) \{ \var{options} \} \end{syntax} Close an external file that is open for writing. Example: \begin{code} close_out ("my_output.dat") \end{code} \subsection{Printing Data} \subsubsection{printf} \begin{syntax} printf \var{format-string-expr} \\ printf \var{format-string-expr} (\var{data-objects}) \end{syntax} Format \ttt{\var{data-objects}} according to \ttt{\var{format-string-expr}} and print the resulting string to standard output if the string variable \ttt{\$out\_file} is undefined. If \ttt{\$out\_file} is defined and the file with this name is open for writing, print to this file instead. Print a newline at the end if \ttt{?out\_advance} is true, otherwise don't finish the line. The \ttt{\var{format-string-expr}} must evaluate to a string. Formatting follows a subset of the rules for the \ttt{printf(3)} command in the \ttt{C} language. The supported rules are: \begin{itemize} \item All characters are printed as-is, with the exception of embedded conversion specifications. \item Conversion specifications are initiated by a percent (\verb|%|) sign and followed by an optional prefix flag, an optional integer value, an optional dot followed by another integer, and a mandatory letter as the conversion specifier. \item A percent sign immediately followed by another percent sign is interpreted as a single percent sign, not as a conversion specification. \item The number of conversion specifiers must be equal to the number of data objects. The data types must also match. \item The first integer indicates the minimum field width, the second one the precision. The field is expanded as needed. \item The conversion specifiers \ttt{d} and \ttt{i} are equivalent, they indicate an integer value. \item The conversion specifier \ttt{e} indicates a real value that should be printed in exponential notation. \item The conversion specifier \ttt{f} indicates a real value that should be printed in decimal notation without exponent. \item The conversion specifier \ttt{g} indicates a real value that should be printed either in exponential or in decimal notation, depending on its value. \item The conversion specifier \ttt{s} indicates a logical or string value that should be printed as a string. \item Possible prefixes are \verb|#| (alternate form, mandatory decimal point for reals), \verb|0| (zero padding), \verb|-| (left adjusted), \verb|+| (always print sign), `\verb| |' (print space before a positive number). \end{itemize} For more details, consult the \verb|printf(3)| manpage. Note that other conversions are not supported and will be rejected by \whizard. The data arguments are numeric, logical or string variables or expressions. Numeric expressions must be enclosed in parantheses. Logical expressions must be enclosed in parantheses prefixed by a question mark \verb|?|. String expressions must be enclosed in parantheses prefixed by a dollar sign \verb|$|. These forms behave as anonymous variables. Note that for simply printing a text string, you may call \ttt{printf} with just a format string and no data arguments. Examples: \begin{code} printf "The W mass is %8f GeV" (mW) int i = 2 int j = 3 printf "%i + %i = %i" (i, j, (i+j)) string $directory = "/usr/local/share" string $file = "foo.dat" printf "File path: %s/%s" ($directory, $file) \end{code} There is a related \ttt{sprintf} function, cf.~Sec.~\ref{sec:sprintf}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{WHIZARD at next-to-leading order} \subsection{Prerequisites} A full NLO computation requires virtual matrix elements obtained from loop diagrams. Since \oMega\ cannot calculate such diagrams, external programs are used. \whizard\ has a generic interface to matrix-element generators that are BLHA-compatible. Explicit implementations exist for \gosam, \openloops\ and \recola. %%%%% \subsubsection{Setting up \gosam} The installation of \gosam\ is detailed on the HepForge page \url{https://gosam/hepforge.org}. We mention here some of the steps necessary to get it to be linked with \whizard. {\bf Bug in \gosam\ installation scripts:} In many versions of \gosam\ there is a bug in the installation scripts that is only relevant if \gosam\ is installed with superuser privileges. Then all files in \ttt{\$installdir/share/golem} do not have read privileges for normal users. These privileges must be given manually to all files in that directory. Prerequisites for \gosam\ to produce code for one-loop matrix elements are the scientific algebra program \ttt{form} and the generator of loop topologies and diagrams, \ttt{qgraf}. These can be accessed via their respective webpages \url{http://www.nikhef.nl/~form/} and \url{http://cfif.ist.utl.pt/~paulo/qgraf.html}. Note also that both \ttt{Java} and the Java runtime environment have to be installed in order for \gosam\ to properly work. Furthermore, \ttt{libtool} needs to be installed. A more convenient way to install \gosam, is the automatic installation script \url{https://gosam.hepforge.org/gosam_installer.py}. %%%%% \subsubsection{Setting up \openloops} \label{sec:openloops-setup} The installation of \openloops\ is explained in detail on the HepForge page \url{https://openloops.hepforge.org}. In the following, the main steps for usage with \whizard\ are summarized. Please note that at the moment, \openloops\ cannot be installed such that in almost all cases the explicit \openloops\ package directory has to be set via \ttt{--with-openloops=}. \openloops\ can be checked out with \begin{code} git clone https://gitlab.com/openloops/OpenLoops.git \end{code} Note that \whizard\ only supports \openloops\ version that are at least 2.1.1 or newer. Alternatively, one can use the public beta version of \openloops, which can be checked out by the command \begin{code} git clone -b public_beta https://gitlab.com/openloops/OpenLoops.git \end{code} The program can be build by running \ttt{scons} or \ttt{./scons}, a local version that is included in the \openloops\ directory. This produces the script \ttt{./openloops}, which is the main hook for the further usage of the program. \openloops\ works by downloading prebuild process libraries, which have to be installed for each individual process. This requires the file \ttt{openloops.cfg}, which should contain the following content: \begin{code} [OpenLoops] process\_repositories=public, whizard\\ compile\_extra=1 \end{code} The first line instructs \openloops\ to also look for process libraries in an additional lepton collider repository. The second line triggers the inclusion of $N+1$-particle tree-level matrix elements in the process directory, so that a complete NLO calculation including real amplitudes can be performed only with \openloops. The libraries can then be installed via \begin{code} ./openloops libinstall proc_name \end{code} A list of supported library names can be found on the \openloops\ web page. Note that a process library also includes all possible permutated processes. The process library \ttt{ppllj}, for example, can also be used to compute the matrix elements for $e^+ e^- \rightarrow q \bar{q}$ (massless quarks only). The massive case of the top quark is handled in \ttt{eett}. Additionally, there are process libraries for top and gauge boson decays, \ttt{tbw}, \ttt{vjj}, \ttt{tbln} and \ttt{tbqq}. Finally, \openloops\ can be linked to \whizard\ during configuration by including \begin{code} --enable-openloops --with-openloops=$OPENLOOPS_PATH, \end{code} where \ttt{\$OPENLOOPS\_PATH} is the directory the \openloops\ executable is located in. \openloops\ one-loop diagrams can then be used with the \sindarin\ option \begin{code} $loop_me_method = "openloops". \end{code} The functional tests which check the \openloops\ functionality require the libraries \ttt{ppllj}, \ttt{eett} and \ttt{tbw} to be installed (note that \ttt{eett} is not contained in \ttt{ppll}). During the configuration of \whizard, it is automatically checked that these two libraries, as well as the option \ttt{compile\_extra=1}, are present. \subsubsection{\openloops\ \sindarin\ flags} Several \sindarin\ options exist to control the behavior of \openloops. \begin{itemize} \item \ttt{openloops\_verbosity}:\\ Decide how much \openloops\ output is printed. Can have values 0, 1 and 2. \item \ttt{?openloops\_use\_cms}:\\ Activates the complex mass scheme. For computations with decaying resonances like the top quark or W or Z bosons, this is the preferred option to avoid gauge-dependencies. \item \ttt{openloops\_phs\_tolerance}:\\ Controls the exponent of \ttt{extra psp\_tolerance} in the BLHA interface, which is the numerical tolerance for the on-shell condition of external particles \item \ttt{openloops\_switch\_off\_muon\_yukawa}:\\ Sets the Yukawa coupling of muons to zero in order to assure agreement with \oMega, which is possibly used for other components and per default does not take $H\mu\mu$ couplings into account. \item \ttt{openloops\_stability\_log}:\\ Creates the directory \ttt{stability\_log}, which contains information about the performance of the matrix elements. Possible values are \begin{itemize} \item 0: No output (default), \item 1: On finish() call, \item 2: Adaptive, \item 3: Always \end{itemize} \item \ttt{?openloops\_use\_collier}: Use Collier as the reduction method (default true). \end{itemize} %%%%% \subsubsection{Setting up \recola} \label{sec:recola-setup} The installation of \recola\ is explained in detail on the HepForge page \url{https://recola.hepforge.org}. In the following the main steps for usage with \whizard\ are summarized. The minimal required version number of \recola\ is 1.3.0. \recola\ can be linked to \whizard\ during configuration by including \begin{code} --enable-recola \end{code} In case the \recola\ library is not in a standard path or a path accessible in the \ttt{LD\_LIBRARY\_PATH} (or \ttt{DYLD\_LIBRARY\_PATH}) of the operating system, then the option \begin{code} --with-recola=$RECOLA_PATH \end{code} can be set, where \ttt{\$RECOLA\_PATH} is the directory the \recola\ library is located in. \recola\ can then be used with the \sindarin\ option \begin{code} $method = "recola" \end{code} or any other of the matrix element methods. Note that there might be a clash of the \collier\ libraries when you have \collier\ installed both via \recola\ and via \openloops, but have compiled them with different \fortran\ compilers. %%%%% \subsection{NLO cross sections} An NLO computation can be switched on in \sindarin\ with \begin{code} process proc_nlo = in1, in2 => out1, ..., outN { nlo_calculation = }, \end{code} where the \ttt{nlo\_calculation} can be followed by a list of strings specifying the desired NLO-components to be integrated, i.e. \ttt{born}, \ttt{real}, \ttt{virtual}, \ttt{dglap}, (for hadron collisions) or \ttt{mismatch} (for the soft mismatch in resonance-aware computations) and \ttt{full}. The \ttt{full} option switches on all components and is required if the total NLO result is desired. For example, specifying \begin{code} nlo_calculation = born, virtual \end{code} will result in the computation of the Born and virtual component. The integration can be carried out in two different modes: Combined and separate integration. In the separate integration mode, each component is integrated individually, allowing for a good overview of their contributions to the total cross section and a fine tuned control over the iterations in each component. In the combined integration mode, all components are added up during integration so that the sum of them is evaluated. Here, only one integration will be displayed. The default method is the separate integration. The convergence of the integration can crucially be influenced by the presence of resonances. A better convergence is in this case achieved activating the resonance-aware FKS subtraction, \begin{code} $fks_mapping_type = "resonances". \end{code} This mode comes with an additional integration component, the so-called soft mismatch. Note that you can modify the number of iterations in each component with the multipliers: \begin{itemize} \item \ttt{mult\_call\_real} multiplies the number of calls to be used in the integration of the real component. A reasonable choice is \ttt{10.0} as the real phase-space is more complicated than the Born but the matrix elements evaluate faster than the virtuals. \item \ttt{mult\_call\_virt} multiplies the number of calls to be used in the integration of the virtual component. A reasonable choice is \ttt{0.5} to make sure that the fast Born component only contributes a negligible MC error compared to the real and virtual components. \item \ttt{mult\_call\_dglap} multiplies the number of calls to be used in the integration of the DGLAP component. \end{itemize} \subsection{Fixed-order NLO events} \label{ss:fixedorderNLOevents} Fixed-order NLO events can also be produced in three different modes: Combined weighted, combined unweighted and separated weighted. \begin{itemize} \item \textbf{Combined weighted}\\ In the combined mode, one single integration grid is produced, from which events are generated with the total NLO weight. The corresponding event file contains $N$ events with born-like kinematics and weight equal to $\mathcal{B} + \mathcal{V} + \sum_{\alpha_r} \mathcal{C}_{\alpha_r}$, where $\mathcal{B}$ is the Born matrix element, $\mathcal{V}$ is the virtual matrix element and $\mathcal{C}_{\alpha_r}$ are the subtraction terms in each singular region. For resonance-aware processes, also the mismatch value is added. Each born-like event is followed by $N_{\text{phs}}$ associated events with real kinematics, i.e. events where one additional QCD particle is present. The corresponding real matrix-elements $\mathcal{R}_\alpha$ form the weight of these events. $N_{\text{phs}}$ the number of distinct phase spaces. Two phase spaces are distinct if they share the same resonance history but have different emitters. So, two $\alpha_r$ can share the same phase space index. The combined event mode is activated by \begin{code} ?combined_nlo_integration = true ?unweighted = false ?fixed_order_nlo_events = true \end{code} Moreover, the process must be specified at next-to-leading-order in its definition using \ttt{nlo\_calculation = full}. \whizard\ then proceeds as in the usual simulation mode. I.e. it first checks whether integration grids are already present and uses them if they fit. Otherwise, it starts an integration. \item \textbf{Combined unweighted}\\ The unweighted combined events can be generated by using the \powheg\ mode, cf. also the next subsection, but disabling the additional radiation and Sudakov factors with the \ttt{?powheg\_disable\_sudakov} switch: \begin{code} ?combined_nlo_integration = true ?powheg_matching = true ?powheg_disable_sudakov = true \end{code} This will produce events with Born kinematics and unit weights (as \ttt{?unweighted} is \ttt{true} by default). The events are unweighted by using $\mathcal{B} + \mathcal{V} + \sum_{\alpha_r} (\mathcal{C}_{\alpha_r} + \mathcal{R}_{\alpha_r})$. Of course, this only works when these weights are positive over the full phase-space, which is not guaranteed for all scales and regions at NLO. However, for many processes perturbation theory works nicely and this is not an issue. \item \textbf{Separate weighted}\\ In the separate mode, grids and events are generated for each individual component of the NLO process. This method is preferable for complicated processes, since it allows to individually tune each grid generation. Moreover, the grid generation is then trivially parallelized. The event files either contain only Born kinematics with weight $\mathcal{B}$ or $\mathcal{V}$ (and mismatch in case of a resonance-aware process) or mixed Born and real kinematics for the real component like in the combined mode. However, the Born events have only the weight $\sum_{\alpha_r} \mathcal{C}_{\alpha_r}$ in this case. The separate event mode is activated by \begin{code} ?unweighted = false ?negative_weights = true ?fixed_order_nlo_events = true \end{code} Note that negative weights have to be switched on because, in contrast to the combined mode, the total cross sections of the individual components can be negative. Also, the desired component has to appear in the process NLO specification, e.g. using \ttt{nlo\_calculation = real}. \end{itemize} Weighted fixed-order NLO events are supported by any output format that supports weights like the \ttt{HepMC} format and unweighted NLO events work with any format. The output can either be written to disk or put into a FIFO to interface it to an analysis program without writing events to file. The weights in the real event output, both in the combined and separate weighted mode, are divided by a factor $N_{\text{phs}} + 1$. This is to account for the fact that we artificially increase the number of events in the output file. Thus, the sum of all event weights correctly reproduces the total cross section. \subsection{\powheg\ matching} To match the NLO computation with a parton shower, \whizard\ supports the \powheg\ matching. It generates a distribution according to \begin{align} \label{eq:powheg} \text{d}\sigma &= \text{d}\Phi_n \,{\bar{B}_{\text{s}}}\,\biggl( {\Delta_{\text{s}}}(p_T^{\text{min}}\bigr) + \text{d}\Phi_{\text{rad}}\,{\Delta_{\text{s}}}(k_{\text{T}}(\Phi_{\text{rad}})\bigr) {\frac{R_{\text{s}}}B}\biggr) \quad \text{where} \\ {\bar{B}_{\text{s}}} &= {B} + {\mathcal{V}} + \text{d}\Phi_{\text{rad}}\, {\mathcal{R}_{\text{s}}} \quad \text{and} \\ {\Delta_{\text{s}}}(p_T) &= \exp\left[- \int{\text{d}\Phi_{\text{rad}}} {\frac{R_{\text{s}}}{B}}\; \theta\left(k_T^2(\Phi_{\text{rad}}) - p_T^2\right)\right]\;. \end{align} The subscript s refers to the singular part of the real component, cf. to the next subsection. Eq.~\eqref{eq:powheg} produces either no or one additional emission. These events can then either be analyzed directly or passed on to the parton shower\footnote{E.g. \pythiaeight\ has explicit examples for \powheg\ input, see also \url{http://home.thep.lu.se/Pythia/pythia82html/POWHEGMerging.html}.} for the full simulation. You activate this with \begin{code} ?fixed_order_nlo_events = false ?combined_nlo_integration = true ?powheg_matching = true \end{code} The $p_T^{\text{min}}$ of Eq.~\eqref{eq:powheg} can be set with \ttt{powheg\_pt\_min}. It sets the minimal scale for the \powheg\ evolution and should be of order 1 GeV and set accordingly in the interfaced shower. The maximal scale is currently given by \ttt{sqrts} but should in the future be changeable with \ttt{powheg\_pt\_min}. Note that the \powheg\ event generation needs an additional grid for efficient event generation that is automatically generated during integration. Further options that steer the efficiency of this grid are \ttt{powheg\_grid\_size\_xi} and \ttt{powheg\_grid\_size\_y}. \subsection{Separation of finite and singular contributions} For both the pure NLO computations as well as the \powheg\ event generation, \whizard\ supports the partitioning of the real into finite and singular contributions with the flag \begin{code} ?nlo_use_real_partition = true \end{code} The finite contributions, which by definition should not contain soft or collinear emissions, will then integrate like a ordinary LO integration with one additional particle. Similarly, the event generation will produce only real events without subtraction terms with Born kinematics for this additional finite component. The \powheg\ event generation will also only use the singular parts. The current implementation uses the following parametrization \begin{align} R &= R_{\text{fin}} + R_{\text{sing}} \;,\\ R_{\text{sing}} &= R F(\Phi_{n+1}) \;,\\ R_{\text{fin}} &= R (1-F(\Phi_{n+1})) \;,\\ F(\Phi_{n+1}) &= \begin{cases} 1 & \text{if} \quad\exists\,(i,j)\in\mathcal{P}_{\text{FKS}}\quad \text{with} \quad \sqrt{(p_i+p_j)^2} < h + m_i + m_j \\ 0 & \text{else} \end{cases} \;. \end{align} Thus, a point is {singular ($F=1$)}, if {any} of the {FKS tuples} forms an {invariant mass} that is {smaller than the hardness scale $h$}. This parameter is controlled in \sindarin\ with \ttt{real\_partition\_scale}. This simplifies in {massless case} to \begin{align} F(\Phi_{n+1}) = \begin{cases} 1 & \text{if} \;\exists\,(i,j)\in\mathcal{P}_{\text{FKS}}\quad \text{with} \quad 2 E_i E_j (1-\cos\theta_{ij}) < h^2 \\ 0 & \text{else} \end{cases} \;. \end{align} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Random number generators} \label{chap:rng} \section{General remarks} \label{sec:rng} The random number generators (RNG) are one of the crucialer points of Monte Carlo calculations, hence, giving those their ``randomness''. A decent multipurpose random generator covers \begin{itemize} \item reproducibility \item large period \item fast generation \item independence \end{itemize} of the random numbers. Therefore, special care is taken for the choice of the RNGs in \whizard{}. It is stated that \whizard{} utilizes \textit{pseudo}-RNGs, which are based on one (or more) recursive algorithm(s) and start-seed(s) to have reproducible sequences of numbers. In contrast, a genuine random generator relies on physical processes. \whizard\ ships with two completely different random number generators which can be selected by setting the \sindarin\ option \begin{code} $rng_method = "rng_tao" \end{code} Although, \whizard{} sets a default seed, it is adviced to use a different one \begin{code} seed = 175368842 \end{code} note that some RNGs do not allow certain seed values (e.g. zero seed). \section{The TAO Random Number Generator} \label{sec:tao} The TAO (``The Art Of'') random number generator is a lagged Fibonacci generator based upon (signed) 32-bit integer arithmetic and was proposed by Donald E. Knuth and is implemented in the \vamp\ package. The TAO random number generator is the default RNG of \whizard{}, but can additionally be set as \sindarin\ option \begin{code} $rng_method = rng_tao \end{code} The TAO random number generators is a subtractive lagged Fibonacci generator \begin{equation*} x_{j} = \left( x_{j-k} - x_{j-L} \right) \mod 2^{30} \end{equation*} with lags $k = 100$ and $l = 37$ and period length $\rho = 2^{30} - 2$. \section{The RNGStream Generator} \label{sec:rngstream} The RNGStream \cite{L_Ecuyer:2002} was originally implemented in \cpp\ with floating point arithmetic and has been ported to \fortranOThree{}. The RNGstream can be selected by the \sindarin\ option \begin{code} $rng_method = "rng_stream" \end{code} The RNGstream supports multiple independent streams and substreams of random numbers which can be directly accessed. The main advantage of the RNGStream lies in the domain of parallelization where different worker have to access different parts of the random number stream to ensure numerical reproducibility. The RNGstream provides exactly this property with its (sub)stream-driven model. Unfortunately, the RNGStream can only be used in combination with \vamptwo{}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Integration Methods} \section{The Monte-Carlo integration routine: \ttt{VAMP}} \label{sec:vamp} \vamp\ \cite{Ohl:1998jn} is a multichannel extension of the \vegas\ \cite{Lepage:1980dq} algorithm. For all possible singularities in the integrand, suitable maps and integration channels are chosen which are then weighted and superimposed to build the phase space parameterization. Both grids and weights are modified in the adaption phase of the integration. The multichannel integration algorithm is implemented as a \fortranNinetyFive\ library with the task of mapping out the integrand and finding suitable parameterizations being completely delegated to the calling program (\whizard\ core in this case). This makes the actual \vamp\ library completely agnostic of the model under consideration. \section{The next generation integrator: \ttt{VAMP2}} \label{sec:vamp2} \vamptwo\ is a modern implementation of the integrator package \vamp\ written in \fortranOThree\, providing the same features. The backbone integrator is still \vegas\ \cite{Lepage:1980dq}, although implemented differently as in \vamp{}. The main advantage over \vamp\ is the overall faster integration due to the usage of \fortranOThree{}, the possible usage of different random number generators and the complete parallelization of \vegas\ and the multichannel integration. \vamptwo{} can be set by the \sindarin{} option \begin{code} $integration_method = "vamp2" \end{code} It is said that the generated grids between \vamp{} and \vamptwo{} are incompatible. \subsection{Multichannel integration} \label{sec:multi-channel} The usual matrix elements do not factorise with respect to their integration variables, thus making an direct integration ansatz with VEGAS unfavorable.\footnote{One prerequisite for the VEGAS algorithm is that the integral factorises, and such produces only the best results for those.} Instead, we apply the multichannel ansatz and let VEGAS integrate each channel in a factorising mapping. The different structures of the matrix element are separated by a partition of unity and the respective mappings, such that each structure factorise at least once. We define the mappings $\phi_i : U \mapsto \Omega$, where $U$ is the unit hypercube and $\Omega$ the physical phase space. We refer to each mapping as a \textit{channel}. Each channel then gives rise to a probability density $g_i : U \mapsto [0, \infty)$, normalised to unity \begin{equation*} \int_0^1 g_i(\phi_i^{-1}(p)) \left| \frac{\partial \phi_i^{-1}}{\partial p} \right| \mathrm{d}\mu(p) = 1, \quad g_i(\phi_i^{-1}(p)) \geq 0, \end{equation*} written for a phase space point $p$ using the mapping $\phi_i$. The \textit{a-priori} channel weights $\alpha_i$ are defined as partition of unity by $\sum_{i\in I} \alpha_i = 1$ and $0 \leq \alpha_i \leq 1$. The overall probability density $g$ of a random sample is then obtained by \begin{equation*} g(p) = \sum_{i \in I} \alpha_i g_i(\phi_i^{-1}(p)) \left| \frac{\partial \phi_i^{-1}}{\partial p} \right|, \end{equation*} which is also a non-negative and normalized probability density. We reformulate the integral \begin{equation*} I(f) = \sum_{i \in I} \alpha_i \int_\Omega g_i(\phi_i^{-1}(p)) \left| \frac{\partial \phi_i^{-1}}{\partial p} \right| \frac{f(p)}{g(p)} \mathrm{d}\mu(p). \end{equation*} The actual integration of each channel is then done by VEGAS, which shapes the $g_i$. \subsection{VEGAS} \label{sec:vegas} VEGAS is an adaptive and iterative Monte Carlo algorithm for integration using importance sampling. After each iteration, VEGAS adapts the probability density $g_i$ using information collected while sampling. For independent integration variables, the probability density factorises $g_i = \prod_{j = 1}^{d} g_{i,j}$ for each integration axis and each (independent) $g_{i,j}$ is defined by a normalised step function \begin{equation*} g_{i,j} (x_j) = \frac{1}{N\Delta x_{j,k}}, \quad x_{j,k} - \Delta x_{j,k} \leq x_{j} < x_{j,k}, \end{equation*} where the steps are $0 = x_{j, 0} < \cdots < x_{j,k} < \cdots < x_{j,N} = 1$ for each dimension $j$. The algorithm randomly selects for each dimension a bin and a position inside the bin and calculates the respective $g_{i,j}$. \subsection{Channel equivalences} \label{sec:equivalences} The automated mulitchannel phasespace configuration can lead to a surplus of degrees of freedom, e.g. for a highly complex process with a large number of channels (VBS). In order to marginalize the redundant degrees of freedom of phasespace configuration, the adaptation distribution of the grids are aligned in accordance to their phasespace relation, hence the binning of the grids is equialized. These equivalences are activated by default for \vamp{} and \vamptwo{}, but can be steered by: \begin{code} ?use_vamp_equivalences = true \end{code} Be aware, that the usage of equivalences are currently only possible for LO processes. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Phase space parameterizations} \section{General remarks} \whizard\ as a default performs an adaptive multi-channel Monte-Carlo integration. Besides its default phase space algorithm, \ttt{wood}, to be detailed in Sec.~\ref{sec:wood}, \whizard\ contains a phase space method \ttt{phs\_none} which is a dummy method that is intended for setups of processes where no phase space integration is needed, but the program flow needs a (dummy) integrator for internal consistency. Then, for testing purposes, there is a single-channel phase space integrator, \ttt{phs\_single}. From version 2.6.0 of \whizard\ on, there is also a second implementation of the \ttt{wood} phase space algorithm, called \ttt{fast\_wood}, cf. Sec.~\ref{sec:fast_wood}, whose implementation differs technically and which therefore solves certain technical flaws of the \ttt{wood} implementation. Additionally, \whizard\ supports single-channel, flat phase-space using RAMBO (on diet). %%% \section{The flat method: \ttt{rambo}} \label{sec:rambo} The \ttt{RAMBO} algorithm produces a flat phase-space with constant volume for massless particles. \ttt{RAMBO} was originally published in \cite{Kleiss:1985gy}. We use the slim version, called \ttt{RAMBO} on diet, published in \cite{Platzer:2013esa}. The overall weighting efficiency of the algorithm is unity for massless final-state particles. For the massive case, the weighting efficiency of unity will decrease rendering the algorithm less efficient. But in most cases, the invariants are in regions of phase space where they are much larger than the masses of the final-state particles. We provide the \ttt{RAMBO} mainly for cross checking our implementation and do not recommend it for real world application, even though it can be used as one. The \ttt{RAMBO} method becomes useful as a fall-back option if the standard algorithm fails for physical reasons, see, e.g., Sec.~\ref{sec:ps_anomalous}. %%% \section{The default method: \ttt{wood}} \label{sec:wood} The \ttt{wood} algorithm classifies different phase space channels according to their importance for a full scattering or decay process following heuristic rules. For that purpose, \whizard\ investigates the kinematics of the different channels depending on the total center-of-mass energy (or the mass of the decaying particle) and the masses of the final-state particles. The \ttt{wood} phase space inherits its name from the naming schemes of structures of increasing complexities, namely trees, forests and groves. Simply stated, a phase-space forest is a collection of phase-space trees. A phase-space tree is a parameterization for a valid channel in the multi-channel adaptive integration, and each variable in the a tree corresponds to an integration dimension, defined by an appropriate mapping of the $(0,1)$ interval of the unit hypercube to the allowed range of the corresponding integration variable. The whole set of these phase-space trees, collected in a phase-space forest object hence contains all parameterizations of the phase space that \whizard\ will use for a single hard process. Note that processes might contain flavor sums of particles in the final state. As \whizard\ will use the same phase space parameterization for all channels for this set of subprocesses, all particles in those flavor sums have to have the same mass. E.g. in the definition of a "light" jet consisting of the first five quarks and antiquarks, \begin{code} alias jet = u:d:s:c:b:U:D:S:C:B \end{code} all quarks including strange, charm and bottom have to be massless for the phase-space integration. \whizard\ can treat processes with subprocesses having final-state particles with different masses in an "additive" way, where each subprocess will become a distinct component of the whole process. Each process component will get its own phase-space parameterization, such that they can allow for different masses. E.g. in a 4-flavor scheme for massless $u,d,s,c$ quarks one can write \begin{code} alias jet = u:d:s:c:U:D:S:C process eeqq = e1, E1 => (jet, jet) + (b, B) \end{code} In that case, the parameterizations will be for massless final state quarks for the first subprocess, and for massive $b$ quarks for the second subprocess. In general, for high-energy lepton colliders, the difference would not matter much, but performing the integration e.g. for $\sqrt{s} = 11$ GeV, the difference will be tremendous. \whizard\ avoids inconsistent phase-space parameterizations in that way. As a multi-particle process will contain hundred or thousands of different channels, the different integration channels (trees) are grouped into so called {\em groves}. All channels/trees in the same grove share a common weight for the phase-space integration, following the assumption that they are related by some approximate symmetry. The \vamp\ adaptive multi-channel integrator (cf. Sec.~\ref{sec:vamp}) allows for equivalences between different integration channels. This means that trees/channels that are related by an exact symmetry are connected by an array of these equivalences. The phase-space setup, i.e. the detailed structure of trees and forests, are written by \whizard\ into a phase-space file that has the same name as the corresponding process (or process component) with the suffix \ttt{.phs}. For the \ttt{wood} phase-space method this file is written by a \fortran\ module which constructs a similar tree-like structure as the directed acyclical graphs (DAGs) in the \oMega\ matrix element generator but in a less efficient way. In some very rare cases with externally generated models (cf. Chapter~\ref{chap:extmodels}) the phase-space generation has been reported to fail as \whizard\ could not find a valid phase-space channel. Such pathological cases cannot occur for the hard-coded model implementations inside \whizard. They can only happen if there are in principle two different Feynman diagrams contributing to the same phase-space channel and \whizard\ considers the second one as extremely subleading (and would hence drop it). If for some reason however the first Feynman diagram is then absent, no phase-space channel could be found. This problem cannot occur with the \ttt{fast\_wood} implementation discussed in the next section, cf.~\ref{sec:fast_wood}. The \ttt{wood} algorithms orders the different groves of phase-space channels according to a heuristic importance depending on the kinematic properties of the different phase-space channels in the groves. A phase-space (\ttt{.phs}) file looks typically like this: \begin{code} process sm_i1 ! List of subprocesses with particle bincodes: ! 8 4 1 2 ! e+ e- => mu+ mu- ! 8 4 1 2 md5sum_process = "1B3B7A30C24664A73D3D027382CFB4EF" md5sum_model_par = "7656C90A0B2C4325AD911301DACF50EB" md5sum_phs_config = "6F72D447E8960F50FDE4AE590AD7044B" sqrts = 1.000000000000E+02 m_threshold_s = 5.000000000000E+01 m_threshold_t = 1.000000000000E+02 off_shell = 2 t_channel = 6 keep_nonresonant = T ! Multiplicity = 2, no resonances, 0 logs, 0 off-shell, s-channel graph grove #1 ! Channel #1 tree 3 ! Multiplicity = 1, 1 resonance, 0 logs, 0 off-shell, s-channel graph grove #2 ! Channel #2 tree 3 map 3 s_channel 23 ! Z \end{code} The first line contains the process name, followed by a list of subprocesses with the external particles and their binary codes. Then there are three lines of MD5 check sums, used for consistency checks. \whizard\ (unless told otherwise) will check for the existence of a phase-space file, and if the check sum matches, it will reuse the existing file and not generate it again. Next, there are several kinematic parameters, namely the center-of-mass energy of the process, \ttt{sqrts}, and two mass thresholds, \ttt{m\_threshold\_s} and \ttt{m\_threshold\_t}. The latter two are kinematical thresholds, below which \whizard\ will consider $s$-channel and $t$-channel-like kinematic configurations as effectively massless, respectively. The default values shown in the example have turned out to be optimal values for Standard Model particles. The two integers \ttt{off\_shell} and \ttt{t\_channel} give the number of off-shell lines and of $t$-channel lines that \whizard\ will allow for finding valid phase-space channels, respectively. This neglects extremley multi-peripheral background-like diagram constellations which are very subdominamnt compared to resonant signal processes. The final flag specifies whether \whizard\ will keep non-resonant phase-space channels (default), or whether it will focus only on resonant situations. After this header, there is a list of all groves, i.e. collections of phase-space channels which are connected by quasi-symmetries, together with the corresponding multiplicity of subchannels in that grove. In the phase-space file behind the multiplicity, \whizard\ denotes the number of (massive) resonances, logarithmcally enhanced kinematics (e.g. collinear regions), and number of off-shell lines, respectively. The final entry in the grove header notifies whether the diagrams in that grove have $s$-channel topologies, or count the number of corresponding $t$-channel lines. Another example is shown here, \begin{code} ! Multiplicity = 3, no resonances, 2 logs, 0 off-shell, 1 t-channel line grove #1 ! Channel #1 tree 3 12 map 3 infrared 22 ! A map 12 t_channel 2 ! u ! Channel #2 tree 3 11 map 3 infrared 22 ! A map 11 t_channel 2 ! u ! Channel #3 tree 3 20 map 3 infrared 22 ! A map 20 t_channel 2 ! u ! Channel #4 tree 3 19 map 3 infrared 22 ! A map 19 t_channel 2 ! u \end{code} where \whizard\ notifies in different situations a photon exchange as \ttt{infrared}. So it detects a possible infrared singularity where a particle can become arbitrarily soft. Such a situation can tell the user that there might be a cut necessary in order to get a meaningful integration result. The phase-space setup that is generated and used by the \ttt{wood} phase-space method can be visualized using the \sindarin\ option \begin{code} ?vis_channels = true \end{code} The \ttt{wood} phase-space method can be invoked with the \sindarin\ command \begin{code} $phs_method = "wood" \end{code} Note that this line is unnecessary, as \ttt{wood} is the default phase-space method of \whizard. %%%%% \section{A new method: \ttt{fast\_wood}} \label{sec:fast_wood} This method (which is available from version 2.6.0 on) is an alternative implementation of the \ttt{wood} phase-space algorithm. It uses the recursive structures inside the \oMega\ matrix element generator to generate all the structures needed for the different phase-space channels. In that way, it can avoid some of the bottlenecks of the \ttt{wood} \fortran\ implementation of the algorithm. On the other hand, it is only available if the \oMega\ matrix element generator has been enabled (which is the default for \whizard). The \ttt{fast\_wood} method is then invoked via \begin{code} ?omega_write_phs_output = true $phs_method = "fast_wood" \end{code} The first option is necessary in order to tell \oMega\ to write out the output needed for the \ttt{fast\_wood} parser in order to generate the phase-space file. This is not enabled by default in order not to generate unnecessary files in case the default method \ttt{wood} is used. So the \ttt{fast\_wood} implementation of the \ttt{wood} phase-space algorithm parses the tree-like represenation of the recursive set of one-particle off-shell wave functions that make up the whole amplitude inside \oMega\ in the form of a directed acyclical graph (DAG) in order to generate the phase-space (\ttt{.phs}) file (cf. Sec.~\ref{sec:wood}). In that way, the algorithm makes sure that only phase-space channels are generated for which there are indeed (sub)amplitudes in the matrix elements, and this also allows to exclude vetoed channels due to restrictions imposed on the matrix elements from the phase-space setup (cf. next Sec.~\ref{sec:ps_restrictions}). %%%%% \section{Phase space respecting restrictions on subdiagrams} \label{sec:ps_restrictions} The \fortran\ implementation of the \ttt{wood} phase-space does not know anything about possible restrictions that maybe imposed on the \oMega\ matrix elements, cf. Sec.~\ref{sec:process options}. Consequently, the \ttt{wood} phase space also generates phase-space channels that might be absent when restrictions are imposed. This is not a principal problem, as in the adaptation of the phase-space channels \whizard's integrator \vamp\ will recognize that there is zero weight in that channel and will drop the channel (stop sampling in that channel) after some iterations. However, this is a waste of ressources as it is in principle known that this channel is absent. Using the \ttt{fast\_wood} phase-space algorithm (cf. Sec.~\ref{sec:fast_wood} will take restrictions into account, as \oMega\ will not generate trees for channels that are removed with the restrictions command. So it advisable for the user in the case of very complicated processes with restrictions to use the \ttt{fast\_wood} phase-space method to make \whizard\ generation and integration of the phase space less cumbersome. %%%%% \section{Phase space for processes forbidden at tree level} \label{sec:ps_anomalous} The phase-space generators \ttt{wood} and \ttt{fast\_wood} are intended for tree-level processes with their typical patterns of singularities, which can be read off from Feynman graphs. They can and should be used for loop-induced or for externally provided matrix elements as long as \whizard\ does not provide a dedicated phase-space module. Some scattering processes do not occur at tree level but become allowed if loop effects are included in the calculation. A simple example is the elastic QED process \begin{displaymath} A\quad A \longrightarrow A\quad A \end{displaymath} which is mediated by a fermion loop. Similarly, certain applications provide externally provided or hand-taylored matrix-element code that replaces the standard \oMega\ code. Currently, \whizard's phase-space parameterization is nevertheless tied to the \oMega\ generator, so for tree-level forbidden processes the phase-space construction process will fail. There are two possible solutions for this problem: \begin{enumerate} \item It is possible to provide the phase-space parameterization information externally, by supplying an appropriately formatted \ttt{.phs} file, bypassing the automatic algorithm. Assuming that this phase-space file has been named \ttt{my\_phase\_space.phs}, the \sindarin\ code should contain the following: \begin{code} ?rebuild_phase_space = false $phs_file = "my_phase_space.phs" \end{code} Regarding the contents of this file, we recommend to generate an appropriate \ttt{.phs} for a similar setup, using the standard algorithm. The generated file can serve as a template, which can be adapted to the particular case. In detail, the \ttt{.phs} file consists of entries that specify the process, then a standard header which contains MD5 sums and such -- these variables must be present but their values are irrelevant for the present case --, and finally at least one \ttt{grove} with \ttt{tree} entries that specify the parameterization. Individual parameterizations are built from the final-state and initial-state momenta (in this order) which we label in binary form as $1,2,4,8,\dots$. The actual tree consists of iterative fusions of those external lines. Each fusion is indicated by the number that results from adding the binary codes of the external momenta that contribute to it. For instance, a valid phase-space tree for the process $AA\to AA$ is given by the simple entry \begin{code} tree 3 \end{code} which indicates that the final-state momenta $1$ and $2$ are combined to a fusion $1+2=3$. The setup is identical to a process such as $e^+e^-\to\mu^+\mu^-$ below the $Z$ threshold. Hence, we can take the \ttt{.phs} file for the latter process, replace the process tag, and use it as an external phase-space file. \item For realistic applications of \whizard\ together with one-loop matrix-element providers, the actual number of final-state particles may be rather small, say $2,3,4$. Furthermore, one-loop processes which are forbidden at tree level do not contain soft or collinear singularities. In this situation, the \ttt{RAMBO} phase-space integration method, cf.\ Sec.~\ref{sec:rambo} is a viable alternative which does not suffer from the problem. \end{enumerate} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Methods for Hard Interactions} \label{chap:hardint} The hard interaction process is the core of any physics simulation within an MC event generator. One tries to describe the dominant particle interaction in the physics process of interest at a given order in perturbation theory, thereby making use of field-theoretic factorization theorems, especially for QCD, in order to separate non-perturbative physics like parton distribution functions (PDFs) or fragmentation functions from the perturbative part. Still, it is in many cases not possible to describe the perturbative part completely by means of fixed-order hard matrix elements: in soft and/or collinear regions of phase space, multiple emission of gluons and quarks (in general QCD jets) and photons necessitates a resummation, as large logarithms accompany the perturbative coupling constants and render fixed-order perturbation theory unreliable. The resummation of these large logarithms can be done analytically or (semi-)numerically, however, usually only for very inclusive quantities. At the level of exclusive events, these phase space regions are the realm of (QCD and also QED) parton showers that approximate multi-leg matrix elements from the hard perturbative into to the soft-/collinear regime. The hard matrix elements are then the core building blocks of the physics description inside the MC event generator. \whizard\ generates these hard matrix elements at tree-level (or sometimes for loop-induced processes using effective operators as insertions) as leading-order processes. This is done by the \oMega\ subpackage that is automatically called by \whizard. Besides these physical matrix elements, there exist a couple of methods to generate dummy matrix elements for testing purposes, or for generating beam profiles and using them with externally linked special matrix elements. Especially for one-loop processes (next-to-leading order for tree-allowed processes or leading-order for loop-induced processes), \whizard\ allows to use matrix elements from external providers, so called OLP programs (one-loop providers). Of course, all of these external packages can also generate tree-level matrix elements, which can then be used as well in \whizard. We start the discussion with the two different options for test matrix elements, internal test matrix elements with no generated compiled code in Sec.~\ref{sec:test_me} and so called template matrix elements with actual \fortran\ code that is compiled and linked, and can also be modified by the user in Sec.~\ref{sec:template_me}. Then, we move to the main matrix element method by the matrix element generator \oMega\ in Sec.~\ref{sec:omega_me}. Matrix elements from the external matrix element generators are discussed in the order of which interfaces for the external tools have been implemented: \gosam\ in Sec.~\ref{sec:gosam_me}, \openloops\ in Sec.~\ref{sec:openloops_me}, and \recola\ in Sec.~\ref{sec:recola_me}. %%%%% \section{Internal test matrix elements} \label{sec:test_me} This method is merely for internal consistency checks inside \whizard, and is not really intended to be utilized by the user. The method is invoked by \begin{code} $method = "unit_test" \end{code} This particular method is only applicable for the internal test model \ttt{Test.mdl}, which just contains a Higgs boson and a top quark. Technically, it will also works within model specifications for the Standard Model, or the Minimal Supersymmetric Standard Model (MSSM), or all models which contain particles named as \ttt{H} and \ttt{t} with PDG codes 25 and 6, respectively. So, the models \ttt{QED} and {QCD} will not work. Irrespective of what is given in the \sindarin\ file as a scattering input process, \whizard\ will always take the process \begin{code} model = SM process = H, H => H, H \end{code} or for the test model: \begin{code} model = Test process = s, s => s, s \end{code} as corresponding process. (This is the same process, just with differing nomenclature in the different models). No matrix element code is generated and compiled, the matrix element is completely internal, included in the \whizard\ executable (or library), with a unit value for the squared amplitude. The integration will always be performed for this particularly process, even if the user provides a different process for that method. Hence, the result will always be the volume of the relativistic two-particle phase space. The only two parameters that influence the result are the collider energy, \ttt{sqrts}, and the mass of the Higgs particle with PDG code 25 (this mass parameter can be changed in the model \ttt{Test} as \ttt{ms}, while it would be \ttt{mH} in the Standard Model \ttt{SM}. It is also possible to use a test matrix element, again internal, for decay processes, where again \whizard\ will take a predefined process: \begin{code} model = SM process = H => t, tbar \end{code} in the \ttt{SM} model or \begin{code} model = Test process = s => f, fbar \end{code} Again, this is the same process with PDG codes $25 \to 6 \; -6$ in the corresponding models. Note that in the model \ttt{SM} the mass of the quark is set via the variable \ttt{mtop}, while it is \ttt{mf} in the model \ttt{Test}. Besides the fact that the user always gets a fixed process and cannot modify any matrix element code by hand, one can do all things as for a normal process like generating events, different weights, testing rebuild flags, using different setups and reweight events accordingly. Also factorized processes with production and decay can be tested that way. In order to avoid confusion, it is highly recommended to use this method \ttt{unit\_test} only with the test model setup, model \ttt{Test}. On the technical side, the method \ttt{unit\_test} does not produce a process library (at least not an externally linked one), and also not a makefile in order to modify any process files (which anyways do not exist for that method). Except for the logfiles and the phase space file, all files are internal. %%%%% \section{Template matrix elements} \label{sec:template_me} Much more versatile for the user than the previous matrix element method in~\ref{sec:test_me}, are two different methods with constant template matrix elements. These are written out as \fortran\ code by the \whizard\ main executable (or library), providing an interface that is (almost) identical to the matrix element code produced by the \oMega\ generator (cf. the next section, Sec.~\ref{sec:omega_me}. There are actually two different methods for that purpose, providing matrix elements with different normalizations: \begin{code} $method = "template" \end{code} generates matrix elements which give after integration over phase space exactly one. Of course, for multi-particle final states the integration can fluctuate numerically and could then give numbers that are only close to one but not exactly one. Furthermore, the normalization is not exact if any of the external particles have non-zero masses, or there are any cuts involved. But otherwise, the integral from \whizard\ should give unity irrespective of the number of final state particles. In contrast to this, the second method, \begin{code} $method = "template_unity" \end{code} gives a unit matrix elements, or rather a matrix element that contains helicity and color averaging factors for the initial state and the square root of the factorials of identical final state particles in the denominator. Hence, integration over the final state momentum configuration gives a cross section that corresponds to the volume of the $n$-particle final state phase space, divided by the corresponding flux factor, resulting in \begin{equation} \sigma(s, 2 \to 2,0) = \frac{3.8937966\cdot 10^{11}}{16\pi} \cdot \frac{1}{s \text{[GeV]}^2} \; \text{fb} \end{equation} for the massless case and \begin{equation} \sigma(s, 2 \to 2,m_i) = \frac{3.8937966\cdot 10^{11}}{16\pi} \cdot \sqrt{\frac{\lambda (s,m_3^2,m_4^2)}{\lambda (s,m_1^2,m_2^2)}} \cdot \frac{1}{s \text{[GeV]}^2} \; \text{fb} \end{equation} for the massive case. Here, $m_1$ and $m_2$ are the masses of the incoming, $m_3$ and $m_4$ the masses of the outgoing particles, and $\lambda(x,y,z) = x^2 + y^2 + z^2 - 2xy - 2xz - 2yz$. For the general massless case with no cuts, the integral should be exactly \begin{equation} \sigma(s, 2\to n, 0) = \frac{(2\pi)^4}{2 s}\Phi_n(s) = \frac{1}{16\pi s}\,\frac{\Phi_n(s)}{\Phi_2(s)}, \end{equation} where the volume of the massless $n$-particle phase space is given by \begin{equation}\label{phi-n} \Phi_n(s) = \frac{1}{4(2\pi)^5} \left(\frac{s}{16\pi^2}\right)^{n-2} \frac{1}{(n-1)!(n-2)!}. \end{equation} For $n\neq2$ the phase space volume is dimensionful, so the units of the integral are $\fb\times\GeV^{2(n-2)}$. (Note that for physical matrix elements this is compensated by momentum factors from wave functions, propagators, vertices and possibly dimensionful coupling constants, but here the matrix element is just equal to unity.) Note that the phase-space integration for the \ttt{template} and \ttt{template\_unity} matrix element methods is organized in the same way as it would be for the real $2\to n$ process. Since such a phase space parameterization is not optimized for the constant matrix element that is supplied instead, good convergence is not guaranteed. (Setting \ttt{?stratified = true} may be helpful here.) The possibility to call a dummy matrix element with this method allows to histogram spectra or structure functions: Choose a trivial process such as $uu\to dd$, select the \ttt{template\_unity} method, switch on structure functions for one (or both) beams, and generate events. The distribution of the final-state mass squared reflects the $x$ dependence of the selected structure function. Furthermore, the constant in the source code of the unit matrix elements can be easily modified by the user with their \fortran\ code in order to study customized matrix elements. Just rerun \whizard\ with the \ttt{--recompile} option after the modification of the matrix element code. Both methods, \ttt{template} and \ttt{template\_unity} will also work even if no \ocaml\ compiler is found or used and consequently the \oMega\ matrix elemente generator (cf. Sec.~\ref{sec:omega_me} is disable. The methods produce a process library for their corresponding processes, and a makefile, by which \whizard\ steers compilation and linking of the process source code. %%%%% \section{The O'Mega matrix elements} \label{sec:omega_me} \oMega\ is a subpackage of \whizard, written in \ocaml, which can produce matrix elements for a wide class of implemented physics models (cf. Sec.~\ref{sec:smandfriends} and \ref{sec:bsmmodels} for a list of all implemented physics models), and even almost arbitrary models when using external Lagrange level tools, cf. Chap.~\ref{chap:extmodels}. There are two different variants for matrix elements from \oMega: the first one is invoked as \begin{code} $method = "omega" \end{code} and is the default method for \whizard. It produces matrix element as \fortran\ code which is then compiled and linked. An alternative method, which for the moment is only available for the Standard Model and its variants as well models which are quite similar to the SM, e.g. the Two-Higgs doublet model or the Higgs-singlet extension. This method is taken when setting \begin{code} $method = "ovm" \end{code} The acronym \ttt{ovm} stands for \oMega\ Virtual Machine (OVM). The first (default) method (\ttt{omega}) of \oMega\ matrix elements produces \fortran\ code for the matrix elements,that is compiled by the same compiler with which \whizard\ has been compiled. The OVM method (\ttt{ovm}) generates an \ttt{ASCII} file with so called op code for operations. These are just numbers which tell what numerical operations are to be performed on momenta, wave functions and vertex expression in order to yield a complex number for the amplitude. The op codes are interpreted by the OVM in the same as a Java Virtual Machine. In both cases, a compiled \fortran\ is generated which for the \ttt{omega} method contains the full expression for the matrix element as \fortran\ code, while for the \ttt{ovm} method this is the driver file of the OVM. Hence, for the \ttt{ovm} method this file always has roughly the same size irrespective of the complexity of the process. For the \ttt{ovm} method, there will also be the \ttt{ASCII} file that contains the op codes, which has a name with an \ttt{.hbc} suffix: \ttt{.hbc}. For both \oMega\ methods, there will be a process library created as for the template matrix elements (cf. Sec.~\ref{sec:template_me}) named \ttt{default\_lib.f90} which can be given a user-defined name using the \ttt{library = ""} command. Again, for both methods \ttt{omega} and \ttt{ovm}, a makefile named \ttt{\_lib.makefile} is generated by which \whizard\ steers compilation, linking and clean-up of the process sources. This makefile can handily be adapted by the user in case she or he wants to modify the source code for the process (in the case of the source code method). Note that \whizard's default ME method via \oMega\ allows the user to specify many different options either globally for all processes in the \sindarin, or locally for each process separately in curly brackets behind the corresponding process definition. Examples are \begin{itemize} \item Restrictions for the matrix elements like the exclusion of intermediate resonances, the appearance of specific vertices or coupling constants in the matrix elments. For more details on this cf. Sec.~\ref{subsec:restrictions}. \item Choice of a specific scheme for the width of massive intermediate resonances, whether to use constant width, widths only in $s$-channel like kinematics (this is the default), a fudged-width scheme or the complex-mass scheme. The latter is actually steered as a specific scheme of the underlying model and not with a specific \oMega\ command. \item Choice of the electroweak gauge for the amplitude. The default is the unitary gauge. \end{itemize} With the exception of the restrictions steered by the \ttt{\$restrictions = ""} string expression, these options have to be set in their specific \oMega\ syntax verbatim via the string command \ttt{\$omega\_flags = ""}. %%%%% \section{Interface to GoSam} \label{sec:gosam_me} One of the supported methods for automated matrix elements from external providers is for the \gosam\ package. This program package which is a combination of \python\ scripts and \fortran\ libraries, allows both for tree and one-loop matrix elements (which is leading or next-to-leading order, depending on whether the corresponding process is allowed at the tree level or not). In principle, the advanced version of \gosam\ also allows for the evaluation of two-loop virtual matrix elements, however, this is currently not supported in \whizard. This method is invoked via the command \begin{code} $method = "gosam" \end{code} Of course, this will only work correctly of \gosam\ with all its subcomponents has been correctly found during configuration of \whizard\ and then subsequently correctly linked. In order to generate the tables for spin, flavor and color states for the corresponding process, first \oMega\ is called to provide \fortran\ code for the interfaces to all the metadata for the process(es) to be evaluated. Next, the \gosam\ \python\ script is automatically invoked that first checks for the necessary ingredients to produce, compile and link the \gosam\ matrix elements. These are the the \ttt{Qgraf} topology generator for the diagrams, \ttt{Form} to perform algebra, the \ttt{Samurai}, \ttt{AVHLoop}, \ttt{QCDLoop} and \ttt{Ninja} libraries for Passarino-Veltman reduction, one-loop tensor integrals etc. As a next step, \gosam\ automatically writes and executes a \ttt{configure} script, and then it exchanges the Binoth Les Houches accord (BLHA) contract files between \whizard\ and itself~\cite{Binoth:2010xt,Alioli:2013nda} to check whether it actually generate code for the demanded process at the given order. Note that the contract and answer files do not have to be written by the user by hand, but are generated automatically within the program work flow initiated by the original \sindarin\ script. \gosam\ then generates \fortran\ code for the different components of the processes, compiles it and links it into a library, which is then automatically accessible (as an external process library) from inside \whizard. The phase space setup and the integration as well as the LO (and NLO) event generation work then in exactly the same way as for \oMega\ matrix elements. As an NLO calculation consists of different components for the Born, the real correction, the virtual correction, the subtraction part and possible further components depending on the details of the calculation, there is the possible to separately choose the matrix element method for those components via the keywords \ttt{\$loop\_me\_method}, \ttt{\$real\_tree\_me\_method}, \ttt{\$correlation\_me\_method} etc. These keywords overwrite the master switch of the \ttt{\$method} keyword. For more information on the switches and details of the functionality of \gosam, cf. \url{http://gosam.hepforge.org}. %%%%% \section{Interface to Openloops} \label{sec:openloops_me} Very similar to the case of \gosam, cf. Sec.~\ref{sec:gosam_me}, is the case for \openloops\ matrix elements. Also here, first \oMega\ is called in order to provide an interface for the spin, flavor and color degrees of freedom for the corresponding process. Information exchange between \whizard\ and \openloops\ then works in the same automatic way as for \gosam\ via the BLHA interface. This matrix element method is invoked via \begin{code} $method = "openloops" \end{code} This again is the master switch that will tell \whizard\ to use \openloops\ for all components, while there are special keywords to tailor-make the setup for the different components of an NLO calculation (cf. Sec.~\ref{sec:gosam_me}. The main difference between \openloops\ and \gosam\ is that for \openloops\ there is no process code to be generated, compiled and linked for a process, but a precompiled library is called and linked, e.g. \ttt{ppllj} for the Drell-Yan process. Of course, this library has to be installed on the system, but if that is not the case, the user can execute the \openloops\ script in the source directory of \openloops\ to download, compile and link the corresponding dynamic library. This limits (for the moment) the usage of \openloops\ to processes where pre-existint libraries for that specific processes have been generated by the \openloops\ authors. A new improved generator for general process libraries for \openloops\ will get rid of that restriction. For more information on the installation, switches and details of the functionality of \openloops, cf. \url{http://openloops.hepforge.org}. %%%%% \section{Interface to Recola} \label{sec:recola_me} The third one-loop provider (OLP) for external matrix elements that is supported by \whizard, is \recola. In contrast to \gosam, cf. Sec.~\ref{sec:gosam_me}, and \openloops, cf. Sec.~\ref{sec:openloops_me}, \recola\ does not use a BLHA interface to exchange information with \whizard, but its own tailor-made C interoperable library interface to communicate to the Monte Carlo side. \recola\ matrix elements are called for via \begin{code} $method = "recola" \end{code} \recola\ uses a highly efficient algorithm to generate process code for LO and NLO SM amplitudes in a fully recursive manner. At the moment, the setup of the interface within \whizard\ does not allow to invoke more than one different process in \recola: this would lead to a repeated initialization of the main setup of \recola\ and would consequently crash it. It is foreseen in the future to have a safeguard mechanism inside \whizard\ in order to guarantee initialization of \recola\ only once, but this is not yet implemented. Further information on the installation, details and parameters of \recola\ can be found at \url{http://recola.hepforge.org}. %%%%% \section{Special applications} \label{sec:special_me} There are also special applications with combinations of matrix elements from different sources for dedicated purposes like e.g. for the matched top--anti-top threshold in $e^+e^-$. For this special application which depending on the order of the matching takes only \oMega\ matrix elements or at NLO combines amplitudes from \oMega\ and \openloops, is invoked by the method: \begin{code} $method = "threshold" \end{code} \newpage %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Implemented physics} \label{chap:physics} %%%%% \section{The hard interaction models} In this section, we give a brief overview over the different incarnations of models for the description of the realm of subatomic particles and their interactions inside \whizard. In Sec.~\ref{sec:smandfriends}, the Standard Model (SM) itself and straightforward extensions and modifications thereof in the gauge, fermionic and Higgs sector are described. Then, Sec.~\ref{sec:bsmmodels} gives a list and short description of all genuine beyond the SM models (BSM) that are currently implemented in \whizard\ and its matrix element generator \oMega. Additional models beyond that can be integrated and handled via the interfaces to external tools like \sarah\ and \FeynRules, or the universal model format \UFO, cf. Chap.~\ref{chap:extmodels}. %%%%%%%%%%%%%%% \subsection{The Standard Model and friends} \label{sec:smandfriends} %%%% \subsection{Beyond the Standard Model} \label{sec:bsmmodels} \begin{table} \begin{center} \begin{tabular}{|l|l|l|} \hline MODEL TYPE & with CKM matrix & trivial CKM \\ \hline\hline Yukawa test model & \tt{---} & \tt{Test} \\ \hline QED with $e,\mu,\tau,\gamma$ & \tt{---} & \tt{QED} \\ QCD with $d,u,s,c,b,t,g$ & \tt{---} & \tt{QCD} \\ Standard Model & \tt{SM\_CKM} & \tt{SM} \\ SM with anomalous gauge couplings & \tt{SM\_ac\_CKM} & \tt{SM\_ac} \\ SM with $Hgg$, $H\gamma\gamma$, $H\mu\mu$, $He^+e^-$ & \tt{SM\_Higgs\_CKM} & \tt{SM\_Higgs} \\ SM with bosonic dim-6 operators & \tt{---} & \tt{SM\_dim6} \\ SM with charge 4/3 top & \tt{---} & \tt{SM\_top} \\ SM with anomalous top couplings & \tt{---} & \tt{SM\_top\_anom} \\ SM with anomalous Higgs couplings & \tt{---} & \tt{SM\_rx}/\tt{NoH\_rx}/\tt{SM\_ul} \\\hline SM extensions for $VV$ scattering & \tt{---} & \tt{SSC}/\tt{AltH}/\tt{SSC\_2}/\tt{SSC\_AltT} \\\hline SM with $Z'$ & \tt{---} & \tt{Zprime} \\ \hline Two-Higgs Doublet Model & \tt{THDM\_CKM} & \tt{THDM} \\ \hline\hline MSSM & \tt{MSSM\_CKM} & \tt{MSSM} \\ \hline MSSM with gravitinos & \tt{---} & \tt{MSSM\_Grav} \\ \hline NMSSM & \tt{NMSSM\_CKM} & \tt{NMSSM} \\ \hline extended SUSY models & \tt{---} & \tt{PSSSM} \\ \hline\hline Littlest Higgs & \tt{---} & \tt{Littlest} \\ \hline Littlest Higgs with ungauged $U(1)$ & \tt{---} & \tt{Littlest\_Eta} \\ \hline Littlest Higgs with $T$ parity & \tt{---} & \tt{Littlest\_Tpar} \\ \hline Simplest Little Higgs (anomaly-free) & \tt{---} & \tt{Simplest} \\ \hline Simplest Little Higgs (universal) & \tt{---} & \tt{Simplest\_univ} \\ \hline\hline SM with graviton & \tt{---} & \tt{Xdim} \\ \hline UED & \tt{---} & \tt{UED} \\ \hline ``SQED'' with gravitino & \tt{---} & \tt{GravTest} \\ \hline Augmentable SM template & \tt{---} & \tt{Template} \\ \hline \end{tabular} \end{center} \caption{\label{tab:models} List of models available in \whizard. There are pure test models or models implemented for theoretical investigations, a long list of SM variants as well as a large number of BSM models.} \end{table} \subsubsection{Strongly Interacting Models and Composite Models} Higgsless models have been studied extensively before the Higgs boson discovery at the LHC Run I in 2012 in order to detect possible loopholes in the electroweak Higgs sector discovery potential of this collider. The Threesite Higgsless Model is one of the simplest incarnations of these models, and was one of the first BSM models beyond SUSY and Little Higgs models that have been implemented in \whizard~\cite{Speckner:2010zi}. It is also called the Minimal Higgsless Model (MHM)~\cite{Chivukula:2006cg} is a minimal deconstructed Higgsless model which contains only the first resonance in the tower of Kaluza-Klein modes of a Higgsless extra-dimensional model. It is a non-renormalizable, effective theory whose gauge group is an extension of the SM with an extra $SU(2)$ gauge group. The breaking of the extended electroweak gauge symmetry is accomplished by a set of nonlinear sigma fields which represent the effects of physics at a higher scale and make the theory nonrenormalizable. The physical vector boson spectrum contains the usual photon, $W^\pm$ and $Z$ bosons as well as a $W'^\pm$ and $Z'$ boson. Additionally, a new set of heavy fermions are introduced to accompany the new gauge group ``site'' which mix to form the physical eigenstates. This mixing is controlled by the small mixing parameter $\epsilon_L$ which is adjusted to satisfy constraints from precision observables, such as the S parameter~\cite{Chivukula:2005xm}. Here, additional weak gauge boson production at the LHC was one of the focus of the studies with \whizard~\cite{Ohl:2008ri}. \subsubsection{Supersymmetric Models} \whizard/\oMega\ was the first multi-leg matrix-element/event generator to include the full Minimal Supersymmetric Standard Model (MSSM), and also the NMSSM. The SUSY implementations in \whizard\ have been extensively tested~\cite{Ohl:2002jp,Reuter:2009ex}, and have been used for many theoretical and experimental studies (some prime examples being~\cite{Kalinowski:2008fk,Robens:2008sa,Hagiwara:2005wg}. \subsubsection{Little Higgs Models} \subsubsection{Inofficial models} There have been several models that have been included within the \whizard/\oMega\ framework but never found their way into the official release series. One famous example is the non-commutative extension of the SM, the NCSM. There have been several studies, e.g. simulations on the $s$-channel production of a $Z$ boson at the photon collider option of the ILC~\cite{Ohl:2004tn}. Also, the production of electroweak gauge bosons at the LHC in the framework of the NCSM have been studied~\cite{Ohl:2010zf}. %%%%%%%%%%%%%%% \section{The SUSY Les Houches Accord (SLHA) interface} \label{sec:slha} To be filled in ...~\cite{Skands:2003cj,AguilarSaavedra:2005pw,Allanach:2008qq}. The neutralino sector deserves special attention. After diagonalization of the mass matrix expresssed in terms of the gaugino and higgsino eigenstates, the resulting mass eigenvalues may be either negative or positive. In this case, two procedures can be followed. Either the masses are rendered positive and the associated mixing matrix gets purely imaginary entries or the masses are kept signed, the mixing matrix in this case being real. According to the SLHA agreement, the second option is adopted. For a specific eigenvalue, the phase is absorbed into the definition of the relevant eigenvector, rendering the mass negative. However, \whizard\ has not yet officially tested for negative masses. For external SUSY models (cf.~Chap.~\ref{chap:extmodels}) this means, that one must be careful using a SLHA file with explicit factors of the complex unity in the mixing matrix, and on the other hand, real and positive masses for the neutralinos. For the hard-coded SUSY models, this is completely handled internally. Especially Ref.~\cite{Hagiwara:2005wg} discusses the details of the neutralino (and chargino) mixing matrix. %%%%%%%%%%%%%%%% \section{Lepton Collider Beam Spectra} \label{sec:beamspectra} For the simulation of lepton collider beam spectra there are two dedicated tools, \circeone\ and \circetwo\ that have been written as in principle independent tools. Both attempt to describe the details of electron (and positron) beams in a realistic lepton collider environment. Due to the quest for achieving high peak luminosities at $e^+e^-$ machines, the goal is to make the spatial extension of the beam as small as possible but keeping the area of the beam roughly constant. This is achieved by forcing the beams in the final focus into the shape of a quasi-2D bunch. Due to the high charge density in that bunch, the bunch electron distribution is modified by classical electromagnetic radiation, so called {\em beamstrahlung}. The two \circe\ packages are intended to perform a simulation of this beamstrahlung and its consequences on the electron beam spectrum as realistic as possible. More details about the two packages can be found in their stand-alone documentations. We will discuss the basic features of lepton-collider beam simulations in the next two sections, including the technicalities of passing simulations of the machine beam setup to \whizard. This will be followed by a section on the simulation of photon collider spectra, included for historical reasons. %%%%% \subsection{\circeone} While the bunches in a linear collider cross only once, due to their small size they experience a strong beam-beam effect. There is a code to simulate the impact of this effect on luminosity and background, called \ttt{GuineaPig++}~\cite{Schulte:1998au,Schulte:1999tx,Schulte:2007zz}. This takes into account the details of the accelerator, the final focus etc. on the structure of the beam and the main features of the resulting energy spectrum of the electrons and positrons. It offers the state-of-the-art simulation of lepton-collider beam spectra as close as possible to reality. However, for many high-luminosity simulations, event files produced with \ttt{GuineaPig++} are usually too small, in the sense that not enough independent events are available for physics simulations. Lepton collider beam spectra do peak at the nominal beam energy ($\sqrt{s}/2$) of the collider, and feature very steeply falling tails. Such steeply falling distributions are very poorly mapped by histogrammed distributions with fixed bin widths. The main working assumption to handle such spectra are being followed within \circeone: \begin{enumerate} \label{circe1_assumptions} \item The beam spectra for the two beams $P_1$ and $P_2$ factorize (here $x_1$ and $x_2$ are the energy fractions of the two beams, respectively): \begin{equation*} D_{P_1P_2} (x_1, x_2) = D_{P_1} (x_1) \cdot D_{P_2} (x_2) \end{equation*} \item The peak is described with a delta distribution, and the tail with a power law: \begin{equation*} D(x) = d \cdot \delta(1-x) \; + \; c \cdot x^\alpha \, (1-x)^\beta \end{equation*} \end{enumerate} The two powers $\alpha$ and $\beta$ are the main coefficients that can be tuned in order to describe the spectrum with \circeone\ as close as possible as the original \ttt{GuineaPig++} spectrum. More details about how \circeone\ works and what it does can be found in its own write-up in \ttt{circe1/share/doc}. \subsection{\circetwo} The two conditions listed in \ref{circe1_assumptions} are too restrictive and hence insufficient to describe more complicated lepton-collider beam spectra, as they e.g. occur in the CLIC drive-beam design. Here, the two beams are highly correlated and also a power-law description does not give good enough precision for the tails. To deal with these problems, \circetwo\ starts with a two-dimensional histogram featuring factorized, but variable bin widths in order to simulate the steep parts of the distributions. The limited statistics from too small \ttt{GuineaPig++} event output files leads to correlated fluctuations that would leave strange artifacts in the distributions. To abandon them, Gaussian filters are applied to smooth out the correlated fluctuations. Here care has to be taken when going from the continuum in $x$ momentum fraction space to the corresponding \begin{figure} \centering \includegraphics{circe2-smoothing} \caption{\label{fig:circe2-smoothing} Smoothing the bin at the $x_{e^+} = 1$ boundary with Gaussian filters of 3 and 10 bins width compared to no smoothing.} \end{figure} boundaries: separate smoothing procedures are being applied to the bins in the continuum region and those in the boundary in order to avoid artificial unphysical beam energy spreads. Fig.~\ref{fig:circe2-smoothing} shows the smoothing of the distribution for the bin at the $x_{e^+} = 1$ boundary. The blue dots show the direct \ttt{GuineaPig++} output comprising the fluctuations due to the low statistics. Gaussian filters with widths of 3 and 10 bins, respectively, have been applied (orange and green dots, resp.). While there is still considerable fluctuation for 3 bin width Gaussian filtering, the distribution is perfectly smooth for 10 bin width. Hence, five bin widths seem a reasonable compromise for histograms with a total of 100 bins. Note that the bins are not equidistant, but shrink with a power law towards the $x_{e^-} = 1$ boundary on the right hand side of Fig.~\ref{fig:circe2-smoothing}. \whizard\ ships (inside its subpackage \circetwo) with prepared beam spectra ready to be used within \circetwo\ for the ILC beam spectra used in the ILC TDR~\cite{Behnke:2013xla,Baer:2013cma,Adolphsen:2013jya,Adolphsen:2013kya,Behnke:2013lya}. These comprise the designed staging energies of 200 GeV, 230 GeV, 250 GeV, 350 GeV, and 500 GeV. Note that all of these spectra up to now do not take polarization of the original beams on the beamstrahlung into account, but are polarization-averaged. For backwards compatibility, also the 500 GeV spectra for the TESLA design~\cite{AguilarSaavedra:2001rg,Richard:2001qm}, here both for polarized and polarization-averaged cases, are included. Correlated spectra for CLIC staging energies like 350 GeV, 1400 GeV and 3000 GeV are not yet (as of version 2.2.4) included in the \whizard\ distribution. In the following we describe how to obtain such files with the tools included in \whizard (resp. \circetwo). The procedure is equivalent to the so-called \ttt{lumi-linker} construction used by Timothy Barklow (SLAC) together with the legacy version \whizard\ttt{ 1.95}. The workflow to produce such files is to run \ttt{GuineaPig++} with the following input parameters: \begin{Code} do_lumi = 7; num_lumi = 100000000; num_lumi_eg = 100000000; num_lumi_gg = 100000000; \end{Code} This demands from \ttt{GuineaPig++} the generation of distributions for the $e^-e^+$, $e^\mp \gamma$, and $\gamma\gamma$ components of the beamstrahlung's spectrum, respectively. These are the files \ttt{lumi.ee.out}, \ttt{lumi.eg.out}, \ttt{lumi.ge.out}, and \ttt{lumi.gg.out}, respectively. These contain pairs $(E_1, E_2)$ of beam energies, {\em not} fractions of the original beam energy. Huge event numbers are out in here, as \ttt{GuineaPig++} will produce only a small fraction due to a very low generation efficiency. The next step is to transfer these output files from \ttt{GuineaPig++} into input files used with \circetwo. This is done by means of the tool \ttt{circe\_tool.opt} that is installed together with the \whizard\ main binary and libraries. The user should run this executable with the following input file: \begin{Code} { file="ilc500/ilc500.circe" # to be loaded by WHIZARD { design="ILC" roots=500 bins=100 scale=250 # E in [0,1] { pid/1=electron pid/2=positron pol=0 # unpolarized e-/e+ events="ilc500/lumi.ee.out" columns=2 # <= Guinea-Pig lumi = 1564.763360 # <= Guinea-Pig iterations = 10 # adapting bins smooth = 5 [0,1) [0,1) # Gaussian filter 5 bins smooth = 5 [1] [0,1) smooth = 5 [0,1) [1] } } } \end{Code} The first line defines the output file, that later can be read in into the beamstrahlung's description of \whizard\ (cf. below). Then, in the second line the design of the collider (here: ILC for 500 GeV center-of-mass energy, with the number of bins) is specified. The next line tells the tool to take the unpolarized case, then the \ttt{GuineaPig++} parameters (event file and luminosity) are set. In the last three lines, details concerning the adaptation of the simulation as well as the smoothing procedure are being specified: the number of iterations in the adaptation procedure, and for the smoothing with the Gaussian filter first in the continuum and then at the two edges of the spectrum. For more details confer the documentation in the \circetwo\ subpackage. This produces the corresponding input files that can be used within \whizard\ to describe beamstrahlung for lepton colliders, using a \sindarin\ input file like: \begin{Code} beams = e1, E1 => circe2 $circe2_file = "ilc500.circe" $circe2_design = "ILC" ?circe2_polarized = false \end{Code} %%%%% \subsection{Photon Collider Spectra} For details confer the complete write-up of the \circetwo\ subpackage. %%%%% \section{Transverse momentum for ISR photons} \label{sec:isr-photon-handler} The structure functions that describe the splitting of a beam particle into a particle pair, of which one enters the hard interaction and the other one is radiated, are defined and evaluated in the strict collinear approximation. In particular, this holds for the ISR structure function which describes the radiation of photons off a charged particle in the initial state. The ISR structure function that is used by \whizard\ is understood to be inclusive, i.e., it implicitly contains an integration over transverse momentum. This approach is to be used for computing a total cross section via \ttt{integrate}. In \whizard, it is possible to unfold this integration, as a transformation that is applied by \ttt{simulate} step, event by event. The resulting modified events will show a proper logarithmic momentum-transfer ($Q^2$) distribution for the radiated photons. The recoil is applied to the hard-interaction system, such that four-momentum and $\sqrt{\hat s}$ are conserved. The distribution is cut off by $Q_{\text{max}}^2$ (cf. \ttt{isr\_q\_max}) for large momentum transfer, and smoothly by the parton mass (cf.\ \ttt{isr\_mass}) for small momentum transfer. To activate this modification, set \begin{Code} ?isr_handler = true $isr_handler_mode = "recoil" \end{Code} before, or as an option to, the \ttt{simulate} command. Limitations: the current implementation of the $p_T$ modification works only for the symmetric double-ISR case, i.e., both beams have to be charged particles with identical mass (e.g., $e^+e^-$). The mode \ttt{recoil} generates exactly one photon per beam, i.e., it modifies the momentum of the single collinear photon that the ISR structure function implementation produces, for each beam. (It is foreseen that further modes or options will allow to generate multiple photons. Alternatively, the \pythia\ shower can be used to simulate multiple photons radiated from the initial state.) %%%%% \section{Transverse momentum for the EPA approximation} \label{sec:epa-beam-handler} For the equivalent-photon approximation (EPA), which is also defined in the collinear limit, recoil momentum can be inserted into generated events in an entirely analogous way. The appropriate settings are \begin{Code} ?epa_handler = true $epa_handler_mode = "recoil" \end{Code} Limitations: as for ISR, the current implementation of the $p_T$ modification works only for the symmetric double-EPA case. Both incoming particles of the hard process must be photons, while both beams must be charged particles with identical mass (e.g., $e^+e^-$). Furthermore, the current implementation does not respect the kinematical limit parameter \verb|epa_q_min|, it has to be set to zero. In effect, the lower $Q^2$ cutoff is determined by the beam-particle mass \verb|epa_mass|, and the upper cutoff is either given by $Q_{\text{max}}$ (the parameter \verb|epa_q_max|), or by the limit $\sqrt{s}$ if this is not set. It is possible to combine the ISR and EPA handlers, for processes where ISR is active for one of the beams, EPA for the other beam. For this scenario to work, both handler switches must be on, and both mode strings must coincide. The parameters are set separately for ISR and EPA, as described above. %%%%% \section{Resonances and continuum} \subsection{Complete matrix elements} Many elementary physical processes are composed of contributions that can be qualified as (multiply) \emph{resonant} or \emph{continuum}. For instance, the amplitude for the process $e^+e^-\to q\bar q q\bar q$, evaluated at tree level in perturbation theory, contains Feynman diagrams with zero, one, or two $W$ and $Z$ bosons as virtual lines. If the kinematical constraints allow this, two vector bosons can become simultaneously on-shell in part of phase space. To a first approximation, this situation is understood as $W^+W^-$ or $ZZ$ production with subsequent decay. The kinematical distributions show distinct resonances in the quark-pair spectra. Other graphs contain only one s-channel $W/Z$ boson, or none at all, such as graphs with $q\bar q$ production and subsequent gluon radiation, splitting into another $q\bar q$ pair. A \whizard\ declaration of the form \begin{Code} process q4 = e1, E1 => u, U, d, D \end{Code} produces the full set of graphs for the selected final state, which after squaring and integrating yields the exact tree-level result for the process. The result contains all doubly and singly resonant parts, with correct resonance shapes, as well as the continuum contribution and all interference. This is, to given order in perturbation theory, the best possible approximation to the true result. \subsection{Processes restricted to resonances} For an intuitive separation of a two-boson ``signal'' contribution, it is possible to restrict the set of graphs to a certain intermediate state. For instance, the declaration \begin{Code} process q4_zz = e1, E1 => u, U, d, D { $restrictions = "3+4~Z && 5+6~Z" } \end{Code} generates an amplitude that contains only those Feynman graphs where the specified quarks are connected to a $Z$ virtual line. The result may be understood as $ZZ$ production with subsequent decay, where the $Z$ resonances exhibit a Breit-Wigner shape. Combining this with the analogous $W^+W^-$ restricted process, the user can generate ``signal'' processes. Adding both ``signal'' cross sections $WW$ and $ZZ$ will result in a reasonable approximation to the exact tree-level cross section. The amplitude misses the single-resonant and continuum contributions, and the squared amplitude misses the interference terms, however. More importantly, the restricted processes as such are not gauge-invariant (with respect to the electroweak gauge group), and they are no longer dominant away from resonant kinematics. We therefore strongly recommend that such restricted processes are always accompanied by a cut setup that restricts the kinematics to an approximately on-shell pattern for both resonances. For instance: \begin{Code} cuts = all 85 GeV < M < 95 GeV [u:U] and all 85 GeV < M < 95 GeV [d:D] \end{Code} In this region, the gauge-dependent and continuum contributions are strictly subdominant. Away from the resonance(s), the results for a restricted process are meaningless, and the full process has to be computed instead. \subsection{Factorized processes} Another method for obtaining the signal contribution is a proper factorization into resonance production and decay. We would have to generate a production process and two decay processes: \begin{Code} process z_uu = Z => u, U process z_dd = Z => d, D process zz = e1, E1 => Z, Z \end{Code} All three processes must be integrated. The integration results are partial decay widths and the $ZZ$ production cross section, respectively. (Note that cut expressions in \sindarin\ apply to all integrations, so make sure that no production-process cuts are active when integrating the decay processes.) During a later event-generation step, the $Z$ decays can then be activated by declaring the $Z$ as unstable, \begin{Code} unstable Z (z_uu, z_dd) \end{Code} and then simulating the production process \begin{Code} simulate (zz) \end{Code} The generated events will consist of four-fermion final states, including all combinations of both decay modes. It is important to note that in this setup, the invariant $u\bar u$ and $d\bar d$ masses will be always \emph{exactly} equal to the $Z$ mass. There is no Breit-Wigner shape involved. However, in this approximation the results are gauge-invariant, as there is no off-shell contribution involved. For further details on factorized processes and spin correlations, cf.\ Sec.~\ref{sec:spin-correlations}. \subsection{Resonance insertion in the event record} From the above discussion, we may conclude that it is always preferable to compute the complete process for a given final state, as long as this is computationally feasible. However, in the simulation step this approach also has a drawback. Namely, if a parton-shower module (see below) is switched on, the parton-shower algorithm relies on event details in order to determine the radiation pattern of gluons and further splitting. In the generated event records, the full-process events carry the signature of non-resonant continuum production with no intermediate resonances. The parton shower will thus start the evolution at the process energy scale, the total available energy. By contrast, for an electroweak production and decay process, the evolution should start only at the vector boson mass, $m_Z$. In effect, even though the resonant contribution of $WW$ and $ZZ$ constitutes the bulk of the cross section, the radiation pattern follows the dynamics of four-quark continuum production. In general, the number of radiated hadrons will be too high. \begin{figure} \begin{center} \includegraphics[width=.41\textwidth]{resonance_e_gam} \includegraphics[width=.41\textwidth]{resonance_n_charged} \\ \includegraphics[width=.41\textwidth]{resonance_n_hadron} \includegraphics[width=.41\textwidth]{resonance_n_particles} \\ \includegraphics[width=.41\textwidth]{resonance_n_photons} \includegraphics[width=.41\textwidth]{resonance_n_visible} \end{center} \caption{The process $e^+e^- \to jjjj$ at 250 GeV center-of-mass energy is compared transferring the partonic events naively to the parton shower, i.e. without respecting any intermediate resonances (red lines). The blue lines show the process factorized into $WW$ production and decay, where the shower knows the origin of the two jet pairs. The orange and dark green lines show the resonance treatment as mentioned in the text, with \ttt{resonance\_on\_shell\_limit = 1} and \ttt{= 4}, respectively. \pythiasix\ parton shower and hadronization with the OPAL tune have been used. The observables are: photon energy distribution and number of charged tracks (upper line left/right, number of hadrons and total number of particles (middle left/right), and number of photons and neutral particles (lower line left/right).} \end{figure} To overcome this problem, there is a refinement of the process description available in \whizard. By modifying the process declaration to \begin{Code} ?resonance_history = true resonance_on_shell_limit = 4 process q4 = e1, E1 => u, U, d, D \end{Code} we advise the program to produce not just the complete matrix element, but also all possible restricted matrix elements containing resonant intermediate states. This has no effect at all on the integration step, and thus on the total cross section. However, when subsequently events are generated with this setting, the program checks, for each event, the kinematics and determines the set of potentially resonant contributions. The criterion is whether the off-shellness of a particular would-be resonance is less than the resonance width multiplied by the value of \verb|resonance_on_shell_limit| (default value $=4$). For the set of resonance histories which pass this criterion (which can be empty), their respective squared matrix element is related to the full-process matrix element. The ratio is interpreted as a probability. The random-number generator then selects one or none of the resonance histories, and modifies the event record accordingly. In effect, for an appropriate fraction of the events, depending on the kinematics, the parton-shower module is provided with resonance information, so it can adjust the radiation pattern accordingly. It has to be mentioned that generating the matrix-element code for all possible resonance histories takes additional computing resources. In the current default setup, this feature is switched off. It has to be explicitly activated via the \verb|?resonance_history| flag. Also, the feature can be activated or deactivated individually for each process, such as in \begin{Code} ?resonance_history = true process q4_with_res = e1, E1 => u, U, d, D { ?resonance_history = true } process q4_wo_res = e1, E1 => u, U, d, D { ?resonance_history = false } \end{Code} If the flag is \verb|false| for a process, no resonance code will be generated. Similarly, the flag has to be globally or locally active when \verb|simulate| is called, such that the feature takes effect for event generation. There are two additional parameters that can fine-tune the conditions for resonance insertion in the event record. Firstly, the parameter \verb|resonance_on_shell_turnoff|, if nonzero, enables a Gaussian suppression of the probability for resonance insertion. For instance, setting \begin{Code} ?resonance_history = true resonance_on_shell_turnoff = 4 resonance_on_shell_limit = 8 \end{Code} will reduce the probability for the event to be qualified as resonant by $e^{-1}= 37\,\%$ if the kinematics is off-shell by four units of the width, and by $e^{-4}=2\,\%$ at eight units of the width. Beyond this point, the setting of the \verb|resonance_on_shell_limit| parameter eliminates resonance insertion altogether. In effect, the resonance-background transition is realized in a smooth way. Secondly, within the resonant-kinematics range the probability for qualifying the event as background can be reduced by the parameter \verb|resonance_background_factor| (default value $=1$) to a number between zero and one. Setting this to zero means that the event will be necessarily qualified as resonant, if it falls within the resonant-kinematics range. Note that if an event, by the above mechanism, is identified as following a certain resonance history, the assigned color flow will be chosen to match the resonance history, not the complete matrix element. This may result in a reassignment of color flow with respect to the original partonic event. Finally, we mention the order of execution: any additional matrix element code is compiled and linked when \verb|compile| is executed for the processes in question. If this command is omitted, the \verb|simulate| command will trigger compilation. \section{Parton showers and Hadronization} In order to produce sensible events, final state QCD (and also QED) radiation has to be considered as well as the binding of strongly interacting partons into mesons and baryons. Furthermore, final state hadronic resonances undergo subsequent decays into those particles showing up in (or traversing) the detector. The latter are mostly pions, kaons, photons, electrons and muons. The physics associated with these topics can be divided into the perturbative part which is the regime of the parton shower, and the non-perturbative part which is the regime for the hadronization. \whizard\ comes with its own two different parton shower implementations, an analytic and a so-called $k_T$-ordered parton shower that will be detailed in the next section. Note that in general it is not advisable to use different shower and hadronization methods, or in other words, when using shower and hadronization methods from different programs these would have to be tuned together again with the corresponding data. Parton showers are approximations to full matrix elements taking only the leading color flow into account, and neglecting all interferences between different amplitudes leading to the same exclusive final state. They rely on the QCD (and QED) splitting functions to describe the emissions of partons off other partons. This is encoded in the so-called Sudakov form factor~\cite{Sudakov:1954sw}: \begin{equation*} \Delta( t_1, t_2) = \exp \left[ \int\limits_{t_1}^{t_2} \mbox{d} t \int\limits_{z_-}^{z_+} \mbox{d} z \frac{\alpha_s}{2 \pi t} P(z) \right] \end{equation*} This gives the probability for a parton to evolve from scale $t_2$ to $t_1$ without any further emissions of partons. $t$ is the evolution parameter of the shower, which can be a parton energy, an emission angle, a virtuality, a transverse momentum etc. The variable $z$ relates the two partons after the branching, with the most common choice being the ratio of energies of the parton after and before the branching. For final-state radiation brachings occur after the hard interaction, the evolution of the shower starts at the scale of the hard interaction, $t \sim \hat{s}$, down to a cut-off scale $t = t_{\text{cut}}$ that marks the transition to the non-perturbative regime of hadronization. In the space-like evolution for the initial-state shower, the evolution is from a cut-off representing the factorization scale for the parton distribution functions (PDFs) to the inverse of the hard process scale, $-\hat{s}$. Technically, this evolution is then backwards in (shower) time~\cite{Sjostrand:1985xi}, leading to the necessity to include the PDFs in the Sudakov factors. The main switches for the shower and hadronization which are realized as transformations on the partonic events within \whizard\ are \ttt{?allow\_shower} and \ttt{?allow\_hadronization}, which are true by default and only there for technical reasons. Next, different shower and hadronization methods can be chosen within \whizard: \begin{code} $shower_method = "WHIZARD" $hadronization_method = "PYTHIA6" \end{code} The snippet above shows the default choices in \whizard\, namely \whizard's intrinsic parton shower, but \pythiasix\ as hadronization tool. (Note that \whizard\ does not have its own hadronization module yet.) The usage of \pythiasix\ for showering and hadronization will be explained in Sec.~\ref{sec:pythia6}, while the two different implementations of the \whizard\ homebrew parton showers are discussed in Sec.~\ref{sec:ktordered} and~\ref{sec:analytic}, respectively. %%%%% \subsection{The $k_T$-ordered parton shower} \label{sec:ktordered} %%%%% \subsection{The analytic parton shower} \label{sec:analytic} %%%%% \subsection{Parton shower and hadronization from \pythiasix} \label{sec:pythia6} Development of the \pythiasix\ generator for parton shower and hadronization (the \fortran\ version) has been discontinued by the authors several years ago. Hence, the final release of that program is frozen. This allowed to ship this final version, v6.427, with the \whizard\ distribution without the need of updating it all the time. One of the main reasons for that inclusion -- besides having the standard tool for showering and hadronization for decays at hand -- is to allow for backwards validation within \whizard\ particularly for the event samples generated for the development of linear collider physics: first for TESLA, JLC and NLC, and later on for the Conceptual and Technical Design Report for ILC, for the Conceptual Design Report for CLIC as well as for the Letters of Intent for the LC detectors, ILD and SiD. Usually, an external parton shower and hadronization program (PS) is steered via the transfer of event files that are given to the PS via LHE events, while the PS program then produces hadron level events, usually in HepMC format. These can then be directed towards a full or fast detector simulation program. As \pythiasix\ has been completely integrated inside the \whizard\ framework, the showered or more general hadron level events can be returned to and kept inside \whizard's internal event record, and hence be used in \whizard's internal event analysis. In that way, the events can be also written out in event formats that are not supported by \pythiasix, e.g. \ttt{LCIO} via the output capabilities of \whizard. There are several switches to directly steer \pythiasix\ (the values in brackets correspond to the \pythiasix\ variables): \begin{code} ps_mass_cutoff = 1 GeV [PARJ(82)] ps_fsr_lambda = 0.29 GeV [PARP(72)] ps_isr_lambda = 0.29 GeV [PARP(61)] ps_max_n_flavors = 5 [MSTJ(45)] ?ps_isr_alphas_running = true [MSTP(64)] ?ps_fsr_alphas_running = true [MSTJ(44)] ps_fixed_alphas = 0.2 [PARU(111)] ?ps_isr_angular_ordered = true [MSTP(62)] ps_isr_primordial_kt_width = 1.5 GeV [PARP(91)] ps_isr_primordial_kt_cutoff = 5.0 GeV [PARP(93)] ps_isr_z_cutoff = 0.999 [1-PARP(66)] ps_isr_minenergy = 2 GeV [PARP(65)] ?ps_isr_only_onshell_emitted_partons = true [MSTP(63)] \end{code} The values given above are the default values. The first value corresponds to the \pythiasix\ parameter \ttt{PARJ(82)}, its squared being the minimal virtuality that is allowed for the parton shower, i.e. the cross-over to the hadronization. The same parameter is used also for the \whizard\ showers. \ttt{ps\_fsr\_lambda} is the equivalent of \ttt{PARP(72)} and is the $\Lambda_{\text{QCD}}$ for the final state shower. The corresponding variable for the initial state shower is called \ttt{PARP(61)} in \pythiasix. By the next variable (\ttt{MSTJ(45)}), the maximal number of flavors produced in splittings in the shower is given, together with the number of active flavors in the running of $\alpha_s$. \ttt{?ps\_isr\_alphas\_running} which corresponds to \ttt{MSTP(64)} in \pythiasix\ determines whether or net a running $\alpha_s$ is taken in the space-like initial state showers. The same variable for the final state shower is \ttt{MSTJ(44)}. For fixed $\alpha_s$, the default value is given by \ttt{ps\_fixed\_alpha}, corresponding to \ttt{PARU(111)}. \ttt{MSTP(62)} determines whether the ISR shower is angular order, i.e. whether angles are increasing towards the hard interaction. This is per default true, and set in the variable \ttt{?ps\_isr\_angular\_ordered}. The width of the distribution for the primordial (intrinsic) $k_T$ distribution (which is a non-perturbative quantity) is the \pythiasix\ variable \ttt{PARP(91)}, while in \whizard\ it is given by \ttt{pythia\_isr\_primordial\_kt\_width}. The next variable (\ttt{PARP(93}) gives the upper cutoff for that distribution, which is 5 GeV per default. For splitting in space-like showers, there is a cutoff on the $z$ variable named \ttt{ps\_isr\_z\_cutoff} in \whizard. This corresponds to one minus the value of the \pythiasix\ parameter \ttt{PARP(66)}. \ttt{PARP(65)}, on the other hand, gives the minimal (effective) energy for a time-like or on-shell emitted parton on a space-like QCD shower, given by the \sindarin\ parameter \ttt{ps\_isr\_minenergy}. Whether or not partons emitted from space-like showers are allowed to be only on-shell is given by \ttt{?ps\_isr\_only\_onshell\_emitted\_partons}, \ttt{MSTP(63)} in \pythiasix\ language. For more details confer the \pythiasix\ manual~\cite{Sjostrand:2006za}. Any other non-standard \pythiasix\ parameter can be fed into the parton shower via the string variable \begin{code} $ps_PYTHIA_PYGIVE = "...." \end{code} Variables set here get preference over the ones set explicitly by dedicated \sindarin\ commands. For example, the OPAL tune for hadronic final states can be set via: \begin{code} $ps_PYTHIA_PYGIVE = "MSTJ(28)=0; PMAS(25,1)=120.; PMAS(25,2)=0.3605E-02; MSTJ(41)=2; MSTU(22)=2000; PARJ(21)=0.40000; PARJ(41)=0.11000; PARJ(42)=0.52000; PARJ(81)=0.25000; PARJ(82)=1.90000; MSTJ(11)=3; PARJ(54)=-0.03100; PARJ(55)=-0.00200; PARJ(1)=0.08500; PARJ(3)=0.45000; PARJ(4)=0.02500; PARJ(2)=0.31000; PARJ(11)=0.60000; PARJ(12)=0.40000; PARJ(13)=0.72000; PARJ(14)=0.43000; PARJ(15)=0.08000; PARJ(16)=0.08000; PARJ(17)=0.17000; MSTP(3)=1;MSTP(71)=1" \end{code} \vspace{0.5cm} A very common error that appears quite often when using \pythiasix\ for SUSY or any other model having a stable particle that serves as a possible Dark Matter candidate, is the following warning/error message: \begin{Code} Advisory warning type 3 given after 0 PYEXEC calls: (PYRESD:) Failed to decay particle 1000022 with mass 15.000 ****************************************************************************** ****************************************************************************** *** FATAL ERROR: Simulation: failed to generate valid event after 10000 tries ****************************************************************************** ****************************************************************************** \end{Code} In that case, \pythiasix\ gets a stable particle (here the lightest neutralino with the PDG code 1000022) handed over and does not know what to do with it. Particularly, it wants to treat it as a heavy resonance which should be decayed, but does not know how do that. After a certain number of tries (in the example abobe 10k), \whizard\ ends with a fatal error telling the user that the event transformation for the parton shower in the simulation has failed without producing a valid event. The solution to work around that problem is to let \pythiasix\ know that the neutralino (or any other DM candidate) is stable by means of \begin{code} $ps_PYTHIA_PYGIVE = "MDCY(C1000022,1)=0" \end{code} Here, 1000022 has to be replaced by the stable dark matter candidate or long-lived particle in the user's favorite model. Also note that with other options being passed to \pythiasix\, the \ttt{MDCY} option above has to be added to an existing \ttt{\$ps\_PYTHIA\_PYGIVE} command separated by a semicolon. %%%%% \subsection{Parton shower and hadronization from \pythiaeight} \subsection{Other tools for parton shower and hadronization} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{More on Event Generation} \label{chap:events} In order to perform a physics analysis with \whizard\ one has to generate events. This seems to be a trivial statement, but as there have been any questions like "My \whizard\ does not produce plots -- what has gone wrong?" we believe that repeating that rule is worthwile. Of course, it is not mandatory to use \whizard's own analysis set-up, the user can always choose to just generate events and use his/her own analysis package like \ttt{ROOT}, or \ttt{TopDrawer}, or you name it for the analysis. Accordingly, we first start to describe how to generate events and what options there are -- different event formats, renaming output files, using weighted or unweighted events with different normalizations. How to re-use and manipulate already generated event samples, how to limit the number of events per file, etc. etc. \section{Event generation} To explain how event generation works, we again take our favourite example, $e^+e^- \to \mu^+ \mu^-$, \begin{verbatim} process eemm = e1, E1 => e2, E2 \end{verbatim} The command to trigger generation of events is \ttt{simulate () \{ \}}, so in our case -- neglecting any options for now -- simply: \begin{verbatim} simulate (eemm) \end{verbatim} When you run this \sindarin\ file you will experience a fatal error: \ttt{FATAL ERROR: Colliding beams: sqrts is zero (please set sqrts)}. This is because \whizard\ needs to compile and integrate the process \ttt{eemm} first before event simulation, because it needs the information of the corresponding cross section, phase space parameterization and grids. It does both automatically, but you have to provide \whizard\ with the beam setup, or at least with the center-of-momentum energy. A corresponding \ttt{integrate} command like \begin{verbatim} sqrts = 500 GeV integrate (eemm) { iterations = 3:10000 } \end{verbatim} obviously has to appear {\em before} the corresponding \ttt{simulate} command (otherwise you would be punished by the same error message as before). Putting things in the correct order results in an output like: \begin{footnotesize} \begin{verbatim} | Reading model file '/usr/local/share/whizard/models/SM.mdl' | Preloaded model: SM | Process library 'default_lib': initialized | Preloaded library: default_lib | Reading commands from file 'bla.sin' | Process library 'default_lib': recorded process 'eemm' sqrts = 5.000000000000E+02 | Integrate: current process library needs compilation | Process library 'default_lib': compiling ... | Process library 'default_lib': keeping makefile | Process library 'default_lib': keeping driver | Process library 'default_lib': active | Process library 'default_lib': ... success. | Integrate: compilation done | RNG: Initializing TAO random-number generator | RNG: Setting seed for random-number generator to 29912 | Initializing integration for process eemm: | ------------------------------------------------------------------------ | Process [scattering]: 'eemm' | Library name = 'default_lib' | Process index = 1 | Process components: | 1: 'eemm_i1': e-, e+ => mu-, mu+ [omega] | ------------------------------------------------------------------------ | Beam structure: [any particles] | Beam data (collision): | e- (mass = 5.1099700E-04 GeV) | e+ (mass = 5.1099700E-04 GeV) | sqrts = 5.000000000000E+02 GeV | Phase space: generating configuration ... | Phase space: ... success. | Phase space: writing configuration file 'eemm_i1.phs' | Phase space: 2 channels, 2 dimensions | Phase space: found 2 channels, collected in 2 groves. | Phase space: Using 2 equivalences between channels. | Phase space: wood Warning: No cuts have been defined. | OpenMP: Using 8 threads | Starting integration for process 'eemm' | Integrate: iterations = 3:10000 | Integrator: 2 chains, 2 channels, 2 dimensions | Integrator: Using VAMP channel equivalences | Integrator: 10000 initial calls, 20 bins, stratified = T | Integrator: VAMP |=============================================================================| | It Calls Integral[fb] Error[fb] Err[%] Acc Eff[%] Chi2 N[It] | |=============================================================================| 1 9216 4.2833237E+02 7.14E-02 0.02 0.02* 40.29 2 9216 4.2829071E+02 7.08E-02 0.02 0.02* 40.29 3 9216 4.2838304E+02 7.04E-02 0.02 0.02* 40.29 |-----------------------------------------------------------------------------| 3 27648 4.2833558E+02 4.09E-02 0.01 0.02 40.29 0.43 3 |=============================================================================| | Time estimate for generating 10000 events: 0d:00h:00m:04s | Creating integration history display eemm-history.ps and eemm-history.pdf | Starting simulation for process 'eemm' | Simulate: using integration grids from file 'eemm_m1.vg' | RNG: Initializing TAO random-number generator | RNG: Setting seed for random-number generator to 29913 | OpenMP: Using 8 threads | Simulation: requested number of events = 0 | corr. to luminosity [fb-1] = 0.0000E+00 | Events: writing to raw file 'eemm.evx' | Events: generating 0 unweighted, unpolarized events ... | Events: event normalization mode '1' | ... event sample complete. | Events: closing raw file 'eemm.evx' | There were no errors and 1 warning(s). | WHIZARD run finished. |=============================================================================| \end{verbatim} \end{footnotesize} So, \whizard\ tells you that it has entered simulation mode, but besides this, it has not done anything. The next step is that you have to demand event generation -- there are two ways to do this: you could either specify a certain number, say 42, of events you want to have generated by \whizard, or you could provide a number for an integrated luminosity of some experiment. (Note, that if you choose to take both options, \whizard\ will take the one which gives the larger event sample. This, of course, depends on the given process(es) -- as well as cuts -- and its corresponding cross section(s).) The first of these options is set with the command: \ttt{n\_events = }, the second with \ttt{luminosity = }. Another important point already stated several times in the manual is that \whizard\ follows the commands in the steering \sindarin\ file in a chronological order. Hence, a given number of events or luminosity {\em after} a \ttt{simulate} command will be ignored -- or are relevant only for any \ttt{simulate} command potentially following further down in the \sindarin\ file. So, in our case, try: \begin{verbatim} n_events = 500 luminosity = 10 simulate (eemm) \end{verbatim} Per default, numbers for integrated luminosity are understood as inverse femtobarn. So, for the cross section above this would correspond to 4283 events, clearly superseding the demand for 500 events. After reducing the luminosity number from ten to one inverse femtobarn, 500 is the larger number of events taken by \whizard\ for event generation. Now \whizard\ tells you: \begin{verbatim} | Simulation: requested number of events = 500 | corr. to luminosity [fb-1] = 1.1673E+00 | Events: reading from raw file 'eemm.evx' | Events: reading 500 unweighted, unpolarized events ... | Events: event normalization mode '1' | ... event file terminates after 0 events. | Events: appending to raw file 'eemm.evx' | Generating remaining 500 events ... | ... event sample complete. | Events: closing raw file 'eemm.evx' \end{verbatim} I.e., it evaluates the luminosity to which the sample of 500 events would correspond to, which is now, of course, bigger than the $1 \fb^{-1}$ explicitly given for the luminosity. Furthermore, you can read off that a file \ttt{whizard.evx} has been generated, containing the demanded 500 events. (It was there before containing zero events, because to \ttt{n\_events} or \ttt{luminosity} value had been set. \whizard\ then tried to get the events first from file before generating new ones). Files with the suffix \ttt{.evx} are binary format event files, using a machine-dependent \whizard-specific event file format. Before we list the event formats supported by \whizard, the next two sections will tell you more about unweighted and weighted events as well as different possibilities to normalize events in \whizard. As already explained for the libraries, as well as the phase space and grid files in Chap.~\ref{chap:sindarin}, \whizard\ is trying to re-use as much information as possible. This is of course also true for the event files. There are special MD5 check sums testing the integrity and compatibility of the event files. If you demand for a process for which an event file already exists (as in the example above, though it was empty) equally many or less events than generated before, \whizard\ will not generate again but re-use the existing events (as already explained, the events are stored in a \whizard-own binary event format, i.e. in a so-called \ttt{.evx} file. If you suppress generation of that file, as will be described in subsection \ref{sec:eventformats} then \whizard\ has to generate events all the time). From version v2.2.0 of \whizard\ on, the program is also able to read in event from different event formats. However, most event formats do not contain as many information as \whizard's internal format, and a complete reconstruction of the events might not be possible. Re-using event files is very practical for doing several different analyses with the same data, especially if there are many and big data samples. Consider the case, there is an event file with 200 events, and you now ask \whizard\ to generate 300 events, then it will re-use the 200 events (if MD5 check sums are OK!), generate the remaining 100 events and append them to the existing file. If the user for some reason, however, wants to regenerate events (i.e. ignoring possibly existing events), there is the command option \ttt{whizard --rebuild-events}. %%%%%%%%% \section{Unweighted and weighted events} \whizard\ is able to generate unweighted events, i.e. events that are distributed uniformly and each contribute with the same event weight to the whole sample. This is done by mapping out the phase space of the process under consideration according to its different phase space channels (which each get their own weights), and then unweighting the sample of weighted events. Only a sample of unweighted events could in principle be compared to a real data sample from some experiment. The seventh column in the \whizard\ iteration/adaptation procedure tells you about the efficiency of the grids, i.e. how well the phase space is mapped to a flat function. The better this is achieved, the higher the efficiency becomes, and the closer the weights of the different phase space channels are to uniformity. This means, for higher efficiency less weighted events ("calls") are needed to generate a single unweighted event. An efficiency of 10 \% means that ten weighted events are needed to generate one single unweighted event. After the integration is done, \whizard\ uses the duration of calls during the adaptation to estimate a time interval needed to generate 10,000 unweighted events. The ability of the adaptive multi-channel Monte Carlo decreases with the number of integrations, i.e. with the number of final state particles. Adding more and more final state particles in general also increases the complexity of phase space, especially its singularity structure. For a $2 \to 2$ process the efficiency is roughly of the order of several tens of per cent. As a rule of thumb, one can say that with every additional pair of final state particle the average efficiency one can achieve decreases by a factor of five to ten. The default of \whizard\ is to generate {\em unweighted} events. One can use the logical variable \ttt{?unweighted = false} to disable unweighting and generate weighted events. (The command \ttt{?unweighted = true} is a tautology, because \ttt{true} is the default for this variable.) Note that again this command has to appear {\em before} the corresponding \ttt{simulate} command, otherwise it will be ignored or effective only for any \ttt{simulate} command appearing later in the \sindarin\ file. In the unweighted procedure, \whizard\ is keeping track of the highest weight that has been appeared during the adaptation, and the efficiency for the unweighting has been estimated from the average value of the sampling function compared to the maximum value. In principle, during event generation no events should be generated whose sampling function value exceeds the maximum function value encountered during the grid adaptation. Sometimes, however, there are numerical fluctuations and such events are happening. They are called {\em excess events}. \whizard\ does keep track of these excess events during event generation and will report about them, e.g.: \begin{code} Warning: Encountered events with excess weight: 9 events ( 0.090 %) | Maximum excess weight = 6.083E-01 | Average excess weight = 2.112E-04 \end{code} Whenever in an event generation excess events appear, this shows that the adaptation of the sampling function has not been perfect. When the number of excess weights is a finite number of percent, you should inspect the phase-space setup and try to improve its settings to get a better adaptation. Generating \emph{weighted} events is, of course, much faster if the same number of events is requested. Each event carries a weight factor which is taken into account for any internal analysis (histograms), and written to file if an external file format has been selected. The file format must support event weights. In a weighted event sample, there is typically a fraction of events which effectively have weight zero, namely those that have been created by the phase-space sampler but do not pass the requested cuts. In the default setup, those events are silently dropped, such that the events written to file or available for analysis all have nonzero weight. However, dropping such events affects the overall normalization. If this has happened, the program will issue a warning of the form \begin{code} | Dropped events (weight zero) = 1142 (total 2142) Warning: All event weights must be rescaled by f = 4.66853408E-01 \end{code} This factor has to be applied by hand to any external event files (and to internally generated histograms). The program cannot include the factor in the event records, because it is known only after all events have been generated. To avoid this problem, there is the logical flag \ttt{?keep\_failed\_events} which tells \whizard\ not to drop events with weight zero. The normalization will be correct, but the event sample will include invalid events which have to be vetoed by their zero weight, before any operations on the event record are performed. %%%%%%%%% \section{Choice on event normalizations} There are basically four different choices to normalize event weights ($\braket{\ldots}$ denotes the average): \begin{enumerate} \item $\braket{w_i} = 1$, \qquad\qquad $\Braket{\sum_i w_i} = N$ \item $\braket{w_i} = \sigma$, \qquad\qquad $\Braket{\sum_i w_i} = N \times \sigma$ \item $\braket{w_i} = 1/N$, \quad\qquad $\Braket{\sum_i w_i} = 1$ \item $\braket{w_i} = \sigma/N$, \quad\qquad $\Braket{\sum_i w_i} = \sigma$ \end{enumerate} So the four options are to have the average weight equal to unity, to the cross section of the corresponding process, to one over the number of events, or the cross section over the event calls. In these four cases, the event weights sum up to the event number, the event number times the cross section, to unity, and to the cross section, respectively. Note that neither of these really guarantees that all event weights individually lie in the interval $0 \leq w_i \leq 1$. The user can steer the normalization of events by using in \sindarin\ input files the string variable \ttt{\$sample\_normalization}. The default is \ttt{\$sample\_normalization = "auto"}, which uses option 1 for unweighted and 2 for weighted events, respectively. Note that this is also what the Les Houches Event Format (LHEF) demands for both types of events. This is \whizard's preferred mode, also for the reason, that event normalizations are independent from the number of events. Hence, event samples can be cut or expanded without further need to adjust the normalization. The unit normalization (option 1) can be switched on also for weighted events by setting the event normalization variable equal to \ttt{"1"}. Option 2 can be demanded by setting \ttt{\$sample\_normalization = "sigma"}. Options 3 and 4 can be set by \ttt{"1/n"} and \ttt{"sigma/n"}, respectively. \whizard\ accepts small and capital letters for these expressions. In the following section we show some examples when discussing the different event formats available in \whizard. %%%%%%%%% \section{Event selection} The \ttt{selection} expression (cf.\ Sec.~\ref{subsec:analysis}) reduces the event sample during generation or rescanning, selecting only events for which the expression evaluates to \ttt{true}. Apart from internal analysis, the selection also applies to writing external files. For instance, the following code generates a $e^+e^-\to W^+W^-$ sample with longitudinally polarized $W$ bosons only: \begin{footnotesize} \begin{verbatim} process ww = "e+", "e-" => "W-", "W+" polarized "W+" polarized "W-" ?polarized_events = true sqrts = 500 selection = all Hel == 0 ["W+":"W-"] simulate (ww) { n_events = 1000 } \end{verbatim} \end{footnotesize} The number of events that end up in the sample on file is equal to the number of events with longitudinally polarized $W$s in the generated sample, so the file will contain less than 1000 events. %%%%%%%%% \section{Supported event formats} \label{sec:eventformats} Event formats can either be distinguished whether they are plain text (i.e. ASCII) formats or binary formats. Besides this, one can classify event formats according to whether they are natively supported by \whizard\ or need some external program or library to be linked. Table~\ref{tab:eventformats} gives a complete list of all event formats available in \whizard. The second column shows whether these are ASCII or binary formats, the third column contains brief remarks about the corresponding format, while the last column tells whether external programs or libraries are needed (which is the case only for the HepMC formats). \begin{table} \begin{center} \begin{tabular}{|l||l|l|r|}\hline Format & Type & remark & ext. \\\hline ascii & ASCII & \whizard\ verbose format & no \\ Athena & ASCII & variant of HEPEVT & no \\ debug & ASCII & most verbose \whizard\ format & no \\ evx & binary & \whizard's home-brew & no \\ HepMC & ASCII & HepMC format & yes \\ HEPEVT & ASCII & \whizard~1 style & no \\ LCIO & ASCII & LCIO format & yes \\ LHA & ASCII & \whizard~1/old Les Houches style &no \\ LHEF & ASCII & Les Houches accord compliant & no \\ long & ASCII & variant of HEPEVT & no \\ mokka & ASCII & variant of HEPEVT & no \\ short & ASCII & variant of HEPEVT & no \\ StdHEP (HEPEVT) & binary & based on HEPEVT common block & no \\ StdHEP (HEPRUP/EUP) & binary & based on HEPRUP/EUP common block & no \\ Weight stream & ASCII & just weights & no \\ \hline \end{tabular} \end{center} \caption{\label{tab:eventformats} Event formats supported by \whizard, classified according to ASCII/binary formats and whether an external program or library is needed to generate a file of this format. For both the HEPEVT and the LHA format there is a more verbose variant. } \end{table} The "\ttt{.evx}'' is \whizard's native binary event format. If you demand event generation and do not specify anything further, \whizard\ will write out its events exclusively in this binary format. So in the examples discussed in the previous chapters (where we omitted all details about event formats), in all cases this and only this internal binary format has been generated. The generation of this raw format can be suppressed (e.g. if you want to have only one specific event file type) by setting the variable \verb|?write_raw = false|. However, if the raw event file is not present, \whizard\ is not able to re-use existing events (e.g. from an ASCII file) and will regenerate events for a given process. Note that from version v2.2.0 of \whizard\ on, the program is able to (partially) reconstruct complete events also from other formats than its internal format (e.g. LHEF), but this is still under construction and not yet complete. Other event formats can be written out by setting the variable \ttt{sample\_format = }, where \ttt{} can be any of the following supported variables: \begin{itemize} \item \ttt{ascii}: a quite verbose ASCII format which contains lots of information (an example is shown in the appendix). \newline Standard suffix: \ttt{.evt} \item \ttt{debug}: an even more verbose ASCII format intended for debugging which prints out also information about the internal data structures \newline Standard suffix: \ttt{.debug} \item \ttt{hepevt}: ASCII format that writes out a specific incarnation of the HEPEVT common block (\whizard~1 back-compatibility) \newline Standard suffix: \ttt{.hepevt} \item \ttt{hepevt\_verb}: more verbose version of \ttt{hepevt} (\whizard~1 back-compatibility) \newline Standard suffix: \ttt{.hepevt.verb} \item \ttt{short}: abbreviated variant of the previous HEPEVT (\whizard\ 1 back-compatibility) \newline Standard suffix: \ttt{.short.evt} \item \ttt{long}: HEPEVT variant that contains a little bit more information than the short format but less than HEPEVT (\whizard\ 1 back-compatibility) \newline Standard suffix: \ttt{.long.evt} \item \ttt{athena}: HEPEVT variant suitable for read-out in the ATLAS ATHENA software environment (\whizard\ 1 back-compatibility) \newline Standard suffix: \ttt{.athena.evt} \item \ttt{mokka}: HEPEVT variant suitable for read-out in the MOKKA ILC software environment \newline Standard suffix: \ttt{.mokka.evt} \item \ttt{lcio}: LCIO ASCII format (only available if LCIO is installed and correctly linked) \newline Standard suffix: \ttt{.lcio} \item \ttt{lha}: Implementation of the Les Houches Accord as it was in the old MadEvent and \whizard~1 \newline Standard suffix: \ttt{.lha} \item \ttt{lha\_verb}: more verbose version of \ttt{lha} \newline Standard suffix: \ttt{.lha.verb} \item \ttt{lhef}: Formatted Les Houches Accord implementation that contains the XML headers \newline Standard suffix: \ttt{.lhe} \item \ttt{hepmc}: HepMC ASCII format (only available if HepMC is installed and correctly linked) \newline Standard suffix: \ttt{.hepmc} \item \ttt{stdhep}: StdHEP binary format based on the HEPEVT common block \newline Standard suffix: \ttt{.hep} \item \ttt{stdhep\_up}: StdHEP binary format based on the HEPRUP/HEPEUP common blocks \newline Standard suffix: \ttt{.up.hep} \item \ttt{stdhep\_ev4}: StdHEP binary format based on the HEPEVT/HEPEV4 common blocks \newline Standard suffix: \ttt{.ev4.hep} \item \ttt{weight\_stream}: Format that prints out only the event weight (and maybe alternative ones) \newline Standard suffix: \ttt{.weight.dat} \end{itemize} Of course, the variable \ttt{sample\_format} can contain more than one of the above identifiers, in which case more than one different event file format is generated. The list above also shows the standard suffixes for these event formats (remember, that the native binary format of \whizard\ does have the suffix \ttt{.evx}). (The suffix of the different event formats can even be changed by the user by setting the corresponding variable \ttt{\$extension\_lhef = "foo"} or \ttt{\$extension\_ascii\_short = "bread"}. The dot is automatically included.) The name of the corresponding event sample is taken to be the string of the name of the first process in the \ttt{simulate} statement. Remember, that conventionally the events for all processes in one \ttt{simulate} statement will be written into one single event file. So \ttt{simulate (proc1, proc2)} will write events for the two processes \ttt{proc1} and \ttt{proc2} into one single event file with name \ttt{proc1.evx}. The name can be changed by the user with the command \ttt{\$sample = ""}. The commands \ttt{\$sample} and \ttt{sample\_format} are both accepted as optional arguments of a \ttt{simulate} command, so e.g. \ttt{simulate (proc) \{ \$sample = "foo" sample\_format = hepmc \}} generates an event sample in the HepMC format for the process \ttt{proc} in the file \ttt{foo.hepmc}. Examples for event formats, for specifications of the event formats correspond the different accords and publications~\footnote{Some event formats, based on the \ttt{HEPEVT} or \ttt{HEPEUP} common blocks, use fixed-form ASCII output with a two-digit exponent for real numbers. There are rare cases (mainly, ISR photons) where the event record can contain numbers with absolute value less than $10^{-99}$. Since those numbers are not representable in that format, \whizard\ will set all non-zero numbers below that value to $\pm 10^{-99}$, when filling either common block. Obviously, such values are physically irrelevant, but in the output they are representable and distinguishable from zero.}: \paragraph{HEPEVT:} The HEPEVT is an ASCII event format that does not contain an event file header. There is a one-line header for each single event, containing four entries. The number of particles in the event (\ttt{ISTHEP}), which is four for a fictitious example process $hh\to hh$, but could be larger if e.g. beam remnants are demanded to be included in the event. The second entry and third entry are the number of outgoing particles and beam remnants, respectively. The event weight is the last entry. For each particle in the event there are three lines: the first one is the status according to the HEPEVT format, \ttt{ISTHEP}, the second one the PDG code, \ttt{IDHEP}, then there are the one or two possible mother particle, \ttt{JMOHEP}, the first and last possible daughter particle, \ttt{JDAHEP}, and the polarization. The second line contains the three momentum components, $p_x$, $p_y$, $p_z$, the particle energy $E$, and its mass, $m$. The last line contains the position of the vertex in the event reconstruction. \begin{scriptsize} \begin{verbatim} 4 2 0 3.0574068604E+08 2 25 0 0 3 4 0 0.0000000000E+00 0.0000000000E+00 4.8412291828E+02 5.0000000000E+02 1.2500000000E+02 0.0000000000E+00 0.0000000000E+00 0.0000000000E+00 0.0000000000E+00 0.0000000000E+00 2 25 0 0 3 4 0 0.0000000000E+00 0.0000000000E+00 -4.8412291828E+02 5.0000000000E+02 1.2500000000E+02 0.0000000000E+00 0.0000000000E+00 0.0000000000E+00 0.0000000000E+00 0.0000000000E+00 1 25 1 2 0 0 0 -1.4960220911E+02 -4.6042825611E+02 0.0000000000E+00 5.0000000000E+02 1.2500000000E+02 0.0000000000E+00 0.0000000000E+00 0.0000000000E+00 0.0000000000E+00 0.0000000000E+00 1 25 1 2 0 0 0 1.4960220911E+02 4.6042825611E+02 0.0000000000E+00 5.0000000000E+02 1.2500000000E+02 0.0000000000E+00 0.0000000000E+00 0.0000000000E+00 0.0000000000E+00 0.0000000000E+00 \end{verbatim} \end{scriptsize} \paragraph{ASCII SHORT:} This is basically the same as the HEPEVT standard, but very much abbreviated. The header line for each event is identical, but the first line per particle does only contain the PDG and the polarization, while the vertex information line is omitted. \begin{scriptsize} \begin{verbatim} 4 2 0 3.0574068604E+08 25 0 0.0000000000E+00 0.0000000000E+00 4.8412291828E+02 5.0000000000E+02 1.2500000000E+02 25 0 0.0000000000E+00 0.0000000000E+00 -4.8412291828E+02 5.0000000000E+02 1.2500000000E+02 25 0 -1.4960220911E+02 -4.6042825611E+02 0.0000000000E+00 5.0000000000E+02 1.2500000000E+02 25 0 1.4960220911E+02 4.6042825611E+02 0.0000000000E+00 5.0000000000E+02 1.2500000000E+02 \end{verbatim} \end{scriptsize} \paragraph{ASCII LONG:} Identical to the ASCII short format, but after each event there is a line containg two values: the value of the sample function to be integrated over phase space, so basically the squared matrix element including all normalization factors, flux factor, structure functions etc. \begin{scriptsize} \begin{verbatim} 4 2 0 3.0574068604E+08 25 0 0.0000000000E+00 0.0000000000E+00 4.8412291828E+02 5.0000000000E+02 1.2500000000E+02 25 0 0.0000000000E+00 0.0000000000E+00 -4.8412291828E+02 5.0000000000E+02 1.2500000000E+02 25 0 -1.4960220911E+02 -4.6042825611E+02 0.0000000000E+00 5.0000000000E+02 1.2500000000E+02 25 0 1.4960220911E+02 4.6042825611E+02 0.0000000000E+00 5.0000000000E+02 1.2500000000E+02 1.0000000000E+00 1.0000000000E+00 \end{verbatim} \end{scriptsize} \paragraph{ATHENA:} Quite similar to the HEPEVT ASCII format. The header line, however, does contain only two numbers: an event counter, and the number of particles in the event. The first line for each particle lacks the polarization information (irrelevant for the ATHENA environment), but has as leading entry an ordering number counting the particles in the event. The vertex information line has only the four relevant position entries. \begin{scriptsize} \begin{verbatim} 0 4 1 2 25 0 0 3 4 0.0000000000E+00 0.0000000000E+00 4.8412291828E+02 5.0000000000E+02 1.2500000000E+02 0.0000000000E+00 0.0000000000E+00 0.0000000000E+00 0.0000000000E+00 2 2 25 0 0 3 4 0.0000000000E+00 0.0000000000E+00 -4.8412291828E+02 5.0000000000E+02 1.2500000000E+02 0.0000000000E+00 0.0000000000E+00 0.0000000000E+00 0.0000000000E+00 3 1 25 1 2 0 0 -1.4960220911E+02 -4.6042825611E+02 0.0000000000E+00 5.0000000000E+02 1.2500000000E+02 0.0000000000E+00 0.0000000000E+00 0.0000000000E+00 0.0000000000E+00 4 1 25 1 2 0 0 1.4960220911E+02 4.6042825611E+02 0.0000000000E+00 5.0000000000E+02 1.2500000000E+02 0.0000000000E+00 0.0000000000E+00 0.0000000000E+00 0.0000000000E+00 \end{verbatim} \end{scriptsize} \paragraph{MOKKA:} Quite similar to the ASCII short format, but the event entries are the particle status, the PDG code, the first and last daughter, the three spatial components of the momentum, as well as the mass. \begin{scriptsize} \begin{verbatim} 4 2 0 3.0574068604E+08 2 25 3 4 0.0000000000E+00 0.0000000000E+00 4.8412291828E+02 1.2500000000E+02 2 25 3 4 0.0000000000E+00 0.0000000000E+00 -4.8412291828E+02 1.2500000000E+02 1 25 0 0 -1.4960220911E+02 -4.6042825611E+02 0.0000000000E+00 1.2500000000E+02 1 25 0 0 1.4960220911E+02 4.6042825611E+02 0.0000000000E+00 1.2500000000E+02 \end{verbatim} \end{scriptsize} \paragraph{LHA:} This is the implementation of the Les Houches Accord, as it was used in \whizard\ 1 and the old MadEvent. There is a first line containing six entries: 1. the number of particles in the event, \ttt{NUP}, 2. the subprocess identification index, \ttt{IDPRUP}, 3. the event weight, \ttt{XWGTUP}, 4. the scale of the process, \ttt{SCALUP}, 5. the value or status of $\alpha_{QED}$, \ttt{AQEDUP}, 6. the value for $\alpha_s$, \ttt{AQCDUP}. The next seven lines contain as many entries as there are particles in the event: the first one has the PDG codes, \ttt{IDUP}, the next two the first and second mother of the particles, \ttt{MOTHUP}, the fourth and fifth line the two color indices, \ttt{ICOLUP}, the next one the status of the particle, \ttt{ISTUP}, and the last line the polarization information, \ttt{ISPINUP}. At the end of the event there are as lines for each particles with the counter in the event and the four-vector of the particle. For more information on this event format confer~\cite{LesHouches}. \begin{scriptsize} \begin{verbatim} 25 25 5.0000000000E+02 5.0000000000E+02 -1 -1 -1 -1 3 1 1.0000000000E-01 1.0000000000E-03 1.0000000000E+00 42 4 1 3.0574068604E+08 1.000000E+03 -1.000000E+00 -1.000000E+00 25 25 25 25 0 0 1 1 0 0 2 2 0 0 0 0 0 0 0 0 -1 -1 1 1 9 9 9 9 1 5.0000000000E+02 0.0000000000E+00 0.0000000000E+00 4.8412291828E+02 2 5.0000000000E+02 0.0000000000E+00 0.0000000000E+00 -4.8412291828E+02 3 5.0000000000E+02 -1.4960220911E+02 -4.6042825611E+02 0.0000000000E+00 4 5.0000000000E+02 1.4960220911E+02 4.6042825611E+02 0.0000000000E+00 \end{verbatim} \end{scriptsize} \paragraph{LHEF:} This is the modern version of the Les Houches accord event format (LHEF), for the details confer the corresponding publication~\cite{LHEF}. \begin{scriptsize} \begin{verbatim}
WHIZARD 2.8.3
25 25 5.0000000000E+02 5.0000000000E+02 -1 -1 -1 -1 3 1 1.0000000000E-01 1.0000000000E-03 1.0000000000E+00 42 4 42 3.0574068604E+08 1.0000000000E+03 -1.0000000000E+00 -1.0000000000E+00 25 -1 0 0 0 0 0.0000000000E+00 0.0000000000E+00 4.8412291828E+02 5.0000000000E+02 1.2500000000E+02 0.0000000000E+00 9.0000000000E+00 25 -1 0 0 0 0 0.0000000000E+00 0.0000000000E+00 -4.8412291828E+02 5.0000000000E+02 1.2500000000E+02 0.0000000000E+00 9.0000000000E+00 25 1 1 2 0 0 -1.4960220911E+02 -4.6042825611E+02 0.0000000000E+00 5.0000000000E+02 1.2500000000E+02 0.0000000000E+00 9.0000000000E+00 25 1 1 2 0 0 1.4960220911E+02 4.6042825611E+02 0.0000000000E+00 5.0000000000E+02 1.2500000000E+02 0.0000000000E+00 9.0000000000E+00
\end{verbatim} \end{scriptsize} Note that for the LHEF format, there are different versions according to the different stages of agreement. They can be addressed from within the \sindarin\ file by setting the string variable \ttt{\$lhef\_version} to one of (at the moment) three values: \ttt{"1.0"}, \ttt{"2.0"}, or \ttt{"3.0"}. The examples above corresponds (as is indicated in the header) to the version \ttt{"1.0"} of the LHEF format. Additional information in form of alternative squared matrix elements or event weights in the event are the most prominent features of the other two more advanced versions. For more details confer the literature. \vspace{.5cm} Sample files for the default ASCII format as well as for the debug event format are shown in the appendix. %%%%%%%%% \section[Interfaces to Parton Showers, Matching and Hadronization]{Interfaces to Parton Showers, Matching\\and Hadronization} This section describes the interfaces to the internal parton shower as well as the parton shower and hadronization routines from \pythia. Moreover, our implementation of the MLM matching making use of the parton showers is described. Sample \sindarin\ files are located in the \ttt{share/examples} directory. All input files come in two versions, one using the internal shower, ending in \ttt{W.sin}, and one using \pythia's shower, ending in \ttt{P.sin}. Thus we state all file names as ending with \ttt{X.sin}, where \ttt{X} has to be replaced by either \ttt{W} or \ttt{P}. The input files include \ttt{EENoMatchingX.sin} and \ttt{DrellYanNoMatchingX.sin} for $e^+ e^- \to hadrons$ and $p\bar{p} \to Z$ without matching. The corresponding \sindarin\ files with matching enabled are \ttt{EEMatching2X.sin} to \ttt{EEMatching5X.sin} for $e^+ e^- \to hadrons$ with a different number of partons included in the matrix element and \ttt{DrallYanMatchingX.sin} for Drell-Yan with one matched emission. \subsection{Parton Showers and Hadronization} From version 2.1 onwards, \whizard\ contains an implementation of an analytic parton shower as presented in \cite{Kilian:2011ka}, providing the opportunity to perform the parton shower from whithin \whizard. Moreover, an interface to \pythia\ is included, which can be used to delegate the parton shower to \pythia. The same interface can be used to hadronize events using the generated events using \pythia's hadronization routines. Note that by \pythia's default, when performing initial-state radiation multiple interactions are included and when performing the hadronization hadronic decays are included. If required, these additional steps have to be switched off using the corresponding arguments for \pythia's \ttt{PYGIVE} routine vie the \ttt{\$ps\_PYTHIA\_PYGIVE} string. Note that from version 2.2.4 on the earlier flag \ttt{--enable-shower} flag has been abandoned, and there is only a flag to either compile or not compile the interally attached \pythia\ttt{6} package (\ttt{--enable-pythia6}) last release of the \fortran\ \pythia, v6.427) as well as the interface. It can be invoked by the following \sindarin\ keywords:\\[2ex] % \centerline{\begin{tabular}{|l|l|} \hline\ttt{?ps\_fsr\_active = true} & master switch for final-state parton showers\\\hline \ttt{?ps\_isr\_active = true} & master switch for initial-state parton showers\\\hline \ttt{?ps\_taudec\_active = true} & master switch for $\tau$ decays (at the moment only via \ttt{TAUOLA}\\\hline \ttt{?hadronization\_active = true} & master switch to enable hadronization\\\hline \ttt{\$shower\_method = "PYTHIA6"} & switch to use \pythiasix's parton shower instead of \\ & \whizard's own shower\\\hline \end{tabular}}\mbox{} \vspace{4mm} If either \ttt{?ps\_fsr\_active} or \ttt{?ps\_isr\_active} is set to \verb|true|, the event will be transferred to the internal shower routines or the \pythia\ data structures, and the chosen shower steps (initial- and final-state radiation) will be performed. If hadronization is enabled via the \ttt{?hadronization\_active} switch, \whizard\ will call \pythia's hadronization routine. The hadron\-ization can be applied to events showered using the internal shower or showered using \pythia's shower routines, as well as unshowered events. Any necessary transfer of event data to \pythia\ is automatically taken care of within \whizard's shower interface. The resulting (showered and/or hadronized) event will be transferred back to \whizard, the former final particles will be marked as intermediate. The analysis can be applied to a showered and/or hadronized event just like in the unshowered/unhadronized case. Any event file can be used and will contain the showered/hadronized event. Settings for the internal analytic parton shower are set via the following \sindarin\ variables:\\[2ex] \begin{description} \item[\ttt{ps\_mass\_cutoff}] The cut-off in virtuality, below which, partons are assumed to radiate no more. Used for both ISR and FSR. Given in $\mbox{GeV}$. (Default = 1.0) \item[\ttt{ps\_fsr\_lambda}] The value for $\Lambda$ used in calculating the value of the running coupling constant $\alpha_S$ for Final State Radiation. Given in $\mbox{GeV}$. (Default = 0.29) \item[\ttt{ps\_isr\_lambda}] The value for $\Lambda$ used in calculating the value of the running coupling constant $\alpha_S$ for Initial State Radiation. Given in $\mbox{GeV}$. (Default = 0.29) \item[\ttt{ps\_max\_n\_flavors}] Number of quark flavours taken into account during shower evolution. Meaningful choices are 3 to include $u,d,s$-quarks, 4 to include $u,d,s,c$-quarks and 5 to include $u,d,s,c,b$-quarks. (Default = 5) \item[\ttt{?ps\_isr\_alphas\_running}] Switch to decide between a constant $\alpha_S$, given by \ttt{ps\_fixed\_alphas}, and a running $\alpha_S$, calculated using \ttt{ps\_isr\_lambda} for ISR. (Default = true) \item[\ttt{?ps\_fsr\_alphas\_running}] Switch to decide between a constant $\alpha_S$, given by \ttt{ps\_fixed\_alphas}, and a running $\alpha_S$, calculated using \ttt{ps\_fsr\_lambda} for FSR. (Default = true) \item[\ttt{ps\_fixed\_alphas}] Fixed value of $\alpha_S$ for the parton shower. Used if either one of the variables \ttt{?ps\_fsr\_alphas\_running} or \ttt{?ps\_isr\_alphas\_running} are set to \verb|false|. (Default = 0.0) \item[\ttt{?ps\_isr\_angular\_ordered}] Switch for angular ordered ISR. (Default = true )\footnote{The FSR is always simulated with angular ordering enabled.} \item[\ttt{ps\_isr\_primordial\_kt\_width}] The width in $\mbox{GeV}$ of the Gaussian assumed to describe the transverse momentum of partons inside the proton. Other shapes are not yet implemented. (Default = 0.0) \item[\ttt{ps\_isr\_primordial\_kt\_cutoff}] The maximal transverse momentum in $\mbox{GeV}$ of a parton inside the proton. Used as a cut-off for the Gaussian. (Default = 5.0) \item[\ttt{ps\_isr\_z\_cutoff}] Maximal $z$-value in initial state branchings. (Default = 0.999) \item[\ttt{ps\_isr\_minenergy}] Minimal energy in $\mbox{GeV}$ of an emitted timelike or final parton. Note that the energy is not calculated in the labframe but in the center-of-mas frame of the two most initial partons resolved so far, so deviations may occur. (Default = 1.0) \item[\ttt{ps\_isr\_tscalefactor}] Factor for the starting scale in the initial state shower evolution. ( Default = 1.0 ) \item[\ttt{?ps\_isr\_only\_onshell\_emitted\_partons}] Switch to allow only for on-shell emitted partons, thereby rejecting all possible final state parton showers starting from partons emitted during the ISR. (Default = false) \end{description} Settings for the \pythia\ are transferred using the following \sindarin\ variables:\\[2ex] \centerline{\begin{tabular}{|l|l|} \hline\ttt{?ps\_PYTHIA\_verbose} & if set to false, output from \pythia\ will be suppressed\\\hline \ttt{\$ps\_PYTHIA\_PYGIVE} & a string containing settings transferred to \pythia's \ttt{PYGIVE} subroutine.\\ & The format is explained in the \pythia\ manual. The limitation to 100 \\ & characters mentioned there does not apply here, the string is split \\ & appropriately before being transferred to \pythia.\\\hline \end{tabular}}\mbox{} \vspace{4mm} Note that the included version of \pythia\ uses \lhapdf\ for initial state radiation whenever this is available, but the PDF set has to be set manually in that case using the keyword \ttt{ps\_PYTHIA\_PYGIVE}. \subsection{Parton shower -- Matrix Element Matching} Along with the inclusion of the parton showers, \whizard\ includes an implementation of the MLM matching procedure. For a detailed description of the implemented steps see \cite{Kilian:2011ka}. The inclusion of MLM matching still demands some manual settings in the \sindarin\ file. For a given base process and a matching of $N$ additional jets, all processes that can be obtained by attaching up to $N$ QCD splittings, either a quark emitting a gluon or a gluon splitting into two quarks ar two gluons, have to be manually specified as additional processes. These additional processes need to be included in the \ttt{simulate} statement along with the original process. The \sindarin\ variable \ttt{mlm\_nmaxMEjets} has to be set to the maximum number of additional jets $N$. Moreover additional cuts have to be specified for the additional processes. \begin{verbatim} alias quark = u:d:s:c alias antiq = U:D:S:C alias j = quark:antiq:g ?mlm_matching = true mlm_ptmin = 5 GeV mlm_etamax = 2.5 mlm_Rmin = 1 cuts = all Dist > mlm_Rmin [j, j] and all Pt > mlm_ptmin [j] and all abs(Eta) < mlm_etamax [j] \end{verbatim} Note that the variables \ttt{mlm\_ptmin}, \ttt{mlm\_etamax} and \ttt{mlm\_Rmin} are used by the matching routine. Thus, replacing the variables in the \ttt{cut} expression and omitting the assignment would destroy the matching procedure. The complete list of variables introduced to steer the matching procedure is as follows: \begin{description} \item[\ttt{?mlm\_matching\_active}] Master switch to enable MLM matching. (Default = false) \item[\ttt{mlm\_ptmin}] Minimal transverse momentum, also used in the definition of a jet \item[\ttt{mlm\_etamax}] Maximal absolute value of pseudorapidity $\eta$, also used in defining a jet \item[\ttt{mlm\_Rmin}] Minimal $\eta-\phi$ distance $R_{min}$ \item[\ttt{mlm\_nmaxMEjets}] Maximum number of jets $N$ \item[\ttt{mlm\_ETclusfactor}] Factor to vary the jet definition. Should be $\geq 1$ for complete coverage of phase space. (Default = 1) \item[\ttt{mlm\_ETclusminE}] Minimal energy in the variation of the jet definition \item[\ttt{mlm\_etaclusfactor}] Factor in the variation of the jet definition. Should be $\leq 1$ for complete coverage of phase space. (Default = 1) \item[\ttt{mlm\_Rclusfactor}] Factor in the variation of the jet definition. Should be $\ge 1$ for complete coverage of phase space. (Default = 1) \end{description} The variation of the jet definition is a tool to asses systematic uncertainties introduced by the matching procedure (See section 3.1 in \cite{Kilian:2011ka}). %%%%%%%%% \section{Rescanning and recalculating events} \label{sec:rescan} In the simplest mode of execution, \whizard\ handles its events at the point where they are generated. It can apply event transforms such as decays or shower (see above), it can analyze the events, calculate and plot observables, and it can output them to file. However, it is also possible to apply two different operations to those events in parallel, or to reconsider and rescan an event sample that has been previously generated. We first discuss the possibilities that \ttt{simulate} offers. For each event, \whizard\ calculates the matrix element for the hard interaction, supplements this by Jacobian and phase-space factors in order to obtain the event weight, optionally applies a rejection step in order to gather uniformly weighted events, and applies the cuts and analysis setup. We may ask about the event matrix element or weight, or the analysis result, that we would have obtained for a different setting. To this end, there is an \ttt{alt\_setup} option. This option allows us to recalculate, event by event, the matrix element, weight, or analysis contribution with a different parameter set but identical kinematics. For instance, we may evaluate a distribution for both zero and non-zero anomalous coupling \ttt{fw} and enter some observable in separate histograms: \begin{footnotesize} \begin{verbatim} simulate (some_proc) { fw = 0 analysis = record hist1 (eval Pt [H]) alt_setup = { fw = 0.01 analysis = record hist2 (eval Pt [H]) } } \end{verbatim} \end{footnotesize} In fact, the \ttt{alt\_setup} object is not restricted to a single code block (enclosed in curly braces) but can take a list of those, \begin{footnotesize} \begin{verbatim} alt_setup = { fw = 0.01 }, { fw = 0.02 }, ... \end{verbatim} \end{footnotesize} Each block provides the environment for a separate evaluation of the event data. The generation of these events, i.e., their kinematics, is still steered by the primary environment. The \ttt{alt\_setup} blocks may modify various settings that affect the evaluation of an event, including physical parameters, PDF choice, cuts and analysis, output format, etc. This must not (i.e., cannot) affect the kinematics of an event, so don't modify particle masses. When applying cuts, they can only reduce the generated event sample, so they apply on top of the primary cuts for the simulation. Alternatively, it is possible to \ttt{rescan} a sample that has been generated by a previous \ttt{simulate} command: \begin{footnotesize} \begin{verbatim} simulate (some_proc) { $sample = "my_events" analysis = record hist1 (eval Pt [H]) } ?update_sqme = true ?update_weight = true rescan "my_events" (some_proc) { fw = 0.01 analysis = record hist2 (eval Pt [H]) } rescan "my_events" (some_proc) { fw = 0.05 analysis = record hist3 (eval Pt [H]) } \end{verbatim} \end{footnotesize} In more complicated situation, rescanning is more transparent and offers greater flexibility than doing all operations at the very point of event generation. Combining these features with the \ttt{scan} looping construct, we already cover a considerable range of applications. (There are limitations due to the fact that \sindarin\ doesn't provide array objects, yet.) Note that the \ttt{rescan} construct also allows for an \ttt{alt\_setup} option. You may generate a new sample by rescanning, for which you may choose any output format: \begin{footnotesize} \begin{verbatim} rescan "my_events" (some_proc) { selection = all Pt > 100 GeV [H] $sample = "new_events" sample_format = lhef } \end{verbatim} \end{footnotesize} The event sample that you rescan need not be an internal raw \whizard\ file, as above. You may rescan a LHEF file, \begin{footnotesize} \begin{verbatim} rescan "lhef_events" (proc) { $rescan_input_format = "lhef" } \end{verbatim} \end{footnotesize} This file may have any origin, not necessarily from \whizard. To understand such an external file, \whizard\ must be able to reconstruct the hard process and match it to a process with a known name (e.g., \ttt{proc}), that has been defined in the \sindarin\ script previously. Within its limits, \whizard\ can thus be used for translating an event sample from one format to another format. There are three important switches that control the rescanning behavior. They can be set or unset independently. \begin{itemize} \item \ttt{?update\_sqme} (default: false). If true, \whizard\ will recalculate the hard matrix element for each event. When applying an analysis, the recalculated squared matrix element (averaged and summed over quantum numbers as usual) is available as the variable \ttt{sqme\_prc}. This may be related to \ttt{sqme\_ref}, the corresponding value in the event file, if available. (For the \ttt{alt\_env} option, this switch is implied.) \item \ttt{?update\_weight} (default: false). If true, \whizard\ will recalculate the event weight according to the current environment and apply this to the event. In particular, the user may apply a \ttt{reweight} expression. In an analysis, the new weight value is available as \ttt{weight\_prc}, to be related to \ttt{weight\_ref} from the sample. The updated weight will be applied for histograms and averages. An unweighted event sample will thus be transformed into a weighted event sample. (This switch is also implied for the \ttt{alt\_env} option.) \item \ttt{?update\_event} (default: false). If true, \whizard\ will generate a new decay chain etc., if applicable. That is, it reuses just the particles in the hard process. Otherwise, the complete event is kept as it is written to file. \end{itemize} For these options to make sense, \whizard\ must have access to a full process object, so the \sindarin\ script must contain not just a definition but also a \ttt{compile} command for the matrix elements in question. If an event file (other than raw format) contains several processes as a mixture, they must be identifiable by a numeric ID. \whizard\ will recognize the processes if their respective \sindarin\ definitions contain appropriate \ttt{process\_num\_id} options, such as \begin{footnotesize} \begin{verbatim} process foo = u, ubar => d, dbar { process_num_id = 42 } \end{verbatim} \end{footnotesize} Certain event-file formats, such as LHEF, support alternative matrix-element values or weights. \whizard\ can thus write both original and recalculated matrix-element and weight values. Other formats support only a single event weight, so the \ttt{?update\_weight} option is necessary for a visible effect. External event files in formats such as LHEF, HepMC, or LCIO, also may carry information about the value of the strong coupling $\alpha_s$ and the energy scale of each event. This information will also be provided by \whizard\ when writing external event files. When such an event file is rescanned, the user has the choice to either user the $\alpha_s$ value that \whizard\ defines in the current context (or the method for obtaining an event-specific running $\alpha_s$ value), or override this for each event by using the value in the event file. The corresponding parameter is \ttt{?use\_alphas\_from\_file}, which is false by default. Analogously, the parameter \ttt{?use\_scale\_from\_file} may be set to override the scale definition in the current context. Obviously, these settings influence matrix-element recalculation and therefore require \ttt{?update\_sqme} to be set in order to become operational. %%%%%%%%% \section{Negative weight events} For usage at NLO refer to Subsection~\ref{ss:fixedorderNLOevents}. In case, you have some other mechanism to produce events with negative weights (e.g. with the \ttt{weight = {\em }} command), keep in mind that you should activate \ttt{?negative\_weights = true} and \ttt{unweighted = false}. The generation of unweighted events with varying sign (also known as events and counter events) is currently not supported. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Internal Data Visualization} \label{chap:visualization} \section{GAMELAN} The data values and tables that we have introduced in the previous section can be visualized using built-in features of \whizard. To be precise, \whizard\ can write \LaTeX\ code which incorporates code in the graphics language GAMELAN to produce a pretty-printed account of observables, histograms, and plots. GAMELAN is a macro package for MetaPost, which is part of the \TeX/\LaTeX\ family. MetaPost, a derivative of Knuth's MetaFont language for font design, is usually bundled with the \TeX\ distribution, but might need a separate switch for installation. The GAMELAN macros are contained in a subdirectory of the \whizard\ package. Upon installation, they will be installed in the appropriate directory, including the \ttt{gamelan.sty} driver for \LaTeX. \whizard\ uses a subset of GAMELAN's graphics macros directly, but it allows for access to the full package if desired. An (incomplete) manual for GAMELAN can be found in the \ttt{share/doc} subdirectory of the \whizard\ system. \whizard\ itself uses a subset of the GAMELAN capabilities, interfaced by \sindarin\ commands and parameters. They are described in this chapter. To process analysis output beyond writing tables to file, the \ttt{write\_analysis} command described in the previous section should be replaced by \ttt{compile\_analysis}, with the same syntax: \begin{quote} \begin{footnotesize} \ttt{compile\_analysis (\emph{analysis-tags}) \{ \ttt{\emph{options}} \}} \end{footnotesize} \end{quote} where \ttt{\emph{analysis-tags}}, a comma-separated list of analysis objects, is optional. If there are no tags, all analysis objects are processed. The \ttt{\emph{options}} script of local commands is also optional, of course. This command will perform the following actions: \begin{enumerate} \item It writes a data file in default format, as \ttt{write\_analysis} would do. The file name is given by \ttt{\$out\_file}, if nonempty. The file must not be already open, since the command needs a self-contained file, but the name is otherwise arbitrary. If the value of \ttt{\$out\_file} is empty, the default file name is \ttt{whizard\_analysis.dat}. \item It writes a driver file for the chosen datasets, whose name is derived from the data file by replacing the file extension of the data file with the extension \ttt{.tex}. The driver file is a \LaTeX\ source file which contains embedded GAMELAN code that handles the selected graphics data. In the \LaTeX\ document, there is a separate section for each contained dataset. Furthermore, a process-/analysis-specific makefile with the name \ttt{\_ana.makefile} is created that can be used to generate postscript or PDF output from the \LaTeX\ source. If the steering flag \ttt{?analysis\_file\_only} is set to \ttt{true}, then the \LaTeX\ file and the makefile are only written, but no execution of the makefile resulting in compilation of the \LaTeX\ code (see the next item) is invoked. \item As mentioned above, if the flag \ttt{?analysis\_file\_only} is set to \ttt{false} (which is the default), the driver file is processed by \LaTeX (invoked by calling the makefile with the name \ttt{\_ana.makefile}), which generates an appropriate GAMELAN source file with extension \ttt{.mp}. This code is executed (calling GAMELAN/MetaPost, and again \LaTeX\ for typesetting embedded labels). There is a second \LaTeX\ pass (automatically done by the makefile) which collects the results, and finally conversion to PostScript and PDF formats. \end{enumerate} The resulting PostScript or PDF file -- the file name is the name of the data file with the extension replaced by \ttt{.ps} or \ttt{.pdf}, respectively -- can be printed or viewed with an appropriate viewer such as \ttt{gv}. The viewing command is not executed automatically by \whizard. Note that \LaTeX\ will write further files with extensions \ttt{.log}, \ttt{.aux}, and \ttt{.dvi}, and GAMELAN will produce auxiliary files with extensions \ttt{.ltp} and \ttt{.mpx}. The log file in particular, could overwrite \whizard's log file if the basename is identical. Be careful to use a value for \ttt{\$out\_file} which is not likely to cause name clashes. \subsection{User-specific changes} In the case, that the \sindarin\ \ttt{compile\_analysis} command is invoked and the flag named \ttt{?analysis\_file\_only} is not changed from its default value \ttt{false}, \whizard\ calls the process-/analysis-specific makefile triggering the compilation of the \LaTeX\ code and the GAMELAN plots and histograms. If the user wants to edit the analysis output, for example changing captions, headlines, labels, properties of the plots, graphs and histograms using GAMELAN specials etc., this is possible and the output can be regenerated using the makefile. The user can also directly invoke the GAMELAN script, \ttt{whizard-gml}, that is installed in the binary directly along with the \whizard\ binary and other scripts. Note however, that the \LaTeX\ environment for the specific style files have to be set by hand (the command line invocation in the makefile does this automatically). Those style files are generally written into \ttt{share/texmf/whizard/} directory. The user can execute the commands in the same way as denoted in the process-/analysis-specific makefile by hand. %%%%% \section{Histogram Display} %%%%% \section{Plot Display} \section{Graphs} \label{sec:graphs} Graphs are an additional type of analysis object. In contrast to histograms and plots, they do not collect data directly, but they rather act as containers for graph elements, which are copies of existing histograms and plots. Their single purpose is to be displayed by the GAMELAN driver. Graphs are declared by simple assignments such as \begin{quote} \begin{footnotesize} \ttt{graph g1 = hist1} \\ \ttt{graph g2 = hist2 \& hist3 \& plot1} \end{footnotesize} \end{quote} The first declaration copies a single histogram into the graph, the second one copies two histograms and a plot. The syntax for collecting analysis objects uses the \ttt{\&} concatenation operator, analogous to string concatenation. In the assignment, the rhs must contain only histograms and plots. Further concatenating previously declared graphs is not supported. After the graph has been declared, its contents can be written to file (\ttt{write\_analysis}) or, usually, compiledd by the \LaTeX/GAMELAN driver via the \ttt{compile\_analysis} command. The graph elements on the right-hand side of the graph assignment are copied with their current data content. This implies a well-defined order of statements: first, histograms and plots are declared, then they are filled via \ttt{record} commands or functions, and finally they can be collected for display by graph declarations. A simple graph declaration without options as above is possible, but usually there are option which affect the graph display. There are two kinds of options: graph options and drawing options. Graph options apply to the graph as a whole (title, labels, etc.) and are placed in braces on the lhs of the assigment. Drawing options apply to the individual graph elements representing the contained histograms and plots, and are placed together with the graph element on the rhs of the assignment. Thus, the complete syntax for assigning multiple graph elements is \begin{quote} \begin{footnotesize} \ttt{graph \emph{graph-tag} \{ \emph{graph-options} \}} \\ \ttt{= \emph{graph-element-tag1} \{ \emph{drawing-options1} \}} \\ \ttt{\& \emph{graph-element-tag2} \{ \emph{drawing-options2} \}} \\ \ldots \end{footnotesize} \end{quote} This form is recommended, but graph and drawing options can also be set as global parameters, as usual. We list the supported graph and drawing options in Tables~\ref{tab:graph-options} and \ref{tab:drawing-options}, respectively. \begin{table} \caption{Graph options. The content of strings of type \LaTeX\ must be valid \LaTeX\ code (containing typesetting commands such as math mode). The content of strings of type GAMELAN must be valid GAMELAN code. If a graph bound is kept \emph{undefined}, the actual graph bound is determined such as not to crop the graph contents in the selected direction.} \label{tab:graph-options} \begin{center} \begin{tabular}{|l|l|l|l|} \hline Variable & Default & Type & Meaning \\ \hline\hline \ttt{\$title} & \ttt{""} & \LaTeX & Title of the graph = subsection headline \\ \hline \ttt{\$description} & \ttt{""} & \LaTeX & Description text for the graph \\ \hline \ttt{\$x\_label} & \ttt{""} & \LaTeX & $x$-axis label \\ \hline \ttt{\$y\_label} & \ttt{""} & \LaTeX & $y$-axis label \\ \hline \ttt{graph\_width\_mm} & 130 & Integer & graph width (on paper) in mm \\ \hline \ttt{graph\_height\_mm} & 90 & Integer & graph height (on paper) in mm \\ \hline \ttt{?x\_log} & false & Logical & Whether the $x$-axis scale is linear or logarithmic \\ \hline \ttt{?y\_log} & false & Logical & Whether the $y$-axis scale is linear or logarithmic \\ \hline \ttt{x\_min} & \emph{undefined} & Real & Lower bound for the $x$ axis \\ \hline \ttt{x\_max} & \emph{undefined} & Real & Upper bound for the $x$ axis \\ \hline \ttt{y\_min} & \emph{undefined} & Real & Lower bound for the $y$ axis \\ \hline \ttt{y\_max} & \emph{undefined} & Real & Upper bound for the $y$ axis \\ \hline \ttt{gmlcode\_bg} & \ttt{""} & GAMELAN & Code to be executed before drawing \\ \hline \ttt{gmlcode\_fg} & \ttt{""} & GAMELAN & Code to be executed after drawing \\ \hline \end{tabular} \end{center} \end{table} \begin{table} \caption{Drawing options. The content of strings of type GAMELAN must be valid GAMELAN code. The behavior w.r.t. the flags with \emph{undefined} default value depends on the type of graph element. Histograms: draw baseline, piecewise, fill area, draw curve, no errors, no symbols; Plots: no baseline, no fill, draw curve, no errors, no symbols.} \label{tab:drawing-options} \begin{center} \begin{tabular}{|l|l|l|l|} \hline Variable & Default & Type & Meaning \\ \hline\hline \ttt{?draw\_base} & \emph{undefined} & Logical & Whether to draw a baseline for the curve \\ \hline \ttt{?draw\_piecewise} & \emph{undefined} & Logical & Whether to draw bins separately (histogram) \\ \hline \ttt{?fill\_curve} & \emph{undefined} & Logical & Whether to fill area between baseline and curve \\ \hline \ttt{\$fill\_options} & \ttt{""} & GAMELAN & Options for filling the area \\ \hline \ttt{?draw\_curve} & \emph{undefined} & Logical & Whether to draw the curve as a line \\ \hline \ttt{\$draw\_options} & \ttt{""} & GAMELAN & Options for drawing the line \\ \hline \ttt{?draw\_errors} & \emph{undefined} & Logical & Whether to draw error bars for data points \\ \hline \ttt{\$err\_options} & \ttt{""} & GAMELAN & Options for drawing the error bars \\ \hline \ttt{?draw\_symbols} & \emph{undefined} & Logical & Whether to draw symbols at data points \\ \hline \ttt{\$symbol} & Black dot & GAMELAN & Symbol to be drawn \\ \hline \ttt{gmlcode\_bg} & \ttt{""} & GAMELAN & Code to be executed before drawing \\ \hline \ttt{gmlcode\_fg} & \ttt{""} & GAMELAN & Code to be executed after drawing \\ \hline \end{tabular} \end{center} \end{table} \section{Drawing options} The options for coloring lines, filling curves, or choosing line styles make use of macros in the GAMELAN language. At this place, we do not intend to give a full account of the possiblities, but we rather list a few basic features that are likely to be useful for drawing graphs. \subsubsection{Colors} GAMELAN knows about basic colors identified by name: \begin{center} \ttt{black}, \ttt{white}, \ttt{red}, \ttt{green}, \ttt{blue}, \ttt{cyan}, \ttt{magenta}, \ttt{yellow} \end{center} More generically, colors in GAMELAN are RGB triplets of numbers (actually, numeric expressions) with values between 0 and 1, enclosed in brackets: \begin{center} \ttt{(\emph{r}, \emph{g}, \emph{b})} \end{center} To draw an object in color, one should apply the construct \ttt{withcolor \emph{color}} to its drawing code. The default color is always black. Thus, this will make a plot drawn in blue: \begin{quote} \begin{footnotesize} \ttt{\$draw\_options = "withcolor blue"} \end{footnotesize} \end{quote} and this will fill the drawing area of some histogram with an RGB color: \begin{quote} \begin{footnotesize} \ttt{\$fill\_options = "withcolor (0.8, 0.7, 1)"} \end{footnotesize} \end{quote} \subsubsection{Dashes} By default, lines are drawn continuously. Optionally, they can be drawn using a \emph{dash pattern}. Predefined dash patterns are \begin{center} \ttt{evenly}, \ttt{withdots}, \ttt{withdashdots} \end{center} Going beyond the predefined patterns, a generic dash pattern has the syntax \begin{center} \ttt{dashpattern (on \emph{l1} off \emph{l2} on} \ldots \ttt{)} \end{center} with an arbitrary repetition of \ttt{on} and \ttt{off} clauses. The numbers \ttt{\emph{l1}}, \ttt{\emph{l2}}, \ldots\ are lengths measured in pt. To apply a dash pattern, the option syntax \ttt{dashed \emph{dash-pattern}} should be used. Options strings can be concatenated. Here is how to draw in color with dashes: \begin{quote} \begin{footnotesize} \ttt{\$draw\_options = "withcolor red dashed evenly"} \end{footnotesize} \end{quote} and this draws error bars consisting of intermittent dashes and dots: \begin{quote} \begin{footnotesize} \ttt{\$err\_options = "dashed (withdashdots scaled 0.5)"} \end{footnotesize} \end{quote} The extra brackets ensure that the scale factor $1/2$ is applied only the dash pattern. \subsubsection{Hatching} Areas (e.g., below a histogram) can be filled with plain colors by the \ttt{withcolor} option. They can also be hatched by stripes, optionally rotated by some angle. The syntax is completely analogous to dashes. There are two predefined \emph{hatch patterns}: \begin{center} \ttt{withstripes}, \ttt{withlines} \end{center} and a generic hatch pattern is written \begin{center} \ttt{hatchpattern (on \emph{w1} off \emph{w2} on} \ldots \ttt{)} \end{center} where the numbers \ttt{\emph{l1}}, \ttt{\emph{l2}}, \ldots\ determine the widths of the stripes, measured in pt. When applying a hatch pattern, the pattern may be rotated by some angle (in degrees) and scaled. This looks like \begin{quote} \begin{footnotesize} \ttt{\$fill\_options = "hatched (withstripes scaled 0.8 rotated 60)"} \end{footnotesize} \end{quote} \subsubsection{Smooth curves} Plot points are normally connected by straight lines. If data are acquired by statistical methods, such as Monte Carlo integration, this is usually recommended. However, if a plot is generated using an analytic mathematical formula, or with sufficient statistics to remove fluctuations, it might be appealing to connect lines by some smooth interpolation. GAMELAN can switch on spline interpolation by the specific drawing option \ttt{linked smoothly}. Note that the results can be surprising if the data points do have sizable fluctuations or sharp kinks. \subsubsection{Error bars} Plots and histograms can be drawn with error bars. For histograms, only vertical error bars are supported, while plot points can have error bars in $x$ and $y$ direction. Error bars are switched on by the \ttt{?draw\_errors} flag. There is an option to draw error bars with ticks: \ttt{withticks} and an alternative option to draw arrow heads: \ttt{witharrows}. These can be used in the \ttt{\$err\_options} string. \subsubsection{Symbols} To draw symbols at plot points (or histogram midpoints), the flag \ttt{?draw\_symbols} has to be switched on. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Fast Detector Simulation and External Analysis} \label{chap:ext_anal} Events from a Monte Carlo event generator are further used in an analysis, most often combined with a detector simulation. Event files from the generator are then classified whether they are (i) parton level (coming from the hard matrix element) for which mostly LHE or \hepmc\ event formats are used, particle level (after parton shower and hadronization) - usually in \hepmc\ or \lcio\ format -, or detector level objects. The latter is the realm of packages like \ROOT\ or specific software from the experimental software frameworks. While detailed experimental studies take into account the best-possible detector description in a so-called full simulation via \geant\ which takes several seconds per event, fast studies are made with parameterized fast detector simulations like in \delphes\ or \texttt{SGV}. In the following, we discuss the options to interface external packages for these purposes or to pipe events from \whizard\ to such external packages. %%%%% \section{Interfacing ROOT} \label{sec:root} One of the most distributed analysis framework is \ROOT~\cite{Brun:1997pa}. In \whizard\ for the moment there is no direct interface to the \ROOT\ framework. The easiest way to write out particle-level events in the \ROOT\ or \ttt{RootTree} format is to use \whizard's interface to \hepmcthree: this modern incarnation of the \hepmc\ format has different writer classes, where the writer class for \ROOT\ and \ttt{RootTree} files is supported by \whizard's \hepmcthree\ interface. For this to work, one only has to make sure that \hepmcthree\ has been built with \ROOT\ support, and that the \whizard\ \ttt{configure} has to detect the \ROOT\ setup on the computing environment. For more details cf. the installation section~\ref{sec:hepmc}. If this has been successfully linked, then \whizard\ can use its own \hepmcthree\ interface to write out \ROOT\ or \ttt{RootTree} formats. This can be done by setting the following options in the \sindarin\ files: \begin{code} $hepmc3_mode = "Root" \end{code} or \begin{code} $hepmc3_mode = "RootTree" \end{code} For more details cf.~the \ROOT\ manual and documentation therein. %%%%% \section{Interfacing RIVET} \label{sec:rivet} \rivet~\cite{Buckley:2010ar} is a very mighty analysis framework which has been developed to make experimental analyses from the LHC experiments available for non-collaboration members. It can be easily used to analyze events and produce high-quality plots for differential distributions and experimental observables. Since version 3~\cite{Bierlich:2019rhm} there is now also a lot of functionality that comes very handy for plotting differential distributions at fixed order in NLO calculations, e.g. negative weights in bins or how to treat imperfectly balanced events and counterevents close to bin boundaries etc. For the moment, \whizard\ does not have a dedicated interface to \rivet, so the preferred method is to write out events, best in the \hepmc\ or \hepmcthree\ format and then read them into \rivet. A more sophisticated interface is foreseen for a future version of \whizard, while there are already development versions where \whizard\ detects all the \rivet\ infrastructure and libraries. But they are not yet used. For more details and practical examples cf.~the \rivet\ manual. This describes in detail especially the \rivet\ installation. A typical error that occurs on systems where no \ROOT\ is installed (cf.~Sec.~\ref{sec:root}) is the one these \ttt{Missing TPython.h} missing headers. Then \rivet\ can nevertheless be easily built without \ROOT\ support by setting \begin{code} --disable-root \end{code} in the \ttt{rivet-bootstrap} script. For an installation of \rivet\ it is favorable to include the location of the \rivet\ \python\ scripts in the \ttt{PYTHONPATH} environment variable. They can be accessed from the \rivet\ configuration script as \begin{code} /rivet-config --pythonpath \end{code} If the \python\ path is not known within the environment variables, then one commonly encounters error like \ttt{No module named rivet} or \ttt{Import error: no module named yoda} when running \rivet\ scripts like e.g. \ttt{yodamerge}. If you use a \rivet\ version older than \ttt{v3.1.1} there is no support for \hepmcthree\ yet, so when using \hepmcthree\ with \whizard\ please use the backwards compatibility mode of \hepmcthree in the \sindarin\ file: \begin{code} $hepmc3_mode = "HepMC2" \end{code} When using MPI parallelized runs of \whizard\ there will a large number of different \ttt{.hepmc} files (also if some grid architecture has produced these event files in junks). Then one has to first merge these event files. Here, we quickly explain how to steer \rivet\ for your own analysis. For more details, please confer the \rivet\ manual. \begin{enumerate} \item The command \begin{code} rivet-mkanalysis \end{code} creates a template \rivet\ plugin for the analysis \ttt{.cc}, a template info file \ttt{.info} amd a template file for the plot generation \ttt{.plot}. Note that this overwrites potentially existing files in this folder with the same name. \item Now, analysis statements like e.g. cuts etc. can be implemented in \ttt{.cc}. For analysis of parton-level events without parton showering, the cuts can be equivalent to those in \whizard, i.e. the generator-level cuts can be as strict as the analysis cuts to avoid generating unnecessary events. If parton showering is applied it is better to have looser generator than analysis cuts to avoid undesired plot artifacts. \item Next, one executes the command (the shared library name might be different e.g. on Darwin or BSD OS) \begin{code} rivet-buildplugin Rivet.so .cc \end{code} This creates an executable \rivet\ analysis library \ttt{Rivet.so}. The custom analysis should now appear in the output of \begin{code} rivet --list \end{code} If this is not the case, the analysis path has to be exported first as \ttt{RIVET\_ANALYSIS\_PATH=\$PWD}. \item We are now ready to use the custom analysis to analyze the \ttt{.hepmc} events by executing the command \begin{code} rivet --pwd --analysis= -o .yoda \end{code} and save the produced histograms of the analysis in the \ttt{.yoda} format. In general the option \ttt{--ignore-beams} for \rivet\ should be used to prevent \rivet\ to stumble over beam remnants. This is also relevant for lepton collider processes with electron PDFs. For a large number of events, event files can become very big. To avoid writing them all on disk, a FIFO for the \ttt{} can be used. \item Different \ttt{yoda} files can now be merged into a single file using the command \begin{code} _full.yoda _01.yoda ... \end{code} This should be applied e.g. for the case of fixed-order NLO differential distributions where Born, real and virtual components have been generated separately. \item Finally, plots can be produced: after listing all the histograms to be plotted in the plot file \ttt{.plot}, the command \begin{code} rivet-mkhtml _full.yoda \end{code} translates the \ttt{.yoda} file into a histogram file in the \ttt{.dat} format. These plots can either be visually enhanced by modifying the \ttt{.plot} file as is described on the webpage \url{https://rivet.hepforge.org/make-plots.html}, or by using any other external plotting tool like e.g. \ttt{Gnuplot} for the \ttt{.dat} files. \end{enumerate} Clearly, this gives only a rough sketch on how to use \rivet\ for an analysis. For more details, please consult the \rivet\ webpage and the \rivet\ manual. %%%%% \vspace{1cm} \section{Fast Detector Simulation with DELPHES} \label{sec:delphes} Fast detector simulation allows relatively quick checks whether experimental analyses actually work in a semi-realistic detector study. There are some older tools for fast simulation like e.g.~\ttt{PGS} (which is no longer actively maintained) and \ttt{SGV} which is default fast simulation for ILC studies. For LHC and general future hadron collider studies, \delphes~\cite{deFavereau:2013fsa} is the most commonly used tool for fast detector simulation. The details on how to obtain and build \delphes\ can be obtained from their webpage, \url{https://cp3.irmp.ucl.ac.be/projects/delphes}. It depends both on~\ttt{Tcl/Tk} as well as \ROOT~(cf. Sec.~\ref{sec:root}. Interfacing any Monte Carlo event generator with a fast detector simulation like \delphes\ is rather trivial: \delphes\ ships with up to five executables \begin{code} DelphesHepMC DelphesLHEF DelphesPythia8 DelphesROOT DelphesSTDHEP \end{code} \ttt{DelphesPythia8} is a direct interface between \pythiaeight\ and \delphes, so detector-level events are directly produced via an API interface between \pythiaeight\ and \delphes. This is the most convenient method which is foreseen for \whizard, however not yet implemented. The other four binaries take input files in the \hepmc, LHE, \stdhep\ and \ROOT\ format, apply a fast detector simulation according to the chosen input file and give a \ROOT\ detector-level event file as output. Executing one of the binaries above without options, the following message will be displayed: \begin{code} ./DelphesHepMC Usage: DelphesHepMC config_file output_file [input_file(s)] config_file - configuration file in Tcl format, output_file - output file in ROOT format, input_file(s) - input file(s) in HepMC format, with no input_file, or when input_file is -, read standard input. \end{code} Using \delphes\ with \hepmc\ event files then works as \begin{code} ./DelphesHepMC cards/delphes_card_ATLAS.tcl output.root input.hepmc \end{code} For \stdhep\ files which are directly by \whizard\ without external packages (only assuming that the XDR C libraries are present on the system), execute \begin{code} ./DelphesSTDHEP cards/delphes_card_ILD.tcl delphes_output.root input.hep \end{code} For LHE files as input, use \begin{code} ./DelphesLHEF cards/delphes_card_CLICdet_Stage1.tcl delphes_output.root input.lhef \end{code} and for \ROOT\ (particle-level) files use \begin{code} ./DelphesROOT cards/delphes_card_CMS.tcl delphes_output.root input.root \end{code} In the \delphes\ cards directory, there is a long list of supported input files for existing and future detectors, a few of which we have displayed here. \delphes\ detector-level output files can then be analyzed with \ROOT\ as described in the \delphes\ manual. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{User Interfaces for WHIZARD} \label{chap:userint} \section{Command Line and \sindarin\ Input Files} \label{sec:cmdline-options} The standard way of using \whizard\ involves a command script written in \sindarin. This script is executed by \whizard\ by mentioning it on the command line: \begin{interaction} whizard script-name.sin \end{interaction} You may specify several script files on the command line; they will be executed consecutively. If there is no script file, \whizard\ will read commands from standard input. Hence, this is equivalent: \begin{interaction} cat script-name.sin | whizard \end{interaction} When executed from the command line, \whizard\ accepts several options. They are given in long form, i.e., they begin with two dashes. Values that belong to options follow the option string, separated either by whitespace or by an equals sign. Hence, \ttt{--prefix /usr} and \ttt{--prefix=/usr} are equivalent. Some options are also available in short form, a single dash with a single letter. Short-form options can be concatenated, i.e., a dash followed by several option letters. The first set of options is intended for normal operation. \begin{description} \item[\ttt{--debug AREA}]: Switch on debug output for \ttt{AREA}. \ttt{AREA} can be one of \whizard's source directories or \ttt{all}. \item[\ttt{--debug2 AREA}]: Switch on more verbose debug output for \ttt{AREA}. \item[\ttt{--single-event}]: Only compute one phase-space point (for debugging). \item[\ttt{--execute COMMANDS}]: Execute \ttt{COMMANDS} as a script before the script file (see below). Short version: \ttt{-e} \item[\ttt{--file CMDFILE}]: Execute commands in \ttt{CMDFILE} before the main script file (see below). Short version: \ttt{-f} \item[\ttt{--help}]: List the available options and exit. Short version: \ttt{-h} \item[\ttt{--interactive}]: Run \whizard\ interactively. See Sec.~\ref{sec:whish}. Short version: \ttt{-i}. \item[\ttt{--library LIB}]: Preload process library \ttt{LIB} (instead of the default \ttt{processes}). Short version: \ttt{-l}. \item[\ttt{--localprefix DIR}]: Search in \ttt{DIR} for local models. Default is \ttt{\$HOME/.whizard}. \item[\ttt{--logfile \ttt{FILE}}]: Write log to \ttt{FILE}. Default is \ttt{whizard.log}. Short version: \ttt{-L}. \item[\ttt{--logging}]: Start logging on startup (default). \item[\ttt{--model MODEL}]: Preload model \ttt{MODEL}. Default is the Standard Model \ttt{SM}. Short version: \ttt{-m}. \item[\ttt{--no-banner}]: Do not display banner at startup. \item[\ttt{--no-library}]: Do not preload a library. \item[\ttt{--no-logfile}]: Do not write a logfile. \item[\ttt{--no-logging}]: Do not issue information into the logfile. \item[\ttt{--no-model}]: Do not preload a specific physics model. \item[\ttt{--no-rebuild}]: Do not force a rebuild. \item[\ttt{--query VARIABLE}]: Display documentation of \ttt{VARIABLE}. Short version: \ttt{-q}. \item[\ttt{--rebuild}]: Do not preload a process library and do all calculations from scratch, even if results exist. This combines all rebuild options. Short version: \ttt{-r}. \item[\ttt{--rebuild-library}]: Rebuild the process library, even if code exists. \item[\ttt{--rebuild-phase-space}]: Rebuild the phase space setup, even if it exists. \item[\ttt{--rebuild-grids}]: Redo the integration, even if previous grids and results exist. \item[\ttt{--rebuild-events}]: Redo event generation, discarding previous event files. \item[\ttt{--show-config}]: Show build-time configuration. \item[\ttt{--version}]: Print version information and exit. Short version: \ttt{-V}. \item[-]: Any further options are interpreted as file names. \end{description} The second set of options refers to the configuration. They are relevant when dealing with a relocated \whizard\ installation, e.g., on a batch systems. \begin{description} \item[\ttt{--prefix DIR}]: Specify the actual location of the \whizard\ installation, including all subdirectories. \item[\ttt{--exec-prefix DIR}]: Specify the actual location of the machine-specific parts of the \whizard\ installation (rarely needed). \item[\ttt{--bindir DIR}]: Specify the actual location of the executables contained in the \whizard\ installation (rarely needed). \item[\ttt{--libdir DIR}]: Specify the actual location of the libraries contained in the \whizard\ installation (rarely needed). \item[\ttt{--includedir DIR}]: Specify the actual location of the include files contained in the \whizard\ installation (rarely needed). \item[\ttt{--datarootdir DIR}]: Specify the actual location of the data files contained in the \whizard\ installation (rarely needed). \item[\ttt{--libtool LOCAL\_LIBTOOL}]: Specify the actual location and name of the \ttt{libtool} script that should be used by \whizard. \item[\ttt{--lhapdfdir DIR}]: Specify the actual location and of the \lhapdf\ installation that should be used by \whizard. \end{description} The \ttt{--execute} and \ttt{--file} options allow for fine-tuning the command flow. The \whizard\ main program will concatenate all commands given in \ttt{--execute} commands together with all commands contained in \ttt{--file} options, in the order they are encountered, as a contiguous command stream that is executed \emph{before} the main script (in the example above, \ttt{script-name.sin}). Regarding the \ttt{--execute} option, commands that contain blanks must be enclosed in matching single- or double-quote characters since the individual tokens would otherwise be intepreted as separate option strings. Unfortunately, a Unix/Linux shell interpreter will strip quotes before handing the command string over to the program. In that situation, the quote-characters must be quoted themselves, or the string must be enclosed in quotes twice. Either version should work as a command line interpreted by the shell: \begin{interaction} whizard --execute \'int my_flag = 1\' script-name.sin whizard --execute "'int my_flag = 1'" script-name.sin \end{interaction} \section{WHISH -- The \whizard\ Shell/Interactive mode} \label{sec:whish} \whizard\ can be also run in the interactive mode using its own shell environment. This is called the \whizard\ Shell (WHISH). For this purpose, one starts with the command \begin{interaction} /home/user$ whizard --interactive \end{interaction} or \begin{interaction} /home/user$ whizard -i \end{interaction} \whizard\ will preload the Standard Model and display a command prompt: \begin{interaction} whish? \end{interaction} You now can enter one or more \sindarin\ commands, just as if they were contained in a script file. The commands are compiled and executed after you hit the ENTER key. When done, you get a new prompt. The WHISH can be closed by the \ttt{quit} command: \begin{verbatim} whish? quit \end{verbatim} Obviously, each input must be self-contained: commands must be complete, and conditionals or scans must be closed on the same line. If \whizard\ is run without options and without a script file, it also reads commands interactively, from standard input. The difference is that in this case, interactive input is multi-line, terminated by \ttt{Ctrl-D}, the script is then compiled and executed as a whole, and \whizard\ terminates. In WHISH mode, each input line is compiled and executed individually. Furthermore, fatal errors are masked, so in case of error the program does not terminate but returns to the WHISH command line. (The attempt to recover may fail in some circumstances, however.) \section{Graphical user interface} \emph{This is still experimental.} \whizard\ ships with a graphical interface that can be steered in a browser of your choice. It is located in \ttt{share/gui}. To use it, you have to run \ttt{npm install} (which will install javascript libraries locally in that folder) and \ttt{npm start} (which will start a local web server on your machine) in that folder. More technical details and how to get \ttt{npm} is discussed in \ttt{share/gui/README.md}. When it is running, you can access the GUI by entering \ttt{localhost:3000} as address in your browser. The GUI is separated into different tabs for basic settings, integration, simulation, cuts, scans, NLO and beams. You can select and enter what you are interested in and the GUI will produce a \sindarin\ file. You can use the GUI to run WHIZARD with that \sindarin\ or just produce it with the GUI and then tweak it further with an editor. In case you run it in the GUI, the log file will be updated in the browser as it is produced. Any \sindarin\ features that are not supported by the GUI can be added directly as "Additional Code". \section{WHIZARD as a library} \emph{This is planned, but not implemented yet.} %%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Examples} \label{chap:examples} In this chapter we discuss the running and steering of \whizard\ with the help of several examples. These examples can be found in the \ttt{share/examples} directory of your installation. All of these examples are also shown on the \whizard\ Wiki page: \url{https://whizard.hepforge.org/trac/wiki}. \section{$Z$ lineshape at LEP I} By this example, we demonstrate how a scan over collision energies works, using as example the measurement of the $Z$ lineshape at LEP I in 1989. The \sindarin\ script for this example, \ttt{Z-lineshape.sin} can be found in the \ttt{share/examples} folder of the \whizard\ installation. We first use the Standard model as physics model: \begin{code} model = SM \end{code} Aliases for electron, muon and their antiparticles as leptons and those including the photon as particles in general are introduced: \begin{code} alias lep = e1:E1:e2:E2 alias prt = lep:A \end{code} Next, the two processes are defined, \eemm, and the same with an explicit QED photon: $e^+e^- \to \mu^+\mu^-\gamma$, \begin{code} process bornproc = e1, E1 => e2, E2 process rc = e1, E1 => e2, E2, A compile \end{code} and the processes are compiled. Now, we define some very loose cuts to avoid singular regions in phase space, name an infrared cutoff of 100 MeV for all particles, a cut on the angular separation from the beam axis and a di-particle invariant mass cut which regularizes collinear singularities: \begin{code} cuts = all E >= 100 MeV [prt] and all abs (cos(Theta)) <= 0.99 [prt] and all M2 >= (1 GeV)^2 [prt, prt] \end{code} For the graphical analysis, we give a description and labels for the $x$- and $y$-axis in \LaTeX\ syntax: \begin{code} $description = "A WHIZARD Example" $x_label = "$\sqrt{s}$/GeV" $y_label = "$\sigma(s)$/pb" \end{code} We define two plots for the lineshape of the \eemm\ process between 88 and 95 GeV, \begin{code} $title = "The Z Lineshape in $e^+e^-\to\mu^+\mu^-$" plot lineshape_born { x_min = 88 GeV x_max = 95 GeV } \end{code} and the same for the radiative process with an additional photon: \begin{code} $title = "The Z Lineshape in $e^+e^-\to\mu^+\mu^-\gamma$" plot lineshape_rc { x_min = 88 GeV x_max = 95 GeV } \end{code} %$ The next part of the \sindarin\ file actually performs the scan: \begin{code} scan sqrts = ((88.0 GeV => 90.0 GeV /+ 0.5 GeV), (90.1 GeV => 91.9 GeV /+ 0.1 GeV), (92.0 GeV => 95.0 GeV /+ 0.5 GeV)) { beams = e1, E1 integrate (bornproc) { iterations = 2:1000:"gw", 1:2000 } record lineshape_born (sqrts, integral (bornproc) / 1000) integrate (rc) { iterations = 5:3000:"gw", 2:5000 } record lineshape_rc (sqrts, integral (rc) / 1000) } \end{code} So from 88 to 90 GeV, we go in 0.5 GeV steps, then from 90 to 92 GeV in tenth of GeV, and then up to 95 GeV again in half a GeV steps. The partonic beam definition is redundant. Then, the born process is integrated, using a certain specification of calls with adaptation of grids and weights, as well as a final pass. The lineshape of the Born process is defined as a \ttt{record} statement, generating tuples of $\sqrt{s}$ and the Born cross section (converted from femtobarn to picobarn). The same happens for the radiative $2\to3$ process with a bit more iterations because of the complexity, and the definition of the corresponding lineshape record. If you run the \sindarin\ script, you will find an output like: \begin{scriptsize} \begin{Verbatim}[frame=single] | Process library 'default_lib': loading | Process library 'default_lib': ... success. $description = "A WHIZARD Example" $x_label = "$\sqrt{s}$/GeV" $y_label = "$\sigma(s)$/pb" $title = "The Z Lineshape in $e^+e^-\to\mu^+\mu^-$" x_min = 8.800000000000E+01 x_max = 9.500000000000E+01 $title = "The Z Lineshape in $e^+e^-\to\mu^+\mu^-\gamma$" x_min = 8.800000000000E+01 x_max = 9.500000000000E+01 sqrts = 8.800000000000E+01 | RNG: Initializing TAO random-number generator | RNG: Setting seed for random-number generator to 10713 | Initializing integration for process bornproc: | ------------------------------------------------------------------------ | Process [scattering]: 'bornproc' | Library name = 'default_lib' | Process index = 1 | Process components: | 1: 'bornproc_i1': e-, e+ => mu-, mu+ [omega] | ------------------------------------------------------------------------ | Beam structure: e-, e+ | Beam data (collision): | e- (mass = 5.1099700E-04 GeV) | e+ (mass = 5.1099700E-04 GeV) | sqrts = 8.800000000000E+01 GeV | Phase space: generating configuration ... | Phase space: ... success. | Phase space: writing configuration file 'bornproc_i1.phs' | Phase space: 1 channels, 2 dimensions | Phase space: found 1 channel, collected in 1 grove. | Phase space: Using 1 equivalence between channels. | Phase space: wood | Applying user-defined cuts. | OpenMP: Using 8 threads | Starting integration for process 'bornproc' | Integrate: iterations = 2:1000:"gw", 1:2000 | Integrator: 1 chains, 1 channels, 2 dimensions | Integrator: Using VAMP channel equivalences | Integrator: 1000 initial calls, 20 bins, stratified = T | Integrator: VAMP |=============================================================================| | It Calls Integral[fb] Error[fb] Err[%] Acc Eff[%] Chi2 N[It] | |=============================================================================| 1 800 2.5881432E+05 1.85E+03 0.72 0.20* 48.97 2 800 2.6368495E+05 9.25E+02 0.35 0.10* 28.32 |-----------------------------------------------------------------------------| 2 1600 2.6271122E+05 8.28E+02 0.32 0.13 28.32 5.54 2 |-----------------------------------------------------------------------------| 3 1988 2.6313791E+05 5.38E+02 0.20 0.09* 35.09 |-----------------------------------------------------------------------------| 3 1988 2.6313791E+05 5.38E+02 0.20 0.09 35.09 |=============================================================================| | Time estimate for generating 10000 events: 0d:00h:00m:05s [.......] \end{Verbatim} \end{scriptsize} %$ and then the integrations for the other energy points of the scan will \begin{figure} \centering \includegraphics[width=.47\textwidth]{Z-lineshape_1} \includegraphics[width=.47\textwidth]{Z-lineshape_2} \caption{\label{fig:zlineshape} $Z$ lineshape in the dimuon final state (left), and with an additional photon (right)} \end{figure} follow, and finally the same is done for the radiative process as well. At the end of the \sindarin\ script we compile the graphical \whizard\ analysis and direct the data for the plots into the file \ttt{Z-lineshape.dat}: \begin{code} compile_analysis { $out_file = "Z-lineshape.dat" } \end{code} %$ In this case there is no event generation, but simply the cross section values for the scan are dumped into a data file: \begin{scriptsize} \begin{Verbatim}[frame=single] $out_file = "Z-lineshape.dat" | Opening file 'Z-lineshape.dat' for output | Writing analysis data to file 'Z-lineshape.dat' | Closing file 'Z-lineshape.dat' for output | Compiling analysis results display in 'Z-lineshape.tex' \end{Verbatim} \end{scriptsize} %$ Fig.~\ref{fig:zlineshape} shows the graphical \whizard\ output of the $Z$ lineshape in the dimuon final state from the scan on the left, and the same for the radiative process with an additional photon on the right. %%%%%%%%%%%%%%% \section{$W$ pairs at LEP II} This example which can be found as file \ttt{LEP\_cc10.sin} in the \ttt{share/examples} directory, shows $W$ pair production in the semileptonic mode at LEP II with its final energy of 209 GeV. Because there are ten contributing Feynman diagrams, the process has been dubbed CC10: charged current process with 10 diagrams. We work within the Standard Model: \begin{code} model = SM \end{code} Then the process is defined, where no flavor summation is done for the jets here: \begin{code} process cc10 = e1, E1 => e2, N2, u, D \end{code} A compilation statement is optional, and then we set the muon mass to zero: \begin{code} mmu = 0 \end{code} The final LEP center-of-momentum energy of 209 GeV is set: \begin{code} sqrts = 209 GeV \end{code} Then, we integrate the process: \begin{code} integrate (cc10) { iterations = 12:20000 } \end{code} Running the \sindarin\ file up to here, results in the output: \begin{scriptsize} \begin{Verbatim}[frame=single] | Process library 'default_lib': loading | Process library 'default_lib': ... success. SM.mmu = 0.000000000000E+00 sqrts = 2.090000000000E+02 | RNG: Initializing TAO random-number generator | RNG: Setting seed for random-number generator to 31255 | Initializing integration for process cc10: | ------------------------------------------------------------------------ | Process [scattering]: 'cc10' | Library name = 'default_lib' | Process index = 1 | Process components: | 1: 'cc10_i1': e-, e+ => mu-, numubar, u, dbar [omega] | ------------------------------------------------------------------------ | Beam structure: [any particles] | Beam data (collision): | e- (mass = 5.1099700E-04 GeV) | e+ (mass = 5.1099700E-04 GeV) | sqrts = 2.090000000000E+02 GeV | Phase space: generating configuration ... | Phase space: ... success. | Phase space: writing configuration file 'cc10_i1.phs' | Phase space: 25 channels, 8 dimensions | Phase space: found 25 channels, collected in 7 groves. | Phase space: Using 25 equivalences between channels. | Phase space: wood Warning: No cuts have been defined. | OpenMP: Using 8 threads | Starting integration for process 'cc10' | Integrate: iterations = 12:20000 | Integrator: 7 chains, 25 channels, 8 dimensions | Integrator: Using VAMP channel equivalences | Integrator: 20000 initial calls, 20 bins, stratified = T | Integrator: VAMP |=============================================================================| | It Calls Integral[fb] Error[fb] Err[%] Acc Eff[%] Chi2 N[It] | |=============================================================================| 1 19975 6.4714908E+02 2.17E+01 3.36 4.75* 2.33 2 19975 7.3251876E+02 2.45E+01 3.34 4.72* 2.17 3 19975 6.7746497E+02 2.39E+01 3.52 4.98 1.77 4 19975 7.2075198E+02 2.41E+01 3.34 4.72* 1.76 5 19975 6.5976152E+02 2.26E+01 3.43 4.84 1.46 6 19975 6.6633310E+02 2.26E+01 3.39 4.79* 1.43 7 19975 6.7539385E+02 2.29E+01 3.40 4.80 1.43 8 19975 6.6754027E+02 2.11E+01 3.15 4.46* 1.41 9 19975 7.3975817E+02 2.52E+01 3.40 4.81 1.53 10 19975 7.2284275E+02 2.39E+01 3.31 4.68* 1.47 11 19975 6.5476917E+02 2.18E+01 3.33 4.71 1.33 12 19975 7.2963866E+02 2.54E+01 3.48 4.92 1.46 |-----------------------------------------------------------------------------| 12 239700 6.8779583E+02 6.69E+00 0.97 4.76 1.46 2.18 12 |=============================================================================| | Time estimate for generating 10000 events: 0d:00h:01m:16s | Creating integration history display cc10-history.ps and cc10-history.pdf \end{Verbatim} \end{scriptsize} \begin{figure} \centering \includegraphics[width=.6\textwidth]{cc10_1} \\\vspace{5mm} \includegraphics[width=.6\textwidth]{cc10_2} \caption{Histogram of the dijet invariant mass from the CC10 $W$ pair production at LEP II, peaking around the $W$ mass (upper plot), and of the muon energy (lower plot).} \label{fig:cc10} \end{figure} The next step is event generation. In order to get smooth distributions, we set the integrated luminosity to 10 fb${}^{-1}$. (Note that LEP II in its final year 2000 had an integrated luminosity of roughly 0.2 fb${}^{-1}$.) \begin{code} luminosity = 10 \end{code} With the simulated events corresponding to those 10 inverse femtobarn we want to perform a \whizard\ analysis: we are going to plot the dijet invariant mass, as well as the energy of the outgoing muon. For the plot of the analysis, we define a description and label the $y$ axis: \begin{code} $description = "A WHIZARD Example. Charged current CC10 process from LEP 2." $y_label = "$N_{\textrm{events}}$" \end{code} We also use \LaTeX-syntax for the title of the first plot and the $x$-label, and then define the histogram of the dijet invariant mass in the range around the $W$ mass from 70 to 90 GeV in steps of half a GeV: \begin{code} $title = "Di-jet invariant mass $M_{jj}$ in $e^+e^- \to \mu^- \bar\nu_\mu u \bar d$" $x_label = "$M_{jj}$/GeV" histogram m_jets (70 GeV, 90 GeV, 0.5 GeV) \end{code} And we do the same for the second histogram of the muon energy: \begin{code} $title = "Muon energy $E_\mu$ in $e^+e^- \to \mu^- \bar\nu_\mu u \bar d$" $x_label = "$E_\mu$/GeV" histogram e_muon (0 GeV, 209 GeV, 4) \end{code} Now, we define the \ttt{analysis} consisting of two \ttt{record} statements initializing the two observables that are plotted as histograms: \begin{code} analysis = record m_jets (eval M [u,D]); record e_muon (eval E [e2]) \end{code} At the very end, we perform the event generation \begin{code} simulate (cc10) \end{code} and finally the writing and compilation of the analysis in a named data file: \begin{code} compile_analysis { $out_file = "cc10.dat" } \end{code} This event generation part screen output looks like this: \begin{scriptsize} \begin{Verbatim}[frame=single] luminosity = 1.000000000000E+01 $description = "A WHIZARD Example. Charged current CC10 process from LEP 2." $y_label = "$N_{\textrm{events}}$" $title = "Di-jet invariant mass $M_{jj}$ in $e^+e^- \to \mu^- \bar\nu_\mu u \bar d$" $x_label = "$M_{jj}$/GeV" $title = "Muon energy $E_\mu$ in $e^+e^- \to \mu^- \bar\nu_\mu u \bar d$" $x_label = "$E_\mu$/GeV" | Starting simulation for process 'cc10' | Simulate: using integration grids from file 'cc10_m1.vg' | RNG: Initializing TAO random-number generator | RNG: Setting seed for random-number generator to 9910 | OpenMP: Using 8 threads | Simulation: using n_events as computed from luminosity value | Events: writing to raw file 'cc10.evx' | Events: generating 6830 unweighted, unpolarized events ... | Events: event normalization mode '1' | ... event sample complete. Warning: Encountered events with excess weight: 39 events ( 0.571 %) | Maximum excess weight = 1.027E+00 | Average excess weight = 6.764E-04 | Events: closing raw file 'cc10.evx' $out_file = "cc10.dat" | Opening file 'cc10.dat' for output | Writing analysis data to file 'cc10.dat' | Closing file 'cc10.dat' for output | Compiling analysis results display in 'cc10.tex' \end{Verbatim} \end{scriptsize} %$ Then comes the \LaTeX\ output of the compilation of the graphical analysis. Fig.~\ref{fig:cc10} shows the two histograms as the are produced as result of the \whizard\ internal graphical analysis. %%%%%%%%%%%%%%% \section{Higgs search at LEP II} This example can be found under the name \ttt{LEP\_higgs.sin} in the \ttt{share/doc} folder of \whizard. It displays different search channels for a very light would-be SM Higgs boson of mass 115 GeV at the LEP II machine at its highest energy it finally achieved, 209 GeV. First, we use the Standard Model: \begin{code} model = SM \end{code} Then, we define aliases for neutrinos, antineutrinos, light quarks and light anti-quarks: \begin{code} alias n = n1:n2:n3 alias N = N1:N2:N3 alias q = u:d:s:c alias Q = U:D:S:C \end{code} Now, we define the signal process, which is Higgsstrahlung, \begin{code} process zh = e1, E1 => Z, h \end{code} the missing-energy channel, \begin{code} process nnbb = e1, E1 => n, N, b, B \end{code} and finally the 4-jet as well as dilepton-dijet channels: \begin{code} process qqbb = e1, E1 => q, Q, b, B process bbbb = e1, E1 => b, B, b, B process eebb = e1, E1 => e1, E1, b, B process qqtt = e1, E1 => q, Q, e3, E3 process bbtt = e1, E1 => b, B, e3, E3 compile \end{code} and we compile the code. We set the center-of-momentum energy to the highest energy LEP II achieved, \begin{code} sqrts = 209 GeV \end{code} For the Higgs boson, we take the values of a would-be SM Higgs boson with mass of 115 GeV, which would have had a width of a bit more than 3 MeV: \begin{code} mH = 115 GeV wH = 3.228 MeV \end{code} We take a running $b$ quark mass to take into account NLO corrections to the $Hb\bar b$ vertex, while all other fermions are massless: \begin{code} mb = 2.9 GeV me = 0 ms = 0 mc = 0 \end{code} \begin{scriptsize} \begin{Verbatim}[frame=single] | Process library 'default_lib': loading | Process library 'default_lib': ... success. sqrts = 2.090000000000E+02 SM.mH = 1.150000000000E+02 SM.wH = 3.228000000000E-03 SM.mb = 2.900000000000E+00 SM.me = 0.000000000000E+00 SM.ms = 0.000000000000E+00 SM.mc = 0.000000000000E+00 \end{Verbatim} \end{scriptsize} To avoid soft-collinear singular phase-space regions, we apply an invariant mass cut on light quark pairs: \begin{code} cuts = all M >= 10 GeV [q,Q] \end{code} Now, we integrate the signal process as well as the combined signal and background processes: \begin{code} integrate (zh) { iterations = 5:5000} integrate(nnbb,qqbb,bbbb,eebb,qqtt,bbtt) { iterations = 12:20000 } \end{code} \begin{scriptsize} \begin{Verbatim}[frame=single] | RNG: Initializing TAO random-number generator | RNG: Setting seed for random-number generator to 21791 | Initializing integration for process zh: | ------------------------------------------------------------------------ | Process [scattering]: 'zh' | Library name = 'default_lib' | Process index = 1 | Process components: | 1: 'zh_i1': e-, e+ => Z, H [omega] | ------------------------------------------------------------------------ | Beam structure: [any particles] | Beam data (collision): | e- (mass = 0.0000000E+00 GeV) | e+ (mass = 0.0000000E+00 GeV) | sqrts = 2.090000000000E+02 GeV | Phase space: generating configuration ... | Phase space: ... success. | Phase space: writing configuration file 'zh_i1.phs' | Phase space: 1 channels, 2 dimensions | Phase space: found 1 channel, collected in 1 grove. | Phase space: Using 1 equivalence between channels. | Phase space: wood | Applying user-defined cuts. | OpenMP: Using 8 threads | Starting integration for process 'zh' | Integrate: iterations = 5:5000 | Integrator: 1 chains, 1 channels, 2 dimensions | Integrator: Using VAMP channel equivalences | Integrator: 5000 initial calls, 20 bins, stratified = T | Integrator: VAMP |=============================================================================| | It Calls Integral[fb] Error[fb] Err[%] Acc Eff[%] Chi2 N[It] | |=============================================================================| 1 4608 1.6114109E+02 5.52E-04 0.00 0.00* 99.43 2 4608 1.6114220E+02 5.59E-04 0.00 0.00 99.43 3 4608 1.6114103E+02 5.77E-04 0.00 0.00 99.43 4 4608 1.6114111E+02 5.74E-04 0.00 0.00* 99.43 5 4608 1.6114103E+02 5.66E-04 0.00 0.00* 99.43 |-----------------------------------------------------------------------------| 5 23040 1.6114130E+02 2.53E-04 0.00 0.00 99.43 0.82 5 |=============================================================================| [.....] \end{Verbatim} \end{scriptsize} \begin{figure} \centering \includegraphics[width=.48\textwidth]{lep_higgs_1} \includegraphics[width=.48\textwidth]{lep_higgs_2} \\\vspace{5mm} \includegraphics[width=.48\textwidth]{lep_higgs_3} \caption{Upper line: final state $bb + E_{miss}$, histogram of the invisible mass distribution (left), and of the di-$b$ distribution (right). Lower plot: light dijet distribution in the $bbjj$ final state.} \label{fig:lep_higgs} \end{figure} Because the other integrations look rather similar, we refrain from displaying them here, too. As a next step, we define titles, descriptions and axis labels for the histograms we want to generate. There are two of them, one os the invisible mass distribution, the other is the di-$b$-jet invariant mass. Both histograms are taking values between 70 and 130 GeV with bin widths of half a GeV: \begin{code} $description = "A WHIZARD Example. Light Higgs search at LEP. A 115 GeV pseudo-Higgs has been added. Luminosity enlarged by two orders of magnitude." $y_label = "$N_{\textrm{events}}$" $title = "Invisible mass distribution in $e^+e^- \to \nu\bar\nu b \bar b$" $x_label = "$M_{\nu\nu}$/GeV" histogram m_invisible (70 GeV, 130 GeV, 0.5 GeV) $title = "$bb$ invariant mass distribution in $e^+e^- \to \nu\bar\nu b \bar b$" $x_label = "$M_{b\bar b}$/GeV" histogram m_bb (70 GeV, 130 GeV, 0.5 GeV) \end{code} The analysis is initialized by defining the two records for the invisible mass and the invariant mass of the two $b$ jets: \begin{code} analysis = record m_invisible (eval M [n,N]); record m_bb (eval M [b,B]) \end{code} In order to have enough statistics, we enlarge the LEP integrated luminosity at 209 GeV by more than two orders of magnitude: \begin{code} luminosity = 10 \end{code} We start event generation by simulating the process with two $b$ jets and two neutrinos in the final state: \begin{code} simulate (nnbb) \end{code} As a third histogram, we define the dijet invariant mass of two light jets: \begin{code} $title = "Dijet invariant mass distribution in $e^+e^- \to q \bar q b \bar b$" $x_label = "$M_{q\bar q}$/GeV" histogram m_jj (70 GeV, 130 GeV, 0.5 GeV) \end{code} Then we simulate the 4-jet process defining the light-dijet distribution as a local record: \begin{code} simulate (qqbb) { analysis = record m_jj (eval M / 1 GeV [combine [q,Q]]) } \end{code} Finally, we compile the analysis, \begin{code} compile_analysis { $out_file = "lep_higgs.dat" } \end{code} \begin{scriptsize} \begin{Verbatim}[frame=single] | Starting simulation for process 'nnbb' | Simulate: using integration grids from file 'nnbb_m1.vg' | RNG: Initializing TAO random-number generator | RNG: Setting seed for random-number generator to 21798 | OpenMP: Using 8 threads | Simulation: using n_events as computed from luminosity value | Events: writing to raw file 'nnbb.evx' | Events: generating 1070 unweighted, unpolarized events ... | Events: event normalization mode '1' | ... event sample complete. Warning: Encountered events with excess weight: 207 events ( 19.346 %) | Maximum excess weight = 1.534E+00 | Average excess weight = 4.909E-02 | Events: closing raw file 'nnbb.evx' $title = "Dijet invariant mass distribution in $e^+e^- \to q \bar q b \bar b$" $x_label = "$M_{q\bar q}$/GeV" | Starting simulation for process 'qqbb' | Simulate: using integration grids from file 'qqbb_m1.vg' | RNG: Initializing TAO random-number generator | RNG: Setting seed for random-number generator to 21799 | OpenMP: Using 8 threads | Simulation: using n_events as computed from luminosity value | Events: writing to raw file 'qqbb.evx' | Events: generating 4607 unweighted, unpolarized events ... | Events: event normalization mode '1' | ... event sample complete. Warning: Encountered events with excess weight: 112 events ( 2.431 %) | Maximum excess weight = 8.875E-01 | Average excess weight = 4.030E-03 | Events: closing raw file 'qqbb.evx' $out_file = "lep_higgs.dat" | Opening file 'lep_higgs.dat' for output | Writing analysis data to file 'lep_higgs.dat' | Closing file 'lep_higgs.dat' for output | Compiling analysis results display in 'lep_higgs.tex' \end{Verbatim} \end{scriptsize} The graphical analysis of the events generated by \whizard\ are shown in Fig.~\ref{fig:lep_higgs}. In the upper left, the invisible mass distribution in the $b\bar b + E_{miss}$ state is shown, peaking around the $Z$ mass. The upper right shows the $M(b\bar b)$ distribution in the same final state, while the lower plot has the invariant mass distribution of the two non-$b$-tagged (light) jets in the $bbjj$ final state. The latter shows only the $Z$ peak, while the former exhibits the narrow would-be 115 GeV Higgs state. %%%%%%%%%%%%%%% \section{Deep Inelastic Scattering at HERA} %%%%%%%%%%%%%%% \section{$W$ endpoint at LHC} %%%%%%%%%%%%%%% \section{SUSY Cascades at LHC} %%%%%%%%%%%%%%% \section{Polarized $WW$ at ILC} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Technical details -- Advanced Spells} \label{chap:tuning} \section{Efficiency and tuning} Since massless fermions and vector bosons (or almost massless states in a certain approximation) lead to restrictive selection rules for allowed helicity combinations in the initial and final state. To make use of this fact for the efficiency of the \whizard\ program, we are applying some sort of heuristics: \whizard\ dices events into all combinatorially possible helicity configuration during a warm-up phase. The user can specify a helicity threshold which sets the number of zeros \whizard\ should have got back from a specific helicity combination in order to ignore that combination from now on. By that mechanism, typically half up to more than three quarters of all helicity combinations are discarded (and hence the corresponding number of matrix element calls). This reduces calculation time up to more than one order of magnitude. \whizard\ shows at the end of the integration those helicity combinations which finally contributed to the process matrix element. Note that this list -- due to the numerical heuristics -- might very well depend on the number of calls for the matrix elements per iteration, and also on the corresponding random number seed. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{New External Physics Models} \label{chap:extmodels} It is never possible to include all incarnations of physics models that can be described by the maybe weirdest form of a quantum field theory in a tailor-made implementation within a program like \whizard. Users clearly want to be able to use their own special type of model; in order to do so there are external tools to translate models described by their field content and Lagrangian densities into Feynman rules and make them available in an event generator like \whizard. In this chapter, we describe the interfaces to two such external models, \sarah\ and \FeynRules. The \FeynRules\ interface had been started already for the legacy version \whizard\ttt{1} (where it had to be downloaded from \url{https://whizard.hepforge.org} as a separate package), but for the \whizard\ttt{two} release series it has been included in the \FeynRules\ package (from their version v1.6.0 on). Note that there was a regression for the usage of external models (from either \sarah\ or \FeynRules) in the first release of series v2.2, v2.2.0. This has been fixed in all upcoming versions. Besides using \sarah\ or \FeynRules\ via their interfaces, there is now a much easier way to let those programs output model files in the "Universal FeynRules Output" (or \UFO). This option does not have any principle limitations for models, and also does not rely on the never truly constant interfaces between two different tools. Their usage is described in Sec.~\ref{sec:ufo}. %%%%%%%%%%%%%%% \section{New physics models via \sarah} \sarah~\cite{Staub:2008uz,Staub:2009bi,Staub:2010jh,Staub:2012pb,Staub:2013tta} is a \Mathematica~\cite{mathematica} package which derives for a given model the minimum conditions of the vacuum, the mass matrices, and vertices at tree-level as well as expressions for the one-loop corrections for all masses and the full two-loop renormalization group equations (RGEs). The vertices can be exported to be used with \whizard/\oMega. All other information can be used to generate \fortran\ source code for the RGE solution tool and spectrum generator \spheno~\cite{Porod:2003um,Porod:2011nf} to get a spectrum generator for any model. The advantage is that \spheno\ calculates a consistent set of parameters (couplings, masses, rotation matrices, decay widths) which can be used as input for \whizard. \sarah\ and \spheno\ can be also downloaded from the \ttt{HepForge} server: \begin{center} \url{https://sarah.hepforge.org} \\ \url{https://spheno.hepforge.org} \end{center} \subsection{\whizard/\oMega\ model files from \sarah} \subsubsection{Generating the model files} Here we are giving only the information relevant to generate models for \whizard. For more details about the installation of \sarah\ and an exhaustion documentation about its usage, confer the \sarah\ manual. To generate the model files for \whizard/\oMega\ with \sarah, a new \Mathematica\ session has to be started. \sarah\ is loaded via \begin{code} </Output/TMSSM/EWSB/WHIZARD_Omega/ \end{code} and run % \begin{code} ./configure make install \end{code} % By default, the last command installs the compiled model into \verb".whizard" in current user's home directory where it is automatically picked up by \whizard. Alternative installation paths can be specified using the \verb"--prefix" option to \whizard. % \begin{code} ./configure --prefix=/path/to/installation/prefix \end{code} % If the files are installed into the \whizard\ installation prefix, the program will also pick them up automatically, while {\whizard}'s \verb"--localprefix" option must be used to communicate any other choice to \whizard. In case \whizard\ is not available in the binary search path, the \verb"WO_CONFIG" environment variable can be used to point \verb"configure" to the binaries % \begin{code} ./configure WO_CONFIG=/path/to/whizard/binaries \end{code} % More information on the available options and their syntax can be obtained with the \verb"--help" option. After the model is compiled it can be used in \whizard\ as \begin{code} model = tmssm_sarah \end{code} \subsection{Linking \spheno\ and \whizard} As mentioned above, the user can also use \spheno\ to generate spectra for its models. This is done by means of \fortran\ code for \spheno, exported from \sarah. To do so, the user has to apply the command \verb"MakeSPheno[]". For more details about the options of this command and how to compile and use the \spheno\ output, we refer to the \sarah\ manual. \\ As soon as the \spheno\ version for the given model is ready it can be used to generate files with all necessary numerical values for the parameters in a format which is understood by \whizard. For this purpose, the corresponding flag in the Les Houches input file of \spheno\ has to be turned on: \begin{code} Block SPhenoInput # SPheno specific input ... 75 1 # Write WHIZARD files \end{code} Afterwards, \spheno\ returns not only the spectrum file in the standard SUSY Les Houches accord (SLHA) format (for more details about the SLHA and the \whizard\ SLHA interface cf. Sec.~\ref{sec:slha}), but also an additional file called \verb"WHIZARD.par.TMSSM" for our example. This file can be used in the \sindarin\ input file via \begin{code} include ("WHIZARD.par.TMSSM") \end{code} %%%%% \subsection{BSM Toolbox} A convenient way to install \sarah\ together with \whizard, \spheno\ and some other codes are the \ttt{BSM Toolbox} scripts \footnote{Those script have been published under the name SUSY Toolbox but \sarah\ is with version 4 no longer restricted to SUSY models}~\cite{Staub:2011dp}. These scripts are available at \begin{center} \url{https://sarah.hepforge.org/Toolbox.html} \end{center} The \ttt{Toolbox} provides two scripts. First, the \verb"configure" script is used via \begin{code} toolbox-src-dir> mkdir build toolbox-src-dir> cd build toolbox-src-dir> ../configure \end{code} % The \verb"configure" script checks for the requirements of the different packages and downloads all codes. All downloaded archives will be placed in the \verb"tarballs" subdirectory of the directory containing the \verb"configure" script. Command line options can be used to disable specific packages and to point the script to custom locations of compilers and of the \Mathematica\ kernel; a full list of those can be obtained by calling \verb"configure" with the \verb"--help" option. After \verb"configure" finishes successfully, \verb"make" can be called to build all configured packages % \begin{code} toolbox-build-dir> make \end{code} \verb"configure" creates also the second script which automates the implementation of a new model into all packages. The \verb"butler" script takes as argument the name of the model in \sarah, e.g. \begin{code} > ./butler TMSSM \end{code} The \verb"butler" script runs \sarah\ to get the output in the same form as the \whizard/\oMega\ model files and the code for \spheno. Afterwards, it installs the model in all packages and compiles the new \whizard/\oMega\ model files as well as the new \spheno\ module. %%%%% \newpage \section{New physics models via \FeynRules} In this section, we present the interface between the external tool \FeynRules\ \cite{Christensen:2008py,Christensen:2009jx,Duhr:2011se} and \whizard. \FeynRules\ is a \Mathematica~\cite{mathematica} package that allows to derive Feynman rules from any perturbative quantum field theory-based Lagrangian in an automated way. It can be downloaded from \begin{center} \url{http://feynrules.irmp.ucl.ac.be/} \end{center} The input provided by the user is threefold and consists of the Lagrangian defining the model, together with the definitions of all the particles and parameters that appear in the model. Once this information is provided, \FeynRules\ can perform basic checks on the sanity of the implementation (e.g. hermiticity, normalization of the quadratic terms), and finally computes all the interaction vertices associated with the model and store them in an internal format for later processing. After the Feynman rules have been obtained, \FeynRules\ can export the interaction vertices to \whizard\ via a dedicated interface~\cite{Christensen:2010wz}. The interface checks whether all the vertices are compliant with the structures supported by \whizard's matrix element generator \oMega, and discard them in the case they are not supported. The output of the interface consists of a set of files organized in a single directory which can be injected into \whizard/\oMega\ and used as any other built-in models. Together with the model files, a framework is created which allows to communicate the new models to \whizard\ in a well defined way, after which step the model can be used exactly like the built-in ones. This specifically means that the user is not required to manually modify the code of \whizard/\oMega, the models created by the interface can be used directly without any further user intervention. We first describe the installation and general usage of the interface, and then list the general properties like the supported particle types, color quantum numbers and Lorentz structures as well as types of gauge interactions. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Installation and Usage of the \whizard-\FeynRules\ interface} \label{sec:interface-usage} \paragraph{{\bf Installation and basic usage:}} % From \FeynRules\ version 1.6.0 onward, the interface to \whizard\ is part of the \FeynRules\ distribution\footnote{Note that though the main interface of \FeynRules\ to \whizard\ is for the most recent \whizard\ release, but also the legacy branch \whizard\ttt{1} is supported.}. In addition, the latest version of the interface can be downloaded from the \whizard\ homepage on \ttt{HepForge}. There you can also find an installer that can be used to inject the interface into an existing \FeynRules\ installation (which allows to use the interface with the \FeynRules\ release series1.4.x where it is not part of the package). Once installed, the interface can be called and used in the same way \FeynRules' other interfaces described in~\cite{Christensen:2008py}. The details of how to install and use \FeynRules\ itself can be found there,~\cite{Christensen:2008py,Christensen:2009jx,Duhr:2011se}. Here, we only describe how to use the interface to inject new models into \whizard. For example, once the \FeynRules\ environment has been initialized and a model has been loaded, the command \begin{code} WriteWOOutput[L] \end{code} will call the \ttt{FeynmanRules} command to extract the Feynman rules from the Lagrangian \ttt{L}, translate them together with the model data and finally write the files necessary for using the model within \whizard\ to an output directory (the name of which is inferred from the model name by default). Options can be added for further control over the translation process (see Sec.~\ref{app:interface-options}). Instead of using a Lagrangian, it is also possible to call the interface on a pure vertex list. For example, the following command \begin{code} WriteWOOutput[Input -> list] \end{code} will directly translate the vertex list \ttt{list}. Note that this vertex list must be given in flavor-expanded form in order for the interface to process it correctly. The interface also supports the \ttt{WriteWOExtParams} command described in~\cite{Christensen:2008py}. Issuing \begin{code} WriteWOExtParams[filename] \end{code} will write a list of all the external parameters to \ttt{filename}. This is done in the form of a \sindarin\ script. The only option accepted by the command above is the target version of \whizard, set by the option \ttt{WOWhizardVersion}. During execution, the interface will print out a series of messages. It is highly advised to carefully read through this output as it not only summarizes the settings and the location of the output files, but also contains information on any skipped vertices or potential incompatibilities of the model with \whizard. After the interface has run successfully and written the model files to the output directory, the model must be imported into \whizard. For doing so, the model files have to be compiled and can then be installed independently of \whizard. In the simplest scenario, assuming that the output directory is the current working directory and that the \whizard\ binaries can be found in the current \ttt{\$\{PATH\}}, the installation is performed by simply executing \begin{code} ./configure~\&\&~make clean~\&\&~make install \end{code} This will compile the model and install it into the directory \ttt{\$\{HOME\}/.whizard}, making it fully available to \whizard\ without any further intervention. The build system can be adapted to more complicated cases through several options to the \ttt{configure} which are listed in the \ttt{INSTALL} file created in the output directory. A detailed explanation of all options can be found in Sec.~\ref{app:interface-options}. \paragraph{\bf Supported fields and vertices:} The following fields are currently supported by the interface: scalars, Dirac and Majorana fermions, vectors and symmetric tensors. The set of accepted operators, the full list of which can be found in Tab.~\ref{tab-operators}, is a subset of all the operators supported by \oMega. While still limited, this list is sufficient for a large number of BSM models. In addition, a future version of \whizard/\oMega\ will support the definition of completely general Lorentz structures in the model, allowing the interface to translate all interactions handled by \FeynRules. This will be done by means of a parser within \oMega\ of the \ttt{UFO} file format for model files from \FeynRules. \begin{table*}[!t] \centerline{\begin{tabular}{|c|c|} \hline Particle spins & Supported Lorentz structures \\\hline\hline FFS & \parbox{0.7\textwidth}{\raggedright All operators of dimension four are supported. \strut}\\\hline FFV & \parbox[t]{0.7\textwidth}{\raggedright All operators of dimension four are supported. \strut}\\\hline SSS & \parbox{0.7\textwidth}{\raggedright All dimension three interactions are supported. \strut}\\\hline SVV & \parbox[t]{0.7\textwidth}{\raggedright Supported operators:\\ \mbox{}\hspace{5ex}$\begin{aligned} \text{dimension 3:} & \quad\mathcal{O}_3 = V_1^\mu V_{2\mu}\phi \mbox{}\\ \text{dimension 5:} & \quad\mathcal{O}_5 = \phi \left(\partial^\mu V_1^\nu - \partial^\nu V_1^\mu\right) \left(\partial_\mu V_{2\nu} - \partial_\nu V_{2\mu}\right) \end{aligned}$\\ Note that $\mathcal{O}_5$ generates the effective gluon-gluon-Higgs couplings obtained by integrating out heavy quarks. \strut}\\\hline SSV & \parbox[t]{0.7\textwidth}{\raggedright $\left(\phi_1\partial^\mu\phi_2 - \phi_2\partial^\mu\phi_1\right)V_\mu\;$ type interactions are supported. \strut}\\\hline SSVV & \parbox{0.7\textwidth}{\raggedright All dimension four interactions are supported. \strut}\\\hline SSSS & \parbox{0.7\textwidth}{\raggedright All dimension four interactions are supported. \strut}\\\hline VVV & \parbox[t]{0.7\textwidth}{\raggedright All parity-conserving dimension four operators are supported, with the restriction that non-gauge interactions may be split into several vertices and can only be handled if all three fields are mutually different.\strut \strut}\\\hline VVVV & \parbox[t]{0.7\textwidth}{\raggedright All parity conserving dimension four operators are supported. \strut}\\\hline TSS, TVV, TFF & \parbox[t]{0.7\textwidth}{\raggedright The three point couplings in the Appendix of Ref.\ \cite{Han:1998sg} are supported. \strut}\\\hline \end{tabular}} \caption{All Lorentz structures currently supported by the \whizard-\FeynRules\ interface, sorted with respect to the spins of the particles. ``S'' stands for scalar, ``F'' for fermion (either Majorana or Dirac) and ``V'' for vector.} \label{tab-operators} \end{table*} \paragraph{\bf Color:} % Color is treated in \oMega\ in the color flow decomposition, with the flow structure being implicitly determined from the representations of the particles present at the vertex. Therefore, the interface has to strip the color structure from the vertices derived by \FeynRules\ before writing them out to the model files. While this process is straightforward for all color structures which correspond only to a single flow assignment, vertices with several possible flow configurations must be treated with care in order to avoid mismatches between the flows assigned by \oMega\ and those actually encoded in the couplings. To this end, the interface derives the color flow decomposition from the color structure determined by \FeynRules\ and rejects all vertices which would lead to a wrong flow assignment by \oMega\ (these rejections are accompanied by warnings from the interface)\footnote{For the old \whizard\ttt{1} legacy branch, there was a maximum number of external color flows that had to explicitly specified. Essentially, this is $n_8 - \frac{1}{2}n_3$ where $n_8$ is the maximum number of external color octets and $n_3$ is the maximum number of external triplets and antitriplets. This can be set in the \whizard/\FeynRules\ interface by the \ttt{WOMaxNcf} command, whose default is \ttt{4}.}. At the moment, the $SU(3)_C$ representations supported by both \whizard\ and the interface are singlets ($1$), triplets ($3$), antitriplets ($\bar{3}$) and octets ($8$). Tab.~\ref{tab:su3struct} shows all combinations of these representations which can form singlets together with the support status of the respective color structures in \whizard\ and the interface. Although the supported color structures do not comprise all possible singlets, the list is sufficient for a large number of SM extensions. Furthermore, a future revision of \whizard/\oMega\ will allow for explicit color flow assignments, thus removing most of the current restrictions. \begin{table*} \centerline{\begin{tabular}{|c|c|} \hline $SU(3)_C$ representations & Support status \\\hline\hline \parbox[t]{0.2\textwidth}{ \centerline{\begin{tabular}[t]{lll} $111,\quad$ & $\bar{3}31,\quad$ & $\bar{3}38,$ \\ $1111,$ & $\bar{3}311,$ & $\bar{3}381$ \end{tabular}}} & \parbox[t]{0.7\textwidth}{\raggedright\strut Fully supported by the interface\strut} \\\hline $888,\quad 8881$ & \parbox{0.7\textwidth}{\raggedright\strut Supported only if at least two of the octets are identical particles.\strut} \\\hline $881,\quad 8811$ & \parbox{0.7\textwidth}{\raggedright\strut Fully supported by the interface\footnote{% Not available in version 1.95 and earlier. Note that in order to use such couplings in 1.96/97, the \oMega\ option \ttt{2g} must be added to the process definition in \ttt{whizard.prc}.}.\strut} \\\hline $\bar{3}388$ & \parbox{0.7\textwidth}{\raggedright\strut Supported only if the octets are identical particles.\strut} \\\hline $8888$ & \parbox{0.7\textwidth}{\raggedright\strut The only supported flow structure is \begin{equation*} \parbox{21mm}{\includegraphics{flow4}}\cdot\;\Gamma(1,2,3,4) \quad+\quad \text{all acyclic permutations} \end{equation*} where $\Gamma(1,2,3,4)$ represents the Lorentz structure associated with the first flow.\strut} \\\hline \parbox[t]{0.2\textwidth}{ \centerline{\begin{tabular}[t]{lll} $333,\quad$ & $\bar{3}\bar{3}\bar{3},\quad$ & $3331$\\ $\bar{3}\bar{3}\bar{3}1,$ & $\bar{3}\bar{3}33$ \end{tabular}}} & \parbox[t]{0.7\textwidth}{\raggedright\strut Unsupported (at the moment)\strut} \\\hline \end{tabular}} \caption{All possible combinations of three or four $SU(3)_C$ representations supported by \FeynRules\ which can be used to build singlets, together with the support status of the corresponding color structures in \whizard\ and the interface.} \label{tab:su3struct} \end{table*} \paragraph{\bf Running $\alpha_S$:} While a running strong coupling is fully supported by the interface, a choice has to be made which quantities are to be reevaluated when the strong coupling is evolved. By default \ttt{aS}, \ttt{G} (see Ref.~\cite{Christensen:2008py} for the nomenclature regarding the QCD coupling) and any vertex factors depending on them are evolved. The list of internal parameters that are to be recalculated (together with the vertex factors depending on them) can be extended (beyond \ttt{aS} and \ttt{G}) by using the option \ttt{WORunParameters} when calling the interface~\footnote{As the legacy branch, \whizard\ttt{1}, does not support a running strong coupling, this is also vetoed by the interface when using \whizard \ttt{1.x}.}. \paragraph{\bf Gauge choices:} \label{sec:gauge-choices} The interface supports the unitarity, Feynman and $R_\xi$ gauges. The choice of gauge must be communicated to the interface via the option \ttt{WOGauge}. Note that massless gauge bosons are always treated in Feynman gauge. If the selected gauge is Feynman or $R_\xi$, the interface can automatically assign the proper masses to the Goldstone bosons. This behavior is requested by using the \ttt{WOAutoGauge} option. In the $R_\xi$ gauges, the symbol representing the gauge $\xi$ must be communicated to the interface by using the \ttt{WOGaugeSymbol} option (the symbol is automatically introduced into the list of external parameters if \ttt{WOAutoGauge} is selected at the same time). This feature can be used to automatically extend models implemented in Feynman gauge to the $R_\xi$ gauges. Since \whizard\ (at least until the release series 2.3) is a tree-level tool working with helicity amplitudes, the ghost sector is irrelevant for \whizard\ and hence dropped by the interface. \subsection{Options of the \whizard-\FeynRules\ interface} \label{app:interface-options} In the following we present a comprehensive list of all the options accepted by \ttt{WriteWOOutput}. Additionally, we note that all options of the \FeynRules\ command \ttt{FeynmanRules} are accepted by \ttt{WriteWOOutput}, which passes them on to \ttt{FeynmanRules}. \begin{description} \item[\ttt{Input}]\mbox{}\\ An optional vertex list to use instead of a Lagrangian (which can then be omitted). % \item[\ttt{WOWhizardVersion}]\mbox{}\\ Select the \whizard\ version for which code is to be generated. The currently available choices are summarized in Tab.~\ref{tab-wowhizardversion}. %% \begin{table} \centerline{\begin{tabular}{|l|l|} \hline \ttt{WOWhizardVersion} & \whizard\ versions supported \\\hline\hline \ttt{"2.0.3"} (default) & 2.0.3+ \\\hline \ttt{"2.0"} & 2.0.0 -- 2.0.2 \\\hline\hline \ttt{"1.96"} & 1.96+ \qquad (deprecated) \\\hline \ttt{"1.93"} & 1.93 -- 1.95 \qquad (deprecated) \\\hline \ttt{"1.92"} & 1.92 \qquad (deprecated) \\\hline \end{tabular}} \caption{Currently available choices for the \ttt{WOWhizardVersion} option, together with the respective \whizard\ versions supported by them.} \label{tab-wowhizardversion} \end{table} %% This list will expand as the program evolves. To get a summary of all choices available in a particular version of the interface, use the command \ttt{?WOWhizardVersion}. % \item[\ttt{WOModelName}]\mbox{}\\ The name under which the model will be known to \whizard\footnote{For versions 1.9x, model names must start with ``\ttt{fr\_}'' if they are to be picked up by \whizard\ automatically.}. The default is determined from the \FeynRules\ model name. % \item[\ttt{Output}]\mbox{}\\ The name of the output directory. The default is determined from the \FeynRules\ model name. % \item[\ttt{WOGauge}]\mbox{}\\ Gauge choice (\emph{cf.} Sec.~\ref{sec:gauge-choices}). Possible values are: \ttt{WOUnitarity} (default), \ttt{WOFeynman}, \ttt{WORxi} % \item[\ttt{WOGaugeParameter}]\mbox{}\\ The external or internal parameter representing the gauge $\xi$ in the $R_\xi$ gauges (\emph{cf.} Sec.~\ref{sec:gauge-choices}). Default: \ttt{Rxi} % \item[\ttt{WOAutoGauge}]\mbox{}\\ Automatically assign the Goldstone boson masses in the Feynman and $R_\xi$ gauges and automatically append the symbol for $\xi$ to the parameter list in the $R_\xi$ gauges. Default: \ttt{False} % \item[\ttt{WORunParameters}]\mbox{}\\ The list of all internal parameters which will be recalculated if $\alpha_S$ is evolved (see above)\footnote{Not available for versions older than 2.0.0}. Default: \mbox{\ttt{\{aS, G\}}} % \item[\ttt{WOFast}]\mbox{}\\ If the interface drops vertices which are supported, this option can be set to \ttt{False} to enable some more time consuming checks which might aid the identification. Default: \ttt{True} % \item[\ttt{WOMaxCouplingsPerFile}]\mbox{}\\ The maximum number of couplings that are written to a single \fortran\ file. If compilation takes too long or fails, this can be lowered. Default: \ttt{500} % \item[\ttt{WOVerbose}]\mbox{}\\ Enable verbose output and in particular more extensive information on any skipped vertices. Default: \ttt{False} \end{description} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Validation of the interface} The output of the interface has been extensively validated. Specifically, the integrated cross sections for all possible $2\rightarrow 2$ processes in the \FeynRules\ SM, the MSSM and the Three-Site Higgsless Model have been compared between \whizard, \madgraph, and \CalcHep, using the respective \FeynRules\ interfaces as well as the in-house implementations of these models (the Three-Site Higgsless model not being available in \madgraph). Also, different gauges have been checked for \whizard\ and \CalcHep. In all comparisons, excellent agreement within the Monte Carlo errors was achieved. The detailed comparison including examples of the comparison tables can be found in~\cite{Christensen:2010wz}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Examples for the \whizard-/\FeynRules\ interface} Here, we will use the Standard Model, the MSSM and the Three-Site Higgsless Model as prime examples to explain the usage of the interface. Those are the models that have been used in the validation of the interface in~\cite{Christensen:2010wz}. The examples are constructed to show the application of the different options of the interface and to serve as a starting point for the generation of the user's own \whizard\ versions of other \FeynRules\ models. \subsubsection{\whizard-\FeynRules\ example: Standard Model}\label{sec:usageSM} To start off, we will create {\sc Whizard} 2 versions of the Standard Model as implemented in \FeynRules\ for different gauge choices. \paragraph{SM: Unitarity Gauge} In order to invoke \FeynRules, we change to the corresponding directory and load the program in \Mathematica\ via \begin{code} $FeynRulesPath = SetDirectory[""]; < WOFeynman]; \end{code} The modified gauge is reflected in the output of the interface \begin{code} Short model name is "fr_standard_model" Gauge: Feynman Generating code for WHIZARD / O'Mega version 2.0.3 Maximum number of couplings per FORTRAN module: 500 Extensive lorentz structure checks disabled. \end{code} The summary of the vertex identification now takes the following form \begin{code} processed a total of 163 vertices, kept 139 of them and threw away 24, 24 of which contained ghosts. \end{code} Again, this line tells us that there were no problems --- the only discarded interactions involved the ghost sector which is irrelevant for the tree-level part of \whizard. For a tree-level calculation, the only difference between the different gauges from the perspective of the interface are the gauge boson propagators and the Goldstone boson masses. Therefore, the interface can automatically convert a model in Feynman gauge to a model in $R_\xi$ gauge. To this end, the call to the interface must be changed to \begin{code} WriteWOOutput[LSM, WOGauge -> WORxi, WOAutoGauge -> True]; \end{code} The \verb?WOAutoGauge? argument instructs the interface to automatically \begin{enumerate} \item Introduce a symbol for the gauge parameter $\xi$ into the list of external parameters \item Generate the Goldstone boson masses from those of the associated gauge bosons (ignoring the values provided by \FeynRules) \end{enumerate} The modified setup is again reflected in the interface output \begin{code} Short model name is "fr_standard_model" Gauge: Rxi Gauge symbol: "Rxi" Generating code for WHIZARD / O'Mega version 2.0.3 Maximum number of couplings per FORTRAN module: 500 Extensive lorentz structure checks disabled. \end{code} Note the default choice \verb?Rxi? for the name of the $\xi$ parameter -- this can be modified via the option \verb?WOGaugeParameter?. While the \verb?WOAutoGauge? feature allows to generate $R_\xi$ gauged models from models implemented in Feynman gauge, it is of course also possible to use models genuinely implemented in $R_\xi$ gauge by setting this parameter to \verb?False?. Also, note that the choice of gauge only affects the propagators of massive fields. Massless gauge bosons are always treated in Feynman gauge. \paragraph{Compilation and usage} In order to compile and use the freshly generated model files, change to the output directory which can be determined from the interface output (in this example, it is \verb?fr_standard_model-WO?). Assuming that \whizard\ is available in the binary search path, compilation and installation proceeds as described above by executing \begin{code} ./configure && make && make install \end{code} The model is now ready and can be used similarly to the builtin \whizard\ models. For example, a minimal \whizard\ input file for calculating the $e^+e^- \longrightarrow W^+W^-$ scattering cross section in the freshly generated model would look like \begin{code} model = fr_standard_model process test = "e+", "e-" -> "W+", "W-" sqrts = 500 GeV integrate (test) \end{code} %%%%% \subsubsection{\whizard/\FeynRules\ example: MSSM} In this Section, we illustrate the usage of the interface between {\sc FeynRules} and {\sc Whizard} in the context of the MSSM. All the parameters of the model are then ordered in Les Houches blocks and counters following the SUSY Les Houches Accord (SLHA) \cite{Skands:2003cj,AguilarSaavedra:2005pw,Allanach:2008qq} (cf. also Sec.~\ref{sec:slha}). After having downloaded the model from the \FeynRules\ website, we store it in a new directory, labelled \verb"MSSM", of the model library of the local installation of \FeynRules. The model can then be loaded in \Mathematica\ as in the case of the SM example above \begin{code} $FeynRulesPath = SetDirectory[""]; <True" option of both interface commands \verb"FeynmanRules" and \verb"WriteWOOutput". The Feynman rules of the MSSM are then computed within the \Mathematica\ notebook by \begin{code} rules = FeynmanRules[lag, Exclude4Scalars->True, FlavorExpand->True]; \end{code} where \verb'lag' is the variable containing the Lagrangian. By default, all the parameters of the model are set to the value of \ttt{1}. A complete parameter \ttt{{\em }.dat} file must therefore be loaded. Such a parameter file can be downloaded from the \FeynRules\ website or created by hand by the user, and loaded into \FeynRules\ as \begin{code} ReadLHAFile[Input -> ".dat"]; \end{code} This command does not reduce the size of the model output by removing vertices with vanishing couplings. However, if desired, this task could be done with the \ttt{LoadRestriction} command (see Ref.\ \cite{Fuks:2012im} for details). The vertices are exported to \whizard\ by the command \begin{code} WriteWOOutput[Input -> rules]; \end{code} Note that the numerical values of the parameters of the model can be modified directly from \whizard, without having to generate a second time the \whizard\ model files from \FeynRules. A \sindarin\ script is created by the interface with the help of the instruction \begin{code} WriteWOExtParams["parameters.sin"]; \end{code} and can be further modified according to the needs of the user. \subsubsection{\whizard-\FeynRules\ example: Three-Site Higgsless Model} The Three-Site Higgsless model or Minimal Higgsless model (MHM) has been implemented into \ttt{LanHEP}~\cite{He:2007ge}, \FeynRules\ and independently into \whizard~\cite{Speckner:2010zi}, and the collider phenomenology has been studied by making use of these implementations \cite{He:2007ge,Ohl:2010zf,Speckner:2010zi}. Furthermore, the independent implementations in \FeynRules\ and directly into {\sc Whizard} have been compared and found to agree~\cite{Christensen:2010wz}. After the discovery of a Higgs boson at the LHC in 2012, such a model is not in good agreement with experimental data any more. Here, we simply use it as a guinea pig to describe the handling of a model with non-renormalizable interactions with the \FeynRules\ interface, and discuss how to generate \whizard\ model files for it. The model has been implemented in Feynman gauge as well as unitarity gauge and contains the variable \verb|FeynmanGauge| which can be set to \verb|True| or \verb|False|. When set to \verb|True|, the option \verb|WOGauge-> WOFeynman| must be used, as explained in~\cite{Christensen:2010wz}. $R_\xi$ gauge can also be accomplished with this model by use of the options \verb|WOGauge -> WORxi| and \verb?WOAutoGauge -> True?. Since this model makes use of a nonlinear sigma field of the form \begin{equation} \Sigma = 1 + i\pi - \frac{1}{2}\pi^2+\cdots \end{equation} many higher dimensional operators are included in the model which are not currently not supported by \whizard. Even for a future release of \whizard\ containing general Lorentz structures in interaction vertices, the user would be forced to expand the series only up to a certain order. Although \whizard\ can reject these vertices and print a warning message to the user, it is preferable to remove the vertices right away in the interface by the option \verb|MaxCanonicalDimension->4|. This is passed to the command \verb|FeynmanRules| and restricts the Feynman rules to those of dimension four and smaller\footnote{\ttt{MaxCanonicalDimension} is an option of the \ttt{FeynmanRules} function rather than of the interface, itself. In fact, the interface accepts all the options of {\tt FeynmanRules} and simply passes them on to the latter.}. As the use of different gauges was already illustrated in the SM example, we discuss the model only in Feynman gauge here. We load \FeynRules: \begin{code} $FeynRulesPath = SetDirectory[""]; <"]; LoadModel["3-Site-particles.fr", "3-Site-parameters.fr", "3-Site-lagrangian.fr"]; FeynmanGauge = True; \end{code} where \verb|| is the path to the directory where the MHM model files are stored and where the output of the \whizard\ interface will be written. The \whizard\ interface is then initiated: \begin{code} WriteWOOutput[LGauge, LGold, LGhost, LFermion, LGoldLeptons, LGoldQuarks, MaxCanonicalDimension->4, WOGauge->WOFeynman, WOModelName->"fr_mhm"]; \end{code} where we have also made use of the option \verb|WOModelName| to change the name of the model as seen by \whizard. As in the case of the SM, the interface begins by writing a short informational message: \begin{code} Short model name is "fr_mhm" Gauge: Feynman Generating code for WHIZARD / O'Mega version 2.0.3 Automagically assigning Goldstone boson masses... Maximum number of couplings per FORTRAN module: 500 Extensive lorentz structure checks disabled. \end{code} After calculating the Feynman rules and processing the vertices, the interface gives a summary: \begin{code} processed a total of 922 vertices, kept 633 of them and threw away 289, 289 of which contained ghosts. \end{code} showing that no vertices were missed. The files are stored in the directory \verb|fr_mhm| and are ready to be installed and used with \whizard. %%%%%%%%%%%%%%% \section{New physics models via the \UFO\ file format} \label{sec:ufo} In this section, we describe how to use the {\em Universal FeynRules Output} (\UFO, \cite{Degrande:2011ua}) format for physics models inside \whizard. Please refer the manuals of e.g.~\FeynRules\ manual for details on how to generate a \UFO\ file for your favorite physics model. \UFO\ files are a collection of \ttt{Python} scripts that encode the particles, the couplings, the Lorentz structures, the decays, as well as parameters, vertices and propagators of the corresponding model. They reside in a directory of the exact name of the model they have been created from. If the user wants to generate events for processes from a physics model from a \UFO\ file, then this directory of scripts generated by \FeynRules\ is immediately available if it is a subdirectory of the working directory of \whizard. The directory name will be taken as the model name. (The \UFO-model file name must not start with a non-letter character, i.e. especially not a number. In case such a file name wants to be used at all costs, the model name in the \sindarin\ script has to put in quotation marks, but this is not guaranteed to always work.) Then, a \UFO\ model named, e.g., \ttt{test\_model} is accessed by an extra \ttt{ufo} tag in the model assignment: \begin{Code} model = test_model (ufo) \end{Code} If desired, \whizard\ can access a directory of \UFO\ files elsewhere on the file system. For instance, if \FeynRules\ output resides in the subdirectory \ttt{MyMdl} of \ttt{/home/users/john/ufo}, \whizard\ can use the model named \ttt{MyMdl} as follows \begin{Code} model = MyMdl (ufo ('/home/users/john/my_ufo_models')) \end{Code} that is, the \sindarin\ keyword \ttt{ufo} can take an argument. Note however, that the latter approach can backfire --- in case just the working directory is packed and archived for future reference. %%%%%%%%%%%%%%% \clearpage %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \appendix %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{\sindarin\ Reference} In the \sindarin\ language, there are certain pre-defined constructors or commands that cannot be used in different context by the user, which are e.g. \ttt{alias}, \ttt{beams}, \ttt{integrate}, \ttt{simulate} etc. A complete list will be given below. Also units are fixed, like \ttt{degree}, \ttt{eV}, \ttt{keV}, \ttt{MeV}, \ttt{GeV}, and \ttt{TeV}. Again, these tags are locked and not user-redefinable. Their functionality will be listed in detail below, too. Furthermore, a variable with a preceding question mark, ?, is a logical, while a preceding dollar, \$, denotes a character string variable. Also, a lot of unary and binary operators exist, \ttt{+ - $\backslash$ , = : => < > <= >= \^ \; () [] \{\} } \url{==}, as well as quotation marks, ". Note that the different parentheses and brackets fulfill different purposes, which will be explained below. Comments in a line can either be marked by a hash, \#, or an exclamation mark, !. \section{Commands and Operators} We begin the \sindarin\ reference with all commands, operators, functions and constructors. The list of variables (which can be set to change behavior of \whizard) can be found in the next section. \begin{itemize} \item \ttt{+} \newline 1) Arithmetic operator for addition of integers, reals and complex numbers. Example: \ttt{real mm = mH + mZ} (cf. also \ttt{-}, \ttt{*}, \ttt{/}, \ttt{\^{}}). 2) It also adds different particles for inclusive process containers: \ttt{process foo = e1, E1 => (e2, E2) + (e3, E3)}. 3) It also serves as a shorthand notation for the concatenation of ($\to$) \ttt{combine} operations on particles/subevents, e.g. \ttt{cuts = any 170 GeV < M < 180 GeV [b + lepton + invisible]}. %%%%% \item \ttt{-} \newline Arithmetic operator for subtraction of integers, reals and complex numbers. Example: \ttt{real foo = 3.1 - 5.7} (cf. also \ttt{+}, \ttt{*}, \ttt{/}, \ttt{\^{}}). %%%%% \item \ttt{/} \newline Arithmetic operator for division of integers, reals and complex numbers. Example: \ttt{scale = mH / 2} (cf. also \ttt{+}, \ttt{*}, \ttt{-}, \ttt{\^{}}). %%%%% \item \ttt{*} \newline Arithmetic operator for multiplication of integers, reals and complex numbers. Example: \ttt{complex z = 2 * I} (cf. also \ttt{+}, \ttt{/}, \ttt{-}, \ttt{\^{}}). %%%%% \item \ttt{\^{}} \newline Arithmetic operator for exponentiation of integers, reals and complex numbers. Example: \ttt{real z = x\^{}2 + y\^{}2} (cf. also \ttt{+}, \ttt{/}, \ttt{-}, \ttt{\^{}}). %%%%% \item \ttt{<} \newline Arithmetic comparator between values that checks for ordering of two values: \ttt{{\em } < {\em }} tests whether \ttt{{\em val1}} is smaller than \ttt{{\em val2}}. Allowed for integer and real values. Note that this is an exact comparison if \ttt{tolerance} is set to zero. For a finite value of \ttt{tolerance} it is a ``fuzzy'' comparison. (cf. also \ttt{tolerance}, \ttt{<>}, \ttt{==}, \ttt{>}, \ttt{>=}, \ttt{<=}) %%%%% \item \ttt{>} \newline Arithmetic comparator between values that checks for ordering of two values: \ttt{{\em } > {\em }} tests whether \ttt{{\em val1}} is larger than \ttt{{\em val2}}. Allowed for integer and real values. Note that this is an exact comparison if \ttt{tolerance} is set to zero. For a finite value of \ttt{tolerance} it is a ``fuzzy'' comparison. (cf. also \ttt{tolerance}, \ttt{<>}, \ttt{==}, \ttt{>}, \ttt{>=}, \ttt{<=}) %%%%% \item \ttt{<=} \newline Arithmetic comparator between values that checks for ordering of two values: \ttt{{\em } <= {\em }} tests whether \ttt{{\em val1}} is smaller than or equal \ttt{{\em val2}}. Allowed for integer and real values. Note that this is an exact comparison if \ttt{tolerance} is set to zero. For a finite value of \ttt{tolerance} it is a ``fuzzy'' comparison. (cf. also \ttt{tolerance}, \ttt{<>}, \ttt{==}, \ttt{>}, \ttt{<}, \ttt{>=}) %%%%% \item \ttt{>=} \newline Arithmetic comparator between values that checks for ordering of two values: \ttt{{\em } >= {\em }} tests whether \ttt{{\em val1}} is larger than or equal \ttt{{\em val2}}. Allowed for integer and real values. Note that this is an exact comparison if \ttt{tolerance} is set to zero. For a finite value of \ttt{tolerance} it is a ``fuzzy'' comparison. (cf. also \ttt{tolerance}, \ttt{<>}, \ttt{==}, \ttt{>}, \ttt{<}, \ttt{>=}) %%%%% \item \ttt{==} \newline Arithmetic comparator between values that checks for identity of two values: \ttt{{\em } == {\em }}. Allowed for integer and real values. Note that this is an exact comparison if \ttt{tolerance} is set to zero. For a finite value of \ttt{tolerance} it is a ``fuzzy'' comparison. (cf. also \ttt{tolerance}, \ttt{<>}, \ttt{>}, \ttt{<}, \ttt{>=}, \ttt{<=}) %%%%% \item \ttt{<>} \newline Arithmetic comparator between values that checks for two values being unequal: \ttt{{\em } <> {\em }}. Allowed for integer and real values. Note that this is an exact comparison if \ttt{tolerance} is set to zero. For a finite value of \ttt{tolerance} it is a ``fuzzy'' comparison. (cf. also \ttt{tolerance}, \ttt{==}, \ttt{>}, \ttt{<}, \ttt{>=}, \ttt{<=}) %%%%% \item \ttt{!} \newline The exclamation mark tells \sindarin\ that everything that follows in that line should be treated as a comment. It is the same as ($\to$) \ttt{\#}. %%%%% \item \ttt{\#} \newline The hash tells \sindarin\ that everything that follows in that line should be treated as a comment. It is the same as ($\to$) \ttt{!}. %%%%% \item \ttt{\&} \newline Concatenates two or more particle lists/subevents and hence acts in the same way as the subevent function ($\to$) \ttt{join}: \ttt{let @visible = [photon] \& [colored] \& [lepton] in ...}. (cf. also \ttt{join}, \ttt{combine}, \ttt{collect}, \ttt{extract}, \ttt{sort}). %%%%% \item \ttt{\$} \newline Constructor at the beginning of a variable name, \ttt{\${\em }}, that specifies a string variable. %%%%% \item \ttt{@} \newline Constructor at the beginning of a variable name, \ttt{@{\em }}, that specifies a subevent variable, e.g. \ttt{let @W\_candidates = combine ["mu-", "numubar"] in ...}. %%%%% \item \ttt{=} \newline Binary constructor to appoint values to commands, e.g. \ttt{{\em } = {\em }} or \newline \ttt{{\em } {\em } = {\em }}. %%%%% \item \ttt{\%} \newline Constructor that gives the percentage of a number, so in principle multiplies a real number by \ttt{0.01}. Example: \ttt{1.23 \%} is equal to \ttt{0.0123}. %%%%% \item \ttt{:} \newline Separator in alias expressions for particles, e.g. \ttt{alias neutrino = n1:n2:n3:N1:N2:N3}. (cf. also \ttt{alias}) %%%%% \item \ttt{;} \newline Concatenation operator for logical expressions: \ttt{{\em lexpr1} ; {\em lexpr2}}. Evaluates \ttt{{\em lexpr1}} and throws the result away, then evaluates \ttt{{\em lexpr2}} and returns that result. Used in analysis expressions. (cf. also \ttt{analysis}, \ttt{record}) %%%%% \item \ttt{/+} \newline Incrementor for ($\to$) \ttt{scan} ranges, that increments additively, \ttt{scan {\em } = ({\em } => {\em } /+ {\em })}. E.g. \ttt{scan int i = (1 => 5 /+ 2)} scans over the values \ttt{1}, \ttt{3}, \ttt{5}. For real ranges, it divides the interval between upper and lower bound into as many intervals as the incrementor provides, e.g. \ttt{scan real r = (1 => 1.5 /+ 0.2)} runs over \ttt{1.0}, \ttt{1.333}, \ttt{1.667}, \ttt{1.5}. %%%%% \item \ttt{/+/} \newline Incrementor for ($\to$) \ttt{scan} ranges, that increments additively, but the number after the incrementor is the number of steps, not the step size: \ttt{scan {\em } = ({\em } => {\em } /+/ {\em })}. It is only available for real scan ranges, and divides the interval \ttt{{\em } - {\em }} into \ttt{{\em }} steps, e.g. \ttt{scan real r = (1 => 1.5 /+/ 3)} runs over \ttt{1.0}, \ttt{1.25}, \ttt{1.5}. %%%%% \item \ttt{/-} \newline Incrementor for ($\to$) \ttt{scan} ranges, that increments subtractively, \ttt{scan {\em } {\em } = ({\em } => {\em } /- {\em })}. E.g. \ttt{scan int i = (9 => 0 /+ 3)} scans over the values \ttt{9}, \ttt{6}, \ttt{3}, \ttt{0}. For real ranges, it divides the interval between upper and lower bound into as many intervals as the incrementor provides, e.g. \ttt{scan real r = (1 => 0.5 /- 0.2)} runs over \ttt{1.0}, \ttt{0.833}, \ttt{0.667}, \ttt{0.5}. %%%%% \item \ttt{/*} \newline Incrementor for ($\to$) \ttt{scan} ranges, that increments multiplicatively, \ttt{scan {\em } {\em } = ({\em } => {\em } /* {\em })}. E.g. \ttt{scan int i = (1 => 4 /* 2)} scans over the values \ttt{1}, \ttt{2}, \ttt{4}. For real ranges, it divides the interval between upper and lower bound into as many intervals as the incrementor provides, e.g. \ttt{scan real r = (1 => 5 /* 2)} runs over \ttt{1.0}, \ttt{2.236} (i.e. $\sqrt{5}$), \ttt{5.0}. %%%%% \item \ttt{/*/} \newline Incrementor for ($\to$) \ttt{scan} ranges, that increments multiplicatively, but the number after the incrementor is the number of steps, not the step size: \ttt{scan {\em } {\em } = ({\em } => {\em } /*/ {\em })}. It is only available for real scan ranges, and divides the interval \ttt{{\em } - {\em }} into \ttt{{\em }} steps, e.g. \ttt{scan real r = (1 => 9 /*/ 4)} runs over \ttt{1.000}, \ttt{2.080}, \ttt{4.327}, \ttt{9.000}. %%%%% \item \ttt{//} \newline Incrementor for ($\to$) \ttt{scan} ranges, that increments by division, \ttt{scan {\em } {\em } = ({\em } => {\em } // {\em })}. E.g. \ttt{scan int i = (13 => 0 // 3)} scans over the values \ttt{13}, \ttt{4}, \ttt{1}, \ttt{0}. For real ranges, it divides the interval between upper and lower bound into as many intervals as the incrementor provides, e.g. \ttt{scan real r = (5 => 1 // 2)} runs over \ttt{5.0}, \ttt{2.236} (i.e. $\sqrt{5}$), \ttt{1.0}. %%%%% \item \ttt{=>} \newline Binary operator that is used in several different contexts: 1) in process declarations between the particles specifying the initial and final state, e.g. \ttt{process {\em } = {\em }, {\em } => {\em }, ....}; 2) for the specification of beams when structure functions are applied to the beam particles, e.g. \ttt{beams = p, p => pdf\_builtin}; 3) for the specification of the scan range in the \ttt{scan {\em } {\em } = ({\em } => {\em } {\em })} (cf. also \ttt{process}, \ttt{beams}, \ttt{scan}) %%%%% \item \ttt{\%d} \newline Format specifier in analogy to the \ttt{C} language for the print out on screen by the ($\to$) \ttt{printf} or into strings by the ($\to$) \ttt{sprintf} command. It is used for decimal integer numbers, e.g. \ttt{printf "one = \%d" (i)}. The difference between \ttt{\%i} and \ttt{\%d} does not play a role here. (cf. also \ttt{printf}, \ttt{sprintf}, \ttt{\%i}, \ttt{\%e}, \ttt{\%f}, \ttt{\%g}, \ttt{\%E}, \ttt{\%F}, \ttt{\%G}, \ttt{\%s}) %%%%% \item \ttt{\%e} \newline Format specifier in analogy to the \ttt{C} language for the print out on screen by the ($\to$) \ttt{printf} or into strings by the ($\to$) \ttt{sprintf} command. It is used for floating-point numbers in standard form \ttt{[-]d.ddd e[+/-]ddd}. Usage e.g. \ttt{printf "pi = \%e" (PI)}. (cf. also \ttt{printf}, \ttt{sprintf}, \ttt{\%d}, \ttt{\%i}, \ttt{\%f}, \ttt{\%g}, \ttt{\%E}, \ttt{\%F}, \ttt{\%G}, \ttt{\%s}) %%%%% \item \ttt{\%E} \newline Same as ($\to$) \ttt{\%e}, but using upper-case letters. (cf. also \ttt{printf}, \ttt{sprintf}, \ttt{\%d}, \ttt{\%i}, \ttt{\%e}, \ttt{\%f}, \ttt{\%g}, \ttt{\%F}, \ttt{\%G}, \ttt{\%s}) %%%%% \item \ttt{\%f} \newline Format specifier in analogy to the \ttt{C} language for the print out on screen by the ($\to$) \ttt{printf} or into strings by the ($\to$) \ttt{sprintf} command. It is used for floating-point numbers in fixed-point form. Usage e.g. \ttt{printf "pi = \%f" (PI)}. (cf. also \ttt{printf}, \ttt{sprintf}, \ttt{\%d}, \ttt{\%i}, \ttt{\%e}, \ttt{\%g}, \ttt{\%E}, \ttt{\%F}, \ttt{\%G}, \ttt{\%s}) %%%%% \item \ttt{\%F} \newline Same as ($\to$) \ttt{\%f}, but using upper-case letters. (cf. also \ttt{printf}, \ttt{sprintf}, \ttt{\%d}, \ttt{\%i}, \ttt{\%e}, \ttt{\%f}, \ttt{\%g}, \ttt{\%E}, \ttt{\%G}, \ttt{\%s}) %%%%% \item \ttt{\%g} \newline Format specifier in analogy to the \ttt{C} language for the print out on screen by the ($\to$) \ttt{printf} or into strings by the ($\to$) \ttt{sprintf} command. It is used for floating-point numbers in normal or exponential notation, whichever is more approriate. Usage e.g. \ttt{printf "pi = \%g" (PI)}. (cf. also \ttt{printf}, \ttt{sprintf}, \ttt{\%d}, \ttt{\%i}, \ttt{\%e}, \ttt{\%f}, \ttt{\%E}, \ttt{\%F}, \ttt{\%G}, \ttt{\%s}) %%%%% \item \ttt{\%G} \newline Same as ($\to$) \ttt{\%g}, but using upper-case letters. (cf. also \ttt{printf}, \ttt{sprintf}, \ttt{\%d}, \ttt{\%i}, \ttt{\%e}, \ttt{\%f}, \ttt{\%g}, \ttt{\%E}, \ttt{\%F}, \ttt{\%s}) %%%%% \item \ttt{\%i} \newline Format specifier in analogy to the \ttt{C} language for the print out on screen by the ($\to$) \ttt{printf} or into strings by the ($\to$) \ttt{sprintf} command. It is used for integer numbers, e.g. \ttt{printf "one = \%i" (i)}. The difference between \ttt{\%i} and \ttt{\%d} does not play a role here. (cf. \ttt{printf}, \ttt{sprintf}, \ttt{\%d}, \ttt{\%e}, \ttt{\%f}, \ttt{\%g}, \ttt{\%E}, \ttt{\%F}, \ttt{\%G}, \ttt{\%s}) %%%%% \item \ttt{\%s} \newline Format specifier in analogy to the \ttt{C} language for the print out on screen by the ($\to$) \ttt{printf} or into strings by the ($\to$) \ttt{sprintf} command. It is used for logical or string variables e.g. \ttt{printf "foo = \%s" (\$method)}. (cf. \ttt{printf}, \ttt{sprintf}, \ttt{\%d}, \ttt{\%i}, \ttt{\%e}, \ttt{\%f}, \ttt{\%g}, \ttt{\%E}, \ttt{\%F}, \ttt{\%G}) %%%%% \item \ttt{abarn} \newline Physical unit, stating that a number is in attobarns ($10^{-18}$ barn). (cf. also \ttt{nbarn}, \ttt{fbarn}, \ttt{pbarn}) %%%%% \item \ttt{abs} \newline Numerical function that takes the absolute value of its argument: \ttt{abs ({\em })} yields \ttt{|{\em }|}. (cf. also \ttt{conjg}, \ttt{sgn}, \ttt{mod}, \ttt{modulo}) %%%%% \item \ttt{acos} \newline Numerical function \ttt{asin ({\em })} that calculates the arccosine trigonometric function (inverse of \ttt{cos}) of real and complex numerical numbers or variables. (cf. also \ttt{sin}, \ttt{cos}, \ttt{tan}, \ttt{asin}, \ttt{atan}) %%%%% \item \ttt{alias} \newline This allows to define a collective expression for a class of particles, e.g. to define a generic expression for leptons, neutrinos or a jet as \ttt{alias lepton = e1:e2:e3:E1:E2:E3}, \ttt{alias neutrino = n1:n2:n3:N1:N2:N3}, and \ttt{alias jet = u:d:s:c:U:D:S:C:g}, respectively. %%%%% \item \ttt{all} \newline \ttt{all} is a function that works on a logical expression and a list, \ttt{all {\em } [{\em }]}, and returns \ttt{true} if and only if \ttt{log\_expr} is fulfilled for {\em all} entries in \ttt{list}, and \ttt{false} otherwise. Examples: \ttt{all Pt > 100 GeV [lepton]} checks whether all leptons are harder than 100 GeV, \ttt{all Dist > 2 [u:U, d:D]} checks whether all pairs of corresponding quarks are separated in $R$ space by more than 2. Logical expressions with \ttt{all} can be logically combined with \ttt{and} and \ttt{or}. (cf. also \ttt{any}, \ttt{and}, \ttt{no}, and \ttt{or}) %%%%% \item \ttt{alt\_setup} \newline This command allows to specify alternative setups for a process/list of processes, \ttt{alt\_setup = \{ {\em } \} [, \{ {\em } \} , ...]}. An alternative setup can be a resetting of a coupling constant, or different cuts etc. It can be particularly used in a ($\to$) \ttt{rescan} procedure. %%%%% \item \ttt{analysis} \newline This command, \ttt{analysis = {\em }}, allows to define an analysis as a logical expression, with a syntax similar to the ($\to$) \ttt{cuts} or ($\to$) \ttt{selection} command. Note that a ($\to$) formally is a logical expression. %%%%% \item \ttt{and} \newline This is the standard two-place logical connective that has the value true if both of its operands are true, otherwise a value of false. It is applied to logical values, e.g. cut expressions. (cf. also \ttt{all}, \ttt{no}, \ttt{or}). %%%%% \item \ttt{any} \newline \ttt{any} is a function that works on a logical expression and a list, \ttt{any {\em } [{\em }]}, and returns \ttt{true} if \ttt{log\_expr} is fulfilled for any entry in \ttt{list}, and \ttt{false} otherwise. Examples: \ttt{any PDG == 13 [lepton]} checks whether any lepton is a muon, \ttt{any E > 2 * mW [jet]} checks whether any jet has an energy of twice the $W$ mass. Logical expressions with \ttt{any} can be logically combined with \ttt{and} and \ttt{or}. (cf. also \ttt{all}, \ttt{and}, \ttt{no}, and \ttt{or}) %%%%% \item \ttt{as} \newline cf. \ttt{compile} %%%%% \item \ttt{ascii} \newline Specifier for the \ttt{sample\_format} command to demand the generation of the standard \whizard\ verbose/debug ASCII event files. (cf. also \ttt{\$sample}, \ttt{\$sample\_normalization}, \ttt{sample\_format}) %%%%% \item \ttt{asin} \newline Numerical function \ttt{asin ({\em })} that calculates the arcsine trigonometric function (inverse of \ttt{sin}) of real and complex numerical numbers or variables. (cf. also \ttt{sin}, \ttt{cos}, \ttt{tan}, \ttt{acos}, \ttt{atan}) %%%%% \item \ttt{atan} \newline Numerical function \ttt{atan ({\em })} that calculates the arctangent trigonometric function (inverse of \ttt{tan}) of real and complex numerical numbers or variables. (cf. also \ttt{sin}, \ttt{cos}, \ttt{tan}, \ttt{asin}, \ttt{acos}) %%%%% \item \ttt{athena} \newline Specifier for the \ttt{sample\_format} command to demand the generation of the ATHENA variant for HEPEVT ASCII event files. (cf. also \ttt{\$sample}, \ttt{\$sample\_normalization}, \ttt{sample\_format}) %%%%% \item \ttt{beam} \newline Constructor that specifies a particle (in a subevent) as beam particle. It is used in cuts, analyses or selections, e.g. \ttt{cuts = all Theta > 20 degree [beam lepton, lepton]}. (cf. also \ttt{incoming}, \ttt{outgoing}, \ttt{cuts}, \ttt{analysis}, \ttt{selection}, \ttt{record}) %%%%% \item \ttt{beam\_events} \newline Beam structure specifier to read in lepton collider beamstrahlung's spectra from external files as pairs of energy fractions: \ttt{beams: e1, E1 => beam\_events}. Note that this is a pair spectrum that has to be applied to both beams simultaneously. (cf. also \ttt{beams}, \ttt{\$beam\_events\_file}, \ttt{?beam\_events\_warn\_eof}) %%%%% \item \ttt{beams} \newline This specifies the contents and structure of the beams: \ttt{beams = {\em }, {\em } [ => {\em } ....]}. If this command is absent in the input file, \whizard\ automatically takes the two incoming partons (or one for decays) of the corresponding process as beam particles, and no structure functions are applied. Protons and antiprotons as beam particles are predefined as \ttt{p} and \ttt{pbar}, respectively. A structure function, like \ttt{pdf\_builtin}, \ttt{ISR}, \ttt{EPA} and so on are switched on as e.g. \ttt{beams = p, p => lhapdf}. Structure functions can be specified for one of the two beam particles only, of the structure function is not a spectrum. (cf. also \ttt{beams\_momentum}, \ttt{beams\_theta}, \ttt{beams\_phi}, \ttt{beams\_pol\_density}, \ttt{beams\_pol\_fraction}, \ttt{beam\_events}, \ttt{circe1}, \ttt{circe2}, \ttt{energy\_scan}, \ttt{epa}, \ttt{ewa}, \ttt{isr}, \ttt{lhapdf}, \ttt{pdf\_builtin}). %%%%% \item \ttt{beams\_momentum} \newline Command to set the momenta (or energies) for the two beams of a scattering process: \ttt{beams\_momentum = {\em }, {\em }} to allow for asymmetric beam setups (e.g. HERA: \ttt{beams\_momentum = 27.5 GeV, 920 GeV}). Two arguments must be present for a scattering process, but the command can be used with one argument to integrate and simulate a decay of a moving particle. (cf. also \ttt{beams}, \ttt{beams\_theta}, \ttt{beams\_phi}, \ttt{beams\_pol\_density}, \ttt{beams\_pol\_fraction}) %%%%% \item \ttt{beams\_phi} \newline Same as ($\to$) \ttt{beams\_theta}, but to allow for a non-vanishing beam azimuth angle, too. (cf. also \ttt{beams}, \ttt{beams\_theta}, \ttt{beams\_momentum}, \ttt{beams\_pol\_density}, \ttt{beams\_pol\_fraction}) %%%%% \item \ttt{beams\_pol\_density} \newline This command allows to specify the initial state for polarized beams by the syntax: \ttt{beams\_pol\_density = @({\em }), @({\em })}. Two polarization specifiers are mandatory for scattering, while one can be used for decays from polarized probes. The specifier \ttt{{\em }} can be empty (no polarization), has one entry (for a definite helicity/spin orientation), or ranges of entries of a spin density matrix. The command can be used globally, or as a local argument of the \ttt{integrate} command. For detailed information, see Sec.~\ref{sec:initialpolarization}. It is also possible to use variables as placeholders in the specifiers. Note that polarization is assumed to be complete, for partial polarization use ($\to$) \ttt{beams\_pol\_fraction}. (cf. also \ttt{beams}, \ttt{beams\_theta}, \ttt{beams\_phi}, \ttt{beams\_momentum}, \ttt{beams\_pol\_fraction}) %%%%% \item \ttt{beams\_pol\_fraction} \newline This command allows to specify the amount of polarization when using polarized beams ($\to$ \ttt{beams\_pol\_density}). The syntax is: \ttt{beams\_pol\_fraction = {\em }, {\em }}. Two fractions must be present for scatterings, being real numbers between \ttt{0} and \ttt{1}. A specification with percentage is also possible, e.g. \ttt{beams\_pol\_fraction = 80\%, 40\%}. (cf. also \ttt{beams}, \ttt{beams\_theta}, \ttt{beams\_phi}, \ttt{beams\_momentum}, \ttt{beams\_pol\_density}) %%%%% \item \ttt{beams\_theta} \newline Command to set a crossing angle (with respect to the $z$ axis) for one or both of the beams of a scattering process: \ttt{beams\_theta = {\em }, {\em }} to allow for asymmetric beam setups (e.g. \ttt{beams\_angle = 0, 10 degree}). Two arguments must be present for a scattering process, but the command can be used with one argument to integrate and simulate a decay of a moving particle. (cf. also \ttt{beams}, \ttt{beams\_phi}, \ttt{beams\_momentum}, \ttt{beams\_pol\_density}, \ttt{beams\_pol\_fraction}) %%%%% \item \ttt{by} \newline Constructor that replaces the default sorting criterion (according to PDG codes) of the ($\to$) \ttt{sort} function on particle lists/subevents by one given by a unary or binary particle observable: \ttt{sort by {\em } [{\em } [, {\em }] ]}. (cf. also \ttt{sort}, \ttt{extract}, \ttt{join}, \ttt{collect}, \ttt{combine}, \ttt{+}) %%%%% \item \ttt{ceiling} \newline This is a function \ttt{ceiling ({\em })} that gives the least integer greater than or equal to \ttt{{\em }}, e.g. \ttt{int i = ceiling (4.56789)} gives \ttt{i = 5}. (cf. also \ttt{int}, \ttt{nint}, \ttt{floor}) %%%%% \item \ttt{circe1} \newline Beam structure specifier for the \circeone\ structure function for beamstrahlung at a linear lepton collider: \ttt{beams = e1, E1 => circe1}. Note that this is a pair spectrum, so the specifier acts for both beams simultaneously. (cf. also \ttt{beams}, \ttt{?circe1\_photons}, \ttt{?circe1\_photon2}, \ttt{circe1\_sqrts}, \ttt{?circe1\_generate}, \ttt{?circe1\_map}, \ttt{circe1\_eps}, \newline \ttt{circe1\_mapping\_slope}, \ttt{circe1\_ver}, \ttt{circe1\_rev}, \ttt{\$circe1\_acc}, \ttt{circe1\_chat}) %%%%% \item \ttt{circe2} \newline Beam structure specifier for the lepton-collider structure function for photon spectra, \circetwo: \ttt{beams = A, A => circe2}. Note that this is a pair spectrum, an application to only one beam is not possible. (cf. also \ttt{beams}, \ttt{?circe2\_polarized}, \ttt{\$circe2\_file}, \ttt{\$circe2\_design}) %%%%% \item \ttt{clear} \newline This command allows to clear a variable set before: \ttt{clear ({\em })} resets the variable \ttt{{\em }} which could be the \ttt{beams}, the \ttt{unstable} settings, \ttt{sqrts}, any kind of \ttt{cuts} or \ttt{scale} expressions, any user-set variable etc. The syntax of the command is completely analogous to ($\to$) \ttt{show}. %%%%% \item \ttt{close\_out} \newline With the command, \ttt{close\_out ("{\em })} user-defined information like data or ($\to$) \ttt{printf} statements can be written out to a user-defined file. The command closes an I/O stream to an external file \ttt{{\em }}. (cf. also \ttt{open\_out}, \ttt{\$out\_file}, \ttt{printf}) %%%%% \item \ttt{cluster} \newline Command that allows to cluster all particles in a subevent to a set of jets: \ttt{cluster [{\em}]}. It also to cluster particles subject to a certain boolean condition, \ttt{cluster if {\em} [{\em}]}. At the moment only available if the \fastjet\ package is linked. (cf. also \ttt{jet\_r}, \ttt{combine}, \ttt{jet\_algorithm}, \ttt{kt\_algorithm}, \newline \ttt{cambridge\_[for\_passive\_]algorithm}, \ttt{antikt\_algorithm}, \ttt{plugin\_algorithm}, \newline \ttt{genkt\_[for\_passive\_]algorithm}, \ttt{ee\_kt\_algorithm}, \ttt{ee\_genkt\_algorithm}, \ttt{?keep\_flavors\_when\_clustering}) %%%%% \item \ttt{collect} \newline The \ttt{collect [{\em }]} operation collects all particles in the list \ttt{{\em }} into a one-entry subevent with a four-momentum of the sum of all four-momenta of non-overlapping particles in \ttt{{\em }}. (cf. also \ttt{combine}, \ttt{select}, \ttt{extract}, \ttt{sort}) %%%%% \item \ttt{complex} \newline Defines a complex variable. The syntax is e.g. \ttt{complex x = 2 + 3 * I}. (cf.~also \ttt{int}, \ttt{real}) %%%%% \item \ttt{combine} \newline The \ttt{combine [{\em }, {\em }]} operation makes a particle list whose entries are the result of adding (the momenta of) each pair of particles in the two input lists \ttt{list1}, {list2}. For example, \ttt{combine [incoming lepton, lepton]} constructs all mutual pairings of an incoming lepton with an outgoing lepton (an alias for the leptons has to be defined, of course). (cf. also \ttt{collect}, \ttt{select}, \ttt{extract}, \ttt{sort}, \ttt{+}) %%%%% \item \ttt{compile} \newline The \ttt{compile ()} command has no arguments (the parentheses can also been left out: /\ttt{compile ()}. The command is optional, it invokes the compilation of the process(es) (i.e. the matrix element file(s)) to be compiled as a shared library. This shared object file has the standard name \ttt{default\_lib.so} and resides in the \ttt{.libs} subdirectory of the corresponding user workspace. If the user has defined a different library name \ttt{lib\_name} with the \ttt{library} command, then WHIZARD compiles this as the shared object \ttt{.libs/lib\_name.so}. (This allows to split process classes and to avoid too large libraries.) Another possibility is to use the command \ttt{compile as "static\_name"}. This will compile and link the process library in a static way and create the static executable \ttt{static\_name} in the user workspace. (cf. also \ttt{library}) %%%%% \item \ttt{compile\_analysis} \newline The \ttt{compile\_analysis} statement does the same as the \ttt{write\_analysis} command, namely to tell \whizard\ to write the analysis setup by the user for the \sindarin\ input file under consideration. If no \ttt{\$out\_file} is provided, the histogram tables/plot data etc. are written to the default file \ttt{whizard\_analysis.dat}. In addition to \ttt{write\_analysis}, \ttt{compile\_analysis} also invokes the \whizard\ \LaTeX routines for producing postscript or PDF output of the data (unless the flag $\rightarrow$ \ttt{?analysis\_file\_only} is set to \ttt{true}). (cf. also \ttt{\$out\_file}, \ttt{write\_analysis}, \ttt{?analysis\_file\_only}) %%%%% \item \ttt{conjg} \newline Numerical function that takes the complex conjugate of its argument: \ttt{conjg ({\em })} yields \ttt{{\em }$^\ast$}. (cf. also \ttt{abs}, \ttt{sgn}, \ttt{mod}, \ttt{modulo}) %%%%% \item \ttt{cos} \newline Numerical function \ttt{cos ({\em })} that calculates the cosine trigonometric function of real and complex numerical numbers or variables. (cf. also \ttt{sin}, \ttt{tan}, \ttt{asin}, \ttt{acos}, \ttt{atan}) %%%%% \item \ttt{cosh} \newline Numerical function \ttt{cosh ({\em })} that calculates the hyperbolic cosine function of real and complex numerical numbers or variables. Note that its inverse function is part of the \ttt{Fortran2008} status and hence not realized. (cf. also \ttt{sinh}, \ttt{tanh}) %%%%% \item \ttt{count} \newline Subevent function that counts the number of particles or particle pairs in a subevent: \ttt{count [{\em } [, {\em }]]}. This can also be a counting subject to a condition: \ttt{count if {\em } [{\em } [, {\em }]]}. %%%%% \item \ttt{cuts} \newline This command defines the cuts to be applied to certain processes. The syntax is: \ttt{cuts = {\em } {\em } [{\em }]}, where the cut expression must be initialized with a logical classifier \ttt{log\_class} like \ttt{all}, \ttt{any}, \ttt{no}. The logical expression \ttt{log\_expr} contains the cut to be evaluated. Note that this need not only be a kinematical cut expression like \ttt{E > 10 GeV} or \ttt{5 degree < Theta < 175 degree}, but can also be some sort of trigger expression or event selection. Whether the expression is evaluated on particles or pairs of particles depends on whether the discriminating variable is unary or binary, \ttt{Dist} being obviously binary, \ttt{Pt} being unary. Note that some variables are both unary and binary, e.g. the invariant mass $M$. Cut expressions can be connected by the logical connectives \ttt{and} and \ttt{or}. The \ttt{cuts} statement acts on all subsequent process integrations and analyses until a new \ttt{cuts} statement appears. (cf. also \ttt{all}, \ttt{any}, \ttt{Dist}, \ttt{E}, \ttt{M}, \ttt{no}, \ttt{Pt}). %%%%% \item \ttt{debug} \newline Specifier for the \ttt{sample\_format} command to demand the generation of the very verbose \whizard\ ASCII event file format intended for debugging. (cf. also \ttt{\$sample}, \ttt{sample\_format}, \ttt{\$sample\_normalization}) %%%%% \item \ttt{degree} \newline Expression specifying the physical unit of degree for angular variables, e.g. the cut expression function \ttt{Theta}. (if no unit is specified for angular variables, radians are used; cf. \ttt{rad}, \ttt{mrad}). %%%% \item \ttt{Dist} \newline Binary observable specifier, that gives the $\eta$-$\phi$- (pseudorapidity-azimuth) distance $R = \sqrt{(\Delta \eta)^2 + (\Delta\phi)^2}$ between the momenta of the two particles: \ttt{eval Dist [jet, jet]}. (cf. also \ttt{eval}, \ttt{cuts}, \ttt{selection}, \ttt{Theta}, \ttt{Eta}, \ttt{Phi}) %%%%% \item \ttt{dump} \newline Specifier for the \ttt{sample\_format} command to demand the generation of the intrinsic \whizard\ event record format (output of the \ttt{particle\_t} type container). (cf. also \ttt{\$sample}, \ttt{sample\_format}, \ttt{\$sample\_normalization} %%%%% \item \ttt{E} \newline Unary (binary) observable specifier for the energy of a single (two) particle(s), e.g. \ttt{eval E ["W+"]}, \ttt{all E > 200 GeV [b, B]}. (cf. \ttt{eval}, \ttt{cuts}, \ttt{selection}) %%%%% \item \ttt{else} \label{sindarin_else}\newline Constructor for providing an alternative in a conditional clause: \ttt{if {\em } then {\em } else {\em } endif}. (cf. also \ttt{if}, \ttt{elsif}, \ttt{endif}, \ttt{then}). %%%%% \item \ttt{elsif} \newline Constructor for concatenating more than one conditional clause with each other: \ttt{if {\em } then {\em } elsif {\em } then {\em } \ldots endif}. (cf. also \ttt{if}, \ttt{else}, \ttt{endif}, \ttt{then}). %%%%% \item \ttt{endif} \newline Mandatory constructor to conclude a conditional clause: \ttt{if {\em } then \ldots endif}. (cf. also \ttt{if}, \ttt{else}, \ttt{elsif}, \ttt{then}). %%%%% \item \ttt{energy\_scan} \newline Beam structure specifier for the energy scan structure function: \ttt{beams = e1, E1 => energy\_scan}. This pair spectrum that has to be applied to both beams simultaneously can be used to scan over a range of collider energies without using the \ttt{scan} command. (cf. also \ttt{beams}, \ttt{scan}, \ttt{?energy\_scan\_normalize}) %%%%% \item \ttt{epa} \newline Beam structure specifier for the equivalent-photon approximation (EPA), i.e the Weizs\"acker-Williams structure function: e.g. \ttt{beams = e1, E1 => epa} (applied to both beams), or e.g. \ttt{beams = e1, u => epa, none} (applied to only one beam). (cf. also \ttt{beams}, \ttt{epa\_alpha}, \ttt{epa\_x\_min}, \ttt{epa\_mass}, \ttt{epa\_q\_max}, \ttt{epa\_q\_min}, \ttt{?epa\_recoil}, \ttt{?epa\_keep\_energy}) %%%%% \item \ttt{Eta} \newline Unary and also binary observable specifier, that as a unary observable gives the pseudorapidity of a particle momentum. The pseudorapidity is given by $\eta = - \log \left[ \tan (\theta/2) \right]$, where $\theta$ is the angle with the beam direction. As a binary observable, it gives the pseudorapidity difference between the momenta of two particles, where $\theta$ is the enclosed angle: \ttt{eval Eta [e1]}, \ttt{all abs (Eta) < 3.5 [jet, jet]}. (cf. also \ttt{eval}, \ttt{cuts}, \ttt{selection}, \ttt{Rap}, \ttt{abs}) %%%%% \item \ttt{eV} \newline Physical unit, stating that the corresponding number is in electron volt. (cf. also \ttt{keV}, \ttt{meV}, \ttt{MeV}, \ttt{GeV}, \ttt{TeV}) %%%%% \item \ttt{eval} \newline Evaluator that tells \whizard\ to evaluate the following expr: \ttt{eval {\em }}. Examples are: \ttt{eval Rap [e1]}, \ttt{eval M / 1 GeV [combine [q,Q]]} etc. (cf. also \ttt{cuts}, \ttt{selection}, \ttt{record}) %%%%% \item \ttt{ewa} \newline Beam structure specifier for the equivalent-photon approximation (EWA): e.g. \ttt{beams = e1, E1 => ewa} (applied to both beams), or e.g. \ttt{beams = e1, u => ewa, none} (applied to only one beam). (cf. also \ttt{beams}, \ttt{ewa\_x\_min}, \ttt{ewa\_pt\_max}, \ttt{ewa\_mass}, \ttt{?ewa\_keep\_energy}, \ttt{?ewa\_recoil}) %%%%% \item \ttt{exec} \newline Constructor \ttt{exec ("{\em }")} that demands WHIZARD to execute/run the command \ttt{cmd\_name}. For this to work that specific command must be present either in the path of the operating system or as a command in the user workspace. %%%%% \item \ttt{exit} \newline Command to finish the \whizard\ run (and not execute any further code beyond the appearance of \ttt{exit} in the \sindarin\ file. The command (which is the same as $\to$ \ttt{quit}) allows for an argument, \ttt{exit ({\em })}, where the expression can be executed, e.g. a screen message or an exit code. %%%%% \item \ttt{exp} \newline Numerical function \ttt{exp ({\em })} that calculates the exponential of real and complex numerical numbers or variables. (cf. also \ttt{sqrt}, \ttt{log}, \ttt{log10}) %%%%% \item \ttt{expect} \newline The binary function \ttt{expect} compares two numerical expressions whether they fulfill a certain ordering condition or are equal up to a specific uncertainty or tolerance which can bet set by the specifier \ttt{tolerance}, i.e. in principle it checks whether a logical expression is true. The \ttt{expect} function does actually not just check a value for correctness, but also records its result. If failures are present when the program terminates, the exit code is nonzero. The syntax is \ttt{expect ({\em } {\em } {\em })}, where \ttt{{\em }} and \ttt{{\em }} are two numerical values (or corresponding variables) and \ttt{{\em }} is one of the following logical comparators: \ttt{<}, \ttt{>}, \ttt{<=}, \ttt{>=}, \ttt{==}, \ttt{<>}. (cf. also \ttt{<}, \ttt{>}, \ttt{<=}, \ttt{>=}, \ttt{==}, \ttt{<>}, \ttt{tolerance}). %%%%% \item \ttt{extract} \newline Subevent function that either extracts the first element of a particle list/subevent: \ttt{extract [ {\em }]}, or the element at position \ttt{} of the particle list: \ttt{extract {\em index } [ {\em }]}. Negative index values count from the end of the list. (cf. also \ttt{sort}, \ttt{combine}, \ttt{collect}, \ttt{+}, \ttt{index}) %%%%% \item \ttt{factorization\_scale} \newline This is a command, \ttt{factorization\_scale = {\em }}, that sets the factorization scale of a process or list of processes. It overwrites a possible scale set by the ($\to$) \ttt{scale} command. \ttt{{\em }} can be any kinematic expression that leads to a result of momentum dimension one, e.g. \ttt{100 GeV}, \ttt{eval Pt [e1]}. (cf. also \ttt{renormalization\_scale}). %%%%% \item \ttt{false} \newline Constructor stating that a logical expression or variable is false, e.g. \ttt{?{\em } = false}. (cf. also \ttt{true}). %%%%% \item \ttt{fbarn} \newline Physical unit, stating that a number is in femtobarns ($10^{-15}$ barn). (cf. also \ttt{nbarn}, \ttt{abarn}, \ttt{pbarn}) %%%%% \item \ttt{floor} \newline This is a function \ttt{floor ({\em })} that gives the greatest integer less than or equal to \ttt{{\em }}, e.g. \ttt{int i = floor (4.56789)} gives \ttt{i = 4}. (cf. also \ttt{int}, \ttt{nint}, \ttt{ceiling}) %%%%% \item \ttt{gaussian} \newline Beam structure specifier that imposes a Gaussian energy distribution, separately for each beam. The $\sigma$ values are set by \ttt{gaussian\_spread1} and \ttt{gaussian\_spread2}, respectively. %%%%% \item \ttt{GeV} \newline Physical unit, energies in $10^9$ electron volt. This is the default energy unit of WHIZARD. (cf. also \ttt{eV}, \ttt{keV}, \ttt{MeV}, \ttt{meV}, \ttt{TeV}) %%%%% \item \ttt{graph} \newline This command defines the necessary information regarding producing a graph of a function in \whizard's internal graphical \gamelan\ output. The syntax is: \ttt{graph {\em } \{ {\em } \}}. The record with name \ttt{{\em }} has to be defined, either before or after the graph definition. Possible optional arguments of the \ttt{graph} command are the minimal and maximal values of the axes (\ttt{x\_min}, \ttt{x\_max}, \ttt{y\_min}, \ttt{y\_max}). (cf. \ttt{plot}, \ttt{histogram}, \ttt{record}) %%%%% \item \ttt{Hel} \newline Unary observable specifier that allows to specify the helicity of a particle, e.g. \ttt{all Hel == -1 [e1]} in a selection. (cf. also \ttt{eval}, \ttt{cuts}, \ttt{selection}) %%%%% \item \ttt{hepevt} \newline Specifier for the \ttt{sample\_format} command to demand the generation of HEPEVT ASCII event files. (cf. also \ttt{\$sample}, \ttt{sample\_format}) %%%%% \item \ttt{hepevt\_verb} \newline Specifier for the \ttt{sample\_format} command to demand the generation of the extended or verbose version of HEPEVT ASCII event files. (cf. also \ttt{\$sample}, \ttt{sample\_format}) %%%%% \item \ttt{hepmc} \newline Specifier for the \ttt{sample\_format} command to demand the generation of HepMC ASCII event files. Note that this is only available if the HepMC package is installed and correctly linked. (cf. also \ttt{\$sample}, \ttt{sample\_format}, \ttt{?hepmc\_output\_cross\_section}) %%%%% \item \ttt{histogram} \newline This command defines the necessary information regarding plotting data as a histogram, in the form of: \ttt{histogram {\em } \{ {\em } \}}. The record with name \ttt{{\em }} has to be defined, either before or after the histogram definition. Possible optional arguments of the \ttt{histogram} command are the minimal and maximal values of the axes (\ttt{x\_min}, \ttt{x\_max}, \ttt{y\_min}, \ttt{y\_max}). (cf. \ttt{graph}, \ttt{plot}, \ttt{record}) %%%%% \item \ttt{if} \newline Conditional clause with the construction \ttt{if {\em } then {\em } [else {\em } \ldots] endif}. Note that there must be an \ttt{endif} statement. For more complicated expressions it is better to use expressions in parentheses: \ttt{if ({\em }) then \{{\em }\} else \{{\em }\} endif}. Examples are a selection of up quarks over down quarks depending on a logical variable: \ttt{if ?ok then u else d}, or the setting of an integer variable depending on the rapidity of some particle: \ttt{if (eta > 0) then \{ a = +1\} else \{ a = -1\}}. (cf. also \ttt{elsif}, \ttt{endif}, \ttt{then}) %%%%% \item \ttt{in} \newline Second part of the constructor to let a variable be local to an expression. It has the syntax \ttt{let {\em } = {\em } in {\em }}. E.g. \ttt{let int a = 3 in let int b = 4 in {\em }} (cf. also \ttt{let}) %%%%% \item \ttt{include} \newline The \ttt{include} statement, \ttt{include ("file.sin")} allows to include external \sindarin\ files \ttt{file.sin} into the main WHIZARD input file. A standard example is the inclusion of the standard cut file \ttt{default\_cuts.sin}. %%%%% \item \ttt{incoming} \newline Constructor that specifies particles (or subevents) as incoming. It is used in cuts, analyses or selections, e.g. \ttt{cuts = all Theta > 20 degree [incoming lepton, lepton]}. (cf. also \ttt{beam}, \ttt{outgoing}, \ttt{cuts}, \ttt{analysis}, \ttt{selection}, \ttt{record}) %%%%% \item \ttt{index} \newline Specifies the position of the element of a particle to be extracted by the subevent function ($\to$) \ttt{extract}: \ttt{extract {\em index } [ {\em }]}. Negative index values count from the end of the list. (cf. also \ttt{extract}, \ttt{sort}, \ttt{combine}, \ttt{collect}, \ttt{+}) %%%%% \item \ttt{int} \newline 1) This is a constructor to specify integer constants in the input file. Strictly speaking, it is a unary function setting the value \ttt{int\_val} of the integer variable \ttt{int\_var}: \ttt{int {\em } = {\em }}. Note that is mandatory for all user-defined variables. (cf. also \ttt{real} and \ttt{complex}) 2) It is a function \ttt{int ({\em })} that converts real and complex numbers (here their real parts) into integers. (cf. also \ttt{nint}, \ttt{floor}, \ttt{ceiling}) %%%%% \item \ttt{integrate} \newline The \ttt{integrate ({\em }) \{ {\em } \}} command invokes the integration (phase-space generation and Monte-Carlo sampling) of the process \ttt{proc\_name} (which can also be a list of processes) with the integration options \ttt{{\em }}. Possible options are (1) via \ttt{\$integration\_method = "{\em }"} the integration method (the default being VAMP), (2) the number of iterations and calls per integration during the Monte-Carlo phase-space integration via the \ttt{iterations} specifier; (3) goal for the accuracy, error or relative error (\ttt{accuracy\_goal}, \ttt{error\_goal}, \ttt{relative\_error\_goal}). (4) Invoking only phase space generation (\ttt{?phs\_only = true}), (5) making test calls of the matrix element. (cf. also \ttt{iterations}, \ttt{accuracy\_goal}, \ttt{error\_goal}, \ttt{relative\_error\_goal}, \ttt{error\_threshold}) %%%%% \item \ttt{isr} \newline Beam structure specifier for the lepton-collider/QED initial-state radiation (ISR) structure function: e.g. \ttt{beams = e1, E1 => isr} (applied to both beams), or e.g. \ttt{beams = e1, u => isr, none} (applied to only one beam). (cf. also \ttt{beams}, \ttt{isr\_alpha}, \ttt{isr\_q\_max}, \ttt{isr\_mass}, \ttt{isr\_order}, \ttt{?isr\_recoil}, \ttt{?isr\_keep\_energy}) %%%%% \item \ttt{iterations} \qquad (default: internal heuristics) \newline Option to set the number of iterations and calls per iteration during the Monte-Carlo phase-space integration process. The syntax is \ttt{iterations = {\em }:{\em }}. Note that this can be also a list, separated by colons, which breaks up the integration process into passes of the specified number of integrations and calls each. It works for all integration methods. For VAMP, there is the additional option to specify whether grids and channel weights should be adapted during iterations (\ttt{"g"}, \ttt{"w"}, \ttt{"gw"} for both, or \ttt{""} for no adaptation). (cf. also \ttt{integrate}, \ttt{accuracy\_goal}, \ttt{error\_goal}, \ttt{relative\_error\_goal}, \ttt{error\_threshold}). %%%%% \item \ttt{join} \newline Subevent function that concatenates two particle lists/subevents if there is no overlap: \ttt{join [{\em }, {\em }]}. The joining of the two lists can also be made depending on a condition: \ttt{join if {\em } [{\em }, {\em }]}. (cf. also \ttt{\&}, \ttt{collect}, \ttt{combine}, \ttt{extract}, \ttt{sort}, \ttt{+}) %%%%% \item \ttt{keV} \newline Physical unit, energies in $10^3$ electron volt. (cf. also \ttt{eV}, \ttt{meV}, \ttt{MeV}, \ttt{GeV}, \ttt{TeV}) %%%%% \item \ttt{kT} \newline Binary particle observable that represents a jet $k_T$ clustering measure: \ttt{kT [j1, j2]} gives the following kinematic expression: $2 \min(E_{j1}^2, E_{j2}^2) / Q^2 \times (1 - \cos\theta_{j1,j2})$. At the moment, $Q^2 = 1$. %%%%% \item \ttt{let} \newline This allows to let a variable be local to an expression. It has the syntax \ttt{let {\em } = {\em } in {\em }}. E.g. \ttt{let int a = 3 in let int b = 4 in {\em }} (cf. also \ttt{in}) %%%%% \item \ttt{lha} \newline Specifier for the \ttt{sample\_format} command to demand the generation of the \whizard\ version 1 style (deprecated) LHA ASCII event format files. (cf. also \ttt{\$sample}, \newline \ttt{sample\_format}) %%%%% \item \ttt{lhapdf} \newline This is a beams specifier to demand calling \lhapdf\ parton densities as structure functions to integrate processes in hadron collisions. Note that this only works if the external \lhapdf\ library is present and correctly linked. (cf. \ttt{beams}, \ttt{\$lhapdf\_dir}, \ttt{\$lhapdf\_file}, \ttt{lhapdf\_photon}, \ttt{\$lhapdf\_photon\_file}, \ttt{lhapdf\_member}, \ttt{lhapdf\_photon\_scheme}) %%%%% \item \ttt{lhapdf\_photon} \newline This is a beams specifier to demand calling \lhapdf\ parton densities as structure functions to integrate processes in hadron collisions with a photon as initializer of the hard scattering process. Note that this only works if the external \lhapdf\ library is present and correctly linked. (cf. \ttt{beams}, \ttt{lhapdf}, \ttt{\$lhapdf\_dir}, \ttt{\$lhapdf\_file}, \ttt{\$lhapdf\_photon\_file}, \ttt{lhapdf\_member}, \ttt{lhapdf\_photon\_scheme}) %%%%% \item \ttt{lhef} \newline Specifier for the \ttt{sample\_format} command to demand the generation of the Les Houches Accord (LHEF) event format files, with XML headers. There are several different versions of this format, which can be selected via the \ttt{\$lhef\_version} specifier (cf. also \ttt{\$sample}, \ttt{sample\_format}, \ttt{\$lhef\_version}, \ttt{\$lhef\_extension}, \ttt{?lhef\_write\_sqme\_prc}, \newline \ttt{?lhef\_write\_sqme\_ref}, \ttt{?lhef\_write\_sqme\_alt}) %%%%% \item \ttt{library} \newline The command \ttt{library = "{\em }"} allows to specify a separate shared object library archive \ttt{lib\_name.so}, not using the standard library \ttt{default\_lib.so}. Those libraries (when using shared libraries) are located in the \ttt{.libs} subdirectory of the user workspace. Specifying a separate library is useful for splitting up large lists of processes, or to restrict a larger number of different loaded model files to one specific process library. (cf. also \ttt{compile}, \ttt{\$library\_name}) %%%%% \item \ttt{log} \newline Numerical function \ttt{log ({\em })} that calculates the natural logarithm of real and complex numerical numbers or variables. (cf. also \ttt{sqrt}, \ttt{exp}, \ttt{log10}) %%%%% \item \ttt{log10} \newline Numerical function \ttt{log10 ({\em })} that calculates the base 10 logarithm of real and complex numerical numbers or variables. (cf. also \ttt{sqrt}, \ttt{exp}, \ttt{log}) %%%%% \item \ttt{long} \newline Specifier for the \ttt{sample\_format} command to demand the generation of the long variant of HEPEVT ASCII event files. (cf. also \ttt{\$sample}, \ttt{sample\_format}) %%%%% \item \ttt{M} \newline Unary (binary) observable specifier for the (signed) mass of a single (two) particle(s), e.g. \ttt{eval M [e1]}, \ttt{any M = 91 GeV [e2, E2]}. (cf. \ttt{eval}, \ttt{cuts}, \ttt{selection}) %%%%% \item \ttt{M2} \newline Unary (binary) observable specifier for the mass squared of a single (two) particle(s), e.g. \ttt{eval M2 [e1]}, \ttt{all M2 > 2*mZ [e2, E2]}. (cf. \ttt{eval}, \ttt{cuts}, \ttt{selection}) %%%%% \item \ttt{max} \newline Numerical function with two arguments \ttt{max ({\em }, {\em })} that gives the maximum of the two arguments: $\max (var1, var2)$. It can act on all combinations of integer and real variables. Example: \ttt{real heavier\_mass = max (mZ, mH)}. (cf. also \ttt{min}) %%%%% \item \ttt{meV} \newline Physical unit, stating that the corresponding number is in $10^{-3}$ electron volt. (cf. also \ttt{eV}, \ttt{keV}, \ttt{MeV}, \ttt{GeV}, \ttt{TeV}) %%%%% \item \ttt{MeV} \newline Physical unit, energies in $10^6$ electron volt. (cf. also \ttt{eV}, \ttt{keV}, \ttt{meV}, \ttt{GeV}, \ttt{TeV}) %%%%% \item \ttt{min} \newline Numerical function with two arguments \ttt{min ({\em }, {\em })} that gives the minimum of the two arguments: $\min (var1, var2)$. It can act on all combinations of integer and real variables. Example: \ttt{real lighter\_mass = min (mZ, mH)}. (cf. also \ttt{max}) %%%%% \item \ttt{mod} \newline Numerical function for integer and real numbers \ttt{mod (x, y)} that computes the remainder of the division of \ttt{x} by \ttt{y} (which must not be zero). (cf. also \ttt{abs}, \ttt{conjg}, \ttt{sgn}, \ttt{modulo}) %%%%% \item \ttt{model} \qquad (default: \ttt{SM}) \newline With this specifier, \ttt{model = {\em }}, one sets the hard interaction physics model for the processes defined after this model specification. The list of available models can be found in Table \ref{tab:models}. Note that the model specification can appear arbitrarily often in a \sindarin\ input file, e.g. for compiling and running processes defined in different physics models. (cf. also \ttt{\$model\_name}) %%%%% \item \ttt{modulo} \newline Numerical function for integer and real numbers \ttt{modulo (x, y)} that computes the value of $x$ modulo $y$. (cf. also \ttt{abs}, \ttt{conjg}, \ttt{sgn}, \ttt{mod}) %%%%% \item \ttt{mokka} \newline Specifier for the \ttt{sample\_format} command to demand the generation of the MOKKA variant for HEPEVT ASCII event files. (cf. also \ttt{\$sample}, \ttt{sample\_format}) %%%%% \item \ttt{mrad} \newline Expression specifying the physical unit of milliradians for angular variables. This default in \whizard\ is \ttt{rad}. (cf. \ttt{degree}, \ttt{rad}). %%%%% \item \ttt{nbarn} \newline Physical unit, stating that a number is in nanobarns ($10^{-9}$ barn). (cf. also \ttt{abarn}, \ttt{fbarn}, \ttt{pbarn}) %%%%% \item \ttt{n\_in} \newline Integer variable that accesses the number of incoming particles of a process. It can be used in cuts or in an analysis. (cf. also \ttt{sqrts\_hat}, \ttt{cuts}, \ttt{record}, \ttt{n\_out}, \ttt{n\_tot}) %%%%% \item \ttt{Nacl} \newline Unary observable specifier that returns the total number of open anticolor lines of a particle or subevent (i.e., composite particle). Defined only if \ttt{?colorize\_subevt} is true.. (cf. also \ttt{Ncol}, \ttt{?colorize\_subevt}) %%%%% \item \ttt{Ncol} \newline Unary observable specifier that returns the total number of open color lines of a particle or subevent (i.e., composite particle). Defined only if \ttt{?colorize\_subevt} is true.. (cf. also \ttt{Nacl}, \ttt{?colorize\_subevt}) %%%%% \item \ttt{nint} \newline This is a function \ttt{nint ({\em })} that converts real numbers into the closest integer, e.g. \ttt{int i = nint (4.56789)} gives \ttt{i = 5}. (cf. also \ttt{int}, \ttt{floor}, \ttt{ceiling}) %%%%% \item \ttt{no} \newline \ttt{no} is a function that works on a logical expression and a list, \ttt{no {\em } [{\em }]}, and returns \ttt{true} if and only if \ttt{log\_expr} is fulfilled for {\em none} of the entries in \ttt{list}, and \ttt{false} otherwise. Examples: \ttt{no Pt < 100 GeV [lepton]} checks whether no lepton is softer than 100 GeV. It is the logical opposite of the function \ttt{all}. Logical expressions with \ttt{no} can be logically combined with \ttt{and} and \ttt{or}. (cf. also \ttt{all}, \ttt{any}, \ttt{and}, and \ttt{or}) %%%%% \item \ttt{none} \newline Beams specifier that can used to explicitly {\em not} apply a structure function to a beam, e.g. in HERA physics: \ttt{beams = e1, P => none, pdf\_builtin}. (cf. also \ttt{beams}) %%%%% \item \ttt{not} \newline This is the standard logical negation that converts true into false and vice versa. It is applied to logical values, e.g. cut expressions. (cf. also \ttt{and}, \ttt{or}). %%%%% \item \ttt{n\_out} \newline Integer variable that accesses the number of outgoing particles of a process. It can be used in cuts or in an analysis. (cf. also \ttt{sqrts\_hat}, \ttt{cuts}, \ttt{record}, \ttt{n\_in}, \ttt{n\_tot}) %%%%% \item \ttt{n\_tot} \newline Integer variable that accesses the total number of particles (incoming plus outgoing) of a process. It can be used in cuts or in an analysis. (cf. also \ttt{sqrts\_hat}, \ttt{cuts}, \ttt{record}, \ttt{n\_in}, \ttt{n\_out}) %%%%% \item \ttt{observable} \newline With this, \ttt{observable = {\em }}, the user is able to define a variable specifier \ttt{obs\_spec} for observables. These can be reused in the analysis, e.g. as a \ttt{record}, as functions of the fundamental kinematical variables of the processes. (cf. \ttt{analysis}, \ttt{record}) %%%%% \item \ttt{open\_out} \newline With the command, \ttt{open\_out ("{\em })} user-defined information like data or ($\to$) \ttt{printf} statements can be written out to a user-defined file. The command opens an I/O stream to an external file \ttt{{\em }}. (cf. also \ttt{close\_out}, \ttt{\$out\_file}, \ttt{printf}) %%%%% \item \ttt{or} \newline This is the standard two-place logical connective that has the value true if one of its operands is true, otherwise a value of false. It is applied to logical values, e.g. cut expressions. (cf. also \ttt{and}, \ttt{not}). %%%%% \item \ttt{outgoing} \newline Constructor that specifies particles (or subevents) as outgoing. It is used in cuts, analyses or selections, e.g. \ttt{cuts = all Theta > 20 degree [incoming lepton, outgoing lepton]}. Note that the \ttt{outgoing} keyword is redundant and included only for completeness: \ttt{outgoing lepton} has the same meaning as \ttt{lepton}. (cf. also \ttt{beam}, \ttt{incoming}, \ttt{cuts}, \ttt{analysis}, \ttt{selection}, \ttt{record}) %%%%% \item \ttt{P} \newline Unary (binary) observable specifier for the spatial momentum $\sqrt{\vec{p}^2}$ of a single (two) particle(s), e.g. \ttt{eval P ["W+"]}, \ttt{all P > 200 GeV [b, B]}. (cf. \ttt{eval}, \ttt{cuts}, \ttt{selection}) %%%%% \item \ttt{pbarn} \newline Physical unit, stating that a number is in picobarns ($10^{-12}$ barn). (cf. also \ttt{abarn}, \ttt{fbarn}, \ttt{nbarn}) %%%%% \item \ttt{pdf\_builtin} \newline This is a beams specifier for \whizard's internal PDF structure functions to integrate processes in hadron collisions. (cf. \ttt{beams}, \ttt{pdf\_builtin\_photon}, \ttt{\$pdf\_builtin\_file}) %%%%% \item \ttt{pdf\_builtin\_photon} \newline This is a beams specifier for \whizard's internal PDF structure functions to integrate processes in hadron collisions with a photon as initializer of the hard scattering process. (cf. \ttt{beams}, \ttt{\$pdf\_builtin\_file}) %%%%% \item \ttt{PDG} \newline Unary observable specifier that allows to specify the PDG code of a particle, e.g. \ttt{eval PDG [e1]}, giving \ttt{11}. (cf. also \ttt{eval}, \ttt{cuts}, \ttt{selection}) %%%%% \item \ttt{Phi} \newline Unary and also binary observable specifier, that as a unary observable gives the azimuthal angle of a particle's momentum in the detector frame (beam into $+z$ direction). As a binary observable, it gives the azimuthal difference between the momenta of two particles: \ttt{eval Phi [e1]}, \ttt{all Phi > Pi [jet, jet]}. (cf. also \ttt{eval}, \ttt{cuts}, \ttt{selection}, \ttt{Theta}) %%%%% \item \ttt{photon\_isolation} \newline Logical function \ttt{photon\_isolation if {\em } [{\em } , {\em }]} that cuts out event where the photons in \ttt{{\em }} do not fulfill the condition \ttt{{\em }} and are not isolated from hadronic (and electromagnetic) activity, i.e. the photon fragmentation. (cf. also \ttt{cluster}, \ttt{collect}, \ttt{combine}, \ttt{extract}, \ttt{select}, \ttt{sort}, \ttt{+}) %%%%% \item \ttt{Pl} \newline Unary (binary) observable specifier for the longitudinal momentum ($p_z$ in the c.m. frame) of a single (two) particle(s), e.g. \ttt{eval Pl ["W+"]}, \ttt{all Pl > 200 GeV [b, B]}. (cf. \ttt{eval}, \ttt{cuts}, \ttt{selection}) %%%%% \item \ttt{plot} \newline This command defines the necessary information regarding plotting data as a graph, in the form of: \ttt{plot {\em } \{ {\em } \}}. The record with name \ttt{{\em }} has to be defined, either before or after the plot definition. Possible optional arguments of the \ttt{plot} command are the minimal and maximal values of the axes (\ttt{x\_min}, \ttt{x\_max}, \ttt{y\_min}, \ttt{y\_max}). (cf. \ttt{graph}, \ttt{histogram}, \ttt{record}) %%%%% \item \ttt{polarized} \newline Constructor to instruct \whizard\ to retain polarization of the corresponding particles in the generated events: \ttt{polarized {\em } [, {\em } , ...]}. (cf. also \ttt{unpolarized}, \ttt{simulate}, \ttt{?polarized\_events}) %%%%% \item \ttt{printf} \newline Command that allows to print data as screen messages, into logfiles or into user-defined output files: \ttt{printf "{\em }"}. There exist format specifiers, very similar to the \ttt{C} command \ttt{printf}, e.g. \ttt{printf "\%i" (123)}. (cf. also \ttt{open\_out}, \ttt{close\_out}, \ttt{\$out\_file}, \ttt{?out\_advance}, \ttt{sprintf}, \ttt{\%d}, \ttt{\%i}, \ttt{\%e}, \ttt{\%f}, \ttt{\%g}, \ttt{\%E}, \ttt{\%F}, \ttt{\%G}, \ttt{\%s}) %%%%% \item \ttt{process} \newline Allows to set a hard interaction process, either for a decay process with name \ttt{{\em }} as \ttt{process {\em } = {\em } => {\em }, {\em }, ...}, or for a scattering process with name \ttt{{\em } = {\em }, {\em } => {\em }, {\em }, ...}. Note that there can be arbitrarily many processes to be defined in a \sindarin\ input file. There are two options for particle/process sums: flavor sums: \ttt{{\em }:{\em }:...}, where all masses have to be identical, and inclusive sums, \ttt{{\em } + {\em } + ...}. The latter can be done on the level of individual particles, or sums over whole final states. Here, masses can differ, and terms will be translated into different process components. The \ttt{process} command also allows for optional arguments, e.g. to specify a numerical identifier (cf. \ttt{process\_num\_id}), the method how to generate the code for the matrix element(s): \ttt{\$method}, possible methods are either with the \oMega\ matrix element generator, using template matrix elements with different normalizations, or completely internal matrix element; for \oMega\ matrix elements there is also the possibility to specify possible restrictions (cf. \ttt{\$restrictions}). %%%%% \item \ttt{Pt} \newline Unary (binary) observable specifier for the transverse momentum ($\sqrt{p_x^2 + p_y^2}$ in the c.m. frame) of a single (two) particle(s), e.g. \ttt{eval Pt ["W+"]}, \ttt{all Pt > 200 GeV [b, B]}. (cf. \ttt{eval}, \ttt{cuts}, \ttt{selection}) %%%%% \item \ttt{Px} \newline Unary (binary) observable specifier for the $x$-component of the momentum of a single (two) particle(s), e.g. \ttt{eval Px ["W+"]}, \ttt{all Px > 200 GeV [b, B]}. (cf. \ttt{eval}, \ttt{cuts}, \ttt{selection}) %%%%% \item \ttt{Py} \newline Unary (binary) observable specifier for the $y$-component of the momentum of a single (two) particle(s), e.g. \ttt{eval Py ["W+"]}, \ttt{all Py > 200 GeV [b, B]}. (cf. \ttt{eval}, \ttt{cuts}, \ttt{selection}) %%%%% \item \ttt{Pz} \newline Unary (binary) observable specifier for the $z$-component of the momentum of a single (two) particle(s), e.g. \ttt{eval Pz ["W+"]}, \ttt{all Pz > 200 GeV [b, B]}. (cf. \ttt{eval}, \ttt{cuts}, \ttt{selection}) %%%%% \item \ttt{quit} \newline Command to finish the \whizard\ run (and not execute any further code beyond the appearance of \ttt{quit} in the \sindarin\ file. The command (which is the same as $\to$ \ttt{exit}) allows for an argument, \ttt{quit ({\em })}, where the expression can be executed, e.g. a screen message or an quit code. %%%%% \item \ttt{rad} \newline Expression specifying the physical unit of radians for angular variables. This is the default in \whizard. (cf. \ttt{degree}, \ttt{mrad}). %%%%% \item \ttt{Rap} \newline Unary and also binary observable specifier, that as a unary observable gives the rapidity of a particle momentum. The rapidity is given by $y = \frac12 \log \left[ (E + p_z)/(E-p_z) \right]$. As a binary observable, it gives the rapidity difference between the momenta of two particles: \ttt{eval Rap [e1]}, \ttt{all abs (Rap) < 3.5 [jet, jet]}. (cf. also \ttt{eval}, \ttt{cuts}, \ttt{selection}, \ttt{Eta}, \ttt{abs}) %%%%% \item \ttt{read\_slha} \newline Tells \whizard\ to read in an input file in the SUSY Les Houches accord (SLHA), as \ttt{read\_slha ("slha\_file.slha")}. Note that the files for the use in \whizard\ should have the suffix \ttt{.slha}. (cf. also \ttt{write\_slha}, \ttt{?slha\_read\_decays}, \ttt{?slha\_read\_input}, \ttt{?slha\_read\_spectrum}) %%%%% \item \ttt{real} \newline This is a constructor to specify real constants in the input file. Strictly speaking, it is a unary function setting the value \ttt{real\_val} of the real variable \ttt{real\_var}: \ttt{real {\em } = {\em }}. (cf. also \ttt{int} and \ttt{complex}) %%%%% \item \ttt{real\_epsilon}\\ Predefined real; the relative uncertainty intrinsic to the floating point type of the \fortran\ compiler with which \whizard\ has been built. %%%%% \item \ttt{real\_precision}\\ Predefined integer; the decimal precision of the floating point type of the \fortran\ compiler with which \whizard\ has been built. %%%%% \item \ttt{real\_range}\\ Predefined integer; the decimal range of the floating point type of the \fortran\ compiler with which \whizard\ has been built. %%%%% \item \ttt{real\_tiny}\\ Predefined real; the smallest number which can be represented by the floating point type of the \fortran\ compiler with which \whizard\ has been built. %%%%% \item \ttt{record} \newline The \ttt{record} constructor provides an internal data structure in \sindarin\ input files. Its syntax is in general \ttt{record {\em } ({\em })}. The \ttt{{\em }} could be the definition of a tuple of points for a histogram or an \ttt{eval} constructor that tells \whizard\ e.g. by which rule to calculate an observable to be stored in the record \ttt{record\_name}. Example: \ttt{record h (12)} is a record for a histogram defined under the name \ttt{h} with the single data point (bin) at value 12; \ttt{record rap1 (eval Rap [e1])} defines a record with name \ttt{rap1} which has an evaluator to calculate the rapidity (predefined \whizard\ function) of an outgoing electron. (cf. also \ttt{eval}, \ttt{histogram}, \ttt{plot}) %%%%% \item \ttt{renormalization\_scale} \newline This is a command, \ttt{renormalization\_scale = {\em }}, that sets the renormalization scale of a process or list of processes. It overwrites a possible scale set by the ($\to$) \ttt{scale} command. \ttt{{\em }} can be any kinematic expression that leads to a result of momentum dimension one, e.g. \ttt{100 GeV}, \ttt{eval Pt [e1]}. (cf. also \ttt{factorization\_scale}). %%%%% \item \ttt{rescan} \newline This command allows to rescan event samples with modified model parameter, beam structure etc. to recalculate (analysis) observables, e.g.: \newline \ttt{rescan "{\em }" ({\em }) \{ {\em }\}}. \newline \ttt{"{\em }"} is the name of the event file and \ttt{{\em }} is the process whose (existing) event file of arbitrary size that is to be rescanned. Several flags allow to reconstruct the beams ($\to$ \ttt{?recover\_beams}), to reuse only the hard process but rebuild the full events ($\to$ \ttt{?update\_event}), to recalculate the matrix element ($\to$ \ttt{?update\_sqme}) or to recalculate the individual event weight ($\to$ \ttt{?update\_weight}). Further rescan options are redefining model parameter input, or defining a completely new alternative setup ($\to$ \ttt{alt\_setup}) (cf. also \ttt{\$rescan\_input\_format}) %%%%% \item \ttt{results} \newline Only used in the combination \ttt{show (results)}. Forces \whizard\ to print out a results summary for the integrated processes. (cf. also \ttt{show}) %%%%% \item \ttt{reweight} \newline The \ttt{reweight = {\em }} command allows to give for a process or list of processes an alternative weight, given by any kind of scalar expression \ttt{{\em }}, e.g. \ttt{reweight = 0.2} or \ttt{reweight = (eval M2 [e1, E1]) / (eval M2 [e2, E2])}. (cf. also \ttt{alt\_setup}, \ttt{weight}, \ttt{rescan}) %%%%% \item \ttt{sample\_format} \newline Variable that allows the user to specify additional event formats beyond the \whizard\ native binary event format. Its syntax is \ttt{sample\_format = {\em }}, where \ttt{{\em }} can be any of the following specifiers: \ttt{hepevt}, \ttt{hepevt\_verb}, \ttt{ascii}, \ttt{athena}, \ttt{debug}, \ttt{long}, \ttt{short}, \ttt{hepmc}, \ttt{lhef}, \ttt{lha}, \ttt{lha\_verb}, \ttt{stdhep}, \ttt{stdhep\_up}. (cf. also \ttt{\$sample}, \ttt{simulate}, \ttt{hepevt}, \ttt{ascii}, \ttt{athena}, \ttt{debug}, \ttt{long}, \ttt{short}, \ttt{hepmc}, \ttt{lhef}, \ttt{lha}, \ttt{stdhep}, \ttt{stdhep\_up}, \newline \ttt{\$sample\_normalization}, \ttt{?sample\_pacify}, \ttt{sample\_max\_tries}, \ttt{sample\_split\_n\_evt}, \ttt{sample\_split\_n\_kbytes}) %%%%% \item \ttt{scale} \newline This is a command, \ttt{scale = {\em }}, that sets the kinematic scale of a process or list of processes. Unless overwritten explicitly by ($\to$) \ttt{factorization\_scale} and/or ($\to$) \ttt{renormalization\_scale} it sets both scales. \ttt{{\em }} can be any kinematic expression that leads to a result of momentum dimension one, e.g. \ttt{scale = 100 GeV}, \ttt{scale = eval Pt [e1]}. %%%%% \item \ttt{scan} \newline Constructor to perform loops over variables or scan over processes in the integration procedure. The syntax is \ttt{scan {\em } {\em } ({\em } or {\em } => {\em } /{\em } {\em }) \{ {\em } \}}. The variable \ttt{var} can be specified if it is not a real, e.g. an integer. \ttt{var\_name} is the name of the variable which is also allowed to be a predefined one like \ttt{seed}. For the scan, one can either specify an explicit list of values \ttt{value list}, or use an initial and final value and a rule to increment. The \ttt{scan\_cmd} can either be just a \ttt{show} to print out the scanned variable or the integration of a process. Examples are: \ttt{scan seed (32 => 1 // 2) \{ show (seed\_value) \} }, which runs the seed down in steps 32, 16, 8, 4, 2, 1 (division by two). \ttt{scan mW (75 GeV, 80 GeV => 82 GeV /+ 0.5 GeV, 83 GeV => 90 GeV /* 1.2) \{ show (sw) \} } scans over the $W$ mass for the values 75, 80, 80.5, 81, 81.5, 82, 83 GeV, namely one discrete value, steps by adding 0.5 GeV, and increase by 20 \% (the latter having no effect as it already exceeds the final value). It prints out the corresponding value of the effective mixing angle which is defined as a dependent variable in the model input file(s). \ttt{scan sqrts (500 GeV => 600 GeV /+ 10 GeV) \{ integrate (proc) \} } integrates the process \ttt{proc} in eleven increasing 10 GeV steps in center-of-mass energy from 500 to 600 GeV. (cf. also \ttt{/+}, \ttt{/+/}, \ttt{/-}, \ttt{/*}, \ttt{/*/}, \ttt{//}) %%%%% \item \ttt{select} \newline Subevent function \ttt{select if {\em } [{\em } [ , {\em }]]} that selects all particles in \ttt{{\em }} that satisfy the condition \ttt{{\em }}. The second particle list \ttt{{\em }} is for conditions that depend on binary observables. (cf. also \ttt{collect}, \ttt{combine}, \ttt{extract}, \ttt{sort}, \ttt{+}) %%%%% \item \ttt{select\_b\_jet} \newline Subevent function \ttt{select if {\em } [{\em } [ , {\em }]]} that selects all particles in \ttt{{\em }} that are $b$ jets and satisfy the condition \ttt{{\em }}. The second particle list \ttt{{\em }} is for conditions that depend on binary observables. (cf. also \ttt{cluster}, \ttt{collect}, \ttt{combine}, \ttt{extract}, \ttt{select}, \ttt{sort}, \ttt{+}) %%%%% \item \ttt{select\_c\_jet} \newline Subevent function \ttt{select if {\em } [{\em } [ , {\em }]]} that selects all particles in \ttt{{\em }} that are $c$ jets (but {\em not} $b$ jets) and satisfy the condition \ttt{{\em }}. The second particle list \ttt{{\em }} is for conditions that depend on binary observables. (cf. also \ttt{cluster}, \ttt{collect}, \ttt{combine}, \ttt{extract}, \ttt{select}, \ttt{sort}, \ttt{+}) %%%%% \item \ttt{select\_light\_jet} \newline Subevent function \ttt{select if {\em } [{\em } [ , {\em }]]} that selects all particles in \ttt{{\em }} that are light(-flavor) jets and satisfy the condition \ttt{{\em }}. The second particle list \ttt{{\em }} is for conditions that depend on binary observables. (cf. also \ttt{cluster}, \ttt{collect}, \ttt{combine}, \ttt{extract}, \ttt{select}, \ttt{sort}, \ttt{+}) %%%%% \item \ttt{select\_non\_b\_jet} \newline Subevent function \ttt{select if {\em } [{\em } [ , {\em }]]} that selects all particles in \ttt{{\em }} that are {\em not} $b$ jets ($c$ and light jets) and satisfy the condition \ttt{{\em }}. The second particle list \ttt{{\em }} is for conditions that depend on binary observables. (cf. also \ttt{cluster}, \ttt{collect}, \ttt{combine}, \ttt{extract}, \ttt{select}, \ttt{sort}, \ttt{+}) %%%%% \item \ttt{selection} \newline Command that allows to select particular final states in an analysis selection, \ttt{selection = {\em }}. The term \ttt{log\_expr} can be any kind of logical expression. The syntax matches exactly the one of the ($\to$) \ttt{cuts} command. E.g. \ttt{selection = any PDG == 13} is an electron selection in a lepton sample. %%%%% \item \ttt{sgn} \newline Numerical function for integer and real numbers that gives the sign of its argument: \ttt{sgn ({\em })} yields $+1$ if \ttt{{\em }} is positive or zero, and $-1$ otherwise. (cf. also \ttt{abs}, \ttt{conjg}, \ttt{mod}, \ttt{modulo}) %%%%% \item \ttt{short} \newline Specifier for the \ttt{sample\_format} command to demand the generation of the short variant of HEPEVT ASCII event files. (cf. also \ttt{\$sample}, \ttt{sample\_format}) %%%%% \item \ttt{show} \newline This is a unary function that is operating on specific constructors in order to print them out in the \whizard\ screen output as well as the log file \ttt{whizard.log}. Examples are \ttt{show({\em })} to issue a specific parameter from a model or a constant defined in a \sindarin\ input file, \ttt{show(integral({\em }))}, \ttt{show(library)}, \ttt{show(results)}, or \ttt{show({\em })} for any arbitrary variable. Further possibilities are \ttt{show(real)}, \ttt{show(string)}, \ttt{show(logical)} etc. to allow to show all defined real, string, logical etc. variables, respectively. (cf. also \ttt{library}, \ttt{results}) %%%%% \item \ttt{simulate} \newline This command invokes the generation of events for the process \ttt{proc} by means of \ttt{simulate ({\em })}. Optional arguments: \ttt{\$sample}, \ttt{sample\_format}, \ttt{checkpoint} (cf. also \ttt{integrate}, \ttt{luminosity}, \ttt{n\_events}, \ttt{\$sample}, \ttt{sample\_format}, \ttt{checkpoint}, \ttt{?unweighted}, \ttt{safety\_factor}, \ttt{?negative\_weights}, \ttt{sample\_max\_tries}, \ttt{sample\_split\_n\_evt}, \ttt{sample\_split\_n\_kbytes}) %%%%% \item \ttt{sin} \newline Numerical function \ttt{sin ({\em })} that calculates the sine trigonometric function of real and complex numerical numbers or variables. (cf. also \ttt{cos}, \ttt{tan}, \ttt{asin}, \ttt{acos}, \ttt{atan}) %%%%% \item \ttt{sinh} \newline Numerical function \ttt{sinh ({\em })} that calculates the hyperbolic sine function of real and complex numerical numbers or variables. Note that its inverse function is part of the \ttt{Fortran2008} status and hence not realized. (cf. also \ttt{cosh}, \ttt{tanh}) %%%%% \item \ttt{sort} \newline Subevent function that allows to sort a particle list/subevent either by increasing PDG code: \ttt{sort [{\em }]} (particles first, then antiparticles). Alternatively, it can sort according to a unary or binary particle observable (in that case there is a second particle list, where the first particle is taken as a reference): \ttt{sort by {\em } [{\em } [, {\em }]]}. (cf. also \ttt{extract}, \ttt{combine}, \ttt{collect}, \ttt{join}, \ttt{by}, \ttt{+}) %%%%% \item \ttt{sprintf} \newline Command that allows to print data into a string variable: \ttt{sprintf "{\em }"}. There exist format specifiers, very similar to the \ttt{C} command \ttt{sprintf}, e.g. \ttt{sprintf "\%i" (123)}. (cf. \ttt{printf}, \ttt{\%d}, \ttt{\%i}, \ttt{\%e}, \ttt{\%f}, \ttt{\%g}, \ttt{\%E}, \ttt{\%F}, \ttt{\%G}, \ttt{\%s}) %%%%% \item \ttt{sqrt} \newline Numerical function \ttt{sqrt ({\em })} that calculates the square root of real and complex numerical numbers or variables. (cf. also \ttt{exp}, \ttt{log}, \ttt{log10}) %%%%% \item \ttt{sqrts\_hat} \newline Real variable that accesses the partonic energy of a hard-scattering process. It can be used in cuts or in an analysis, e.g. \ttt{cuts = sqrts\_hat > {\em } [ {\em } ]}. The physical unit can be one of the following \ttt{eV}, \ttt{keV}, \ttt{MeV}, \ttt{GeV}, and \ttt{TeV}. (cf. also \ttt{sqrts}, \ttt{cuts}, \ttt{record}) %%%%% \item \ttt{stable} \newline This constructor allows particles in the final states of processes in decay cascade set-up to be set as stable, and not letting them decay. The syntax is \ttt{stable {\em }} (cf. also \ttt{unstable}) %%%%% \item \ttt{stdhep} \newline Specifier for the \ttt{sample\_format} command to demand the generation of binary StdHEP event files based on the HEPEVT common block. (cf. also \ttt{\$sample}, \ttt{sample\_format}) %%%%% \item \ttt{stdhep\_up} \newline Specifier for the \ttt{sample\_format} command to demand the generation of binary StdHEP event files based on the HEPRUP/HEPEUP common blocks. (cf. also \ttt{\$sample}, \ttt{sample\_format}) %%%%% \item \ttt{tan} \newline Numerical function \ttt{tan ({\em })} that calculates the tangent trigonometric function of real and complex numerical numbers or variables. (cf. also \ttt{sin}, \ttt{cos}, \ttt{asin}, \ttt{acos}, \ttt{atan}) %%%%% \item \ttt{tanh} \newline Numerical function \ttt{tanh ({\em })} that calculates the hyperbolic tangent function of real and complex numerical numbers or variables. Note that its inverse function is part of the \ttt{Fortran2008} status and hence not realized. (cf. also \ttt{cosh}, \ttt{sinh}) %%%%% \item \ttt{TeV} \newline Physical unit, for energies in $10^{12}$ electron volt. (cf. also \ttt{eV}, \ttt{keV}, \ttt{MeV}, \ttt{meV}, \ttt{GeV}) %%%% \item \ttt{then} \newline Mandatory phrase in a conditional clause: \ttt{if {\em } then {\em } \ldots endif}. (cf. also \ttt{if}, \ttt{else}, \ttt{elsif}, \ttt{endif}). %%%%% \item \ttt{Theta} \newline Unary and also binary observable specifier, that as a unary observable gives the angle between a particle's momentum and the beam axis ($+z$ direction). As a binary observable, it gives the angle enclosed between the momenta of the two particles: \ttt{eval Theta [e1]}, \ttt{all Theta > 30 degrees [jet, jet]}. (cf. also \ttt{eval}, \ttt{cuts}, \ttt{selection}, \ttt{Phi}, \ttt{Theta\_star}) %%%%% \item \ttt{Theta\_star} \newline Binary observable specifier, that gives the polar angle enclosed between the momenta of the two particles in the rest frame of the mother particle (momentum sum of the two particle): \ttt{eval Theta\_star [jet, jet]}. (cf. also \ttt{eval}, \ttt{cuts}, \ttt{selection}, \ttt{Theta}) %%%%% \item \ttt{true} \newline Constructor stating that a logical expression or variable is true, e.g. \ttt{?{\em } = true}. (cf. also \ttt{false}). %%%%% \item \ttt{unpolarized} \newline Constructor to force \whizard\ to discard polarization of the corresponding particles in the generated events: \ttt{unpolarized {\em } [, {\em } , ...]}. (cf. also \ttt{polarized}, \ttt{simulate}, \ttt{?polarized\_events}) %%%%% \item \ttt{unstable} \newline This constructor allows to let final state particles of the hard interaction undergo a subsequent (cascade) decay (in the on-shell approximation). For this the user has to define the list of desired \begin{figure} \begin{Verbatim}[frame=single] process zee = Z => e1, E1 process zuu = Z => u, U process zz = e1, E1 => Z, Z compile integrate (zee) { iterations = 1:100 } integrate (zuu) { iterations = 1:100 } sqrts = 500 GeV integrate (zz) { iterations = 3:5000, 2:5000 } unstable Z (zee, zuu) \end{Verbatim} \caption{\label{fig:ex_unstable} \sindarin\ input file for unstable particles and inclusive decays.} \end{figure} decay channels as \ttt{unstable {\em } ({\em }, {\em }, ....)}, where \ttt{mother} is the mother particle, and the argument is a list of decay channels. Note that -- unless the \ttt{?auto\_decays = true} flag has been set -- these decay channels have to be provided by the user as in the example in Fig. \ref{fig:ex_unstable}. First, the $Z$ decays to electrons and up quarks are generated, then $ZZ$ production at a 500 GeV ILC is called, and then both $Z$s are decayed according to the probability distribution of the two generated decay matrix elements. This obviously allows also for inclusive decays. (cf. also \ttt{stable}, \ttt{?auto\_decays}) %%%%% \item \ttt{weight} \newline This is a command, \ttt{weight = {\em }}, that allows to specify a weight for a process or list of processes. \ttt{{\em }} can be any expression that leads to a scalar result, e.g. \ttt{weight = 0.2}, \ttt{weight = eval Pt [jet]}. (cf. also \ttt{rescan}, \ttt{alt\_setup}, \ttt{reweight}) %%%%% \item \ttt{write\_analysis} \newline The \ttt{write\_analysis} statement tells \whizard\ to write the analysis setup by the user for the \sindarin\ input file under consideration. If no \ttt{\$out\_file} is provided, the histogram tables/plot data etc. are written to the default file \ttt{whizard\_analysis.dat}. Note that the related command \ttt{compile\_analysis} does the same as \ttt{write\_analysis} but in addition invokes the \whizard\ \LaTeX routines for producing postscript or PDF output of the data. (cf. also \ttt{\$out\_file}, \ttt{compile\_analysis}) %%%%% \item \ttt{write\_slha} \newline Demands \whizard\ to write out a file in the SUSY Les Houches accord (SLHA) format. (cf. also \ttt{read\_slha}, \ttt{?slha\_read\_decays}, \ttt{?slha\_read\_input}, \ttt{?slha\_read\_spectrum}) %%%%% \end{itemize} \section{Variables} \subsection{Rebuild Variables} \begin{itemize} \item \ttt{?rebuild\_events} \qquad (default: \ttt{false}) \newline This logical variable, if set \ttt{true} triggers \whizard\ to newly create an event sample, even if nothing seems to have changed, including the MD5 checksum. This can be used when manually manipulating some settings. (cf also \ttt{?rebuild\_grids}, \ttt{?rebuild\_library}, \ttt{?rebuild\_phase\_space}) %%%%% \item \ttt{?rebuild\_grids} \qquad (default: \ttt{false}) \newline The logical variable \ttt{?rebuild\_grids} forces \whizard\ to newly create the VAMP grids when using VAMP as an integration method, even if they are already present. (cf. also \ttt{?rebuild\_events}, \ttt{?rebuild\_library}, \ttt{?rebuild\_phase\_space}) %%%%% \item \ttt{?rebuild\_library} \qquad (default: \ttt{false}) \newline The logical variable \ttt{?rebuild\_library = true/false} specifies whether the library(-ies) for the matrix element code for processes is re-generated (incl. possible Makefiles etc.) by the corresponding ME method (e.g. if the process has been changed, but not its name). This can also be set as a command-line option \ttt{whizard --rebuild}. The default is \ttt{false}, i.e. code is never re-generated if it is present and the MD5 checksum is valid. (cf. also \ttt{?recompile\_library}, \ttt{?rebuild\_grids}, \ttt{?rebuild\_phase\_space}) %%%%% \item \ttt{?rebuild\_phase\_space} \qquad (default: \ttt{false}) \newline This logical variable, if set \ttt{true}, triggers recreation of the phase space file by \whizard\. (cf. also \ttt{?rebuild\_events}, \ttt{?rebuild\_grids}, \ttt{?rebuild\_library}) %%%%% \item \ttt{?recompile\_library} \qquad (default: \ttt{false}) \newline The logical variable \ttt{?recompile\_library = true/false} specifies whether the library(-ies) for the matrix element code for processes is re-compiled (e.g. if the process code has been manually modified by the user). This can also be set as a command-line option \ttt{whizard --recompile}. The default is \ttt{false}, i.e. code is never re-compiled if its corresponding object file is present. (cf. also \ttt{?rebuild\_library}) %%%%% \end{itemize} \subsection{Standard Variables} \begin{itemize} \input{variables} \end{itemize} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \clearpage \section*{Acknowledgements} We would like to thank E.~Boos, R.~Chierici, K.~Desch, M.~Kobel, F.~Krauss, P.M.~Manakos, N.~Meyer, K.~M\"onig, H.~Reuter, T.~Robens, S.~Rosati, J.~Schumacher, M.~Schumacher, and C.~Schwinn who contributed to \whizard\ by their suggestions, bits of codes and valuable remarks and/or used several versions of the program for real-life applications and thus helped a lot in debugging and improving the code. Special thanks go to A.~Vaught and J.~Weill for their continuos efforts on improving the g95 and gfortran compilers, respectively. %\end{fmffile} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% References %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %\baselineskip15pt \begin{thebibliography}{19} \bibitem{PYTHIA} T.~Sj\"ostrand, Comput.\ Phys.\ Commun.\ \textbf{82} (1994) 74. \bibitem{comphep} A.~Pukhov, \emph{et al.}, Preprint INP MSU 98-41/542, \ttt{hep-ph/9908288}. \bibitem{madgraph} T.~Stelzer and W.F.~Long, Comput.\ Phys.\ Commun.\ \textbf{81} (1994) 357. \bibitem{omega} T.~Ohl, \emph{Proceedings of the Seventh International Workshop on Advanced Computing and Analysis Technics in Physics Research}, ACAT 2000, Fermilab, October 2000, IKDA-2000-30, \ttt{hep-ph/0011243}; M.~Moretti, Th.~Ohl, and J.~Reuter, LC-TOOL-2001-040 \bibitem{VAMP} T.~Ohl, {\em Vegas revisited: Adaptive Monte Carlo integration beyond factorization}, Comput.\ Phys.\ Commun.\ {\bf 120}, 13 (1999) [arXiv:hep-ph/9806432]. %%CITATION = CPHCB,120,13;%% \bibitem{CIRCE} T.~Ohl, {\em CIRCE version 1.0: Beam spectra for simulating linear collider physics}, Comput.\ Phys.\ Commun.\ {\bf 101}, 269 (1997) [arXiv:hep-ph/9607454]. %%CITATION = CPHCB,101,269;%% %\cite{Gribov:1972rt} \bibitem{Gribov:1972rt} V.~N.~Gribov and L.~N.~Lipatov, {\em e+ e- pair annihilation and deep inelastic e p scattering in perturbation theory}, Sov.\ J.\ Nucl.\ Phys.\ {\bf 15}, 675 (1972) [Yad.\ Fiz.\ {\bf 15}, 1218 (1972)]. %%CITATION = SJNCA,15,675;%% %\cite{Kuraev:1985hb} \bibitem{Kuraev:1985hb} E.~A.~Kuraev and V.~S.~Fadin, {\em On Radiative Corrections to e+ e- Single Photon Annihilation at High-Energy}, Sov.\ J.\ Nucl.\ Phys.\ {\bf 41}, 466 (1985) [Yad.\ Fiz.\ {\bf 41}, 733 (1985)]. %%CITATION = SJNCA,41,466;%% %\cite{Skrzypek:1990qs} \bibitem{Skrzypek:1990qs} M.~Skrzypek and S.~Jadach, {\em Exact and approximate solutions for the electron nonsinglet structure function in QED}, Z.\ Phys.\ C {\bf 49}, 577 (1991). %%CITATION = ZEPYA,C49,577;%% %\cite{Schulte:1998au} \bibitem{Schulte:1998au} D.~Schulte, {\em Beam-beam simulations with Guinea-Pig}, eConf C {\bf 980914}, 127 (1998). %%CITATION = ECONF,C980914,127;%% %\cite{Schulte:1999tx} \bibitem{Schulte:1999tx} D.~Schulte, {\em Beam-beam simulations with GUINEA-PIG}, CERN-PS-99-014-LP. %%CITATION = CERN-PS-99-014-LP;%% %\cite{Schulte:2007zz} \bibitem{Schulte:2007zz} D.~Schulte, M.~Alabau, P.~Bambade, O.~Dadoun, G.~Le Meur, C.~Rimbault and F.~Touze, {\em GUINEA PIG++ : An Upgraded Version of the Linear Collider Beam Beam Interaction Simulation Code GUINEA PIG}, Conf.\ Proc.\ C {\bf 070625}, 2728 (2007). %%CITATION = CONFP,C070625,2728;%% %\cite{Behnke:2013xla} \bibitem{Behnke:2013xla} T.~Behnke, J.~E.~Brau, B.~Foster, J.~Fuster, M.~Harrison, J.~M.~Paterson, M.~Peskin and M.~Stanitzki {\it et al.}, {\em The International Linear Collider Technical Design Report - Volume 1: Executive Summary}, arXiv:1306.6327 [physics.acc-ph]. %%CITATION = ARXIV:1306.6327;%% %\cite{Baer:2013cma} \bibitem{Baer:2013cma} H.~Baer, T.~Barklow, K.~Fujii, Y.~Gao, A.~Hoang, S.~Kanemura, J.~List and H.~E.~Logan {\it et al.}, {\em The International Linear Collider Technical Design Report - Volume 2: Physics}, arXiv:1306.6352 [hep-ph]. %%CITATION = ARXIV:1306.6352;%% %\cite{Adolphsen:2013jya} \bibitem{Adolphsen:2013jya} C.~Adolphsen, M.~Barone, B.~Barish, K.~Buesser, P.~Burrows, J.~Carwardine, J.~Clark and H\'{e}l\`{e}n.~M.~Durand {\it et al.}, {\em The International Linear Collider Technical Design Report - Volume 3.I: Accelerator \& in the Technical Design Phase}, arXiv:1306.6353 [physics.acc-ph]. %%CITATION = ARXIV:1306.6353;%% %\cite{Adolphsen:2013kya} \bibitem{Adolphsen:2013kya} C.~Adolphsen, M.~Barone, B.~Barish, K.~Buesser, P.~Burrows, J.~Carwardine, J.~Clark and H\'{e}l\`{e}n.~M.~Durand {\it et al.}, {\em The International Linear Collider Technical Design Report - Volume 3.II: Accelerator Baseline Design}, arXiv:1306.6328 [physics.acc-ph]. %%CITATION = ARXIV:1306.6328;%% %\cite{Behnke:2013lya} \bibitem{Behnke:2013lya} T.~Behnke, J.~E.~Brau, P.~N.~Burrows, J.~Fuster, M.~Peskin, M.~Stanitzki, Y.~Sugimoto and S.~Yamada {\it et al.}, %``The International Linear Collider Technical Design Report - Volume 4: Detectors,'' arXiv:1306.6329 [physics.ins-det]. %%CITATION = ARXIV:1306.6329;%% %\cite{Aicheler:2012bya} \bibitem{Aicheler:2012bya} M.~Aicheler, P.~Burrows, M.~Draper, T.~Garvey, P.~Lebrun, K.~Peach and N.~Phinney {\it et al.}, {\em A Multi-TeV Linear Collider Based on CLIC Technology : CLIC Conceptual Design Report}, CERN-2012-007. %%CITATION = CERN-2012-007;%% %\cite{Lebrun:2012hj} \bibitem{Lebrun:2012hj} P.~Lebrun, L.~Linssen, A.~Lucaci-Timoce, D.~Schulte, F.~Simon, S.~Stapnes, N.~Toge and H.~Weerts {\it et al.}, {\em The CLIC Programme: Towards a Staged e+e- Linear Collider Exploring the Terascale : CLIC Conceptual Design Report}, arXiv:1209.2543 [physics.ins-det]. %%CITATION = ARXIV:1209.2543;%% %\cite{Linssen:2012hp} \bibitem{Linssen:2012hp} L.~Linssen, A.~Miyamoto, M.~Stanitzki and H.~Weerts, {\em Physics and Detectors at CLIC: CLIC Conceptual Design Report}, arXiv:1202.5940 [physics.ins-det]. %%CITATION = ARXIV:1202.5940;%% %\cite{vonWeizsacker:1934sx} \bibitem{vonWeizsacker:1934sx} C.~F.~von Weizs\"acker, {\em Radiation emitted in collisions of very fast electrons}, Z.\ Phys.\ {\bf 88}, 612 (1934). %%CITATION = ZEPYA,88,612;%% %\cite{Williams:1934ad} \bibitem{Williams:1934ad} E.~J.~Williams, {\em Nature of the high-energy particles of penetrating radiation and status of ionization and radiation formulae}, Phys.\ Rev.\ {\bf 45}, 729 (1934). %%CITATION = PHRVA,45,729;%% %\cite{Budnev:1974de} \bibitem{Budnev:1974de} V.~M.~Budnev, I.~F.~Ginzburg, G.~V.~Meledin and V.~G.~Serbo, {\em The Two photon particle production mechanism. Physical problems. Applications. Equivalent photon approximation}, Phys.\ Rept.\ {\bf 15} (1974) 181. %%CITATION = PRPLC,15,181;%% %\cite{Ginzburg:1981vm} \bibitem{Ginzburg:1981vm} I.~F.~Ginzburg, G.~L.~Kotkin, V.~G.~Serbo and V.~I.~Telnov, {\em Colliding gamma e and gamma gamma Beams Based on the Single Pass Accelerators (of Vlepp Type)}, Nucl.\ Instrum.\ Meth.\ {\bf 205}, 47 (1983). %%CITATION = NUIMA,205,47;%% %\cite{Telnov:1989sd} \bibitem{Telnov:1989sd} V.~I.~Telnov, {\em Problems of Obtaining $\gamma \gamma$ and $\gamma \epsilon$ Colliding Beams at Linear Colliders}, Nucl.\ Instrum.\ Meth.\ A {\bf 294}, 72 (1990). %%CITATION = NUIMA,A294,72;%% %\cite{Telnov:1995hc} \bibitem{Telnov:1995hc} V.~I.~Telnov, {\em Principles of photon colliders}, Nucl.\ Instrum.\ Meth.\ A {\bf 355}, 3 (1995). %%CITATION = NUIMA,A355,3;%% %\cite{AguilarSaavedra:2001rg} \bibitem{AguilarSaavedra:2001rg} J.~A.~Aguilar-Saavedra {\it et al.} [ECFA/DESY LC Physics Working Group Collaboration], {\em TESLA: The Superconducting electron positron linear collider with an integrated x-ray laser laboratory. Technical design report. Part 3. Physics at an e+ e- linear collider}, hep-ph/0106315. %%CITATION = HEP-PH/0106315;%% %\cite{Richard:2001qm} \bibitem{Richard:2001qm} F.~Richard, J.~R.~Schneider, D.~Trines and A.~Wagner, {\em TESLA, The Superconducting Electron Positron Linear Collider with an Integrated X-ray Laser Laboratory, Technical Design Report Part 1 : Executive Summary}, hep-ph/0106314. %%CITATION = HEP-PH/0106314;%% %\cite{Sudakov:1954sw} \bibitem{Sudakov:1954sw} V.~V.~Sudakov, %``Vertex parts at very high-energies in quantum electrodynamics,'' Sov.\ Phys.\ JETP {\bf 3}, 65 (1956) [Zh.\ Eksp.\ Teor.\ Fiz.\ {\bf 30}, 87 (1956)]. %%CITATION = SPHJA,3,65;%% \cite{Sjostrand:1985xi} \bibitem{Sjostrand:1985xi} T.~Sjostrand, %``A Model for Initial State Parton Showers,'' Phys.\ Lett.\ {\bf 157B}, 321 (1985). doi:10.1016/0370-2693(85)90674-4 %%CITATION = doi:10.1016/0370-2693(85)90674-4;%% %\cite{Sjostrand:2006za} \bibitem{Sjostrand:2006za} T.~Sjostrand, S.~Mrenna and P.~Z.~Skands, %``PYTHIA 6.4 Physics and Manual,'' JHEP {\bf 0605}, 026 (2006) doi:10.1088/1126-6708/2006/05/026 [hep-ph/0603175]. %%CITATION = doi:10.1088/1126-6708/2006/05/026;%% %\cite{Ohl:1998jn} \bibitem{Ohl:1998jn} T.~Ohl, {\em Vegas revisited: Adaptive Monte Carlo integration beyond factorization}, Comput.\ Phys.\ Commun.\ {\bf 120}, 13 (1999) [hep-ph/9806432]. %%CITATION = HEP-PH/9806432;%% %\cite{Lepage:1980dq} \bibitem{Lepage:1980dq} G.~P.~Lepage, %``Vegas: An Adaptive Multidimensional Integration Program,'' CLNS-80/447. %%CITATION = CLNS-80/447;%% \bibitem{HDECAY} A.~Djouadi, J.~Kalinowski, M.~Spira, Comput.\ Phys.\ Commun.\ \textbf{108} (1998) 56-74. %\cite{Beyer:2006hx} \bibitem{Beyer:2006hx} M.~Beyer, W.~Kilian, P.~Krstono\v{s}ic, K.~M\"onig, J.~Reuter, E.~Schmidt and H.~Schr\"oder, {\em Determination of New Electroweak Parameters at the ILC - Sensitivity to New Physics}, Eur.\ Phys.\ J.\ C {\bf 48}, 353 (2006) [hep-ph/0604048]. %%CITATION = HEP-PH/0604048;%% %\cite{Alboteanu:2008my} \bibitem{Alboteanu:2008my} A.~Alboteanu, W.~Kilian and J.~Reuter, {\em Resonances and Unitarity in Weak Boson Scattering at the LHC}, JHEP {\bf 0811}, 010 (2008) [arXiv:0806.4145 [hep-ph]]. %%CITATION = ARXIV:0806.4145;%% %\cite{Binoth:2010xt} \bibitem{Binoth:2010xt} T.~Binoth {\it et al.}, %``A Proposal for a standard interface between Monte Carlo tools and one-loop programs,'' Comput.\ Phys.\ Commun.\ {\bf 181}, 1612 (2010) doi:10.1016/j.cpc.2010.05.016 [arXiv:1001.1307 [hep-ph]]. %%CITATION = doi:10.1016/j.cpc.2010.05.016;%% %\cite{Alioli:2013nda} \bibitem{Alioli:2013nda} S.~Alioli {\it et al.}, %``Update of the Binoth Les Houches Accord for a standard interface %between Monte Carlo tools and one-loop programs,'' Comput.\ Phys.\ Commun.\ {\bf 185}, 560 (2014) doi:10.1016/j.cpc.2013.10.020 [arXiv:1308.3462 [hep-ph]]. %%CITATION = doi:10.1016/j.cpc.2013.10.020;%% %\cite{Speckner:2010zi} \bibitem{Speckner:2010zi} C.~Speckner, {\em LHC Phenomenology of the Three-Site Higgsless Model}, PhD thesis, arXiv:1011.1851 [hep-ph]. %%CITATION = ARXIV:1011.1851;%% %\cite{Chivukula:2006cg} \bibitem{Chivukula:2006cg} R.~S.~Chivukula, B.~Coleppa, S.~Di Chiara, E.~H.~Simmons, H.~-J.~He, M.~Kurachi and M.~Tanabashi, {\em A Three Site Higgsless Model}, Phys.\ Rev.\ D {\bf 74}, 075011 (2006) [hep-ph/0607124]. %%CITATION = HEP-PH/0607124;%% %\cite{Chivukula:2005xm} \bibitem{Chivukula:2005xm} R.~S.~Chivukula, E.~H.~Simmons, H.~-J.~He, M.~Kurachi and M.~Tanabashi, {\em Ideal fermion delocalization in Higgsless models}, Phys.\ Rev.\ D {\bf 72}, 015008 (2005) [hep-ph/0504114]. %%CITATION = HEP-PH/0504114;%% %\cite{Ohl:2008ri} \bibitem{Ohl:2008ri} T.~Ohl and C.~Speckner, {\em Production of Almost Fermiophobic Gauge Bosons in the Minimal Higgsless Model at the LHC}, Phys.\ Rev.\ D {\bf 78}, 095008 (2008) [arXiv:0809.0023 [hep-ph]]. %%CITATION = ARXIV:0809.0023;%% %\cite{Ohl:2002jp} \bibitem{Ohl:2002jp} T.~Ohl and J.~Reuter, {\em Clockwork SUSY: Supersymmetric Ward and Slavnov-Taylor identities at work in Green's functions and scattering amplitudes}, Eur.\ Phys.\ J.\ C {\bf 30}, 525 (2003) [hep-th/0212224]. %%CITATION = HEP-TH/0212224;%% %\cite{Reuter:2009ex} \bibitem{Reuter:2009ex} J.~Reuter and F.~Braam, {\em The NMSSM implementation in WHIZARD}, AIP Conf.\ Proc.\ {\bf 1200}, 470 (2010) [arXiv:0909.3059 [hep-ph]]. %%CITATION = ARXIV:0909.3059;%% %\cite{Kalinowski:2008fk} \bibitem{Kalinowski:2008fk} J.~Kalinowski, W.~Kilian, J.~Reuter, T.~Robens and K.~Rolbiecki, {\em Pinning down the Invisible Sneutrino}, JHEP {\bf 0810}, 090 (2008) [arXiv:0809.3997 [hep-ph]]. %%CITATION = ARXIV:0809.3997;%% %\cite{Robens:2008sa} \bibitem{Robens:2008sa} T.~Robens, J.~Kalinowski, K.~Rolbiecki, W.~Kilian and J.~Reuter, {\em (N)LO Simulation of Chargino Production and Decay}, Acta Phys.\ Polon.\ B {\bf 39}, 1705 (2008) [arXiv:0803.4161 [hep-ph]]. %%CITATION = ARXIV:0803.4161;%% %\cite{Kilian:2004pp} \bibitem{Kilian:2004pp} W.~Kilian, D.~Rainwater and J.~Reuter, {\em Pseudo-axions in little Higgs models}, Phys.\ Rev.\ D {\bf 71}, 015008 (2005) [hep-ph/0411213]. %%CITATION = HEP-PH/0411213;%% %\cite{Kilian:2006eh} \bibitem{Kilian:2006eh} W.~Kilian, D.~Rainwater and J.~Reuter, {\em Distinguishing little-Higgs product and simple group models at the LHC and ILC}, Phys.\ Rev.\ D {\bf 74}, 095003 (2006) [Erratum-ibid.\ D {\bf 74}, 099905 (2006)] [hep-ph/0609119]. %%CITATION = HEP-PH/0609119;%% %\cite{Ohl:2004tn} \bibitem{Ohl:2004tn} T.~Ohl and J.~Reuter, {\em Testing the noncommutative standard model at a future photon collider}, Phys.\ Rev.\ D {\bf 70}, 076007 (2004) [hep-ph/0406098]. %%CITATION = HEP-PH/0406098;%% %\cite{Ohl:2010zf} \bibitem{Ohl:2010zf} T.~Ohl and C.~Speckner, {\em The Noncommutative Standard Model and Polarization in Charged Gauge Boson Production at the LHC}, Phys.\ Rev.\ D {\bf 82}, 116011 (2010) [arXiv:1008.4710 [hep-ph]]. %%CITATION = ARXIV:1008.4710;%% \bibitem{LesHouches} E.~Boos {\it et al.}, {\em Generic user process interface for event generators}, arXiv:hep-ph/0109068. %%CITATION = HEP-PH/0109068;%% \bibitem{Skands:2003cj} P.~Z.~Skands {\it et al.}, {\em SUSY Les Houches Accord: Interfacing SUSY Spectrum Calculators, Decay Packages, and Event Generators}, JHEP {\bf 0407}, 036 (2004) [arXiv:hep-ph/0311123]. %%CITATION = JHEPA,0407,036;%% %\cite{AguilarSaavedra:2005pw} \bibitem{AguilarSaavedra:2005pw} J.~A.~Aguilar-Saavedra, A.~Ali, B.~C.~Allanach, R.~L.~Arnowitt, H.~A.~Baer, J.~A.~Bagger, C.~Balazs and V.~D.~Barger {\it et al.}, {\em Supersymmetry parameter analysis: SPA convention and project}, Eur.\ Phys.\ J.\ C {\bf 46}, 43 (2006) [hep-ph/0511344]. %%CITATION = HEP-PH/0511344;%% %\cite{Allanach:2008qq} \bibitem{Allanach:2008qq} B.~C.~Allanach, C.~Balazs, G.~Belanger, M.~Bernhardt, F.~Boudjema, D.~Choudhury, K.~Desch and U.~Ellwanger {\it et al.}, %``SUSY Les Houches Accord 2,'' Comput.\ Phys.\ Commun.\ {\bf 180}, 8 (2009) [arXiv:0801.0045 [hep-ph]]. %%CITATION = ARXIV:0801.0045;%% \bibitem{LHEF} J.~Alwall {\it et al.}, {\em A standard format for Les Houches event files}, Comput.\ Phys.\ Commun.\ {\bf 176}, 300 (2007) [arXiv:hep-ph/0609017]. %%CITATION = CPHCB,176,300;%% \bibitem{Hagiwara:2005wg} K.~Hagiwara {\it et al.}, {\em Supersymmetry simulations with off-shell effects for LHC and ILC}, Phys.\ Rev.\ D {\bf 73}, 055005 (2006) [arXiv:hep-ph/0512260]. %%CITATION = PHRVA,D73,055005;%% \bibitem{Allanach:2002nj} B.~C.~Allanach {\it et al.}, {\em The Snowmass points and slopes: Benchmarks for SUSY searches}, in {\it Proc. of the APS/DPF/DPB Summer Study on the Future of Particle Physics (Snowmass 2001) } ed. N.~Graf, Eur.\ Phys.\ J.\ C {\bf 25} (2002) 113 [eConf {\bf C010630} (2001) P125] [arXiv:hep-ph/0202233]. %%CITATION = HEP-PH 0202233;%% \bibitem{PeskinSchroeder} M.E. Peskin, D.V.Schroeder, {\em An Introduction to Quantum Field Theory}, Addison-Wesley Publishing Co., 1995. \bibitem{stdhep} L.~Garren, {\em StdHep, Monte Carlo Standardization at FNAL}, Fermilab CS-doc-903, \url{http://cd-docdb.fnal.gov/cgi-bin/ShowDocument?docid=903} %\cite{Frixione:1998jh} \bibitem{Frixione:1998jh} S.~Frixione, %``Isolated photons in perturbative QCD,'' Phys.\ Lett.\ B {\bf 429}, 369 (1998) doi:10.1016/S0370-2693(98)00454-7 [hep-ph/9801442]. %%CITATION = doi:10.1016/S0370-2693(98)00454-7;%% \bibitem{LHAPDF} W.~Giele {\it et al.}, {\em The QCD / SM working group: Summary report}, arXiv:hep-ph/0204316; %%CITATION = HEP-PH/0204316;%% M.~R.~Whalley, D.~Bourilkov and R.~C.~Group, {\em The Les Houches Accord PDFs (LHAPDF) and Lhaglue}, arXiv:hep-ph/0508110; %%CITATION = HEP-PH/0508110;%% D.~Bourilkov, R.~C.~Group and M.~R.~Whalley, {\em LHAPDF: PDF use from the Tevatron to the LHC}, arXiv:hep-ph/0605240. %%CITATION = HEP-PH/0605240;%% \bibitem{HepMC} M.~Dobbs and J.~B.~Hansen, {\em The HepMC C++ Monte Carlo event record for High Energy Physics}, Comput.\ Phys.\ Commun.\ {\bf 134}, 41 (2001). %%CITATION = CPHCB,134,41;%% %\cite{Boos:2004kh} \bibitem{Boos:2004kh} E.~Boos {\it et al.} [CompHEP Collaboration], %``CompHEP 4.4: Automatic computations from Lagrangians to events,'' Nucl.\ Instrum.\ Meth.\ A {\bf 534}, 250 (2004) [hep-ph/0403113]. %%CITATION = HEP-PH/0403113;%% %493 citations counted in INSPIRE as of 12 May 2014 % Parton distributions %\cite{Pumplin:2002vw} \bibitem{Pumplin:2002vw} J.~Pumplin, D.~R.~Stump, J.~Huston {\it et al.}, {\em New generation of parton distributions with uncertainties from global QCD analysis}, JHEP {\bf 0207}, 012 (2002). [hep-ph/0201195]. %\cite{Martin:2004dh} \bibitem{Martin:2004dh} A.~D.~Martin, R.~G.~Roberts, W.~J.~Stirling {\it et al.}, {\em Parton distributions incorporating QED contributions}, Eur.\ Phys.\ J.\ {\bf C39}, 155-161 (2005). [hep-ph/0411040]. %\cite{Martin:2009iq} \bibitem{Martin:2009iq} A.~D.~Martin, W.~J.~Stirling, R.~S.~Thorne {\it et al.}, {\em Parton distributions for the LHC}, Eur.\ Phys.\ J.\ {\bf C63}, 189-285 (2009). [arXiv:0901.0002 [hep-ph]]. %\cite{Lai:2010vv} \bibitem{Lai:2010vv} H.~L.~Lai, M.~Guzzi, J.~Huston, Z.~Li, P.~M.~Nadolsky, J.~Pumplin and C.~P.~Yuan, {\em New parton distributions for collider physics}, Phys.\ Rev.\ D {\bf 82}, 074024 (2010) [arXiv:1007.2241 [hep-ph]]. %%CITATION = PHRVA,D82,074024;%% %\cite{Owens:2012bv} \bibitem{Owens:2012bv} J.~F.~Owens, A.~Accardi and W.~Melnitchouk, {\em Global parton distributions with nuclear and finite-$Q^2$ corrections}, Phys.\ Rev.\ D {\bf 87}, no. 9, 094012 (2013) [arXiv:1212.1702 [hep-ph]]. %%CITATION = ARXIV:1212.1702;%% %\cite{Accardi:2016qay} \bibitem{Accardi:2016qay} A.~Accardi, L.~T.~Brady, W.~Melnitchouk, J.~F.~Owens and N.~Sato, %``Constraints on large-$x$ parton distributions from new weak boson production and deep-inelastic scattering data,'' arXiv:1602.03154 [hep-ph]. %%CITATION = ARXIV:1602.03154;%% %\cite{Harland-Lang:2014zoa} \bibitem{Harland-Lang:2014zoa} L.~A.~Harland-Lang, A.~D.~Martin, P.~Motylinski and R.~S.~Thorne, %``Parton distributions in the LHC era: MMHT 2014 PDFs,'' arXiv:1412.3989 [hep-ph]. %%CITATION = ARXIV:1412.3989;%% %\cite{Dulat:2015mca} \bibitem{Dulat:2015mca} S.~Dulat {\it et al.}, %``The CT14 Global Analysis of Quantum Chromodynamics,'' arXiv:1506.07443 [hep-ph]. %%CITATION = ARXIV:1506.07443;%% %\cite{Salam:2008qg} \bibitem{Salam:2008qg} G.~P.~Salam and J.~Rojo, {\em A Higher Order Perturbative Parton Evolution Toolkit (HOPPET)}, Comput.\ Phys.\ Commun.\ {\bf 180}, 120 (2009) [arXiv:0804.3755 [hep-ph]]. %%CITATION = ARXIV:0804.3755;%% %\cite{Kilian:2011ka} \bibitem{Kilian:2011ka} W.~Kilian, J.~Reuter, S.~Schmidt and D.~Wiesler, {\em An Analytic Initial-State Parton Shower}, JHEP {\bf 1204} (2012) 013 [arXiv:1112.1039 [hep-ph]]. %%CITATION = ARXIV:1112.1039;%% %\cite{Staub:2008uz} \bibitem{Staub:2008uz} F.~Staub, {\em Sarah}, arXiv:0806.0538 [hep-ph]. %%CITATION = ARXIV:0806.0538;%% %\cite{Staub:2009bi} \bibitem{Staub:2009bi} F.~Staub, {\em From Superpotential to Model Files for FeynArts and CalcHep/CompHep}, Comput.\ Phys.\ Commun.\ {\bf 181}, 1077 (2010) [arXiv:0909.2863 [hep-ph]]. %%CITATION = ARXIV:0909.2863;%% %\cite{Staub:2010jh} \bibitem{Staub:2010jh} F.~Staub, {\em Automatic Calculation of supersymmetric Renormalization Group Equations and Self Energies}, Comput.\ Phys.\ Commun.\ {\bf 182}, 808 (2011) [arXiv:1002.0840 [hep-ph]]. %%CITATION = ARXIV:1002.0840;%% %\cite{Staub:2012pb} \bibitem{Staub:2012pb} F.~Staub, {\em SARAH 3.2: Dirac Gauginos, UFO output, and more}, Computer Physics Communications {\bf 184}, pp. 1792 (2013) [Comput.\ Phys.\ Commun.\ {\bf 184}, 1792 (2013)] [arXiv:1207.0906 [hep-ph]]. %%CITATION = ARXIV:1207.0906;%% %\cite{Staub:2013tta} \bibitem{Staub:2013tta} F.~Staub, {\em SARAH 4: A tool for (not only SUSY) model builders}, Comput.\ Phys.\ Commun.\ {\bf 185}, 1773 (2014) [arXiv:1309.7223 [hep-ph]]. %%CITATION = ARXIV:1309.7223;%% \bibitem{mathematica} \Mathematica\ is a registered trademark of Wolfram Research, Inc., Champain, IL, USA. %\cite{Porod:2003um} \bibitem{Porod:2003um} W.~Porod, {\em SPheno, a program for calculating supersymmetric spectra, SUSY particle decays and SUSY particle production at e+ e- colliders}, Comput.\ Phys.\ Commun.\ {\bf 153}, 275 (2003) [hep-ph/0301101]. %%CITATION = HEP-PH/0301101;%% %\cite{Porod:2011nf} \bibitem{Porod:2011nf} W.~Porod and F.~Staub, {\em SPheno 3.1: Extensions including flavour, CP-phases and models beyond the MSSM}, Comput.\ Phys.\ Commun.\ {\bf 183}, 2458 (2012) [arXiv:1104.1573 [hep-ph]]. %%CITATION = ARXIV:1104.1573;%% %\cite{Staub:2011dp} \bibitem{Staub:2011dp} F.~Staub, T.~Ohl, W.~Porod and C.~Speckner, %``A Tool Box for Implementing Supersymmetric Models,'' Comput.\ Phys.\ Commun.\ {\bf 183}, 2165 (2012) [arXiv:1109.5147 [hep-ph]]. %%CITATION = ARXIV:1109.5147;%% %%%%% FeynRules %%%%% %\cite{Christensen:2008py} \bibitem{Christensen:2008py} N.~D.~Christensen and C.~Duhr, {\em FeynRules - Feynman rules made easy}, Comput.\ Phys.\ Commun.\ {\bf 180}, 1614 (2009) [arXiv:0806.4194 [hep-ph]]. %%CITATION = ARXIV:0806.4194;%% %\cite{Christensen:2009jx} \bibitem{Christensen:2009jx} N.~D.~Christensen, P.~de Aquino, C.~Degrande, C.~Duhr, B.~Fuks, M.~Herquet, F.~Maltoni and S.~Schumann, {\em A Comprehensive approach to new physics simulations}, Eur.\ Phys.\ J.\ C {\bf 71}, 1541 (2011) [arXiv:0906.2474 [hep-ph]]. %%CITATION = ARXIV:0906.2474;%% %\cite{Duhr:2011se} \bibitem{Duhr:2011se} C.~Duhr and B.~Fuks, %``A superspace module for the FeynRules package,'' Comput.\ Phys.\ Commun.\ {\bf 182}, 2404 (2011) [arXiv:1102.4191 [hep-ph]]. %%CITATION = ARXIV:1102.4191;%% %\cite{Christensen:2010wz} \bibitem{Christensen:2010wz} N.~D.~Christensen, C.~Duhr, B.~Fuks, J.~Reuter and C.~Speckner, {\em Introducing an interface between WHIZARD and FeynRules}, Eur.\ Phys.\ J.\ C {\bf 72}, 1990 (2012) [arXiv:1010.3251 [hep-ph]]. %%CITATION = ARXIV:1010.3251;%% %\cite{Degrande:2011ua} \bibitem{Degrande:2011ua} C.~Degrande, C.~Duhr, B.~Fuks, D.~Grellscheid, O.~Mattelaer and T.~Reiter, %``UFO - The Universal FeynRules Output,'' Comput.\ Phys.\ Commun.\ {\bf 183}, 1201 (2012) doi:10.1016/j.cpc.2012.01.022 [arXiv:1108.2040 [hep-ph]]. %%CITATION = doi:10.1016/j.cpc.2012.01.022;%% %\cite{Han:1998sg} \bibitem{Han:1998sg} T.~Han, J.~D.~Lykken and R.~-J.~Zhang, {\em On Kaluza-Klein states from large extra dimensions}, Phys.\ Rev.\ D {\bf 59}, 105006 (1999) [hep-ph/9811350]. %%CITATION = HEP-PH/9811350;%% %\cite{Fuks:2012im} \bibitem{Fuks:2012im} B.~Fuks, {\em Beyond the Minimal Supersymmetric Standard Model: from theory to phenomenology}, Int.\ J.\ Mod.\ Phys.\ A {\bf 27}, 1230007 (2012) [arXiv:1202.4769 [hep-ph]]. %%CITATION = ARXIV:1202.4769;%% %\cite{He:2007ge} \bibitem{He:2007ge} H.~-J.~He, Y.~-P.~Kuang, Y.~-H.~Qi, B.~Zhang, A.~Belyaev, R.~S.~Chivukula, N.~D.~Christensen and A.~Pukhov {\it et al.}, {\em CERN LHC Signatures of New Gauge Bosons in Minimal Higgsless Model}, Phys.\ Rev.\ D {\bf 78}, 031701 (2008) [arXiv:0708.2588 [hep-ph]]. %%CITATION = ARXIV:0708.2588;%% %%%%% WHIZARD NLO %%%%% %\cite{Kilian:2006cj} \bibitem{Kilian:2006cj} W.~Kilian, J.~Reuter and T.~Robens, {\em NLO Event Generation for Chargino Production at the ILC}, Eur.\ Phys.\ J.\ C {\bf 48}, 389 (2006) [hep-ph/0607127]. %%CITATION = HEP-PH/0607127;%% %\cite{Binoth:2010ra} \bibitem{Binoth:2010ra} J.~R.~Andersen {\it et al.} [SM and NLO Multileg Working Group Collaboration], {\em Les Houches 2009: The SM and NLO Multileg Working Group: Summary report}, arXiv:1003.1241 [hep-ph]. %%CITATION = ARXIV:1003.1241;%% %\cite{Butterworth:2010ym} \bibitem{Butterworth:2010ym} J.~M.~Butterworth, A.~Arbey, L.~Basso, S.~Belov, A.~Bharucha, F.~Braam, A.~Buckley and M.~Campanelli {\it et al.}, {\em Les Houches 2009: The Tools and Monte Carlo working group Summary Report}, arXiv:1003.1643 [hep-ph], arXiv:1003.1643 [hep-ph]. %%CITATION = ARXIV:1003.1643;%% %\cite{Binoth:2009rv} \bibitem{Binoth:2009rv} T.~Binoth, N.~Greiner, A.~Guffanti, J.~Reuter, J.-P.~.Guillet and T.~Reiter, {\em Next-to-leading order QCD corrections to pp --> b anti-b b anti-b + X at the LHC: the quark induced case}, Phys.\ Lett.\ B {\bf 685}, 293 (2010) [arXiv:0910.4379 [hep-ph]]. %%CITATION = ARXIV:0910.4379;%% %\cite{Greiner:2011mp} \bibitem{Greiner:2011mp} N.~Greiner, A.~Guffanti, T.~Reiter and J.~Reuter, {\em NLO QCD corrections to the production of two bottom-antibottom pairs at the LHC} Phys.\ Rev.\ Lett.\ {\bf 107}, 102002 (2011) [arXiv:1105.3624 [hep-ph]]. %% CITATION = ARXIV:1105.3624;%% %\cite{L_Ecuyer:2002} \bibitem{L_Ecuyer:2002} P.~L\'{e}Ecuyer, R.~Simard, E.~J.~Chen, and W.~D.~Kelton, {\em An Object-Oriented Random-Number Package with Many Long Streams and Substreams}, Operations Research, vol. 50, no. 6, pp. 1073-1075, Dec. 2002. %\cite{Platzer:2013esa} \bibitem{Platzer:2013esa} S.~Pl\"atzer, {\em RAMBO on diet}, [arXiv:1308.2922 [hep-ph]]. %% CITATION = ARXIV:1308.2922;%% %\cite{Kleiss:1991rn} \bibitem{Kleiss:1991rn} R.~Kleiss and W.~J.~Stirling, {\em Massive multiplicities and Monte Carlo}, Nucl.\ Phys.\ B {\bf 385}, 413 (1992). doi:10.1016/0550-3213(92)90107-M %%CITATION = doi:10.1016/0550-3213(92)90107-M;%% %\cite{Kleiss:1985gy} \bibitem{Kleiss:1985gy} R.~Kleiss, W.~J.~Stirling and S.~D.~Ellis, {\em A New Monte Carlo Treatment of Multiparticle Phase Space at High-energies}, Comput.\ Phys.\ Commun.\ {\bf 40} (1986) 359. doi:10.1016/0010-4655(86)90119-0 %% CITATION = doi:10.1016/0010-4655(86)90119-0;%% %\cite{Brun:1997pa} \bibitem{Brun:1997pa} R.~Brun and F.~Rademakers, {\em ROOT: An object oriented data analysis framework}, Nucl. Instrum. Meth. A \textbf{389}, 81-86 (1997) doi:10.1016/S0168-9002(97)00048-X %\cite{Buckley:2010ar} \bibitem{Buckley:2010ar} A.~Buckley, J.~Butterworth, L.~Lonnblad, D.~Grellscheid, H.~Hoeth, J.~Monk, H.~Schulz and F.~Siegert, {\em Rivet user manual}, Comput. Phys. Commun. \textbf{184}, 2803-2819 (2013) doi:10.1016/j.cpc.2013.05.021 [arXiv:1003.0694 [hep-ph]]. %\cite{Bierlich:2019rhm} \bibitem{Bierlich:2019rhm} C.~Bierlich, A.~Buckley, J.~Butterworth, C.~H.~Christensen, L.~Corpe, D.~Grellscheid, J.~F.~Grosse-Oetringhaus, C.~Gutschow, P.~Karczmarczyk, J.~Klein, L.~Lönnblad, C.~S.~Pollard, P.~Richardson, H.~Schulz and F.~Siegert, {\em Robust Independent Validation of Experiment and Theory: Rivet version 3}, SciPost Phys. \textbf{8}, 026 (2020) doi:10.21468/SciPostPhys.8.2.026 [arXiv:1912.05451 [hep-ph]]. %\cite{deFavereau:2013fsa} \bibitem{deFavereau:2013fsa} J.~de Favereau \textit{et al.} [DELPHES 3], {\em DELPHES 3, A modular framework for fast simulation of a generic collider experiment}, JHEP \textbf{02}, 057 (2014) doi:10.1007/JHEP02(2014)057 [arXiv:1307.6346 [hep-ex]] \end{thebibliography} \end{document} Index: trunk/ChangeLog =================================================================== --- trunk/ChangeLog (revision 8413) +++ trunk/ChangeLog (revision 8414) @@ -1,2037 +1,2040 @@ ChangeLog -- Summary of changes to the WHIZARD package Use svn log to see detailed changes. Version 2.8.3 2020-03-03 RELEASE: version 2.8.3 +2020-06-22 + Running width scheme supported for O'Mega matrix elements + 2020-06-20 Adding H-s-s coupling to SM_Higgs(_CKM) models 2020-06-17 Completion of ILC 2->6 fermion extended test suite 2020-06-15 Bug fix: PYTHIA6/Tauola, correctly assign tau spins for stau decays 2020-06-09 Bug fix: correctly update calls for additional VAMP/2 iterations Bug fix: correct assignment for tau spins from PYTHIA6 interface 2020-06-04 Bug fix: cascades2 tree merge with empty subtree(s) 2020-05-31 Switch $epa_mode for different EPA implementations 2020-05-26 Bug fix: spin information transferred for resonance histories 2020-04-13 HepMC: correct weighted events for non-xsec event normalizations 2020-04-04 Improved HepMC3 interface: HepMC3 Root/RootTree interface 2020-03-24 ISR: Fix on-shell kinematics for events with ?isr_handler=true (set ?isr_handler_keep_mass=false for old behavior) 2020-03-11 Beam masses are correctly passed to hard matrix element for CIRCE2 EPA with polarized beams: double-counting corrected 2020-02-25 Bug fix: Scale and alphas can be retrieved from internal event format to external formats 2020-02-17 Bug fix: ?keep_failed_events now forces output of actual event data Bug fix: particle-set reconstruction (rescanning events w/o radiation) 2020-01-28 Bug fix for left-over EPA parameter epa_e_max (replaced by epa_q_max) 2020-01-23 Bug fix for real components of NLO QCD 2->1 processes 2020-01-22 Bug fix: correct random number sequencing during parallel MPI event generation with rng_stream 2020-01-21 Consistent distribution of events during parallel MPI event generation 2020-01-20 Bug fix for configure setup for automake v1.16+ 2020-01-18 General SLHA parameter files for UFO models supported 2020-01-08 Bug fix: correctly register RECOLA processes with flavor sums 2019-12-19 Support for UFO customized propagators O'Mega unit tests for fermion-number violating interactions 2019-12-10 For distribution building: check for graphviz/dot version 2.40 or newer 2019-11-21 Bug fix: alternate setups now work correctly Infrastructure for accessing alpha_QED event-by-event Guard against tiny numbers that break ASCII event output Enable inverse hyperbolic functions as SINDARIN observables Remove old compiler bug workarounds 2019-11-20 Allow quoted -e argument, implemented -f option 2019-11-19 Bug fix: resonance histories now work also with UFO models Fix in numerical precision of ASCII VAMP2 grids 2019-11-06 Add squared matrix elements to the LCIO event header 2019-11-05 Do not include RNG state in MD5 sum for CIRCE1/2 2019-11-04 Full CIRCE2 ILC 250 and 500 GeV beam spectra added Minor update on LCIO event header information 2019-10-30 NLO QCD for final states completed When using Openloops, v2.1.1+ mandatory 2019-10-25 Binary grid files for VAMP2 integrator ################################################################## 2019-10-24 RELEASE: version 2.8.2 2019-10-20 Bug fix for HepMC linker flags 2019-10-19 Support for spin-2 particles from UFO files 2019-09-27 LCIO event format allows rescan and alternate weights 2019-09-24 Compatibility fix for OCaml v4.08.0+ ################################################################## 2019-09-21 RELEASE: version 2.8.1 2019-09-19 Carriage return characters in UFO models can be parsed Mathematica symbols in UFO models possible Unused/undefined parameters in UFO models handled 2019-09-13 New extended NLO test suite for ee and pp processes 2019-09-09 Photon isolation (separation of perturbative and fragmentation part a la Frixione) 2019-09-05 Major progress on NLO QCD for hadron collisions: - correctly assign flavor structures for alpha regions - fix crossing of particles for initial state splittings - correct assignment for PDF factors for real subtractions - fix kinematics for collinear splittings - bug fix for integrated virtual subtraction terms 2019-09-03 b and c jet selection in cuts and analysis 2019-08-27 Support for Intel MPI 2019-08-20 Complete (preliminary) HepMC3 support (incl. backwards HepMC2 write/read mode) 2019-08-08 Bug fix: handle carriage returns in UFO files (non-Unix OS) ################################################################## 2019-08-07 RELEASE: version 2.8.0 2019-07-31 Complete WHIZARD UFO interface: - general Lorentz structures - matrix element support for general color factors - missing features: Majorana fermions and SLHA 2019-07-20 Make WHIZARD compatible with OCaml 4.08.0+ 2019-07-19 Fix version testing for LHAPDF 6.2.3 and newer Minimal required OCaml version is now 4.02.3. 2019-04-18 Correctly generate ordered FKS tuples for alpha regions from all possible underlying Born processes 2019-04-08 Extended O'Mega/Recola matrix element test suite 2019-03-29 Correct identical particle symmetry factors for FKS subtraction 2019-03-28 Correct assertion of spin-correlated matrix elements for hadron collisions 2019-03-27 Bug fix for cut-off parameter delta_i for collinear plus/minus regions ################################################################## 2019-03-27 RELEASE: version 2.7.1 2019-02-19 Further infrastructure for HepMC3 interface (v3.01.00) 2019-02-07 Explicit configure option for using debugging options Bug fix for performance by removing unnecessary debug operations 2019-01-29 Bug fix for DGLAP remnants with cut-off parameter delta_i 2019-01-24 Radiative decay neu2 -> neu1 A added to MSSM_Hgg model ################################################################## 2019-01-21 RELEASE: version 2.7.0 2018-12-18 Support RECOLA for integrated und unintegrated subtractions 2018-12-11 FCNC top-up sector in model SM_top_anom 2018-12-05 Use libtirpc instead of SunRPC on Arch Linux etc. 2018-11-30 Display rescaling factor for weighted event samples with cuts 2018-11-29 Reintroduce check against different masses in flavor sums Bug fix for wrong couplings in the Littlest Higgs model(s) 2018-11-22 Bug fix for rescanning events with beam structure 2018-11-09 Major refactoring of internal process data 2018-11-02 PYTHIA8 interface 2018-10-29 Flat phase space parametrization with RAMBO (on diet) implemented 2018-10-17 Revise extended test suite 2018-09-27 Process container for RECOLA processes 2018-09-15 Fixes by M. Berggren for PYTHIA6 interface 2018-09-14 First fixes after HepForge modernization ################################################################## 2018-08-23 RELEASE: version 2.6.4 2018-08-09 Infrastructure to check colored subevents 2018-07-10 Infrastructure for running WHIZARD in batch mode 2018-07-04 MPI available from distribution tarball 2018-06-03 Support Intel Fortran Compiler under MAC OS X 2018-05-07 FKS slicing parameter delta_i (initial state) implementend 2018-05-03 Refactor structure function assignment for NLO 2018-05-02 FKS slicing parameter xi_cut, delta_0 implemented 2018-04-20 Workspace subdirectory for process integration (grid/phs files) Packing/unpacking of files at job end/start Exporting integration results from scan loops 2018-04-13 Extended QCD NLO test suite 2018-04-09 Bug fix for Higgs Singlet Extension model 2018-04-06 Workspace subdirectory for process generation and compilation --job-id option for creating job-specific names 2018-03-20 Bug fix for color flow matching in hadron collisions with identical initial state quarks 2018-03-08 Structure functions quantum numbers correctly assigned for NLO 2018-02-24 Configure setup includes 'pgfortran' and 'flang' 2018-02-21 Include spin-correlated matrix elements in interactions 2018-02-15 Separate module for QED ISR structure functions ################################################################## 2018-02-10 RELEASE: version 2.6.3 2018-02-08 Improvements in memory management for PS generation 2018-01-31 Partial refactoring: quantum number assigment NLO Initial-state QCD splittings for hadron collisions 2018-01-25 Bug fix for weighted events with VAMP2 2018-01-17 Generalized interface for Recola versions 1.3+ and 2.1+ 2018-01-15 Channel equivalences also for VAMP2 integrator 2018-01-12 Fix for OCaml compiler 4.06 (and newer) 2017-12-19 RECOLA matrix elements with flavor sums can be integrated 2017-12-18 Bug fix for segmentation fault in empty resonance histories 2017-12-16 Fixing a bug in PYTHIA6 PYHEPC routine by omitting CMShowers from transferral between PYTHIA and WHIZARD event records 2017-12-15 Event index for multiple processes in event file correct ################################################################## 2017-12-13 RELEASE: version 2.6.2 2017-12-07 User can set offset in event numbers 2017-11-29 Possibility to have more than one RECOLA process in one file 2017-11-23 Transversal/mixed (and unitarized) dim-8 operators 2017-11-16 epa_q_max replaces epa_e_max (trivial factor 2) 2017-11-15 O'Mega matrix element compilation silent now 2017-11-14 Complete expanded P-wave form factor for top threshold 2017-11-10 Incoming particles can be accessed in SINDARIN 2017-11-08 Improved handling of resonance insertion, additional parameters 2017-11-04 Added Higgs-electron coupling (SM_Higgs) ################################################################## 2017-11-03 RELEASE: version 2.6.1 2017-10-20 More than 5 NLO components possible at same time 2017-10-19 Gaussian cutoff for shower resonance matching 2017-10-12 Alternative (more efficient) method to generate phase space file 2017-10-11 Bug fix for shower resonance histories for processes with multiple components 2017-09-25 Bug fix for process libraries in shower resonance histories 2017-09-21 Correctly generate pT distribution for EPA remnants 2017-09-20 Set branching ratios for unstable particles also by hand 2017-09-14 Correctly generate pT distribution for ISR photons ################################################################## 2017-09-08 RELEASE: version 2.6.0 2017-09-05 Bug fix for initial state NLO QCD flavor structures Real and virtual NLO QCD hadron collider processes work with internal interactions 2017-09-04 Fully validated MPI integration and event generation 2017-09-01 Resonance histories for shower: full support Bug fix in O'Mega model constraints O'Mega allows to output a parsable form of the DAG 2017-08-24 Resonance histories in events for transferral to parton shower (e.g. in ee -> jjjj) 2017-08-01 Alpha version of HepMC v3 interface (not yet really functional) 2017-07-31 Beta version for RECOLA OLP support 2017-07-06 Radiation generator fix for LHC processes 2017-06-30 Fix bug for NLO with structure functions and/or polarization 2017-06-23 Collinear limit for QED corrections works 2017-06-17 POWHEG grids generated already during integration 2017-06-12 Soft limit for QED corrections works 2017-05-16 Beta version of full MPI parallelization (VAMP2) Check consistency of POWHEG grid files Logfile config-summary.log for configure summary 2017-05-12 Allow polarization in top threshold 2017-05-09 Minimal demand automake 1.12.2 Silent rules for make procedures 2017-05-07 Major fix for POWHEG damping Correctly initialize FKS ISR phasespace ################################################################## 2017-05-06 RELEASE: version 2.5.0 2017-05-05 Full UFO support (SM-like models) Fixed-beam ISR FKS phase space 2017-04-26 QED splittings in radiation generator 2017-04-10 Retire deprecated O'Mega vertex cache files ################################################################## 2017-03-24 RELEASE: version 2.4.1 2017-03-16 Distinguish resonance charge in phase space channels Keep track of resonance histories in phase space Complex mass scheme default for OpenLoops amplitudes 2017-03-13 Fix helicities for polarized OpenLoops calculations 2017-03-09 Possibility to advance RNG state in rng_stream 2017-03-04 General setup for partitioning real emission phase space 2017-03-06 Bug fix on rescan command for converting event files 2017-02-27 Alternative multi-channel VEGAS implementation VAMP2: serial backbone for MPI setup Smoothstep top threshold matching 2017-02-25 Single-beam structure function with s-channel mapping supported Safeguard against invalid process libraries 2017-02-16 Radiation generator for photon emission 2017-02-10 Fixes for NLO QCD processes (color correlations) 2017-01-16 LCIO variable takes precedence over LCIO_DIR 2017-01-13 Alternative random number generator rng_stream (cf. L'Ecuyer et al.) 2017-01-01 Fix for multi-flavor BLHA tree matrix elements 2016-12-31 Grid path option for VAMP grids 2016-12-28 Alpha version of Recola OLP support 2016-12-27 Dalitz plots for FKS phase space 2016-12-14 NLO multi-flavor events possible 2016-12-09 LCIO event header information added 2016-12-02 Alpha version of RECOLA interface Bug fix for generator status in LCIO ################################################################## 2016-11-28 RELEASE: version 2.4.0 2016-11-24 Bug fix for OpenLoops interface: EW scheme is set by WHIZARD Bug fixes for top threshold implementation 2016-11-11 Refactoring of dispatching 2016-10-18 Bug fix for LCIO output 2016-10-10 First implementation for collinear soft terms 2016-10-06 First full WHIZARD models from UFO files 2016-10-05 WHIZARD does not support legacy gcc 4.7.4 any longer 2016-09-30 Major refactoring of process core and NLO components 2016-09-23 WHIZARD homogeneous entity: discarding subconfigures for CIRCE1/2, O'Mega, VAMP subpackages; these are reconstructable by script projectors 2016-09-06 Introduce main configure summary 2016-08-26 Fix memory leak in event generation ################################################################## 2016-08-25 RELEASE: version 2.3.1 2016-08-19 Bug fix for EW-scheme dependence of gluino propagators 2016-08-01 Beta version of complex mass scheme support 2016-07-26 Fix bug in POWHEG damping for the matching ################################################################## 2016-07-21 RELEASE: version 2.3.0 2016-07-20 UFO file support (alpha version) in O'Mega 2016-07-13 New (more) stable of WHIZARD GUI Support for EW schemes for OpenLoops Factorized NLO top decays for threshold model 2016-06-15 Passing factorization scale to PYTHIA6 Adding charge and neutral observables 2016-06-14 Correcting angular distribution/tweaked kinematics in non-collinear structure functions splittings 2016-05-10 Include (Fortran) TAUOLA/PHOTOS for tau decays via PYTHIA6 (backwards validation of LC CDR/TDR samples) 2016-04-27 Within OpenLoops virtuals: support for Collier library 2016-04-25 O'Mega vertex tables only loaded at first usage 2016-04-21 New CJ15 PDF parameterizations added 2016-04-21 Support for hadron collisions at NLO QCD 2016-04-05 Support for different (parameter) schemes in model files 2016-03-31 Correct transferral of lifetime/vertex from PYTHIA/TAUOLA into the event record 2016-03-21 New internal implementation of polarization via Bloch vectors, remove pointer constructions 2016-03-13 Extension of cascade syntax for processes: exclude propagators/vertices etc. possible 2016-02-24 Full support for OpenLoops QCD NLO matrix elements, inclusion in test suite 2016-02-12 Substantial progress on QCD NLO support 2016-02-02 Automated resonance mapping for FKS subtraction 2015-12-17 New BSM model WZW for diphoton resonances ################################################################## 2015-11-22 RELEASE: version 2.2.8 2015-11-21 Bug fix for fixed-order NLO events 2015-11-20 Anomalous FCNC top-charm vertices 2015-11-19 StdHEP output via HEPEVT/HEPEV4 supported 2015-11-18 Full set of electroweak dim-6 operators included 2015-10-22 Polarized one-loop amplitudes supported 2015-10-21 Fixes for event formats for showered events 2015-10-14 Callback mechanism for event output 2015-09-22 Bypass matrix elements in pure event sample rescans StdHep frozen final version v5.06.01 included internally 2015-09-21 configure option --with-precision to demand 64bit, 80bit, or 128bit Fortran and bind C precision types 2015-09-07 More extensive tests of NLO infrastructure and POWHEG matching 2015-09-01 NLO decay infrastructure User-defined squared matrix elements Inclusive FastJet algorithm plugin Numerical improvement for small boosts ################################################################## 2015-08-11 RELEASE: version 2.2.7 2015-08-10 Infrastructure for damped POWHEG Massive emitters in POWHEG Born matrix elements via BLHA GoSam filters via SINDARIN Minor running coupling bug fixes Fixed-order NLO events 2015-08-06 CT14 PDFs included (LO, NLO, NNLL) 2015-07-07 Revalidation of ILC WHIZARD-PYTHIA event chain Extended test suite for showered events Alpha version of massive FSR for POWHEG 2015-06-09 Fix memory leak in interaction for long cascades Catch mismatch between beam definition and CIRCE2 spectrum 2015-06-08 Automated POWHEG matching: beta version Infrastructure for GKS matching Alpha version of fixed-order NLO events CIRCE2 polarization averaged spectra with explicitly polarized beams 2015-05-12 Abstract matching type: OO structure for matching/merging 2015-05-07 Bug fix in event record WHIZARD-PYTHIA6 transferral Gaussian beam spectra for lepton colliders ################################################################## 2015-05-02 RELEASE: version 2.2.6 2015-05-01 Models for (unitarized) tensor resonances in VBS 2015-04-28 Bug fix in channel weights for event generation. 2015-04-18 Improved event record transfer WHIZARD/PYTHIA6 2015-03-19 POWHEG matching: alpha version ################################################################## 2015-02-27 RELEASE: version 2.2.5 2015-02-26 Abstract types for quantum numbers 2015-02-25 Read-in of StdHEP events, self-tests 2015-02-22 Bug fix for mother-daughter relations in showered/hadronized events 2015-02-20 Projection on polarization in intermediate states 2015-02-13 Correct treatment of beam remnants in event formats (also LC remnants) ################################################################## 2015-02-06 RELEASE: version 2.2.4 2015-02-06 Bug fix in event output 2015-02-05 LCIO event format supported 2015-01-30 Including state matrices in WHIZARD's internal IO Versioning for WHIZARD's internal IO Libtool update from 2.4.3 to 2.4.5 LCIO event output (beta version) 2015-01-27 Progress on NLO integration Fixing a bug for multiple processes in a single event file when using beam event files 2015-01-19 Bug fix for spin correlations evaluated in the rest frame of the mother particle 2015-01-17 Regression fix for statically linked processes from SARAH and FeynRules 2015-01-10 NLO: massive FKS emitters supported (experimental) 2015-01-06 MMHT2014 PDF sets included 2015-01-05 Handling mass degeneracies in auto_decays 2014-12-19 Fixing bug in rescan of event files ################################################################## 2014-11-30 RELEASE: version 2.2.3 2014-11-29 Beta version of LO continuum/NLL-threshold matched top threshold model for e+e- physics 2014-11-28 More internal refactoring: disentanglement of module dependencies 2014-11-21 OVM: O'Mega Virtual Machine, bytecode instructions instead of compiled Fortran code 2014-11-01 Higgs Singlet extension model included 2014-10-18 Internal restructuring of code; half-way WHIZARD main code file disassembled 2014-07-09 Alpha version of NLO infrastructure ################################################################## 2014-07-06 RELEASE: version 2.2.2 2014-07-05 CIRCE2: correlated LC beam spectra and GuineaPig Interface to LC machine parameters 2014-07-01 Reading LHEF for decayed/factorized/showered/ hadronized events 2014-06-25 Configure support for GoSAM/Ninja/Form/QGraf 2014-06-22 LHAPDF6 interface 2014-06-18 Module for automatic generation of radiation and loop infrastructure code 2014-06-11 Improved internal directory structure ################################################################## 2014-06-03 RELEASE: version 2.2.1 2014-05-30 Extensions of internal PDG arrays 2014-05-26 FastJet interface 2014-05-24 CJ12 PDFs included 2014-05-20 Regression fix for external models (via SARAH or FeynRules) ################################################################## 2014-05-18 RELEASE: version 2.2.0 2014-04-11 Multiple components: inclusive process definitions, syntax: process A + B + ... 2014-03-13 Improved PS mappings for e+e- ISR ILC TDR and CLIC spectra included in CIRCE1 2014-02-23 New models: AltH w\ Higgs for exclusion purposes, SM_rx for Dim 6-/Dim-8 operators, SSC for general strong interactions (w/ Higgs), and NoH_rx (w\ Higgs) 2014-02-14 Improved s-channel mapping, new on-shell production mapping (e.g. Drell-Yan) 2014-02-03 PRE-RELEASE: version 2.2.0_beta 2014-01-26 O'Mega: Feynman diagram generation possible (again) 2013-12-16 HOPPET interface for b parton matching 2013-11-15 PRE-RELEASE: version 2.2.0_alpha-4 2013-10-27 LHEF standards 1.0/2.0/3.0 implemented 2013-10-15 PRE-RELEASE: version 2.2.0_alpha-3 2013-10-02 PRE-RELEASE: version 2.2.0_alpha-2 2013-09-25 PRE-RELEASE: version 2.2.0_alpha-1 2013-09-12 PRE-RELEASE: version 2.2.0_alpha 2013-09-03 General 2HDM implemented 2013-08-18 Rescanning/recalculating events 2013-06-07 Reconstruction of complete event from 4-momenta possible 2013-05-06 Process library stacks 2013-05-02 Process stacks 2013-04-29 Single-particle phase space module 2013-04-26 Abstract interface for random number generator 2013-04-24 More object-orientation on modules Midpoint-rule integrator 2013-04-05 Object-oriented integration and event generation 2013-03-12 Processes recasted object-oriented: MEs, scales, structure functions First infrastructure for general Lorentz structures 2013-01-17 Object-orientated reworking of library and process core, more variable internal structure, unit tests 2012-12-14 Update Pythia version to 6.4.27 2012-12-04 Fix the phase in HAZ vertices 2012-11-21 First O'Mega unit tests, some infrastructure 2012-11-13 Bug fix in anom. HVV Lorentz structures ################################################################## 2012-09-18 RELEASE: version 2.1.1 2012-09-11 Model MSSM_Hgg with Hgg and HAA vertices 2012-09-10 First version of implementation of multiple interactions in WHIZARD 2012-09-05 Infrastructure for internal CKKW matching 2012-09-02 C, C++, Python API 2012-07-19 Fixing particle numbering in HepMC format ################################################################## 2012-06-15 RELEASE: version 2.1.0 2012-06-14 Analytical and kT-ordered shower officially released PYTHIA interface officially released 2012-05-09 Intrisince PDFs can be used for showering 2012-05-04 Anomalous Higgs couplings a la hep-ph/9902321 ################################################################## 2012-03-19 RELEASE: version 2.0.7 2012-03-15 Run IDs are available now More event variables in analysis Modified raw event format (compatibility mode exists) 2012-03-12 Bug fix in decay-integration order MLM matching steered completely internally now 2012-03-09 Special phase space mapping for narrow resonances decaying to 4-particle final states with far off-shell intermediate states Running alphas from PDF collaborations with builtin PDFs 2012-02-16 Bug fix in cascades decay infrastructure 2012-02-04 WHIZARD documentation compatible with TeXLive 2011 2012-02-01 Bug fix in FeynRules interface with --prefix flag 2012-01-29 Bug fix with name clash of O'Mega variable names 2012-01-27 Update internal PYTHIA to version 6.4.26 Bug fix in LHEF output 2012-01-21 Catching stricter automake 1.11.2 rules 2011-12-23 Bug fix in decay cascade setup 2011-12-20 Bug fix in helicity selection rules 2011-12-16 Accuracy goal reimplemented 2011-12-14 WHIZARD compatible with TeXLive 2011 2011-12-09 Option --user-target added ################################################################## 2011-12-07 RELEASE: version 2.0.6 2011-12-07 Bug fixes in SM_top_anom Added missing entries to HepMC format 2011-12-06 Allow to pass options to O'Mega Bug fix for HEPEVT block for showered/hadronized events 2011-12-01 Reenabled user plug-in for external code for cuts, structure functions, routines etc. 2011-11-29 Changed model SM_Higgs for Higgs phenomenology 2011-11-25 Supporting a Y, (B-L) Z' model 2011-11-23 Make WHIZARD compatible for MAC OS X Lion/XCode 4 2011-09-25 WHIZARD paper published: Eur.Phys.J. C71 (2011) 1742 2011-08-16 Model SM_QCD: QCD with one EW insertion 2011-07-19 Explicit output channel for dvips avoids printing 2011-07-10 Test suite for WHIZARD unit tests 2011-07-01 Commands for matrix element tests More OpenMP parallelization of kinematics Added unit tests 2011-06-23 Conversion of CIRCE2 from F77 to F90, major clean-up 2011-06-14 Conversion of CIRCE1 from F77 to F90 2011-06-10 OpenMP parallelization of channel kinematics (by Matthias Trudewind) 2011-05-31 RELEASE: version 1.97 2011-05-24 Minor bug fixes: update grids and elsif statement. ################################################################## 2011-05-10 RELEASE: version 2.0.5 2011-05-09 Fixed bug in final state flavor sums Minor improvements on phase-space setup 2011-05-05 Minor bug fixes 2011-04-15 WHIZARD as a precompiled 64-bit binary available 2011-04-06 Wall clock instead of cpu time for time estimates 2011-04-05 Major improvement on the phase space setup 2011-04-02 OpenMP parallelization for helicity loop in O'Mega matrix elements 2011-03-31 Tools for relocating WHIZARD and use in batch environments 2011-03-29 Completely static builds possible, profiling options 2011-03-28 Visualization of integration history 2011-03-27 Fixed broken K-matrix implementation 2011-03-23 Including the GAMELAN manual in the distribution 2011-01-26 WHIZARD analysis can handle hadronized event files 2011-01-17 MSTW2008 and CT10 PDF sets included 2010-12-23 Inclusion of NMSSM with Hgg couplings 2010-12-21 Advanced options for integration passes 2010-11-16 WHIZARD supports CTEQ6 and possibly other PDFs directly; data files included in the distribution ################################################################## 2010-10-26 RELEASE: version 2.0.4 2010-10-06 Bug fix in MSSM implementation 2010-10-01 Update to libtool 2.4 2010-09-29 Support for anomalous top couplings (form factors etc.) Bug fix for running gauge Yukawa SUSY couplings 2010-09-28 RELEASE: version 1.96 2010-09-21 Beam remnants and pT spectra for lepton collider re-enabled Restructuring subevt class 2010-09-16 Shower and matching are disabled by default PYTHIA as a conditional on these two options 2010-09-14 Possibility to read in beam spectra re-enabled (e.g. Guinea Pig) 2010-09-13 Energy scan as (pseudo-) structure functions re-implemented 2010-09-10 CIRCE2 included again in WHIZARD 2 and validated 2010-09-02 Re-implementation of asymmetric beam energies and collision angles, e-p collisions work, inclusion of a HERA DIS test case ################################################################## 2010-10-18 RELEASE: version 2.0.3 2010-08-08 Bug in CP-violating anomalous triple TGCs fixed 2010-08-06 Solving backwards compatibility problem with O'Caml 3.12.0 2010-07-12 Conserved quantum numbers speed up O'Mega code generation 2010-07-07 Attaching full ISR/FSR parton shower and MPI/ISR module Added SM model containing Hgg, HAA, HAZ vertices 2010-07-02 Matching output available as LHEF and STDHEP 2010-06-30 Various bug fixes, missing files, typos 2010-06-26 CIRCE1 completely re-enabled Chaining structure functions supported 2010-06-25 Partial support for conserved quantum numbers in O'Mega 2010-06-21 Major upgrade of the graphics package: error bars, smarter SINDARIN steering, documentation, and all that... 2010-06-17 MLM matching with PYTHIA shower included 2010-06-16 Added full CIRCE1 and CIRCE2 versions including full documentation and miscellanea to the trunk 2010-06-12 User file management supported, improved variable and command structure 2010-05-24 Improved handling of variables in local command lists 2010-05-20 PYTHIA interface re-enabled 2010-05-19 ASCII file formats for interfacing ROOT and gnuplot in data analysis ################################################################## 2010-05-18 RELEASE: version 2.0.2 2010-05-14 Reimplementation of visualization of phase space channels Minor bug fixes 2010-05-12 Improved phase space - elimination of redundancies 2010-05-08 Interface for polarization completed: polarized beams etc. 2010-05-06 Full quantum numbers appear in process log Integration results are usable as user variables Communication with external programs 2010-05-05 Split module commands into commands, integration, simulation modules 2010-05-04 FSR+ISR for the first time connected to the WHIZARD 2 core ################################################################## 2010-04-25 RELEASE: version 2.0.1 2010-04-23 Automatic compile and integrate if simulate is called Minor bug fixes in O'Mega 2010-04-21 Checkpointing for event generation Flush statements to use WHIZARD inside a pipe 2010-04-20 Reimplementation of signal handling in WGIZARD 2.0 2010-04-19 VAMP is now a separately configurable and installable unit of WHIZARD, included VAMP self-checks Support again compilation in quadruple precision 2010-04-06 Allow for logarithmic plots in GAMELAN, reimplement the possibility to set the number of bins 2010-04-15 Improvement on time estimates for event generation ################################################################## 2010-04-12 RELEASE: version 2.0.0 2010-04-09 Per default, the code for the amplitudes is subdivided to allow faster compiler optimization More advanced and unified and straightforward command language syntax Final bug fixes 2010-04-07 Improvement on SINDARIN syntax; printf, sprintf function thorugh a C interface 2010-04-05 Colorizing DAGs instead of model vertices: speed boost in colored code generation 2010-03-31 Generalized options for normalization of weighted and unweighted events Grid and weight histories added again to log files Weights can be used in analyses 2010-03-28 Cascade decays completely implemented including color and spin correlations 2010-03-07 Added new WHIZARD header with logo 2010-03-05 Removed conflict in O'Mega amplitudes between flavour sums and cascades StdHEP interface re-implemented 2010-03-03 RELEASE: version 2.0.0rc3 Several bug fixes for preventing abuse in input files OpenMP support for amplitudes Reimplementation of WHIZARD 1 HEPEVT ASCII event formats FeynRules interface successfully passed MSSM test 2010-02-26 Eliminating ghost gluons from multi-gluon amplitudes 2010-02-25 RELEASE: version 1.95 HEPEVT format from WHIZARD 1 re-implemented in WHIZARD 2 2010-02-23 Running alpha_s implemented in the FeynRules interface 2010-02-19 MSSM (semi-) automatized self-tests finalized 2010-02-17 RELEASE: version 1.94 2010-02-16 Closed memory corruption in WHIZARD 1 Fixed problems of old MadGraph and CompHep drivers with modern compilers Uncolored vertex selection rules for colored amplitudes in O'Mega 2010-02-15 Infrastructure for color correlation computation in O'Mega finished Forbidden processes are warned about, but treated as non-fatal 2010-02-14 Color correlation computation in O'Mega finalized 2010-02-10 Improving phase space mappings for identical particles in initial and final states Introduction of more extended multi-line error message 2010-02-08 First O'Caml code for computation of color correlations in O'Mega 2010-02-07 First MLM matching with e+ e- -> jets ################################################################## 2010-02-06 RELEASE: version 2.0.0rc2 2010-02-05 Reconsidered the Makefile structure and more extended tests Catch a crash between WHIZARD and O'Mega for forbidden processes Tensor products of arbitrary color structures in jet definitions 2010-02-04 Color correlation computation in O'Mega finalized ################################################################## 2010-02-03 RELEASE: version 2.0.0rc1 ################################################################## 2010-01-31 Reimplemented numerical helicity selection rules Phase space functionality of version 1 restored and improved 2009-12-05 NMSSM validated with FeynRules in WHIZARD 1 (Felix Braam) 2009-12-04 RELEASE: version 2.0.0alpha ################################################################## 2009-04-16 RELEASE: version 1.93 2009-04-15 Clean-up of Makefiles and configure scripts Reconfiguration of BSM model implementation extended supersymmetric models 2008-12-23 New model NMSSM (Felix Braam) SLHA2 added Bug in LHAPDF interface fixed 2008-08-16 Bug fixed in K matrix implementation Gravitino option in the MSSM added 2008-03-20 Improved color and flavor sums ################################################################## 2008-03-12 RELEASE: version 1.92 LHEF (Les Houches Event File) format added Fortran 2003 command-line interface (if supported by the compiler) Automated interface to colored models More bug fixes and workarounds for compiler compatibility ################################################################## 2008-03-06 RELEASE: version 1.91 New model K-matrix (resonances and anom. couplings in WW scattering) EWA spectrum Energy-scan pseudo spectrum Preliminary parton shower module (only from final-state quarks) Cleanup and improvements of configure process Improvements for O'Mega parameter files Quadruple precision works again More plotting options: lines, symbols, errors Documentation with PDF bookmarks enabled Various bug fixes 2007-11-29 New model UED ################################################################## 2007-11-23 RELEASE: version 1.90 O'Mega now part of the WHIZARD tree Madgraph/CompHEP disabled by default (but still usable) Support for LHAPDF (preliminary) Added new models: SMZprime, SM_km, Template Improved compiler recognition and compatibility Minor bug fixes ################################################################## 2006-06-15 RELEASE: version 1.51 Support for anomaly-type Higgs couplings (to gluon and photon/Z) Support for spin 3/2 and spin 2 New models: Little Higgs (4 versions), toy models for extra dimensions and gravitinos Fixes to the whizard.nw source documentation to run through LaTeX Intel 9.0 bug workaround (deallocation of some arrays) 2006-05-15 O'Mega RELEASE: version 0.11 merged JRR's O'Mega extensions ################################################################## 2006-02-07 RELEASE: version 1.50 To avoid confusion: Mention outdated manual example in BUGS file O'Mega becomes part of the WHIZARD generator 2006-02-02 [bug fix update] Bug fix: spurious error when writing event files for weighted events Bug fix: 'r' option for omega produced garbage for some particle names Workaround for ifort90 bug (crash when compiling whizard_event) Workaround for ifort90 bug (crash when compiling hepevt_common) 2006-01-27 Added process definition files for MSSM 2->2 processes Included beam recoil for EPA (T.Barklow) Updated STDHEP byte counts (for STDHEP 5.04.02) Fixed STDHEP compatibility (avoid linking of incomplete .so libs) Fixed issue with comphep requiring Xlibs on Opteron Fixed issue with ifort 8.x on Opteron (compiling 'signal' interface) Fixed color-flow code: was broken for omega with option 'c' and 'w' Workaround hacks for g95 compatibility 2005-11-07 O'Mega RELEASE: version 0.10 O'Mega, merged JRR's and WK's color hack for WHiZard O'Mega, EXPERIMENTAL: cache fusion tables (required for colors a la JRR/WK) O'Mega, make JRR's MSSM official ################################################################## 2005-10-25 RELEASE: version 1.43 Minor fixes in MSSM couplings (Higgs/3rd gen squarks). This should be final, since the MSSM results agree now completely with Madgraph and Sherpa User-defined lower and upper limits for split event file count Allow for counters (events, bytes) exceeding $2^{31}$ Revised checksum treatment and implementation (now MD5) Bug fix: missing process energy scale in raw event file ################################################################## 2005-09-30 RELEASE: version 1.42 Graphical display of integration history ('make history') Allow for switching off signals even if supported (configure option) 2005-09-29 Revised phase space generation code, in particular for flavor sums Negative cut and histogram codes use initial beams instead of initial parton momenta. This allows for computing, e.g., E_miss Support constant-width and zero-width options for O'Mega Width options now denoted by w:X (X=f,c,z). f option obsolescent Bug fix: colorized code: flipped indices could screw up result Bug fix: O'Mega with 'c' and 'w:f' option together (still some problem) Bug fix: dvips on systems where dvips defaults to lpr Bug fix: integer overflow if too many events are requested 2005-07-29 Allow for 2 -> 1 processes (if structure functions are on) 2005-07-26 Fixed and expanded the 'test' matrix element: Unit matrix element with option 'u' / default: normalized phase space ################################################################## 2005-07-15 RELEASE: version 1.41 Bug fix: no result for particle decay processes with width=0 Bug fix: line breaks in O'Mega files with color decomposition 2005-06-02 New self-tests (make test-QED / test-QCD / test-SM) check lists of 2->2 processes Bug fix: HELAS calling convention for wwwwxx and jwwwxx (4W-Vertex) 2005-05-25 Revised Makefile structure Eliminated obsolete references to ISAJET/SUSY (superseded by SLHA) 2005-05-19 Support for color in O'Mega (using color flow decomposition) New model QCD Parameter file changes that correspond to replaced SM module in O'Mega Bug fixes in MSSM (O'Mega) parameter file 2005-05-18 New event file formats, useful for LHC applications: ATHENA and Les Houches Accord (external fragmentation) Naive (i.e., leading 1/N) color factor now implemented both for incoming and outgoing partons 2005-01-26 include missing HELAS files for bundle pgf90 compatibility issues [note: still internal error in pgf90] ################################################################## 2004-12-13 RELEASE: version 1.40 compatibility fix: preprocessor marks in helas code now commented out minor bug fix: format string in madgraph source 2004-12-03 support for arbitray beam energies and directions allow for pT kick in structure functions bug fix: rounding error could result in zero cross section (compiler-dependent) 2004-10-07 simulate decay processes list fraction (of total width/cross section) instead of efficiency in process summary new cut/analysis parameters AA, AAD, CTA: absolute polar angle 2004-10-04 Replaced Madgraph I by Madgraph II. Main improvement: model no longer hardcoded introduced parameter reset_seed_each_process (useful for debugging) bug fix: color initialization for some processes was undefined 2004-09-21 don't compile unix_args module if it is not required ################################################################## 2004-09-20 RELEASE: version 1.30 g95 compatibility issues resolved some (irrelevant) memory leaks closed removed obsolete warning in circe1 manual update (essentially) finished 2004-08-03 O'Mega RELEASE: version 0.9 O'Mega, src/trie.mli, src/trie.ml: make interface compatible with the O'Caml 3.08 library (remains compatible with older versions). Implementation of unused functions still incomplete. 2004-07-26 minor fixes and improvements in make process 2004-06-29 workarounds for new Intel compiler bugs ... no rebuild of madgraph/comphep executables after 'make clean' bug fix in phase space routine: wrong energy for massive initial particles bug fix in (new) model interface: name checks for antiparticles pre-run checks for comphep improved ww-strong model file extended Model files particle name fixes, chep SM vertices included 2004-06-22 O'Mega RELEASE: version 0.8 O'Mega MSSM: sign of W+/W-/A and W+/W-/Z couplings 2004-05-05 Fixed bug in PDFLIB interface: p+pbar was initialized as p+p (ThO) NAG compiler: set number of continuation lines to 200 as default Extended format for cross section summary; appears now in whizard.out Fixed 'bundle' feature 2004-04-28 Fixed compatibility with revised O'Mega SM_ac model Fixed problem with x=0 or x=1 when calling PDFLIB (ThO) Fixed bug in comphep module: Vtb was overlooked ################################################################## 2004-04-15 RELEASE: version 1.28 Fixed bug: Color factor was missing for O'Mega processes with four quarks and more Manual partially updated 2004-04-08 Support for grid files in binary format New default value show_histories=F (reduce output file size) Revised phase space switches: removed annihilation_lines, removed s_channel_resonance, changed meaning of extra_off_shell_lines, added show_deleted_channels Bug fixed which lead to omission of some phase space channels Color flow guessed only if requested by guess_color_flow 2004-03-10 New model interface: Only one model name specified in whizard.prc All model-dependent files reside in conf/models (modellib removed) 2004-03-03 Support for input/output in SUSY Les Houches Accord format Split event files if requested Support for overall time limit Support for CIRCE and CIRCE2 generator mode Support for reading beam events from file 2004-02-05 Fixed compiler problems with Intel Fortran 7.1 and 8.0 Support for catching signals ################################################################## 2003-08-06 RELEASE: version 1.27 User-defined PDF libraries as an alternative to the standard PDFLIB 2003-07-23 Revised phase space module: improved mappings for massless particles, equivalences of phase space channels are exploited Improved mapping for PDF (hadron colliders) Madgraph module: increased max number of color flows from 250 to 1000 ################################################################## 2003-06-23 RELEASE: version 1.26 CIRCE2 support Fixed problem with 'TC' integer kind [Intel compiler complained] 2003-05-28 Support for drawing histograms of grids Bug fixes for MSSM definitions ################################################################## 2003-05-22 RELEASE: version 1.25 Experimental MSSM support with ISAJET interface Improved capabilities of generating/analyzing weighted events Optional drawing phase space diagrams using FeynMF ################################################################## 2003-01-31 RELEASE: version 1.24 A few more fixes and workarounds (Intel and Lahey compiler) 2003-01-15 Fixes and workarounds needed for WHIZARD to run with Intel compiler Command-line option interface for the Lahey compiler Bug fix: problem with reading whizard.phs ################################################################## 2002-12-10 RELEASE: version 1.23 Command-line options (on some systems) Allow for initial particles in the event record, ordered: [beams, initials] - [remnants] - outgoing partons Support for PYTHIA 6.2: Les Houches external process interface String pythia_parameters can be up to 1000 characters long Select color flow states in (internal) analysis Bug fix in color flow content of raw event files Support for transversal polarization of fermion beams Cut codes: PHI now for absolute azimuthal angle, DPHI for distance 'Test' matrix elements optionally respect polarization User-defined code can be inserted for spectra, structure functions and fragmentation Time limits can be specified for adaptation and simulation User-defined file names and file directory Initial weights in input file no longer supported Bug fix in MadGraph (wave function counter could overflow) Bug fix: Gamelan (graphical analysis) was not built if noweb absent ################################################################## 2002-03-16 RELEASE: version 1.22 Allow for beam remnants in the event record 2002-03-01 Handling of aliases in whizard.prc fixed (aliases are whole tokens) 2002-02-28 Optimized phase space handling routines (total execution time reduced by 20-60%, depending on process) ################################################################## 2002-02-26 RELEASE: version 1.21 Fixed ISR formula (ISR was underestimated in previous versions). New version includes ISR in leading-log approximation up to third order. Parameter ISR_sqrts renamed to ISR_scale. ################################################################## 2002-02-19 RELEASE: version 1.20 New process-generating method 'test' (dummy matrix element) Compatibility with autoconf 2.50 and current O'Mega version 2002-02-05 Prevent integration channels from being dropped (optionally) New internal mapping for structure functions improves performance Old whizard.phx file deleted after recompiling (could cause trouble) 2002-01-24 Support for user-defined cuts and matrix element reweighting STDHEP output now written by write_events_format=20 (was 3) 2002-01-16 Improved structure function handling; small changes in user interface: new parameter structured_beams in &process_input parameter fixed_energy in &beam_input removed Support for multiple initial states Eta-phi (cone) cut possible (hadron collider applications) Fixed bug: Whizard library was not always recompiled when necessary Fixed bug: Default cuts were insufficient in some cases Fixed bug: Unusable phase space mappings generated in some cases 2001-12-06 Reorganized document source 2001-12-05 Preliminary CIRCE2 support (no functionality yet) 2001-11-27 Intel compiler support (does not yet work because of compiler bugs) New cut and analysis mode cos-theta* and related Fixed circular jetset_interface dependency warning Some broadcast routines removed (parallel support disabled anyway) Minor shifts in cleanup targets (Makefiles) Modified library search, check for pdflib8* 2001-08-06 Fixed bug: I/O unit number could be undefined when reading phase space Fixed bug: Unitialized variable could cause segfault when event generation was disabled Fixed bug: Undefined subroutine in CIRCE replacement module Enabled feature: TGCs in O'Mega (not yet CompHEP!) matrix elements (CompHEP model sm-GF #5, O'Mega model SM_ac) Fixed portability issue: Makefile did rely on PWD environment variable Fixed portability issue: PYTHIA library search ambiguity resolved 2001-08-01 Default whizard.prc and whizard.in depend on activated modules Fixed bug: TEX=latex was not properly enabled when making plots 2001-07-20 Fixed output settings in PERL script calls Cache enabled in various configure checks 2001-07-13 Support for multiple processes in a single WHIZARD run. The integrations are kept separate, but the generated events are mixed The whizard.evx format has changed (incompatible), including now the color flow information for PYTHIA fragmentation Output files are now process-specific, except for the event file Phase space file whizard.phs (if present) is used only as input, program-generated phase space is now in whizard.phx 2001-07-10 Bug fix: Undefined parameters in parameters_SM_ac.f90 removed 2001-07-04 Bug fix: Compiler options for the case OMEGA is disabled Small inconsistencies in whizard.out format fixed 2001-07-01 Workaround for missing PDFLIB dummy routines in PYTHIA library ################################################################## 2001-06-30 RELEASE: version 1.13 Default path /cern/pro/lib in configure script 2001-06-20 New fragmentation option: Interface for PYTHIA with full color flow information, beam remnants etc. 2001-06-18 Severe bug fixed in madgraph interface: 3-gluon coupling was missing Enabled color flow information in madgraph 2001-06-11 VAMP interface module rewritten Revised output format: Multiple VAMP iterations count as one WHIZARD iteration in integration passes 1 and 3 Improved message and error handling Bug fix in VAMP: handle exceptional cases in rebinning_weights 2001-05-31 new parameters for grid adaptation: accuracy_goal and efficiency_goal ################################################################## 2001-05-29 RELEASE: version 1.12 bug fixes (compilation problems): deleted/modified unused functions 2001-05-16 diagram selection improved and documented 2001-05-06 allow for disabling packages during configuration 2001-05-03 slight changes in whizard.out format; manual extended ################################################################## 2001-04-20 RELEASE: version 1.11 fixed some configuration and compilation problems (PDFLIB etc.) 2001-04-18 linked PDFLIB: support for quark/gluon structure functions 2001-04-05 parameter interface written by PERL script SM_ac model file: fixed error in continuation line 2001-03-13 O'Mega, O'Caml 3.01: incompatible changes O'Mega, src/trie.mli: add covariance annotation to T.t This breaks O'Caml 3.00, but is required for O'Caml 3.01. O'Mega, many instances: replace `sig include Module.T end' by `Module.T', since the bug is fixed in O'Caml 3.01 2001-02-28 O'Mega, src/model.mli: new field Model.vertices required for model functors, will retire Model.fuse2, Model.fuse3, Model.fusen soon. ################################################################## 2001-03-27 RELEASE: version 1.10 reorganized the modules as libraries linked PYTHIA: support for parton fragmentation 2000-12-14 fixed some configuration problems (if noweb etc. are absent) ################################################################## 2000-12-01 RELEASE of first public version: version 1.00beta Index: trunk/omega/src/modellib_PSSSM.ml =================================================================== --- trunk/omega/src/modellib_PSSSM.ml (revision 8413) +++ trunk/omega/src/modellib_PSSSM.ml (revision 8414) @@ -1,1972 +1,1974 @@ (* modellib_PSSSM.ml -- Copyright (C) 1999-2020 by Wolfgang Kilian Thorsten Ohl Juergen Reuter WHIZARD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. WHIZARD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *) (* \thocwmodulesection{Extended Supersymmetric Standard Model(s)} *) (* This is based on the NMSSM implementation by Felix Braam, and extended to the exotica -- leptoquarks, leptoquarkinos, additional Higgses etc. -- by Daniel Wiesler. Note that for the Higgs sector vertices the conventions of the Franke/Fraas paper have been used. *) module type extMSSM_flags = sig val ckm_present : bool end module PSSSM : extMSSM_flags = struct let ckm_present = false end module PSSSM_QCD : extMSSM_flags = struct let ckm_present = false end module ExtMSSM (Flags : extMSSM_flags) = struct open Coupling let default_width = ref Timelike let use_fudged_width = ref false let options = Options.create [ "constant_width", Arg.Unit (fun () -> default_width := Constant), "use constant width (also in t-channel)"; "fudged_width", Arg.Set use_fudged_width, "use fudge factor for charge particle width"; "custom_width", Arg.String (fun f -> default_width := Custom f), "use custom width"; "cancel_widths", Arg.Unit (fun () -> default_width := Vanishing), "use vanishing width"; "cms_width", Arg.Unit (fun () -> default_width := Complex_Mass), - "use complex mass scheme"] + "use complex mass scheme"; + "running_width", Arg.Unit (fun () -> default_width := Running), + "use running width"] (*additional combinatorics *) (* yields a list of tuples consistig of the off-diag combinations of the elements in "set" *) let choose2 set = List.map (function [x;y] -> (x,y) | _ -> failwith "choose2") (Combinatorics.choose 2 set) (* [pairs] *) (* [pairs] appends the diagonal combinations to [choose2] *) let rec diag = function | [] -> [] | x1 :: rest -> (x1, x1) :: diag rest let pairs l = choose2 l @ diag l (* [triples] *) (* rank 3 generalization of [pairs] *) let rec cloop set i j k = if i > ((List.length set)-1) then [] else if j > i then cloop set (succ i) (j-i-1) (j-i-1) else if k > j then cloop set i (succ j) (k-j-1) else (List.nth set i, List.nth set j, List.nth set k) :: cloop set i j (succ k) let triples set = cloop set 0 0 0 (* [two_and_one] *) let rec two_and_one' l1 z n = if n < 0 then [] else ((fst (List.nth (pairs l1) n)),(snd (List.nth (pairs l1) n)), z):: two_and_one' l1 z (pred n) let two_and_one l1 l2 = let f z = two_and_one' l1 z ((List.length (pairs l1))-1) in List.flatten ( List.map f l2 ) type gen = | G of int | GG of gen*gen let rec string_of_gen = function | G n when n > 0 -> string_of_int n | G n -> string_of_int (abs n) ^ "c" | GG (g1,g2) -> string_of_gen g1 ^ "_" ^ string_of_gen g2 (* With this we distinguish the flavour. *) type sff = | SL | SN | SU | SD let string_of_sff = function | SL -> "sl" | SN -> "sn" | SU -> "su" | SD -> "sd" (* With this we distinguish the mass eigenstates. At the moment we have to cheat a little bit for the sneutrinos. Because we are dealing with massless neutrinos there is only one sort of sneutrino. *) type sfm = | M1 | M2 let string_of_sfm = function | M1 -> "1" | M2 -> "2" (* We also introduce special types for the charginos and neutralinos. *) type char = | C1 | C2 | C1c | C2c | C3 | C3c | C4 | C4c type neu = | N1 | N2 | N3 | N4 | N5 | N6 | N7 | N8 | N9 | N10 | N11 let int_of_char = function | C1 -> 1 | C2 -> 2 | C1c -> -1 | C2c -> -2 | C3 -> 3 | C4 -> 4 | C3c -> -3 | C4c -> -4 let string_of_char c = string_of_int (int_of_char c) let conj_char = function | C1 -> C1c | C2 -> C2c | C1c -> C1 | C2c -> C2 | C3 -> C3c | C4 -> C4c | C3c -> C3 | C4c -> C4 let string_of_neu = function | N1 -> "1" | N2 -> "2" | N3 -> "3" | N4 -> "4" | N5 -> "5" | N6 -> "6" | N7 -> "7" | N8 -> "8" | N9 -> "9" | N10 -> "10"| N11 -> "11" (* For NMSSM-like the Higgs bosons, we follow the conventions of Franke/Fraas. Daniel Wiesler: extended to E6 models. *) type shiggs = | S1 | S2 | S3 | S4 | S5 | S6 | S7 | S8 | S9 type phiggs = | P1 | P2 | P3 | P4 | P5 | P6 | P7 (* [HCx] is always the $H^+$, [HCxc] the $H^-$. *) type chiggs = | HC1 | HC2 | HC3 | HC4 | HC5 | HC1c | HC2c | HC3c | HC4c | HC5c let conj_chiggs = function | HC1 -> HC1c | HC2 -> HC2c | HC1c -> HC1 | HC2c -> HC2 | HC3 -> HC3c | HC4 -> HC4c | HC3c -> HC3 | HC4c -> HC4 | HC5 -> HC5c | HC5c -> HC5 let string_of_shiggs = function | S1 -> "1" | S2 -> "2" | S3 -> "3" | S4 -> "4" | S5 -> "5" | S6 -> "6" | S7 -> "7" | S8 -> "8" | S9 -> "9" let string_of_phiggs = function | P1 -> "1" | P2 -> "2" | P3 -> "3" | P4 -> "4" | P5 -> "5" | P6 -> "6" | P7 -> "7" let nlist = [ N1; N2; N3; N4; N5; N6; N7; N8; N9; N10; N11 ] let slist = [ S1; S2; S3; S4; S5; S6; S7; S8; S9 ] let plist = [ P1; P2; P3; P4; P5; P6; P7 ] let clist = [ HC1; HC2; HC3; HC4; HC5; HC1c; HC2c; HC3c; HC4c; HC5c ] let charlist = [ C1; C2; C3; C4; C1c; C2c; C3c; C4c ] type flavor = | L of int | N of int | U of int | D of int | Sup of sfm*int | Sdown of sfm*int | Ga | Wp | Wm | Z | Gl | Slepton of sfm*int | Sneutrino of int | Neutralino of neu | Chargino of char | Gluino | SHiggs of shiggs | PHiggs of phiggs | CHiggs of chiggs | LQ of sfm*int | LQino of int let string_of_fermion_type = function | L _ -> "l" | U _ -> "u" | D _ -> "d" | N _ -> "n" | _ -> failwith "Modellib_PSSSM.ExtMSSM.string_of_fermion_type: invalid fermion type" let string_of_fermion_gen = function | L g | U g | D g | N g -> string_of_int (abs (g)) | _ -> failwith "Modellib_PSSSM.ExtMSSM.string_of_fermion_gen: invalid fermion type" type gauge = unit let gauge_symbol () = failwith "Modellib_PSSSM.ExtMSSM.gauge_symbol: internal error" (* At this point we will forget graviton and -ino. *) let family g = [ L g; N g; Slepton (M1,g); Slepton (M2,g); Sneutrino g; U g; D g; Sup (M1,g); Sup (M2,g); Sdown (M1,g); Sdown (M2,g); LQ (M1,g); LQ (M2,g); LQino g ] let external_flavors () = [ "1st Generation matter", ThoList.flatmap family [1; -1]; "2nd Generation matter", ThoList.flatmap family [2; -2]; "3rd Generation matter", ThoList.flatmap family [3; -3]; "Gauge Bosons", [Ga; Z; Wp; Wm; Gl]; "Charginos", List.map (fun a -> Chargino a) charlist; "Neutralinos", List.map (fun a -> Neutralino a) nlist; "Higgs Bosons", List.map (fun a -> SHiggs a) slist @ List.map (fun a -> PHiggs a) plist @ List.map (fun a -> CHiggs a) clist; "Gluino", [Gluino]] let flavors () = ThoList.flatmap snd (external_flavors ()) let spinor n m = if n >= 0 && m >= 0 then Spinor else if n <= 0 && m <=0 then ConjSpinor else invalid_arg "Modellib_PSSSM.ExtMSSM.spinor: internal error" let lorentz = function | L g -> spinor g 0 | N g -> spinor g 0 | U g -> spinor g 0 | D g -> spinor g 0 | LQino g -> spinor g 0 | Chargino c -> spinor (int_of_char c) 0 | Ga | Gl -> Vector | Wp | Wm | Z -> Massive_Vector | SHiggs _ | PHiggs _ | CHiggs _ | Sup _ | Sdown _ | Slepton _ | Sneutrino _ | LQ _ -> Scalar | Neutralino _ | Gluino -> Majorana let color = function | U g -> Color.SUN (if g > 0 then 3 else -3) | Sup (m,g) -> Color.SUN (if g > 0 then 3 else -3) | D g -> Color.SUN (if g > 0 then 3 else -3) | Sdown (m,g) -> Color.SUN (if g > 0 then 3 else -3) | LQ (m,g) -> Color.SUN (if g > 0 then 3 else -3) | LQino g -> Color.SUN (if g > 0 then 3 else -3) | Gl | Gluino -> Color.AdjSUN 3 | _ -> Color.Singlet let nc () = 3 let prop_spinor n m = if n >= 0 && m >=0 then Prop_Spinor else if n <=0 && m <=0 then Prop_ConjSpinor else invalid_arg "Modellib_PSSSM.ExtMSSM.prop_spinor: internal error" let propagator = function | L g -> prop_spinor g 0 | N g -> prop_spinor g 0 | U g -> prop_spinor g 0 | D g -> prop_spinor g 0 | LQino g -> prop_spinor g 0 | Chargino c -> prop_spinor (int_of_char c) 0 | Ga | Gl -> Prop_Feynman | Wp | Wm | Z -> Prop_Unitarity | SHiggs _ | PHiggs _ | CHiggs _ -> Prop_Scalar | Sup _ | Sdown _ | Slepton _ | Sneutrino _ -> Prop_Scalar | LQ _ -> Prop_Scalar | Gluino -> Prop_Majorana | Neutralino _ -> Prop_Majorana (* Optionally, ask for the fudge factor treatment for the widths of charged particles. Currently, this only applies to $W^\pm$ and top. *) let width f = if !use_fudged_width then match f with | Wp | Wm | U 3 | U (-3) -> Fudged | _ -> !default_width else !default_width let goldstone _ = None let conjugate = function | L g -> L (-g) | N g -> N (-g) | U g -> U (-g) | D g -> D (-g) | Sup (m,g) -> Sup (m,-g) | Sdown (m,g) -> Sdown (m,-g) | Slepton (m,g) -> Slepton (m,-g) | Sneutrino g -> Sneutrino (-g) | Gl -> Gl | Ga -> Ga | Z -> Z | Wp -> Wm | Wm -> Wp | SHiggs s -> SHiggs s | PHiggs p -> PHiggs p | CHiggs c -> CHiggs (conj_chiggs c) | Gluino -> Gluino | Neutralino n -> Neutralino n | Chargino c -> Chargino (conj_char c) | LQino g -> LQino (-g) | LQ (m,g) -> LQ (m,-g) let fermion = function | L g -> if g > 0 then 1 else -1 | N g -> if g > 0 then 1 else -1 | U g -> if g > 0 then 1 else -1 | D g -> if g > 0 then 1 else -1 | Gl | Ga | Z | Wp | Wm -> 0 | SHiggs _ | PHiggs _ | CHiggs _ -> 0 | Neutralino _ -> 2 | Chargino c -> if (int_of_char c) > 0 then 1 else -1 | Sup _ -> 0 | Sdown _ -> 0 | Slepton _ -> 0 | Sneutrino _ -> 0 | Gluino -> 2 | LQ _ -> 0 | LQino g -> if g > 0 then 1 else -1 (* This model does NOT have a conserved generation quantum number. *) module Ch = Charges.QQ let ( // ) = Algebra.Small_Rational.make let charge = function | L n -> if n > 0 then -1//1 else 1//1 | Slepton (_,n) -> if n > 0 then -1//1 else 1//1 | N n -> 0//1 | Sneutrino n -> 0//1 | U n -> if n > 0 then 2//3 else -2//3 | Sup (_,n) -> if n > 0 then 2//3 else -2//3 | D n | LQ (_,n) | LQino n -> if n > 0 then -1//3 else 1//3 | Sdown (_,n) -> if n > 0 then -1//3 else 1//3 | Gl | Ga | Z | Neutralino _ | Gluino -> 0//1 | Wp -> 1//1 | Wm -> -1//1 | SHiggs _ | PHiggs _ -> 0//1 | CHiggs (HC1|HC2|HC3|HC4|HC5) -> 1//1 | CHiggs (HC1c|HC2c|HC3c|HC4c|HC5c) -> -1//1 | Chargino (C1|C2|C3|C4) -> 1//1 | Chargino (C1c|C2c|C3c|C4c) -> -1//1 let lepton = function | L n | N n -> if n > 0 then 1//1 else -1//1 | Slepton (_,n) | Sneutrino n -> if n > 0 then 1//1 else -1//1 | LQ (_,n) | LQino n -> if n > 0 then 1//1 else -1//1 | _ -> 0//1 let baryon = function | U n | D n -> if n > 0 then 1//1 else -1//1 | Sup (_,n) | Sdown (_,n) -> if n > 0 then 1//1 else -1//1 | LQ (_,n) | LQino n -> if n > 0 then 1//1 else -1//1 | _ -> 0//1 let charges f = [ charge f; lepton f; baryon f] (* We introduce a Boolean type vc as a pseudonym for Vertex Conjugator to distinguish between vertices containing complex mixing matrices like the CKM--matrix or the sfermion or neutralino/chargino--mixing matrices, which have to become complex conjugated. The true--option stands for the conjugated vertex, the false--option for the unconjugated vertex. *) type vc = bool type constant = | E | G | Q_lepton | Q_up | Q_down | Q_charg | G_Z | G_CC | G_CCQ of vc*int*int | G_NC_neutrino | G_NC_lepton | G_NC_up | G_NC_down | I_Q_W | I_G_ZWW | G_WWWW | G_ZZWW | G_PZWW | G_PPWW | G_strong | G_SS | I_G_S | Gs | G_NZN of neu*neu | G_CZC of char*char | G_YUK_FFS of flavor*flavor*shiggs | G_YUK_FFP of flavor*flavor*phiggs | G_YUK_LCN of int | G_YUK_UCD of int*int | G_YUK_DCU of int*int | G_NHC of vc*neu*char | G_YUK_C of vc*flavor*char*sff*sfm | G_YUK_Q of vc*int*flavor*char*sff*sfm | G_YUK_N of vc*flavor*neu*sff*sfm | G_YUK_G of vc*flavor*sff*sfm | G_NWC of neu*char | G_CWN of char*neu | G_CSC of char*char*shiggs | G_CPC of char*char*phiggs | G_WSQ of vc*int*int*sfm*sfm | G_SLSNW of vc*int*sfm | G_ZSF of sff*int*sfm*sfm | G_CICIS of neu*neu*shiggs | G_CICIP of neu*neu*phiggs | G_GH_WPC of phiggs | G_GH_WSC of shiggs | G_GH_ZSP of shiggs*phiggs | G_GH_WWS of shiggs | G_GH_ZZS of shiggs | G_GH_ZCC | G_GH_GaCC | G_GH4_ZZPP of phiggs*phiggs | G_GH4_ZZSS of shiggs*shiggs | G_GH4_ZZCC | G_GH4_GaGaCC | G_GH4_ZGaCC | G_GH4_WWCC | G_GH4_WWPP of phiggs*phiggs | G_GH4_WWSS of shiggs*shiggs | G_GH4_ZWSC of shiggs | G_GH4_GaWSC of shiggs | G_GH4_ZWPC of phiggs | G_GH4_GaWPC of phiggs | G_WWSFSF of sff*int*sfm*sfm | G_WPSLSN of vc*int*sfm | G_H3_SCC of shiggs | G_H3_SSS of shiggs*shiggs*shiggs | G_H3_SPP of shiggs*phiggs*phiggs | G_SFSFS of shiggs*sff*int*sfm*sfm | G_SFSFP of phiggs*sff*int*sfm*sfm | G_HSNSL of vc*int*sfm | G_HSUSD of vc*sfm*sfm*int*int | G_WPSUSD of vc*sfm*sfm*int*int | G_WZSUSD of vc*sfm*sfm*int*int | G_WZSLSN of vc*int*sfm | G_GlGlSQSQ | G_PPSFSF of sff | G_ZZSFSF of sff*int*sfm*sfm | G_ZPSFSF of sff*int*sfm*sfm | G_GlZSFSF of sff*int*sfm*sfm | G_GlPSQSQ | G_GlWSUSD of vc*sfm*sfm*int*int | G_YUK_LQ_S of int*shiggs*int | G_YUK_LQ_P of int*phiggs*int | G_LQ_NEU of sfm*int*int*neu | G_LQ_EC_UC of vc*sfm*int*int*int | G_LQ_GG of sfm*int*int | G_LQ_SSU of sfm*sfm*sfm*int*int*int | G_LQ_SSD of sfm*sfm*int*int*int | G_LQ_S of sfm*sfm*int*shiggs*int | G_LQ_P of sfm*sfm*int*phiggs*int | G_ZLQ of int*sfm*sfm | G_ZZLQLQ | G_ZPLQLQ | G_PPLQLQ | G_ZGlLQLQ | G_PGlLQLQ | G_NLQC | G_GlGlLQLQ (* Two integer counters for the QCD and EW order of the couplings. *) type orders = int * int let orders = function | _ -> (0,0) (* \begin{subequations} \begin{align} \alpha_{\text{QED}} &= \frac{1}{137.0359895} \\ \sin^2\theta_w &= 0.23124 \end{align} \end{subequations} Here we must perhaps allow for complex input parameters. So split them into their modulus and their phase. At first, we leave them real; the generalization to complex parameters is obvious. *) let parameters () = { input = []; derived = []; derived_arrays = [] } module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) (* For the couplings there are generally two possibilities concerning the sign of the covariant derivative. \begin{equation} {\rm CD}^\pm = \partial_\mu \pm \ii g T^a A^a_\mu \end{equation} The particle data group defines the signs consistently to be positive. Since the convention for that signs also influence the phase definitions of the gaugino/higgsino fields via the off-diagonal entries in their mass matrices it would be the best to adopt that convention. *) (*** REVISED: Compatible with CD+. FB ***) let electromagnetic_currents_3 g = [ ((L (-g), Ga, L g), FBF (1, Psibar, V, Psi), Q_lepton); ((U (-g), Ga, U g), FBF (1, Psibar, V, Psi), Q_up); ((D (-g), Ga, D g), FBF (1, Psibar, V, Psi), Q_down)] (*** REVISED: Compatible with CD+. FB***) let electromagnetic_sfermion_currents g m = [ ((Ga, Slepton (m,-g), Slepton (m,g)), Vector_Scalar_Scalar 1, Q_lepton); ((Ga, Sup (m,-g), Sup (m,g)), Vector_Scalar_Scalar 1, Q_up); ((Ga, Sdown (m,-g), Sdown (m,g)), Vector_Scalar_Scalar 1, Q_down)] (*** REVISED: Compatible with CD+. FB***) let electromagnetic_currents_2 c = let cc = conj_char c in [ ((Chargino cc, Ga, Chargino c), FBF (1, Psibar, V, Psi), Q_charg) ] (*** REVISED: Compatible with CD+. FB***) let neutral_currents g = [ ((L (-g), Z, L g), FBF (1, Psibar, VA, Psi), G_NC_lepton); ((N (-g), Z, N g), FBF (1, Psibar, VA, Psi), G_NC_neutrino); ((U (-g), Z, U g), FBF (1, Psibar, VA, Psi), G_NC_up); ((D (-g), Z, D g), FBF (1, Psibar, VA, Psi), G_NC_down)] (* \begin{equation} \mathcal{L}_{\textrm{CC}} = \mp \frac{g}{2\sqrt2} \sum_i \bar\psi_i \gamma^\mu (1-\gamma_5)(T^+W^+_\mu+T^-W^-_\mu)\psi_i , \end{equation} where the sign corresponds to $\text{CD}_\pm$, respectively. *) (*** REVISED: Compatible with CD+. ***) (* Remark: The definition with the other sign compared to the SM files comes from the fact that $g_{cc} = 1/(2\sqrt{2})$ is used overwhelmingly often in the SUSY Feynman rules, so that JR decided to use a different definiton for [g_cc] in SM and MSSM. *) (** FB **) let charged_currents g = [ ((L (-g), Wm, N g), FBF ((-1), Psibar, VL, Psi), G_CC); ((N (-g), Wp, L g), FBF ((-1), Psibar, VL, Psi), G_CC) ] (* The quark with the inverted generation (the antiparticle) is the outgoing one, the other the incoming. The vertex attached to the outgoing up-quark contains the CKM matrix element {\em not} complex conjugated, while the vertex with the outgoing down-quark has the conjugated CKM matrix element. *) (*** REVISED: Compatible with CD+. FB ***) let charged_quark_currents g h = [ ((D (-g), Wm, U h), FBF ((-1), Psibar, VL, Psi), G_CCQ (true,g,h)); ((U (-g), Wp, D h), FBF ((-1), Psibar, VL, Psi), G_CCQ (false,h,g))] (*** REVISED: Compatible with CD+.FB ***) let charged_chargino_currents n c = let cc = conj_char c in [ ((Chargino cc, Wp, Neutralino n), FBF (1, Psibar, VLR, Chi), G_CWN (c,n)); ((Neutralino n, Wm, Chargino c), FBF (1, Chibar, VLR, Psi), G_NWC (n,c)) ] (*** REVISED: Compatible with CD+. FB***) let charged_slepton_currents g m = [ ((Wm, Slepton (m,-g), Sneutrino g), Vector_Scalar_Scalar (-1), G_SLSNW (true,g,m)); ((Wp, Slepton (m,g), Sneutrino (-g)), Vector_Scalar_Scalar 1, G_SLSNW (false,g,m)) ] (*** REVISED: Compatible with CD+. FB***) let charged_squark_currents' g h m1 m2 = [ ((Wm, Sup (m1,g), Sdown (m2,-h)), Vector_Scalar_Scalar (-1), G_WSQ (true,g,h,m1,m2)); ((Wp, Sup (m1,-g), Sdown (m2,h)), Vector_Scalar_Scalar 1, G_WSQ (false,g,h,m1,m2)) ] let charged_squark_currents g h = List.flatten (Product.list2 (charged_squark_currents' g h) [M1;M2] [M1;M2] ) (*** REVISED: Compatible with CD+. FB ***) let neutral_sfermion_currents' g m1 m2 = [ ((Z, Slepton (m1,-g), Slepton (m2,g)), Vector_Scalar_Scalar (-1), G_ZSF (SL,g,m1,m2)); ((Z, Sup (m1,-g), Sup (m2,g)), Vector_Scalar_Scalar (-1), G_ZSF (SU,g,m1,m2)); ((Z, Sdown (m1,-g), Sdown (m2,g)), Vector_Scalar_Scalar (-1), G_ZSF (SD,g,m1,m2))] let neutral_sfermion_currents g = List.flatten (Product.list2 (neutral_sfermion_currents' g) [M1;M2] [M1;M2]) @ [ ((Z, Sneutrino (-g), Sneutrino g), Vector_Scalar_Scalar (-1), G_ZSF (SN,g,M1,M1)) ] (* The reality of the coupling of the Z-boson to two identical neutralinos makes the vector part of the coupling vanish. So we distinguish them not by the name but by the structure of the couplings. *) (*** REVISED: Compatible with CD+. FB***) let neutral_Z (n,m) = [ ((Neutralino n, Z, Neutralino m), FBF (1, Chibar, VA, Chi), (G_NZN (n,m))) ] (*** REVISED: Compatible with CD+. FB***) let charged_Z c1 c2 = let cc1 = conj_char c1 in ((Chargino cc1, Z, Chargino c2), FBF ((-1), Psibar, VA , Psi), G_CZC (c1,c2)) (*** REVISED: Compatible with CD+. Remark: This is pure octet. FB***) let yukawa_v = [ (Gluino, Gl, Gluino), FBF (1, Chibar, V, Chi), Gs] (*** REVISED: Independent of the sign of CD. ***) (*** REVISED: Felix Braam: Compact version using new COMBOS + FF-Couplings *) let yukawa_higgs_FFS f s = [((conjugate f, SHiggs s, f ), FBF (1, Psibar, S, Psi), G_YUK_FFS (conjugate f, f, s))] let yukawa_higgs_FFP f p = [((conjugate f, PHiggs p, f), FBF (1, Psibar, P, Psi), G_YUK_FFP (conjugate f ,f , p))] (* JR: Only the first charged Higgs. *) let yukawa_higgs_NLC g = [ ((N (-g), CHiggs HC1, L g), FBF (1, Psibar, Coupling.SR, Psi), G_YUK_LCN g); ((L (-g), CHiggs HC1c, N g), FBF (1, Psibar, Coupling.SL, Psi), G_YUK_LCN g)] let yukawa_higgs g = yukawa_higgs_NLC g @ List.flatten ( Product.list2 yukawa_higgs_FFS [L g; U g; D g] [S1; S2; S3]) @ List.flatten ( Product.list2 yukawa_higgs_FFP [L g; U g; D g] [P1; P2]) (* JR: Only the first charged Higgs. *) (*** REVISED: Independent of the sign of CD. FB***) let yukawa_higgs_quark (g,h) = [ ((U (-g), CHiggs HC1, D h), FBF (1, Psibar, SLR, Psi), G_YUK_UCD (g, h)); ((D (-h), CHiggs HC1c, U g), FBF (1, Psibar, SLR, Psi), G_YUK_DCU (g, h)) ] (*** REVISED: Compatible with CD+.FB*) (*** REVISED: Compact version using new COMBOS*) let yukawa_shiggs_2 c1 c2 s = let cc1 = conj_char c1 in ((Chargino cc1, SHiggs s, Chargino c2), FBF (1, Psibar, SLR, Psi), G_CSC (c1,c2,s)) let yukawa_phiggs_2 c1 c2 p = let cc1 = conj_char c1 in ((Chargino cc1, PHiggs p, Chargino c2), FBF (1, Psibar, SLR, Psi), G_CPC (c1,c2,p)) let yukawa_higgs_2 = Product.list3 yukawa_shiggs_2 [C1;C2] [C1;C2] [S1;S2;S3] @ Product.list3 yukawa_phiggs_2 [C1;C2] [C1;C2] [P1;P2] (* JR: Only the first charged Higgs. *) (*** REVISED: Compatible with CD+.FB ***) let higgs_charg_neutr n c = let cc = conj_char c in [ ((Neutralino n, CHiggs HC1c, Chargino c), FBF (-1, Chibar, SLR, Psi), G_NHC (false,n,c)); ((Chargino cc, CHiggs HC1, Neutralino n), FBF (-1, Psibar, SLR, Chi), G_NHC (true,n,c)) ] (*** REVISED: Compatible with CD+. FB***) (*** REVISED: Compact version using new COMBOS*) let shiggs_neutr (n,m,s) = ((Neutralino n, SHiggs s, Neutralino m), FBF (1, Chibar, SP, Chi), G_CICIS (n,m,s)) let phiggs_neutr (n,m,p) = ((Neutralino n, PHiggs p, Neutralino m), FBF (1, Chibar, SP, Chi), G_CICIP (n,m,p)) let higgs_neutr = List.map shiggs_neutr (two_and_one [N1;N2;N3;N4;N5] [S1;S2;S3]) @ List.map phiggs_neutr (two_and_one [N1;N2;N3;N4;N5] [P1;P2]) (*** REVISED: Compatible with CD+. FB***) let yukawa_n_2 n m g = [ ((Neutralino n, Slepton (m,-g), L g), FBF (1, Chibar, SLR, Psi), G_YUK_N (true,L g,n,SL,m)); ((L (-g), Slepton (m,g), Neutralino n), FBF (1, Psibar, SLR, Chi), G_YUK_N (false,L g,n,SL,m)); ((Neutralino n, Sup (m,-g), U g), FBF (1, Chibar, SLR, Psi), G_YUK_N (true,U g,n,SU,m)); ((U (-g), Sup (m,g), Neutralino n), FBF (1, Psibar, SLR, Chi), G_YUK_N (false,U g,n,SU,m)); ((Neutralino n, Sdown (m,-g), D g), FBF (1, Chibar, SLR, Psi), G_YUK_N (true,D g,n,SD,m)); ((D (-g), Sdown (m,g), Neutralino n), FBF (1, Psibar, SLR, Chi), G_YUK_N (false,D g,n,SD,m)) ] let yukawa_n_3 n g = [ ((Neutralino n, Sneutrino (-g), N g), FBF (1, Chibar, SLR, Psi), G_YUK_N (true,N g,n,SN,M1)); ((N (-g), Sneutrino g, Neutralino n), FBF (1, Psibar, SLR, Chi), G_YUK_N (false,N g, n,SN,M1)) ] let yukawa_n_5 g m = [ ((U (-g), Sup (m,g), Gluino), FBF (1, Psibar, SLR, Chi), G_YUK_G (false,U g,SU,m)); ((D (-g), Sdown (m,g), Gluino), FBF (1, Psibar, SLR, Chi), G_YUK_G (false,D g,SD,m)); ((Gluino, Sup (m,-g), U g), FBF (1, Chibar, SLR, Psi), G_YUK_G (true,U g,SU,m)); ((Gluino, Sdown (m,-g), D g), FBF (1, Chibar, SLR, Psi), G_YUK_G (true,D g,SD,m))] let yukawa_n = List.flatten (Product.list3 yukawa_n_2 [N1;N2;N3;N4;N5] [M1;M2] [1;2;3]) @ List.flatten (Product.list2 yukawa_n_3 [N1;N2;N3;N4;N5] [1;2;3]) @ List.flatten (Product.list2 yukawa_n_5 [1;2;3] [M1;M2]) (*** REVISED: Compatible with CD+.FB ***) let yukawa_c_2 c g = let cc = conj_char c in [ ((L (-g), Sneutrino g, Chargino cc), BBB (1, Psibar, SLR, Psibar), G_YUK_C (true,L g,c,SN,M1)); ((Chargino c, Sneutrino (-g), L g), PBP (1, Psi, SLR, Psi), G_YUK_C (false,L g,c,SN,M1)) ] let yukawa_c_3 c m g = let cc = conj_char c in [ ((N (-g), Slepton (m,g), Chargino c), FBF (1, Psibar, SLR, Psi), G_YUK_C (true,N g,c,SL,m)); ((Chargino cc, Slepton (m,-g), N g), FBF (1, Psibar, SLR, Psi), G_YUK_C (false,N g,c,SL,m)) ] let yukawa_c c = ThoList.flatmap (yukawa_c_2 c) [1;2;3] @ List.flatten (Product.list2 (yukawa_c_3 c) [M1;M2] [1;2;3]) (*** REVISED: Compatible with CD+. FB***) let yukawa_cq' c (g,h) m = let cc = conj_char c in [ ((Chargino c, Sup (m,-g), D h), PBP (1, Psi, SLR, Psi), G_YUK_Q (false,g,D h,c,SU,m)); ((D (-h), Sup (m,g), Chargino cc), BBB (1, Psibar, SLR, Psibar), G_YUK_Q (true,g,D h,c,SU,m)); ((Chargino cc, Sdown (m,-g), U h), FBF (1, Psibar, SLR, Psi), G_YUK_Q (true,g,U h,c,SD,m)); ((U (-h), Sdown (m,g), Chargino c), FBF (1, Psibar, SLR, Psi), G_YUK_Q (false,g,U h,c,SD,m)) ] let yukawa_cq c = if Flags.ckm_present then List.flatten (Product.list2 (yukawa_cq' c) [(1,1);(1,2);(2,1);(2,2);(1,3);(2,3);(3,3);(3,2);(3,1)] [M1;M2]) else List.flatten (Product.list2 (yukawa_cq' c) [(1,1);(2,2);(3,3)] [M1;M2]) (*** REVISED: Compatible with CD+. Remark: Singlet and octet gluon exchange. The coupling is divided by sqrt(2) to account for the correct normalization of the Lie algebra generators. **FB*) let col_currents g = [ ((D (-g), Gl, D g), FBF ((-1), Psibar, V, Psi), Gs); ((U (-g), Gl, U g), FBF ((-1), Psibar, V, Psi), Gs)] (*** REVISED: Compatible with CD+. Remark: Singlet and octet gluon exchange. The coupling is divided by sqrt(2) to account for the correct normalization of the Lie algebra generators. **FB*) (** LQ-coupl. **DW**) let chg = function | M1 -> M2 | M2 -> M1 (** LQ - Yuk's **) let yuk_lqino_se_uc1' g1 g2 g3 m = let cm = chg m in [ ((U (-g3), Slepton (m,-g2), LQino g1), FBF (1, Psibar, SLR, Psi), G_LQ_EC_UC (true,cm,g1,g2,g3)) ] let yuk_lqino_se_uc1 g1 g2 g3 = ThoList.flatmap (yuk_lqino_se_uc1' g1 g2 g3) [M1;M2] let yuk_lqino_se_uc2' g1 g2 g3 m = let cm = chg m in [ ((LQino (-g1), Slepton (m,g2), U g3), FBF (1, Psibar, SLR, Psi), G_LQ_EC_UC (false,cm,g1,g2,g3)) ] let yuk_lqino_se_uc2 g1 g2 g3 = ThoList.flatmap (yuk_lqino_se_uc2' g1 g2 g3) [M1;M2] let yuk_lqino_sn_dc1 g1 g2 g3 = [ ((D (-g3), Sneutrino (-g2), LQino g1), FBF (-1, Psibar, SLR, Psi), G_LQ_EC_UC (true,M2,g1,g2,g3)) ] let yuk_lqino_sn_dc2 g1 g2 g3 = [ ((LQino (-g1), Sneutrino g2, D g3), FBF (-1, Psibar, SLR, Psi), G_LQ_EC_UC (false,M2,g1,g2,g3)) ] let yuk_lqino_ec_su1' g1 g2 g3 m = let cm = chg m in [ ((LQino (-g1), Sup (m,g3), L g2), FBF (1, Psibar, SLR, Psi), G_LQ_EC_UC (true,cm,g1,g2,g3)) ] let yuk_lqino_ec_su1 g1 g2 g3 = ThoList.flatmap (yuk_lqino_ec_su1' g1 g2 g3) [M1;M2] let yuk_lqino_ec_su2' g1 g2 g3 m = let cm = chg m in [ ((L (-g2), Sup (m,-g3), LQino (g1)), FBF (1, Psibar, SLR, Psi), G_LQ_EC_UC (false,cm,g1,g2,g3)) ] let yuk_lqino_ec_su2 g1 g2 g3 = ThoList.flatmap (yuk_lqino_ec_su2' g1 g2 g3) [M1;M2] let yuk_lqino_nc_sd1 g1 g2 g3 = [ ((LQino (-g1), Sdown (M1,g3), N g2), FBF (-1, Psibar, SLR, Psi), G_LQ_EC_UC (true,M2,g1,g2,g3)) ] let yuk_lqino_nc_sd2 g1 g2 g3 = [ ((N (-g2), Sdown (M1,-g3), LQino (g1)), FBF (-1, Psibar, SLR, Psi), G_LQ_EC_UC (false,M2,g1,g2,g3)) ] let yuk_lq_ec_uc' g1 g2 g3 m = [ ((L (-g2), LQ (m,g1), U (-g3)), BBB (1, Psibar, SLR, Psibar), G_LQ_EC_UC (false,m,g1,g2,g3)) ] let yuk_lq_ec_uc g1 g2 g3 = ThoList.flatmap (yuk_lq_ec_uc' g1 g2 g3) [M1;M2] let yuk_lq_ec_uc2' g1 g2 g3 m = [ ((L (g2), LQ (m,-g1), U (g3)), PBP (1, Psi, SLR, Psi), G_LQ_EC_UC (true,m,g1,g2,g3)) ] let yuk_lq_ec_uc2 g1 g2 g3 = ThoList.flatmap (yuk_lq_ec_uc2' g1 g2 g3) [M1;M2] let yuk_lq_nc_dc g1 g2 g3 = [ ((N (-g2), LQ (M2,g1), D (-g3)), BBB (-1, Psibar, SLR, Psibar), G_LQ_EC_UC (false,M2,g1,g2,g3)) ] let yuk_lq_nc_dc2 g1 g2 g3 = [ ((N (g2), LQ (M2,-g1), D (g3)), PBP (-1, Psi, SLR, Psi), G_LQ_EC_UC (true,M2,g1,g2,g3)) ] (*** Daniel Wiesler: LQ - F-Term w/ vev ***) let lq_se_su' g1 g2 g3 m1 m2 m3 = [ ((LQ (m1,g1), Slepton (m2,-g2), Sup (m3,-g3)), Scalar_Scalar_Scalar 1, G_LQ_SSU (m1,m2,m3,g1,g2,g3)) ] let lq_se_su g1 g2 g3 = List.flatten (Product.list3 (lq_se_su' g1 g2 g3) [M1;M2] [M1;M2] [M1;M2] ) let lq_snu_sd' g1 g2 g3 m1 m2 = [ ((LQ (m1,g1), Sdown (m2,-g2), Sneutrino (-g3)), Scalar_Scalar_Scalar 1, G_LQ_SSD (m1,m2,g1,g2,g3)) ] let lq_snu_sd g1 g2 g3 = List.flatten (Product.list2 (lq_snu_sd' g1 g2 g3) [M1;M2] [M1;M2] ) (*** Daniel Wiesler: LQ - Higgs ***) let lq_shiggs' g1 s g2 m1 m2 = [ ((LQ (m1,g1), SHiggs s, LQ (m2,-g2)), Scalar_Scalar_Scalar 1, G_LQ_S (m1,m2,g1,s,g2))] let lq_shiggs g1 s g2 = List.flatten ( Product.list2 (lq_shiggs' g1 s g2) [M1;M2] [M1;M2]) let lq_phiggs' g1 p g2 m1 m2 = [ ((LQ (m1,g1), PHiggs p, LQ (m2,-g2)), Scalar_Scalar_Scalar 1, G_LQ_P (m1,m2,g1,p,g2))] let lq_phiggs g1 p g2 = List.flatten ( Product.list2 (lq_phiggs' g1 p g2) [M1;M2] [M1;M2]) let yuk_lqino_shiggs g1 s g2 = [ ((LQino (-g1), SHiggs s, LQino g2), FBF (1, Psibar, SLR, Psi), G_YUK_LQ_S (g1,s,g2)) ] let yuk_lqino_phiggs g1 p g2 = [ ((LQino (-g1), PHiggs p, LQino g2), FBF (1, Psibar, SLR, Psi), G_YUK_LQ_P (g1,p,g2)) ] (*** Daniel Wiesler: LQ - Neutralinos. ***) let lqino_lq_neu' n g1 g2 m = [ ((Neutralino n, LQ (m,-g1), LQino g2), FBF (1, Chibar, SLR, Psi), G_LQ_NEU (m,g1,g2,n)) ] let lqino_lq_neu n g1 g2 = ThoList.flatmap (lqino_lq_neu' n g1 g2) [M1;M2] let lqino_lq_neu2' n g1 g2 m = [ ((LQino (-g2), LQ (m,g1), Neutralino n), FBF (1, Psibar, SLR, Chi), G_LQ_NEU (m,g1,g2,n)) ] let lqino_lq_neu2 n g1 g2 = ThoList.flatmap (lqino_lq_neu2' n g1 g2) [M1;M2] (*** Daniel Wiesler: LQ-LQino-Gluino ***) let lqino_lq_gg' g1 g2 m = [ ((Gluino, LQ (m,-g1), LQino g2), FBF (1, Chibar, SLR, Psi), G_LQ_GG (m,g1,g2)) ] let lqino_lq_gg g1 g2 = ThoList.flatmap (lqino_lq_gg' g1 g2) [M1;M2] (*** Daniel Wiesler: LQ - Gauge ***) let col_lqino_currents g = [ ((LQino (-g), Gl, LQino g), FBF ((-1), Psibar, V, Psi), Gs)] let neutr_lqino_current g = [ ((LQino (-g), Z, LQino g), FBF (1, Psibar, V, Psi), G_NLQC)] let col_lq_currents m g = [ ((Gl, LQ (m,-g), LQ (m,g)), Vector_Scalar_Scalar (-1), Gs)] let lq_neutr_Z g m1 m2 = [ ((Z, LQ (m1,-g), LQ (m2,g)), Vector_Scalar_Scalar (-1), G_ZLQ (g,m1,m2))] let em_lq_currents g m = [ ((Ga, LQ (m,-g), LQ (m,g)), Vector_Scalar_Scalar 1, Q_down)] let em_lqino_currents g = [ ((LQino (-g), Ga, LQino g), FBF (1, Psibar, V, Psi), Q_down)] let gluon2_lq2' g m = [ ((LQ (m,g), LQ (m,-g), Gl, Gl), Scalar2_Vector2 2, G_GlGlLQLQ)] let gluon2_lq2 g = ThoList.flatmap (gluon2_lq2' g) [M1;M2] let lq_gauge4' g m = [ ((Z, Z, LQ (m,g), LQ (m,-g)), Scalar2_Vector2 1, G_ZZLQLQ); ((Z, Ga, LQ (m,g), LQ (m,-g)), Scalar2_Vector2 1, G_ZPLQLQ); ((Ga, Ga, LQ (m,g), LQ (m,-g)), Scalar2_Vector2 1, G_PPLQLQ)] let lq_gauge4 g = ThoList.flatmap (lq_gauge4' g) [M1;M2] let lq_gg_gauge2' g m = [ ((Z, Gl, LQ (m,g), LQ (m,-g)), Scalar2_Vector2 1, G_ZGlLQLQ); ((Ga, Gl, LQ (m,g), LQ (m,-g)), Scalar2_Vector2 1, G_PGlLQLQ)] let lq_gg_gauge2 g = ThoList.flatmap (lq_gg_gauge2' g) [M1;M2] let col_sfermion_currents g m = [ ((Gl, Sup (m,-g), Sup (m,g)), Vector_Scalar_Scalar (-1), Gs); ((Gl, Sdown (m,-g), Sdown (m,g)), Vector_Scalar_Scalar (-1), Gs)] (*** REVISED: Compatible with CD+. **FB*) let triple_gauge = [ ((Ga, Wm, Wp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW); ((Gl, Gl, Gl), Gauge_Gauge_Gauge 1, I_G_S)] (*** REVISED: Independent of the sign of CD. **FB*) let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] let quartic_gauge = [ (Wm, Wp, Wm, Wp), gauge4, G_WWWW; (Wm, Z, Wp, Z), minus_gauge4, G_ZZWW; (Wm, Z, Wp, Ga), minus_gauge4, G_PZWW; (Wm, Ga, Wp, Ga), minus_gauge4, G_PPWW; (Gl, Gl, Gl, Gl), gauge4, G_SS] (* The [Scalar_Vector_Vector] couplings do not depend on the choice of the sign of the covariant derivative since they are quadratic in the gauge couplings. *) (* JR: Only the first charged Higgs. *) (*** REVISED: Compatible with CD+. ***) (*** Revision: 2005-03-10: first two vertices corrected. ***) (*** REVISED: Felix Braam: Compact version using new COMBOS*) (*** REVISED: Felix Braam: Couplings adjusted to FF-convention*) let gauge_higgs_WPC p= [ ((Wm, CHiggs HC1, PHiggs p), Vector_Scalar_Scalar 1, G_GH_WPC p); ((Wp, CHiggs HC1c, PHiggs p), Vector_Scalar_Scalar 1, G_GH_WPC p)] let gauge_higgs_WSC s= [((Wm, CHiggs HC1, SHiggs s),Vector_Scalar_Scalar 1, G_GH_WSC s); ((Wp, CHiggs HC1c, SHiggs s),Vector_Scalar_Scalar (-1), G_GH_WSC s)] let gauge_higgs_ZSP s p = [((Z, SHiggs s, PHiggs p),Vector_Scalar_Scalar 1, G_GH_ZSP (s,p))] let gauge_higgs_WWS s= ((SHiggs s, Wp, Wm),Scalar_Vector_Vector 1, G_GH_WWS s) let gauge_higgs_ZZS s= ((SHiggs s, Z, Z), Scalar_Vector_Vector 1, G_GH_ZZS s) let gauge_higgs_ZCC = ((Z, CHiggs HC1, CHiggs HC1c),Vector_Scalar_Scalar 1, G_GH_ZCC ) let gauge_higgs_GaCC = ((Ga, CHiggs HC1, CHiggs HC1c),Vector_Scalar_Scalar 1, G_GH_GaCC ) let gauge_higgs = ThoList.flatmap gauge_higgs_WPC [P1;P2] @ ThoList.flatmap gauge_higgs_WSC [S1;S2;S3] @ List.flatten (Product.list2 gauge_higgs_ZSP [S1;S2;S3] [P1;P2]) @ List.map gauge_higgs_WWS [S1;S2;S3] @ List.map gauge_higgs_ZZS [S1;S2;S3] @ [gauge_higgs_ZCC] @ [gauge_higgs_GaCC] (*** REVISED: Compact version using new COMBOS*) (*** REVISED: Couplings adjusted to FF-convention*) let gauge_higgs4_ZZPP (p1,p2) = ((PHiggs p1, PHiggs p2, Z, Z), Scalar2_Vector2 1, G_GH4_ZZPP (p1,p2)) let gauge_higgs4_ZZSS (s1,s2) = ((SHiggs s1, SHiggs s2 , Z, Z), Scalar2_Vector2 1, G_GH4_ZZSS (s1,s2)) (* JR: Only the first charged Higgs. *) let gauge_higgs4_ZZCC = ((CHiggs HC1, CHiggs HC1c, Z, Z), Scalar2_Vector2 1, G_GH4_ZZCC) let gauge_higgs4_GaGaCC = ((CHiggs HC1, CHiggs HC1c, Ga, Ga), Scalar2_Vector2 1, G_GH4_GaGaCC) let gauge_higgs4_ZGaCC = ((CHiggs HC1, CHiggs HC1c, Ga, Z), Scalar2_Vector2 1, G_GH4_ZGaCC ) let gauge_higgs4_WWCC = ((CHiggs HC1, CHiggs HC1c, Wp, Wm), Scalar2_Vector2 1, G_GH4_WWCC ) let gauge_higgs4_WWPP (p1,p2) = ((PHiggs p1, PHiggs p2, Wp, Wm), Scalar2_Vector2 1, G_GH4_WWPP (p1,p2)) let gauge_higgs4_WWSS (s1,s2) = ((SHiggs s1, SHiggs s2, Wp, Wm), Scalar2_Vector2 1, G_GH4_WWSS (s1,s2)) (* JR: Only the first charged Higgs. *) let gauge_higgs4_ZWSC s = [ ((CHiggs HC1, SHiggs s, Wm, Z), Scalar2_Vector2 1, G_GH4_ZWSC s); ((CHiggs HC1c, SHiggs s, Wp, Z), Scalar2_Vector2 1, G_GH4_ZWSC s)] let gauge_higgs4_GaWSC s = [ ((CHiggs HC1, SHiggs s, Wm, Ga), Scalar2_Vector2 1, G_GH4_GaWSC s); ((CHiggs HC1c, SHiggs s, Wp, Ga), Scalar2_Vector2 1, G_GH4_GaWSC s) ] let gauge_higgs4_ZWPC p = [ ((CHiggs HC1, PHiggs p, Wm, Z), Scalar2_Vector2 1, G_GH4_ZWPC p); ((CHiggs HC1c, PHiggs p, Wp, Z), Scalar2_Vector2 (-1), G_GH4_ZWPC p)] let gauge_higgs4_GaWPC p = [ ((CHiggs HC1, PHiggs p, Wm, Ga), Scalar2_Vector2 1, G_GH4_GaWPC p); ((CHiggs HC1c, PHiggs p, Wp, Ga), Scalar2_Vector2 (-1), G_GH4_GaWPC p) ] let gauge_higgs4 = List.map gauge_higgs4_ZZPP (pairs [P1;P2]) @ List.map gauge_higgs4_ZZSS (pairs [S1;S2;S3]) @ [gauge_higgs4_ZZCC] @ [gauge_higgs4_GaGaCC] @ [gauge_higgs4_ZGaCC] @ [gauge_higgs4_WWCC] @ List.map gauge_higgs4_WWPP (pairs [P1;P2]) @ List.map gauge_higgs4_WWSS (pairs [S1;S2;S3]) @ ThoList.flatmap gauge_higgs4_ZWSC [S1;S2;S3] @ ThoList.flatmap gauge_higgs4_GaWSC [S1;S2;S3] @ ThoList.flatmap gauge_higgs4_ZWPC [P1;P2] @ ThoList.flatmap gauge_higgs4_GaWPC [P1;P2] (*** Added by Felix Braam. ***) let gauge_sfermion4' g m1 m2 = [ ((Wp, Wm, Slepton (m1,g), Slepton (m2,-g)), Scalar2_Vector2 1, G_WWSFSF (SL,g,m1,m2)); ((Z, Ga, Slepton (m1,g), Slepton (m2,-g)), Scalar2_Vector2 1, G_ZPSFSF (SL,g,m1,m2)); ((Z, Z, Slepton (m1,g), Slepton (m2,-g)), Scalar2_Vector2 1, G_ZZSFSF (SL,g,m1,m2)); ((Wp, Wm, Sup (m1,g), Sup (m2,-g)), Scalar2_Vector2 1, G_WWSFSF (SU,g,m1,m2)); ((Wp, Wm, Sdown (m1,g), Sdown (m2,-g)), Scalar2_Vector2 1, G_WWSFSF (SD,g,m1,m2)); ((Z, Z, Sup (m1,g), Sup (m2,-g)), Scalar2_Vector2 1, G_ZZSFSF (SU,g,m1,m2)); ((Z, Z, Sdown (m1,g), Sdown (m2,-g)), Scalar2_Vector2 1, G_ZZSFSF (SD,g,m1,m2)); ((Z, Ga, Sup (m1,g), Sup (m2,-g)), Scalar2_Vector2 1, G_ZPSFSF (SU,g,m1,m2)); ((Z, Ga, Sdown (m1,g), Sdown (m2,-g)), Scalar2_Vector2 1, G_ZPSFSF (SD,g,m1,m2)) ] let gauge_sfermion4'' g m = [ ((Wp, Ga, Slepton (m,g), Sneutrino (-g)), Scalar2_Vector2 1, G_WPSLSN (false,g,m)); ((Wm, Ga, Slepton (m,-g), Sneutrino g), Scalar2_Vector2 1, G_WPSLSN (true,g,m)); ((Wp, Z, Slepton (m,g), Sneutrino (-g)), Scalar2_Vector2 1, G_WZSLSN (false,g,m)); ((Wm, Z, Slepton (m,-g), Sneutrino g), Scalar2_Vector2 1, G_WZSLSN (true,g,m)); ((Ga, Ga, Slepton (m,g), Slepton (m,-g)), Scalar2_Vector2 1, G_PPSFSF SL); ((Ga, Ga, Sup (m,g), Sup (m,-g)), Scalar2_Vector2 1, G_PPSFSF SU); ((Ga, Ga, Sdown (m,g), Sdown (m,-g)), Scalar2_Vector2 1, G_PPSFSF SD)] let gauge_sfermion4 g = List.flatten (Product.list2 (gauge_sfermion4' g) [M1;M2] [M1;M2]) @ ThoList.flatmap (gauge_sfermion4'' g) [M1;M2] @ [ ((Wp, Wm, Sneutrino g, Sneutrino (-g)), Scalar2_Vector2 1, G_WWSFSF (SN,g,M1,M1)); ((Z, Z, Sneutrino g, Sneutrino (-g)), Scalar2_Vector2 1, G_ZZSFSF (SN,g,M1,M1)) ] (*** Modified by Felix Braam. ***) let gauge_squark4'' g h m1 m2 = [ ((Wp, Ga, Sup (m1,-g), Sdown (m2,h)), Scalar2_Vector2 1, G_WPSUSD (false,m1,m2,g,h)); ((Wm, Ga, Sup (m1,g), Sdown (m2,-h)), Scalar2_Vector2 1, G_WPSUSD (true,m1,m2,g,h)); ((Wp, Z, Sup (m1,-g), Sdown (m2,h)), Scalar2_Vector2 1, G_WZSUSD (false,m1,m2,g,h)); ((Wm, Z, Sup (m1,g), Sdown (m2,-h)), Scalar2_Vector2 1, G_WZSUSD (true,m1,m2,g,h)) ] let gauge_squark4' g h = List.flatten (Product.list2 (gauge_squark4'' g h) [M1;M2] [M1;M2]) let gauge_squark4 = if Flags.ckm_present then List.flatten (Product.list2 gauge_squark4' [1;2;3] [1;2;3]) else ThoList.flatmap (fun g -> gauge_squark4' g g) [1;2;3] let gluon_w_squark'' g h m1 m2 = [ ((Gl, Wp, Sup (m1,-g), Sdown (m2,h)), Scalar2_Vector2 1, G_GlWSUSD (false,m1,m2,g,h)); ((Gl, Wm, Sup (m1,g), Sdown (m2,-h)), Scalar2_Vector2 1, G_GlWSUSD (true,m1,m2,g,h)) ] let gluon_w_squark' g h = List.flatten (Product.list2 (gluon_w_squark'' g h) [M1;M2] [M1;M2]) let gluon_w_squark = if Flags.ckm_present then List.flatten (Product.list2 gluon_w_squark' [1;2;3] [1;2;3]) else ThoList.flatmap (fun g -> gluon_w_squark' g g) [1;2;3] (*** Modified by Felix Braam. ***) let gluon_gauge_squark' g m1 m2 = [ ((Gl, Z, Sup (m1,g), Sup (m2,-g)), Scalar2_Vector2 2, G_GlZSFSF (SU,g,m1,m2)); ((Gl, Z, Sdown (m1,g), Sdown (m2,-g)), Scalar2_Vector2 2, G_GlZSFSF (SD,g,m1,m2)) ] let gluon_gauge_squark'' g m = [ ((Gl, Ga, Sup (m,g), Sup (m,-g)), Scalar2_Vector2 2, G_GlPSQSQ); ((Gl, Ga, Sdown (m,g), Sdown (m,-g)), Scalar2_Vector2 (-1), G_GlPSQSQ) ] (*** Modified by Felix Braam. ***) let gluon_gauge_squark g = List.flatten (Product.list2 (gluon_gauge_squark' g) [M1;M2] [M1;M2]) @ ThoList.flatmap (gluon_gauge_squark'' g) [M1;M2] let gluon2_squark2' g m = [ ((Gl, Gl, Sup (m,g), Sup (m,-g)), Scalar2_Vector2 2, G_GlGlSQSQ); ((Gl, Gl, Sdown (m,g), Sdown (m,-g)), Scalar2_Vector2 2, G_GlGlSQSQ) ] let gluon2_squark2 g = ThoList.flatmap (gluon2_squark2' g) [M1;M2] (* JR: Only the first charged Higgs. *) (*** REVISED: Independent of the sign of CD. ***) (*** REVISED: Felix Braam: Compact version using new COMBOS *) (*** REVISED: Felix Braam: Couplings adjusted to FF-convention *) let higgs_SCC s = ((CHiggs HC1, CHiggs HC1c, SHiggs s), Scalar_Scalar_Scalar 1, G_H3_SCC s ) let higgs_SSS (s1,s2,s3)= ((SHiggs s1, SHiggs s2, SHiggs s3), Scalar_Scalar_Scalar 1, G_H3_SSS (s1,s2,s3)) let higgs_SPP (p1,p2,s) = ((SHiggs s, PHiggs p1, PHiggs p2), Scalar_Scalar_Scalar 1, G_H3_SPP (s,p1,p2)) let higgs = List.map higgs_SCC [S1;S2;S3]@ List.map higgs_SSS (triples [S1;S2;S3])@ List.map higgs_SPP (two_and_one [P1;P2] [S1;S2;S3]) let higgs4 = [] (* The vertices of the type Higgs - Sfermion - Sfermion are independent of the choice of the CD sign since they are quadratic in the gauge coupling. *) (* JR: Only the first charged Higgs. *) (*** REVISED: Independent of the sign of CD. ***) let higgs_sneutrino' s g = ((SHiggs s, Sneutrino g, Sneutrino (-g)), Scalar_Scalar_Scalar 1, G_SFSFS (s,SN,g,M1,M1)) let higgs_sneutrino'' g m = [((CHiggs HC1, Sneutrino (-g), Slepton (m,g)), Scalar_Scalar_Scalar 1, G_HSNSL (false,g,m)); ((CHiggs HC1c, Sneutrino g, Slepton (m,-g)), Scalar_Scalar_Scalar 1, G_HSNSL (true,g,m))] let higgs_sneutrino = Product.list2 higgs_sneutrino' [S1;S2;S3] [1;2;3] @ List.flatten ( Product.list2 higgs_sneutrino'' [1;2;3] [M1;M2] ) (* Under the assumption that there is no mixing between the left- and right-handed sfermions for the first two generations there is only a coupling of the form Higgs - sfermion1 - sfermion2 for the third generation. All the others are suppressed by $m_f/M_W$. *) (*** REVISED: Independent of the sign of CD. ***) let higgs_sfermion_S s g m1 m2 = [ ((SHiggs s, Slepton (m1,g), Slepton (m2,-g)), Scalar_Scalar_Scalar 1, G_SFSFS (s,SL,g,m1,m2)); ((SHiggs s, Sup (m1,g), Sup (m2,-g)), Scalar_Scalar_Scalar 1, G_SFSFS (s,SU,g,m1,m2)); ((SHiggs s, Sdown (m1,g), Sdown (m2,-g)), Scalar_Scalar_Scalar 1, G_SFSFS (s,SD,g,m1,m2))] let higgs_sfermion' g m1 m2 = (higgs_sfermion_S S1 g m1 m2) @ (higgs_sfermion_S S2 g m1 m2) @ (higgs_sfermion_S S3 g m1 m2) let higgs_sfermion_P p g m1 m2 = [ ((PHiggs p, Slepton (m1,g), Slepton (m2,-g)), Scalar_Scalar_Scalar 1, G_SFSFP (p,SL,g,m1,m2)); ((PHiggs p, Sup (m1,g), Sup (m2,-g)), Scalar_Scalar_Scalar 1, G_SFSFP (p,SU,g,m1,m2)); ((PHiggs p, Sdown (m1,g), Sdown (m2,-g)), Scalar_Scalar_Scalar 1, G_SFSFP (p,SD,g,m1,m2)) ] let higgs_sfermion'' g m1 m2 = (higgs_sfermion_P P1 g m1 m2) @ (higgs_sfermion_P P2 g m1 m2) let higgs_sfermion = List.flatten (Product.list3 higgs_sfermion' [1;2;3] [M1;M2] [M1;M2]) @ List.flatten (Product.list3 higgs_sfermion'' [1;2;3] [M1;M2] [M1;M2]) (* JR: Only the first charged Higgs. *) (*** REVISED: Independent of the sign of CD. ***) let higgs_squark' g h m1 m2 = [ ((CHiggs HC1, Sup (m1,-g), Sdown (m2,h)), Scalar_Scalar_Scalar 1, G_HSUSD (false,m1,m2,g,h)); ((CHiggs HC1c, Sup (m1,g), Sdown (m2,-h)), Scalar_Scalar_Scalar 1, G_HSUSD (true,m1,m2,g,h)) ] let higgs_squark_a g h = higgs_squark' g h M1 M1 let higgs_squark_b (g,h) = List.flatten (Product.list2 (higgs_squark' g h) [M1;M2] [M1;M2]) let higgs_squark = if Flags.ckm_present then List.flatten (Product.list2 higgs_squark_a [1;2] [1;2]) @ ThoList.flatmap higgs_squark_b [(1,3);(2,3);(3,3);(3,1);(3,2)] else higgs_squark_a 1 1 @ higgs_squark_a 2 2 @ higgs_squark_b (3,3) let vertices3 = (ThoList.flatmap electromagnetic_currents_3 [1;2;3] @ ThoList.flatmap electromagnetic_currents_2 [C1;C2] @ List.flatten (Product.list2 electromagnetic_sfermion_currents [1;2;3] [M1;M2]) @ ThoList.flatmap neutral_currents [1;2;3] @ ThoList.flatmap neutral_sfermion_currents [1;2;3] @ ThoList.flatmap charged_currents [1;2;3] @ List.flatten (Product.list2 charged_slepton_currents [1;2;3] [M1;M2]) @ (if Flags.ckm_present then List.flatten (Product.list2 charged_quark_currents [1;2;3] [1;2;3]) @ List.flatten (Product.list2 charged_squark_currents [1;2;3] [1;2;3]) @ ThoList.flatmap yukawa_higgs_quark [(1,3);(2,3);(3,3);(3,1);(3,2)] else charged_quark_currents 1 1 @ charged_quark_currents 2 2 @ charged_quark_currents 3 3 @ charged_squark_currents 1 1 @ charged_squark_currents 2 2 @ charged_squark_currents 3 3 @ ThoList.flatmap yukawa_higgs_quark [(3,3)]) @ (*i ThoList.flatmap yukawa_higgs [1;2;3] @ i*) yukawa_higgs 3 @ yukawa_n @ ThoList.flatmap yukawa_c [C1;C2] @ ThoList.flatmap yukawa_cq [C1;C2] @ List.flatten (Product.list2 charged_chargino_currents [N1;N2;N3;N4;N5] [C1;C2]) @ triple_gauge @ ThoList.flatmap neutral_Z (pairs [N1;N2;N3;N4;N5]) @ Product.list2 charged_Z [C1;C2] [C1;C2] @ gauge_higgs @ higgs @ yukawa_higgs_2 @ (*i List.flatten (Product.list2 yukawa_higgs_quark [1;2;3] [1;2;3]) @ i*) List.flatten (Product.list2 higgs_charg_neutr [N1;N2;N3;N4;N5] [C1;C2]) @ higgs_neutr @ higgs_sneutrino @ higgs_sfermion @ higgs_squark @ yukawa_v @ ThoList.flatmap col_currents [1;2;3] @ List.flatten (Product.list2 col_sfermion_currents [1;2;3] [M1;M2])) @ List.flatten (Product.list2 col_lq_currents [M1;M2] [1;2;3]) @ ThoList.flatmap col_lqino_currents [1;2;3] @ ThoList.flatmap em_lqino_currents [1;2;3] @ ThoList.flatmap neutr_lqino_current [1;2;3] @ List.flatten (Product.list3 yuk_lqino_se_uc1 [1;2;3] [1;2;3] [1;2;3]) @ List.flatten (Product.list3 yuk_lqino_se_uc2 [1;2;3] [1;2;3] [1;2;3]) @ List.flatten (Product.list3 yuk_lqino_ec_su1 [1;2;3] [1;2;3] [1;2;3]) @ List.flatten (Product.list3 yuk_lqino_ec_su2 [1;2;3] [1;2;3] [1;2;3]) @ List.flatten (Product.list3 yuk_lqino_sn_dc1 [1;2;3] [1;2;3] [1;2;3]) @ List.flatten (Product.list3 yuk_lqino_sn_dc2 [1;2;3] [1;2;3] [1;2;3]) @ List.flatten (Product.list3 yuk_lqino_nc_sd1 [1;2;3] [1;2;3] [1;2;3]) @ List.flatten (Product.list3 yuk_lqino_nc_sd2 [1;2;3] [1;2;3] [1;2;3]) @ List.flatten (Product.list3 yuk_lq_ec_uc [1;2;3] [1;2;3] [1;2;3]) @ List.flatten (Product.list3 yuk_lq_ec_uc2 [1;2;3] [1;2;3] [1;2;3]) @ List.flatten (Product.list3 yuk_lq_nc_dc [1;2;3] [1;2;3] [1;2;3]) @ List.flatten (Product.list3 yuk_lq_nc_dc2 [1;2;3] [1;2;3] [1;2;3]) @ List.flatten (Product.list3 lq_neutr_Z [1;2;3] [M1;M2] [M1;M2]) @ List.flatten (Product.list2 em_lq_currents [1;2;3] [M1;M2]) @ List.flatten (Product.list3 lq_shiggs [1;2;3] [S1;S2;S3;S4;S5;S6;S7;S8;S9] [1;2;3]) @ List.flatten (Product.list3 lq_phiggs [1;2;3] [P1;P2;P3;P4;P5;P6;P7] [1;2;3]) @ List.flatten (Product.list3 yuk_lqino_shiggs [1;2;3] [S1;S2;S3;S4;S5;S6;S7;S8;S9] [1;2;3]) @ List.flatten (Product.list3 yuk_lqino_phiggs [1;2;3] [P1;P2;P3;P4;P5;P6;P7] [1;2;3]) @ List.flatten (Product.list3 lqino_lq_neu nlist [1;2;3] [1;2;3]) @ List.flatten (Product.list3 lqino_lq_neu2 nlist [1;2;3] [1;2;3]) @ List.flatten (Product.list3 lq_se_su [1;2;3] [1;2;3] [1;2;3]) @ List.flatten (Product.list3 lq_snu_sd [1;2;3] [1;2;3] [1;2;3]) @ List.flatten (Product.list2 lqino_lq_gg [1;2;3] [1;2;3]) let vertices4 = (quartic_gauge @ higgs4 @ gauge_higgs4 @ ThoList.flatmap gauge_sfermion4 [1;2;3] @ gauge_squark4 @ gluon_w_squark @ ThoList.flatmap gluon2_squark2 [1;2;3] @ ThoList.flatmap gluon_gauge_squark [1;2;3] @ ThoList.flatmap gluon2_lq2 [1;2;3] @ ThoList.flatmap lq_gauge4 [1;2;3] @ ThoList.flatmap lq_gg_gauge2 [1;2;3]) let vertices () = (vertices3, vertices4, []) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 (* SLHA2-Nomenclature for neutral Higgses *) let flavor_of_string s = match s with | "e-" -> L 1 | "e+" -> L (-1) | "mu-" -> L 2 | "mu+" -> L (-2) | "tau-" -> L 3 | "tau+" -> L (-3) | "nue" -> N 1 | "nuebar" -> N (-1) | "numu" -> N 2 | "numubar" -> N (-2) | "nutau" -> N 3 | "nutaubar" -> N (-3) | "se1-" -> Slepton (M1,1) | "se1+" -> Slepton (M1,-1) | "smu1-" -> Slepton (M1,2) | "smu1+" -> Slepton (M1,-2) | "stau1-" -> Slepton (M1,3) | "stau1+" -> Slepton (M1,-3) | "se2-" -> Slepton (M2,1) | "se2+" -> Slepton (M2,-1) | "smu2-" -> Slepton (M2,2) | "smu2+" -> Slepton (M2,-2) | "stau2-" -> Slepton (M2,3) | "stau2+" -> Slepton (M2,-3) | "snue" -> Sneutrino 1 | "snue*" -> Sneutrino (-1) | "snumu" -> Sneutrino 2 | "snumu*" -> Sneutrino (-2) | "snutau" -> Sneutrino 3 | "snutau*" -> Sneutrino (-3) | "u" -> U 1 | "ubar" -> U (-1) | "c" -> U 2 | "cbar" -> U (-2) | "t" -> U 3 | "tbar" -> U (-3) | "d" -> D 1 | "dbar" -> D (-1) | "s" -> D 2 | "sbar" -> D (-2) | "b" -> D 3 | "bbar" -> D (-3) | "A" -> Ga | "Z" | "Z0" -> Z | "W+" -> Wp | "W-" -> Wm | "gl" | "g" -> Gl | "h01" -> SHiggs S1 | "h02" -> SHiggs S2 | "h03" -> SHiggs S3 | "A01" -> PHiggs P1 | "A02" -> PHiggs P2 | "h04" -> SHiggs S4 | "h05" -> SHiggs S5 | "h06" -> SHiggs S6 | "A03" -> PHiggs P3 | "A04" -> PHiggs P4 | "h07" -> SHiggs S7 | "h08" -> SHiggs S8 | "h09" -> SHiggs S9 | "A05" -> PHiggs P5 | "A06" -> PHiggs P6 | "A07" -> PHiggs P7 (* JR: Only the first charged Higgs. *) | "H+" -> CHiggs HC1 | "H-" -> CHiggs HC1c | "su1" -> Sup (M1,1) | "su1c" -> Sup (M1,-1) | "sc1" -> Sup (M1,2) | "sc1c" -> Sup (M1,-2) | "st1" -> Sup (M1,3) | "st1c" -> Sup (M1,-3) | "su2" -> Sup (M2,1) | "su2c" -> Sup (M2,-1) | "sc2" -> Sup (M2,2) | "sc2c" -> Sup (M2,-2) | "st2" -> Sup (M2,3) | "st2c" -> Sup (M2,-3) | "sgl" | "sg" -> Gluino | "sd1" -> Sdown (M1,1) | "sd1c" -> Sdown (M1,-1) | "ss1" -> Sdown (M1,2) | "ss1c" -> Sdown (M1,-2) | "sb1" -> Sdown (M1,3) | "sb1c" -> Sdown (M1,-3) | "sd2" -> Sdown (M2,1) | "sd2c" -> Sdown (M2,-1) | "ss2" -> Sdown (M2,2) | "ss2c" -> Sdown (M2,-2) | "sb2" -> Sdown (M2,3) | "sb2c" -> Sdown (M2,-3) | "neu1" -> Neutralino N1 | "neu2" -> Neutralino N2 | "neu3" -> Neutralino N3 | "neu4" -> Neutralino N4 | "neu5" -> Neutralino N5 | "neu6" -> Neutralino N6 | "neu7" -> Neutralino N7 | "neu8" -> Neutralino N8 | "neu9" -> Neutralino N9 | "neu10" -> Neutralino N10 | "neu11" -> Neutralino N11 | "ch1+" -> Chargino C1 | "ch2+" -> Chargino C2 | "ch1-" -> Chargino C1c | "ch2-" -> Chargino C2c | "ch3+" -> Chargino C3 | "ch4+" -> Chargino C4 | "ch3-" -> Chargino C3c | "ch4-" -> Chargino C4c | "lq11" -> LQ (M1,1) | "lq11c" -> LQ (M1,-1) | "lq12" -> LQ (M2,1) | "lq12c" -> LQ (M2,-1) | "lq21" -> LQ (M1,2) | "lq21c" -> LQ (M1,-2) | "lq22" -> LQ (M2,2) | "lq22c" -> LQ (M2,-2) | "lq31" -> LQ (M1,3) | "lq31c" -> LQ (M1,-3) | "lq32" -> LQ (M2,3) | "lq32c" -> LQ (M2,-3) | "lqino1" -> LQino 1 | "lqino1b" -> LQino (-1) | "lqino2" -> LQino 2 | "lqino2b" -> LQino (-2) | "lqino3" -> LQino 3 | "lqino3b" -> LQino (-3) | s -> invalid_arg ("HUBABUBA: %s Modellib_PSSSM.ExtMSSM.flavor_of_string:" ^ s) let flavor_to_string = function | L 1 -> "e-" | L (-1) -> "e+" | L 2 -> "mu-" | L (-2) -> "mu+" | L 3 -> "tau-" | L (-3) -> "tau+" | N 1 -> "nue" | N (-1) -> "nuebar" | N 2 -> "numu" | N (-2) -> "numubar" | N 3 -> "nutau" | N (-3) -> "nutaubar" | U 1 -> "u" | U (-1) -> "ubar" | U 2 -> "c" | U (-2) -> "cbar" | U 3 -> "t" | U (-3) -> "tbar" | U _ -> invalid_arg "Modellib_PSSSM.ExtMSSM.flavor_to_string: invalid up type quark" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | D _ -> invalid_arg "Modellib_PSSSM.ExtMSSM.flavor_to_string: invalid down type quark" | Gl -> "gl" | Gluino -> "sgl" | Ga -> "A" | Z -> "Z" | Wp -> "W+" | Wm -> "W-" | SHiggs S1 -> "h01" | SHiggs S2 -> "h02" | SHiggs S3 -> "h03" | PHiggs P1 -> "A01" | PHiggs P2 -> "A02" | SHiggs S4 -> "h04" | SHiggs S5 -> "h05" | SHiggs S6 -> "h06" | PHiggs P3 -> "A03" | PHiggs P4 -> "A04" | SHiggs S7 -> "h07" | SHiggs S8 -> "h08" | SHiggs S9 -> "h09" | PHiggs P5 -> "A05" | PHiggs P6 -> "A06" | PHiggs P7 -> "A07" (* JR: Only the first charged Higgs. *) | CHiggs HC1 -> "H+" | CHiggs HC1c -> "H-" | CHiggs HC2 -> "HX_1+" | CHiggs HC2c -> "HX_1-" | CHiggs HC3 -> "HX_2+" | CHiggs HC3c -> "HX_2-" | CHiggs HC4 -> "HX_3+" | CHiggs HC4c -> "HX_3-" | CHiggs HC5 -> "HX_4+" | CHiggs HC5c -> "HX_4-" | Slepton (M1,1) -> "se1-" | Slepton (M1,-1) -> "se1+" | Slepton (M1,2) -> "smu1-" | Slepton (M1,-2) -> "smu1+" | Slepton (M1,3) -> "stau1-" | Slepton (M1,-3) -> "stau1+" | Slepton (M2,1) -> "se2-" | Slepton (M2,-1) -> "se2+" | Slepton (M2,2) -> "smu2-" | Slepton (M2,-2) -> "smu2+" | Slepton (M2,3) -> "stau2-" | Slepton (M2,-3) -> "stau2+" | Sneutrino 1 -> "snue" | Sneutrino (-1) -> "snue*" | Sneutrino 2 -> "snumu" | Sneutrino (-2) -> "snumu*" | Sneutrino 3 -> "snutau" | Sneutrino (-3) -> "snutau*" | Sup (M1,1) -> "su1" | Sup (M1,-1) -> "su1c" | Sup (M1,2) -> "sc1" | Sup (M1,-2) -> "sc1c" | Sup (M1,3) -> "st1" | Sup (M1,-3) -> "st1c" | Sup (M2,1) -> "su2" | Sup (M2,-1) -> "su2c" | Sup (M2,2) -> "sc2" | Sup (M2,-2) -> "sc2c" | Sup (M2,3) -> "st2" | Sup (M2,-3) -> "st2c" | Sdown (M1,1) -> "sd1" | Sdown (M1,-1) -> "sd1c" | Sdown (M1,2) -> "ss1" | Sdown (M1,-2) -> "ss1c" | Sdown (M1,3) -> "sb1" | Sdown (M1,-3) -> "sb1c" | Sdown (M2,1) -> "sd2" | Sdown (M2,-1) -> "sd2c" | Sdown (M2,2) -> "ss2" | Sdown (M2,-2) -> "ss2c" | Sdown (M2,3) -> "sb2" | Sdown (M2,-3) -> "sb2c" | Neutralino n -> "neu" ^ string_of_neu n | Chargino C1 -> "ch1+" | Chargino C1c -> "ch1-" | Chargino C2 -> "ch2+" | Chargino C2c -> "ch2-" | Chargino C3 -> "ch3+" | Chargino C3c -> "ch3-" | Chargino C4 -> "ch4+" | Chargino C4c -> "ch4-" | LQ (M1,1) -> "lq11" | LQ (M1,-1) -> "lq11c" | LQ (M2,1) -> "lq12" | LQ (M2,-1) -> "lq12c" | LQ (M1,2) -> "lq21" | LQ (M1,-2) -> "lq21c" | LQ (M2,2) -> "lq22" | LQ (M2,-2) -> "lq22c" | LQ (M1,3) -> "lq31" | LQ (M1,-3) -> "lq31c" | LQ (M2,3) -> "lq32" | LQ (M2,-3) -> "lq32c" | LQino 1 -> "lqino1" | LQino (-1) -> "lqino1b" | LQino 2 -> "lqino2" | LQino (-2) -> "lqino2b" | LQino 3 -> "lqino3" | LQino (-3) -> "lqino3b" | _ -> invalid_arg "Modellib_PSSSM.ExtMSSM.flavor_to_string" let flavor_to_TeX = function | L 1 -> "e^-" | L (-1) -> "e^+" | L 2 -> "\\mu^-" | L (-2) -> "\\mu^+" | L 3 -> "\\tau^-" | L (-3) -> "\\tau^+" | N 1 -> "\\nu_e" | N (-1) -> "\\bar{\\nu}_e" | N 2 -> "\\nu_\\mu" | N (-2) -> "\\bar{\\nu}_\\mu" | N 3 -> "\\nu_\\tau" | N (-3) -> "\\bar{\\nu}_\\tau" | U 1 -> "u" | U (-1) -> "\\bar{u}" | U 2 -> "c" | U (-2) -> "\\bar{c}" | U 3 -> "t" | U (-3) -> "\\bar{t}" | D 1 -> "d" | D (-1) -> "\\bar{d}" | D 2 -> "s" | D (-2) -> "\\bar{s}" | D 3 -> "b" | D (-3) -> "\\bar{b}" | L _ -> invalid_arg "Modellib_PSSSM.ExtMSSM.flavor_to_TeX: invalid lepton" | N _ -> invalid_arg "Modellib_PSSSM.ExtMSSM.flavor_to_TeX: invalid neutrino" | U _ -> invalid_arg "Modellib_PSSSM.ExtMSSM.flavor_to_TeX: invalid up type quark" | D _ -> invalid_arg "Modellib_PSSSM.ExtMSSM.flavor_to_TeX: invalid down type quark" | Gl -> "g" | Gluino -> "\\widetilde{g}" | Ga -> "\\gamma" | Z -> "Z" | Wp -> "W^+" | Wm -> "W^-" | SHiggs S1 -> "S_1" | SHiggs S2 -> "S_2" | SHiggs S3 -> "S_3" | SHiggs S4 -> "S_4" | SHiggs S5 -> "S_5" | SHiggs S6 -> "S_6" | SHiggs S7 -> "S_7" | SHiggs S8 -> "S_8" | SHiggs S9 -> "S_9" | PHiggs P1 -> "P_1" | PHiggs P2 -> "P_2" | PHiggs P3 -> "P_3" | PHiggs P4 -> "P_4" | PHiggs P5 -> "P_5" | PHiggs P6 -> "P_6" | PHiggs P7 -> "P_7" | CHiggs HC1 -> "H^+" | CHiggs HC1c -> "H^-" | CHiggs HC2 -> "X_{H,1}^+" | CHiggs HC2c -> "X_{H,1}^-" | CHiggs HC3 -> "X_{H,2}^+" | CHiggs HC3c -> "X_{H,2}^-" | CHiggs HC4 -> "X_{H,3}^+" | CHiggs HC4c -> "X_{H,3}^-" | CHiggs HC5 -> "X_{H,4}^+" | CHiggs HC5c -> "X_{H,4}^-" | Slepton (M1,1) -> "\\widetilde{e}_1^-" | Slepton (M1,-1) -> "\\widetilde{e}_1^+" | Slepton (M1,2) -> "\\widetilde{\\mu}_1^-" | Slepton (M1,-2) -> "\\widetilde{\\mu}_1^+" | Slepton (M1,3) -> "\\widetilde{\\tau}_1^-" | Slepton (M1,-3) -> "\\widetilde{\\tau}_1^+" | Slepton (M2,1) -> "\\widetilde{e}_2^-" | Slepton (M2,-1) -> "\\widetilde{e}_2^+" | Slepton (M2,2) -> "\\widetilde{\\mu}_2^-" | Slepton (M2,-2) -> "\\widetilde{\\mu}_2^+" | Slepton (M2,3) -> "\\widetilde{\\tau}_2^-" | Slepton (M2,-3) -> "\\widetilde{\\tau}_2^+" | Sneutrino 1 -> "\\widetilde{\\nu}_e" | Sneutrino (-1) -> "\\widetilde{\\nu}_e^*" | Sneutrino 2 -> "\\widetilde{\\nu}_\\mu" | Sneutrino (-2) -> "\\widetilde{\\nu}_\\mu^*" | Sneutrino 3 -> "\\widetilde{\\nu}_\\tau" | Sneutrino (-3) -> "\\widetilde{\\nu}_\\tau^*" | Sup (M1,1) -> "\\widetilde{u}_1" | Sup (M1,-1) -> "\\widetilde{u}_1^*" | Sup (M1,2) -> "\\widetilde{c}_1" | Sup (M1,-2) -> "\\widetilde{c}_1^*" | Sup (M1,3) -> "\\widetilde{t}_1" | Sup (M1,-3) -> "\\widetilde{t}_1^*" | Sup (M2,1) -> "\\widetilde{u}_2" | Sup (M2,-1) -> "\\widetilde{u}_2^*" | Sup (M2,2) -> "\\widetilde{c}_2" | Sup (M2,-2) -> "\\widetilde{c}_2^*" | Sup (M2,3) -> "\\widetilde{t}_2" | Sup (M2,-3) -> "\\widetilde{t}_2^*" | Sdown (M1,1) -> "\\widetilde{d}_1" | Sdown (M1,-1) -> "\\widetilde{d}_1^*" | Sdown (M1,2) -> "\\widetilde{s}_1" | Sdown (M1,-2) -> "\\widetilde{s}_1^*" | Sdown (M1,3) -> "\\widetilde{b}_1" | Sdown (M1,-3) -> "\\widetilde{b}_1^*" | Sdown (M2,1) -> "\\widetilde{d}_2" | Sdown (M2,-1) -> "\\widetilde{d}_2^*" | Sdown (M2,2) -> "\\widetilde{s}_2" | Sdown (M2,-2) -> "\\widetilde{s}_2^*" | Sdown (M2,3) -> "\\widetilde{b}_2" | Sdown (M2,-3) -> "\\widetilde{b}_2^*" | Neutralino N1 -> "\\widetilde{\\chi}^0_1" | Neutralino N2 -> "\\widetilde{\\chi}^0_2" | Neutralino N3 -> "\\widetilde{\\chi}^0_3" | Neutralino N4 -> "\\widetilde{\\chi}^0_4" | Neutralino N5 -> "\\widetilde{\\chi}^0_5" | Neutralino N6 -> "\\widetilde{\\chi}^0_6" | Neutralino N7 -> "\\widetilde{\\chi}^0_7" | Neutralino N8 -> "\\widetilde{\\chi}^0_8" | Neutralino N9 -> "\\widetilde{\\chi}^0_9" | Neutralino N10 -> "\\widetilde{\\chi}^0_{10}" | Neutralino N11 -> "\\widetilde{\\chi}^0_{11}" | Slepton _ -> invalid_arg "Modellib_PSSSM.ExtMSSM.flavor_to_TeX: invalid slepton" | Sneutrino _ -> invalid_arg "Modellib_PSSSM.ExtMSSM.flavor_to_TeX: invalid sneutrino" | Sup _ -> invalid_arg "Modellib_PSSSM.ExtMSSM.flavor_to_TeX: invalid up type squark" | Sdown _ -> invalid_arg "Modellib_PSSSM.ExtMSSM.flavor_to_TeX: invalid down type squark" | Chargino C1 -> "\\widetilde{\\chi}_1^+" | Chargino C1c -> "\\widetilde{\\chi}_1^-" | Chargino C2 -> "\\widetilde{\\chi}_2^+" | Chargino C2c -> "\\widetilde{\\chi}_2^-" | Chargino C3 -> "\\widetilde{\\chi}_3^+" | Chargino C3c -> "\\widetilde{\\chi}_3^-" | Chargino C4 -> "\\widetilde{\\chi}_4^+" | Chargino C4c -> "\\widetilde{\\chi}_4^-" | LQ (M1,1) -> "D_{1,,1}" | LQ (M1,-1) -> "D_{1,,1}^*" | LQ (M2,1) -> "D_{1,,2}" | LQ (M2,-1) -> "D_{1,,2}^*" | LQ (M1,2) -> "D_{2,,1}" | LQ (M1,-2) -> "D_{2,,1}^*" | LQ (M2,2) -> "D_{2,,2}" | LQ (M2,-2) -> "D_{2,,2}^*" | LQ (M1,3) -> "D_{3,,1}" | LQ (M1,-3) -> "D_{3,,1}^*" | LQ (M2,3) -> "D_{3,,2}" | LQ (M2,-3) -> "D_{3,,2}^*" | LQino 1 -> "\\widetilde{D}_1" | LQino (-1) -> "\\bar\\widetilde{D}_1" | LQino 2 -> "\\widetilde{D}_2" | LQino (-2) -> "\\bar\\widetilde{D}_2" | LQino 3 -> "\\widetilde{D}_3" | LQino (-3) -> "\\bar\\widetilde{D}_3" | LQ _ -> invalid_arg "Modellib_PSSSM.ExtMSSM.flavor_to_TeX: invalid leptoquark type" | LQino _ -> invalid_arg "Modellib_PSSSM.ExtMSSM.flavor_to_TeX: invalid leptoquarkino type" let flavor_symbol = function | L g when g > 0 -> "l" ^ string_of_int g | L g -> "l" ^ string_of_int (abs g) ^ "b" | N g when g > 0 -> "n" ^ string_of_int g | N g -> "n" ^ string_of_int (abs g) ^ "b" | U g when g > 0 -> "u" ^ string_of_int g | U g -> "u" ^ string_of_int (abs g) ^ "b" | D g when g > 0 -> "d" ^ string_of_int g | D g -> "d" ^ string_of_int (abs g) ^ "b" | Gl -> "gl" | Ga -> "a" | Z -> "z" | Wp -> "wp" | Wm -> "wm" | Slepton (M1,g) when g > 0 -> "sl1" ^ string_of_int g | Slepton (M1,g) -> "sl1c" ^ string_of_int (abs g) | Slepton (M2,g) when g > 0 -> "sl2" ^ string_of_int g | Slepton (M2,g) -> "sl2c" ^ string_of_int (abs g) | Sneutrino g when g > 0 -> "sn" ^ string_of_int g | Sneutrino g -> "snc" ^ string_of_int (abs g) | Sup (M1,g) when g > 0 -> "su1" ^ string_of_int g | Sup (M1,g) -> "su1c" ^ string_of_int (abs g) | Sup (M2,g) when g > 0 -> "su2" ^ string_of_int g | Sup (M2,g) -> "su2c" ^ string_of_int (abs g) | Sdown (M1,g) when g > 0 -> "sd1" ^ string_of_int g | Sdown (M1,g) -> "sd1c" ^ string_of_int (abs g) | Sdown (M2,g) when g > 0 -> "sd2" ^ string_of_int g | Sdown (M2,g) -> "sd2c" ^ string_of_int (abs g) | Neutralino n -> "neu" ^ (string_of_neu n) | Chargino c when (int_of_char c) > 0 -> "cp" ^ string_of_char c | Chargino c -> "cm" ^ string_of_int (abs (int_of_char c)) | Gluino -> "sgl" | SHiggs s -> "h0" ^ (string_of_shiggs s) | PHiggs p -> "A0" ^ (string_of_phiggs p) | CHiggs HC1 -> "hp" | CHiggs HC1c -> "hm" | CHiggs _ -> invalid_arg "charged Higgs not yet implemented" | LQ (M1,g) when g > 0 -> "lq" ^ string_of_int g ^ "1" | LQ (M1,g) -> "lq" ^ string_of_int (abs g) ^ "1c" | LQ (M2,g) when g > 0 -> "lq" ^ string_of_int g ^ "2" | LQ (M2,g) -> "lq" ^ string_of_int (abs g) ^ "2c" | LQino g when g > 0 -> "lqino" ^ string_of_int g | LQino g -> "lqino" ^ string_of_int (abs g) ^ "b" let pdg = function | L g when g > 0 -> 9 + 2*g | L g -> - 9 + 2*g | N g when g > 0 -> 10 + 2*g | N g -> - 10 + 2*g | U g when g > 0 -> 2*g | U g -> 2*g | D g when g > 0 -> - 1 + 2*g | D g -> 1 + 2*g | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) | SHiggs S1 -> 25 | SHiggs S2 -> 35 | PHiggs P1 -> 36 (* JR: Only the first charged Higgs. *) | CHiggs HC1 -> 37 | CHiggs HC1c -> (-37) | CHiggs _ -> invalid_arg "charged Higgs not yet implemented" | Slepton (M1,g) when g > 0 -> 1000009 + 2*g | Slepton (M1,g) -> - 1000009 + 2*g | Slepton (M2,g) when g > 0 -> 2000009 + 2*g | Slepton (M2,g) -> - 2000009 + 2*g | Sneutrino g when g > 0 -> 1000010 + 2*g | Sneutrino g -> - 1000010 + 2*g | Sup (M1,g) when g > 0 -> 1000000 + 2*g | Sup (M1,g) -> - 1000000 + 2*g | Sup (M2,g) when g > 0 -> 2000000 + 2*g | Sup (M2,g) -> - 2000000 + 2*g | Sdown (M1,g) when g > 0 -> 999999 + 2*g | Sdown (M1,g) -> - 999999 + 2*g | Sdown (M2,g) when g > 0 -> 1999999 + 2*g | Sdown (M2,g) -> - 1999999 + 2*g | Gluino -> 1000021 (* JR: only the first two charginos. *) | Chargino C1 -> 1000024 | Chargino C1c -> (-1000024) | Chargino C2 -> 1000037 | Chargino C2c -> (-1000037) | Chargino C3 -> 1000039 | Chargino C3c -> (-1000039) | Chargino C4 -> 1000041 | Chargino C4c -> (-1000041) | Neutralino N1 -> 1000022 | Neutralino N2 -> 1000023 | Neutralino N3 -> 1000025 | Neutralino N4 -> 1000035 (* According to SLHA2 (not anymore ?!?)*) | Neutralino N5 -> 1000045 | Neutralino N6 -> 1000046 | Neutralino N7 -> 1000047 | Neutralino N8 -> 1000048 | Neutralino N9 -> 1000049 | Neutralino N10 -> 1000050 | Neutralino N11 -> 1000051 | PHiggs P2 -> 46 | PHiggs P3 -> 47 | PHiggs P4 -> 48 | PHiggs P5 -> 49 | PHiggs P6 -> 50 | PHiggs P7 -> 51 | SHiggs S3 -> 45 | SHiggs S4 -> 52 | SHiggs S5 -> 53 | SHiggs S6 -> 54 | SHiggs S7 -> 55 | SHiggs S8 -> 56 | SHiggs S9 -> 57 | LQ (M1,g) when g > 0 -> 1000059 + g | LQ (M1,g) -> - 1000059 + g | LQ (M2,g) when g > 0 -> 2000059 + g | LQ (M2,g) -> - 2000059 + g | LQino g when g > 0 -> 59 + g | LQino g -> -59 + g (* We must take care of the pdg numbers for the two different kinds of sfermions in the MSSM. The particle data group in its Monte Carlo particle numbering scheme takes only into account mixtures of the third generation squarks and the stau. For the other sfermions we will use the number of the lefthanded field for the lighter mixed state and the one for the righthanded for the heavier. Below are the official pdg numbers from the Particle Data Group. In order not to produce arrays with some million entries in the Fortran code for the masses and the widths we introduce our private pdg numbering scheme which only extends not too far beyond 42. Our private scheme then has the following pdf numbers (for the sparticles the subscripts $L/R$ and $1/2$ are taken synonymously): \begin{center} \renewcommand{\arraystretch}{1.2} \begin{tabular}{|r|l|l|}\hline $d$ & down-quark & 1 \\\hline $u$ & up-quark & 2 \\\hline $s$ & strange-quark & 3 \\\hline $c$ & charm-quark & 4 \\\hline $b$ & bottom-quark & 5 \\\hline $t$ & top-quark & 6 \\\hline\hline $e^-$ & electron & 11 \\\hline $\nu_e$ & electron-neutrino & 12 \\\hline $\mu^-$ & muon & 13 \\\hline $\nu_\mu$ & muon-neutrino & 14 \\\hline $\tau^-$ & tau & 15 \\\hline $\nu_\tau$ & tau-neutrino & 16 \\\hline\hline $g$ & gluon & (9) 21 \\\hline $\gamma$ & photon & 22 \\\hline $Z^0$ & Z-boson & 23 \\\hline $W^+$ & W-boson & 24 \\\hline\hline $h^0$ & light Higgs boson & 25 \\\hline $H^0$ & heavy Higgs boson & 35 \\\hline $A^0$ & pseudoscalar Higgs & 36 \\\hline $H^+$ & charged Higgs & 37 \\\hline\hline $\tilde{d}_L$ & down-squark 1 & 41 \\\hline $\tilde{u}_L$ & up-squark 1 & 42 \\\hline $\tilde{s}_L$ & strange-squark 1 & 43 \\\hline $\tilde{c}_L$ & charm-squark 1 & 44 \\\hline $\tilde{b}_L$ & bottom-squark 1 & 45 \\\hline $\tilde{t}_L$ & top-squark 1 & 46 \\\hline $\tilde{d}_R$ & down-squark 2 & 47 \\\hline $\tilde{u}_R$ & up-squark 2 & 48 \\\hline $\tilde{s}_R$ & strange-squark 2 & 49 \\\hline $\tilde{c}_R$ & charm-squark 2 & 50 \\\hline $\tilde{b}_R$ & bottom-squark 2 & 51 \\\hline $\tilde{t}_R$ & top-squark 2 & 52 \\\hline\hline $\tilde{e}_L$ & selectron 1 & 53 \\\hline $\tilde{\nu}_{e,L}$ & electron-sneutrino & 54 \\\hline $\tilde{\mu}_L$ & smuon 1 & 55 \\\hline $\tilde{\nu}_{\mu,L}$ & muon-sneutrino & 56 \\\hline $\tilde{\tau}_L$ & stau 1 & 57 \\\hline $\tilde{\nu}_{\tau,L}$ & tau-sneutrino & 58 \\\hline $\tilde{e}_R$ & selectron 2 & 59 \\\hline $\tilde{\mu}_R$ & smuon 2 & 61 \\\hline $\tilde{\tau}_R$ & stau 2 & 63 \\\hline\hline $\tilde{g}$ & gluino & 64 \\\hline $\tilde{\chi}^0_1$ & neutralino 1 & 65 \\\hline $\tilde{\chi}^0_2$ & neutralino 2 & 66 \\\hline $\tilde{\chi}^0_3$ & neutralino 3 & 67 \\\hline $\tilde{\chi}^0_4$ & neutralino 4 & 68 \\\hline $\tilde{\chi}^0_4$ & neutralino 5 & 69 \\\hline $\tilde{\chi4}^+_1$ & chargino 1 & 70 \\\hline $\tilde{\chi}^+_2$ & chargino 2 & 71 \\\hline\hline $a$ & pseudoscalar & 72 \\\hline $s$ & scalar singlet & 73 \\\hline $\tilde{G}$ & gravitino & -- \\\hline\hline \end{tabular} \end{center} *) let pdg_mw = function | L g when g > 0 -> 9 + 2*g | L g -> - 9 + 2*g | N g when g > 0 -> 10 + 2*g | N g -> - 10 + 2*g | U g when g > 0 -> 2*g | U g -> 2*g | D g when g > 0 -> - 1 + 2*g | D g -> 1 + 2*g | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) | SHiggs S1 -> 25 | SHiggs S2 -> 35 | PHiggs P1 -> 36 (* JR: Only the first charged Higgs. *) | CHiggs HC1 -> 37 | CHiggs HC1c -> (-37) | CHiggs _ -> invalid_arg "charged Higgs not yet implemented" | Sup (M1,g) when g > 0 -> 40 + 2*g | Sup (M1,g) -> - 40 + 2*g | Sup (M2,g) when g > 0 -> 46 + 2*g | Sup (M2,g) -> - 46 + 2*g | Sdown (M1,g) when g > 0 -> 39 + 2*g | Sdown (M1,g) -> - 39 + 2*g | Sdown (M2,g) when g > 0 -> 45 + 2*g | Sdown (M2,g) -> - 45 + 2*g | Slepton (M1,g) when g > 0 -> 51 + 2*g | Slepton (M1,g) -> - 51 + 2*g | Slepton (M2,g) when g > 0 -> 57 + 2*g | Slepton (M2,g) -> - 57 + 2*g | Sneutrino g when g > 0 -> 52 + 2*g | Sneutrino g -> - 52 + 2*g | Gluino -> 64 (* JR: Only the first two charginos. *) | Chargino C1 -> 70 | Chargino C1c -> (-70) | Chargino C2 -> 71 | Chargino C2c -> (-71) | Chargino C3 -> 106 | Chargino C3c -> (-106) | Chargino C4 -> 107 | Chargino C4c -> (-107) | Neutralino N1 -> 65 | Neutralino N2 -> 66 | Neutralino N3 -> 67 | Neutralino N4 -> 68 | Neutralino N5 -> 69 | Neutralino N6 -> 100 | Neutralino N7 -> 101 | Neutralino N8 -> 102 | Neutralino N9 -> 103 | Neutralino N10 -> 104 | Neutralino N11 -> 105 | PHiggs P2 -> 72 | PHiggs P3 -> 89 | PHiggs P4 -> 90 | PHiggs P5 -> 91 | PHiggs P6 -> 92 | PHiggs P7 -> 93 | SHiggs S3 -> 73 | SHiggs S4 -> 94 | SHiggs S5 -> 95 | SHiggs S6 -> 96 | SHiggs S7 -> 97 | SHiggs S8 -> 98 | SHiggs S9 -> 99 | LQ (M1,g) when g > 0 -> 78 + 2*g | LQ (M1,g) -> - 78 + 2*g | LQ (M2,g) when g > 0 -> 79 + 2*g | LQ (M2,g) -> - 79 + 2*g | LQino g when g > 0 -> 85 + g | LQino g -> - 85 + g let mass_symbol f = "mass(" ^ string_of_int (abs (pdg_mw f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg_mw f)) ^ ")" let conj_symbol = function | false, str -> str | true, str -> str ^ "_c" let constant_symbol = function | E -> "e" | G -> "g" | G_Z -> "gz" | Q_lepton -> "qlep" | Q_up -> "qup" | Q_down -> "qdwn" | Q_charg -> "qchar" | G_NC_lepton -> "gnclep" | G_NC_neutrino -> "gncneu" | G_NC_up -> "gncup" | G_NC_down -> "gncdwn" | G_CC -> "gcc" | G_CCQ (vc,g1,g2) -> conj_symbol (vc, "g_ccq" ) ^ "(" ^ string_of_int g1 ^ "," ^ string_of_int g2 ^ ")" | I_Q_W -> "iqw" | I_G_ZWW -> "igzww" | G_WWWW -> "gw4" | G_ZZWW -> "gzzww" | G_PZWW -> "gpzww" | G_PPWW -> "gppww" | G_GH4_ZZPP (p1,p2) -> "g_ZZA0A0(" ^ string_of_phiggs p1 ^ "," ^ string_of_phiggs p2 ^ ")" | G_GH4_ZZSS (s1,s2) -> "g_ZZh0h0(" ^ string_of_shiggs s1 ^ "," ^ string_of_shiggs s2 ^ ")" | G_GH4_ZZCC -> "g_zzhphm" | G_GH4_GaGaCC -> "g_AAhphm" | G_GH4_ZGaCC -> "g_zAhphm" | G_GH4_WWCC -> "g_wwhphm" | G_GH4_WWPP (p1,p2) -> "g_WWA0A0(" ^ string_of_phiggs p1 ^ "," ^ string_of_phiggs p2 ^ ")" | G_GH4_WWSS (s1,s2) -> "g_WWh0h0(" ^ string_of_shiggs s1 ^ "," ^ string_of_shiggs s2 ^ ")" | G_GH4_ZWSC s -> "g_ZWhph0(" ^ string_of_shiggs s ^")" | G_GH4_GaWSC s -> "g_AWhph0(" ^ string_of_shiggs s ^")" | G_GH4_ZWPC p -> "g_ZWhpA0(" ^ string_of_phiggs p ^")" | G_GH4_GaWPC p -> "g_AWhpA0(" ^ string_of_phiggs p ^")" | G_CICIS (n1,n2,s) -> "g_neuneuh0(" ^ string_of_neu n1 ^ "," ^ string_of_neu n2 ^ "," ^ string_of_shiggs s ^ ")" | G_CICIP (n1,n2,p) -> "g_neuneuA0(" ^ string_of_neu n1 ^ "," ^ string_of_neu n2 ^ "," ^ string_of_phiggs p ^ ")" | G_H3_SCC s -> "g_h0hphm(" ^ string_of_shiggs s ^ ")" | G_H3_SPP (s,p1,p2) -> "g_h0A0A0(" ^ string_of_shiggs s ^ "," ^ string_of_phiggs p1 ^ "," ^ string_of_phiggs p2 ^ ")" | G_H3_SSS (s1,s2,s3) -> "g_h0h0h0(" ^ string_of_shiggs s1 ^ "," ^ string_of_shiggs s2 ^ "," ^ string_of_shiggs s3 ^ ")" | G_CSC (c1,c2,s) -> "g_chchh0(" ^ string_of_char c1 ^ "," ^ string_of_char c2 ^ "," ^ string_of_shiggs s ^ ")" | G_CPC (c1,c2,p) -> "g_chchA0(" ^ string_of_char c1 ^ "," ^ string_of_char c2 ^ "," ^ string_of_phiggs p ^")" | G_YUK_FFS (f1,f2,s) -> "g_yuk_h0_" ^ string_of_fermion_type f1 ^ string_of_fermion_type f2 ^ "(" ^ string_of_shiggs s ^ "," ^ string_of_fermion_gen f1 ^ ")" | G_YUK_FFP (f1,f2,p) -> "g_yuk_A0_" ^ string_of_fermion_type f1 ^ string_of_fermion_type f2 ^ "(" ^ string_of_phiggs p ^ "," ^ string_of_fermion_gen f1 ^ ")" | G_YUK_LCN g -> "g_yuk_hp_ln(" ^ string_of_int g ^ ")" | G_NWC (n,c) -> "g_nwc(" ^ string_of_char c ^ "," ^ string_of_neu n ^ ")" | G_CWN (c,n) -> "g_cwn(" ^ string_of_char c ^ "," ^ string_of_neu n ^ ")" | G_SLSNW (vc,g,m) -> conj_symbol (vc, "g_wslsn") ^ "(" ^ string_of_int g ^ "," ^ string_of_sfm m ^ ")" | G_NZN (n1,n2) -> "g_zneuneu(" ^ string_of_neu n1 ^ "," ^ string_of_neu n2 ^ ")" | G_CZC (c1,c2) -> "g_zchch(" ^ string_of_char c1 ^ "," ^ string_of_char c2 ^ ")" | Gs -> "gs" | G_YUK_UCD (n,m) -> "g_yuk_hp_ud(" ^ string_of_int n ^ "," ^ string_of_int m ^ ")" | G_YUK_DCU (n,m) -> "g_yuk_hm_du(" ^ string_of_int n ^ "," ^ string_of_int m ^ ")" | G_YUK_N (vc,f,n,sf,m) -> conj_symbol (vc, "g_yuk_neu_" ^ string_of_fermion_type f ^ string_of_sff sf) ^ "(" ^ string_of_fermion_gen f ^ "," ^ string_of_neu n ^ "," ^ string_of_sfm m ^ ")" | G_YUK_G (vc,f,sf,m) -> conj_symbol (vc, "g_yuk_gluino_" ^ string_of_fermion_type f ^ string_of_sff sf) ^ "(" ^ string_of_fermion_gen f ^ "," ^ string_of_sfm m ^ ")" | G_YUK_C (vc,f,c,sf,m) -> conj_symbol (vc, "g_yuk_char_" ^ string_of_fermion_type f ^ string_of_sff sf) ^ "(" ^ string_of_fermion_gen f ^ "," ^ string_of_char c ^ "," ^ string_of_sfm m ^ ")" | G_YUK_Q (vc,g1,f,c,sf,m) -> conj_symbol (vc, "g_yuk_char_" ^ string_of_fermion_type f ^ string_of_sff sf) ^"("^string_of_int g1 ^ "," ^ string_of_fermion_gen f ^ "," ^ string_of_char c ^ "," ^ string_of_sfm m ^ ")" | G_WPSUSD (vc,m1,m2,g1,g2) -> conj_symbol (vc, "g_wA_susd") ^ "(" ^ string_of_int g1 ^ "," ^ string_of_int g2 ^ "," ^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ ")" | G_WZSUSD (vc,m1,m2,g1,g2) -> conj_symbol (vc, "g_wz_susd") ^ "(" ^ string_of_int g1 ^ "," ^ string_of_int g2 ^ "," ^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ ")" (* 3vertex: Higgs-Gauge a la Franke-Fraas *) (* Nomenclature consistent with [flavor_of_string] *) | G_GH_ZSP (s,p) -> "g_zh0a0(" ^ string_of_shiggs s ^ "," ^ string_of_phiggs p ^ ")" | G_GH_WSC s -> "g_Whph0(" ^ string_of_shiggs s ^ ")" | G_GH_WPC p -> "g_WhpA0(" ^ string_of_phiggs p^ ")" | G_GH_ZZS s -> "g_ZZh0(" ^ string_of_shiggs s ^ ")" | G_GH_WWS s -> "g_WWh0(" ^ string_of_shiggs s ^ ")" | G_GH_ZCC -> "g_Zhmhp" | G_GH_GaCC -> "g_Ahmhp" | G_ZSF (f,g,m1,m2) -> "g_z" ^ string_of_sff f ^ string_of_sff f ^ "(" ^ string_of_int g ^ "," ^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ ")" | G_HSNSL (vc,g,m) -> conj_symbol (vc, "g_hp_sl" ^ string_of_sfm m ^ "sn1" ) ^ "(" ^ string_of_int g ^ ")" | G_GlGlSQSQ -> "g_gg_sqsq" | G_PPSFSF f -> "g_AA_" ^ string_of_sff f ^ string_of_sff f | G_ZZSFSF (f,g,m1,m2) -> "g_zz_" ^ string_of_sff f ^string_of_sff f ^ "(" ^ string_of_int g ^ "," ^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ ")" | G_ZPSFSF (f,g,m1,m2) -> "g_zA_" ^ string_of_sff f ^string_of_sff f ^ "(" ^ string_of_int g ^","^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ ")" | G_GlPSQSQ -> "g_gA_sqsq" | G_GlZSFSF (f,g,m1,m2) -> "g_gz_" ^ string_of_sff f ^ string_of_sff f ^ "(" ^ string_of_int g ^ "," ^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ ")" | G_GlWSUSD (vc,m1,m2,g1,g2) -> conj_symbol (vc, "g_gw_susd") ^ "(" ^ string_of_int g1 ^ "," ^string_of_int g2 ^ "," ^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ ")" | G_strong -> "gs" | G_SS -> "gs**2" | I_G_S -> "igs" | G_NHC (vc,n,c) -> conj_symbol(vc,"g_neuhmchar") ^ "(" ^ string_of_neu n ^ "," ^ string_of_char c ^ ")" | G_WWSFSF (f,g,m1,m2) -> "g_ww_" ^ string_of_sff f ^ string_of_sff f ^ "(" ^ string_of_int g ^ "," ^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ ")" | G_WPSLSN (vc,g,m) -> conj_symbol (vc, "g_wA_slsn") ^"("^ string_of_int g ^ "," ^ string_of_sfm m ^ ")" | G_WZSLSN (vc,g,m) -> conj_symbol (vc, "g_wz_slsn") ^ "(" ^ string_of_int g ^ "," ^ string_of_sfm m ^ ")" | G_SFSFS (s,f,g,m1,m2) -> "g_h0_"^ string_of_sff f ^ string_of_sfm m1 ^ string_of_sff f ^ string_of_sfm m2 ^ "(" ^ string_of_shiggs s ^ "," ^ string_of_int g ^ ")" | G_SFSFP (p,f,g,m1,m2) -> "g_A0_"^ string_of_sff f ^ string_of_sfm m1 ^ string_of_sff f ^ string_of_sfm m2 ^ "(" ^ string_of_phiggs p ^ "," ^ string_of_int g ^ ")" | G_HSUSD (vc,m1,m2,g1,g2) -> conj_symbol (vc, "g_hp_su" ^ string_of_sfm m1 ^ "sd" ^ string_of_sfm m2 ) ^ "(" ^ string_of_int g1 ^ "," ^ string_of_int g2 ^ ")" | G_WSQ (vc,g1,g2,m1,m2) -> conj_symbol (vc, "g_wsusd") ^ "(" ^ string_of_int g1 ^ "," ^ string_of_int g2 ^ "," ^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ ")" | G_YUK_LQ_S (g1,s,g3) -> "g_yuk_lq_s(" ^ string_of_int g1 ^ "," ^ string_of_shiggs s ^"," ^ string_of_int g3 ^")" | G_YUK_LQ_P (g1,p,g3) -> "g_yuk_lq_p(" ^ string_of_int g1 ^ "," ^ string_of_phiggs p ^ "," ^ string_of_int g3 ^ ")" | G_LQ_NEU (m,g1,g2,n) -> "g_lq_neu(" ^ string_of_sfm m ^ "," ^ string_of_int g1 ^ "," ^ string_of_int g2 ^ "," ^ string_of_neu n ^ ")" | G_LQ_GG (m,g1,g2) -> "g_lq_gg(" ^ string_of_sfm m ^ "," ^ string_of_int g1 ^ "," ^ string_of_int g2 ^ ")" | G_LQ_EC_UC (vc,m,g1,g2,g3) -> conj_symbol(vc,"g_lq_ec_uc") ^ "(" ^ string_of_sfm m ^ "," ^ string_of_int g1 ^ "," ^ string_of_int g2 ^ "," ^ string_of_int g3 ^ ")" | G_LQ_SSU (m1,m2,m3,g1,g2,g3) -> "g_lq_sst(" ^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ "," ^ string_of_sfm m3 ^ "," ^ string_of_int g1 ^ "," ^ string_of_int g2 ^ "," ^ string_of_int g3 ^ ")" | G_LQ_SSD (m1,m2,g1,g2,g3) -> "g_lq_ssta(" ^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ "," ^ string_of_int g1 ^ "," ^ string_of_int g2 ^ "," ^ string_of_int g3 ^ ")" | G_LQ_S (m1,m2,g1,s,g2) -> "g_lq_s(" ^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ "," ^ string_of_int g1 ^ "," ^ string_of_shiggs s ^ "," ^ string_of_int g2 ^ ")" | G_LQ_P (m1,m2,g1,p,g2) -> "g_lq_s(" ^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ "," ^ string_of_int g1 ^ "," ^ string_of_phiggs p ^ "," ^ string_of_int g2 ^ ")" | G_ZLQ (g,m1,m2) -> "g_zlqlq(" ^ string_of_int g ^ "," ^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ ")" | G_ZZLQLQ -> "g_zz_lqlq" | G_ZPLQLQ -> "g_zA_lqlq" | G_PPLQLQ -> "g_AA_lqlq" | G_ZGlLQLQ -> "g_zg_lqlq" | G_PGlLQLQ -> "g_Ag_lqlq" | G_GlGlLQLQ -> "g_gg_lqlq" | G_NLQC -> "g_nlqc" end Index: trunk/omega/src/modellib_SM.ml =================================================================== --- trunk/omega/src/modellib_SM.ml (revision 8413) +++ trunk/omega/src/modellib_SM.ml (revision 8414) @@ -1,2912 +1,2914 @@ (* modellib_SM.ml -- Copyright (C) 1999-2020 by Wolfgang Kilian Thorsten Ohl Juergen Reuter with contributions from Christian Speckner Fabian Bach (only parts of this file) So Young Shim (only parts of this file) WHIZARD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. WHIZARD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *) (* \thocwmodulesection{$\phi^3$} *) module Phi3 = struct open Coupling let options = Options.empty type flavor = Phi let external_flavors () = [ "", [Phi]] let flavors () = ThoList.flatmap snd (external_flavors ()) type gauge = unit type constant = G type orders = unit let orders = function | _ -> () let lorentz _ = Scalar let color _ = Color.Singlet let nc () = 0 let propagator _ = Prop_Scalar let width _ = Timelike let goldstone _ = None let conjugate f = f let fermion _ = 0 module Ch = Charges.Null let charges _ = () module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) let vertices () = ([(Phi, Phi, Phi), Scalar_Scalar_Scalar 1, G], [], []) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 3 let parameters () = { input = [G, 1.0]; derived = []; derived_arrays = [] } let flavor_of_string = function | "p" -> Phi | _ -> invalid_arg "Modellib.Phi3.flavor_of_string" let flavor_to_string Phi = "phi" let flavor_to_TeX Phi = "\\phi" let flavor_symbol Phi = "phi" let gauge_symbol () = failwith "Modellib.Phi3.gauge_symbol: internal error" let pdg _ = 1 let mass_symbol _ = "m" let width_symbol _ = "w" let constant_symbol G = "g" end (* \thocwmodulesection{$\lambda_3\phi^3+\lambda_4\phi^4$} *) module Phi4 = struct open Coupling let options = Options.empty type flavor = Phi let external_flavors () = [ "", [Phi]] let flavors () = ThoList.flatmap snd (external_flavors ()) type gauge = unit type constant = G3 | G4 type orders = unit let orders = function | _ -> () let lorentz _ = Scalar let color _ = Color.Singlet let nc () = 0 let propagator _ = Prop_Scalar let width _ = Timelike let goldstone _ = None let conjugate f = f let fermion _ = 0 module Ch = Charges.Null let charges _ = () module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) let vertices () = ([(Phi, Phi, Phi), Scalar_Scalar_Scalar 1, G3], [(Phi, Phi, Phi, Phi), Scalar4 1, G4], []) let fuse2 _ = failwith "Modellib.Phi4.fuse2" let fuse3 _ = failwith "Modellib.Phi4.fuse3" let fuse = function | [] | [_] -> invalid_arg "Modellib.Phi4.fuse" | [_; _] -> [Phi, V3 (Scalar_Scalar_Scalar 1, F23, G3)] | [_; _; _] -> [Phi, V4 (Scalar4 1, F234, G4)] | _ -> [] let max_degree () = 4 let parameters () = { input = [G3, 1.0; G4, 1.0]; derived = []; derived_arrays = [] } let flavor_of_string = function | "p" -> Phi | _ -> invalid_arg "Modellib.Phi4.flavor_of_string" let flavor_to_string Phi = "phi" let flavor_to_TeX Phi = "\\phi" let flavor_symbol Phi = "phi" let gauge_symbol () = failwith "Modellib.Phi4.gauge_symbol: internal error" let pdg _ = 1 let mass_symbol _ = "m" let width_symbol _ = "w" let constant_symbol = function | G3 -> "g3" | G4 -> "g4" end (* \thocwmodulesection{Quantum Electro Dynamics} *) module QED = struct open Coupling let options = Options.empty type flavor = | Electron | Positron | Muon | AntiMuon | Tau | AntiTau | Photon let external_flavors () = [ "Leptons", [Electron; Positron; Muon; AntiMuon; Tau; AntiTau]; "Gauge Bosons", [Photon] ] let flavors () = ThoList.flatmap snd (external_flavors ()) type gauge = unit type constant = Q type orders = unit let orders = function | _ -> () let lorentz = function | Electron | Muon | Tau -> Spinor | Positron | AntiMuon | AntiTau -> ConjSpinor | Photon -> Vector let color _ = Color.Singlet let nc () = 0 let propagator = function | Electron | Muon | Tau -> Prop_Spinor | Positron | AntiMuon | AntiTau -> Prop_ConjSpinor | Photon -> Prop_Feynman let width _ = Timelike let goldstone _ = None let conjugate = function | Electron -> Positron | Positron -> Electron | Muon -> AntiMuon | AntiMuon -> Muon | Tau -> AntiTau | AntiTau -> Tau | Photon -> Photon let fermion = function | Electron | Muon | Tau -> 1 | Positron | AntiMuon | AntiTau -> -1 | Photon -> 0 (* Taking generation numbers makes electric charge redundant. *) module Ch = Charges.ZZ let charges = function | Electron -> [1; 0; 0] | Muon -> [0; 1; 0] | Tau -> [0; 0; 1] | Positron -> [-1;0; 0] | AntiMuon -> [0;-1; 0] | AntiTau -> [0; 0;-1] | Photon -> [0; 0; 0] module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) let vertices () = ([(Positron, Photon, Electron), FBF (1, Psibar, V, Psi), Q; (AntiMuon, Photon, Muon), FBF (1, Psibar, V, Psi), Q; (AntiTau, Photon, Tau), FBF (1, Psibar, V, Psi), Q], [], []) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 3 let parameters () = { input = [Q, 1.0]; derived = []; derived_arrays = [] } let flavor_of_string = function | "e-" -> Electron | "e+" -> Positron | "m-" -> Muon | "m+" -> AntiMuon | "t-" -> Tau | "t+" -> AntiTau | "A" -> Photon | _ -> invalid_arg "Modellib.QED.flavor_of_string" let flavor_to_string = function | Electron -> "e-" | Positron -> "e+" | Muon -> "m-" | AntiMuon -> "m+" | Tau -> "t-" | AntiTau -> "t+" | Photon -> "A" let flavor_to_TeX = function | Electron -> "e^-" | Positron -> "e^+" | Muon -> "\\mu^-" | AntiMuon -> "\\mu^+" | Tau -> "^\\tau^-" | AntiTau -> "\\tau+^" | Photon -> "\\gamma" let flavor_symbol = function | Electron -> "ele" | Positron -> "pos" | Muon -> "muo" | AntiMuon -> "amu" | Tau -> "tau" | AntiTau -> "ata" | Photon -> "gam" let gauge_symbol () = failwith "Modellib.QED.gauge_symbol: internal error" let pdg = function | Electron -> 11 | Positron -> -11 | Muon -> 13 | AntiMuon -> -13 | Tau -> 15 | AntiTau -> -15 | Photon -> 22 let mass_symbol f = "mass(" ^ string_of_int (abs (pdg f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg f)) ^ ")" let constant_symbol = function | Q -> "qlep" end (* \thocwmodulesection{Quantum Chromo Dynamics} *) module QCD = struct open Coupling let options = Options.empty type flavor = | U | Ubar | D | Dbar | C | Cbar | S | Sbar | T | Tbar | B | Bbar | Gl let external_flavors () = [ "Quarks", [U; D; C; S; T; B; Ubar; Dbar; Cbar; Sbar; Tbar; Bbar]; "Gauge Bosons", [Gl]] let flavors () = ThoList.flatmap snd (external_flavors ()) type gauge = unit type constant = Gs | G2 | I_Gs type orders = unit let orders = function | _ -> () let lorentz = function | U | D | C | S | T | B -> Spinor | Ubar | Dbar | Cbar | Sbar | Tbar | Bbar -> ConjSpinor | Gl -> Vector let color = function | U | D | C | S | T | B -> Color.SUN 3 | Ubar | Dbar | Cbar | Sbar | Tbar | Bbar -> Color.SUN (-3) | Gl -> Color.AdjSUN 3 let nc () = 3 let propagator = function | U | D | C | S | T | B -> Prop_Spinor | Ubar | Dbar | Cbar | Sbar | Tbar | Bbar -> Prop_ConjSpinor | Gl -> Prop_Feynman let width _ = Timelike let goldstone _ = None let conjugate = function | U -> Ubar | D -> Dbar | C -> Cbar | S -> Sbar | T -> Tbar | B -> Bbar | Ubar -> U | Dbar -> D | Cbar -> C | Sbar -> S | Tbar -> T | Bbar -> B | Gl -> Gl let fermion = function | U | D | C | S | T | B -> 1 | Ubar | Dbar | Cbar | Sbar | Tbar | Bbar -> -1 | Gl -> 0 module Ch = Charges.ZZ let charges = function | D -> [1; 0; 0; 0; 0; 0] | U -> [0; 1; 0; 0; 0; 0] | S -> [0; 0; 1; 0; 0; 0] | C -> [0; 0; 0; 1; 0; 0] | B -> [0; 0; 0; 0; 1; 0] | T -> [0; 0; 0; 0; 0; 1] | Dbar -> [-1; 0; 0; 0; 0; 0] | Ubar -> [0; -1; 0; 0; 0; 0] | Sbar -> [0; 0; -1; 0; 0; 0] | Cbar -> [0; 0; 0; -1; 0; 0] | Bbar -> [0; 0; 0; 0; -1; 0] | Tbar -> [0; 0; 0; 0; 0; -1] | Gl -> [0; 0; 0; 0; 0; 0] module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) (* This is compatible with CD+. *) let color_current = [ ((Dbar, Gl, D), FBF ((-1), Psibar, V, Psi), Gs); ((Ubar, Gl, U), FBF ((-1), Psibar, V, Psi), Gs); ((Cbar, Gl, C), FBF ((-1), Psibar, V, Psi), Gs); ((Sbar, Gl, S), FBF ((-1), Psibar, V, Psi), Gs); ((Tbar, Gl, T), FBF ((-1), Psibar, V, Psi), Gs); ((Bbar, Gl, B), FBF ((-1), Psibar, V, Psi), Gs)] let three_gluon = [ ((Gl, Gl, Gl), Gauge_Gauge_Gauge 1, I_Gs)] let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let four_gluon = [ ((Gl, Gl, Gl, Gl), gauge4, G2)] let vertices3 = (color_current @ three_gluon) let vertices4 = four_gluon let vertices () = (vertices3, vertices4, []) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 let parameters () = { input = [Gs, 1.0]; derived = []; derived_arrays = [] } let flavor_of_string = function | "u" -> U | "d" -> D | "c" -> C | "s" -> S | "t" -> T | "b" -> B | "ubar" -> Ubar | "dbar" -> Dbar | "cbar" -> Cbar | "sbar" -> Sbar | "tbar" -> Tbar | "bbar" -> Bbar | "gl" -> Gl | _ -> invalid_arg "Modellib.QCD.flavor_of_string" let flavor_to_string = function | U -> "u" | Ubar -> "ubar" | D -> "d" | Dbar -> "dbar" | C -> "c" | Cbar -> "cbar" | S -> "s" | Sbar -> "sbar" | T -> "t" | Tbar -> "tbar" | B -> "b" | Bbar -> "bbar" | Gl -> "gl" let flavor_to_TeX = function | U -> "u" | Ubar -> "\\bar{u}" | D -> "d" | Dbar -> "\\bar{d}" | C -> "c" | Cbar -> "\\bar{c}" | S -> "s" | Sbar -> "\\bar{s}" | T -> "t" | Tbar -> "\\bar{t}" | B -> "b" | Bbar -> "\\bar{b}" | Gl -> "g" let flavor_symbol = function | U -> "u" | Ubar -> "ubar" | D -> "d" | Dbar -> "dbar" | C -> "c" | Cbar -> "cbar" | S -> "s" | Sbar -> "sbar" | T -> "t" | Tbar -> "tbar" | B -> "b" | Bbar -> "bbar" | Gl -> "gl" let gauge_symbol () = failwith "Modellib.QCD.gauge_symbol: internal error" let pdg = function | D -> 1 | Dbar -> -1 | U -> 2 | Ubar -> -2 | S -> 3 | Sbar -> -3 | C -> 4 | Cbar -> -4 | B -> 5 | Bbar -> -5 | T -> 6 | Tbar -> -6 | Gl -> 21 let mass_symbol f = "mass(" ^ string_of_int (abs (pdg f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg f)) ^ ")" let constant_symbol = function | I_Gs -> "(0,1)*gs" | Gs -> "gs" | G2 -> "gs**2" end (* \thocwmodulesection{Complete Minimal Standard Model (Unitarity Gauge)} *) module type SM_flags = sig val higgs_triangle : bool (* $H\gamma\gamma$, $Hg\gamma$ and $Hgg$ couplings *) val higgs_hmm : bool (* $H\mu^+\mu^-$ and $He^+e^-$ couplings *) val triple_anom : bool val quartic_anom : bool val higgs_anom : bool val dim6 : bool val k_matrix : bool val ckm_present : bool val top_anom : bool val top_anom_4f : bool val tt_threshold : bool end module SM_no_anomalous : SM_flags = struct let higgs_triangle = false let higgs_hmm = false let triple_anom = false let quartic_anom = false let higgs_anom = false let dim6 = false let k_matrix = false let ckm_present = false let top_anom = false let top_anom_4f = false let tt_threshold = false end module SM_no_anomalous_ckm : SM_flags = struct let higgs_triangle = false let higgs_hmm = false let triple_anom = false let quartic_anom = false let higgs_anom = false let dim6 = false let k_matrix = false let ckm_present = true let top_anom = false let top_anom_4f = false let tt_threshold = false end module SM_anomalous : SM_flags = struct let higgs_triangle = false let higgs_hmm = false let triple_anom = true let quartic_anom = true let higgs_anom = true let dim6 = false let k_matrix = false let ckm_present = false let top_anom = false let top_anom_4f = false let tt_threshold = false end module SM_anomalous_ckm : SM_flags = struct let higgs_triangle = false let higgs_hmm = false let triple_anom = true let quartic_anom = true let higgs_anom = true let dim6 = false let k_matrix = false let ckm_present = true let top_anom = false let top_anom_4f = false let tt_threshold = false end module SM_k_matrix : SM_flags = struct let higgs_triangle = false let higgs_hmm = false let triple_anom = false let quartic_anom = true let higgs_anom = false let dim6 = false let k_matrix = true let ckm_present = false let top_anom = false let top_anom_4f = false let tt_threshold = false end module SM_Higgs : SM_flags = struct let higgs_triangle = true let higgs_hmm = true let triple_anom = false let quartic_anom = false let higgs_anom = false let dim6 = false let k_matrix = false let ckm_present = false let top_anom = false let top_anom_4f = false let tt_threshold = false end module SM_Higgs_CKM : SM_flags = struct let higgs_triangle = true let higgs_hmm = true let triple_anom = false let quartic_anom = false let higgs_anom = false let dim6 = false let k_matrix = false let ckm_present = true let top_anom = false let top_anom_4f = false let tt_threshold = false end module SM_anomalous_top : SM_flags = struct let higgs_triangle = false let higgs_hmm = false let triple_anom = false let quartic_anom = false let higgs_anom = false let dim6 = false let k_matrix = false let ckm_present = false let top_anom = true let top_anom_4f = true let tt_threshold = false end module SM_tt_threshold : SM_flags = struct let higgs_triangle = false let higgs_hmm = false let triple_anom = false let quartic_anom = false let higgs_anom = false let dim6 = false let k_matrix = false let ckm_present = true let top_anom = false let top_anom_4f = false let tt_threshold = true end module SM_dim6 : SM_flags = struct let higgs_triangle = false let higgs_hmm = false let triple_anom = false let quartic_anom = false let higgs_anom = false let dim6 = true let k_matrix = false let ckm_present = false let top_anom = false let top_anom_4f = false let tt_threshold = false end (* \thocwmodulesection{Complete Minimal Standard Model (including some extensions)} *) module SM (Flags : SM_flags) = struct open Coupling let default_width = ref Timelike let use_fudged_width = ref false let options = Options.create [ "constant_width", Arg.Unit (fun () -> default_width := Constant), "use constant width (also in t-channel)"; "fudged_width", Arg.Set use_fudged_width, "use fudge factor for charge particle width"; "custom_width", Arg.String (fun f -> default_width := Custom f), "use custom width"; "cancel_widths", Arg.Unit (fun () -> default_width := Vanishing), "use vanishing width"; "cms_width", Arg.Unit (fun () -> default_width := Complex_Mass), - "use complex mass scheme" ] + "use complex mass scheme"; + "running_width", Arg.Unit (fun () -> default_width := Running), + "use running width" ] type f_aux_top = TTGG | TBWA | TBWZ | TTWW | BBWW | TCGG | TUGG (*i top auxiliary field "flavors" i*) | QGUG | QBUB | QW | DL | DR | QUQD1L | QUQD1R | QUQD8L | QUQD8R type matter_field = L of int | N of int | U of int | D of int type gauge_boson = Ga | Wp | Wm | Z | Gl type other = Phip | Phim | Phi0 | H | Aux_top of int*int*int*bool*f_aux_top (*i lorentz*color*charge*top-side*flavor i*) type flavor = M of matter_field | G of gauge_boson | O of other let matter_field f = M f let gauge_boson f = G f let other f = O f type field = | Matter of matter_field | Gauge of gauge_boson | Other of other let field = function | M f -> Matter f | G f -> Gauge f | O f -> Other f type gauge = unit let gauge_symbol () = failwith "Modellib.SM.gauge_symbol: internal error" let family n = List.map matter_field [ L n; N n; U n; D n ] let rec aux_top_flavors (f,l,co,ch) = List.append ( List.map other [ Aux_top (l,co,ch/2,true,f); Aux_top (l,co,ch/2,false,f) ] ) ( if ch > 1 then List.append ( List.map other [ Aux_top (l,co,-ch/2,true,f); Aux_top (l,co,-ch/2,false,f) ] ) ( aux_top_flavors (f,l,co,(ch-2)) ) else [] ) let external_flavors () = [ "1st Generation", ThoList.flatmap family [1; -1]; "2nd Generation", ThoList.flatmap family [2; -2]; "3rd Generation", ThoList.flatmap family [3; -3]; "Gauge Bosons", List.map gauge_boson [Ga; Z; Wp; Wm; Gl]; "Higgs", List.map other [H]; "Goldstone Bosons", List.map other [Phip; Phim; Phi0] ] let flavors () = List.append ( ThoList.flatmap snd (external_flavors ()) ) ( ThoList.flatmap aux_top_flavors [ (TTGG,2,1,1); (TCGG,2,1,1); (TUGG,2,1,1); (TBWA,2,0,2); (TBWZ,2,0,2); (TTWW,2,0,1); (BBWW,2,0,1); (QGUG,1,1,1); (QBUB,1,0,1); (QW,1,0,3); (DL,0,0,3); (DR,0,0,3); (QUQD1L,0,0,3); (QUQD1R,0,0,3); (QUQD8L,0,1,3); (QUQD8R,0,1,3) ] ) let spinor n = if n >= 0 then Spinor else ConjSpinor let lorentz_aux = function | 2 -> Tensor_1 | 1 -> Vector | 0 -> Scalar | _ -> invalid_arg ("SM.lorentz_aux: wrong value") let lorentz = function | M f -> begin match f with | L n -> spinor n | N n -> spinor n | U n -> spinor n | D n -> spinor n end | G f -> begin match f with | Ga | Gl -> Vector | Wp | Wm | Z -> Massive_Vector end | O f -> begin match f with | Aux_top (l,_,_,_,_) -> lorentz_aux l | _ -> Scalar end let color = function | M (U n) -> Color.SUN (if n > 0 then 3 else -3) | M (D n) -> Color.SUN (if n > 0 then 3 else -3) | G Gl -> Color.AdjSUN 3 | O (Aux_top (_,co,_,_,_)) -> if co == 0 then Color.Singlet else Color.AdjSUN 3 | _ -> Color.Singlet let nc () = 3 let prop_spinor n = if n >= 0 then Prop_Spinor else Prop_ConjSpinor let prop_aux = function | 2 -> Aux_Tensor_1 | 1 -> Aux_Vector | 0 -> Aux_Scalar | _ -> invalid_arg ("SM.prop_aux: wrong value") let propagator = function | M f -> begin match f with | L n -> prop_spinor n | N n -> prop_spinor n | U n -> prop_spinor n | D n -> prop_spinor n end | G f -> begin match f with | Ga | Gl -> Prop_Feynman | Wp | Wm | Z -> Prop_Unitarity end | O f -> begin match f with | Phip | Phim | Phi0 -> Only_Insertion | H -> Prop_Scalar | Aux_top (l,_,_,_,_) -> prop_aux l end (* Optionally, ask for the fudge factor treatment for the widths of charged particles. Currently, this only applies to $W^\pm$ and top. *) let width f = if !use_fudged_width then match f with | G Wp | G Wm | M (U 3) | M (U (-3)) -> Fudged | _ -> !default_width else !default_width let goldstone = function | G f -> begin match f with | Wp -> Some (O Phip, Coupling.Integer 1) | Wm -> Some (O Phim, Coupling.Integer 1) | Z -> Some (O Phi0, Coupling.Integer 1) | _ -> None end | _ -> None let conjugate = function | M f -> M (begin match f with | L n -> L (-n) | N n -> N (-n) | U n -> U (-n) | D n -> D (-n) end) | G f -> G (begin match f with | Gl -> Gl | Ga -> Ga | Z -> Z | Wp -> Wm | Wm -> Wp end) | O f -> O (begin match f with | Phip -> Phim | Phim -> Phip | Phi0 -> Phi0 | H -> H | Aux_top (l,co,ch,n,f) -> Aux_top (l,co,(-ch),(not n),f) end) let fermion = function | M f -> begin match f with | L n -> if n > 0 then 1 else -1 | N n -> if n > 0 then 1 else -1 | U n -> if n > 0 then 1 else -1 | D n -> if n > 0 then 1 else -1 end | G f -> begin match f with | Gl | Ga | Z | Wp | Wm -> 0 end | O _ -> 0 (* Electrical charge, lepton number, baryon number. We could avoid the rationals altogether by multiplying the first and last by 3 \ldots *) module Ch = Charges.QQ let ( // ) = Algebra.Small_Rational.make let generation' = function | 1 -> [ 1//1; 0//1; 0//1] | 2 -> [ 0//1; 1//1; 0//1] | 3 -> [ 0//1; 0//1; 1//1] | -1 -> [-1//1; 0//1; 0//1] | -2 -> [ 0//1; -1//1; 0//1] | -3 -> [ 0//1; 0//1; -1//1] | n -> invalid_arg ("SM.generation': " ^ string_of_int n) (* Generation is not a good quantum number for models with flavor mixing, i.e. if CKM mixing is present. Also, for the FCNC vertices implemented in the SM variant with anomalous top couplings it is not a valid symmetry. *) let generation f = if (Flags.ckm_present || Flags.top_anom) then [] else match f with | M (L n | N n | U n | D n) -> generation' n | G _ | O _ -> [0//1; 0//1; 0//1] let charge = function | M f -> begin match f with | L n -> if n > 0 then -1//1 else 1//1 | N n -> 0//1 | U n -> if n > 0 then 2//3 else -2//3 | D n -> if n > 0 then -1//3 else 1//3 end | G f -> begin match f with | Gl | Ga | Z -> 0//1 | Wp -> 1//1 | Wm -> -1//1 end | O f -> begin match f with | H | Phi0 -> 0//1 | Phip -> 1//1 | Phim -> -1//1 | Aux_top (_,_,ch,_,_) -> ch//1 end let lepton = function | M f -> begin match f with | L n | N n -> if n > 0 then 1//1 else -1//1 | U _ | D _ -> 0//1 end | G _ | O _ -> 0//1 let baryon = function | M f -> begin match f with | L _ | N _ -> 0//1 | U n | D n -> if n > 0 then 1//1 else -1//1 end | G _ | O _ -> 0//1 let charges f = [ charge f; lepton f; baryon f] @ generation f type constant = | Unit | Half | Pi | Alpha_QED | Sin2thw | Sinthw | Costhw | E | G_weak | I_G_weak | Vev | Q_lepton | Q_up | Q_down | G_CC | G_CCQ of int*int | G_NC_neutrino | G_NC_lepton | G_NC_up | G_NC_down | G_TVA_ttA | G_TVA_bbA | G_TVA_tuA | G_TVA_tcA | G_TVA_tcZ | G_TVA_tuZ | G_TVA_bbZ | G_VLR_ttZ | G_TVA_ttZ | G_VLR_tcZ | G_VLR_tuZ | VA_ILC_ttA | VA_ILC_ttZ | G_VLR_btW | G_VLR_tbW | G_TLR_btW | G_TRL_tbW | G_TLR_btWZ | G_TRL_tbWZ | G_TLR_btWA | G_TRL_tbWA | G_TVA_ttWW | G_TVA_bbWW | G_TVA_ttG | G_TVA_ttGG | G_TVA_tcG | G_TVA_tcGG | G_TVA_tuG | G_TVA_tuGG | G_SP_ttH | G_VLR_qGuG | G_VLR_qBuB | G_VLR_qBuB_u | G_VLR_qBuB_d | G_VLR_qBuB_e | G_VL_qBuB_n | G_VL_qW | G_VL_qW_u | G_VL_qW_d | G_SL_DttR | G_SR_DttR | G_SL_DttL | G_SLR_DbtR | G_SL_DbtL | C_quqd1R_bt | C_quqd1R_tb | C_quqd1L_bt | C_quqd1L_tb | C_quqd8R_bt | C_quqd8R_tb | C_quqd8L_bt | C_quqd8L_tb | I_Q_W | I_G_ZWW | G_WWWW | G_ZZWW | G_AZWW | G_AAWW | I_G1_AWW | I_G1_ZWW | I_G1_plus_kappa_plus_G4_AWW | I_G1_plus_kappa_plus_G4_ZWW | I_G1_plus_kappa_minus_G4_AWW | I_G1_plus_kappa_minus_G4_ZWW | I_G1_minus_kappa_plus_G4_AWW | I_G1_minus_kappa_plus_G4_ZWW | I_G1_minus_kappa_minus_G4_AWW | I_G1_minus_kappa_minus_G4_ZWW | I_lambda_AWW | I_lambda_ZWW | G5_AWW | G5_ZWW | I_kappa5_AWW | I_kappa5_ZWW | I_lambda5_AWW | I_lambda5_ZWW | Alpha_WWWW0 | Alpha_ZZWW1 | Alpha_WWWW2 | Alpha_ZZWW0 | Alpha_ZZZZ | D_Alpha_ZZWW0_S | D_Alpha_ZZWW0_T | D_Alpha_ZZWW1_S | D_Alpha_ZZWW1_T | D_Alpha_ZZWW1_U | D_Alpha_WWWW0_S | D_Alpha_WWWW0_T | D_Alpha_WWWW0_U | D_Alpha_WWWW2_S | D_Alpha_WWWW2_T | D_Alpha_ZZZZ_S | D_Alpha_ZZZZ_T | G_HWW | G_HHWW | G_HZZ | G_HHZZ | G_Htt | G_Hbb | G_Hcc | G_Hss | G_Hmm | G_Hee | G_Htautau | G_H3 | G_H4 | G_HGaZ | G_HGaGa | G_Hgg | G_HGaZ_anom | G_HGaGa_anom | G_HZZ_anom | G_HWW_anom | G_HGaZ_u | G_HZZ_u | G_HWW_u | Gs | I_Gs | G2 | Mass of flavor | Width of flavor | K_Matrix_Coeff of int | K_Matrix_Pole of int | I_Dim6_AWW_Gauge | I_Dim6_AWW_GGG | I_Dim6_AWW_DP | I_Dim6_AWW_DW | I_Dim6_WWZ_W | I_Dim6_WWZ_DPWDW | I_Dim6_WWZ_DW | I_Dim6_WWZ_D (*i | I_Dim6_GGG_G | I_Dim6_GGG_CG i*) | G_HZZ6_V3 | G_HZZ6_D | G_HZZ6_DP | G_HZZ6_PB | G_HWW_6_D | G_HWW_6_DP | G_HGaZ6_D | G_HGaZ6_DP | G_HGaZ6_PB | G_HGaGa6 | Dim6_vev3 | Dim6_Cphi | Anom_Dim6_AAWW_DW | Anom_Dim6_AAWW_W | Anom_Dim6_H4_v2 | Anom_Dim6_H4_P2 | Anom_Dim6_AHWW_DPB | Anom_Dim6_AHWW_DPW | Anom_Dim6_AHWW_DW | Anom_Dim6_HHWW_DW | Anom_Dim6_HHWW_DPW | Anom_Dim6_HWWZ_DW | Anom_Dim6_HWWZ_DDPW | Anom_Dim6_HWWZ_DPW | Anom_Dim6_HWWZ_DPB | Anom_Dim6_AHHZ_D | Anom_Dim6_AHHZ_DP | Anom_Dim6_AHHZ_PB | Anom_Dim6_AZWW_W | Anom_Dim6_AZWW_DWDPW | Anom_Dim6_WWWW_W | Anom_Dim6_WWWW_DWDPW | Anom_Dim6_WWZZ_W | Anom_Dim6_WWZZ_DWDPW | Anom_Dim6_HHAA | Anom_Dim6_HHZZ_D | Anom_Dim6_HHZZ_DP | Anom_Dim6_HHZZ_PB | Anom_Dim6_HHZZ_T (* Two integer counters for the QCD and EW order of the couplings. *) type orders = int * int let orders = function | Q_lepton | Q_up | Q_down | G_NC_lepton | G_NC_neutrino | G_NC_up | G_NC_down | G_CC | G_CCQ _ | G_Htt | G_H3 | G_Hbb | G_Hcc | G_Hss | G_Htautau | G_Hmm | G_Hee | I_Q_W | I_G_ZWW | I_G1_AWW | I_G1_ZWW | I_G_weak | G_HWW | G_HZZ | G_HWW_u | G_HZZ_u | G_HGaZ_u | G_HWW_anom | G_HZZ_anom | G_HGaZ | G_HGaGa | G_HGaZ_anom | G_HGaGa_anom | Half | Unit | I_G1_plus_kappa_plus_G4_AWW | I_G1_plus_kappa_plus_G4_ZWW | I_G1_minus_kappa_plus_G4_AWW | I_G1_minus_kappa_plus_G4_ZWW | I_G1_plus_kappa_minus_G4_AWW | I_G1_plus_kappa_minus_G4_ZWW | I_G1_minus_kappa_minus_G4_AWW | I_G1_minus_kappa_minus_G4_ZWW | I_kappa5_AWW | I_kappa5_ZWW | G5_AWW | G5_ZWW | I_lambda_AWW | I_lambda_ZWW | I_lambda5_AWW | I_lambda5_ZWW | G_TVA_ttA | G_TVA_bbA | G_TVA_tcA | G_TVA_tuA | G_VLR_ttZ | G_TVA_ttZ | G_VLR_tcZ | G_TVA_tcZ | G_TVA_bbZ | VA_ILC_ttA | VA_ILC_ttZ | G_VLR_tuZ | G_TVA_tuZ | G_VLR_btW | G_VLR_tbW | G_TLR_btW | G_TRL_tbW | G_TLR_btWA | G_TRL_tbWA | G_TLR_btWZ | G_TRL_tbWZ | G_VLR_qBuB | G_VLR_qBuB_u | G_VLR_qBuB_d | G_VLR_qBuB_e | G_VL_qBuB_n | G_VL_qW | G_VL_qW_u | G_VL_qW_d | G_SL_DttR | G_SR_DttR | G_SL_DttL | G_SLR_DbtR | G_SL_DbtL | G_HZZ6_V3 | G_HZZ6_D | G_HZZ6_DP | G_HZZ6_PB | G_HGaZ6_D | G_HGaZ6_DP | G_HGaZ6_PB | G_HWW_6_D | G_HWW_6_DP | G_HGaGa6 | I_Dim6_AWW_Gauge | I_Dim6_AWW_GGG | I_Dim6_AWW_DP | I_Dim6_AWW_DW | I_Dim6_WWZ_W | I_Dim6_WWZ_DPWDW | I_Dim6_WWZ_DW | I_Dim6_WWZ_D (*i | I_Dim6_GGG_G | I_Dim6_GGG_CG i*) | Dim6_vev3 | Dim6_Cphi | Anom_Dim6_H4_v2 | Anom_Dim6_H4_P2 | Anom_Dim6_AAWW_DW | Anom_Dim6_AAWW_W | Anom_Dim6_AHWW_DPB | Anom_Dim6_AHWW_DPW | Anom_Dim6_AHWW_DW | Anom_Dim6_HHWW_DW | Anom_Dim6_HHWW_DPW | Anom_Dim6_HWWZ_DW | Anom_Dim6_HWWZ_DDPW | Anom_Dim6_HWWZ_DPW | Anom_Dim6_HWWZ_DPB | Anom_Dim6_AHHZ_D | Anom_Dim6_AHHZ_DP | Anom_Dim6_AHHZ_PB | Anom_Dim6_AZWW_W | Anom_Dim6_AZWW_DWDPW | Anom_Dim6_WWWW_W | Anom_Dim6_WWWW_DWDPW | Anom_Dim6_WWZZ_W | Anom_Dim6_WWZZ_DWDPW | Anom_Dim6_HHAA | Anom_Dim6_HHZZ_D | Anom_Dim6_HHZZ_DP | Anom_Dim6_HHZZ_PB | Anom_Dim6_HHZZ_T | G_TVA_ttWW | G_TVA_bbWW | G_SP_ttH -> (0,1) | G_HHWW | G_HHZZ | G_H4 | G_WWWW | G_ZZWW | G_AZWW | G_AAWW | Alpha_WWWW0 | Alpha_WWWW2 | Alpha_ZZWW0 | Alpha_ZZWW1 | Alpha_ZZZZ | D_Alpha_WWWW0_S | D_Alpha_WWWW0_T | D_Alpha_WWWW0_U | D_Alpha_WWWW2_S | D_Alpha_WWWW2_T | D_Alpha_ZZWW0_S | D_Alpha_ZZWW0_T | D_Alpha_ZZWW1_S | D_Alpha_ZZWW1_T | D_Alpha_ZZWW1_U | D_Alpha_ZZZZ_S | D_Alpha_ZZZZ_T -> (0,2) | Gs | I_Gs | G_TVA_ttG | G_TVA_ttGG | G_TVA_tcG | G_TVA_tcGG | G_TVA_tuG | G_TVA_tuGG | G_VLR_qGuG | C_quqd1R_bt | C_quqd1R_tb | C_quqd1L_bt | C_quqd1L_tb | C_quqd8R_bt | C_quqd8R_tb | C_quqd8L_bt | C_quqd8L_tb -> (1,0) | G2 | G_Hgg -> (2,0) (* These constants are not used, hence initialized to zero. *) | Sinthw | Sin2thw | Costhw | Pi | Alpha_QED | G_weak | K_Matrix_Coeff _ | K_Matrix_Pole _ | Mass _ | Width _ | Vev | E -> (0,0) (* \begin{dubious} The current abstract syntax for parameter dependencies is admittedly tedious. Later, there will be a parser for a convenient concrete syntax as a part of a concrete syntax for models. But as these examples show, it should include simple functions. \end{dubious} *) (* \begin{subequations} \begin{align} \alpha_{\text{QED}} &= \frac{1}{137.0359895} \\ \sin^2\theta_w &= 0.23124 \end{align} \end{subequations} *) let input_parameters = [ Alpha_QED, 1. /. 137.0359895; Sin2thw, 0.23124; Mass (G Z), 91.187; Mass (M (N 1)), 0.0; Mass (M (L 1)), 0.51099907e-3; Mass (M (N 2)), 0.0; Mass (M (L 2)), 0.105658389; Mass (M (N 3)), 0.0; Mass (M (L 3)), 1.77705; Mass (M (U 1)), 5.0e-3; Mass (M (D 1)), 3.0e-3; Mass (M (U 2)), 1.2; Mass (M (D 2)), 0.1; Mass (M (U 3)), 174.0; Mass (M (D 3)), 4.2 ] (* \begin{subequations} \begin{align} e &= \sqrt{4\pi\alpha} \\ \sin\theta_w &= \sqrt{\sin^2\theta_w} \\ \cos\theta_w &= \sqrt{1-\sin^2\theta_w} \\ g &= \frac{e}{\sin\theta_w} \\ m_W &= \cos\theta_w m_Z \\ v &= \frac{2m_W}{g} \\ g_{CC} = -\frac{g}{2\sqrt2} &= -\frac{e}{2\sqrt2\sin\theta_w} \\ Q_{\text{lepton}} = -q_{\text{lepton}}e &= e \\ Q_{\text{up}} = -q_{\text{up}}e &= -\frac{2}{3}e \\ Q_{\text{down}} = -q_{\text{down}}e &= \frac{1}{3}e \\ \ii q_We = \ii g_{\gamma WW} &= \ii e \\ \ii g_{ZWW} &= \ii g \cos\theta_w \\ \ii g_{WWW} &= \ii g \end{align} \end{subequations} *) (* \begin{dubious} \ldots{} to be continued \ldots{} The quartic couplings can't be correct, because the dimensions are wrong! \begin{subequations} \begin{align} g_{HWW} &= g m_W = 2 \frac{m_W^2}{v}\\ g_{HHWW} &= 2 \frac{m_W^2}{v^2} = \frac{g^2}{2} \\ g_{HZZ} &= \frac{g}{\cos\theta_w}m_Z \\ g_{HHZZ} &= 2 \frac{m_Z^2}{v^2} = \frac{g^2}{2\cos\theta_w} \\ g_{Htt} &= \lambda_t \\ g_{Hbb} &= \lambda_b=\frac{m_b}{m_t}\lambda_t \\ g_{H^3} &= - \frac{3g}{2}\frac{m_H^2}{m_W} = - 3 \frac{m_H^2}{v} g_{H^4} &= - \frac{3g^2}{4} \frac{m_W^2}{v^2} = -3 \frac{m_H^2}{v^2} \end{align} \end{subequations} \end{dubious} *) let derived_parameters = [ Real E, Sqrt (Prod [Integer 4; Atom Pi; Atom Alpha_QED]); Real Sinthw, Sqrt (Atom Sin2thw); Real Costhw, Sqrt (Diff (Integer 1, Atom Sin2thw)); Real G_weak, Quot (Atom E, Atom Sinthw); Real (Mass (G Wp)), Prod [Atom Costhw; Atom (Mass (G Z))]; Real Vev, Quot (Prod [Integer 2; Atom (Mass (G Wp))], Atom G_weak); Real Q_lepton, Atom E; Real Q_up, Prod [Quot (Integer (-2), Integer 3); Atom E]; Real Q_down, Prod [Quot (Integer 1, Integer 3); Atom E]; Real G_CC, Neg (Quot (Atom G_weak, Prod [Integer 2; Sqrt (Integer 2)])); Complex I_Q_W, Prod [I; Atom E]; Complex I_G_weak, Prod [I; Atom G_weak]; Complex I_G_ZWW, Prod [I; Atom G_weak; Atom Costhw] ] (* \begin{equation} - \frac{g}{2\cos\theta_w} \end{equation} *) let g_over_2_costh = Quot (Neg (Atom G_weak), Prod [Integer 2; Atom Costhw]) (* \begin{subequations} \begin{align} - \frac{g}{2\cos\theta_w} g_V &= - \frac{g}{2\cos\theta_w} (T_3 - 2 q \sin^2\theta_w) \\ - \frac{g}{2\cos\theta_w} g_A &= - \frac{g}{2\cos\theta_w} T_3 \end{align} \end{subequations} *) let nc_coupling c t3 q = (Real_Array c, [Prod [g_over_2_costh; Diff (t3, Prod [Integer 2; q; Atom Sin2thw])]; Prod [g_over_2_costh; t3]]) let half = Quot (Integer 1, Integer 2) let derived_parameter_arrays = [ nc_coupling G_NC_neutrino half (Integer 0); nc_coupling G_NC_lepton (Neg half) (Integer (-1)); nc_coupling G_NC_up half (Quot (Integer 2, Integer 3)); nc_coupling G_NC_down (Neg half) (Quot (Integer (-1), Integer 3)) ] let parameters () = { input = input_parameters; derived = derived_parameters; derived_arrays = derived_parameter_arrays } module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) (* \begin{equation} \mathcal{L}_{\textrm{EM}} = - e \sum_i q_i \bar\psi_i\fmslash{A}\psi_i \end{equation} *) let mgm ((m1, g, m2), fbf, c) = ((M m1, G g, M m2), fbf, c) let mom ((m1, o, m2), fbf, c) = ((M m1, O o, M m2), fbf, c) let electromagnetic_currents n = List.map mgm [ ((L (-n), Ga, L n), FBF (1, Psibar, V, Psi), Q_lepton); ((U (-n), Ga, U n), FBF (1, Psibar, V, Psi), Q_up); ((D (-n), Ga, D n), FBF (1, Psibar, V, Psi), Q_down) ] let color_currents n = List.map mgm [ ((U (-n), Gl, U n), FBF ((-1), Psibar, V, Psi), Gs); ((D (-n), Gl, D n), FBF ((-1), Psibar, V, Psi), Gs) ] (* \begin{equation} \mathcal{L}_{\textrm{NC}} = - \frac{g}{2\cos\theta_W} \sum_i \bar\psi_i\fmslash{Z}(g_V^i-g_A^i\gamma_5)\psi_i \end{equation} *) let neutral_currents n = List.map mgm [ ((L (-n), Z, L n), FBF (1, Psibar, VA, Psi), G_NC_lepton); ((N (-n), Z, N n), FBF (1, Psibar, VA, Psi), G_NC_neutrino); ((U (-n), Z, U n), FBF (1, Psibar, VA, Psi), G_NC_up); ((D (-n), Z, D n), FBF (1, Psibar, VA, Psi), G_NC_down) ] (* \begin{equation} \mathcal{L}_{\textrm{CC}} = - \frac{g}{2\sqrt2} \sum_i \bar\psi_i (T^+\fmslash{W}^+ + T^-\fmslash{W}^-)(1-\gamma_5)\psi_i \end{equation} *) let charged_currents' n = List.map mgm [ ((L (-n), Wm, N n), FBF (1, Psibar, VL, Psi), G_CC); ((N (-n), Wp, L n), FBF (1, Psibar, VL, Psi), G_CC) ] let charged_currents'' n = List.map mgm [ ((D (-n), Wm, U n), FBF (1, Psibar, VL, Psi), G_CC); ((U (-n), Wp, D n), FBF (1, Psibar, VL, Psi), G_CC) ] let charged_currents_triv = ThoList.flatmap charged_currents' [1;2;3] @ ThoList.flatmap charged_currents'' [1;2;3] let charged_currents_ckm = let charged_currents_2 n1 n2 = List.map mgm [ ((D (-n1), Wm, U n2), FBF (1, Psibar, VL, Psi), G_CCQ (n2,n1)); ((U (-n1), Wp, D n2), FBF (1, Psibar, VL, Psi), G_CCQ (n1,n2)) ] in ThoList.flatmap charged_currents' [1;2;3] @ List.flatten (Product.list2 charged_currents_2 [1;2;3] [1;2;3]) let yukawa = [ ((M (U (-3)), O H, M (U 3)), FBF (1, Psibar, S, Psi), G_Htt); ((M (D (-3)), O H, M (D 3)), FBF (1, Psibar, S, Psi), G_Hbb); ((M (U (-2)), O H, M (U 2)), FBF (1, Psibar, S, Psi), G_Hcc); ((M (L (-3)), O H, M (L 3)), FBF (1, Psibar, S, Psi), G_Htautau) ] @ if Flags.higgs_hmm then [ ((M (D (-2)), O H, M (D 2)), FBF (1, Psibar, S, Psi), G_Hss); ((M (L (-2)), O H, M (L 2)), FBF (1, Psibar, S, Psi), G_Hmm); ((M (L (-1)), O H, M (L 1)), FBF (1, Psibar, S, Psi), G_Hee) ] else [] (* \begin{equation} \mathcal{L}_{\textrm{TGC}} = - e \partial_\mu A_\nu W_+^\mu W_-^\nu + \ldots - e \cot\theta_w \partial_\mu Z_\nu W_+^\mu W_-^\nu + \ldots \end{equation} *) let tgc ((g1, g2, g3), t, c) = ((G g1, G g2, G g3), t, c) let standard_triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW); ((Gl, Gl, Gl), Gauge_Gauge_Gauge 1, I_Gs)] (* \begin{multline} \mathcal{L}_{\textrm{TGC}}(g_1,\kappa) = g_1 \mathcal{L}_T(V,W^+,W^-) \\ + \frac{\kappa+g_1}{2} \Bigl(\mathcal{L}_T(W^-,V,W^+) - \mathcal{L}_T(W^+,V,W^-)\Bigr)\\ + \frac{\kappa-g_1}{2} \Bigl(\mathcal{L}_L(W^-,V,W^+) - \mathcal{L}_T(W^+,V,W^-)\Bigr) \end{multline} *) (* \begin{dubious} The whole thing in the LEP2 workshop notation: \begin{multline} \ii\mathcal{L}_{\textrm{TGC},V} / g_{WWV} = \\ g_1^V V^\mu (W^-_{\mu\nu}W^{+,\nu}-W^+_{\mu\nu}W^{-,\nu}) + \kappa_V W^+_\mu W^-_\nu V^{\mu\nu} + \frac{\lambda_V}{m_W^2} V_{\mu\nu} W^-_{\rho\mu} W^{+,\hphantom{\nu}\rho}_{\hphantom{+,}\nu} \\ + \ii g_5^V \epsilon_{\mu\nu\rho\sigma} \left( (\partial^\rho W^{-,\mu}) W^{+,\nu} - W^{-,\mu}(\partial^\rho W^{+,\nu}) \right) V^\sigma \\ + \ii g_4^V W^-_\mu W^+_\nu (\partial^\mu V^\nu + \partial^\nu V^\mu) - \frac{\tilde\kappa_V}{2} W^-_\mu W^+_\nu \epsilon^{\mu\nu\rho\sigma} V_{\rho\sigma} - \frac{\tilde\lambda_V}{2m_W^2} W^-_{\rho\mu} W^{+,\mu}_{\hphantom{+,\mu}\nu} \epsilon^{\nu\rho\alpha\beta} V_{\alpha\beta} \end{multline} using the conventions of Itzykson and Zuber with $\epsilon^{0123} = +1$. \end{dubious} *) (* \begin{dubious} This is equivalent to the notation of Hagiwara et al.~\cite{HPZH87}, if we remember that they have opposite signs for~$g_{WWV}$: \begin{multline} \mathcal{L}_{WWV} / (-g_{WWV}) = \\ \ii g_1^V \left( W^\dagger_{\mu\nu} W^\mu - W^\dagger_\mu W^\mu_{\hphantom{\mu}\nu} \right) V^\nu + \ii \kappa_V W^\dagger_\mu W_\nu V^{\mu\nu} + \ii \frac{\lambda_V}{m_W^2} W^\dagger_{\lambda\mu} W^\mu_{\hphantom{\mu}\nu} V^{\nu\lambda} \\ - g_4^V W^\dagger_\mu W_\nu \left(\partial^\mu V^\nu + \partial^\nu V^\mu \right) + g_5^V \epsilon^{\mu\nu\lambda\sigma} \left( W^\dagger_\mu \stackrel{\leftrightarrow}{\partial_\lambda} W_\nu \right) V_\sigma\\ + \ii \tilde\kappa_V W^\dagger_\mu W_\nu \tilde{V}^{\mu\nu} + \ii\frac{\tilde\lambda_V}{m_W^2} W^\dagger_{\lambda\mu} W^\mu_{\hphantom{\mu}\nu} \tilde{V}^{\nu\lambda} \end{multline} Here $V^\mu$ stands for either the photon or the~$Z$ field, $W^\mu$ is the $W^-$ field, $W_{\mu\nu} = \partial_\mu W_\nu - \partial_\nu W_\mu$, $V_{\mu\nu} = \partial_\mu V_\nu - \partial_\nu V_\mu$, and $\tilde{V}_{\mu\nu} = \frac{1}{2} \epsilon_{\mu\nu\lambda\sigma} V^{\lambda\sigma}$. \end{dubious} *) let anomalous_triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Dim4_Vector_Vector_Vector_T (-1), I_G1_AWW); ((Z, Wm, Wp), Dim4_Vector_Vector_Vector_T (-1), I_G1_ZWW); ((Wm, Ga, Wp), Dim4_Vector_Vector_Vector_T 1, I_G1_plus_kappa_minus_G4_AWW); ((Wm, Z, Wp), Dim4_Vector_Vector_Vector_T 1, I_G1_plus_kappa_minus_G4_ZWW); ((Wp, Ga, Wm), Dim4_Vector_Vector_Vector_T (-1), I_G1_plus_kappa_plus_G4_AWW); ((Wp, Z, Wm), Dim4_Vector_Vector_Vector_T (-1), I_G1_plus_kappa_plus_G4_ZWW); ((Wm, Ga, Wp), Dim4_Vector_Vector_Vector_L (-1), I_G1_minus_kappa_plus_G4_AWW); ((Wm, Z, Wp), Dim4_Vector_Vector_Vector_L (-1), I_G1_minus_kappa_plus_G4_ZWW); ((Wp, Ga, Wm), Dim4_Vector_Vector_Vector_L 1, I_G1_minus_kappa_minus_G4_AWW); ((Wp, Z, Wm), Dim4_Vector_Vector_Vector_L 1, I_G1_minus_kappa_minus_G4_ZWW); ((Ga, Wm, Wp), Dim4_Vector_Vector_Vector_L5 (-1), I_kappa5_AWW); ((Z, Wm, Wp), Dim4_Vector_Vector_Vector_L5 (-1), I_kappa5_ZWW); ((Ga, Wm, Wp), Dim4_Vector_Vector_Vector_T5 (-1), G5_AWW); ((Z, Wm, Wp), Dim4_Vector_Vector_Vector_T5 (-1), G5_ZWW); ((Ga, Wp, Wm), Dim6_Gauge_Gauge_Gauge (-1), I_lambda_AWW); ((Z, Wp, Wm), Dim6_Gauge_Gauge_Gauge (-1), I_lambda_ZWW); ((Ga, Wp, Wm), Dim6_Gauge_Gauge_Gauge_5 (-1), I_lambda5_AWW); ((Z, Wp, Wm), Dim6_Gauge_Gauge_Gauge_5 (-1), I_lambda5_ZWW) ] let anomalous_dim6_triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Dim6_Gauge_Gauge_Gauge_i 1, I_Dim6_AWW_GGG); ((Ga, Wm, Wp), Dim6_AWW_DP 1, I_Dim6_AWW_DP); ((Ga, Wm, Wp), Dim6_AWW_DW 1, I_Dim6_AWW_DW); ((Wm, Wp, Z), Dim6_Gauge_Gauge_Gauge_i 1, I_Dim6_WWZ_W); ((Wm, Wp, Z), Dim6_WWZ_DPWDW 1, I_Dim6_WWZ_DPWDW); ((Wm, Wp, Z), Dim6_WWZ_DW 1, I_Dim6_WWZ_DW); ((Wm, Wp, Z), Dim6_WWZ_D 1, I_Dim6_WWZ_D)(*i ; ((G, G, G), Dim6_Glu_Glu_Glu 1, I_Dim6_GGG_G); ((G, G, G), Gauge_Gauge_Gauge_I 1, I_Dim6_GGG_CG) i*) ] let triple_gauge = if Flags.triple_anom then anomalous_triple_gauge else if Flags.dim6 then standard_triple_gauge @ anomalous_dim6_triple_gauge else standard_triple_gauge (* \begin{equation} \mathcal{L}_{\textrm{QGC}} = - g^2 W_{+,\mu} W_{-,\nu} W_+^\mu W_-^\nu + \ldots \end{equation} *) (* Actually, quartic gauge couplings are a little bit more straightforward using auxiliary fields. Here we have to impose the antisymmetry manually: \begin{subequations} \begin{multline} (W^{+,\mu}_1 W^{-,\nu}_2 - W^{+,\nu}_1 W^{-,\mu}_2) (W^+_{3,\mu} W^-_{4,\nu} - W^+_{3,\nu} W^-_{4,\mu}) \\ = 2(W^+_1W^+_3)(W^-_2W^-_4) - 2(W^+_1W^-_4)(W^-_2W^+_3) \end{multline} also ($V$ can be $A$ or $Z$) \begin{multline} (W^{+,\mu}_1 V^\nu_2 - W^{+,\nu}_1 V^\mu_2) (W^-_{3,\mu} V_{4,\nu} - W^-_{3,\nu} V_{4,\mu}) \\ = 2(W^+_1W^-_3)(V_2V_4) - 2(W^+_1V_4)(V_2W^-_3) \end{multline} \end{subequations} *) (* \begin{subequations} \begin{multline} W^{+,\mu} W^{-,\nu} W^+_\mu W^-_\nu \end{multline} \end{subequations} *) let qgc ((g1, g2, g3, g4), t, c) = ((G g1, G g2, G g3, G g4), t, c) let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] let standard_quartic_gauge = List.map qgc [ (Wm, Wp, Wm, Wp), gauge4, G_WWWW; (Wm, Z, Wp, Z), minus_gauge4, G_ZZWW; (Wm, Z, Wp, Ga), minus_gauge4, G_AZWW; (Wm, Ga, Wp, Ga), minus_gauge4, G_AAWW; (Gl, Gl, Gl, Gl), gauge4, G2 ] (* \begin{subequations} \begin{align} \mathcal{L}_4 &= \alpha_4 \left( \frac{g^4}{2}\left( (W^+_\mu W^{-,\mu})^2 + W^+_\mu W^{+,\mu} W^-_\mu W^{-,\mu} \right)\right.\notag \\ &\qquad\qquad\qquad \left. + \frac{g^4}{\cos^2\theta_w} W^+_\mu Z^\mu W^-_\nu Z^\nu + \frac{g^4}{4\cos^4\theta_w} (Z_\mu Z^\mu)^2 \right) \\ \mathcal{L}_5 &= \alpha_5 \left( g^4 (W^+_\mu W^{-,\mu})^2 + \frac{g^4}{\cos^2\theta_w} W^+_\mu W^{-,\mu} Z_\nu Z^\nu + \frac{g^4}{4\cos^4\theta_w} (Z_\mu Z^\mu)^2 \right) \end{align} \end{subequations} or \begin{multline} \mathcal{L}_4 + \mathcal{L}_5 = (\alpha_4+2\alpha_5) g^4 \frac{1}{2} (W^+_\mu W^{-,\mu})^2 \\ + 2\alpha_4 g^4 \frac{1}{4} W^+_\mu W^{+,\mu} W^-_\mu W^{-,\mu} + \alpha_4 \frac{g^4}{\cos^2\theta_w} W^+_\mu Z^\mu W^-_\nu Z^\nu \\ + 2\alpha_5 \frac{g^4}{\cos^2\theta_w} \frac{1}{2} W^+_\mu W^{-,\mu} Z_\nu Z^\nu + (2\alpha_4 + 2\alpha_5) \frac{g^4}{\cos^4\theta_w} \frac{1}{8} (Z_\mu Z^\mu)^2 \end{multline} and therefore \begin{subequations} \begin{align} \alpha_{(WW)_0} &= (\alpha_4+2\alpha_5) g^4 \\ \alpha_{(WW)_2} &= 2\alpha_4 g^4 \\ \alpha_{(WZ)_0} &= 2\alpha_5 \frac{g^4}{\cos^2\theta_w} \\ \alpha_{(WZ)_1} &= \alpha_4 \frac{g^4}{\cos^2\theta_w} \\ \alpha_{ZZ} &= (2\alpha_4 + 2\alpha_5) \frac{g^4}{\cos^4\theta_w} \end{align} \end{subequations} *) let anomalous_quartic_gauge = if Flags.quartic_anom then List.map qgc [ ((Wm, Wm, Wp, Wp), Vector4 [(1, C_13_42); (1, C_14_23)], Alpha_WWWW0); ((Wm, Wm, Wp, Wp), Vector4 [1, C_12_34], Alpha_WWWW2); ((Wm, Wp, Z, Z), Vector4 [1, C_12_34], Alpha_ZZWW0); ((Wm, Wp, Z, Z), Vector4 [(1, C_13_42); (1, C_14_23)], Alpha_ZZWW1); ((Z, Z, Z, Z), Vector4 [(1, C_12_34); (1, C_13_42); (1, C_14_23)], Alpha_ZZZZ) ] else [] let anomalous_dim6_quartic_gauge = if Flags.dim6 then List.map qgc [ ((Ga, Ga, Wm, Wp), Dim6_Vector4_DW 1, Anom_Dim6_AAWW_DW); ((Ga, Ga, Wm, Wp), Dim6_Vector4_W 1, Anom_Dim6_AAWW_W); ((Ga, Z, Wm, Wp), Dim6_Vector4_W 1, Anom_Dim6_AZWW_W); ((Ga, Z, Wm, Wp), Dim6_Vector4_DW 1, Anom_Dim6_AZWW_DWDPW); ((Wm, Wp, Wm, Wp), Dim6_Vector4_W 1, Anom_Dim6_WWWW_W); ((Wm, Wp, Wm, Wp), Dim6_Vector4_DW 1, Anom_Dim6_WWWW_DWDPW); ((Z, Z, Wm, Wp), Dim6_Vector4_W 1, Anom_Dim6_WWZZ_W); ((Z, Z, Wm, Wp), Dim6_Vector4_DW 1, Anom_Dim6_WWZZ_DWDPW) ] else [] (* In any diagonal channel~$\chi$, the scattering amplitude~$a_\chi(s)$ is unitary iff\footnote{% Trivial proof: \begin{equation} -1 = \textrm{Im}\left(\frac{1}{a_\chi(s)}\right) = \frac{\textrm{Im}(a_\chi^*(s))}{ |a_\chi(s)|^2 } = - \frac{\textrm{Im}(a_\chi(s))}{ |a_\chi(s)|^2 } \end{equation} i.\,e.~$\textrm{Im}(a_\chi(s)) = |a_\chi(s)|^2$.} \begin{equation} \textrm{Im}\left(\frac{1}{a_\chi(s)}\right) = -1 \end{equation} For a real perturbative scattering amplitude~$r_\chi(s)$ this can be enforced easily--and arbitrarily--by \begin{equation} \frac{1}{a_\chi(s)} = \frac{1}{r_\chi(s)} - \mathrm{i} \end{equation} *) let k_matrix_quartic_gauge = if Flags.k_matrix then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_WWWW0_S); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_jr (0, [(1, C_14_23)]), D_Alpha_WWWW0_T); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_jr (0, [(1, C_13_42)]), D_Alpha_WWWW0_U); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_WWWW0_S); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_jr (0, [(1, C_14_23)]), D_Alpha_WWWW0_T); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_jr (0, [(1, C_13_42)]), D_Alpha_WWWW0_U); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_WWWW2_S); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_jr (0, [(1, C_13_42); (1, C_14_23)]), D_Alpha_WWWW2_T); ((Wm, Wp, Z, Z), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_ZZWW0_S); ((Wm, Wp, Z, Z), Vector4_K_Matrix_jr (0, [(1, C_13_42); (1, C_14_23)]), D_Alpha_ZZWW0_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_ZZWW1_S); ((Wm, Z, Wp, Z), Vector4_K_Matrix_jr (0, [(1, C_13_42)]), D_Alpha_ZZWW1_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_jr (0, [(1, C_14_23)]), D_Alpha_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_jr (1, [(1, C_12_34)]), D_Alpha_ZZWW1_S); ((Wp, Z, Z, Wm), Vector4_K_Matrix_jr (1, [(1, C_13_42)]), D_Alpha_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_jr (1, [(1, C_14_23)]), D_Alpha_ZZWW1_T); ((Z, Wp, Wm, Z), Vector4_K_Matrix_jr (2, [(1, C_12_34)]), D_Alpha_ZZWW1_S); ((Z, Wp, Wm, Z), Vector4_K_Matrix_jr (2, [(1, C_13_42)]), D_Alpha_ZZWW1_U); ((Z, Wp, Wm, Z), Vector4_K_Matrix_jr (2, [(1, C_14_23)]), D_Alpha_ZZWW1_T); ((Z, Z, Z, Z), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_jr (0, [(1, C_13_42); (1, C_14_23)]), D_Alpha_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_jr (3, [(1, C_14_23)]), D_Alpha_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_jr (3, [(1, C_13_42); (1, C_12_34)]), D_Alpha_ZZZZ_T)] else [] (*i Thorsten's original implementation of the K matrix, which we keep since it still might be usefull for the future. let k_matrix_quartic_gauge = if Flags.k_matrix then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 0, K_Matrix_Pole 0]), Alpha_WWWW0); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 2, K_Matrix_Pole 2]), Alpha_WWWW2); ((Wm, Wp, Z, Z), Vector4_K_Matrix_tho (0, [(K_Matrix_Coeff 0, K_Matrix_Pole 0); (K_Matrix_Coeff 2, K_Matrix_Pole 2)]), Alpha_ZZWW0); ((Wm, Z, Wp, Z), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 1, K_Matrix_Pole 1]), Alpha_ZZWW1); ((Z, Z, Z, Z), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 0, K_Matrix_Pole 0]), Alpha_ZZZZ) ] else [] i*) let quartic_gauge = standard_quartic_gauge @ anomalous_quartic_gauge @ anomalous_dim6_quartic_gauge @ k_matrix_quartic_gauge let standard_gauge_higgs = [ ((O H, G Wp, G Wm), Scalar_Vector_Vector 1, G_HWW); ((O H, G Z, G Z), Scalar_Vector_Vector 1, G_HZZ) ] let standard_gauge_higgs4 = [ (O H, O H, G Wp, G Wm), Scalar2_Vector2 1, G_HHWW; (O H, O H, G Z, G Z), Scalar2_Vector2 1, G_HHZZ ] let standard_higgs = [ (O H, O H, O H), Scalar_Scalar_Scalar 1, G_H3 ] let standard_higgs4 = [ (O H, O H, O H, O H), Scalar4 1, G_H4 ] (* WK's couplings (apparently, he still intends to divide by $\Lambda^2_{\text{EWSB}}=16\pi^2v_{\mathrm{F}}^2$): \begin{subequations} \begin{align} \mathcal{L}^{\tau}_4 &= \left\lbrack (\partial_{\mu}H)(\partial^{\mu}H) + \frac{g^2v_{\mathrm{F}}^2}{4} V_{\mu} V^{\mu} \right\rbrack^2 \\ \mathcal{L}^{\tau}_5 &= \left\lbrack (\partial_{\mu}H)(\partial_{\nu}H) + \frac{g^2v_{\mathrm{F}}^2}{4} V_{\mu} V_{\nu} \right\rbrack^2 \end{align} \end{subequations} with \begin{equation} V_{\mu} V_{\nu} = \frac{1}{2} \left( W^+_{\mu} W^-_{\nu} + W^+_{\nu} W^-_{\mu} \right) + \frac{1}{2\cos^2\theta_{w}} Z_{\mu} Z_{\nu} \end{equation} (note the symmetrization!), i.\,e. \begin{subequations} \begin{align} \mathcal{L}_4 &= \alpha_4 \frac{g^4v_{\mathrm{F}}^4}{16} (V_{\mu} V_{\nu})^2 \\ \mathcal{L}_5 &= \alpha_5 \frac{g^4v_{\mathrm{F}}^4}{16} (V_{\mu} V^{\mu})^2 \end{align} \end{subequations} *) (* Breaking thinks up \begin{subequations} \begin{align} \mathcal{L}^{\tau,H^4}_4 &= \left\lbrack (\partial_{\mu}H)(\partial^{\mu}H) \right\rbrack^2 \\ \mathcal{L}^{\tau,H^4}_5 &= \left\lbrack (\partial_{\mu}H)(\partial^{\mu}H) \right\rbrack^2 \end{align} \end{subequations} and \begin{subequations} \begin{align} \mathcal{L}^{\tau,H^2V^2}_4 &= \frac{g^2v_{\mathrm{F}}^2}{2} (\partial_{\mu}H)(\partial^{\mu}H) V_{\mu}V^{\mu} \\ \mathcal{L}^{\tau,H^2V^2}_5 &= \frac{g^2v_{\mathrm{F}}^2}{2} (\partial_{\mu}H)(\partial_{\nu}H) V_{\mu}V_{\nu} \end{align} \end{subequations} i.\,e. \begin{subequations} \begin{align} \mathcal{L}^{\tau,H^2V^2}_4 &= \frac{g^2v_{\mathrm{F}}^2}{2} \left\lbrack (\partial_{\mu}H)(\partial^{\mu}H) W^+_{\nu}W^{-,\nu} + \frac{1}{2\cos^2\theta_{w}} (\partial_{\mu}H)(\partial^{\mu}H) Z_{\nu} Z^{\nu} \right\rbrack \\ \mathcal{L}^{\tau,H^2V^2}_5 &= \frac{g^2v_{\mathrm{F}}^2}{2} \left\lbrack (W^{+,\mu}\partial_{\mu}H) (W^{-,\nu}\partial_{\nu}H) + \frac{1}{2\cos^2\theta_{w}} (Z^{\mu}\partial_{\mu}H)(Z^{\nu}\partial_{\nu}H) \right\rbrack \end{align} \end{subequations} *) (* \begin{multline} \tau^4_8 \mathcal{L}^{\tau,H^2V^2}_4 + \tau^5_8 \mathcal{L}^{\tau,H^2V^2}_5 = \\ - \frac{g^2v_{\mathrm{F}}^2}{2} \Biggl\lbrack 2\tau^4_8 \frac{1}{2}(\ii\partial_{\mu}H)(\ii\partial^{\mu}H) W^+_{\nu}W^{-,\nu} + \tau^5_8 (W^{+,\mu}\ii\partial_{\mu}H) (W^{-,\nu}\ii\partial_{\nu}H) \\ + \frac{2\tau^4_8}{\cos^2\theta_{w}} \frac{1}{4} (\ii\partial_{\mu}H)(\ii\partial^{\mu}H) Z_{\nu} Z^{\nu} + \frac{\tau^5_8}{\cos^2\theta_{w}} \frac{1}{2} (Z^{\mu}\ii\partial_{\mu}H)(Z^{\nu}\ii\partial_{\nu}H) \Biggr\rbrack \end{multline} where the two powers of $\ii$ make the sign conveniently negative, i.\,e. \begin{subequations} \begin{align} \alpha_{(\partial H)^2W^2}^2 &= \tau^4_8 g^2v_{\mathrm{F}}^2\\ \alpha_{(\partial HW)^2}^2 &= \frac{\tau^5_8 g^2v_{\mathrm{F}}^2}{2} \\ \alpha_{(\partial H)^2Z^2}^2 &= \frac{\tau^4_8 g^2v_{\mathrm{F}}^2}{\cos^2\theta_{w}} \\ \alpha_{(\partial HZ)^2}^2 &=\frac{\tau^5_8 g^2v_{\mathrm{F}}^2}{2\cos^2\theta_{w}} \end{align} \end{subequations} *) let anomalous_gauge_higgs = [ (O H, G Ga, G Ga), Dim5_Scalar_Gauge2 1, G_HGaGa_anom; (O H, G Ga, G Z), Dim5_Scalar_Gauge2 1, G_HGaZ_anom; (O H, G Z, G Z), Dim5_Scalar_Gauge2 1, G_HZZ_anom; (O H, G Wp, G Wm), Dim5_Scalar_Gauge2 1, G_HWW_anom; (O H, G Ga, G Z), Dim5_Scalar_Vector_Vector_TU 1, G_HGaZ_u; (O H, G Z, G Z), Dim5_Scalar_Vector_Vector_U 1, G_HZZ_u; (O H, G Wp, G Wm), Dim5_Scalar_Vector_Vector_U 1, G_HWW_u ] let anomalous_dim6_gauge_higgs = [ (O H, G Z, G Z), Scalar_Vector_Vector 1, G_HZZ6_V3; (O H, G Z, G Z), Dim6_Scalar_Vector_Vector_D 1, G_HZZ6_D; (O H, G Z, G Z), Dim6_Scalar_Vector_Vector_DP 1, G_HZZ6_DP; (O H, G Z, G Z), Scalar_Vector_Vector_t 1, G_HZZ6_PB; (O H, G Ga, G Z), Dim6_HAZ_D 1, G_HGaZ6_D; (O H, G Ga, G Z), Dim6_HAZ_DP 1, G_HGaZ6_DP; (O H, G Ga, G Z), Scalar_Vector_Vector_t 1, G_HGaZ6_PB; (O H, G Ga, G Ga), Scalar_Vector_Vector_t 1, G_HGaGa6; (O H, G Wm, G Wp), Dim6_Scalar_Vector_Vector_D 1, G_HWW_6_D; (O H, G Wm, G Wp), Dim6_Scalar_Vector_Vector_DP 1, G_HWW_6_DP ] let anomalous_gauge_higgs4 = [] let anomalous_dim6_gauge_higgs4 = [(G Ga, O H, G Wm, G Wp), Dim6_AHWW_DPB 1, Anom_Dim6_AHWW_DPB; (G Ga, O H, G Wm, G Wp), Dim6_AHWW_DPW 1, Anom_Dim6_AHWW_DPW; (G Ga, O H, G Wm, G Wp), Dim6_AHWW_DW 1, Anom_Dim6_AHWW_DW; (O H, G Wm, G Wp, G Z), Dim6_HWWZ_DW 1, Anom_Dim6_HWWZ_DW; (O H, G Wm, G Wp, G Z), Dim6_HWWZ_DDPW 1, Anom_Dim6_HWWZ_DDPW; (O H, G Wm, G Wp, G Z), Dim6_HWWZ_DPW 1, Anom_Dim6_HWWZ_DPW; (O H, G Wm, G Wp, G Z), Dim6_HWWZ_DPB 1, Anom_Dim6_HWWZ_DPB; (G Ga, O H, O H, G Z), Dim6_AHHZ_D 1, Anom_Dim6_AHHZ_D; (G Ga, O H, O H, G Z), Dim6_AHHZ_DP 1, Anom_Dim6_AHHZ_DP; (G Ga, O H, O H, G Z), Dim6_AHHZ_PB 1, Anom_Dim6_AHHZ_PB; (O H, O H, G Ga, G Ga), Dim6_Scalar2_Vector2_PB 1, Anom_Dim6_HHAA; (O H, O H, G Wm, G Wp), Dim6_Scalar2_Vector2_D 1, Anom_Dim6_HHWW_DW; (O H, O H, G Wm, G Wp), Dim6_Scalar2_Vector2_DP 1, Anom_Dim6_HHWW_DPW; (O H, O H, G Z, G Z), Dim6_HHZZ_T 1, Anom_Dim6_HHZZ_T; (O H, O H, G Z, G Z), Dim6_Scalar2_Vector2_D 1, Anom_Dim6_HHZZ_D; (O H, O H, G Z, G Z), Dim6_Scalar2_Vector2_DP 1, Anom_Dim6_HHZZ_DP; (O H, O H, G Z, G Z), Dim6_Scalar2_Vector2_PB 1, Anom_Dim6_HHZZ_PB ] let anomalous_higgs = [] let anomalous_dim6_higgs = [(O H, O H, O H), Scalar_Scalar_Scalar 1, Dim6_vev3; (O H, O H, O H), Dim6_HHH 1, Dim6_Cphi ] let higgs_triangle_vertices = if Flags.higgs_triangle then [ (O H, G Ga, G Ga), Dim5_Scalar_Gauge2 1, G_HGaGa; (O H, G Ga, G Z), Dim5_Scalar_Gauge2 1, G_HGaZ; (O H, G Gl, G Gl), Dim5_Scalar_Gauge2 1, G_Hgg ] else [] let anomalous_higgs4 = [] let anomalous_dim6_higgs4 = [(O H, O H, O H, O H), Scalar4 1, Anom_Dim6_H4_v2; (O H, O H, O H, O H), Dim6_H4_P2 1, Anom_Dim6_H4_P2] let gauge_higgs = if Flags.higgs_anom then standard_gauge_higgs @ anomalous_gauge_higgs else if Flags.dim6 then standard_gauge_higgs @ anomalous_dim6_gauge_higgs else standard_gauge_higgs let gauge_higgs4 = if Flags.higgs_anom then standard_gauge_higgs4 @ anomalous_gauge_higgs4 else if Flags.dim6 then standard_gauge_higgs4 @ anomalous_dim6_gauge_higgs4 else standard_gauge_higgs4 let higgs = if Flags.higgs_anom then standard_higgs @ anomalous_higgs else if Flags.dim6 then standard_higgs @ anomalous_dim6_higgs else standard_higgs let higgs4 = if Flags.higgs_anom then standard_higgs4 @ anomalous_higgs4 else if Flags.dim6 then standard_higgs4 @ anomalous_dim6_higgs4 else standard_higgs4 let goldstone_vertices = [ ((O Phi0, G Wm, G Wp), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phip, G Ga, G Wm), Scalar_Vector_Vector 1, I_Q_W); ((O Phip, G Z, G Wm), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phim, G Wp, G Ga), Scalar_Vector_Vector 1, I_Q_W); ((O Phim, G Wp, G Z), Scalar_Vector_Vector 1, I_G_ZWW) ] (* Anomalous trilinear interactions $f_i f_j V$ and $ttH$: \begin{equation} \Delta\mathcal{L}_{tt\gamma} = - e \frac{\upsilon}{\Lambda^2} \bar{t} i\sigma^{\mu\nu} k_\nu (d_V(k^2) + i d_A(k^2) \gamma_5) t A_\mu \end{equation} \begin{equation} \Delta\mathcal{L}_{tc\gamma} = - e \frac{\upsilon}{\Lambda^2} \bar{t} i\sigma^{\mu\nu} k_\nu (d_V(k^2) + i d_A(k^2) \gamma_5) c A_\mu \,\text{+\,h.c.} \end{equation} *) let anomalous_ttA = if Flags.top_anom then [ ((M (U (-3)), G Ga, M (U 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_ttA); ((M (U (-3)), G Ga, M (U 2)), FBF (1, Psibar, TVAM, Psi), G_TVA_tcA); ((M (U (-2)), G Ga, M (U 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_tcA); ((M (U (-3)), G Ga, M (U 1)), FBF (1, Psibar, TVAM, Psi), G_TVA_tuA); ((M (U (-1)), G Ga, M (U 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_tuA)] else [] let tt_threshold_ttA = if Flags.tt_threshold then [ ((M (U (-3)), G Ga, M (U 3)), FBF (1, Psibar, VAM, Psi), VA_ILC_ttA) ] else [] (* \begin{equation} \Delta\mathcal{L}_{bb\gamma} = - e \frac{\upsilon}{\Lambda^2} \bar{b} i\sigma^{\mu\nu} k_\nu (d_V(k^2) + i d_A(k^2) \gamma_5) b A_\mu \end{equation} *) let anomalous_bbA = if Flags.top_anom then [ ((M (D (-3)), G Ga, M (D 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_bbA) ] else [] (* \begin{equation} \Delta\mathcal{L}_{ttg} = - g_s \frac{\upsilon}{\Lambda^2} \bar{t}\lambda^a i\sigma^{\mu\nu}k_\nu (d_V(k^2)+id_A(k^2)\gamma_5)tG^a_\mu \end{equation} \begin{equation} \Delta\mathcal{L}_{tcg} = - g_s \frac{\upsilon}{\Lambda^2} \bar{t}\lambda^a i\sigma^{\mu\nu}k_\nu (d_V(k^2)+id_A(k^2)\gamma_5)cG^a_\mu\,\text{+\,h.c.} \end{equation} *) let anomalous_ttG = if Flags.top_anom then [ ((M (U (-3)), G Gl, M (U 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_ttG); ((M (U (-3)), G Gl, M (U 2)), FBF (1, Psibar, TVAM, Psi), G_TVA_tcG); ((M (U (-2)), G Gl, M (U 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_tcG); ((M (U (-3)), G Gl, M (U 1)), FBF (1, Psibar, TVAM, Psi), G_TVA_tuG); ((M (U (-1)), G Gl, M (U 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_tuG)] else [] (* \begin{equation} \Delta\mathcal{L}_{ttZ} = - \frac{g}{2 c_W} \frac{\upsilon^2}{\Lambda^2}\left\lbrack \bar{t} \fmslash{Z} (X_L(k^2) P_L + X_R(k^2) P_R) t + \bar{t}\frac{i\sigma^{\mu\nu}k_\nu}{m_Z} (d_V(k^2)+id_A(k^2)\gamma_5)tZ_\mu\right\rbrack \end{equation} \begin{equation} \Delta\mathcal{L}_{tcZ} = - \frac{g}{2 c_W} \frac{\upsilon^2}{\Lambda^2}\left\lbrack \bar{t} \fmslash{Z} (X_L(k^2) P_L + X_R(k^2) P_R) c + \bar{t}\frac{i\sigma^{\mu\nu}k_\nu}{m_Z} (d_V(k^2)+id_A(k^2)\gamma_5)cZ_\mu\right\rbrack \,\text{+\,h.c.} \end{equation} *) let anomalous_ttZ = if Flags.top_anom then [ ((M (U (-3)), G Z, M (U 3)), FBF (1, Psibar, VLRM, Psi), G_VLR_ttZ); ((M (U (-3)), G Z, M (U 2)), FBF (1, Psibar, VLRM, Psi), G_VLR_tcZ); ((M (U (-2)), G Z, M (U 3)), FBF (1, Psibar, VLRM, Psi), G_VLR_tcZ); ((M (U (-3)), G Z, M (U 1)), FBF (1, Psibar, VLRM, Psi), G_VLR_tuZ); ((M (U (-1)), G Z, M (U 3)), FBF (1, Psibar, VLRM, Psi), G_VLR_tuZ); ((M (U (-3)), G Z, M (U 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_ttZ); ((M (U (-2)), G Z, M (U 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_tcZ); ((M (U (-3)), G Z, M (U 2)), FBF (1, Psibar, TVAM, Psi), G_TVA_tcZ); ((M (U (-1)), G Z, M (U 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_tuZ); ((M (U (-3)), G Z, M (U 1)), FBF (1, Psibar, TVAM, Psi), G_TVA_tuZ)] else [] let tt_threshold_ttZ = if Flags.tt_threshold then [ ((M (U (-3)), G Z, M (U 3)), FBF (1, Psibar, VAM, Psi), VA_ILC_ttZ) ] else [] (* \begin{equation} \Delta\mathcal{L}_{bbZ} = - \frac{g}{2 c_W} \frac{\upsilon^2}{\Lambda^2} \bar{b}\frac{i\sigma^{\mu\nu}k_\nu}{m_Z} (d_V(k^2)+id_A(k^2)\gamma_5)bZ_\mu \end{equation} *) let anomalous_bbZ = if Flags.top_anom then [ ((M (D (-3)), G Z, M (D 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_bbZ) ] else [] (* \begin{equation} \Delta\mathcal{L}_{tbW} = - \frac{g}{\sqrt{2}} \frac{\upsilon^2}{\Lambda^2}\left\lbrack \bar{b}\fmslash{W}^-(V_L(k^2) P_L+V_R(k^2) P_R) t + \bar{b}\frac{i\sigma^{\mu\nu}k_\nu}{m_W} (g_L(k^2)P_L+g_R(k^2)P_R)tW^-_\mu\right\rbrack \,\text{+\,h.c.} \end{equation} *) let anomalous_tbW = if Flags.top_anom then [ ((M (D (-3)), G Wm, M (U 3)), FBF (1, Psibar, VLRM, Psi), G_VLR_btW); ((M (U (-3)), G Wp, M (D 3)), FBF (1, Psibar, VLRM, Psi), G_VLR_tbW); ((M (D (-3)), G Wm, M (U 3)), FBF (1, Psibar, TLRM, Psi), G_TLR_btW); ((M (U (-3)), G Wp, M (D 3)), FBF (1, Psibar, TRLM, Psi), G_TRL_tbW) ] else [] (* \begin{equation} \Delta\mathcal{L}_{ttH} = - \frac{1}{\sqrt{2}} \bar{t} (Y_V(k^2)+iY_A(k^2)\gamma_5)t H \end{equation} *) let anomalous_ttH = if Flags.top_anom then [ ((M (U (-3)), O H, M (U 3)), FBF (1, Psibar, SPM, Psi), G_SP_ttH) ] else [] (* quartic fermion-gauge interactions $f_i f_j V_1 V_2$ emerging from gauge-invariant effective operators: \begin{equation} \Delta\mathcal{L}_{ttgg} = - \frac{g_s^2}{2} f_{abc} \frac{\upsilon}{\Lambda^2} \bar{t} \lambda^a \sigma^{\mu\nu} (d_V(k^2)+id_A(k^2)\gamma_5)t G^b_\mu G^c_\nu \end{equation} \begin{equation} \Delta\mathcal{L}_{tcgg} = - \frac{g_s^2}{2} f_{abc} \frac{\upsilon}{\Lambda^2} \bar{t} \lambda^a \sigma^{\mu\nu} (d_V(k^2)+id_A(k^2)\gamma_5)c G^b_\mu G^c_\nu \,\text{+\,h.c.} \end{equation} *) let anomalous_ttGG = if Flags.top_anom then [ ((M (U (-3)), O (Aux_top (2,1,0,true,TTGG)), M (U 3)), FBF (1, Psibar, TVA, Psi), G_TVA_ttGG); ((M (U (-3)), O (Aux_top (2,1,0,true,TCGG)), M (U 2)), FBF (1, Psibar, TVA, Psi), G_TVA_tcGG); ((M (U (-2)), O (Aux_top (2,1,0,true,TCGG)), M (U 3)), FBF (1, Psibar, TVA, Psi), G_TVA_tcGG); ((M (U (-3)), O (Aux_top (2,1,0,true,TUGG)), M (U 1)), FBF (1, Psibar, TVA, Psi), G_TVA_tuGG); ((M (U (-1)), O (Aux_top (2,1,0,true,TUGG)), M (U 3)), FBF (1, Psibar, TVA, Psi), G_TVA_tuGG); ((O (Aux_top (2,1,0,false,TTGG)), G Gl, G Gl), Aux_Gauge_Gauge 1, I_Gs); ((O (Aux_top (2,1,0,false,TCGG)), G Gl, G Gl), Aux_Gauge_Gauge 1, I_Gs); ((O (Aux_top (2,1,0,false,TUGG)), G Gl, G Gl), Aux_Gauge_Gauge 1, I_Gs)] else [] (* \begin{equation} \Delta\mathcal{L}_{tbWA} = - i\sin\theta_w \frac{g^2}{2\sqrt{2}} \frac{\upsilon^2}{\Lambda^2}\left\lbrack \bar{b}\frac{\sigma^{\mu\nu}}{m_W} (g_L(k^2)P_L+g_R(k^2)P_R)t A_\mu W^-_\nu \right\rbrack \,\text{+\,h.c.} \end{equation} *) let anomalous_tbWA = if Flags.top_anom then [ ((M (D (-3)), O (Aux_top (2,0,-1,true,TBWA)), M (U 3)), FBF (1, Psibar, TLR, Psi), G_TLR_btWA); ((O (Aux_top (2,0,1,false,TBWA)), G Ga, G Wm), Aux_Gauge_Gauge 1, I_G_weak); ((M (U (-3)), O (Aux_top (2,0,1,true,TBWA)), M (D 3)), FBF (1, Psibar, TRL, Psi), G_TRL_tbWA); ((O (Aux_top (2,0,-1,false,TBWA)), G Wp, G Ga), Aux_Gauge_Gauge 1, I_G_weak) ] else [] (* \begin{equation} \Delta\mathcal{L}_{tbWZ} = - i\cos\theta_w \frac{g^2}{2\sqrt{2}} \frac{\upsilon^2}{\Lambda^2}\left\lbrack \bar{b}\frac{\sigma^{\mu\nu}}{m_W} (g_L(k^2)P_L+g_R(k^2)P_R)t Z_\mu W^-_\nu \right\rbrack \,\text{+\,h.c.} \end{equation} *) let anomalous_tbWZ = if Flags.top_anom then [ ((M (D (-3)), O (Aux_top (2,0,-1,true,TBWZ)), M (U 3)), FBF (1, Psibar, TLR, Psi), G_TLR_btWZ); ((O (Aux_top (2,0,1,false,TBWZ)), G Z, G Wm), Aux_Gauge_Gauge 1, I_G_weak); ((M (U (-3)), O (Aux_top (2,0,1,true,TBWZ)), M (D 3)), FBF (1, Psibar, TRL, Psi), G_TRL_tbWZ); ((O (Aux_top (2,0,-1,false,TBWZ)), G Wp, G Z), Aux_Gauge_Gauge 1, I_G_weak) ] else [] (* \begin{equation} \Delta\mathcal{L}_{ttWW} = - i \frac{g^2}{2} \frac{\upsilon^2}{\Lambda^2} \bar{t} \frac{\sigma^{\mu\nu}}{m_W} (d_V(k^2)+id_A(k^2)\gamma_5)t W^-_\mu W^+_\nu \end{equation} *) let anomalous_ttWW = if Flags.top_anom then [ ((M (U (-3)), O (Aux_top (2,0,0,true,TTWW)), M (U 3)), FBF (1, Psibar, TVA, Psi), G_TVA_ttWW); ((O (Aux_top (2,0,0,false,TTWW)), G Wm, G Wp), Aux_Gauge_Gauge 1, I_G_weak) ] else [] (* \begin{equation} \Delta\mathcal{L}_{bbWW} = - i \frac{g^2}{2} \frac{\upsilon^2}{\Lambda^2} \bar{b} \frac{\sigma^{\mu\nu}}{m_W} (d_V(k^2)+id_A(k^2)\gamma_5)b W^-_\mu W^+_\nu \end{equation} *) let anomalous_bbWW = if Flags.top_anom then [ ((M (D (-3)), O (Aux_top (2,0,0,true,BBWW)), M (D 3)), FBF (1, Psibar, TVA, Psi), G_TVA_bbWW); ((O (Aux_top (2,0,0,false,BBWW)), G Wm, G Wp), Aux_Gauge_Gauge 1, I_G_weak) ] else [] (* 4-fermion contact terms emerging from operator rewriting: *) let anomalous_top_qGuG_tt = [ ((M (U (-3)), O (Aux_top (1,1,0,true,QGUG)), M (U 3)), FBF (1, Psibar, VLR, Psi), G_VLR_qGuG) ] let anomalous_top_qGuG_ff n = List.map mom [ ((U (-n), Aux_top (1,1,0,false,QGUG), U n), FBF (1, Psibar, V, Psi), Unit); ((D (-n), Aux_top (1,1,0,false,QGUG), D n), FBF (1, Psibar, V, Psi), Unit) ] let anomalous_top_qGuG = if Flags.top_anom_4f then anomalous_top_qGuG_tt @ ThoList.flatmap anomalous_top_qGuG_ff [1;2;3] else [] let anomalous_top_qBuB_tt = [ ((M (U (-3)), O (Aux_top (1,0,0,true,QBUB)), M (U 3)), FBF (1, Psibar, VLR, Psi), G_VLR_qBuB) ] let anomalous_top_qBuB_ff n = List.map mom [ ((U (-n), Aux_top (1,0,0,false,QBUB), U n), FBF (1, Psibar, VLR, Psi), G_VLR_qBuB_u); ((D (-n), Aux_top (1,0,0,false,QBUB), D n), FBF (1, Psibar, VLR, Psi), G_VLR_qBuB_d); ((L (-n), Aux_top (1,0,0,false,QBUB), L n), FBF (1, Psibar, VLR, Psi), G_VLR_qBuB_e); ((N (-n), Aux_top (1,0,0,false,QBUB), N n), FBF (1, Psibar, VL, Psi), G_VL_qBuB_n) ] let anomalous_top_qBuB = if Flags.top_anom_4f then anomalous_top_qBuB_tt @ ThoList.flatmap anomalous_top_qBuB_ff [1;2;3] else [] let anomalous_top_qW_tq = [ ((M (U (-3)), O (Aux_top (1,0,0,true,QW)), M (U 3)), FBF (1, Psibar, VL, Psi), G_VL_qW); ((M (D (-3)), O (Aux_top (1,0,-1,true,QW)), M (U 3)), FBF (1, Psibar, VL, Psi), G_VL_qW); ((M (U (-3)), O (Aux_top (1,0,1,true,QW)), M (D 3)), FBF (1, Psibar, VL, Psi), G_VL_qW) ] let anomalous_top_qW_ff n = List.map mom [ ((U (-n), Aux_top (1,0,0,false,QW), U n), FBF (1, Psibar, VL, Psi), G_VL_qW_u); ((D (-n), Aux_top (1,0,0,false,QW), D n), FBF (1, Psibar, VL, Psi), G_VL_qW_d); ((N (-n), Aux_top (1,0,0,false,QW), N n), FBF (1, Psibar, VL, Psi), G_VL_qW_u); ((L (-n), Aux_top (1,0,0,false,QW), L n), FBF (1, Psibar, VL, Psi), G_VL_qW_d); ((D (-n), Aux_top (1,0,-1,false,QW), U n), FBF (1, Psibar, VL, Psi), Half); ((U (-n), Aux_top (1,0,1,false,QW), D n), FBF (1, Psibar, VL, Psi), Half); ((L (-n), Aux_top (1,0,-1,false,QW), N n), FBF (1, Psibar, VL, Psi), Half); ((N (-n), Aux_top (1,0,1,false,QW), L n), FBF (1, Psibar, VL, Psi), Half) ] let anomalous_top_qW = if Flags.top_anom_4f then anomalous_top_qW_tq @ ThoList.flatmap anomalous_top_qW_ff [1;2;3] else [] let anomalous_top_DuDd = if Flags.top_anom_4f then [ ((M (U (-3)), O (Aux_top (0,0,0,true,DR)), M (U 3)), FBF (1, Psibar, SR, Psi), Half); ((M (U (-3)), O (Aux_top (0,0,0,false,DR)), M (U 3)), FBF (1, Psibar, SL, Psi), G_SL_DttR); ((M (D (-3)), O (Aux_top (0,0,0,false,DR)), M (D 3)), FBF (1, Psibar, SR, Psi), G_SR_DttR); ((M (U (-3)), O (Aux_top (0,0,0,true,DL)), M (U 3)), FBF (1, Psibar, SL, Psi), Half); ((M (D (-3)), O (Aux_top (0,0,0,false,DL)), M (D 3)), FBF (1, Psibar, SL, Psi), G_SL_DttL); ((M (D (-3)), O (Aux_top (0,0,-1,true,DR)), M (U 3)), FBF (1, Psibar, SR, Psi), Half); ((M (U (-3)), O (Aux_top (0,0,1,false,DR)), M (D 3)), FBF (1, Psibar, SLR, Psi), G_SLR_DbtR); ((M (D (-3)), O (Aux_top (0,0,-1,true,DL)), M (U 3)), FBF (1, Psibar, SL, Psi), Half); ((M (U (-3)), O (Aux_top (0,0,1,false,DL)), M (D 3)), FBF (1, Psibar, SL, Psi), G_SL_DbtL) ] else [] let anomalous_top_quqd1_tq = [ ((M (D (-3)), O (Aux_top (0,0,-1,true,QUQD1R)), M (U 3)), FBF (1, Psibar, SR, Psi), C_quqd1R_bt); ((M (U (-3)), O (Aux_top (0,0, 1,true,QUQD1R)), M (D 3)), FBF (1, Psibar, SL, Psi), C_quqd1R_tb); ((M (D (-3)), O (Aux_top (0,0,-1,true,QUQD1L)), M (U 3)), FBF (1, Psibar, SL, Psi), C_quqd1L_bt); ((M (U (-3)), O (Aux_top (0,0, 1,true,QUQD1L)), M (D 3)), FBF (1, Psibar, SR, Psi), C_quqd1L_tb) ] let anomalous_top_quqd1_ff n = List.map mom [ ((U (-n), Aux_top (0,0, 1,false,QUQD1R), D n), FBF (1, Psibar, SR, Psi), Half); ((D (-n), Aux_top (0,0,-1,false,QUQD1R), U n), FBF (1, Psibar, SL, Psi), Half); ((U (-n), Aux_top (0,0, 1,false,QUQD1L), D n), FBF (1, Psibar, SL, Psi), Half); ((D (-n), Aux_top (0,0,-1,false,QUQD1L), U n), FBF (1, Psibar, SR, Psi), Half) ] let anomalous_top_quqd1 = if Flags.top_anom_4f then anomalous_top_quqd1_tq @ ThoList.flatmap anomalous_top_quqd1_ff [1;2;3] else [] let anomalous_top_quqd8_tq = [ ((M (D (-3)), O (Aux_top (0,1,-1,true,QUQD8R)), M (U 3)), FBF (1, Psibar, SR, Psi), C_quqd8R_bt); ((M (U (-3)), O (Aux_top (0,1, 1,true,QUQD8R)), M (D 3)), FBF (1, Psibar, SL, Psi), C_quqd8R_tb); ((M (D (-3)), O (Aux_top (0,1,-1,true,QUQD8L)), M (U 3)), FBF (1, Psibar, SL, Psi), C_quqd8L_bt); ((M (U (-3)), O (Aux_top (0,1, 1,true,QUQD8L)), M (D 3)), FBF (1, Psibar, SR, Psi), C_quqd8L_tb) ] let anomalous_top_quqd8_ff n = List.map mom [ ((U (-n), Aux_top (0,1, 1,false,QUQD8R), D n), FBF (1, Psibar, SR, Psi), Half); ((D (-n), Aux_top (0,1,-1,false,QUQD8R), U n), FBF (1, Psibar, SL, Psi), Half); ((U (-n), Aux_top (0,1, 1,false,QUQD8L), D n), FBF (1, Psibar, SL, Psi), Half); ((D (-n), Aux_top (0,1,-1,false,QUQD8L), U n), FBF (1, Psibar, SR, Psi), Half) ] let anomalous_top_quqd8 = if Flags.top_anom_4f then anomalous_top_quqd8_tq @ ThoList.flatmap anomalous_top_quqd8_ff [1;2;3] else [] let vertices3 = (ThoList.flatmap electromagnetic_currents [1;2;3] @ ThoList.flatmap color_currents [1;2;3] @ ThoList.flatmap neutral_currents [1;2;3] @ (if Flags.ckm_present then charged_currents_ckm else charged_currents_triv) @ yukawa @ triple_gauge @ gauge_higgs @ higgs @ higgs_triangle_vertices @ goldstone_vertices @ tt_threshold_ttA @ tt_threshold_ttZ @ anomalous_ttA @ anomalous_bbA @ anomalous_ttZ @ anomalous_bbZ @ anomalous_tbW @ anomalous_tbWA @ anomalous_tbWZ @ anomalous_ttWW @ anomalous_bbWW @ anomalous_ttG @ anomalous_ttGG @ anomalous_ttH @ anomalous_top_qGuG @ anomalous_top_qBuB @ anomalous_top_qW @ anomalous_top_DuDd @ anomalous_top_quqd1 @ anomalous_top_quqd8) let vertices4 = quartic_gauge @ gauge_higgs4 @ higgs4 let vertices () = (vertices3, vertices4, []) (* For efficiency, make sure that [F.of_vertices vertices] is evaluated only once. *) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 let flavor_of_string = function | "e-" -> M (L 1) | "e+" -> M (L (-1)) | "mu-" -> M (L 2) | "mu+" -> M (L (-2)) | "tau-" -> M (L 3) | "tau+" -> M (L (-3)) | "nue" -> M (N 1) | "nuebar" -> M (N (-1)) | "numu" -> M (N 2) | "numubar" -> M (N (-2)) | "nutau" -> M (N 3) | "nutaubar" -> M (N (-3)) | "u" -> M (U 1) | "ubar" -> M (U (-1)) | "c" -> M (U 2) | "cbar" -> M (U (-2)) | "t" -> M (U 3) | "tbar" -> M (U (-3)) | "d" -> M (D 1) | "dbar" -> M (D (-1)) | "s" -> M (D 2) | "sbar" -> M (D (-2)) | "b" -> M (D 3) | "bbar" -> M (D (-3)) | "g" | "gl" -> G Gl | "A" -> G Ga | "Z" | "Z0" -> G Z | "W+" -> G Wp | "W-" -> G Wm | "H" -> O H | "Aux_t_ttGG0" -> O (Aux_top (2,1, 0,true,TTGG)) | "Aux_ttGG0" -> O (Aux_top (2,1, 0,false,TTGG)) | "Aux_t_tcGG0" -> O (Aux_top (2,1, 0,true,TCGG)) | "Aux_tcGG0" -> O (Aux_top (2,1, 0,false,TCGG)) | "Aux_t_tbWA+" -> O (Aux_top (2,0, 1,true,TBWA)) | "Aux_tbWA+" -> O (Aux_top (2,0, 1,false,TBWA)) | "Aux_t_tbWA-" -> O (Aux_top (2,0,-1,true,TBWA)) | "Aux_tbWA-" -> O (Aux_top (2,0,-1,false,TBWA)) | "Aux_t_tbWZ+" -> O (Aux_top (2,0, 1,true,TBWZ)) | "Aux_tbWZ+" -> O (Aux_top (2,0, 1,false,TBWZ)) | "Aux_t_tbWZ-" -> O (Aux_top (2,0,-1,true,TBWZ)) | "Aux_tbWZ-" -> O (Aux_top (2,0,-1,false,TBWZ)) | "Aux_t_ttWW0" -> O (Aux_top (2,0, 0,true,TTWW)) | "Aux_ttWW0" -> O (Aux_top (2,0, 0,false,TTWW)) | "Aux_t_bbWW0" -> O (Aux_top (2,0, 0,true,BBWW)) | "Aux_bbWW0" -> O (Aux_top (2,0, 0,false,BBWW)) | "Aux_t_qGuG0" -> O (Aux_top (1,1, 0,true,QGUG)) | "Aux_qGuG0" -> O (Aux_top (1,1, 0,false,QGUG)) | "Aux_t_qBuB0" -> O (Aux_top (1,0, 0,true,QBUB)) | "Aux_qBuB0" -> O (Aux_top (1,0, 0,false,QBUB)) | "Aux_t_qW0" -> O (Aux_top (1,0, 0,true,QW)) | "Aux_qW0" -> O (Aux_top (1,0, 0,false,QW)) | "Aux_t_qW+" -> O (Aux_top (1,0, 1,true,QW)) | "Aux_qW+" -> O (Aux_top (1,0, 1,false,QW)) | "Aux_t_qW-" -> O (Aux_top (1,0,-1,true,QW)) | "Aux_qW-" -> O (Aux_top (1,0,-1,false,QW)) | "Aux_t_dL0" -> O (Aux_top (0,0, 0,true,DL)) | "Aux_dL0" -> O (Aux_top (0,0, 0,false,DL)) | "Aux_t_dL+" -> O (Aux_top (0,0, 1,true,DL)) | "Aux_dL+" -> O (Aux_top (0,0, 1,false,DL)) | "Aux_t_dL-" -> O (Aux_top (0,0,-1,true,DL)) | "Aux_dL-" -> O (Aux_top (0,0,-1,false,DL)) | "Aux_t_dR0" -> O (Aux_top (0,0, 0,true,DR)) | "Aux_dR0" -> O (Aux_top (0,0, 0,false,DR)) | "Aux_t_dR+" -> O (Aux_top (0,0, 1,true,DR)) | "Aux_dR+" -> O (Aux_top (0,0, 1,false,DR)) | "Aux_t_dR-" -> O (Aux_top (0,0,-1,true,DR)) | "Aux_dR-" -> O (Aux_top (0,0,-1,false,DR)) | "Aux_t_quqd1L+" -> O (Aux_top (0,0, 1,true,QUQD1L)) | "Aux_quqd1L+" -> O (Aux_top (0,0, 1,false,QUQD1L)) | "Aux_t_quqd1L-" -> O (Aux_top (0,0,-1,true,QUQD1L)) | "Aux_quqd1L-" -> O (Aux_top (0,0,-1,false,QUQD1L)) | "Aux_t_quqd1R+" -> O (Aux_top (0,0, 1,true,QUQD1R)) | "Aux_quqd1R+" -> O (Aux_top (0,0, 1,false,QUQD1R)) | "Aux_t_quqd1R-" -> O (Aux_top (0,0,-1,true,QUQD1R)) | "Aux_quqd1R-" -> O (Aux_top (0,0,-1,false,QUQD1R)) | "Aux_t_quqd8L+" -> O (Aux_top (0,1, 1,true,QUQD8L)) | "Aux_quqd8L+" -> O (Aux_top (0,1, 1,false,QUQD8L)) | "Aux_t_quqd8L-" -> O (Aux_top (0,1,-1,true,QUQD8L)) | "Aux_quqd8L-" -> O (Aux_top (0,1,-1,false,QUQD8L)) | "Aux_t_quqd8R+" -> O (Aux_top (0,1, 1,true,QUQD8R)) | "Aux_quqd8R+" -> O (Aux_top (0,1, 1,false,QUQD8R)) | "Aux_t_quqd8R-" -> O (Aux_top (0,1,-1,true,QUQD8R)) | "Aux_quqd8R-" -> O (Aux_top (0,1,-1,false,QUQD8R)) | _ -> invalid_arg "Modellib.SM.flavor_of_string" let flavor_to_string = function | M f -> begin match f with | L 1 -> "e-" | L (-1) -> "e+" | L 2 -> "mu-" | L (-2) -> "mu+" | L 3 -> "tau-" | L (-3) -> "tau+" | L _ -> invalid_arg "Modellib.SM.flavor_to_string: invalid lepton" | N 1 -> "nue" | N (-1) -> "nuebar" | N 2 -> "numu" | N (-2) -> "numubar" | N 3 -> "nutau" | N (-3) -> "nutaubar" | N _ -> invalid_arg "Modellib.SM.flavor_to_string: invalid neutrino" | U 1 -> "u" | U (-1) -> "ubar" | U 2 -> "c" | U (-2) -> "cbar" | U 3 -> "t" | U (-3) -> "tbar" | U _ -> invalid_arg "Modellib.SM.flavor_to_string: invalid up type quark" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | D _ -> invalid_arg "Modellib.SM.flavor_to_string: invalid down type quark" end | G f -> begin match f with | Gl -> "gl" | Ga -> "A" | Z -> "Z" | Wp -> "W+" | Wm -> "W-" end | O f -> begin match f with | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | H -> "H" | Aux_top (_,_,ch,n,v) -> "Aux_" ^ (if n then "t_" else "") ^ ( begin match v with | TTGG -> "ttGG" | TBWA -> "tbWA" | TBWZ -> "tbWZ" | TTWW -> "ttWW" | BBWW -> "bbWW" | TCGG -> "tcgg" | TUGG -> "tugg" | QGUG -> "qGuG" | QBUB -> "qBuB" | QW -> "qW" | DL -> "dL" | DR -> "dR" | QUQD1L -> "quqd1L" | QUQD1R -> "quqd1R" | QUQD8L -> "quqd8L" | QUQD8R -> "quqd8R" end ) ^ ( if ch > 0 then "+" else if ch < 0 then "-" else "0" ) end let flavor_to_TeX = function | M f -> begin match f with | L 1 -> "e^-" | L (-1) -> "e^+" | L 2 -> "\\mu^-" | L (-2) -> "\\mu^+" | L 3 -> "\\tau^-" | L (-3) -> "\\tau^+" | L _ -> invalid_arg "Modellib.SM.flavor_to_TeX: invalid lepton" | N 1 -> "\\nu_e" | N (-1) -> "\\bar{\\nu}_e" | N 2 -> "\\nu_\\mu" | N (-2) -> "\\bar{\\nu}_\\mu" | N 3 -> "\\nu_\\tau" | N (-3) -> "\\bar{\\nu}_\\tau" | N _ -> invalid_arg "Modellib.SM.flavor_to_TeX: invalid neutrino" | U 1 -> "u" | U (-1) -> "\\bar{u}" | U 2 -> "c" | U (-2) -> "\\bar{c}" | U 3 -> "t" | U (-3) -> "\\bar{t}" | U _ -> invalid_arg "Modellib.SM.flavor_to_TeX: invalid up type quark" | D 1 -> "d" | D (-1) -> "\\bar{d}" | D 2 -> "s" | D (-2) -> "\\bar{s}" | D 3 -> "b" | D (-3) -> "\\bar{b}" | D _ -> invalid_arg "Modellib.SM.flavor_to_TeX: invalid down type quark" end | G f -> begin match f with | Gl -> "g" | Ga -> "\\gamma" | Z -> "Z" | Wp -> "W^+" | Wm -> "W^-" end | O f -> begin match f with | Phip -> "\\phi^+" | Phim -> "\\phi^-" | Phi0 -> "\\phi^0" | H -> "H" | Aux_top (_,_,ch,n,v) -> "\\textnormal{Aux_" ^ (if n then "t_" else "") ^ ( begin match v with | TTGG -> "ttGG" | TBWA -> "tbWA" | TBWZ -> "tbWZ" | TTWW -> "ttWW" | BBWW -> "bbWW" | TCGG -> "tcgg" | TUGG -> "tugg" | QGUG -> "qGuG" | QBUB -> "qBuB" | QW -> "qW" | DL -> "dL" | DR -> "dR" | QUQD1L -> "quqd1L" | QUQD1R -> "quqd1R" | QUQD8L -> "quqd8L" | QUQD8R -> "quqd8R" end ) ^ ( if ch > 0 then "^+" else if ch < 0 then "^-" else "^0" ) ^ "}" end let flavor_symbol = function | M f -> begin match f with | L n when n > 0 -> "l" ^ string_of_int n | L n -> "l" ^ string_of_int (abs n) ^ "b" | N n when n > 0 -> "n" ^ string_of_int n | N n -> "n" ^ string_of_int (abs n) ^ "b" | U n when n > 0 -> "u" ^ string_of_int n | U n -> "u" ^ string_of_int (abs n) ^ "b" | D n when n > 0 -> "d" ^ string_of_int n | D n -> "d" ^ string_of_int (abs n) ^ "b" end | G f -> begin match f with | Gl -> "gl" | Ga -> "a" | Z -> "z" | Wp -> "wp" | Wm -> "wm" end | O f -> begin match f with | Phip -> "pp" | Phim -> "pm" | Phi0 -> "p0" | H -> "h" | Aux_top (_,_,ch,n,v) -> "aux_" ^ (if n then "t_" else "") ^ ( begin match v with | TTGG -> "ttgg" | TBWA -> "tbwa" | TBWZ -> "tbwz" | TTWW -> "ttww" | BBWW -> "bbww" | TCGG -> "tcgg" | TUGG -> "tugg" | QGUG -> "qgug" | QBUB -> "qbub" | QW -> "qw" | DL -> "dl" | DR -> "dr" | QUQD1L -> "quqd1l" | QUQD1R -> "quqd1r" | QUQD8L -> "quqd8l" | QUQD8R -> "quqd8r" end ) ^ "_" ^ ( if ch > 0 then "p" else if ch < 0 then "m" else "0" ) end let pdg = function | M f -> begin match f with | L n when n > 0 -> 9 + 2*n | L n -> - 9 + 2*n | N n when n > 0 -> 10 + 2*n | N n -> - 10 + 2*n | U n when n > 0 -> 2*n | U n -> 2*n | D n when n > 0 -> - 1 + 2*n | D n -> 1 + 2*n end | G f -> begin match f with | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) end | O f -> begin match f with | Phip | Phim -> 27 | Phi0 -> 26 | H -> 25 | Aux_top (_,_,ch,t,f) -> let n = begin match f with | QW -> 0 | QUQD1R -> 1 | QUQD1L -> 2 | QUQD8R -> 3 | QUQD8L -> 4 | _ -> 5 end in (602 + 3*n - ch) * ( if t then (1) else (-1) ) end let mass_symbol f = if ( Flags.tt_threshold && (abs (pdg f)) == 6 ) then "ttv_mtpole(p12*p12)" else "mass(" ^ string_of_int (abs (pdg f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg f)) ^ ")" let constant_symbol = function | Unit -> "unit" | Half -> "half" | Pi -> "PI" | Alpha_QED -> "alpha" | E -> "e" | G_weak -> "g" | Vev -> "vev" | I_G_weak -> "ig" | Sin2thw -> "sin2thw" | Sinthw -> "sinthw" | Costhw -> "costhw" | Q_lepton -> "qlep" | Q_up -> "qup" | Q_down -> "qdwn" | G_NC_lepton -> "gnclep" | G_NC_neutrino -> "gncneu" | G_NC_up -> "gncup" | G_NC_down -> "gncdwn" | G_TVA_ttA -> "gtva_tta" | G_TVA_bbA -> "gtva_bba" | G_VLR_ttZ -> "gvlr_ttz" | G_TVA_ttZ -> "gtva_ttz" | G_VLR_tcZ -> "gvlr_tcz" | G_TVA_tcZ -> "gtva_tcz" | G_VLR_tuZ -> "gvlr_tuz" | G_TVA_tuZ -> "gtva_tuz" | G_TVA_bbZ -> "gtva_bbz" | G_TVA_tcA -> "gtva_tca" | G_TVA_tuA -> "gtva_tua" | VA_ILC_ttA -> "va_ilc_tta" | VA_ILC_ttZ -> "va_ilc_ttz" | G_VLR_btW -> "gvlr_btw" | G_VLR_tbW -> "gvlr_tbw" | G_TLR_btW -> "gtlr_btw" | G_TRL_tbW -> "gtrl_tbw" | G_TLR_btWA -> "gtlr_btwa" | G_TRL_tbWA -> "gtrl_tbwa" | G_TLR_btWZ -> "gtlr_btwz" | G_TRL_tbWZ -> "gtrl_tbwz" | G_TVA_ttWW -> "gtva_ttww" | G_TVA_bbWW -> "gtva_bbww" | G_TVA_ttG -> "gtva_ttg" | G_TVA_ttGG -> "gtva_ttgg" | G_TVA_tcG -> "gtva_tcg" | G_TVA_tcGG -> "gtva_tcgg" | G_TVA_tuG -> "gtva_tug" | G_TVA_tuGG -> "gtva_tugg" | G_SP_ttH -> "gsp_tth" | G_VLR_qGuG -> "gvlr_qgug" | G_VLR_qBuB -> "gvlr_qbub" | G_VLR_qBuB_u -> "gvlr_qbub_u" | G_VLR_qBuB_d -> "gvlr_qbub_d" | G_VLR_qBuB_e -> "gvlr_qbub_e" | G_VL_qBuB_n -> "gvl_qbub_n" | G_VL_qW -> "gvl_qw" | G_VL_qW_u -> "gvl_qw_u" | G_VL_qW_d -> "gvl_qw_d" | G_SL_DttR -> "gsl_dttr" | G_SR_DttR -> "gsr_dttr" | G_SL_DttL -> "gsl_dttl" | G_SLR_DbtR -> "gslr_dbtr" | G_SL_DbtL -> "gsl_dbtl" | C_quqd1R_bt -> "c_quqd1_1" | C_quqd1R_tb -> "conjg(c_quqd1_1)" | C_quqd1L_bt -> "conjg(c_quqd1_2)" | C_quqd1L_tb -> "c_quqd1_2" | C_quqd8R_bt -> "c_quqd8_1" | C_quqd8R_tb -> "conjg(c_quqd8_1)" | C_quqd8L_bt -> "conjg(c_quqd8_2)" | C_quqd8L_tb -> "c_quqd8_2" | G_CC -> "gcc" | G_CCQ (n1,n2) -> "gccq" ^ string_of_int n1 ^ string_of_int n2 | I_Q_W -> "iqw" | I_G_ZWW -> "igzww" | G_WWWW -> "gw4" | G_ZZWW -> "gzzww" | G_AZWW -> "gazww" | G_AAWW -> "gaaww" | I_G1_AWW -> "ig1a" | I_G1_ZWW -> "ig1z" | I_G1_plus_kappa_plus_G4_AWW -> "ig1pkpg4a" | I_G1_plus_kappa_plus_G4_ZWW -> "ig1pkpg4z" | I_G1_plus_kappa_minus_G4_AWW -> "ig1pkmg4a" | I_G1_plus_kappa_minus_G4_ZWW -> "ig1pkmg4z" | I_G1_minus_kappa_plus_G4_AWW -> "ig1mkpg4a" | I_G1_minus_kappa_plus_G4_ZWW -> "ig1mkpg4z" | I_G1_minus_kappa_minus_G4_AWW -> "ig1mkmg4a" | I_G1_minus_kappa_minus_G4_ZWW -> "ig1mkmg4z" | I_lambda_AWW -> "ila" | I_lambda_ZWW -> "ilz" | G5_AWW -> "rg5a" | G5_ZWW -> "rg5z" | I_kappa5_AWW -> "ik5a" | I_kappa5_ZWW -> "ik5z" | I_lambda5_AWW -> "il5a" | I_lambda5_ZWW -> "il5z" | Alpha_WWWW0 -> "alww0" | Alpha_WWWW2 -> "alww2" | Alpha_ZZWW0 -> "alzw0" | Alpha_ZZWW1 -> "alzw1" | Alpha_ZZZZ -> "alzz" | D_Alpha_ZZWW0_S -> "dalzz0_s(gkm,mkm," | D_Alpha_ZZWW0_T -> "dalzz0_t(gkm,mkm," | D_Alpha_ZZWW1_S -> "dalzz1_s(gkm,mkm," | D_Alpha_ZZWW1_T -> "dalzz1_t(gkm,mkm," | D_Alpha_ZZWW1_U -> "dalzz1_u(gkm,mkm," | D_Alpha_WWWW0_S -> "dalww0_s(gkm,mkm," | D_Alpha_WWWW0_T -> "dalww0_t(gkm,mkm," | D_Alpha_WWWW0_U -> "dalww0_u(gkm,mkm," | D_Alpha_WWWW2_S -> "dalww2_s(gkm,mkm," | D_Alpha_WWWW2_T -> "dalww2_t(gkm,mkm," | D_Alpha_ZZZZ_S -> "dalz4_s(gkm,mkm," | D_Alpha_ZZZZ_T -> "dalz4_t(gkm,mkm," | G_HWW -> "ghww" | G_HZZ -> "ghzz" | G_HHWW -> "ghhww" | G_HHZZ -> "ghhzz" | G_Htt -> "ghtt" | G_Hbb -> "ghbb" | G_Hss -> "ghss" | G_Hee -> "ghee" | G_Htautau -> "ghtautau" | G_Hcc -> "ghcc" | G_Hmm -> "ghmm" | G_HGaZ -> "ghgaz" | G_HGaGa -> "ghgaga" | G_Hgg -> "ghgg" | G_HGaGa_anom -> "ghgaga_ac" | G_HGaZ_anom -> "ghgaz_ac" | G_HZZ_anom -> "ghzz_ac" | G_HWW_anom -> "ghww_ac" | G_HGaZ_u -> "ghgaz_u" | G_HZZ_u -> "ghzz_u" | G_HWW_u -> "ghww_u" | G_H3 -> "gh3" | G_H4 -> "gh4" | Gs -> "gs" | I_Gs -> "igs" | G2 -> "gs**2" | Mass f -> "mass" ^ flavor_symbol f | Width f -> "width" ^ flavor_symbol f | K_Matrix_Coeff i -> "kc" ^ string_of_int i | K_Matrix_Pole i -> "kp" ^ string_of_int i | G_HZZ6_V3 -> "ghzz6v3" | G_HZZ6_D ->"ghzz6d" | G_HZZ6_DP ->"ghzz6dp" | G_HZZ6_PB ->"ghzz6pb" | G_HGaZ6_D -> "ghaz6d" | G_HGaZ6_DP -> "ghaz6dp" | G_HGaZ6_PB -> "ghaz6pb" | G_HGaGa6 -> "ghgaga6" | G_HWW_6_D -> "ghww6d" | G_HWW_6_DP ->"ghww6dp" | I_Dim6_AWW_Gauge -> "dim6awwgauge" | I_Dim6_AWW_GGG -> "dim6awwggg" | I_Dim6_AWW_DP -> "dim6awwdp" | I_Dim6_AWW_DW -> "dim6awwdw" | I_Dim6_WWZ_W -> "dim6wwzw" | I_Dim6_WWZ_DPWDW -> "dim6wwzdpwdw" | I_Dim6_WWZ_DW -> "dim6wwzdw" | I_Dim6_WWZ_D -> "dim6wwzd" | Dim6_vev3 -> "dim6vev3" | Dim6_Cphi -> "dim6cphi" (*i | I_Dim6_GGG_G -> "dim6gggg" | I_Dim6_GGG_CG -> "dim6gggcg" i*) | Anom_Dim6_H4_v2 -> "adim6h4v2" | Anom_Dim6_H4_P2 -> "adim6h4p2" | Anom_Dim6_AHWW_DPB -> "adim6ahwwdpb" | Anom_Dim6_AHWW_DPW -> "adim6ahwwdpw" | Anom_Dim6_AHWW_DW -> "adim6ahwwdw" | Anom_Dim6_AAWW_DW -> "adim6aawwdw" | Anom_Dim6_AAWW_W -> "adim6aawww" | Anom_Dim6_HHWW_DW -> "adim6hhwwdw" | Anom_Dim6_HHWW_DPW -> "adim6hhwwdpw" | Anom_Dim6_HWWZ_DW -> "adim6hwwzdw" | Anom_Dim6_HWWZ_DDPW -> "adim6hwwzddpw" | Anom_Dim6_HWWZ_DPW -> "adim6hwwzdpw" | Anom_Dim6_HWWZ_DPB -> "adim6hwwzdpb" | Anom_Dim6_AHHZ_D -> "adim6ahhzd" | Anom_Dim6_AHHZ_DP -> "adim6ahhzdp" | Anom_Dim6_AHHZ_PB -> "adim6ahhzpb" | Anom_Dim6_AZWW_W -> "adim6azwww" | Anom_Dim6_AZWW_DWDPW -> "adim6azwwdwdpw" | Anom_Dim6_WWWW_W -> "adim6wwwww" | Anom_Dim6_WWWW_DWDPW -> "adim6wwwwdwdpw" | Anom_Dim6_WWZZ_W -> "adim6wwzzw" | Anom_Dim6_WWZZ_DWDPW -> "adim6wwzzdwdpw" | Anom_Dim6_HHAA -> "adim6hhaa" | Anom_Dim6_HHZZ_D -> "adim6hhzzd" | Anom_Dim6_HHZZ_DP -> "adim6hhzzdp" | Anom_Dim6_HHZZ_PB -> "adim6hhzzpb" | Anom_Dim6_HHZZ_T -> "adim6hhzzt" end (* \thocwmodulesection{Incomplete Standard Model in $R_\xi$ Gauge} *) (* \begin{dubious} At the end of the day, we want a functor mapping from gauge models in unitarity gauge to $R_\xi$ gauge and vice versa. For this, we will need a more abstract implementation of (spontaneously broken) gauge theories. \end{dubious} *) module SM_Rxi = struct open Coupling module SM = SM(SM_no_anomalous) let options = SM.options type flavor = SM.flavor let flavors = SM.flavors let external_flavors = SM.external_flavors (* Later: [type orders = SM.orders] *) type constant = SM.constant (* Later: [let orders = SM.orders] *) let lorentz = SM.lorentz let color = SM.color let nc = SM.nc let goldstone = SM.goldstone let conjugate = SM.conjugate let fermion = SM.fermion (* \begin{dubious} Check if it makes sense to have separate gauge fixing parameters for each vector boson. There's probably only one independent parameter for each group factor. \end{dubious} *) type gauge = | XiA | XiZ | XiW let gauge_symbol = function | XiA -> "xia" | XiZ -> "xi0" | XiW -> "xipm" (* Change the gauge boson propagators and make the Goldstone bosons propagating. *) let propagator = function | SM.G SM.Ga -> Prop_Gauge XiA | SM.G SM.Z -> Prop_Rxi XiZ | SM.G SM.Wp | SM.G SM.Wm -> Prop_Rxi XiW | SM.O SM.Phip | SM.O SM.Phim | SM.O SM.Phi0 -> Prop_Scalar | f -> SM.propagator f let width = SM.width module Ch = Charges.QQ let charges = SM.charges module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) let vertices = SM.vertices let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 3 let parameters = SM.parameters let flavor_of_string = SM.flavor_of_string let flavor_to_string = SM.flavor_to_string let flavor_to_TeX = SM.flavor_to_TeX let flavor_symbol = SM.flavor_symbol let pdg = SM.pdg let mass_symbol = SM.mass_symbol let width_symbol = SM.width_symbol let constant_symbol = SM.constant_symbol end (* \thocwmodulesection{Groves} *) module Groves (M : Model.Gauge) : Model.Gauge with module Ch = M.Ch = struct let max_generations = 5 let options = M.options type matter_field = M.matter_field * int type gauge_boson = M.gauge_boson type other = M.other type field = | Matter of matter_field | Gauge of gauge_boson | Other of other type flavor = M of matter_field | G of gauge_boson | O of other let matter_field (f, g) = M (f, g) let gauge_boson f = G f let other f = O f let field = function | M f -> Matter f | G f -> Gauge f | O f -> Other f let project = function | M (f, _) -> M.matter_field f | G f -> M.gauge_boson f | O f -> M.other f let inject g f = match M.field f with | M.Matter f -> M (f, g) | M.Gauge f -> G f | M.Other f -> O f type gauge = M.gauge let gauge_symbol = M.gauge_symbol let color f = M.color (project f) let nc () = 3 let pdg f = M.pdg (project f) let lorentz f = M.lorentz (project f) let propagator f = M.propagator (project f) let fermion f = M.fermion (project f) let width f = M.width (project f) let mass_symbol f = M.mass_symbol (project f) let width_symbol f = M.width_symbol (project f) let flavor_symbol f = M.flavor_symbol (project f) type constant = M.constant (* Later: [type orders = M.orders] *) let constant_symbol = M.constant_symbol let max_degree = M.max_degree let parameters = M.parameters (* Later: [let orders = M.orders] *) let conjugate = function | M (_, g) as f -> inject g (M.conjugate (project f)) | f -> inject 0 (M.conjugate (project f)) let read_generation s = try let offset = String.index s '/' in (int_of_string (String.sub s (succ offset) (String.length s - offset - 1)), String.sub s 0 offset) with | Not_found -> (1, s) let format_generation c s = s ^ "/" ^ string_of_int c let flavor_of_string s = let g, s = read_generation s in inject g (M.flavor_of_string s) let flavor_to_string = function | M (_, g) as f -> format_generation g (M.flavor_to_string (project f)) | f -> M.flavor_to_string (project f) let flavor_to_TeX = function | M (_, g) as f -> format_generation g (M.flavor_to_TeX (project f)) | f -> M.flavor_to_TeX (project f) let goldstone = function | G _ as f -> begin match M.goldstone (project f) with | None -> None | Some (f, c) -> Some (inject 0 f, c) end | M _ | O _ -> None let clone generations flavor = match M.field flavor with | M.Matter f -> List.map (fun g -> M (f, g)) generations | M.Gauge f -> [G f] | M.Other f -> [O f] let generations = ThoList.range 1 max_generations let flavors () = ThoList.flatmap (clone generations) (M.flavors ()) let external_flavors () = List.map (fun (s, fl) -> (s, ThoList.flatmap (clone generations) fl)) (M.external_flavors ()) module Ch = M.Ch let charges f = M.charges (project f) module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) (* In the following functions, we might replace [_] by [(M.Gauge _ | M.Other _)], in order to allow the compiler to check completeness. However, this makes the code much less readable. *) let clone3 ((f1, f2, f3), v, c) = match M.field f1, M.field f2, M.field f3 with | M.Matter _, M.Matter _, M.Matter _ -> invalid_arg "Modellib.Groves().vertices: three matter fields!" | M.Matter f1', M.Matter f2', _ -> List.map (fun g -> ((M (f1', g), M (f2', g), inject 0 f3), v, c)) generations | M.Matter f1', _, M.Matter f3' -> List.map (fun g -> ((M (f1', g), inject 0 f2, M (f3', g)), v, c)) generations | _, M.Matter f2', M.Matter f3' -> List.map (fun g -> ((inject 0 f1, M (f2', g), M (f3', g)), v, c)) generations | M.Matter _, _, _ | _, M.Matter _, _ | _, _, M.Matter _ -> invalid_arg "Modellib.Groves().vertices: lone matter field!" | _, _, _ -> [(inject 0 f1, inject 0 f2, inject 0 f3), v, c] let clone4 ((f1, f2, f3, f4), v, c) = match M.field f1, M.field f2, M.field f3, M.field f4 with | M.Matter _, M.Matter _, M.Matter _, M.Matter _ -> invalid_arg "Modellib.Groves().vertices: four matter fields!" | M.Matter _, M.Matter _, M.Matter _, _ | M.Matter _, M.Matter _, _, M.Matter _ | M.Matter _, _, M.Matter _, M.Matter _ | _, M.Matter _, M.Matter _, M.Matter _ -> invalid_arg "Modellib.Groves().vertices: three matter fields!" | M.Matter f1', M.Matter f2', _, _ -> List.map (fun g -> ((M (f1', g), M (f2', g), inject 0 f3, inject 0 f4), v, c)) generations | M.Matter f1', _, M.Matter f3', _ -> List.map (fun g -> ((M (f1', g), inject 0 f2, M (f3', g), inject 0 f4), v, c)) generations | M.Matter f1', _, _, M.Matter f4' -> List.map (fun g -> ((M (f1', g), inject 0 f2, inject 0 f3, M (f4', g)), v, c)) generations | _, M.Matter f2', M.Matter f3', _ -> List.map (fun g -> ((inject 0 f1, M (f2', g), M (f3', g), inject 0 f4), v, c)) generations | _, M.Matter f2', _, M.Matter f4' -> List.map (fun g -> ((inject 0 f1, M (f2', g), inject 0 f3, M (f4', g)), v, c)) generations | _, _, M.Matter f3', M.Matter f4' -> List.map (fun g -> ((inject 0 f1, inject 0 f2, M (f3', g), M (f4', g)), v, c)) generations | M.Matter _, _, _, _ | _, M.Matter _, _, _ | _, _, M.Matter _, _ | _, _, _, M.Matter _ -> invalid_arg "Modellib.Groves().vertices: lone matter field!" | _, _, _, _ -> [(inject 0 f1, inject 0 f2, inject 0 f3, inject 0 f4), v, c] let clonen (fl, v, c) = match List.map M.field fl with | _ -> failwith "Modellib.Groves().vertices: incomplete" let vertices () = let vertices3, vertices4, verticesn = M.vertices () in (ThoList.flatmap clone3 vertices3, ThoList.flatmap clone4 vertices4, ThoList.flatmap clonen verticesn) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table (* \begin{dubious} The following (incomplete) alternative implementations are included for illustrative purposes only: \end{dubious} *) let injectl g fcl = List.map (fun (f, c) -> (inject g f, c)) fcl let alt_fuse2 f1 f2 = match f1, f2 with | M (f1', g1'), M (f2', g2') -> if g1' = g2' then injectl 0 (M.fuse2 (M.matter_field f1') (M.matter_field f2')) else [] | M (f1', g'), _ -> injectl g' (M.fuse2 (M.matter_field f1') (project f2)) | _, M (f2', g') -> injectl g' (M.fuse2 (project f1) (M.matter_field f2')) | _, _ -> injectl 0 (M.fuse2 (project f1) (project f2)) let alt_fuse3 f1 f2 f3 = match f1, f2, f3 with | M (f1', g1'), M (f2', g2'), M (f3', g3') -> invalid_arg "Modellib.Groves().fuse3: three matter fields!" | M (f1', g1'), M (f2', g2'), _ -> if g1' = g2' then injectl 0 (M.fuse3 (M.matter_field f1') (M.matter_field f2') (project f3)) else [] | M (f1', g1'), _, M (f3', g3') -> if g1' = g3' then injectl 0 (M.fuse3 (M.matter_field f1') (project f2) (M.matter_field f3')) else [] | _, M (f2', g2'), M (f3', g3') -> if g2' = g3' then injectl 0 (M.fuse3 (project f1) (M.matter_field f2') (M.matter_field f3')) else [] | M (f1', g'), _, _ -> injectl g' (M.fuse3 (M.matter_field f1') (project f2) (project f3)) | _, M (f2', g'), _ -> injectl g' (M.fuse3 (project f1) (M.matter_field f2') (project f3)) | _, _, M (f3', g') -> injectl g' (M.fuse3 (project f1) (project f2) (M.matter_field f3')) | _, _, _ -> injectl 0 (M.fuse3 (project f1) (project f2) (project f3)) end (* \thocwmodulesection{MSM With Cloned Families} *) module SM_clones = Groves(SM(SM_no_anomalous)) Index: trunk/omega/src/modellib_BSM.ml =================================================================== --- trunk/omega/src/modellib_BSM.ml (revision 8413) +++ trunk/omega/src/modellib_BSM.ml (revision 8414) @@ -1,15225 +1,15247 @@ (* modellib_BSM.ml -- Copyright (C) 1999-2020 by Wolfgang Kilian Thorsten Ohl Juergen Reuter with contributions from cf. main AUTHORS file WHIZARD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. WHIZARD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *) (* \thocwmodulesection{Littlest Higgs Model} *) module type BSM_flags = sig val u1_gauged : bool val anom_ferm_ass : bool end module BSM_bsm : BSM_flags = struct let u1_gauged = true let anom_ferm_ass = false end module BSM_ungauged : BSM_flags = struct let u1_gauged = false let anom_ferm_ass = false end module BSM_anom : BSM_flags = struct let u1_gauged = false let anom_ferm_ass = true end module Littlest (Flags : BSM_flags) = struct open Coupling let default_width = ref Timelike let use_fudged_width = ref false let options = Options.create [ "constant_width", Arg.Unit (fun () -> default_width := Constant), "use constant width (also in t-channel)"; "fudged_width", Arg.Set use_fudged_width, "use fudge factor for charge particle width"; "custom_width", Arg.String (fun f -> default_width := Custom f), "use custom width"; "cancel_widths", Arg.Unit (fun () -> default_width := Vanishing), "use vanishing width"; "cms_width", Arg.Unit (fun () -> default_width := Complex_Mass), - "use complex mass scheme" ] + "use complex mass scheme" ; + "running_width", Arg.Unit (fun () -> default_width := Running), + "use running width" ] let gauge_symbol () = failwith "Modellib_BSM.Littlest.gauge_symbol: internal error" type matter_field = L of int | N of int | U of int | D of int | TopH | TopHb type gauge_boson = Ga | Wp | Wm | Z | Gl | WHp | WHm | ZH | AH type other = Phip | Phim | Phi0 | H | Eta | Psi0 | Psi1 | Psip | Psim | Psipp | Psimm type flavor = M of matter_field | G of gauge_boson | O of other let matter_field f = M f let gauge_boson f = G f let other f = O f type field = | Matter of matter_field | Gauge of gauge_boson | Other of other let field = function | M f -> Matter f | G f -> Gauge f | O f -> Other f type gauge = unit let gauge_symbol () = failwith "Modellib_BSM.Littlest.gauge_symbol: internal error" let family n = List.map matter_field [ L n; N n; U n; D n ] (* Since [Phi] already belongs to the EW Goldstone bosons we use [Psi] for the TeV scale complex triplet. *) let external_flavors () = [ "1st Generation", ThoList.flatmap family [1; -1]; "2nd Generation", ThoList.flatmap family [2; -2]; "3rd Generation", ThoList.flatmap family [3; -3]; "Heavy Quarks", List.map matter_field [TopH; TopHb]; "Heavy Scalars", List.map other [Psi0; Psi1; Psip; Psim; Psipp; Psimm]; "Gauge Bosons", List.map gauge_boson (if Flags.u1_gauged then [Ga; Z; Wp; Wm; Gl; WHp; WHm; ZH; AH] else [Ga; Z; Wp; Wm; Gl; WHp; WHm; ZH]); "Higgs", List.map other (if Flags.u1_gauged then [H] else [H; Eta]); "Goldstone Bosons", List.map other [Phip; Phim; Phi0] ] let flavors () = ThoList.flatmap snd (external_flavors ()) let spinor n = if n >= 0 then Spinor else ConjSpinor let lorentz = function | M f -> begin match f with | L n -> spinor n | N n -> spinor n | U n -> spinor n | D n -> spinor n | TopH -> Spinor | TopHb -> ConjSpinor end | G f -> begin match f with | Ga | Gl -> Vector | Wp | Wm | Z | WHp | WHm | ZH | AH -> Massive_Vector end | O f -> begin match f with | Phip | Phim | Phi0 | H | Eta | Psi0 | Psi1 | Psip | Psim | Psipp | Psimm -> Scalar end let color = function | M (U n) -> Color.SUN (if n > 0 then 3 else -3) | M (D n) -> Color.SUN (if n > 0 then 3 else -3) | M TopH -> Color.SUN 3 | M TopHb -> Color.SUN (-3) | G Gl -> Color.AdjSUN 3 | _ -> Color.Singlet let nc () = 3 let prop_spinor n = if n >= 0 then Prop_Spinor else Prop_ConjSpinor let propagator = function | M f -> begin match f with | L n -> prop_spinor n | N n -> prop_spinor n | U n -> prop_spinor n | D n -> prop_spinor n | TopH -> Prop_Spinor | TopHb -> Prop_ConjSpinor end | G f -> begin match f with | Ga | Gl -> Prop_Feynman | Wp | Wm | Z | WHp | WHm | ZH | AH -> Prop_Unitarity end | O f -> begin match f with | Phip | Phim | Phi0 -> Only_Insertion | H | Eta | Psi0 | Psi1 | Psip | Psim | Psipp | Psimm -> Prop_Scalar end (* Optionally, ask for the fudge factor treatment for the widths of charged particles. Currently, this only applies to $W^\pm$ and top. *) let width f = if !use_fudged_width then match f with | G Wp | G Wm | M (U 3) | M (U (-3)) | G WHp | G WHm | G ZH | G AH | M TopH | M TopHb -> Fudged | _ -> !default_width else !default_width let goldstone = function | G f -> begin match f with | Wp -> Some (O Phip, Coupling.Integer 1) | Wm -> Some (O Phim, Coupling.Integer 1) | Z -> Some (O Phi0, Coupling.Integer 1) | _ -> None end | _ -> None let conjugate = function | M f -> M (begin match f with | L n -> L (-n) | N n -> N (-n) | U n -> U (-n) | D n -> D (-n) | TopH -> TopHb | TopHb -> TopH end) | G f -> G (begin match f with | Gl -> Gl | Ga -> Ga | Z -> Z | Wp -> Wm | Wm -> Wp | WHm -> WHp | WHp -> WHm | ZH -> ZH | AH -> AH end) | O f -> O (begin match f with | Psi0 -> Psi0 | Psi1 -> Psi1 | Psip -> Psim | Psim -> Psip | Psipp -> Psimm | Psimm -> Psipp | Phip -> Phim | Phim -> Phip | Phi0 -> Phi0 | H -> H | Eta -> Eta end) let fermion = function | M f -> begin match f with | L n -> if n > 0 then 1 else -1 | N n -> if n > 0 then 1 else -1 | U n -> if n > 0 then 1 else -1 | D n -> if n > 0 then 1 else -1 | TopH -> 1 | TopHb -> -1 end | G f -> begin match f with | Gl | Ga | Z | Wp | Wm | WHp | WHm | AH | ZH -> 0 end | O f -> begin match f with | Psi0 | Psi1 | Psip | Psim | Psipp | Psimm | Phip | Phim | Phi0 | H | Eta -> 0 end (* This model does NOT have a conserved generation charge even in absence of CKM mixing because of the heavy top admixture. *) module Ch = Charges.QQ let ( // ) = Algebra.Small_Rational.make let charge = function | M f -> begin match f with | L n -> if n > 0 then -1//1 else 1//1 | N n -> 0//1 | U n -> if n > 0 then 2//3 else -2//3 | D n -> if n > 0 then -1//3 else 1//3 | TopH -> 2//3 | TopHb -> -2//3 end | G f -> begin match f with | Gl | Ga | Z | AH | ZH -> 0//1 | Wp | WHp -> 1//1 | Wm | WHm -> -1//1 end | O f -> begin match f with | H | Phi0 | Eta | Psi1 | Psi0 -> 0//1 | Phip | Psip -> 1//1 | Phim | Psim -> -1//1 | Psipp -> 2//1 | Psimm -> -2//1 end let lepton = function | M f -> begin match f with | L n | N n -> if n > 0 then 1//1 else -1//1 | U _ | D _ | _ -> 0//1 end | G _ | O _ -> 0//1 let baryon = function | M f -> begin match f with | L _ | N _ -> 0//1 | U n | D n -> if n > 0 then 1//1 else -1//1 | TopH -> 1//1 | TopHb -> -1//1 end | G _ | O _ -> 0//1 let charges f = [ charge f; lepton f; baryon f] type constant = | Unit | Pi | Alpha_QED | Sin2thw | Sinthw | Costhw | E | G_weak | Vev | VHeavy | Supp | Supp2 | Sinpsi | Cospsi | Atpsi | Sccs (* Mixing angles of SU(2) *) | Q_lepton | Q_up | Q_down | Q_Z_up | G_CC | G_CCtop | G_NC_neutrino | G_NC_lepton | G_NC_up | G_NC_down | G_NC_heavy | G_NC_h_neutrino | G_NC_h_lepton | G_NC_h_up | G_NC_h_down | G_CC_heavy | G_ZHTHT | G_ZTHT | G_AHTHTH | G_AHTHT | G_AHTT | G_CC_WH | G_CC_W | I_Q_W | I_G_ZWW | I_G_WWW | I_G_AHWW | I_G_ZHWW | I_G_ZWHW | I_G_AHWHWH | I_G_ZHWHWH | I_G_AHWHW | I_Q_H | G_WWWW | G_ZZWW | G_AZWW | G_AAWW | G_WH4 | G_WHWHWW | G_WHWWW | G_WH3W | G_WWAAH | G_WWAZH | G_WWZZH | G_WWZAH | G_WHWHAAH | G_WHWHAZH | G_WHWHZZH | G_WHWHZAH | G_WWZHAH | G_WHWHZHAH | G_WHWZZ | G_WHWAZ | G_WHWAAH | G_WHWZAH | G_WHWZHZH | G_WHWZHAH | G_WHWAZH | G_WHWZZH | G_HWW | G_HHWW | G_HZZ | G_HHZZ | G_PsiWW | G_PsiWHW | G_PsiZZ | G_PsiZHZH | G_PsiZHZ | G_PsiZAH | G_PsiZHAH | G_PsiAHAH | G_PsiZW | G_PsiZWH | G_PsiAHW | G_PsiAHWH | G_PsiZHW | G_PsiZHWH | G_PsippWW | G_PsippWHW | G_PsippWHWH | G_PsiHW | G_PsiHWH | G_Psi0W | G_Psi0WH | G_Psi1W | G_Psi1WH | G_PsiPPW | G_PsiPPWH | G_Psi1HAH | G_Psi01AH | G_AHPsip | G_Psi1HZ | G_Psi1HZH | G_Psi01Z | G_Psi01ZH | G_ZPsip | G_ZPsipp | G_ZHPsipp | G_HHAA | G_HHWHW | G_HHZHZ | G_HHAHZ | G_HHZHAH | G_HPsi0WW | G_HPsi0WHW | G_HPsi0ZZ | G_HPsi0ZHZH | G_HPsi0ZHZ | G_HPsi0AHAH | G_HPsi0ZAH | G_HPsi0ZHAH | G_HPsipWA | G_HPsipWHA | G_HPsipWZ | G_HPsipWHZ | G_HPsipWAH | G_HPsipWHAH | G_HPsipWZH | G_HPsipWHZH | G_HPsippWW | G_HPsippWHWH | G_HPsippWHW | G_Psi00ZH | G_Psi00AH | G_Psi00ZHAH | G_Psi0pWA | G_Psi0pWHA | G_Psi0pWZ | G_Psi0pWHZ | G_Psi0pWAH | G_Psi0pWHAH | G_Psi0pWZH | G_Psi0pWHZH | G_Psi0ppWW | G_Psi0ppWHWH | G_Psi0ppWHW | I_G_Psi0pWA | I_G_Psi0pWHA | I_G_Psi0pWZ | I_G_Psi0pWHZ | I_G_Psi0pWAH | I_G_Psi0pWHAH | I_G_Psi0pWZH | I_G_Psi0pWHZH | I_G_Psi0ppWW | I_G_Psi0ppWHWH | I_G_Psi0ppWHW | G_PsippZZ | G_PsippZHZH | G_PsippAZ | G_PsippAAH | G_PsippZAH | G_PsippWA | G_PsippWHA | G_PsippWZ | G_PsippWHZ | G_PsippWAH | G_PsippWHAH | G_PsippWZH | G_PsippWHZH | G_PsiccZZ | G_PsiccAZ | G_PsiccAAH | G_PsiccZZH | G_PsiccAZH | G_PsiccZAH | G_Htt | G_Hbb | G_Hcc | G_Htautau | G_H3 | G_H4 | G_Hthth | G_Htht | G_Ethth | G_Etht | G_Ett | G_HHtt | G_HHthth | G_HHtht | G_Psi0tt | G_Psi0bb | G_Psi0cc | G_Psi0tautau | G_Psi1tt | G_Psi1bb | G_Psi1cc | G_Psi1tautau | G_Psipq3 | G_Psipq2 | G_Psipl3 | G_Psi0tth | G_Psi1tth | G_Psipbth | G_Ebb | G_HGaGa | G_HGaZ | G_EGaGa | G_EGaZ | G_EGlGl | Gs | I_Gs | G2 | G_HWHW | G_HWHWH | G_HAHAH | G_HZHZ | G_HZHAH | G_HAHZ | Mass of flavor | Width of flavor (* Two integer counters for the QCD and EW order of the couplings. *) type orders = int * int let orders = function | _ -> (0,0) let input_parameters = [] let derived_parameters = [] let g_over_2_costh = Quot (Neg (Atom G_weak), Prod [Integer 2; Atom Costhw]) let nc_coupling c t3 q = (Real_Array c, [Prod [g_over_2_costh; Diff (t3, Prod [Integer 2; q; Atom Sin2thw])]; Prod [g_over_2_costh; t3]]) let half = Quot (Integer 1, Integer 2) let derived_parameter_arrays = [ nc_coupling G_NC_neutrino half (Integer 0); nc_coupling G_NC_lepton (Neg half) (Integer (-1)); nc_coupling G_NC_up half (Quot (Integer 2, Integer 3)); nc_coupling G_NC_down (Neg half) (Quot (Integer (-1), Integer 3)); nc_coupling G_NC_h_neutrino half (Integer 0); nc_coupling G_NC_h_lepton (Neg half) (Integer (-1)); nc_coupling G_NC_h_up half (Quot (Integer 2, Integer 3)); nc_coupling G_NC_h_down (Neg half) (Quot (Integer (-1), Integer 3)) ] let parameters () = { input = input_parameters; derived = derived_parameters; derived_arrays = derived_parameter_arrays } module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) let mgm ((m1, g, m2), fbf, c) = ((M m1, G g, M m2), fbf, c) let mhm ((m1, h, m2), fbf, c) = ((M m1, O h, M m2), fbf, c) let tgc ((g1, g2, g3), t, c) = ((G g1, G g2, G g3), t, c) let qgc ((g1, g2, g3, g4), t, c) = ((G g1, G g2, G g3, G g4), t, c) let hgg ((h, g1, g2), coup, c) = ((O h, G g1, G g2), coup, c) let ghh ((g, h1, h2), coup, c) = ((G g, O h1, O h2), coup, c) let hhgg ((h1, h2, g1, g2), coup, c) = ((O h1, O h2, G g1, G g2), coup, c) let electromagnetic_currents n = List.map mgm [ ((L (-n), Ga, L n), FBF (1, Psibar, V, Psi), Q_lepton); ((U (-n), Ga, U n), FBF (1, Psibar, V, Psi), Q_up); ((D (-n), Ga, D n), FBF (1, Psibar, V, Psi), Q_down) ] let neutral_currents n = List.map mgm [ ((L (-n), Z, L n), FBF (1, Psibar, VA, Psi), G_NC_lepton); ((N (-n), Z, N n), FBF (1, Psibar, VA, Psi), G_NC_neutrino); ((U (-n), Z, U n), FBF (1, Psibar, VA, Psi), G_NC_up); ((D (-n), Z, D n), FBF (1, Psibar, VA, Psi), G_NC_down) ] (* The sign of this coupling is just the one of the T3, being -(1/2) for leptons and down quarks, and +(1/2) for neutrinos and up quarks. *) let neutral_heavy_currents n = List.map mgm ([ ((L (-n), ZH, L n), FBF ((-1), Psibar, VL, Psi), G_NC_heavy); ((N (-n), ZH, N n), FBF (1, Psibar, VL, Psi), G_NC_heavy); ((U (-n), ZH, U n), FBF (1, Psibar, VL, Psi), G_NC_heavy); ((D (-n), ZH, D n), FBF ((-1), Psibar, VL, Psi), G_NC_heavy)] @ (if Flags.u1_gauged then [ ((L (-n), AH, L n), FBF (1, Psibar, VA, Psi), G_NC_h_lepton); ((N (-n), AH, N n), FBF (1, Psibar, VA, Psi), G_NC_h_neutrino); ((D (-n), AH, D n), FBF (1, Psibar, VA, Psi), G_NC_h_down)] else [])) let color_currents n = List.map mgm [ ((D (-n), Gl, D n), FBF ((-1), Psibar, V, Psi), Gs); ((U (-n), Gl, U n), FBF ((-1), Psibar, V, Psi), Gs)] let heavy_top_currents = List.map mgm ([ ((TopHb, Ga, TopH), FBF (1, Psibar, V, Psi), Q_up); ((TopHb, Z, TopH), FBF (1, Psibar, V, Psi), Q_Z_up); ((TopHb, Gl, TopH), FBF (1, Psibar, V, Psi), Gs); ((TopHb, Z, U 3), FBF (1, Psibar, VL, Psi), G_ZTHT); ((U (-3), Z, TopH), FBF (1, Psibar, VL, Psi), G_ZTHT); ((TopHb, ZH, U 3), FBF (1, Psibar, VL, Psi), G_ZHTHT); ((U (-3), ZH, TopH), FBF (1, Psibar, VL, Psi), G_ZHTHT); ((U (-3), Wp, D 3), FBF (1, Psibar, VL, Psi), G_CCtop); ((D (-3), Wm, U 3), FBF (1, Psibar, VL, Psi), G_CCtop); ((TopHb, WHp, D 3), FBF (1, Psibar, VL, Psi), G_CC_WH); ((D (-3), WHm, TopH), FBF (1, Psibar, VL, Psi), G_CC_WH); ((TopHb, Wp, D 3), FBF (1, Psibar, VL, Psi), G_CC_W); ((D (-3), Wm, TopH), FBF (1, Psibar, VL, Psi), G_CC_W)] @ (if Flags.u1_gauged then [ ((U (-3), AH, U 3), FBF (1, Psibar, VA, Psi), G_AHTT); ((TopHb, AH, TopH), FBF (1, Psibar, VA, Psi), G_AHTHTH); ((TopHb, AH, U 3), FBF (1, Psibar, VR, Psi), G_AHTHT); ((U (-3), AH, TopH), FBF (1, Psibar, VR, Psi), G_AHTHT)] else [])) (* \begin{equation} \mathcal{L}_{\textrm{CC}} = - \frac{g}{2\sqrt2} \sum_i \bar\psi_i (T^+\fmslash{W}^+ + T^-\fmslash{W}^-)(1-\gamma_5)\psi_i \end{equation} *) let charged_currents n = List.map mgm [ ((L (-n), Wm, N n), FBF (1, Psibar, VL, Psi), G_CC); ((N (-n), Wp, L n), FBF (1, Psibar, VL, Psi), G_CC); ((D (-n), Wm, U n), FBF (1, Psibar, VL, Psi), G_CC); ((U (-n), Wp, D n), FBF (1, Psibar, VL, Psi), G_CC) ] let charged_heavy_currents n = List.map mgm ([ ((L (-n), WHm, N n), FBF (1, Psibar, VL, Psi), G_CC_heavy); ((N (-n), WHp, L n), FBF (1, Psibar, VL, Psi), G_CC_heavy); ((D (-n), WHm, U n), FBF (1, Psibar, VL, Psi), G_CC_heavy); ((U (-n), WHp, D n), FBF (1, Psibar, VL, Psi), G_CC_heavy)] @ (if Flags.u1_gauged then [ ((U (-n), AH, U n), FBF (1, Psibar, VA, Psi), G_NC_h_up)] else [])) (* We specialize the third generation since there is an additional shift coming from the admixture of the heavy top quark. The universal shift, coming from the mixing in the non-Abelian gauge boson sector is unobservable. (Redefinition of coupling constants by measured ones. *) let yukawa = List.map mhm [ ((U (-3), H, U 3), FBF (1, Psibar, S, Psi), G_Htt); ((D (-3), H, D 3), FBF (1, Psibar, S, Psi), G_Hbb); ((U (-2), H, U 2), FBF (1, Psibar, S, Psi), G_Hcc); ((L (-3), H, L 3), FBF (1, Psibar, S, Psi), G_Htautau)] let yukawa_add' = List.map mhm [ ((TopHb, H, TopH), FBF (1, Psibar, S, Psi), G_Hthth); ((TopHb, H, U 3), FBF (1, Psibar, SLR, Psi), G_Htht); ((U (-3), H, TopH), FBF (1, Psibar, SLR, Psi), G_Htht); ((U (-3), Psi0, U 3), FBF (1, Psibar, S, Psi), G_Psi0tt); ((D (-3), Psi0, D 3), FBF (1, Psibar, S, Psi), G_Psi0bb); ((U (-2), Psi0, U 2), FBF (1, Psibar, S, Psi), G_Psi0cc); ((L (-3), Psi0, L 3), FBF (1, Psibar, S, Psi), G_Psi0tautau); ((U (-3), Psi1, U 3), FBF (1, Psibar, P, Psi), G_Psi1tt); ((D (-3), Psi1, D 3), FBF (1, Psibar, P, Psi), G_Psi1bb); ((U (-2), Psi1, U 2), FBF (1, Psibar, P, Psi), G_Psi1cc); ((L (-3), Psi1, L 3), FBF (1, Psibar, P, Psi), G_Psi1tautau); ((U (-3), Psip, D 3), FBF (1, Psibar, SLR, Psi), G_Psipq3); ((U (-2), Psip, D 2), FBF (1, Psibar, SLR, Psi), G_Psipq2); ((N (-3), Psip, L 3), FBF (1, Psibar, SR, Psi), G_Psipl3); ((D (-3), Psim, U 3), FBF (1, Psibar, SLR, Psi), G_Psipq3); ((D (-2), Psim, U 2), FBF (1, Psibar, SLR, Psi), G_Psipq2); ((L (-3), Psim, N 3), FBF (1, Psibar, SL, Psi), G_Psipl3); ((TopHb, Psi0, U 3), FBF (1, Psibar, SL, Psi), G_Psi0tth); ((U (-3), Psi0, TopH), FBF (1, Psibar, SR, Psi), G_Psi0tth); ((TopHb, Psi1, U 3), FBF (1, Psibar, SL, Psi), G_Psi1tth); ((U (-3), Psi1, TopH), FBF (1, Psibar, SR, Psi), G_Psi1tth); ((TopHb, Psip, D 3), FBF (1, Psibar, SL, Psi), G_Psipbth); ((D (-3), Psim, TopH), FBF (1, Psibar, SR, Psi), G_Psipbth)] let yukawa_add = if Flags.u1_gauged then yukawa_add' else yukawa_add' @ List.map mhm [ ((U (-3), Eta, U 3), FBF (1, Psibar, P, Psi), G_Ett); ((TopHb, Eta, U 3), FBF (1, Psibar, SLR, Psi), G_Etht); ((D (-3), Eta, D 3), FBF (1, Psibar, P, Psi), G_Ebb); ((U (-3), Eta, TopH), FBF (1, Psibar, SLR, Psi), G_Etht)] (* \begin{equation} \mathcal{L}_{\textrm{TGC}} = - e \partial_\mu A_\nu W_+^\mu W_-^\nu + \ldots - e \cot\theta_w \partial_\mu Z_\nu W_+^\mu W_-^\nu + \ldots \end{equation} *) let standard_triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW); ((Gl, Gl, Gl), Gauge_Gauge_Gauge 1, I_Gs) ] let heavy_triple_gauge = List.map tgc ([ ((Ga, WHm, WHp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, WHm, WHp), Gauge_Gauge_Gauge 1, I_G_ZWW); ((ZH, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZHWW); ((Z, WHm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWHW); ((Z, Wm, WHp), Gauge_Gauge_Gauge (-1), I_G_ZWHW); ((ZH, WHm, Wp), Gauge_Gauge_Gauge 1, I_G_WWW); ((ZH, Wm, WHp), Gauge_Gauge_Gauge (-1), I_G_WWW); ((ZH, WHm, WHp), Gauge_Gauge_Gauge (-1), I_G_ZHWHWH)] @ (if Flags.u1_gauged then [ ((AH, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_AHWW); ((AH, WHm, Wp), Gauge_Gauge_Gauge 1, I_G_AHWHW); ((AH, Wm, WHp), Gauge_Gauge_Gauge (-1), I_G_AHWHW); ((AH, WHm, WHp), Gauge_Gauge_Gauge 1, I_G_AHWHWH)] else [])) let triple_gauge = standard_triple_gauge @ heavy_triple_gauge let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] let standard_quartic_gauge = List.map qgc [ (Wm, Wp, Wm, Wp), gauge4, G_WWWW; (Wm, Z, Wp, Z), minus_gauge4, G_ZZWW; (Wm, Z, Wp, Ga), minus_gauge4, G_AZWW; (Wm, Ga, Wp, Ga), minus_gauge4, G_AAWW; (Gl, Gl, Gl, Gl), gauge4, G2 ] let heavy_quartic_gauge = List.map qgc ([ (WHm, Wp, WHm, Wp), gauge4, G_WWWW; (Wm, WHp, Wm, WHp), gauge4, G_WWWW; (WHm, WHp, WHm, WHp), gauge4, G_WH4; (Wm, Wp, WHm, WHp), gauge4, G_WHWHWW; (Wm, Wp, Wm, WHp), gauge4, G_WHWWW; (Wm, Wp, WHm, Wp), gauge4, G_WHWWW; (WHm, WHp, Wm, WHp), gauge4, G_WH3W; (WHm, WHp, WHm, Wp), gauge4, G_WH3W; (WHm, Z, WHp, Z), minus_gauge4, G_ZZWW; (WHm, Z, WHp, Ga), minus_gauge4, G_AZWW; (WHm, Ga, WHp, ZH), minus_gauge4, G_AAWW; (WHm, Z, WHp, ZH), minus_gauge4, G_ZZWW; (Wm, ZH, Wp, ZH), minus_gauge4, G_WWWW; (Wm, Ga, Wp, ZH), minus_gauge4, G_WWAZH; (Wm, Z, Wp, ZH), minus_gauge4, G_WWZZH; (WHm, Ga, WHp, ZH), minus_gauge4, G_WHWHAZH; (WHm, Z, WHp, ZH), minus_gauge4, G_WHWHZZH; (WHm, ZH, WHp, ZH), minus_gauge4, G_WH4; (WHm, Z, Wp, Z), minus_gauge4, G_WHWZZ; (Wm, Z, WHp, Z), minus_gauge4, G_WHWZZ; (WHm, Ga, Wp, Z), minus_gauge4, G_WHWAZ; (Wm, Ga, WHp, Z), minus_gauge4, G_WHWAZ; (WHm, ZH, Wp, ZH), minus_gauge4, G_WHWZHZH; (Wm, ZH, WHp, ZH), minus_gauge4, G_WHWZHZH; (WHm, Ga, Wp, ZH), minus_gauge4, G_WHWAZH; (Wm, Ga, WHp, ZH), minus_gauge4, G_WHWAZH; (WHm, Z, Wp, ZH), minus_gauge4, G_WHWZZH; (Wm, Z, WHp, ZH), minus_gauge4, G_WHWZZH] @ (if Flags.u1_gauged then [ (Wm, Ga, Wp, AH), minus_gauge4, G_WWAAH; (Wm, Z, Wp, AH), minus_gauge4, G_WWZAH; (WHm, Ga, WHp, AH), minus_gauge4, G_WHWHAAH; (WHm, Z, WHp, AH), minus_gauge4, G_WHWHZAH; (Wm, ZH, Wp, AH), minus_gauge4, G_WWZHAH; (WHm, ZH, WHp, AH), minus_gauge4, G_WHWHZHAH; (WHm, Ga, Wp, AH), minus_gauge4, G_WHWAAH; (Wm, Ga, WHp, AH), minus_gauge4, G_WHWAAH; (WHm, Z, Wp, AH), minus_gauge4, G_WHWZAH; (Wm, Z, WHp, AH), minus_gauge4, G_WHWZAH; (WHm, ZH, Wp, AH), minus_gauge4, G_WHWZHAH; (Wm, ZH, WHp, AH), minus_gauge4, G_WHWZHAH] else [])) let quartic_gauge = standard_quartic_gauge @ heavy_quartic_gauge let standard_gauge_higgs' = List.map hgg [ ((H, Wp, Wm), Scalar_Vector_Vector 1, G_HWW); ((H, Z, Z), Scalar_Vector_Vector 1, G_HZZ) ] let heavy_gauge_higgs = List.map hgg ([ ((H, Wp, WHm), Scalar_Vector_Vector 1, G_HWHW); ((H, WHp, Wm), Scalar_Vector_Vector 1, G_HWHW); ((H, WHp, WHm), Scalar_Vector_Vector 1, G_HWHWH); ((H, ZH, ZH), Scalar_Vector_Vector 1, G_HWHWH); ((H, ZH, Z), Scalar_Vector_Vector 1, G_HZHZ); ((H, Wp, Wm), Scalar_Vector_Vector 1, G_HZHAH)] @ (if Flags.u1_gauged then [((H, AH, AH), Scalar_Vector_Vector 1, G_HAHAH); ((H, Z, AH), Scalar_Vector_Vector 1, G_HAHZ)] else [])) let triplet_gauge_higgs = List.map hgg ([ ((Psi0, Wp, Wm), Scalar_Vector_Vector 1, G_PsiWW); ((Psi0, WHp, WHm), Scalar_Vector_Vector (-1), G_PsiWW); ((Psi0, WHp, Wm), Scalar_Vector_Vector 1, G_PsiWHW); ((Psi0, WHm, Wp), Scalar_Vector_Vector 1, G_PsiWHW); ((Psi0, Z, Z), Scalar_Vector_Vector 1, G_PsiZZ); ((Psi0, ZH, ZH), Scalar_Vector_Vector 1, G_PsiZHZH); ((Psi0, ZH, Z), Scalar_Vector_Vector 1, G_PsiZHZ); ((Psim, Wp, Z), Scalar_Vector_Vector 1, G_PsiZW); ((Psip, Wm, Z), Scalar_Vector_Vector 1, G_PsiZW); ((Psim, WHp, Z), Scalar_Vector_Vector 1, G_PsiZWH); ((Psip, WHm, Z), Scalar_Vector_Vector 1, G_PsiZWH); ((Psim, Wp, ZH), Scalar_Vector_Vector 1, G_PsiZHW); ((Psip, Wm, ZH), Scalar_Vector_Vector 1, G_PsiZHW); ((Psim, WHp, ZH), Scalar_Vector_Vector 1, G_PsiZHWH); ((Psip, WHm, ZH), Scalar_Vector_Vector 1, G_PsiZHWH); ((Psimm, Wp, Wp), Scalar_Vector_Vector 1, G_PsippWW); ((Psipp, Wm, Wm), Scalar_Vector_Vector 1, G_PsippWW); ((Psimm, WHp, Wp), Scalar_Vector_Vector 1, G_PsippWHW); ((Psipp, WHm, Wm), Scalar_Vector_Vector 1, G_PsippWHW); ((Psimm, WHp, WHp), Scalar_Vector_Vector 1, G_PsippWHWH); ((Psipp, WHm, WHm), Scalar_Vector_Vector 1, G_PsippWHWH)] @ (if Flags.u1_gauged then [((Psi0, AH, Z), Scalar_Vector_Vector 1, G_PsiZAH); ((Psi0, AH, ZH), Scalar_Vector_Vector 1, G_PsiZHAH); ((Psi0, AH, AH), Scalar_Vector_Vector 1, G_PsiAHAH); ((Psim, Wp, AH), Scalar_Vector_Vector 1, G_PsiAHW); ((Psip, Wm, AH), Scalar_Vector_Vector 1, G_PsiAHW); ((Psim, WHp, AH), Scalar_Vector_Vector 1, G_PsiAHWH); ((Psip, WHm, AH), Scalar_Vector_Vector 1, G_PsiAHWH)] else [])) let triplet_gauge2_higgs = List.map ghh ([ ((Wp, H, Psim), Vector_Scalar_Scalar 1, G_PsiHW); ((Wm, H, Psip), Vector_Scalar_Scalar 1, G_PsiHW); ((WHp, H, Psim), Vector_Scalar_Scalar 1, G_PsiHWH); ((WHm, H, Psip), Vector_Scalar_Scalar 1, G_PsiHWH); ((Wp, Psi0, Psim), Vector_Scalar_Scalar 1, G_Psi0W); ((Wm, Psi0, Psip), Vector_Scalar_Scalar 1, G_Psi0W); ((WHp, Psi0, Psim), Vector_Scalar_Scalar 1, G_Psi0WH); ((WHm, Psi0, Psip), Vector_Scalar_Scalar 1, G_Psi0WH); ((Wp, Psi1, Psim), Vector_Scalar_Scalar 1, G_Psi1W); ((Wm, Psi1, Psip), Vector_Scalar_Scalar (-1), G_Psi1W); ((WHp, Psi1, Psim), Vector_Scalar_Scalar 1, G_Psi1WH); ((WHm, Psi1, Psip), Vector_Scalar_Scalar (-1), G_Psi1WH); ((Wp, Psip, Psimm), Vector_Scalar_Scalar 1, G_PsiPPW); ((Wm, Psim, Psipp), Vector_Scalar_Scalar 1, G_PsiPPW); ((WHp, Psip, Psimm), Vector_Scalar_Scalar 1, G_PsiPPWH); ((WHm, Psim, Psipp), Vector_Scalar_Scalar 1, G_PsiPPWH); ((Ga, Psip, Psim), Vector_Scalar_Scalar 1, Q_lepton); ((Ga, Psipp, Psimm), Vector_Scalar_Scalar 2, Q_lepton); ((Z, H, Psi1), Vector_Scalar_Scalar 1, G_Psi1HZ); ((ZH, H, Psi1), Vector_Scalar_Scalar 1, G_Psi1HZH); ((Z, Psi0, Psi1), Vector_Scalar_Scalar 1, G_Psi01Z); ((ZH, Psi0, Psi1), Vector_Scalar_Scalar 1, G_Psi01ZH); ((Z, Psip, Psim), Vector_Scalar_Scalar 1, G_ZPsip); ((Z, Psipp, Psimm), Vector_Scalar_Scalar 2, G_ZPsipp); ((ZH, Psipp, Psimm), Vector_Scalar_Scalar 2, G_ZHPsipp)] @ (if Flags.u1_gauged then [((AH, H, Psi1), Vector_Scalar_Scalar 1, G_Psi1HAH); ((AH, Psi0, Psi1), Vector_Scalar_Scalar 1, G_Psi01AH); ((AH, Psip, Psim), Vector_Scalar_Scalar 1, G_AHPsip); ((AH, Psipp, Psimm), Vector_Scalar_Scalar 2, G_AHPsip)] else [])) let standard_gauge_higgs = standard_gauge_higgs' @ heavy_gauge_higgs @ triplet_gauge_higgs @ triplet_gauge2_higgs let standard_gauge_higgs4 = List.map hhgg [ (H, H, Wp, Wm), Scalar2_Vector2 1, G_HHWW; (H, H, Z, Z), Scalar2_Vector2 1, G_HHZZ ] let littlest_gauge_higgs4 = List.map hhgg ([ (H, H, WHp, WHm), Scalar2_Vector2 (-1), G_HHWW; (H, H, ZH, ZH), Scalar2_Vector2 (-1), G_HHWW; (H, H, Wp, WHm), Scalar2_Vector2 1, G_HHWHW; (H, H, WHp, Wm), Scalar2_Vector2 1, G_HHWHW; (H, H, ZH, Z), Scalar2_Vector2 (-1), G_HHZHZ; (H, Psi0, Wp, Wm), Scalar2_Vector2 1, G_HPsi0WW; (H, Psi0, WHp, WHm), Scalar2_Vector2 (-1), G_HPsi0WW; (H, Psi0, WHp, Wm), Scalar2_Vector2 1, G_HPsi0WHW; (H, Psi0, Wp, WHm), Scalar2_Vector2 1, G_HPsi0WHW; (H, Psi0, Z, Z), Scalar2_Vector2 1, G_HPsi0ZZ; (H, Psi0, ZH, ZH), Scalar2_Vector2 1, G_HPsi0ZHZH; (H, Psi0, ZH, Z), Scalar2_Vector2 1, G_HPsi0ZHZ; (H, Psim, Wp, Ga), Scalar2_Vector2 1, G_HPsipWA; (H, Psip, Wm, Ga), Scalar2_Vector2 1, G_HPsipWA; (H, Psim, WHp, Ga), Scalar2_Vector2 1, G_HPsipWHA; (H, Psip, WHm, Ga), Scalar2_Vector2 1, G_HPsipWHA; (H, Psim, Wp, Z), Scalar2_Vector2 1, G_HPsipWZ; (H, Psip, Wm, Z), Scalar2_Vector2 1, G_HPsipWZ; (H, Psim, WHp, Z), Scalar2_Vector2 1, G_HPsipWHZ; (H, Psip, WHm, Z), Scalar2_Vector2 1, G_HPsipWHZ; (H, Psim, Wp, ZH), Scalar2_Vector2 1, G_HPsipWZH; (H, Psip, Wm, ZH), Scalar2_Vector2 1, G_HPsipWZH; (H, Psim, WHp, ZH), Scalar2_Vector2 1, G_HPsipWHZH; (H, Psip, WHm, ZH), Scalar2_Vector2 1, G_HPsipWHZH; (H, Psimm, Wp, Wp), Scalar2_Vector2 1, G_HPsippWW; (H, Psipp, Wm, Wm), Scalar2_Vector2 1, G_HPsippWW; (H, Psimm, WHp, WHp), Scalar2_Vector2 1, G_HPsippWHWH; (H, Psipp, WHm, WHm), Scalar2_Vector2 1, G_HPsippWHWH; (H, Psimm, WHp, Wp), Scalar2_Vector2 1, G_HPsippWHW; (H, Psipp, WHm, Wm), Scalar2_Vector2 1, G_HPsippWHW; (Psi0, Psi0, Wp, Wm), Scalar2_Vector2 2, G_HHWW; (Psi0, Psi0, WHp, WHm), Scalar2_Vector2 (-2), G_HHWW; (Psi0, Psi0, Z, Z), Scalar2_Vector2 4, G_HHZZ; (Psi0, Psi0, ZH, ZH), Scalar2_Vector2 1, G_Psi00ZH; (Psi0, Psi0, WHp, Wm), Scalar2_Vector2 2, G_HHWHW; (Psi0, Psi0, Wp, WHm), Scalar2_Vector2 2, G_HHWHW; (Psi0, Psi0, Z, ZH), Scalar2_Vector2 4, G_HHZHZ; (Psi0, Psim, Wp, Ga), Scalar2_Vector2 1, G_Psi0pWA; (Psi0, Psip, Wm, Ga), Scalar2_Vector2 1, G_Psi0pWA; (Psi0, Psim, WHp, Ga), Scalar2_Vector2 1, G_Psi0pWHA; (Psi0, Psip, WHm, Ga), Scalar2_Vector2 1, G_Psi0pWHA; (Psi0, Psim, Wp, Z), Scalar2_Vector2 1, G_Psi0pWZ; (Psi0, Psip, Wm, Z), Scalar2_Vector2 1, G_Psi0pWZ; (Psi0, Psim, WHp, Z), Scalar2_Vector2 1, G_Psi0pWHZ; (Psi0, Psip, WHm, Z), Scalar2_Vector2 1, G_Psi0pWHZ; (Psi0, Psim, Wp, ZH), Scalar2_Vector2 1, G_Psi0pWZH; (Psi0, Psip, Wm, ZH), Scalar2_Vector2 1, G_Psi0pWZH; (Psi0, Psim, WHp, ZH), Scalar2_Vector2 1, G_Psi0pWHZH; (Psi0, Psip, WHm, ZH), Scalar2_Vector2 1, G_Psi0pWHZH; (Psi0, Psimm, Wp, Wp), Scalar2_Vector2 1, G_Psi0ppWW; (Psi0, Psipp, Wm, Wm), Scalar2_Vector2 1, G_Psi0ppWW; (Psi0, Psimm, WHp, WHp), Scalar2_Vector2 1, G_Psi0ppWHWH; (Psi0, Psipp, WHm, WHm), Scalar2_Vector2 1, G_Psi0ppWHWH; (Psi0, Psimm, WHp, Wp), Scalar2_Vector2 1, G_Psi0ppWHW; (Psi0, Psipp, WHm, Wm), Scalar2_Vector2 1, G_Psi0ppWHW; (Psi1, Psi1, Wp, Wm), Scalar2_Vector2 2, G_HHWW; (Psi1, Psi1, WHp, WHm), Scalar2_Vector2 (-2), G_HHWW; (Psi1, Psi1, Z, Z), Scalar2_Vector2 4, G_HHZZ; (Psi1, Psi1, ZH, ZH), Scalar2_Vector2 1, G_Psi00ZH; (Psi1, Psi1, WHp, Wm), Scalar2_Vector2 2, G_HHWHW; (Psi1, Psi1, Wp, WHm), Scalar2_Vector2 2, G_HHWHW; (Psi1, Psi1, Z, ZH), Scalar2_Vector2 4, G_HHZHZ; (Psi1, Psim, Wp, Ga), Scalar2_Vector2 1, I_G_Psi0pWA; (Psi1, Psip, Wm, Ga), Scalar2_Vector2 (-1), I_G_Psi0pWA; (Psi1, Psim, WHp, Ga), Scalar2_Vector2 1, I_G_Psi0pWHA; (Psi1, Psip, WHm, Ga), Scalar2_Vector2 (-1), I_G_Psi0pWHA; (Psi1, Psim, Wp, Z), Scalar2_Vector2 1, I_G_Psi0pWZ; (Psi1, Psip, Wm, Z), Scalar2_Vector2 (-1), I_G_Psi0pWZ; (Psi1, Psim, WHp, Z), Scalar2_Vector2 1, I_G_Psi0pWHZ; (Psi1, Psip, WHm, Z), Scalar2_Vector2 (-1), I_G_Psi0pWHZ; (Psi1, Psim, Wp, ZH), Scalar2_Vector2 1, I_G_Psi0pWZH; (Psi1, Psip, Wm, ZH), Scalar2_Vector2 (-1), I_G_Psi0pWZH; (Psi1, Psim, WHp, ZH), Scalar2_Vector2 1, I_G_Psi0pWHZH; (Psi1, Psip, WHm, ZH), Scalar2_Vector2 (-1), I_G_Psi0pWHZH; (Psi1, Psimm, Wp, Wp), Scalar2_Vector2 1, I_G_Psi0ppWW; (Psi1, Psipp, Wm, Wm), Scalar2_Vector2 (-1), I_G_Psi0ppWW; (Psi1, Psimm, WHp, WHp), Scalar2_Vector2 1, I_G_Psi0ppWHWH; (Psi1, Psipp, WHm, WHm), Scalar2_Vector2 (-1), I_G_Psi0ppWHWH; (Psi1, Psimm, WHp, Wp), Scalar2_Vector2 1, I_G_Psi0ppWHW; (Psi1, Psipp, WHm, Wm), Scalar2_Vector2 (-1), I_G_Psi0ppWHW; (Psip, Psim, Wp, Wm), Scalar2_Vector2 4, G_HHWW; (Psip, Psim, WHp, WHm), Scalar2_Vector2 1, G_Psi00ZH; (Psip, Psim, WHp, Wm), Scalar2_Vector2 4, G_HHWHW; (Psip, Psim, Wp, WHm), Scalar2_Vector2 4, G_HHWHW; (Psip, Psim, Z, Z), Scalar2_Vector2 1, G_PsippZZ; (Psip, Psim, Ga, Ga), Scalar2_Vector2 2, G_AAWW; (Psip, Psim, ZH, ZH), Scalar2_Vector2 1, G_PsippZHZH; (Psip, Psim, Ga, Z), Scalar2_Vector2 4, G_PsippAZ; (Psip, Psimm, Wp, Ga), Scalar2_Vector2 1, G_PsippWA; (Psim, Psipp, Wm, Ga), Scalar2_Vector2 1, G_PsippWA; (Psip, Psimm, WHp, Ga), Scalar2_Vector2 1, G_PsippWHA; (Psim, Psipp, WHm, Ga), Scalar2_Vector2 1, G_PsippWHA; (Psip, Psimm, Wp, Z), Scalar2_Vector2 1, G_PsippWZ; (Psim, Psipp, Wm, Z), Scalar2_Vector2 1, G_PsippWZ; (Psip, Psimm, WHp, Z), Scalar2_Vector2 1, G_PsippWHZ; (Psim, Psipp, WHm, Z), Scalar2_Vector2 1, G_PsippWHZ; (Psip, Psimm, Wp, ZH), Scalar2_Vector2 1, G_PsippWZH; (Psim, Psipp, Wm, ZH), Scalar2_Vector2 1, G_PsippWZH; (Psip, Psimm, WHp, ZH), Scalar2_Vector2 1, G_PsippWHZH; (Psim, Psipp, WHm, ZH), Scalar2_Vector2 1, G_PsippWHZH; (Psipp, Psimm, Wp, Wm), Scalar2_Vector2 2, G_HHWW; (Psipp, Psimm, WHp, WHm), Scalar2_Vector2 (-2), G_HHWW; (Psipp, Psimm, WHp, Wm), Scalar2_Vector2 2, G_HHWHW; (Psipp, Psimm, Wp, WHm), Scalar2_Vector2 2, G_HHWHW; (Psipp, Psimm, Z, Z), Scalar2_Vector2 1, G_PsiccZZ; (Psipp, Psimm, Ga, Ga), Scalar2_Vector2 8, G_AAWW; (Psipp, Psimm, ZH, ZH), Scalar2_Vector2 1, G_Psi00ZH; (Psipp, Psimm, Ga, Z), Scalar2_Vector2 1, G_PsiccAZ; (Psipp, Psimm, Z, ZH), Scalar2_Vector2 4, G_PsiccZZH; (Psipp, Psimm, Ga, ZH), Scalar2_Vector2 4, G_PsiccAZH] @ (if Flags.u1_gauged then [(H, H, AH, AH), Scalar2_Vector2 1, G_HHAA; (H, H, AH, Z), Scalar2_Vector2 (-1), G_HHAHZ; (H, H, ZH, AH), Scalar2_Vector2 (-1), G_HHZHAH; (H, Psi0, AH, AH), Scalar2_Vector2 1, G_HPsi0AHAH; (H, Psi0, Z, AH), Scalar2_Vector2 1, G_HPsi0ZAH; (H, Psi0, ZH, AH), Scalar2_Vector2 1, G_HPsi0ZHAH; (H, Psim, Wp, AH), Scalar2_Vector2 1, G_HPsipWAH; (H, Psip, Wm, AH), Scalar2_Vector2 1, G_HPsipWAH; (H, Psim, WHp, AH), Scalar2_Vector2 1, G_HPsipWHAH; (H, Psip, WHm, AH), Scalar2_Vector2 1, G_HPsipWHAH; (Psi0, Psi0, AH, AH), Scalar2_Vector2 1, G_Psi00AH; (Psi0, Psi0, Z, AH), Scalar2_Vector2 4, G_HHAHZ; (Psi0, Psi0, AH, ZH), Scalar2_Vector2 1, G_Psi00ZHAH; (Psi0, Psim, Wp, AH), Scalar2_Vector2 1, G_Psi0pWAH; (Psi0, Psip, Wm, AH), Scalar2_Vector2 1, G_Psi0pWAH; (Psi0, Psim, WHp, AH), Scalar2_Vector2 1, G_Psi0pWHAH; (Psi0, Psip, WHm, AH), Scalar2_Vector2 1, G_Psi0pWHAH; (Psi1, Psi1, AH, AH), Scalar2_Vector2 1, G_Psi00AH; (Psi1, Psi1, Z, AH), Scalar2_Vector2 4, G_HHAHZ; (Psi1, Psi1, AH, ZH), Scalar2_Vector2 1, G_Psi00ZHAH; (Psi1, Psim, Wp, AH), Scalar2_Vector2 1, I_G_Psi0pWAH; (Psi1, Psip, Wm, AH), Scalar2_Vector2 (-1), I_G_Psi0pWAH; (Psi1, Psim, WHp, AH), Scalar2_Vector2 1, I_G_Psi0pWHAH; (Psi1, Psip, WHm, AH), Scalar2_Vector2 (-1), I_G_Psi0pWHAH; (Psip, Psim, AH, AH), Scalar2_Vector2 1, G_Psi00AH; (Psip, Psim, Ga, AH), Scalar2_Vector2 4, G_PsippAAH; (Psip, Psim, Z, AH), Scalar2_Vector2 4, G_PsippZAH; (Psip, Psimm, Wp, AH), Scalar2_Vector2 1, G_PsippWAH; (Psim, Psipp, Wm, AH), Scalar2_Vector2 1, G_PsippWAH; (Psip, Psimm, WHp, AH), Scalar2_Vector2 1, G_PsippWHAH; (Psim, Psipp, WHm, AH), Scalar2_Vector2 1, G_PsippWHAH; (Psipp, Psimm, AH, AH), Scalar2_Vector2 1, G_Psi00AH; (Psipp, Psimm, AH, ZH), Scalar2_Vector2 (-1), G_Psi00ZHAH; (Psipp, Psimm, Ga, AH), Scalar2_Vector2 4, G_PsiccAAH; (Psipp, Psimm, Z, AH), Scalar2_Vector2 4, G_PsiccZAH] else [])) let standard_higgs = [ (O H, O H, O H), Scalar_Scalar_Scalar 1, G_H3 ] let anomaly_higgs = List.map hgg [ (Eta, Gl, Gl), Dim5_Scalar_Gauge2_Skew 1, G_EGlGl; (Eta, Ga, Ga), Dim5_Scalar_Gauge2_Skew 1, G_EGaGa; (Eta, Ga, Z), Dim5_Scalar_Gauge2_Skew 1, G_EGaZ] (* @ [ (H, Ga, Ga), Dim5_Scalar_Gauge2 1, G_HGaGa; (H, Ga, Z), Dim5_Scalar_Gauge2 1, G_HGaZ ] *) let standard_higgs4 = [ (O H, O H, O H, O H), Scalar4 1, G_H4 ] let gauge_higgs = standard_gauge_higgs let gauge_higgs4 = standard_gauge_higgs4 let higgs = standard_higgs let higgs4 = standard_higgs4 let top_quartic = [ ((M (U (-3)), O H, O H, M (U 3)), GBBG (1, Psibar, S2, Psi), G_HHtt); ((M (TopHb), O H, O H, M TopH), GBBG (1, Psibar, S2, Psi), G_HHthth); ((M (U (-3)), O H, O H, M TopH), GBBG (1, Psibar, S2LR, Psi), G_HHtht); ((M (TopHb), O H, O H, M (U 3)), GBBG (1, Psibar, S2LR, Psi), G_HHtht)] let goldstone_vertices = List.map hgg [ ((Phi0, Wm, Wp), Scalar_Vector_Vector 1, I_G_ZWW); ((Phip, Ga, Wm), Scalar_Vector_Vector 1, I_Q_W); ((Phip, Z, Wm), Scalar_Vector_Vector 1, I_G_ZWW); ((Phim, Wp, Ga), Scalar_Vector_Vector 1, I_Q_W); ((Phim, Wp, Z), Scalar_Vector_Vector 1, I_G_ZWW) ] let vertices3 = (ThoList.flatmap electromagnetic_currents [1;2;3] @ ThoList.flatmap color_currents [1;2;3] @ ThoList.flatmap neutral_currents [1;2;3] @ ThoList.flatmap neutral_heavy_currents [1;2;3] @ ThoList.flatmap charged_currents [1;2;3] @ ThoList.flatmap charged_heavy_currents [1;2;3] @ heavy_top_currents @ (if Flags.u1_gauged then [] else anomaly_higgs) @ yukawa @ yukawa_add @ triple_gauge @ gauge_higgs @ higgs @ goldstone_vertices) let vertices4 = quartic_gauge @ gauge_higgs4 @ higgs4 @ top_quartic let vertices () = (vertices3, vertices4, []) (* For efficiency, make sure that [F.of_vertices vertices] is evaluated only once. *) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 let flavor_of_string = function | "e-" -> M (L 1) | "e+" -> M (L (-1)) | "mu-" -> M (L 2) | "mu+" -> M (L (-2)) | "tau-" -> M (L 3) | "tau+" -> M (L (-3)) | "nue" -> M (N 1) | "nuebar" -> M (N (-1)) | "numu" -> M (N 2) | "numubar" -> M (N (-2)) | "nutau" -> M (N 3) | "nutaubar" -> M (N (-3)) | "u" -> M (U 1) | "ubar" -> M (U (-1)) | "c" -> M (U 2) | "cbar" -> M (U (-2)) | "t" -> M (U 3) | "tbar" -> M (U (-3)) | "d" -> M (D 1) | "dbar" -> M (D (-1)) | "s" -> M (D 2) | "sbar" -> M (D (-2)) | "b" -> M (D 3) | "bbar" -> M (D (-3)) | "th" -> M TopH | "thbar" -> M TopHb | "g" | "gl" -> G Gl | "A" -> G Ga | "Z" | "Z0" -> G Z | "AH" | "AH0" | "Ah" | "Ah0" -> G AH | "ZH" | "ZH0" | "Zh" | "Zh0" -> G ZH | "W+" -> G Wp | "W-" -> G Wm | "WH+" -> G WHp | "WH-" -> G WHm | "H" | "h" -> O H | "eta" | "Eta" -> O Eta | "Psi" | "Psi0" | "psi" | "psi0" -> O Psi0 | "Psi1" | "psi1" -> O Psi1 | "Psi+" | "psi+" | "Psip" | "psip" -> O Psip | "Psi-" | "psi-" | "Psim" | "psim" -> O Psim | "Psi++" | "psi++" | "Psipp" | "psipp" -> O Psipp | "Psi--" | "psi--" | "Psimm" | "psimm" -> O Psimm | _ -> invalid_arg "Modellib_BSM.Littlest.flavor_of_string" let flavor_to_string = function | M f -> begin match f with | L 1 -> "e-" | L (-1) -> "e+" | L 2 -> "mu-" | L (-2) -> "mu+" | L 3 -> "tau-" | L (-3) -> "tau+" | L _ -> invalid_arg "Modellib_BSM.Littlest.flavor_to_string" | N 1 -> "nue" | N (-1) -> "nuebar" | N 2 -> "numu" | N (-2) -> "numubar" | N 3 -> "nutau" | N (-3) -> "nutaubar" | N _ -> invalid_arg "Modellib_BSM.Littlest.flavor_to_string" | U 1 -> "u" | U (-1) -> "ubar" | U 2 -> "c" | U (-2) -> "cbar" | U 3 -> "t" | U (-3) -> "tbar" | U _ -> invalid_arg "Modellib_BSM.Littlest.flavor_to_string" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | D _ -> invalid_arg "Modellib_BSM.Littlest.flavor_to_string" | TopH -> "th" | TopHb -> "thbar" end | G f -> begin match f with | Gl -> "g" | Ga -> "A" | Z -> "Z" | Wp -> "W+" | Wm -> "W-" | ZH -> "ZH" | AH -> "AH" | WHp -> "WHp" | WHm -> "WHm" end | O f -> begin match f with | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | H -> "H" | Eta -> "Eta" | Psi0 -> "Psi0" | Psi1 -> "Psi1" | Psip -> "Psi+" | Psim -> "Psi-" | Psipp -> "Psi++" | Psimm -> "Psi--" end let flavor_to_TeX = function | M f -> begin match f with | L 1 -> "e^-" | L (-1) -> "e^+" | L 2 -> "\\mu^-" | L (-2) -> "\\mu^+" | L 3 -> "\\tau^-" | L (-3) -> "\\tau^+" | L _ -> invalid_arg "Modellib_BSM.Littlest.flavor_to_TeX" | N 1 -> "\\nu_e" | N (-1) -> "\\bar{\\nu}_e" | N 2 -> "\\nu_\\mu" | N (-2) -> "\\bar{\\nu}_\\mu" | N 3 -> "\\nu_\\tau" | N (-3) -> "\\bar{\\nu}_\\tau" | N _ -> invalid_arg "Modellib_BSM.Littlest.flavor_to_TeX" | U 1 -> "u" | U (-1) -> "\\bar{u}" | U 2 -> "c" | U (-2) -> "\\bar{c}" | U 3 -> "t" | U (-3) -> "\\bar{t}" | U _ -> invalid_arg "Modellib_BSM.Littlest.flavor_to_TeX" | D 1 -> "d" | D (-1) -> "\\bar{d}" | D 2 -> "s" | D (-2) -> "\\bar{s}" | D 3 -> "b" | D (-3) -> "\\bar{b}" | D _ -> invalid_arg "Modellib_BSM.Littlest.flavor_to_TeX" | TopH -> "T" | TopHb -> "\\bar{T}" end | G f -> begin match f with | Gl -> "g" | Ga -> "\\gamma" | Z -> "Z" | Wp -> "W^+" | Wm -> "W^-" | ZH -> "Z_H" | AH -> "\\gamma_H" | WHp -> "W_H^+" | WHm -> "W_H^-" end | O f -> begin match f with | Phip -> "\\Phi^+" | Phim -> "\\Phi^-" | Phi0 -> "\\Phi^0" | H -> "H" | Eta -> "\\eta" | Psi0 -> "\\Psi_S" | Psi1 -> "\\Psi_P" | Psip -> "\\Psi^+" | Psim -> "\\Psi^-" | Psipp -> "\\Psi^{++}" | Psimm -> "\\Psi^{--}" end let flavor_symbol = function | M f -> begin match f with | L n when n > 0 -> "l" ^ string_of_int n | L n -> "l" ^ string_of_int (abs n) ^ "b" | N n when n > 0 -> "n" ^ string_of_int n | N n -> "n" ^ string_of_int (abs n) ^ "b" | U n when n > 0 -> "u" ^ string_of_int n | U n -> "u" ^ string_of_int (abs n) ^ "b" | D n when n > 0 -> "d" ^ string_of_int n | D n -> "d" ^ string_of_int (abs n) ^ "b" | TopH -> "th" | TopHb -> "thb" end | G f -> begin match f with | Gl -> "gl" | Ga -> "a" | Z -> "z" | Wp -> "wp" | Wm -> "wm" | ZH -> "zh" | AH -> "ah" | WHp -> "whp" | WHm -> "whm" end | O f -> begin match f with | Phip -> "pp" | Phim -> "pm" | Phi0 -> "p0" | H -> "h" | Eta -> "eta" | Psi0 -> "psi0" | Psi1 -> "psi1" | Psip -> "psip" | Psim -> "psim" | Psipp -> "psipp" | Psimm -> "psimm" end (* There are PDG numbers for Z', Z'', W', 32-34, respectively. We just introduce a number 38 for Y0 as a Z'''. As well, there is the number 8 for a t'. But we cheat a little bit and take the number 35 which is reserved for a heavy scalar Higgs for the Eta scalar. For the heavy Higgs states we take 35 and 36 for the neutral ones, 37 for the charged and 38 for the doubly-charged. The pseudoscalar gets the 39. *) let pdg = function | M f -> begin match f with | L n when n > 0 -> 9 + 2*n | L n -> - 9 + 2*n | N n when n > 0 -> 10 + 2*n | N n -> - 10 + 2*n | U n when n > 0 -> 2*n | U n -> 2*n | D n when n > 0 -> - 1 + 2*n | D n -> 1 + 2*n | TopH -> 8 | TopHb -> (-8) end | G f -> begin match f with | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) | AH -> 32 | ZH -> 33 | WHp -> 34 | WHm -> (-34) end | O f -> begin match f with | Phip | Phim -> 27 | Phi0 -> 26 | Psi0 -> 35 | Psi1 -> 36 | Psip -> 37 | Psim -> (-37) | Psipp -> 38 | Psimm -> (-38) | H -> 25 | Eta -> 39 end let mass_symbol f = "mass(" ^ string_of_int (abs (pdg f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg f)) ^ ")" let constant_symbol = function | Unit -> "unit" | Pi -> "PI" | VHeavy -> "vheavy" | Alpha_QED -> "alpha" | E -> "e" | G_weak -> "g" | Vev -> "vev" | Sin2thw -> "sin2thw" | Sinthw -> "sinthw" | Costhw -> "costhw" | Sinpsi -> "sinpsi" | Cospsi -> "cospsi" | Atpsi -> "atpsi" | Sccs -> "sccs" | Supp -> "vF" | Supp2 -> "v2F2" | Q_lepton -> "qlep" | Q_up -> "qup" | Q_down -> "qdwn" | Q_Z_up -> "qzup" | G_ZHTHT -> "gzhtht" | G_ZTHT -> "gztht" | G_AHTHTH -> "gahthth" | G_AHTHT -> "gahtht" | G_AHTT -> "gahtt" | G_NC_lepton -> "gnclep" | G_NC_neutrino -> "gncneu" | G_NC_up -> "gncup" | G_NC_down -> "gncdwn" | G_CC -> "gcc" | G_CCtop -> "gcctop" | G_CC_heavy -> "gcch" | G_CC_WH -> "gccwh" | G_CC_W -> "gccw" | G_NC_h_lepton -> "gnchlep" | G_NC_h_neutrino -> "gnchneu" | G_NC_h_up -> "gnchup" | G_NC_h_down -> "gnchdwn" | G_NC_heavy -> "gnch" | I_Q_W -> "iqw" | I_G_ZWW -> "igzww" | I_G_WWW -> "igwww" | I_G_AHWW -> "igahww" | I_G_ZHWW -> "igzhww" | I_G_ZWHW -> "igzwhw" | I_G_AHWHWH -> "igahwhwh" | I_G_ZHWHWH -> "igzhwhwh" | I_G_AHWHW -> "igahwhw" | I_Q_H -> "iqh" | G_WWWW -> "gw4" | G_ZZWW -> "gzzww" | G_AZWW -> "gazww" | G_AAWW -> "gaaww" | G_WH4 -> "gwh4" | G_WHWHWW -> "gwhwhww" | G_WHWWW -> "gwhwww" | G_WH3W -> "gwh3w" | G_WWAAH -> "gwwaah" | G_WWAZH -> "gwwazh" | G_WWZZH -> "gwwzzh" | G_WWZAH -> "gwwzah" | G_WHWHAAH -> "gwhwhaah" | G_WHWHAZH -> "gwhwhazh" | G_WHWHZZH -> "gwhwhzzh" | G_WHWHZAH -> "gwhwhzah" | G_WWZHAH -> "gwwzhah" | G_WHWHZHAH -> "gwhwhzhah" | G_WHWZZ -> "gwhwzz" | G_WHWAZ -> "gwhwaz" | G_WHWAAH -> "gwhwaah" | G_WHWZAH -> "gwhwzah" | G_WHWZHZH -> "gwhwzhzh" | G_WHWZHAH -> "gwhwzhah" | G_WHWAZH -> "gwhwazh" | G_WHWZZH -> "gwhwzzh" | G_HWW -> "ghww" | G_HZZ -> "ghzz" | G_HHWW -> "ghhww" | G_HHZZ -> "ghhzz" | G_HWHW -> "ghwhw" | G_HWHWH -> "ghwhwh" | G_HAHAH -> "ghahah" | G_HZHZ -> "ghzhz" | G_HZHAH -> "ghzhah" | G_HAHZ -> "ghahz" | G_Htt -> "ghtt" | G_Hbb -> "ghbb" | G_Htautau -> "ghtautau" | G_Hcc -> "ghcc" | G_Hthth -> "ghthth" | G_Htht -> "ghtht" | G_HHtt -> "ghhtt" | G_HHthth -> "ghhthth" | G_HHtht -> "ghhtht" | G_Psi0tt -> "gpsi0tt" | G_Psi0bb -> "gpsi0bb" | G_Psi0cc -> "gpsi0cc" | G_Psi0tautau -> "gpsi0tautau" | G_Psi1tt -> "gpsi1tt" | G_Psi1bb -> "gpsi1bb" | G_Psi1cc -> "gpsi1cc" | G_Psi1tautau -> "gpsi1tautau" | G_Psipq3 -> "gpsipq3" | G_Psipq2 -> "gpsipq2" | G_Psipl3 -> "gpsipl3" | G_Psi0tth -> "gpsi0tth" | G_Psi1tth -> "gpsi1tth" | G_Psipbth -> "gpsipbth" | G_Ethth -> "gethth" | G_Etht -> "getht" | G_Ett -> "gett" | G_Ebb -> "gebb" | G_HGaGa -> "ghgaga" | G_HGaZ -> "ghgaz" | G_EGaGa -> "geaa" | G_EGaZ -> "geaz" | G_EGlGl -> "gegg" | G_H3 -> "gh3" | G_H4 -> "gh4" | G_PsiWW -> "gpsiww" | G_PsiWHW -> "gpsiwhw" | G_PsiZZ -> "gpsizz" | G_PsiZHZH -> "gpsizhzh" | G_PsiZHZ -> "gpsizhz" | G_PsiZAH -> "gpsizah" | G_PsiZHAH -> "gpsizhah" | G_PsiAHAH -> "gpsiahah" | G_PsiZW -> "gpsizw" | G_PsiZWH -> "gpsizwh" | G_PsiAHW -> "gpsiahw" | G_PsiAHWH -> "gpsiahwh" | G_PsiZHW -> "gpsizhw" | G_PsiZHWH -> "gpsizhwh" | G_PsippWW -> "gpsippww" | G_PsippWHW -> "gpsippwhw" | G_PsippWHWH -> "gpsippwhwh" | Gs -> "gs" | G2 -> "gs**2" | I_Gs -> "igs" | G_PsiHW -> "gpsihw" | G_PsiHWH -> "gpsihwh" | G_Psi0W -> "gpsi0w" | G_Psi0WH -> "gpsi0wh" | G_Psi1W -> "gpsi1w" | G_Psi1WH -> "gpsi1wh" | G_PsiPPW -> "gpsippw" | G_PsiPPWH -> "gpsippwh" | G_Psi1HAH -> "gpsihah" | G_Psi01AH -> "gpsi0ah" | G_AHPsip -> "gahpsip" | G_Psi1HZ -> "gpsi1hz" | G_Psi1HZH -> "gpsi1hzh" | G_Psi01Z -> "gpsi01z" | G_Psi01ZH -> "gpsi01zh" | G_ZPsip -> "gzpsip" | G_ZPsipp -> "gzpsipp" | G_ZHPsipp -> "gzhpsipp" | G_HHAA -> "ghhaa" | G_HHWHW -> "ghhwhw" | G_HHZHZ -> "ghhzhz" | G_HHAHZ -> "ghhahz" | G_HHZHAH -> "ghhzhah" | G_HPsi0WW -> "ghpsi0ww" | G_HPsi0WHW -> "ghpsi0whw" | G_HPsi0ZZ -> "ghpsi0zz" | G_HPsi0ZHZH -> "ghpsi0zhzh" | G_HPsi0ZHZ -> "ghpsi0zhz" | G_HPsi0AHAH -> "ghpsi0ahah" | G_HPsi0ZAH -> "ghpsi0zah" | G_HPsi0ZHAH -> "ghpsi0zhah" | G_HPsipWA -> "ghpsipwa" | G_HPsipWHA -> "ghpsipwha" | G_HPsipWZ -> "ghpsipwz" | G_HPsipWHZ -> "ghpsiwhz" | G_HPsipWAH -> "ghpsipwah" | G_HPsipWHAH -> "ghpsipwhah" | G_HPsipWZH -> "ghpsipwzh" | G_HPsipWHZH -> "ghpsipwhzh" | G_HPsippWW -> "ghpsippww" | G_HPsippWHWH -> "ghpsippwhwh" | G_HPsippWHW -> "ghpsippwhw" | G_Psi00ZH -> "gpsi00zh" | G_Psi00AH -> "gpsi00ah" | G_Psi00ZHAH -> "gpsi00zhah" | G_Psi0pWA -> "gpsi0pwa" | G_Psi0pWHA -> "gpsi0pwha" | G_Psi0pWZ -> "gpsi0pwz" | G_Psi0pWHZ -> "gpsi0pwhz" | G_Psi0pWAH -> "gpsi0pwah" | G_Psi0pWHAH -> "gpsi0pwhah" | G_Psi0pWZH -> "gpsi0pwzh" | G_Psi0pWHZH -> "gpsi0pwhzh" | G_Psi0ppWW -> "gpsi0ppww" | G_Psi0ppWHWH -> "gpsi0ppwhwh" | G_Psi0ppWHW -> "gpsi0ppwhw" | I_G_Psi0pWA -> "i_gpsi0pwa" | I_G_Psi0pWHA -> "i_gpsi0pwha" | I_G_Psi0pWZ -> "i_gpsi0pwz" | I_G_Psi0pWHZ -> "i_gpsi0pwhz" | I_G_Psi0pWAH -> "i_gpsi0pwah" | I_G_Psi0pWHAH -> "i_gpsi0pwhah" | I_G_Psi0pWZH -> "i_gpsi0pwzh" | I_G_Psi0pWHZH -> "i_gpsi0pwhzh" | I_G_Psi0ppWW -> "i_gpsi0ppww" | I_G_Psi0ppWHWH -> "i_gpsi0ppwhwh" | I_G_Psi0ppWHW -> "i_gpsi0ppwhw" | G_PsippZZ -> "gpsippzz" | G_PsippZHZH -> "gpsippzhzh" | G_PsippAZ -> "gpsippaz" | G_PsippAAH -> "gpsippaah" | G_PsippZAH -> "gpsippzah" | G_PsippWA -> "gpsippwa" | G_PsippWHA -> "gpsippwha" | G_PsippWZ -> "gpsippwz" | G_PsippWHZ -> "gpsippwhz" | G_PsippWAH -> "gpsippwah" | G_PsippWHAH -> "gpsippwhah" | G_PsippWZH -> "gpsippwzh" | G_PsippWHZH -> "gpsippwhzh" | G_PsiccZZ -> "gpsicczz" | G_PsiccAZ -> "gpsiccaz" | G_PsiccAAH -> "gpsiccaah" | G_PsiccZZH -> "gpsicczzh" | G_PsiccAZH -> "gpsiccazh" | G_PsiccZAH -> "gpsicczah" | Mass f -> "mass" ^ flavor_symbol f | Width f -> "width" ^ flavor_symbol f end module Littlest_Tpar (Flags : BSM_flags) = struct open Coupling let default_width = ref Timelike let use_fudged_width = ref false let options = Options.create [ "constant_width", Arg.Unit (fun () -> default_width := Constant), "use constant width (also in t-channel)"; "fudged_width", Arg.Set use_fudged_width, "use fudge factor for charge particle width"; "custom_width", Arg.String (fun f -> default_width := Custom f), "use custom width"; "cancel_widths", Arg.Unit (fun () -> default_width := Vanishing), "use vanishing width"; "cms_width", Arg.Unit (fun () -> default_width := Complex_Mass), - "use complex mass scheme"] + "use complex mass scheme"; + "running_width", Arg.Unit (fun () -> default_width := Running), + "use running width"] type flavor = L of int | N of int | U of int | D of int | Topp | Toppb | Ga | Wp | Wm | Z | Gl | Lodd of int | Nodd of int | Uodd of int | Dodd of int | WHp | WHm | ZH | AH | Phip | Phim | Phi0 | H | Eta | Psi0 | Psi1 | Psip | Psim | Psipp | Psimm type gauge = unit let gauge_symbol () = failwith "Modellib_BSM.Littlest_Tpar.gauge_symbol: internal error" let family n = [ L n; N n; U n; D n; Dodd n; Nodd n; Lodd n; Uodd n ] (* Since [Phi] already belongs to the EW Goldstone bosons we use [Psi] for the TeV scale complex triplet. We use the notation Todd1 = Uodd 3, Todd2 = Uodd 4. *) let external_flavors () = [ "1st Generation", ThoList.flatmap family [1; -1]; "2nd Generation", ThoList.flatmap family [2; -2]; "3rd Generation", ThoList.flatmap family [3; -3]; "Heavy Quarks", [Topp; Toppb; Uodd 4; Uodd (-4)]; "Heavy Scalars", [Psi0; Psi1; Psip; Psim; Psipp; Psimm]; "Gauge Bosons", if Flags.u1_gauged then [Ga; Z; Wp; Wm; Gl; WHp; WHm; ZH; AH] else [Ga; Z; Wp; Wm; Gl; WHp; WHm; ZH]; "Higgs", if Flags.u1_gauged then [H] else [H; Eta]; "Goldstone Bosons", [Phip; Phim; Phi0] ] let flavors () = ThoList.flatmap snd (external_flavors ()) let spinor n = if n >= 0 then Spinor else ConjSpinor let lorentz = function | L n -> spinor n | N n -> spinor n | U n -> spinor n | D n -> spinor n | Topp -> Spinor | Toppb -> ConjSpinor | Ga | Gl -> Vector | Wp | Wm | Z | WHp | WHm | ZH | AH -> Massive_Vector | _ -> Scalar let color = function | U n -> Color.SUN (if n > 0 then 3 else -3) | Uodd n -> Color.SUN (if n > 0 then 3 else -3) | D n -> Color.SUN (if n > 0 then 3 else -3) | Dodd n -> Color.SUN (if n > 0 then 3 else -3) | Topp -> Color.SUN 3 | Toppb -> Color.SUN (-3) | Gl -> Color.AdjSUN 3 | _ -> Color.Singlet let nc () = 3 let prop_spinor n = if n >= 0 then Prop_Spinor else Prop_ConjSpinor let propagator = function | L n -> prop_spinor n | N n -> prop_spinor n | Lodd n -> prop_spinor n | Nodd n -> prop_spinor n | U n -> prop_spinor n | D n -> prop_spinor n | Uodd n -> prop_spinor n | Dodd n -> prop_spinor n | Topp -> Prop_Spinor | Toppb -> Prop_ConjSpinor | Ga | Gl -> Prop_Feynman | Wp | Wm | Z | WHp | WHm | ZH | AH -> Prop_Unitarity | Phip | Phim | Phi0 -> Only_Insertion | H | Eta | Psi0 | Psi1 | Psip | Psim | Psipp | Psimm -> Prop_Scalar (* Optionally, ask for the fudge factor treatment for the widths of charged particles. Currently, this only applies to $W^\pm$ and top. *) let width f = if !use_fudged_width then match f with | Wp | Wm | U 3 | U (-3) | WHp | WHm | ZH | AH | Uodd _ | Dodd _ | Nodd _ | Lodd _ | Topp | Toppb -> Fudged | _ -> !default_width else !default_width let goldstone = function | Wp -> Some (Phip, Coupling.Integer 1) | Wm -> Some (Phim, Coupling.Integer 1) | Z -> Some (Phi0, Coupling.Integer 1) | _ -> None let conjugate = function | L n -> L (-n) | N n -> N (-n) | Lodd n -> L (-n) | Nodd n -> N (-n) | U n -> U (-n) | D n -> D (-n) | Uodd n -> U (-n) | Dodd n -> D (-n) | Topp -> Toppb | Toppb -> Topp | Gl -> Gl | Ga -> Ga | Z -> Z | Wp -> Wm | Wm -> Wp | WHm -> WHp | WHp -> WHm | ZH -> ZH | AH -> AH | Psi0 -> Psi0 | Psi1 -> Psi1 | Psip -> Psim | Psim -> Psip | Psipp -> Psimm | Psimm -> Psipp | Phip -> Phim | Phim -> Phip | Phi0 -> Phi0 | H -> H | Eta -> Eta let fermion = function | L n -> if n > 0 then 1 else -1 | N n -> if n > 0 then 1 else -1 | U n -> if n > 0 then 1 else -1 | D n -> if n > 0 then 1 else -1 | Lodd n -> if n > 0 then 1 else -1 | Nodd n -> if n > 0 then 1 else -1 | Uodd n -> if n > 0 then 1 else -1 | Dodd n -> if n > 0 then 1 else -1 | Topp -> 1 | Toppb -> -1 | Gl | Ga | Z | Wp | Wm | WHp | WHm | AH | ZH -> 0 | _ -> 0 module Ch = Charges.QQ let ( // ) = Algebra.Small_Rational.make let charge = function | L n | Lodd n -> if n > 0 then -1//1 else 1//1 | N n | Nodd n -> 0//1 | U n | Uodd n -> if n > 0 then 2//3 else -2//3 | D n | Dodd n -> if n > 0 then -1//3 else 1//3 | Topp -> 2//3 | Toppb -> -2//3 | Gl | Ga | Z | AH | ZH -> 0//1 | Wp | WHp -> 1//1 | Wm | WHm -> -1//1 | H | Phi0 | Eta | Psi1 | Psi0 -> 0//1 | Phip | Psip -> 1//1 | Phim | Psim -> -1//1 | Psipp -> 2//1 | Psimm -> -2//1 let lepton = function | L n | N n | Lodd n | Nodd n -> if n > 0 then 1//1 else -1//1 | U _ | D _ | _ -> 0//1 let baryon = function | L _ | N _ -> 0//1 | U n | D n | Uodd n | Dodd n -> if n > 0 then 1//1 else -1//1 | Topp -> 1//1 | Toppb -> -1//1 | _ -> 0//1 let charges f = [ charge f; lepton f; baryon f] type constant = | Unit | Pi | Alpha_QED | Sin2thw | Sinthw | Costhw | E | G_weak | Vev | VHeavy | Supp | Supp2 | Sinpsi | Cospsi | Atpsi | Sccs (* Mixing angles of SU(2) *) | Q_lepton | Q_up | Q_down | Q_Z_up | G_CC | G_CCtop | G_NC_neutrino | G_NC_lepton | G_NC_up | G_NC_down | G_NC_heavy | G_NC_h_neutrino | G_NC_h_lepton | G_NC_h_up | G_NC_h_down | G_CC_heavy | G_ZHTHT | G_ZTHT | G_AHTHTH | G_AHTHT | G_AHTT | G_CC_WH | G_CC_W | Gs | I_Gs | G2 | I_Q_W | I_G_ZWW | I_G_WWW | I_G_AHWW | I_G_ZHWW | I_G_ZWHW | I_G_AHWHWH | I_G_ZHWHWH | I_G_AHWHW | I_Q_H | G_WWWW | G_ZZWW | G_AZWW | G_AAWW | G_WH4 | G_WHWHWW | G_WHWWW | G_WH3W | G_WWAAH | G_WWAZH | G_WWZZH | G_WWZAH | G_WHWHAAH | G_WHWHAZH | G_WHWHZZH | G_WHWHZAH | G_WWZHAH | G_WHWHZHAH | G_WHWZZ | G_WHWAZ | G_WHWAAH | G_WHWZAH | G_WHWZHZH | G_WHWZHAH | G_WHWAZH | G_WHWZZH | G_HWW | G_HHWW | G_HZZ | G_HHZZ | G_PsiWW | G_PsiWHW | G_PsiZZ | G_PsiZHZH | G_PsiZHZ | G_PsiZAH | G_PsiZHAH | G_PsiAHAH | G_PsiZW | G_PsiZWH | G_PsiAHW | G_PsiAHWH | G_PsiZHW | G_PsiZHWH | G_PsippWW | G_PsippWHW | G_PsippWHWH | G_PsiHW | G_PsiHWH | G_Psi0W | G_Psi0WH | G_Psi1W | G_Psi1WH | G_PsiPPW | G_PsiPPWH | G_Psi1HAH | G_Psi01AH | G_AHPsip | G_Psi1HZ | G_Psi1HZH | G_Psi01Z | G_Psi01ZH | G_ZPsip | G_ZPsipp | G_ZHPsipp | G_HHAA | G_HHWHW | G_HHZHZ | G_HHAHZ | G_HHZHAH | G_HPsi0WW | G_HPsi0WHW | G_HPsi0ZZ | G_HPsi0ZHZH | G_HPsi0ZHZ | G_HPsi0AHAH | G_HPsi0ZAH | G_HPsi0ZHAH | G_HPsipWA | G_HPsipWHA | G_HPsipWZ | G_HPsipWHZ | G_HPsipWAH | G_HPsipWHAH | G_HPsipWZH | G_HPsipWHZH | G_HPsippWW | G_HPsippWHWH | G_HPsippWHW | G_Psi00ZH | G_Psi00AH | G_Psi00ZHAH | G_Psi0pWA | G_Psi0pWHA | G_Psi0pWZ | G_Psi0pWHZ | G_Psi0pWAH | G_Psi0pWHAH | G_Psi0pWZH | G_Psi0pWHZH | G_Psi0ppWW | G_Psi0ppWHWH | G_Psi0ppWHW | I_G_Psi0pWA | I_G_Psi0pWHA | I_G_Psi0pWZ | I_G_Psi0pWHZ | I_G_Psi0pWAH | I_G_Psi0pWHAH | I_G_Psi0pWZH | I_G_Psi0pWHZH | I_G_Psi0ppWW | I_G_Psi0ppWHWH | I_G_Psi0ppWHW | G_PsippZZ | G_PsippZHZH | G_PsippAZ | G_PsippAAH | G_PsippZAH | G_PsippWA | G_PsippWHA | G_PsippWZ | G_PsippWHZ | G_PsippWAH | G_PsippWHAH | G_PsippWZH | G_PsippWHZH | G_PsiccZZ | G_PsiccAZ | G_PsiccAAH | G_PsiccZZH | G_PsiccAZH | G_PsiccZAH | G_Htt | G_Hbb | G_Hcc | G_Htautau | G_H3 | G_H4 | G_Hthth | G_Htht | G_Ethth | G_Etht | G_Ett | G_HHtt | G_HHthth | G_HHtht | G_Psi0tt | G_Psi0bb | G_Psi0cc | G_Psi0tautau | G_Psi1tt | G_Psi1bb | G_Psi1cc | G_Psi1tautau | G_Psipq3 | G_Psipq2 | G_Psipl3 | G_Psi0tth | G_Psi1tth | G_Psipbth | G_Ebb | G_HGaGa | G_HGaZ | G_EGaGa | G_EGaZ | G_EGlGl | G_HWHW | G_HWHWH | G_HAHAH | G_HZHZ | G_HZHAH | G_HAHZ | Mass of flavor | Width of flavor (* Two integer counters for the QCD and EW order of the couplings. *) type orders = int * int let orders = function | _ -> (0,0) let input_parameters = [] let derived_parameters = [] let g_over_2_costh = Quot (Neg (Atom G_weak), Prod [Integer 2; Atom Costhw]) let nc_coupling c t3 q = (Real_Array c, [Prod [g_over_2_costh; Diff (t3, Prod [Integer 2; q; Atom Sin2thw])]; Prod [g_over_2_costh; t3]]) let half = Quot (Integer 1, Integer 2) let derived_parameter_arrays = [ nc_coupling G_NC_neutrino half (Integer 0); nc_coupling G_NC_lepton (Neg half) (Integer (-1)); nc_coupling G_NC_up half (Quot (Integer 2, Integer 3)); nc_coupling G_NC_down (Neg half) (Quot (Integer (-1), Integer 3)); nc_coupling G_NC_h_neutrino half (Integer 0); nc_coupling G_NC_h_lepton (Neg half) (Integer (-1)); nc_coupling G_NC_h_up half (Quot (Integer 2, Integer 3)); nc_coupling G_NC_h_down (Neg half) (Quot (Integer (-1), Integer 3)) ] let parameters () = { input = input_parameters; derived = derived_parameters; derived_arrays = derived_parameter_arrays } module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) let electromagnetic_currents n = [ ((L (-n), Ga, L n), FBF (1, Psibar, V, Psi), Q_lepton); ((U (-n), Ga, U n), FBF (1, Psibar, V, Psi), Q_up); ((D (-n), Ga, D n), FBF (1, Psibar, V, Psi), Q_down); ((Lodd (-n), Ga, Lodd n), FBF (1, Psibar, V, Psi), Q_lepton); ((Uodd (-n), Ga, Uodd n), FBF (1, Psibar, V, Psi), Q_up); ((Dodd (-n), Ga, Dodd n), FBF (1, Psibar, V, Psi), Q_down) ] let color_currents n = [ ((U (-n), Gl, U n), FBF ((-1), Psibar, V, Psi), Gs); ((D (-n), Gl, D n), FBF ((-1), Psibar, V, Psi), Gs); ((Uodd (-n), Gl, Uodd n), FBF ((-1), Psibar, V, Psi), Gs); ((Dodd (-n), Gl, Dodd n), FBF ((-1), Psibar, V, Psi), Gs) ] let neutral_currents n = [ ((L (-n), Z, L n), FBF (1, Psibar, VA, Psi), G_NC_lepton); ((N (-n), Z, N n), FBF (1, Psibar, VA, Psi), G_NC_neutrino); ((U (-n), Z, U n), FBF (1, Psibar, VA, Psi), G_NC_up); ((D (-n), Z, D n), FBF (1, Psibar, VA, Psi), G_NC_down) ] (* The sign of this coupling is just the one of the T3, being -(1/2) for leptons and down quarks, and +(1/2) for neutrinos and up quarks. *) let neutral_heavy_currents n = ([ ((L (-n), ZH, L n), FBF ((-1), Psibar, VL, Psi), G_NC_heavy); ((N (-n), ZH, N n), FBF (1, Psibar, VL, Psi), G_NC_heavy); ((U (-n), ZH, U n), FBF (1, Psibar, VL, Psi), G_NC_heavy); ((D (-n), ZH, D n), FBF ((-1), Psibar, VL, Psi), G_NC_heavy)] @ (if Flags.u1_gauged then [ ((L (-n), AH, L n), FBF (1, Psibar, VA, Psi), G_NC_h_lepton); ((N (-n), AH, N n), FBF (1, Psibar, VA, Psi), G_NC_h_neutrino); ((D (-n), AH, D n), FBF (1, Psibar, VA, Psi), G_NC_h_down)] else [])) let heavy_top_currents = ([ ((Toppb, Ga, Topp), FBF (1, Psibar, V, Psi), Q_up); ((Toppb, Z, Topp), FBF (1, Psibar, V, Psi), Q_Z_up); ((Toppb, Gl, Topp), FBF (1, Psibar, V, Psi), Gs); ((Toppb, Z, U 3), FBF (1, Psibar, VL, Psi), G_ZTHT); ((U (-3), Z, Topp), FBF (1, Psibar, VL, Psi), G_ZTHT); ((Toppb, ZH, U 3), FBF (1, Psibar, VL, Psi), G_ZHTHT); ((U (-3), ZH, Topp), FBF (1, Psibar, VL, Psi), G_ZHTHT); ((U (-3), Wp, D 3), FBF (1, Psibar, VL, Psi), G_CCtop); ((D (-3), Wm, U 3), FBF (1, Psibar, VL, Psi), G_CCtop); ((Toppb, WHp, D 3), FBF (1, Psibar, VL, Psi), G_CC_WH); ((D (-3), WHm, Topp), FBF (1, Psibar, VL, Psi), G_CC_WH); ((Toppb, Wp, D 3), FBF (1, Psibar, VL, Psi), G_CC_W); ((D (-3), Wm, Topp), FBF (1, Psibar, VL, Psi), G_CC_W)] @ (if Flags.u1_gauged then [ ((U (-3), AH, U 3), FBF (1, Psibar, VA, Psi), G_AHTT); ((Toppb, AH, Topp), FBF (1, Psibar, VA, Psi), G_AHTHTH); ((Toppb, AH, U 3), FBF (1, Psibar, VR, Psi), G_AHTHT); ((U (-3), AH, Topp), FBF (1, Psibar, VR, Psi), G_AHTHT)] else [])) (* \begin{equation} \mathcal{L}_{\textrm{CC}} = - \frac{g}{2\sqrt2} \sum_i \bar\psi_i (T^+\fmslash{W}^+ + T^-\fmslash{W}^-)(1-\gamma_5)\psi_i \end{equation} *) let charged_currents n = [ ((L (-n), Wm, N n), FBF (1, Psibar, VL, Psi), G_CC); ((N (-n), Wp, L n), FBF (1, Psibar, VL, Psi), G_CC); ((L (-n), WHm, N n), FBF (1, Psibar, VL, Psi), G_CC_heavy); ((N (-n), WHp, L n), FBF (1, Psibar, VL, Psi), G_CC_heavy); ((D (-n), WHm, U n), FBF (1, Psibar, VL, Psi), G_CC_heavy); ((U (-n), WHp, D n), FBF (1, Psibar, VL, Psi), G_CC_heavy)] let quark_currents n = ([ ((D (-n), Wm, U n), FBF (1, Psibar, VL, Psi), G_CC); ((U (-n), Wp, D n), FBF (1, Psibar, VL, Psi), G_CC)] @ (if Flags.u1_gauged then [ ((U (-n), AH, U n), FBF (1, Psibar, VA, Psi), G_NC_h_up)] else [])) (* We specialize the third generation since there is an additional shift coming from the admixture of the heavy top quark. The universal shift, coming from the mixing in the non-Abelian gauge boson sector is unobservable. (Redefinition of coupling constants by measured ones. *) let yukawa = [ ((U (-3), H, U 3), FBF (1, Psibar, S, Psi), G_Htt); ((D (-3), H, D 3), FBF (1, Psibar, S, Psi), G_Hbb); ((U (-2), H, U 2), FBF (1, Psibar, S, Psi), G_Hcc); ((L (-3), H, L 3), FBF (1, Psibar, S, Psi), G_Htautau)] let yukawa_add' = [ ((Toppb, H, Topp), FBF (1, Psibar, S, Psi), G_Hthth); ((Toppb, H, U 3), FBF (1, Psibar, SLR, Psi), G_Htht); ((U (-3), H, Topp), FBF (1, Psibar, SLR, Psi), G_Htht); ((U (-3), Psi0, U 3), FBF (1, Psibar, S, Psi), G_Psi0tt); ((D (-3), Psi0, D 3), FBF (1, Psibar, S, Psi), G_Psi0bb); ((U (-2), Psi0, U 2), FBF (1, Psibar, S, Psi), G_Psi0cc); ((L (-3), Psi0, L 3), FBF (1, Psibar, S, Psi), G_Psi0tautau); ((U (-3), Psi1, U 3), FBF (1, Psibar, P, Psi), G_Psi1tt); ((D (-3), Psi1, D 3), FBF (1, Psibar, P, Psi), G_Psi1bb); ((U (-2), Psi1, U 2), FBF (1, Psibar, P, Psi), G_Psi1cc); ((L (-3), Psi1, L 3), FBF (1, Psibar, P, Psi), G_Psi1tautau); ((U (-3), Psip, D 3), FBF (1, Psibar, SLR, Psi), G_Psipq3); ((U (-2), Psip, D 2), FBF (1, Psibar, SLR, Psi), G_Psipq2); ((N (-3), Psip, L 3), FBF (1, Psibar, SR, Psi), G_Psipl3); ((D (-3), Psim, U 3), FBF (1, Psibar, SLR, Psi), G_Psipq3); ((D (-2), Psim, U 2), FBF (1, Psibar, SLR, Psi), G_Psipq2); ((L (-3), Psim, N 3), FBF (1, Psibar, SL, Psi), G_Psipl3); ((Toppb, Psi0, U 3), FBF (1, Psibar, SL, Psi), G_Psi0tth); ((U (-3), Psi0, Topp), FBF (1, Psibar, SR, Psi), G_Psi0tth); ((Toppb, Psi1, U 3), FBF (1, Psibar, SL, Psi), G_Psi1tth); ((U (-3), Psi1, Topp), FBF (1, Psibar, SR, Psi), G_Psi1tth); ((Toppb, Psip, D 3), FBF (1, Psibar, SL, Psi), G_Psipbth); ((D (-3), Psim, Topp), FBF (1, Psibar, SR, Psi), G_Psipbth)] let yukawa_add = if Flags.u1_gauged then yukawa_add' else yukawa_add' @ [ ((U (-3), Eta, U 3), FBF (1, Psibar, P, Psi), G_Ett); ((Toppb, Eta, U 3), FBF (1, Psibar, SLR, Psi), G_Etht); ((D (-3), Eta, D 3), FBF (1, Psibar, P, Psi), G_Ebb); ((U (-3), Eta, Topp), FBF (1, Psibar, SLR, Psi), G_Etht)] (* \begin{equation} \mathcal{L}_{\textrm{TGC}} = - e \partial_\mu A_\nu W_+^\mu W_-^\nu + \ldots - e \cot\theta_w \partial_\mu Z_\nu W_+^\mu W_-^\nu + \ldots \end{equation} *) (* Check. *) let standard_triple_gauge = [ ((Ga, Wm, Wp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW); ((Gl, Gl, Gl), Gauge_Gauge_Gauge 1, I_Gs) ] let heavy_triple_gauge = ([ ((Ga, WHm, WHp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, WHm, WHp), Gauge_Gauge_Gauge 1, I_G_ZWW); ((ZH, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZHWW); ((Z, WHm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWHW); ((Z, Wm, WHp), Gauge_Gauge_Gauge (-1), I_G_ZWHW); ((ZH, WHm, Wp), Gauge_Gauge_Gauge 1, I_G_WWW); ((ZH, Wm, WHp), Gauge_Gauge_Gauge (-1), I_G_WWW); ((ZH, WHm, WHp), Gauge_Gauge_Gauge (-1), I_G_ZHWHWH)] @ (if Flags.u1_gauged then [ ((AH, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_AHWW); ((AH, WHm, Wp), Gauge_Gauge_Gauge 1, I_G_AHWHW); ((AH, Wm, WHp), Gauge_Gauge_Gauge (-1), I_G_AHWHW); ((AH, WHm, WHp), Gauge_Gauge_Gauge 1, I_G_AHWHWH)] else [])) let triple_gauge = standard_triple_gauge @ heavy_triple_gauge let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] let standard_quartic_gauge = [ (Wm, Wp, Wm, Wp), gauge4, G_WWWW; (Wm, Z, Wp, Z), minus_gauge4, G_ZZWW; (Wm, Z, Wp, Ga), minus_gauge4, G_AZWW; (Wm, Ga, Wp, Ga), minus_gauge4, G_AAWW; (Gl, Gl, Gl, Gl), gauge4, G2] let heavy_quartic_gauge = [ (WHm, Wp, WHm, Wp), gauge4, G_WWWW; (Wm, WHp, Wm, WHp), gauge4, G_WWWW; (WHm, WHp, WHm, WHp), gauge4, G_WH4; (Wm, Wp, WHm, WHp), gauge4, G_WHWHWW; (Wm, Wp, Wm, WHp), gauge4, G_WHWWW; (Wm, Wp, WHm, Wp), gauge4, G_WHWWW; (WHm, WHp, Wm, WHp), gauge4, G_WH3W; (WHm, WHp, WHm, Wp), gauge4, G_WH3W; (WHm, Z, WHp, Z), minus_gauge4, G_ZZWW; (WHm, Z, WHp, Ga), minus_gauge4, G_AZWW; (WHm, Ga, WHp, ZH), minus_gauge4, G_AAWW; (WHm, Z, WHp, ZH), minus_gauge4, G_ZZWW; (Wm, ZH, Wp, ZH), minus_gauge4, G_WWWW; (Wm, Ga, Wp, ZH), minus_gauge4, G_WWAZH; (Wm, Z, Wp, ZH), minus_gauge4, G_WWZZH; (WHm, Ga, WHp, ZH), minus_gauge4, G_WHWHAZH; (WHm, Z, WHp, ZH), minus_gauge4, G_WHWHZZH; (WHm, ZH, WHp, ZH), minus_gauge4, G_WH4; (WHm, Z, Wp, Z), minus_gauge4, G_WHWZZ; (Wm, Z, WHp, Z), minus_gauge4, G_WHWZZ; (WHm, Ga, Wp, Z), minus_gauge4, G_WHWAZ; (Wm, Ga, WHp, Z), minus_gauge4, G_WHWAZ; (WHm, ZH, Wp, ZH), minus_gauge4, G_WHWZHZH; (Wm, ZH, WHp, ZH), minus_gauge4, G_WHWZHZH; (WHm, Ga, Wp, ZH), minus_gauge4, G_WHWAZH; (Wm, Ga, WHp, ZH), minus_gauge4, G_WHWAZH; (WHm, Z, Wp, ZH), minus_gauge4, G_WHWZZH; (Wm, Z, WHp, ZH), minus_gauge4, G_WHWZZH] @ (if Flags.u1_gauged then [ (Wm, Ga, Wp, AH), minus_gauge4, G_WWAAH; (Wm, Z, Wp, AH), minus_gauge4, G_WWZAH; (WHm, Ga, WHp, AH), minus_gauge4, G_WHWHAAH; (WHm, Z, WHp, AH), minus_gauge4, G_WHWHZAH; (Wm, ZH, Wp, AH), minus_gauge4, G_WWZHAH; (WHm, ZH, WHp, AH), minus_gauge4, G_WHWHZHAH; (WHm, Ga, Wp, AH), minus_gauge4, G_WHWAAH; (Wm, Ga, WHp, AH), minus_gauge4, G_WHWAAH; (WHm, Z, Wp, AH), minus_gauge4, G_WHWZAH; (Wm, Z, WHp, AH), minus_gauge4, G_WHWZAH; (WHm, ZH, Wp, AH), minus_gauge4, G_WHWZHAH; (Wm, ZH, WHp, AH), minus_gauge4, G_WHWZHAH] else []) let quartic_gauge = standard_quartic_gauge @ heavy_quartic_gauge let standard_gauge_higgs' = [ ((H, Wp, Wm), Scalar_Vector_Vector 1, G_HWW); ((H, Z, Z), Scalar_Vector_Vector 1, G_HZZ) ] let heavy_gauge_higgs = [ ((H, Wp, WHm), Scalar_Vector_Vector 1, G_HWHW); ((H, WHp, Wm), Scalar_Vector_Vector 1, G_HWHW); ((H, WHp, WHm), Scalar_Vector_Vector 1, G_HWHWH); ((H, ZH, ZH), Scalar_Vector_Vector 1, G_HWHWH); ((H, ZH, Z), Scalar_Vector_Vector 1, G_HZHZ); ((H, Wp, Wm), Scalar_Vector_Vector 1, G_HZHAH)] @ (if Flags.u1_gauged then [((H, AH, AH), Scalar_Vector_Vector 1, G_HAHAH); ((H, Z, AH), Scalar_Vector_Vector 1, G_HAHZ)] else []) let triplet_gauge_higgs = [ ((Psi0, Wp, Wm), Scalar_Vector_Vector 1, G_PsiWW); ((Psi0, WHp, WHm), Scalar_Vector_Vector (-1), G_PsiWW); ((Psi0, WHp, Wm), Scalar_Vector_Vector 1, G_PsiWHW); ((Psi0, WHm, Wp), Scalar_Vector_Vector 1, G_PsiWHW); ((Psi0, Z, Z), Scalar_Vector_Vector 1, G_PsiZZ); ((Psi0, ZH, ZH), Scalar_Vector_Vector 1, G_PsiZHZH); ((Psi0, ZH, Z), Scalar_Vector_Vector 1, G_PsiZHZ); ((Psim, Wp, Z), Scalar_Vector_Vector 1, G_PsiZW); ((Psip, Wm, Z), Scalar_Vector_Vector 1, G_PsiZW); ((Psim, WHp, Z), Scalar_Vector_Vector 1, G_PsiZWH); ((Psip, WHm, Z), Scalar_Vector_Vector 1, G_PsiZWH); ((Psim, Wp, ZH), Scalar_Vector_Vector 1, G_PsiZHW); ((Psip, Wm, ZH), Scalar_Vector_Vector 1, G_PsiZHW); ((Psim, WHp, ZH), Scalar_Vector_Vector 1, G_PsiZHWH); ((Psip, WHm, ZH), Scalar_Vector_Vector 1, G_PsiZHWH); ((Psimm, Wp, Wp), Scalar_Vector_Vector 1, G_PsippWW); ((Psipp, Wm, Wm), Scalar_Vector_Vector 1, G_PsippWW); ((Psimm, WHp, Wp), Scalar_Vector_Vector 1, G_PsippWHW); ((Psipp, WHm, Wm), Scalar_Vector_Vector 1, G_PsippWHW); ((Psimm, WHp, WHp), Scalar_Vector_Vector 1, G_PsippWHWH); ((Psipp, WHm, WHm), Scalar_Vector_Vector 1, G_PsippWHWH)] @ (if Flags.u1_gauged then [((Psi0, AH, Z), Scalar_Vector_Vector 1, G_PsiZAH); ((Psi0, AH, ZH), Scalar_Vector_Vector 1, G_PsiZHAH); ((Psi0, AH, AH), Scalar_Vector_Vector 1, G_PsiAHAH); ((Psim, Wp, AH), Scalar_Vector_Vector 1, G_PsiAHW); ((Psip, Wm, AH), Scalar_Vector_Vector 1, G_PsiAHW); ((Psim, WHp, AH), Scalar_Vector_Vector 1, G_PsiAHWH); ((Psip, WHm, AH), Scalar_Vector_Vector 1, G_PsiAHWH)] else []) let triplet_gauge2_higgs = [ ((Wp, H, Psim), Vector_Scalar_Scalar 1, G_PsiHW); ((Wm, H, Psip), Vector_Scalar_Scalar 1, G_PsiHW); ((WHp, H, Psim), Vector_Scalar_Scalar 1, G_PsiHWH); ((WHm, H, Psip), Vector_Scalar_Scalar 1, G_PsiHWH); ((Wp, Psi0, Psim), Vector_Scalar_Scalar 1, G_Psi0W); ((Wm, Psi0, Psip), Vector_Scalar_Scalar 1, G_Psi0W); ((WHp, Psi0, Psim), Vector_Scalar_Scalar 1, G_Psi0WH); ((WHm, Psi0, Psip), Vector_Scalar_Scalar 1, G_Psi0WH); ((Wp, Psi1, Psim), Vector_Scalar_Scalar 1, G_Psi1W); ((Wm, Psi1, Psip), Vector_Scalar_Scalar (-1), G_Psi1W); ((WHp, Psi1, Psim), Vector_Scalar_Scalar 1, G_Psi1WH); ((WHm, Psi1, Psip), Vector_Scalar_Scalar (-1), G_Psi1WH); ((Wp, Psip, Psimm), Vector_Scalar_Scalar 1, G_PsiPPW); ((Wm, Psim, Psipp), Vector_Scalar_Scalar 1, G_PsiPPW); ((WHp, Psip, Psimm), Vector_Scalar_Scalar 1, G_PsiPPWH); ((WHm, Psim, Psipp), Vector_Scalar_Scalar 1, G_PsiPPWH); ((Ga, Psip, Psim), Vector_Scalar_Scalar 1, Q_lepton); ((Ga, Psipp, Psimm), Vector_Scalar_Scalar 2, Q_lepton); ((Z, H, Psi1), Vector_Scalar_Scalar 1, G_Psi1HZ); ((ZH, H, Psi1), Vector_Scalar_Scalar 1, G_Psi1HZH); ((Z, Psi0, Psi1), Vector_Scalar_Scalar 1, G_Psi01Z); ((ZH, Psi0, Psi1), Vector_Scalar_Scalar 1, G_Psi01ZH); ((Z, Psip, Psim), Vector_Scalar_Scalar 1, G_ZPsip); ((Z, Psipp, Psimm), Vector_Scalar_Scalar 2, G_ZPsipp); ((ZH, Psipp, Psimm), Vector_Scalar_Scalar 2, G_ZHPsipp)] @ (if Flags.u1_gauged then [((AH, H, Psi1), Vector_Scalar_Scalar 1, G_Psi1HAH); ((AH, Psi0, Psi1), Vector_Scalar_Scalar 1, G_Psi01AH); ((AH, Psip, Psim), Vector_Scalar_Scalar 1, G_AHPsip); ((AH, Psipp, Psimm), Vector_Scalar_Scalar 2, G_AHPsip)] else []) let standard_gauge_higgs = standard_gauge_higgs' @ heavy_gauge_higgs @ triplet_gauge_higgs @ triplet_gauge2_higgs let standard_gauge_higgs4 = [ (H, H, Wp, Wm), Scalar2_Vector2 1, G_HHWW; (H, H, Z, Z), Scalar2_Vector2 1, G_HHZZ ] let littlest_gauge_higgs4 = [ (H, H, WHp, WHm), Scalar2_Vector2 (-1), G_HHWW; (H, H, ZH, ZH), Scalar2_Vector2 (-1), G_HHWW; (H, H, Wp, WHm), Scalar2_Vector2 1, G_HHWHW; (H, H, WHp, Wm), Scalar2_Vector2 1, G_HHWHW; (H, H, ZH, Z), Scalar2_Vector2 (-1), G_HHZHZ; (H, Psi0, Wp, Wm), Scalar2_Vector2 1, G_HPsi0WW; (H, Psi0, WHp, WHm), Scalar2_Vector2 (-1), G_HPsi0WW; (H, Psi0, WHp, Wm), Scalar2_Vector2 1, G_HPsi0WHW; (H, Psi0, Wp, WHm), Scalar2_Vector2 1, G_HPsi0WHW; (H, Psi0, Z, Z), Scalar2_Vector2 1, G_HPsi0ZZ; (H, Psi0, ZH, ZH), Scalar2_Vector2 1, G_HPsi0ZHZH; (H, Psi0, ZH, Z), Scalar2_Vector2 1, G_HPsi0ZHZ; (H, Psim, Wp, Ga), Scalar2_Vector2 1, G_HPsipWA; (H, Psip, Wm, Ga), Scalar2_Vector2 1, G_HPsipWA; (H, Psim, WHp, Ga), Scalar2_Vector2 1, G_HPsipWHA; (H, Psip, WHm, Ga), Scalar2_Vector2 1, G_HPsipWHA; (H, Psim, Wp, Z), Scalar2_Vector2 1, G_HPsipWZ; (H, Psip, Wm, Z), Scalar2_Vector2 1, G_HPsipWZ; (H, Psim, WHp, Z), Scalar2_Vector2 1, G_HPsipWHZ; (H, Psip, WHm, Z), Scalar2_Vector2 1, G_HPsipWHZ; (H, Psim, Wp, ZH), Scalar2_Vector2 1, G_HPsipWZH; (H, Psip, Wm, ZH), Scalar2_Vector2 1, G_HPsipWZH; (H, Psim, WHp, ZH), Scalar2_Vector2 1, G_HPsipWHZH; (H, Psip, WHm, ZH), Scalar2_Vector2 1, G_HPsipWHZH; (H, Psimm, Wp, Wp), Scalar2_Vector2 1, G_HPsippWW; (H, Psipp, Wm, Wm), Scalar2_Vector2 1, G_HPsippWW; (H, Psimm, WHp, WHp), Scalar2_Vector2 1, G_HPsippWHWH; (H, Psipp, WHm, WHm), Scalar2_Vector2 1, G_HPsippWHWH; (H, Psimm, WHp, Wp), Scalar2_Vector2 1, G_HPsippWHW; (H, Psipp, WHm, Wm), Scalar2_Vector2 1, G_HPsippWHW; (Psi0, Psi0, Wp, Wm), Scalar2_Vector2 2, G_HHWW; (Psi0, Psi0, WHp, WHm), Scalar2_Vector2 (-2), G_HHWW; (Psi0, Psi0, Z, Z), Scalar2_Vector2 4, G_HHZZ; (Psi0, Psi0, ZH, ZH), Scalar2_Vector2 1, G_Psi00ZH; (Psi0, Psi0, WHp, Wm), Scalar2_Vector2 2, G_HHWHW; (Psi0, Psi0, Wp, WHm), Scalar2_Vector2 2, G_HHWHW; (Psi0, Psi0, Z, ZH), Scalar2_Vector2 4, G_HHZHZ; (Psi0, Psim, Wp, Ga), Scalar2_Vector2 1, G_Psi0pWA; (Psi0, Psip, Wm, Ga), Scalar2_Vector2 1, G_Psi0pWA; (Psi0, Psim, WHp, Ga), Scalar2_Vector2 1, G_Psi0pWHA; (Psi0, Psip, WHm, Ga), Scalar2_Vector2 1, G_Psi0pWHA; (Psi0, Psim, Wp, Z), Scalar2_Vector2 1, G_Psi0pWZ; (Psi0, Psip, Wm, Z), Scalar2_Vector2 1, G_Psi0pWZ; (Psi0, Psim, WHp, Z), Scalar2_Vector2 1, G_Psi0pWHZ; (Psi0, Psip, WHm, Z), Scalar2_Vector2 1, G_Psi0pWHZ; (Psi0, Psim, Wp, ZH), Scalar2_Vector2 1, G_Psi0pWZH; (Psi0, Psip, Wm, ZH), Scalar2_Vector2 1, G_Psi0pWZH; (Psi0, Psim, WHp, ZH), Scalar2_Vector2 1, G_Psi0pWHZH; (Psi0, Psip, WHm, ZH), Scalar2_Vector2 1, G_Psi0pWHZH; (Psi0, Psimm, Wp, Wp), Scalar2_Vector2 1, G_Psi0ppWW; (Psi0, Psipp, Wm, Wm), Scalar2_Vector2 1, G_Psi0ppWW; (Psi0, Psimm, WHp, WHp), Scalar2_Vector2 1, G_Psi0ppWHWH; (Psi0, Psipp, WHm, WHm), Scalar2_Vector2 1, G_Psi0ppWHWH; (Psi0, Psimm, WHp, Wp), Scalar2_Vector2 1, G_Psi0ppWHW; (Psi0, Psipp, WHm, Wm), Scalar2_Vector2 1, G_Psi0ppWHW; (Psi1, Psi1, Wp, Wm), Scalar2_Vector2 2, G_HHWW; (Psi1, Psi1, WHp, WHm), Scalar2_Vector2 (-2), G_HHWW; (Psi1, Psi1, Z, Z), Scalar2_Vector2 4, G_HHZZ; (Psi1, Psi1, ZH, ZH), Scalar2_Vector2 1, G_Psi00ZH; (Psi1, Psi1, WHp, Wm), Scalar2_Vector2 2, G_HHWHW; (Psi1, Psi1, Wp, WHm), Scalar2_Vector2 2, G_HHWHW; (Psi1, Psi1, Z, ZH), Scalar2_Vector2 4, G_HHZHZ; (Psi1, Psim, Wp, Ga), Scalar2_Vector2 1, I_G_Psi0pWA; (Psi1, Psip, Wm, Ga), Scalar2_Vector2 (-1), I_G_Psi0pWA; (Psi1, Psim, WHp, Ga), Scalar2_Vector2 1, I_G_Psi0pWHA; (Psi1, Psip, WHm, Ga), Scalar2_Vector2 (-1), I_G_Psi0pWHA; (Psi1, Psim, Wp, Z), Scalar2_Vector2 1, I_G_Psi0pWZ; (Psi1, Psip, Wm, Z), Scalar2_Vector2 (-1), I_G_Psi0pWZ; (Psi1, Psim, WHp, Z), Scalar2_Vector2 1, I_G_Psi0pWHZ; (Psi1, Psip, WHm, Z), Scalar2_Vector2 (-1), I_G_Psi0pWHZ; (Psi1, Psim, Wp, ZH), Scalar2_Vector2 1, I_G_Psi0pWZH; (Psi1, Psip, Wm, ZH), Scalar2_Vector2 (-1), I_G_Psi0pWZH; (Psi1, Psim, WHp, ZH), Scalar2_Vector2 1, I_G_Psi0pWHZH; (Psi1, Psip, WHm, ZH), Scalar2_Vector2 (-1), I_G_Psi0pWHZH; (Psi1, Psimm, Wp, Wp), Scalar2_Vector2 1, I_G_Psi0ppWW; (Psi1, Psipp, Wm, Wm), Scalar2_Vector2 (-1), I_G_Psi0ppWW; (Psi1, Psimm, WHp, WHp), Scalar2_Vector2 1, I_G_Psi0ppWHWH; (Psi1, Psipp, WHm, WHm), Scalar2_Vector2 (-1), I_G_Psi0ppWHWH; (Psi1, Psimm, WHp, Wp), Scalar2_Vector2 1, I_G_Psi0ppWHW; (Psi1, Psipp, WHm, Wm), Scalar2_Vector2 (-1), I_G_Psi0ppWHW; (Psip, Psim, Wp, Wm), Scalar2_Vector2 4, G_HHWW; (Psip, Psim, WHp, WHm), Scalar2_Vector2 1, G_Psi00ZH; (Psip, Psim, WHp, Wm), Scalar2_Vector2 4, G_HHWHW; (Psip, Psim, Wp, WHm), Scalar2_Vector2 4, G_HHWHW; (Psip, Psim, Z, Z), Scalar2_Vector2 1, G_PsippZZ; (Psip, Psim, Ga, Ga), Scalar2_Vector2 2, G_AAWW; (Psip, Psim, ZH, ZH), Scalar2_Vector2 1, G_PsippZHZH; (Psip, Psim, Ga, Z), Scalar2_Vector2 4, G_PsippAZ; (Psip, Psimm, Wp, Ga), Scalar2_Vector2 1, G_PsippWA; (Psim, Psipp, Wm, Ga), Scalar2_Vector2 1, G_PsippWA; (Psip, Psimm, WHp, Ga), Scalar2_Vector2 1, G_PsippWHA; (Psim, Psipp, WHm, Ga), Scalar2_Vector2 1, G_PsippWHA; (Psip, Psimm, Wp, Z), Scalar2_Vector2 1, G_PsippWZ; (Psim, Psipp, Wm, Z), Scalar2_Vector2 1, G_PsippWZ; (Psip, Psimm, WHp, Z), Scalar2_Vector2 1, G_PsippWHZ; (Psim, Psipp, WHm, Z), Scalar2_Vector2 1, G_PsippWHZ; (Psip, Psimm, Wp, ZH), Scalar2_Vector2 1, G_PsippWZH; (Psim, Psipp, Wm, ZH), Scalar2_Vector2 1, G_PsippWZH; (Psip, Psimm, WHp, ZH), Scalar2_Vector2 1, G_PsippWHZH; (Psim, Psipp, WHm, ZH), Scalar2_Vector2 1, G_PsippWHZH; (Psipp, Psimm, Wp, Wm), Scalar2_Vector2 2, G_HHWW; (Psipp, Psimm, WHp, WHm), Scalar2_Vector2 (-2), G_HHWW; (Psipp, Psimm, WHp, Wm), Scalar2_Vector2 2, G_HHWHW; (Psipp, Psimm, Wp, WHm), Scalar2_Vector2 2, G_HHWHW; (Psipp, Psimm, Z, Z), Scalar2_Vector2 1, G_PsiccZZ; (Psipp, Psimm, Ga, Ga), Scalar2_Vector2 8, G_AAWW; (Psipp, Psimm, ZH, ZH), Scalar2_Vector2 1, G_Psi00ZH; (Psipp, Psimm, Ga, Z), Scalar2_Vector2 1, G_PsiccAZ; (Psipp, Psimm, Z, ZH), Scalar2_Vector2 4, G_PsiccZZH; (Psipp, Psimm, Ga, ZH), Scalar2_Vector2 4, G_PsiccAZH] @ (if Flags.u1_gauged then [(H, H, AH, AH), Scalar2_Vector2 1, G_HHAA; (H, H, AH, Z), Scalar2_Vector2 (-1), G_HHAHZ; (H, H, ZH, AH), Scalar2_Vector2 (-1), G_HHZHAH; (H, Psi0, AH, AH), Scalar2_Vector2 1, G_HPsi0AHAH; (H, Psi0, Z, AH), Scalar2_Vector2 1, G_HPsi0ZAH; (H, Psi0, ZH, AH), Scalar2_Vector2 1, G_HPsi0ZHAH; (H, Psim, Wp, AH), Scalar2_Vector2 1, G_HPsipWAH; (H, Psip, Wm, AH), Scalar2_Vector2 1, G_HPsipWAH; (H, Psim, WHp, AH), Scalar2_Vector2 1, G_HPsipWHAH; (H, Psip, WHm, AH), Scalar2_Vector2 1, G_HPsipWHAH; (Psi0, Psi0, AH, AH), Scalar2_Vector2 1, G_Psi00AH; (Psi0, Psi0, Z, AH), Scalar2_Vector2 4, G_HHAHZ; (Psi0, Psi0, AH, ZH), Scalar2_Vector2 1, G_Psi00ZHAH; (Psi0, Psim, Wp, AH), Scalar2_Vector2 1, G_Psi0pWAH; (Psi0, Psip, Wm, AH), Scalar2_Vector2 1, G_Psi0pWAH; (Psi0, Psim, WHp, AH), Scalar2_Vector2 1, G_Psi0pWHAH; (Psi0, Psip, WHm, AH), Scalar2_Vector2 1, G_Psi0pWHAH; (Psi1, Psi1, AH, AH), Scalar2_Vector2 1, G_Psi00AH; (Psi1, Psi1, Z, AH), Scalar2_Vector2 4, G_HHAHZ; (Psi1, Psi1, AH, ZH), Scalar2_Vector2 1, G_Psi00ZHAH; (Psi1, Psim, Wp, AH), Scalar2_Vector2 1, I_G_Psi0pWAH; (Psi1, Psip, Wm, AH), Scalar2_Vector2 (-1), I_G_Psi0pWAH; (Psi1, Psim, WHp, AH), Scalar2_Vector2 1, I_G_Psi0pWHAH; (Psi1, Psip, WHm, AH), Scalar2_Vector2 (-1), I_G_Psi0pWHAH; (Psip, Psim, AH, AH), Scalar2_Vector2 1, G_Psi00AH; (Psip, Psim, Ga, AH), Scalar2_Vector2 4, G_PsippAAH; (Psip, Psim, Z, AH), Scalar2_Vector2 4, G_PsippZAH; (Psip, Psimm, Wp, AH), Scalar2_Vector2 1, G_PsippWAH; (Psim, Psipp, Wm, AH), Scalar2_Vector2 1, G_PsippWAH; (Psip, Psimm, WHp, AH), Scalar2_Vector2 1, G_PsippWHAH; (Psim, Psipp, WHm, AH), Scalar2_Vector2 1, G_PsippWHAH; (Psipp, Psimm, AH, AH), Scalar2_Vector2 1, G_Psi00AH; (Psipp, Psimm, AH, ZH), Scalar2_Vector2 (-1), G_Psi00ZHAH; (Psipp, Psimm, Ga, AH), Scalar2_Vector2 4, G_PsiccAAH; (Psipp, Psimm, Z, AH), Scalar2_Vector2 4, G_PsiccZAH] else []) let standard_higgs = [ (H, H, H), Scalar_Scalar_Scalar 1, G_H3 ] let anomaly_higgs = [ (Eta, Gl, Gl), Dim5_Scalar_Gauge2_Skew 1, G_EGlGl; (Eta, Ga, Ga), Dim5_Scalar_Gauge2_Skew 1, G_EGaGa; (Eta, Ga, Z), Dim5_Scalar_Gauge2_Skew 1, G_EGaZ] (* @ [ (H, Ga, Ga), Dim5_Scalar_Gauge2 1, G_HGaGa; (H, Ga, Z), Dim5_Scalar_Gauge2 1, G_HGaZ ] *) let standard_higgs4 = [ (H, H, H, H), Scalar4 1, G_H4 ] let gauge_higgs = standard_gauge_higgs let gauge_higgs4 = standard_gauge_higgs4 let higgs = standard_higgs let higgs4 = standard_higgs4 let top_quartic = [ ((U (-3), H, H, U 3), GBBG (1, Psibar, S2, Psi), G_HHtt); ((Toppb, H, H, Topp), GBBG (1, Psibar, S2, Psi), G_HHthth); ((U (-3), H, H, Topp), GBBG (1, Psibar, S2LR, Psi), G_HHtht); ((Toppb, H, H, U 3), GBBG (1, Psibar, S2LR, Psi), G_HHtht)] let goldstone_vertices = [ ((Phi0, Wm, Wp), Scalar_Vector_Vector 1, I_G_ZWW); ((Phip, Ga, Wm), Scalar_Vector_Vector 1, I_Q_W); ((Phip, Z, Wm), Scalar_Vector_Vector 1, I_G_ZWW); ((Phim, Wp, Ga), Scalar_Vector_Vector 1, I_Q_W); ((Phim, Wp, Z), Scalar_Vector_Vector 1, I_G_ZWW) ] let vertices3 = (ThoList.flatmap electromagnetic_currents [1;2;3] @ ThoList.flatmap neutral_currents [1;2;3] @ ThoList.flatmap color_currents [1;2;3] @ ThoList.flatmap neutral_heavy_currents [1;2;3] @ ThoList.flatmap charged_currents [1;2;3] @ ThoList.flatmap quark_currents [1;2] @ heavy_top_currents @ (if Flags.u1_gauged then [] else anomaly_higgs) @ yukawa @ yukawa_add @ triple_gauge @ gauge_higgs @ higgs @ goldstone_vertices) let vertices4 = quartic_gauge @ gauge_higgs4 @ higgs4 @ top_quartic let vertices () = (vertices3, vertices4, []) (* For efficiency, make sure that [F.of_vertices vertices] is evaluated only once. *) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 let flavor_of_string = function | "e-" -> L 1 | "e+" -> L (-1) | "mu-" -> L 2 | "mu+" -> L (-2) | "tau-" -> L 3 | "tau+" -> L (-3) | "nue" -> N 1 | "nuebar" -> N (-1) | "numu" -> N 2 | "numubar" -> N (-2) | "nutau" -> N 3 | "nutaubar" -> N (-3) | "u" -> U 1 | "ubar" -> U (-1) | "c" -> U 2 | "cbar" -> U (-2) | "t" -> U 3 | "tbar" -> U (-3) | "d" -> D 1 | "dbar" -> D (-1) | "s" -> D 2 | "sbar" -> D (-2) | "b" -> D 3 | "bbar" -> D (-3) | "tp" -> Topp | "tpbar" -> Toppb | "g" -> Gl | "A" -> Ga | "Z" | "Z0" -> Z | "AH" | "AH0" | "Ah" | "Ah0" -> AH | "ZH" | "ZH0" | "Zh" | "Zh0" -> ZH | "W+" -> Wp | "W-" -> Wm | "WH+" -> WHp | "WH-" -> WHm | "H" | "h" -> H | "eta" | "Eta" -> Eta | "Psi" | "Psi0" | "psi" | "psi0" -> Psi0 | "Psi1" | "psi1" -> Psi1 | "Psi+" | "psi+" | "Psip" | "psip" -> Psip | "Psi-" | "psi-" | "Psim" | "psim" -> Psim | "Psi++" | "psi++" | "Psipp" | "psipp" -> Psipp | "Psi--" | "psi--" | "Psimm" | "psimm" -> Psimm | _ -> invalid_arg "Modellib_BSM.Littlest_Tpar.flavor_of_string" let flavor_to_string = function | L 1 -> "e-" | L (-1) -> "e+" | L 2 -> "mu-" | L (-2) -> "mu+" | L 3 -> "tau-" | L (-3) -> "tau+" | L _ -> invalid_arg "Modellib_BSM.Littlest_Tpar.flavor_to_string" | N 1 -> "nue" | N (-1) -> "nuebar" | N 2 -> "numu" | N (-2) -> "numubar" | N 3 -> "nutau" | N (-3) -> "nutaubar" | N _ -> invalid_arg "Modellib_BSM.Littlest_Tpar.flavor_to_string" | Lodd 1 -> "l1odd-" | Lodd (-1) -> "l1odd+" | Lodd 2 -> "l2odd-" | Lodd (-2) -> "l2odd+" | Lodd 3 -> "l3odd-" | Lodd (-3) -> "l3odd+" | Lodd _ -> invalid_arg "Modellib_BSM.Littlest_Tpar.flavor_to_string" | Nodd 1 -> "n1odd" | Nodd (-1) -> "n1oddbar" | Nodd 2 -> "n2odd" | Nodd (-2) -> "n2oddbar" | Nodd 3 -> "n3odd" | Nodd (-3) -> "n3oddbar" | Nodd _ -> invalid_arg "Modellib_BSM.Littlest_Tpar.flavor_to_string" | U 1 -> "u" | U (-1) -> "ubar" | U 2 -> "c" | U (-2) -> "cbar" | U 3 -> "t" | U (-3) -> "tbar" | U _ -> invalid_arg "Modellib_BSM.Littlest_Tpar.flavor_to_string" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | D _ -> invalid_arg "Modellib_BSM.Littlest_Tpar.flavor_to_string" | Uodd 1 -> "uodd" | Uodd (-1) -> "uoddbar" | Uodd 2 -> "codd" | Uodd (-2) -> "coddbar" | Uodd 3 -> "t1odd" | Uodd (-3) -> "t1oddbar" | Uodd 4 -> "t2odd" | Uodd (-4) -> "t2oddbar" | Uodd _ -> invalid_arg "Modellib_BSM.Littlest_Tpar.flavor_to_string" | Dodd 1 -> "dodd" | Dodd (-1) -> "doddbar" | Dodd 2 -> "sodd" | Dodd (-2) -> "soddbar" | Dodd 3 -> "bodd" | Dodd (-3) -> "boddbar" | Dodd _ -> invalid_arg "Modellib_BSM.Littlest_Tpar.flavor_to_string" | Topp -> "tp" | Toppb -> "tpbar" | Gl -> "g" | Ga -> "A" | Z -> "Z" | Wp -> "W+" | Wm -> "W-" | ZH -> "ZH" | AH -> "AH" | WHp -> "WHp" | WHm -> "WHm" | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | H -> "H" | Eta -> "Eta" | Psi0 -> "Psi0" | Psi1 -> "Psi1" | Psip -> "Psi+" | Psim -> "Psi-" | Psipp -> "Psi++" | Psimm -> "Psi--" let flavor_to_TeX = function | L 1 -> "e^-" | L (-1) -> "e^+" | L 2 -> "\\mu^-" | L (-2) -> "\\mu^+" | L 3 -> "\\tau^-" | L (-3) -> "\\tau^+" | L _ -> invalid_arg "Modellib_BSM.Littlest_Tpar.flavor_to_TeX" | N 1 -> "\\nu_e" | N (-1) -> "\\bar{\\nu}_e" | N 2 -> "\\nu_\\mu" | N (-2) -> "\\bar{\\nu}_\\mu" | N 3 -> "\\nu_\\tau" | N (-3) -> "\\bar{\\nu}_\\tau" | N _ -> invalid_arg "Modellib_BSM.Littlest_Tpar.flavor_to_TeX" | Lodd 1 -> "L_1^-" | Lodd (-1) -> "L_1^+" | Lodd 2 -> "L_2^-" | Lodd (-2) -> "L_2^+" | Lodd 3 -> "L_3^-" | Lodd (-3) -> "L_3^+" | Lodd _ -> invalid_arg "Modellib_BSM.Littlest_Tpar.flavor_to_TeX" | Nodd 1 -> "N_1" | Nodd (-1) -> "\\bar{N}_1" | Nodd 2 -> "N_2" | Nodd (-2) -> "\\bar{N}_2" | Nodd 3 -> "N_3" | Nodd (-3) -> "\\bar{N}_3" | Nodd _ -> invalid_arg "Modellib_BSM.Littlest_Tpar.flavor_to_TeX" | U 1 -> "u" | U (-1) -> "\\bar{u}" | U 2 -> "c" | U (-2) -> "\\bar{c}" | U 3 -> "t" | U (-3) -> "\\bar{t}" | U _ -> invalid_arg "Modellib_BSM.Littlest_Tpar.flavor_to_TeX" | D 1 -> "d" | D (-1) -> "\\bar{d}" | D 2 -> "s" | D (-2) -> "\\bar{s}" | D 3 -> "b" | D (-3) -> "\\bar{b}" | D _ -> invalid_arg "Modellib_BSM.Littlest_Tpar.flavor_to_TeX" | Uodd 1 -> "U" | Uodd (-1) -> "\\bar{U}" | Uodd 2 -> "C" | Uodd (-2) -> "\\bar{C}" | Uodd 3 -> "T_1" | Uodd (-3) -> "\\bar{T}_1" | Uodd 4 -> "T_2" | Uodd (-4) -> "\\bar{T}_2" | Uodd _ -> invalid_arg "Modellib_BSM.Littlest_Tpar.flavor_to_TeX" | Dodd 1 -> "D" | Dodd (-1) -> "\\bar{D}" | Dodd 2 -> "S" | Dodd (-2) -> "\\bar{S}" | Dodd 3 -> "B" | Dodd (-3) -> "\\bar{B}" | Dodd _ -> invalid_arg "Modellib_BSM.Littlest_Tpar.flavor_to_TeX" | Topp -> "T^\\prime" | Toppb -> "\\bar{T}^\\prime" | Gl -> "g" | Ga -> "\\gamma" | Z -> "Z" | Wp -> "W^+" | Wm -> "W^-" | ZH -> "Z_H" | AH -> "\\gamma_H" | WHp -> "W_H^+" | WHm -> "W_H^-" | Phip -> "\\Phi^+" | Phim -> "\\Phi^-" | Phi0 -> "\\Phi^0" | H -> "H" | Eta -> "\\eta" | Psi0 -> "\\Psi_S" | Psi1 -> "\\Psi_P" | Psip -> "\\Psi^+" | Psim -> "\\Psi^-" | Psipp -> "\\Psi^{++}" | Psimm -> "\\Psi^{--}" let flavor_symbol = function | L n when n > 0 -> "l" ^ string_of_int n | L n -> "l" ^ string_of_int (abs n) ^ "b" | Lodd n when n > 0 -> "lodd" ^ string_of_int n | Lodd n -> "lodd" ^ string_of_int (abs n) ^ "b" | N n when n > 0 -> "n" ^ string_of_int n | N n -> "n" ^ string_of_int (abs n) ^ "b" | Nodd n when n > 0 -> "nodd" ^ string_of_int n | Nodd n -> "nodd" ^ string_of_int (abs n) ^ "b" | U n when n > 0 -> "u" ^ string_of_int n | U n -> "u" ^ string_of_int (abs n) ^ "b" | D n when n > 0 -> "d" ^ string_of_int n | D n -> "d" ^ string_of_int (abs n) ^ "b" | Uodd n when n > 0 -> "uodd" ^ string_of_int n | Uodd n -> "uodd" ^ string_of_int (abs n) ^ "b" | Dodd n when n > 0 -> "dodd" ^ string_of_int n | Dodd n -> "dodd" ^ string_of_int (abs n) ^ "b" | Topp -> "tp" | Toppb -> "tpb" | Gl -> "gl" | Ga -> "a" | Z -> "z" | Wp -> "wp" | Wm -> "wm" | ZH -> "zh" | AH -> "ah" | WHp -> "whp" | WHm -> "whm" | Phip -> "pp" | Phim -> "pm" | Phi0 -> "p0" | H -> "h" | Eta -> "eta" | Psi0 -> "psi0" | Psi1 -> "psi1" | Psip -> "psip" | Psim -> "psim" | Psipp -> "psipp" | Psimm -> "psimm" (* There are PDG numbers for Z', Z'', W', 32-34, respectively. We just introduce a number 38 for Y0 as a Z'''. As well, there is the number 8 for a t'. But we cheat a little bit and take the number 35 which is reserved for a heavy scalar Higgs for the Eta scalar. For the heavy Higgs states we take 35 and 36 for the neutral ones, 37 for the charged and 38 for the doubly-charged. The pseudoscalar gets the 39. For the odd fermions we add 40 to the values for the SM particles. *) let pdg = function | L n when n > 0 -> 9 + 2*n | L n -> - 9 + 2*n | N n when n > 0 -> 10 + 2*n | N n -> - 10 + 2*n | U n when n > 0 -> 2*n | U n -> 2*n | D n when n > 0 -> - 1 + 2*n | D n -> 1 + 2*n | Lodd n when n > 0 -> 49 + 2*n | Lodd n -> - 49 + 2*n | Nodd n when n > 0 -> 50 + 2*n | Nodd n -> - 50 + 2*n | Uodd n when n > 0 -> 40 + 2*n | Uodd n -> -40 + 2*n | Dodd n when n > 0 -> 39 + 2*n | Dodd n -> -39 + 2*n | Topp -> 8 | Toppb -> (-8) | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) | AH -> 32 | ZH -> 33 | WHp -> 34 | WHm -> (-34) | Phip | Phim -> 27 | Phi0 -> 26 | Psi0 -> 35 | Psi1 -> 36 | Psip -> 37 | Psim -> (-37) | Psipp -> 38 | Psimm -> (-38) | H -> 25 | Eta -> 39 let mass_symbol f = "mass(" ^ string_of_int (abs (pdg f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg f)) ^ ")" let constant_symbol = function | Unit -> "unit" | Pi -> "PI" | VHeavy -> "vheavy" | Alpha_QED -> "alpha" | E -> "e" | G_weak -> "g" | Vev -> "vev" | Sin2thw -> "sin2thw" | Sinthw -> "sinthw" | Costhw -> "costhw" | Sinpsi -> "sinpsi" | Cospsi -> "cospsi" | Atpsi -> "atpsi" | Sccs -> "sccs" | Supp -> "vF" | Supp2 -> "v2F2" | Q_lepton -> "qlep" | Q_up -> "qup" | Q_down -> "qdwn" | Q_Z_up -> "qzup" | G_ZHTHT -> "gzhtht" | G_ZTHT -> "gztht" | G_AHTHTH -> "gahthth" | G_AHTHT -> "gahtht" | G_AHTT -> "gahtt" | G_NC_lepton -> "gnclep" | G_NC_neutrino -> "gncneu" | G_NC_up -> "gncup" | G_NC_down -> "gncdwn" | G_CC -> "gcc" | G_CCtop -> "gcctop" | G_CC_heavy -> "gcch" | G_CC_WH -> "gccwh" | G_CC_W -> "gccw" | G_NC_h_lepton -> "gnchlep" | G_NC_h_neutrino -> "gnchneu" | G_NC_h_up -> "gnchup" | G_NC_h_down -> "gnchdwn" | G_NC_heavy -> "gnch" | I_Q_W -> "iqw" | I_G_ZWW -> "igzww" | I_G_WWW -> "igwww" | I_G_AHWW -> "igahww" | I_G_ZHWW -> "igzhww" | I_G_ZWHW -> "igzwhw" | I_G_AHWHWH -> "igahwhwh" | I_G_ZHWHWH -> "igzhwhwh" | I_G_AHWHW -> "igahwhw" | I_Q_H -> "iqh" | Gs -> "gs" | I_Gs -> "igs" | G2 -> "gs**2" | G_WWWW -> "gw4" | G_ZZWW -> "gzzww" | G_AZWW -> "gazww" | G_AAWW -> "gaaww" | G_WH4 -> "gwh4" | G_WHWHWW -> "gwhwhww" | G_WHWWW -> "gwhwww" | G_WH3W -> "gwh3w" | G_WWAAH -> "gwwaah" | G_WWAZH -> "gwwazh" | G_WWZZH -> "gwwzzh" | G_WWZAH -> "gwwzah" | G_WHWHAAH -> "gwhwhaah" | G_WHWHAZH -> "gwhwhazh" | G_WHWHZZH -> "gwhwhzzh" | G_WHWHZAH -> "gwhwhzah" | G_WWZHAH -> "gwwzhah" | G_WHWHZHAH -> "gwhwhzhah" | G_WHWZZ -> "gwhwzz" | G_WHWAZ -> "gwhwaz" | G_WHWAAH -> "gwhwaah" | G_WHWZAH -> "gwhwzah" | G_WHWZHZH -> "gwhwzhzh" | G_WHWZHAH -> "gwhwzhah" | G_WHWAZH -> "gwhwazh" | G_WHWZZH -> "gwhwzzh" | G_HWW -> "ghww" | G_HZZ -> "ghzz" | G_HHWW -> "ghhww" | G_HHZZ -> "ghhzz" | G_HWHW -> "ghwhw" | G_HWHWH -> "ghwhwh" | G_HAHAH -> "ghahah" | G_HZHZ -> "ghzhz" | G_HZHAH -> "ghzhah" | G_HAHZ -> "ghahz" | G_Htt -> "ghtt" | G_Hbb -> "ghbb" | G_Htautau -> "ghtautau" | G_Hcc -> "ghcc" | G_Hthth -> "ghthth" | G_Htht -> "ghtht" | G_HHtt -> "ghhtt" | G_HHthth -> "ghhthth" | G_HHtht -> "ghhtht" | G_Psi0tt -> "gpsi0tt" | G_Psi0bb -> "gpsi0bb" | G_Psi0cc -> "gpsi0cc" | G_Psi0tautau -> "gpsi0tautau" | G_Psi1tt -> "gpsi1tt" | G_Psi1bb -> "gpsi1bb" | G_Psi1cc -> "gpsi1cc" | G_Psi1tautau -> "gpsi1tautau" | G_Psipq3 -> "gpsipq3" | G_Psipq2 -> "gpsipq2" | G_Psipl3 -> "gpsipl3" | G_Psi0tth -> "gpsi0tth" | G_Psi1tth -> "gpsi1tth" | G_Psipbth -> "gpsipbth" | G_Ethth -> "gethth" | G_Etht -> "getht" | G_Ett -> "gett" | G_Ebb -> "gebb" | G_HGaGa -> "ghgaga" | G_HGaZ -> "ghgaz" | G_EGaGa -> "geaa" | G_EGaZ -> "geaz" | G_EGlGl -> "gegg" | G_H3 -> "gh3" | G_H4 -> "gh4" | G_PsiWW -> "gpsiww" | G_PsiWHW -> "gpsiwhw" | G_PsiZZ -> "gpsizz" | G_PsiZHZH -> "gpsizhzh" | G_PsiZHZ -> "gpsizhz" | G_PsiZAH -> "gpsizah" | G_PsiZHAH -> "gpsizhah" | G_PsiAHAH -> "gpsiahah" | G_PsiZW -> "gpsizw" | G_PsiZWH -> "gpsizwh" | G_PsiAHW -> "gpsiahw" | G_PsiAHWH -> "gpsiahwh" | G_PsiZHW -> "gpsizhw" | G_PsiZHWH -> "gpsizhwh" | G_PsippWW -> "gpsippww" | G_PsippWHW -> "gpsippwhw" | G_PsippWHWH -> "gpsippwhwh" | G_PsiHW -> "gpsihw" | G_PsiHWH -> "gpsihwh" | G_Psi0W -> "gpsi0w" | G_Psi0WH -> "gpsi0wh" | G_Psi1W -> "gpsi1w" | G_Psi1WH -> "gpsi1wh" | G_PsiPPW -> "gpsippw" | G_PsiPPWH -> "gpsippwh" | G_Psi1HAH -> "gpsihah" | G_Psi01AH -> "gpsi0ah" | G_AHPsip -> "gahpsip" | G_Psi1HZ -> "gpsi1hz" | G_Psi1HZH -> "gpsi1hzh" | G_Psi01Z -> "gpsi01z" | G_Psi01ZH -> "gpsi01zh" | G_ZPsip -> "gzpsip" | G_ZPsipp -> "gzpsipp" | G_ZHPsipp -> "gzhpsipp" | G_HHAA -> "ghhaa" | G_HHWHW -> "ghhwhw" | G_HHZHZ -> "ghhzhz" | G_HHAHZ -> "ghhahz" | G_HHZHAH -> "ghhzhah" | G_HPsi0WW -> "ghpsi0ww" | G_HPsi0WHW -> "ghpsi0whw" | G_HPsi0ZZ -> "ghpsi0zz" | G_HPsi0ZHZH -> "ghpsi0zhzh" | G_HPsi0ZHZ -> "ghpsi0zhz" | G_HPsi0AHAH -> "ghpsi0ahah" | G_HPsi0ZAH -> "ghpsi0zah" | G_HPsi0ZHAH -> "ghpsi0zhah" | G_HPsipWA -> "ghpsipwa" | G_HPsipWHA -> "ghpsipwha" | G_HPsipWZ -> "ghpsipwz" | G_HPsipWHZ -> "ghpsiwhz" | G_HPsipWAH -> "ghpsipwah" | G_HPsipWHAH -> "ghpsipwhah" | G_HPsipWZH -> "ghpsipwzh" | G_HPsipWHZH -> "ghpsipwhzh" | G_HPsippWW -> "ghpsippww" | G_HPsippWHWH -> "ghpsippwhwh" | G_HPsippWHW -> "ghpsippwhw" | G_Psi00ZH -> "gpsi00zh" | G_Psi00AH -> "gpsi00ah" | G_Psi00ZHAH -> "gpsi00zhah" | G_Psi0pWA -> "gpsi0pwa" | G_Psi0pWHA -> "gpsi0pwha" | G_Psi0pWZ -> "gpsi0pwz" | G_Psi0pWHZ -> "gpsi0pwhz" | G_Psi0pWAH -> "gpsi0pwah" | G_Psi0pWHAH -> "gpsi0pwhah" | G_Psi0pWZH -> "gpsi0pwzh" | G_Psi0pWHZH -> "gpsi0pwhzh" | G_Psi0ppWW -> "gpsi0ppww" | G_Psi0ppWHWH -> "gpsi0ppwhwh" | G_Psi0ppWHW -> "gpsi0ppwhw" | I_G_Psi0pWA -> "i_gpsi0pwa" | I_G_Psi0pWHA -> "i_gpsi0pwha" | I_G_Psi0pWZ -> "i_gpsi0pwz" | I_G_Psi0pWHZ -> "i_gpsi0pwhz" | I_G_Psi0pWAH -> "i_gpsi0pwah" | I_G_Psi0pWHAH -> "i_gpsi0pwhah" | I_G_Psi0pWZH -> "i_gpsi0pwzh" | I_G_Psi0pWHZH -> "i_gpsi0pwhzh" | I_G_Psi0ppWW -> "i_gpsi0ppww" | I_G_Psi0ppWHWH -> "i_gpsi0ppwhwh" | I_G_Psi0ppWHW -> "i_gpsi0ppwhw" | G_PsippZZ -> "gpsippzz" | G_PsippZHZH -> "gpsippzhzh" | G_PsippAZ -> "gpsippaz" | G_PsippAAH -> "gpsippaah" | G_PsippZAH -> "gpsippzah" | G_PsippWA -> "gpsippwa" | G_PsippWHA -> "gpsippwha" | G_PsippWZ -> "gpsippwz" | G_PsippWHZ -> "gpsippwhz" | G_PsippWAH -> "gpsippwah" | G_PsippWHAH -> "gpsippwhah" | G_PsippWZH -> "gpsippwzh" | G_PsippWHZH -> "gpsippwhzh" | G_PsiccZZ -> "gpsicczz" | G_PsiccAZ -> "gpsiccaz" | G_PsiccAAH -> "gpsiccaah" | G_PsiccZZH -> "gpsicczzh" | G_PsiccAZH -> "gpsiccazh" | G_PsiccZAH -> "gpsicczah" | Mass f -> "mass" ^ flavor_symbol f | Width f -> "width" ^ flavor_symbol f end module Simplest (Flags : BSM_flags) = struct open Coupling let default_width = ref Timelike let use_fudged_width = ref false let options = Options.create [ "constant_width", Arg.Unit (fun () -> default_width := Constant), "use constant width (also in t-channel)"; "fudged_width", Arg.Set use_fudged_width, "use fudge factor for charge particle width"; "custom_width", Arg.String (fun f -> default_width := Custom f), "use custom width"; "cancel_widths", Arg.Unit (fun () -> default_width := Vanishing), "use vanishing width"; "cms_width", Arg.Unit (fun () -> default_width := Complex_Mass), - "use complex mass scheme"] + "use complex mass scheme"; + "running_width", Arg.Unit (fun () -> default_width := Running), + "use running width"] (* We do not introduce the Goldstones for the heavy vectors here. The heavy quarks are simply numerated by their generation, the assignments whether they are up- or down-type will be defined by the model. *) type flavor = L of int | N of int | U of int | D of int | QH of int | NH of int | Wp | Wm | Ga | Z | Xp | Xm | X0 | Y0 | ZH | Phip | Phim | Phi0 | H | Eta | Gl type gauge = unit let gauge_symbol () = failwith "Modellib_BSM.Simplest.gauge_symbol: internal error" let family n = [ L n; N n; U n; D n; QH n; NH n ] (* Note that we add all heavy quarks, [U], [D], [C], [S], in order to have both embeddings included. *) let external_flavors () = [ "1st Generation (incl. heavy)", ThoList.flatmap family [1; -1]; "2nd Generation (incl. heavy)", ThoList.flatmap family [2; -2]; "3rd Generation (incl. heavy)", ThoList.flatmap family [3; -3]; "Gauge Bosons", [Ga; Z; Wp; Wm; Gl; Xp; Xm; X0; Y0; ZH]; "Higgs", [H; Eta]; "Goldstone Bosons", [Phip; Phim; Phi0] ] let flavors () = ThoList.flatmap snd (external_flavors ()) let spinor n = if n >= 0 then Spinor else ConjSpinor let lorentz = function | L n -> spinor n | N n -> spinor n | U n -> spinor n | D n -> spinor n | QH n -> spinor n | NH n -> spinor n | Ga | Gl -> Vector | Wp | Wm | Z | Xp | Xm | X0 | Y0 | ZH -> Massive_Vector | _ -> Scalar let color = function | U n -> Color.SUN (if n > 0 then 3 else -3) | D n -> Color.SUN (if n > 0 then 3 else -3) | QH n -> Color.SUN (if n > 0 then 3 else -3) | Gl -> Color.AdjSUN 3 | _ -> Color.Singlet let nc () = 3 let prop_spinor n = if n >= 0 then Prop_Spinor else Prop_ConjSpinor let propagator = function | L n -> prop_spinor n | N n -> prop_spinor n | U n -> prop_spinor n | D n -> prop_spinor n | QH n -> prop_spinor n | NH n -> prop_spinor n | Ga | Gl -> Prop_Feynman | Wp | Wm | Z | Xp | Xm | X0 | Y0 | ZH -> Prop_Unitarity | Phip | Phim | Phi0 -> Only_Insertion | H | Eta -> Prop_Scalar (* Optionally, ask for the fudge factor treatment for the widths of charged particles. Currently, this only applies to $W^\pm$ and top. *) let width f = if !use_fudged_width then match f with | Wp | Wm | U 3 | U (-3) | QH _ | NH _ -> Fudged | _ -> !default_width else !default_width let goldstone = function | Wp -> Some (Phip, Coupling.Integer 1) | Wm -> Some (Phim, Coupling.Integer 1) | Z -> Some (Phi0, Coupling.Integer 1) | _ -> None let conjugate = function | L n -> L (-n) | N n -> N (-n) | U n -> U (-n) | D n -> D (-n) | QH n -> QH (-n) | NH n -> NH (-n) | Ga -> Ga | Gl -> Gl | Z -> Z | Wp -> Wm | Wm -> Wp | Xp -> Xm | Xm -> Xp | X0 -> X0 | Y0 -> Y0 | ZH -> ZH | Phip -> Phim | Phim -> Phip | Phi0 -> Phi0 | H -> H | Eta -> Eta let fermion = function | L n -> if n > 0 then 1 else -1 | N n -> if n > 0 then 1 else -1 | U n -> if n > 0 then 1 else -1 | D n -> if n > 0 then 1 else -1 | QH n -> if n > 0 then 1 else -1 | NH n -> if n > 0 then 1 else -1 | Ga | Gl | Z | Wp | Wm | Xp | Xm | X0 | Y0 | ZH -> 0 | _ -> 0 module Ch = Charges.QQ let ( // ) = Algebra.Small_Rational.make let charge = function | L n -> if n > 0 then -1//1 else 1//1 | N n | NH n -> 0//1 | U n -> if n > 0 then 2//3 else -2//3 | QH 3 -> 2//3 | QH (-3) -> -2//3 | QH (1|2) -> if Flags.anom_ferm_ass then 2//3 else -1//3 | QH ((-1)|(-2)) -> if Flags.anom_ferm_ass then -2//3 else 1//3 | QH n -> invalid_arg ("Simplest.charge: QH " ^ string_of_int n) | D n -> if n > 0 then -1//3 else 1//3 | Gl | Ga | Z | ZH | X0 | Y0 -> 0//1 | Wp | Xp -> 1//1 | Wm | Xm -> -1//1 | H | Phi0 | Eta -> 0//1 | Phip -> 1//1 | Phim -> -1//1 let lepton = function | L n | N n | NH n -> if n > 0 then 1//1 else -1//1 | U _ | D _ | _ -> 0//1 let baryon = function | L _ | N _ -> 0//1 | U n | D n | QH n -> if n > 0 then 1//1 else -1//1 | _ -> 0//1 let charges f = [ charge f; lepton f; baryon f] type constant = | Unit | Pi | Alpha_QED | Sin2thw | Sinthw | Costhw | E | G_weak | Vev | VHeavy | Supp | Supp2 | Sinpsi | Cospsi | Atpsi | Sccs (* Mixing angles of SU(2) *) | Q_lepton | Q_up | Q_down | Q_Z_up | G_CC | I_G_CC | G_NC_neutrino | G_NC_lepton | G_NC_up | G_NC_down | G_NC_X | G_NC_X_t | G_NC_Y | G_NC_Y_t | G_NC_H | G_NC_h_neutrino | G_NC_h_lepton | G_NC_h_up | G_NC_h_down | G_NC_h_top | G_NC_h_bot | G_NCH_N | G_NCH_U | G_NCH_D | G_NCHt | G_zhthth | I_Q_W | I_G_ZWW | I_G_WWW | I_G_Z1 | I_G_Z2 | I_G_Z3 | I_G_Z4 | I_G_Z5 | I_G_Z6 | I_Q_H | Gs | I_Gs | G2 | G_WWWW | G_ZZWW | G_AZWW | G_AAWW | I_Q_ZH | G_HWW | G_HHWW | G_HZZ | G_HHZZ | G_HHZZH | G_heavy_HVV | G_heavy_HWW | G_heavy_HZZ | G_HHthth | G_Htt | G_Hbb | G_Hcc | G_Htautau | G_H3 | G_H4 | G_Hthth | G_Htht | G_Ethth | G_Etht | G_Ett | G_Hqhq | G_Ebb | G_ZEH | G_ZHEH | G_Hgg | G_HGaGa | G_HGaZ | G_EGaGa | G_EGaZ | G_EGlGl | Mass of flavor | Width of flavor (* Two integer counters for the QCD and EW order of the couplings. *) type orders = int * int let orders = function | _ -> (0,0) (* \begin{dubious} The current abstract syntax for parameter dependencies is admittedly tedious. Later, there will be a parser for a convenient concrete syntax as a part of a concrete syntax for models. But as these examples show, it should include simple functions. \end{dubious} *) let input_parameters = [] let derived_parameters = [] let g_over_2_costh = Quot (Neg (Atom G_weak), Prod [Integer 2; Atom Costhw]) let nc_coupling c t3 q = (Real_Array c, [Prod [g_over_2_costh; Diff (t3, Prod [Integer 2; q; Atom Sin2thw])]; Prod [g_over_2_costh; t3]]) let half = Quot (Integer 1, Integer 2) let derived_parameter_arrays = [ nc_coupling G_NC_neutrino half (Integer 0); nc_coupling G_NC_lepton (Neg half) (Integer (-1)); nc_coupling G_NC_up half (Quot (Integer 2, Integer 3)); nc_coupling G_NC_down (Neg half) (Quot (Integer (-1), Integer 3)); nc_coupling G_NC_h_neutrino half (Integer 0); nc_coupling G_NC_h_lepton (Neg half) (Integer (-1)); nc_coupling G_NC_h_up half (Quot (Integer 2, Integer 3)); nc_coupling G_NC_h_down (Neg half) (Quot (Integer (-1), Integer 3)) ] let parameters () = { input = input_parameters; derived = derived_parameters; derived_arrays = derived_parameter_arrays } module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) let electromagnetic_currents n = [ ((L (-n), Ga, L n), FBF (1, Psibar, V, Psi), Q_lepton); ((U (-n), Ga, U n), FBF (1, Psibar, V, Psi), Q_up); ((D (-n), Ga, D n), FBF (1, Psibar, V, Psi), Q_down) ] let color_currents n = [ ((D (-n), Gl, D n), FBF ((-1), Psibar, V, Psi), Gs); ((U (-n), Gl, U n), FBF ((-1), Psibar, V, Psi), Gs); ((QH (-n), Gl, QH n), FBF ((-1), Psibar, V, Psi), Gs)] let neutral_currents n = [ ((L (-n), Z, L n), FBF (1, Psibar, VA, Psi), G_NC_lepton); ((N (-n), Z, N n), FBF (1, Psibar, VA, Psi), G_NC_neutrino); ((U (-n), Z, U n), FBF (1, Psibar, VA, Psi), G_NC_up); ((D (-n), Z, D n), FBF (1, Psibar, VA, Psi), G_NC_down) ] let xy_currents = ThoList.flatmap (fun n -> [ ((N (-n), X0, N n), FBF ((-1), Psibar, VL, Psi), G_NC_X); ((L (-n), Xm, N n), FBF ((-1), Psibar, VL, Psi), G_NC_X); ((N (-n), Xp, L n), FBF ((-1), Psibar, VL, Psi), G_NC_X); ((N (-n), Y0, N n), FBF ((-1), Psibar, VL, Psi), G_NC_Y); ((NH (-n), X0, N n), FBF ((-1), Psibar, VL, Psi), G_CC); ((N (-n), X0, NH n), FBF ((-1), Psibar, VL, Psi), G_CC); ((NH (-n), Y0, N n), FBF ((-1), Psibar, VL, Psi), I_G_CC); ((N (-n), Y0, NH n), FBF ((-1), Psibar, VL, Psi), I_G_CC); ((L (-n), Xm, NH n), FBF ((-1), Psibar, VL, Psi), G_CC); ((NH (-n), Xp, L n), FBF ((-1), Psibar, VL, Psi), G_CC)]) [1;2;3] @ [ ((U (-3), X0, U 3), FBF (1, Psibar, VL, Psi), G_NC_X_t); ((U (-3), Y0, U 3), FBF (1, Psibar, VL, Psi), G_NC_Y_t); ((U (-3), X0, QH 3), FBF (1, Psibar, VL, Psi), G_CC); ((QH (-3), X0, U 3), FBF (1, Psibar, VL, Psi), G_CC); ((U (-3), Y0, QH 3), FBF (1, Psibar, VL, Psi), I_G_CC); ((QH (-3), Y0, U 3), FBF (1, Psibar, VL, Psi), I_G_CC); ((D (-3), Xm, U 3), FBF (1, Psibar, VL, Psi), G_NC_X_t); ((U (-3), Xp, D 3), FBF (1, Psibar, VL, Psi), G_NC_X_t); ((D (-3), Xm, QH 3), FBF (1, Psibar, VL, Psi), G_CC); ((QH (-3), Xp, D 3), FBF (1, Psibar, VL, Psi), G_CC); ((QH (-3), Wp, D 3), FBF (1, Psibar, VL, Psi), G_NC_X_t); ((D (-3), Wm, QH 3), FBF (1, Psibar, VL, Psi), G_NC_X_t); ((QH (-3), Z, U 3), FBF (1, Psibar, VL, Psi), G_NCHt); ((U (-3), Z, QH 3), FBF (1, Psibar, VL, Psi), G_NCHt)] @ ThoList.flatmap (fun n -> if Flags.anom_ferm_ass then [ ((U (-n), X0, U n), FBF ((-1), Psibar, VL, Psi), G_NC_X); ((U (-n), Y0, U n), FBF ((-1), Psibar, VL, Psi), G_NC_Y); ((D (-n), Xm, U n), FBF ((-1), Psibar, VL, Psi), G_NC_X); ((U (-n), Xp, D n), FBF ((-1), Psibar, VL, Psi), G_NC_X); ((QH (-n), X0, U n), FBF ((-1), Psibar, VL, Psi), G_CC); ((U (-n), X0, QH n), FBF ((-1), Psibar, VL, Psi), G_CC); ((QH (-n), Y0, U n), FBF ((-1), Psibar, VL, Psi), I_G_CC); ((U (-n), Y0, QH n), FBF ((-1), Psibar, VL, Psi), I_G_CC); ((D (-n), Xm, QH n), FBF ((-1), Psibar, VL, Psi), G_CC); ((QH (-n), Xp, D n), FBF ((-1), Psibar, VL, Psi), G_CC); ((QH (-n), Wp, D n), FBF ((-1), Psibar, VL, Psi), G_NC_X); ((D (-n), Wm, QH n), FBF ((-1), Psibar, VL, Psi), G_NC_X); ((QH (-n), Z, U n), FBF (1, Psibar, VL, Psi), G_NC_H); ((U (-n), Z, QH n), FBF (1, Psibar, VL, Psi), G_NC_H)] else [ ((D (-n), X0, D n), FBF (1, Psibar, VL, Psi), G_NC_X); ((D (-n), Y0, D n), FBF (1, Psibar, VL, Psi), G_NC_Y); ((D (-n), Xm, U n), FBF (1, Psibar, VL, Psi), G_NC_X); ((U (-n), Xp, D n), FBF (1, Psibar, VL, Psi), G_NC_X); ((QH (-n), X0, D n), FBF ((-1), Psibar, VL, Psi), G_CC); ((D (-n), X0, QH n), FBF ((-1), Psibar, VL, Psi), G_CC); ((QH (-n), Y0, D n), FBF ((-1), Psibar, VL, Psi), I_G_CC); ((D (-n), Y0, QH n), FBF ((-1), Psibar, VL, Psi), I_G_CC); ((QH (-n), Xm, U n), FBF (1, Psibar, VL, Psi), G_CC); ((U (-n), Xp, QH n), FBF (1, Psibar, VL, Psi), G_CC); ((QH (-n), Wm, U n), FBF (1, Psibar, VL, Psi), G_NC_X); ((U (-n), Wp, QH n), FBF (1, Psibar, VL, Psi), G_NC_X); ((QH (-n), Z, D n), FBF (1, Psibar, VL, Psi), G_NC_H); ((D (-n), Z, QH n), FBF (1, Psibar, VL, Psi), G_NC_H)]) [1; 2] (* The sign of this coupling is just the one of the T3, being -(1/2) for leptons and down quarks, and +(1/2) for neutrinos and up quarks. *) let neutral_heavy_currents n = [ ((L (-n), ZH, L n), FBF (1, Psibar, VLR, Psi), G_NC_h_lepton); ((N (-n), ZH, N n), FBF ((-1), Psibar, VLR, Psi), G_NC_h_neutrino); ((U (-n), ZH, U n), FBF ((-1), Psibar, VLR, Psi), (if n = 3 then G_NC_h_top else G_NC_h_up)); ((D (-n), ZH, D n), FBF (1, Psibar, VLR, Psi), (if n = 3 then G_NC_h_bot else G_NC_h_down)); ((NH (-n), ZH, NH n), FBF (1, Psibar, VLR, Psi), G_NCH_N); ((QH (-n), ZH, QH n), FBF (1, Psibar, VLR, Psi), (if n = 3 then G_NCH_U else if Flags.anom_ferm_ass then G_NCH_U else G_NCH_D))] let heavy_currents n = [ ((QH (-n), Ga, QH n), FBF (1, Psibar, V, Psi), (if n=3 then Q_up else if Flags.anom_ferm_ass then Q_up else Q_down))] let charged_currents n = [ ((L (-n), Wm, N n), FBF (1, Psibar, VL, Psi), G_CC); ((N (-n), Wp, L n), FBF (1, Psibar, VL, Psi), G_CC); ((D (-n), Wm, U n), FBF (1, Psibar, VL, Psi), G_CC); ((U (-n), Wp, D n), FBF (1, Psibar, VL, Psi), G_CC) ] let yukawa = [ ((U (-3), H, U 3), FBF (1, Psibar, S, Psi), G_Htt); ((D (-3), H, D 3), FBF (1, Psibar, S, Psi), G_Hbb); ((U (-2), H, U 2), FBF (1, Psibar, S, Psi), G_Hcc); ((L (-3), H, L 3), FBF (1, Psibar, S, Psi), G_Htautau) ] let yukawa_add = [ ((QH (-3), H, U 3), FBF (1, Psibar, SL, Psi), G_Htht); ((U (-3), H, QH 3), FBF (1, Psibar, SR, Psi), G_Htht); ((QH (-3), Eta, U 3), FBF (1, Psibar, SR, Psi), G_Etht); ((U (-3), Eta, QH 3), FBF (1, Psibar, SL, Psi), G_Etht); ((D (-3), Eta, D 3), FBF (1, Psibar, P, Psi), G_Ebb); ((U (-3), Eta, U 3), FBF (1, Psibar, P, Psi), G_Ett)] @ ThoList.flatmap (fun n -> if Flags.anom_ferm_ass then [ ((QH (-n), H, U n), FBF (1, Psibar, SL, Psi), G_Hqhq); ((U (-n), H, QH n), FBF (1, Psibar, SR, Psi), G_Hqhq)] else [ ((QH (-n), H, D n), FBF (1, Psibar, SL, Psi), G_Hqhq); ((D (-n), H, QH n), FBF (1, Psibar, SR, Psi), G_Hqhq)]) [1;2] let standard_triple_gauge = [ ((Ga, Wm, Wp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW); ((Gl, Gl, Gl), Gauge_Gauge_Gauge 1, I_Gs)] let heavy_triple_gauge = [ ((Ga, Xm, Xp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Xm, Xp), Gauge_Gauge_Gauge 1, I_Q_ZH); ((Z, X0, Y0), Gauge_Gauge_Gauge 1, I_G_Z1); ((ZH, X0, Y0), Gauge_Gauge_Gauge 1, I_G_Z2); ((Y0, Wm, Xp), Gauge_Gauge_Gauge 1, I_G_Z3); ((Y0, Wp, Xm), Gauge_Gauge_Gauge (-1), I_G_Z3); ((X0, Wm, Xp), Gauge_Gauge_Gauge 1, I_G_Z4); ((X0, Wp, Xm), Gauge_Gauge_Gauge 1, I_G_Z4); ((ZH, Xm, Xp), Gauge_Gauge_Gauge 1, I_G_Z5); ((ZH, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_Z6)] let triple_gauge = standard_triple_gauge @ heavy_triple_gauge let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] let standard_quartic_gauge = [ (Wm, Wp, Wm, Wp), gauge4, G_WWWW; (Wm, Z, Wp, Z), minus_gauge4, G_ZZWW; (Wm, Z, Wp, Ga), minus_gauge4, G_AZWW; (Wm, Ga, Wp, Ga), minus_gauge4, G_AAWW; (Gl, Gl, Gl, Gl), gauge4, G2] let heavy_quartic_gauge = [] let quartic_gauge = standard_quartic_gauge @ heavy_quartic_gauge let standard_gauge_higgs' = [ ((H, Wp, Wm), Scalar_Vector_Vector 1, G_HWW); ((H, Z, Z), Scalar_Vector_Vector 1, G_HZZ) ] let heavy_gauge_higgs = [ ((H, Wp, Xm), Scalar_Vector_Vector 1, G_heavy_HWW); ((H, Wm, Xp), Scalar_Vector_Vector 1, G_heavy_HWW); ((H, Z, X0), Scalar_Vector_Vector 1, G_heavy_HVV); ((H, ZH, X0), Scalar_Vector_Vector 1, G_heavy_HVV)] let standard_gauge_higgs = standard_gauge_higgs' @ heavy_gauge_higgs let standard_gauge_higgs4 = [ (H, H, Wp, Wm), Scalar2_Vector2 1, G_HHWW; (H, H, Z, Z), Scalar2_Vector2 1, G_HHZZ ] let heavy_gauge_higgs4 = [ (H, H, Z, ZH), Scalar2_Vector2 1, G_HHZZH; (H, H, Xp, Xm), Scalar2_Vector2 (-1), G_HHWW; (H, H, ZH, ZH), Scalar2_Vector2 (-1), G_HHZZ ] let standard_higgs = [ (H, H, H), Scalar_Scalar_Scalar 1, G_H3 ] let anomaly_higgs = [ (Eta, Gl, Gl), Dim5_Scalar_Gauge2_Skew 1, G_EGlGl; (Eta, Ga, Ga), Dim5_Scalar_Gauge2_Skew 1, G_EGaGa; (Eta, Ga, Z), Dim5_Scalar_Gauge2_Skew 1, G_EGaZ ] (* @ [ (H, Ga, Ga), Dim5_Scalar_Gauge2 1, G_HGaGa; (H, Ga, Z), Dim5_Scalar_Gauge2 1, G_HGaZ ] *) let standard_higgs4 = [ (H, H, H, H), Scalar4 1, G_H4 ] let gauge_higgs = standard_gauge_higgs let gauge_higgs4 = standard_gauge_higgs4 @ heavy_gauge_higgs4 let higgs = standard_higgs let eta_higgs_gauge = [ (Z, Eta, H), Vector_Scalar_Scalar 1, G_ZEH; (ZH, Eta, H), Vector_Scalar_Scalar 1, G_ZHEH; (X0, Eta, H), Vector_Scalar_Scalar 1, G_CC ] let top_quartic = [ ((QH (-3), H, H, QH 3), GBBG (1, Psibar, S2, Psi), G_HHthth)] let higgs4 = standard_higgs4 let goldstone_vertices = [ ((Phi0, Wm, Wp), Scalar_Vector_Vector 1, I_G_ZWW); ((Phip, Ga, Wm), Scalar_Vector_Vector 1, I_Q_W); ((Phip, Z, Wm), Scalar_Vector_Vector 1, I_G_ZWW); ((Phim, Wp, Ga), Scalar_Vector_Vector 1, I_Q_W); ((Phim, Wp, Z), Scalar_Vector_Vector 1, I_G_ZWW) ] let vertices3 = (ThoList.flatmap electromagnetic_currents [1;2;3] @ ThoList.flatmap color_currents [1;2;3] @ ThoList.flatmap neutral_currents [1;2;3] @ ThoList.flatmap neutral_heavy_currents [1;2;3] @ ThoList.flatmap heavy_currents [1;2;3] @ ThoList.flatmap charged_currents [1;2;3] @ xy_currents @ anomaly_higgs @ eta_higgs_gauge @ yukawa @ yukawa_add @ triple_gauge @ gauge_higgs @ higgs @ goldstone_vertices) let vertices4 = quartic_gauge @ gauge_higgs4 @ higgs4 let vertices () = (vertices3, vertices4, []) (* For efficiency, make sure that [F.of_vertices vertices] is evaluated only once. *) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 let flavor_of_string = function | "e-" -> L 1 | "e+" -> L (-1) | "mu-" -> L 2 | "mu+" -> L (-2) | "tau-" -> L 3 | "tau+" -> L (-3) | "nue" -> N 1 | "nuebar" -> N (-1) | "numu" -> N 2 | "numubar" -> N (-2) | "nutau" -> N 3 | "nutaubar" -> N (-3) | "nh1" -> NH 1 | "nh1bar" -> NH (-1) | "nh2" -> NH 2 | "nh2bar" -> NH (-2) | "nh3" -> NH 3 | "nh3bar" -> NH (-3) | "u" -> U 1 | "ubar" -> U (-1) | "c" -> U 2 | "cbar" -> U (-2) | "t" -> U 3 | "tbar" -> U (-3) | "d" -> D 1 | "dbar" -> D (-1) | "s" -> D 2 | "sbar" -> D (-2) | "b" -> D 3 | "bbar" -> D (-3) | "uh" -> if Flags.anom_ferm_ass then QH 1 else invalid_arg "Modellib_BSM.Simplest.flavor_of_string" | "dh" -> if Flags.anom_ferm_ass then invalid_arg "Modellib_BSM.Simplest.flavor_of_string" else QH 1 | "uhbar" -> if Flags.anom_ferm_ass then QH (-1) else invalid_arg "Modellib_BSM.Simplest.flavor_of_string" | "dhbar" -> if Flags.anom_ferm_ass then invalid_arg "Modellib_BSM.Simplest.flavor_of_string" else QH (-1) | "ch" -> if Flags.anom_ferm_ass then QH 2 else invalid_arg "Modellib_BSM.Simplest.flavor_of_string" | "sh" -> if Flags.anom_ferm_ass then invalid_arg "Modellib_BSM.Simplest.flavor_of_string" else QH 2 | "chbar" -> if Flags.anom_ferm_ass then QH (-2) else invalid_arg "Modellib_BSM.Simplest.flavor_of_string" | "shbar" -> if Flags.anom_ferm_ass then invalid_arg "Modellib_BSM.Simplest.flavor_of_string" else QH (-2) | "th" -> QH 3 | "thbar" -> QH (-3) | "eta" | "Eta" -> Eta | "A" -> Ga | "Z" | "Z0" -> Z | "g" | "gl" -> Gl | "ZH" | "ZH0" | "Zh" | "Zh0" -> ZH | "W+" -> Wp | "W-" -> Wm | "X+" -> Xp | "X-" -> Xm | "X0" -> X0 | "Y0" -> Y0 | "H" -> H | _ -> invalid_arg "Modellib_BSM.Simplest.flavor_of_string" let flavor_to_string = function | L 1 -> "e-" | L (-1) -> "e+" | L 2 -> "mu-" | L (-2) -> "mu+" | L 3 -> "tau-" | L (-3) -> "tau+" | L _ -> invalid_arg "Modellib_BSM.Simplest.flavor_to_string: invalid lepton" | N 1 -> "nue" | N (-1) -> "nuebar" | N 2 -> "numu" | N (-2) -> "numubar" | N 3 -> "nutau" | N (-3) -> "nutaubar" | N _ -> invalid_arg "Modellib_BSM.Simplest.flavor_to_string: invalid neutrino" | U 1 -> "u" | U (-1) -> "ubar" | U 2 -> "c" | U (-2) -> "cbar" | U 3 -> "t" | U (-3) -> "tbar" | U _ -> invalid_arg "Modellib_BSM.Simplest.flavor_to_string: invalid up type quark" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | D _ -> invalid_arg "Modellib_BSM.Simplest.flavor_to_string: invalid down type quark" | QH 1 -> if Flags.anom_ferm_ass then "uh" else "dh" | QH 2 -> if Flags.anom_ferm_ass then "ch" else "sh" | QH 3 -> "th" | QH (-1) -> if Flags.anom_ferm_ass then "uhbar" else "dhbar" | QH (-2) -> if Flags.anom_ferm_ass then "chbar" else "shbar" | QH (-3) -> "thbar" | QH _ -> invalid_arg "Modellib_BSM.Simplest.flavor_to_string: invalid heavy quark" | NH n when n > 0 -> "nh" ^ string_of_int n | NH n -> "nh" ^ string_of_int (abs n) ^ "bar" | Ga -> "A" | Z -> "Z" | Gl -> "gl" | Wp -> "W+" | Wm -> "W-" | Xp -> "X+" | Xm -> "X-" | X0 -> "X0" | Y0 -> "Y0" | ZH -> "ZH" | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | H -> "H" | Eta -> "Eta" let flavor_to_TeX = function | L 1 -> "e^-" | L (-1) -> "\\e^+" | L 2 -> "\\mu^-" | L (-2) -> "\\mu^+" | L 3 -> "\\tau^-" | L (-3) -> "\\tau^+" | L _ -> invalid_arg "Modellib_BSM.Simplest.flavor_to_TeX: invalid lepton" | N 1 -> "\\nu_e" | N (-1) -> "\\bar{\\nu}_e" | N 2 -> "\\nu_\\mu" | N (-2) -> "\\bar{\\nu}_\\mu" | N 3 -> "\\nu_\\tau" | N (-3) -> "\\bar{\\nu}_\\tau" | N _ -> invalid_arg "Modellib_BSM.Simplest.flavor_to_TeX: invalid neutrino" | U 1 -> "u" | U (-1) -> "\\bar{u}" | U 2 -> "c" | U (-2) -> "\\bar{c}" | U 3 -> "t" | U (-3) -> "\\bar{t}" | U _ -> invalid_arg "Modellib_BSM.Simplest.flavor_to_TeX: invalid up type quark" | D 1 -> "d" | D (-1) -> "\\bar{d}" | D 2 -> "s" | D (-2) -> "\\bar{s}" | D 3 -> "b" | D (-3) -> "\\bar{b}" | D _ -> invalid_arg "Modellib_BSM.Simplest.flavor_to_TeX: invalid down type quark" | QH 1 -> if Flags.anom_ferm_ass then "U" else "D" | QH 2 -> if Flags.anom_ferm_ass then "C" else "S" | QH 3 -> "T" | QH (-1) -> if Flags.anom_ferm_ass then "\\bar{U}" else "\\bar{D}" | QH (-2) -> if Flags.anom_ferm_ass then "\\bar{C}" else "\\bar{S}" | QH (-3) -> "thbar" | QH _ -> invalid_arg "Modellib_BSM.Simplest.flavor_to_TeX: invalid heavy quark" | NH n when n > 0 -> "N_" ^ string_of_int n | NH n -> "\\bar{N}_" ^ string_of_int (abs n) | Ga -> "\\gamma" | Z -> "Z" | Gl -> "g" | Wp -> "W^+" | Wm -> "W^-" | Xp -> "X^+" | Xm -> "X^-" | X0 -> "X^0" | Y0 -> "Y^0" | ZH -> "Z_H" | Phip -> "\\phi^+" | Phim -> "\\phi^-" | Phi0 -> "\\phi^0" | H -> "H" | Eta -> "\\eta" let flavor_symbol = function | L n when n > 0 -> "l" ^ string_of_int n | L n -> "l" ^ string_of_int (abs n) ^ "b" | N n when n > 0 -> "n" ^ string_of_int n | N n -> "n" ^ string_of_int (abs n) ^ "b" | U n when n > 0 -> "u" ^ string_of_int n | U n -> "u" ^ string_of_int (abs n) ^ "b" | D n when n > 0 -> "d" ^ string_of_int n | D n -> "d" ^ string_of_int (abs n) ^ "b" | NH n when n > 0 -> "nh" ^ string_of_int n | NH n -> "nh" ^ string_of_int (abs n) ^ "b" | QH n when n > 0 -> "qh" ^ string_of_int n | QH n -> "qh" ^ string_of_int (abs n) ^ "b" | Ga -> "a" | Z -> "z" | Gl -> "gl" | Wp -> "wp" | Wm -> "wm" | Xp -> "xp" | Xm -> "xm" | X0 -> "x0" | Y0 -> "y0" | ZH -> "zh" | Phip -> "pp" | Phim -> "pm" | Phi0 -> "p0" | H -> "h" | Eta -> "eta" (* There are PDG numbers for Z', Z'', W', 32-34, respectively. We just introduce a number 38 for Y0 as a Z'''. As well, there is the number 8 for a t'. But we cheat a little bit and take the number 35 which is reserved for a heavy scalar Higgs for the Eta scalar. We abuse notation for the heavy quarks and take the PDG code for their SUSY partners!!! (What about an update of the PDG numbering scheme?) Thereby we take only those for up-type (s)quarks. The heavy neutrinos get the numbers of the sneutrinos. *) let pdg = function | L n when n > 0 -> 9 + 2*n | L n -> - 9 + 2*n | N n when n > 0 -> 10 + 2*n | N n -> - 10 + 2*n | U n when n > 0 -> 2*n | U n -> 2*n | D n when n > 0 -> - 1 + 2*n | D n -> 1 + 2*n | NH n when n > 0 -> 1000010 + 2*n | NH n -> - 1000010 + 2*n | QH 3 -> 1000006 | QH (-3) -> - 1000006 | QH n when n > 0 -> if Flags.anom_ferm_ass then 1000000 + 2*n else 999999 + 2*n | QH n -> if Flags.anom_ferm_ass then - 1000000 + 2*n else - 999999 + 2*n | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) | Xp -> 34 | Xm -> (-34) | ZH -> 32 | X0 -> 33 | Y0 -> 38 | Phip | Phim -> 27 | Phi0 -> 26 | H -> 25 | Eta -> 36 (* As in the case of SUSY we introduce an internal dummy pdf code in order to have manageable arrays. Heavy neutrinos get numbers 41,43,45, while the heavy quarks have the numbers 40,42,44. I take them all as up type here. *) let pdg_mw = function | L n when n > 0 -> 9 + 2*n | L n -> - 9 + 2*n | N n when n > 0 -> 10 + 2*n | N n -> - 10 + 2*n | U n when n > 0 -> 2*n | U n -> 2*n | D n when n > 0 -> - 1 + 2*n | D n -> 1 + 2*n | NH n when n > 0 -> 39 + 2*n | NH n -> - 39 + 2*n | QH n when n > 0 -> 38 + 2*n | QH n -> - 38 + 2*n | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) | Xp -> 34 | Xm -> (-34) | ZH -> 32 | X0 -> 33 | Y0 -> 38 | Phip | Phim -> 27 | Phi0 -> 26 | H -> 25 | Eta -> 36 let mass_symbol f = "mass(" ^ string_of_int (abs (pdg_mw f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg_mw f)) ^ ")" let constant_symbol = function | Unit -> "unit" | Pi -> "PI" | VHeavy -> "vheavy" | Alpha_QED -> "alpha" | E -> "e" | G_weak -> "g" | Vev -> "vev" | Sin2thw -> "sin2thw" | Sinthw -> "sinthw" | Costhw -> "costhw" | Sinpsi -> "sinpsi" | Cospsi -> "cospsi" | Atpsi -> "atpsi" | Sccs -> "sccs" | Supp -> "vF" | Supp2 -> "v2F2" | Q_lepton -> "qlep" | Q_up -> "qup" | Q_down -> "qdwn" | Q_Z_up -> "qzup" | G_zhthth -> "gzhthth" | G_NC_lepton -> "gnclep" | G_NC_neutrino -> "gncneu" | G_NC_up -> "gncup" | G_NC_down -> "gncdwn" | G_NC_X -> "gncx" | G_NC_X_t -> "gncxt" | G_NC_Y -> "gncy" | G_NC_Y_t -> "gncyt" | G_NC_H -> "gnch" | G_CC -> "gcc" | I_G_CC -> "i_gcc" | G_NC_h_lepton -> "gnchlep" | G_NC_h_neutrino -> "gnchneu" | G_NC_h_up -> "gnchup" | G_NC_h_down -> "gnchdwn" | G_NC_h_top -> "gnchtop" | G_NC_h_bot -> "gnchbot" | G_NCH_N -> "gnchn" | G_NCH_U -> "gnchu" | G_NCH_D -> "gnchd" | G_NCHt -> "gncht" | I_Q_W -> "iqw" | I_G_ZWW -> "igzww" | I_G_WWW -> "igwww" | I_Q_H -> "iqh" | I_Q_ZH -> "iqzh" | I_G_Z1 -> "igz1" | I_G_Z2 -> "igz2" | I_G_Z3 -> "igz3" | I_G_Z4 -> "igz4" | I_G_Z5 -> "igz5" | I_G_Z6 -> "igz6" | G_HHthth -> "ghhthth" | G_WWWW -> "gw4" | G_ZZWW -> "gzzww" | G_AZWW -> "gazww" | G_AAWW -> "gaaww" | G_HWW -> "ghww" | G_HZZ -> "ghzz" | G_heavy_HVV -> "ghyhvv" | G_heavy_HWW -> "ghyhww" | G_heavy_HZZ -> "ghyhzz" | G_HHWW -> "ghhww" | G_HHZZ -> "ghhzz" | G_HHZZH -> "ghhzzh" | G_Hgg -> "ghgg" | G_Htt -> "ghtt" | G_Hbb -> "ghbb" | G_Htautau -> "ghtautau" | G_Hcc -> "ghcc" | G_Hthth -> "ghthth" | G_Htht -> "ghtht" | G_Hqhq -> "ghqhq" | G_Ethth -> "gethth" | G_Etht -> "getht" | G_Ett -> "gett" | G_Ebb -> "gebb" | G_HGaGa -> "ghgaga" | G_HGaZ -> "ghgaz" | G_EGaGa -> "geaa" | G_EGaZ -> "geaz" | G_EGlGl -> "gegg" | G_ZEH -> "gzeh" | G_ZHEH -> "gzheh" | G_H3 -> "gh3" | G_H4 -> "gh4" | Mass f -> "mass" ^ flavor_symbol f | Width f -> "width" ^ flavor_symbol f | Gs -> "gs" | I_Gs -> "igs" | G2 -> "gs**2" end module Xdim (Flags : BSM_flags) = struct open Coupling let default_width = ref Timelike let use_fudged_width = ref false let options = Options.create [ "constant_width", Arg.Unit (fun () -> default_width := Constant), "use constant width (also in t-channel)"; "fudged_width", Arg.Set use_fudged_width, "use fudge factor for charge particle width"; "custom_width", Arg.String (fun f -> default_width := Custom f), "use custom width"; "cancel_widths", Arg.Unit (fun () -> default_width := Vanishing), "use vanishing width"; "cms_width", Arg.Unit (fun () -> default_width := Complex_Mass), - "use complex mass scheme"] + "use complex mass scheme"; + "running_width", Arg.Unit (fun () -> default_width := Running), + "use running width"] type matter_field = L of int | N of int | U of int | D of int type gauge_boson = Ga | Wp | Wm | Z | Gl type other = Phip | Phim | Phi0 | H | Grav type flavor = M of matter_field | G of gauge_boson | O of other let matter_field f = M f let gauge_boson f = G f let other f = O f type field = | Matter of matter_field | Gauge of gauge_boson | Other of other let field = function | M f -> Matter f | G f -> Gauge f | O f -> Other f type gauge = unit let gauge_symbol () = failwith "Modellib_BSM.Xdim.gauge_symbol: internal error" let family n = List.map matter_field [ L n; N n; U n; D n ] let external_flavors () = [ "1st Generation", ThoList.flatmap family [1; -1]; "2nd Generation", ThoList.flatmap family [2; -2]; "3rd Generation", ThoList.flatmap family [3; -3]; "Gauge Bosons", List.map gauge_boson [Ga; Z; Wp; Wm; Gl]; "Higgs", List.map other [H]; "Graviton", List.map other [Grav]; "Goldstone Bosons", List.map other [Phip; Phim; Phi0] ] let flavors () = ThoList.flatmap snd (external_flavors ()) let spinor n = if n >= 0 then Spinor else ConjSpinor let lorentz = function | M f -> begin match f with | L n -> spinor n | N n -> spinor n | U n -> spinor n | D n -> spinor n end | G f -> begin match f with | Ga | Gl -> Vector | Wp | Wm | Z -> Massive_Vector end | O f -> begin match f with | Grav -> Tensor_2 | _ -> Scalar end let color = function | M (U n) -> Color.SUN (if n > 0 then 3 else -3) | M (D n) -> Color.SUN (if n > 0 then 3 else -3) | G Gl -> Color.AdjSUN 3 | _ -> Color.Singlet let nc () = 3 let prop_spinor n = if n >= 0 then Prop_Spinor else Prop_ConjSpinor let propagator = function | M f -> begin match f with | L n -> prop_spinor n | N n -> prop_spinor n | U n -> prop_spinor n | D n -> prop_spinor n end | G f -> begin match f with | Ga | Gl -> Prop_Feynman | Wp | Wm | Z -> Prop_Unitarity end | O f -> begin match f with | Phip | Phim | Phi0 -> Only_Insertion | H -> Prop_Scalar | Grav -> Prop_Tensor_2 end (* Optionally, ask for the fudge factor treatment for the widths of charged particles. Currently, this only applies to $W^\pm$ and top. *) let width f = if !use_fudged_width then match f with | G Wp | G Wm | M (U 3) | M (U (-3)) | O Grav -> Fudged | _ -> !default_width else !default_width let goldstone = function | G f -> begin match f with | Wp -> Some (O Phip, Coupling.Integer 1) | Wm -> Some (O Phim, Coupling.Integer 1) | Z -> Some (O Phi0, Coupling.Integer 1) | _ -> None end | _ -> None let conjugate = function | M f -> M (begin match f with | L n -> L (-n) | N n -> N (-n) | U n -> U (-n) | D n -> D (-n) end) | G f -> G (begin match f with | Gl -> Gl | Ga -> Ga | Z -> Z | Wp -> Wm | Wm -> Wp end) | O f -> O (begin match f with | Phip -> Phim | Phim -> Phip | Phi0 -> Phi0 | H -> H | Grav -> Grav end) let fermion = function | M f -> begin match f with | L n -> if n > 0 then 1 else -1 | N n -> if n > 0 then 1 else -1 | U n -> if n > 0 then 1 else -1 | D n -> if n > 0 then 1 else -1 end | G f -> begin match f with | Gl | Ga | Z | Wp | Wm -> 0 end | O _ -> 0 module Ch = Charges.QQ let ( // ) = Algebra.Small_Rational.make let generation' = function | 1 -> [ 1//1; 0//1; 0//1] | 2 -> [ 0//1; 1//1; 0//1] | 3 -> [ 0//1; 0//1; 1//1] | -1 -> [-1//1; 0//1; 0//1] | -2 -> [ 0//1; -1//1; 0//1] | -3 -> [ 0//1; 0//1; -1//1] | n -> invalid_arg ("Xdim.generation': " ^ string_of_int n) let generation f = match f with | M (L n | N n | U n | D n) -> generation' n | G _ | O _ -> [0//1; 0//1; 0//1] let charge = function | M f -> begin match f with | L n -> if n > 0 then -1//1 else 1//1 | N n -> 0//1 | U n -> if n > 0 then 2//3 else -2//3 | D n -> if n > 0 then -1//3 else 1//3 end | G f -> begin match f with | Gl | Ga | Z -> 0//1 | Wp -> 1//1 | Wm -> -1//1 end | O f -> begin match f with | H | Phi0 | Grav -> 0//1 | Phip -> 1//1 | Phim -> -1//1 end let lepton = function | M f -> begin match f with | L n | N n -> if n > 0 then 1//1 else -1//1 | U _ | D _ -> 0//1 end | G _ | O _ -> 0//1 let baryon = function | M f -> begin match f with | L _ | N _ -> 0//1 | U n | D n -> if n > 0 then 1//1 else -1//1 end | G _ | O _ -> 0//1 let charges f = [ charge f; lepton f; baryon f] @ generation f type constant = | Unit | Pi | Alpha_QED | Sin2thw | Sinthw | Costhw | E | G_weak | Vev | Q_lepton | Q_up | Q_down | G_CC | G_CCQ of int*int | G_NC_neutrino | G_NC_lepton | G_NC_up | G_NC_down | Gs | I_Gs | G2 | I_Q_W | I_G_ZWW | G_WWWW | G_ZZWW | G_AZWW | G_AAWW | G_HWW | G_HHWW | G_HZZ | G_HHZZ | G_Htt | G_Hbb | G_Hcc | G_Htautau | G_H3 | G_H4 | G_HGaZ | G_HGaGa | G_Hgg | G_Grav | Mass of flavor | Width of flavor (* Two integer counters for the QCD and EW order of the couplings. *) type orders = int * int let orders = function | _ -> (0,0) let input_parameters = [] let derived_parameters = [] let g_over_2_costh = Quot (Neg (Atom G_weak), Prod [Integer 2; Atom Costhw]) let nc_coupling c t3 q = (Real_Array c, [Prod [g_over_2_costh; Diff (t3, Prod [Integer 2; q; Atom Sin2thw])]; Prod [g_over_2_costh; t3]]) let half = Quot (Integer 1, Integer 2) let derived_parameter_arrays = [ nc_coupling G_NC_neutrino half (Integer 0); nc_coupling G_NC_lepton (Neg half) (Integer (-1)); nc_coupling G_NC_up half (Quot (Integer 2, Integer 3)); nc_coupling G_NC_down (Neg half) (Quot (Integer (-1), Integer 3)) ] let parameters () = { input = input_parameters; derived = derived_parameters; derived_arrays = derived_parameter_arrays } module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) let mgm ((m1, g, m2), fbf, c) = ((M m1, G g, M m2), fbf, c) let mom ((m1, o, m2), fbf, c) = ((M m1, O o, M m2), fbf, c) let electromagnetic_currents n = List.map mgm [ ((L (-n), Ga, L n), FBF (1, Psibar, V, Psi), Q_lepton); ((U (-n), Ga, U n), FBF (1, Psibar, V, Psi), Q_up); ((D (-n), Ga, D n), FBF (1, Psibar, V, Psi), Q_down) ] let neutral_currents n = List.map mgm [ ((L (-n), Z, L n), FBF (1, Psibar, VA, Psi), G_NC_lepton); ((N (-n), Z, N n), FBF (1, Psibar, VA, Psi), G_NC_neutrino); ((U (-n), Z, U n), FBF (1, Psibar, VA, Psi), G_NC_up); ((D (-n), Z, D n), FBF (1, Psibar, VA, Psi), G_NC_down) ] let color_currents n = List.map mgm [ ((U (-n), Gl, U n), FBF ((-1), Psibar, V, Psi), Gs); ((D (-n), Gl, D n), FBF ((-1), Psibar, V, Psi), Gs) ] let charged_currents n = List.map mgm [ ((L (-n), Wm, N n), FBF (1, Psibar, VL, Psi), G_CC); ((N (-n), Wp, L n), FBF (1, Psibar, VL, Psi), G_CC); ((D (-n), Wm, U n), FBF (1, Psibar, VL, Psi), G_CC); ((U (-n), Wp, D n), FBF (1, Psibar, VL, Psi), G_CC) ] let gravity_currents n = List.map mom [ ((L (-n), Grav, L n), Graviton_Spinor_Spinor 1, G_Grav); ((N (-n), Grav, N n), Graviton_Spinor_Spinor 1, G_Grav); ((U (-n), Grav, U n), Graviton_Spinor_Spinor 1, G_Grav); ((D (-n), Grav, D n), Graviton_Spinor_Spinor 1, G_Grav) ] let yukawa = List.map mom [ ((U (-3), H, U 3), FBF (1, Psibar, S, Psi), G_Htt); ((D (-3), H, D 3), FBF (1, Psibar, S, Psi), G_Hbb); ((U (-2), H, U 2), FBF (1, Psibar, S, Psi), G_Hcc); ((L (-3), H, L 3), FBF (1, Psibar, S, Psi), G_Htautau) ] let tgc ((g1, g2, g3), t, c) = ((G g1, G g2, G g3), t, c) let standard_triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW); ((Gl, Gl, Gl), Gauge_Gauge_Gauge 1, I_Gs) ] let triple_gauge = standard_triple_gauge let qgc ((g1, g2, g3, g4), t, c) = ((G g1, G g2, G g3, G g4), t, c) let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] let standard_quartic_gauge = List.map qgc [ (Wm, Wp, Wm, Wp), gauge4, G_WWWW; (Wm, Z, Wp, Z), minus_gauge4, G_ZZWW; (Wm, Z, Wp, Ga), minus_gauge4, G_AZWW; (Wm, Ga, Wp, Ga), minus_gauge4, G_AAWW; (Gl, Gl, Gl, Gl), gauge4, G2] let quartic_gauge = standard_quartic_gauge let gravity_gauge = [ (O Grav, G Z, G Z), Graviton_Vector_Vector 1, G_Grav; (O Grav, G Wp, G Wm), Graviton_Vector_Vector 1, G_Grav; (O Grav, G Ga, G Ga), Graviton_Vector_Vector 1, G_Grav; (O Grav, G Gl, G Gl), Graviton_Vector_Vector 1, G_Grav ] let standard_gauge_higgs = [ ((O H, G Wp, G Wm), Scalar_Vector_Vector 1, G_HWW); ((O H, G Z, G Z), Scalar_Vector_Vector 1, G_HZZ) ] let standard_gauge_higgs4 = [ (O H, O H, G Wp, G Wm), Scalar2_Vector2 1, G_HHWW; (O H, O H, G Z, G Z), Scalar2_Vector2 1, G_HHZZ ] let standard_higgs = [ (O H, O H, O H), Scalar_Scalar_Scalar 1, G_H3 ] let standard_higgs4 = [ (O H, O H, O H, O H), Scalar4 1, G_H4 ] let gravity_higgs = [ (O Grav, O H, O H), Graviton_Scalar_Scalar 1, G_Grav] let anomalous_gauge_higgs = [] let anomalous_gauge_higgs4 = [] let anomalous_higgs = [] let anomaly_higgs = [ (O H, G Ga, G Ga), Dim5_Scalar_Gauge2 1, G_HGaGa; (O H, G Ga, G Z), Dim5_Scalar_Gauge2 1, G_HGaZ; (O H, G Gl, G Gl), Dim5_Scalar_Gauge2 1, G_Hgg ] let anomalous_higgs4 = [] let gauge_higgs = standard_gauge_higgs let gauge_higgs4 = standard_gauge_higgs4 let higgs = standard_higgs @ gravity_higgs let higgs4 = standard_higgs4 let goldstone_vertices = [ ((O Phi0, G Wm, G Wp), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phip, G Ga, G Wm), Scalar_Vector_Vector 1, I_Q_W); ((O Phip, G Z, G Wm), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phim, G Wp, G Ga), Scalar_Vector_Vector 1, I_Q_W); ((O Phim, G Wp, G Z), Scalar_Vector_Vector 1, I_G_ZWW) ] let vertices3 = (ThoList.flatmap electromagnetic_currents [1;2;3] @ ThoList.flatmap neutral_currents [1;2;3] @ ThoList.flatmap color_currents [1;2;3] @ ThoList.flatmap charged_currents [1;2;3] @ ThoList.flatmap gravity_currents [1;2;3] @ yukawa @ triple_gauge @ gravity_gauge @ gauge_higgs @ higgs @ anomaly_higgs @ goldstone_vertices) let vertices4 = quartic_gauge @ gauge_higgs4 @ higgs4 let vertices () = (vertices3, vertices4, []) (* For efficiency, make sure that [F.of_vertices vertices] is evaluated only once. *) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 let flavor_of_string = function | "e-" -> M (L 1) | "e+" -> M (L (-1)) | "mu-" -> M (L 2) | "mu+" -> M (L (-2)) | "tau-" -> M (L 3) | "tau+" -> M (L (-3)) | "nue" -> M (N 1) | "nuebar" -> M (N (-1)) | "numu" -> M (N 2) | "numubar" -> M (N (-2)) | "nutau" -> M (N 3) | "nutaubar" -> M (N (-3)) | "u" -> M (U 1) | "ubar" -> M (U (-1)) | "c" -> M (U 2) | "cbar" -> M (U (-2)) | "t" -> M (U 3) | "tbar" -> M (U (-3)) | "d" -> M (D 1) | "dbar" -> M (D (-1)) | "s" -> M (D 2) | "sbar" -> M (D (-2)) | "b" -> M (D 3) | "bbar" -> M (D (-3)) | "g" | "gl" -> G Gl | "A" -> G Ga | "Z" | "Z0" -> G Z | "W+" -> G Wp | "W-" -> G Wm | "H" -> O H | "GG" -> O Grav | _ -> invalid_arg "Modellib_BSM.Xdim.flavor_of_string" let flavor_to_string = function | M f -> begin match f with | L 1 -> "e-" | L (-1) -> "e+" | L 2 -> "mu-" | L (-2) -> "mu+" | L 3 -> "tau-" | L (-3) -> "tau+" | L _ -> invalid_arg "Modellib_BSM.Xdim.flavor_to_string: invalid lepton" | N 1 -> "nue" | N (-1) -> "nuebar" | N 2 -> "numu" | N (-2) -> "numubar" | N 3 -> "nutau" | N (-3) -> "nutaubar" | N _ -> invalid_arg "Modellib_BSM.Xdim.flavor_to_string: invalid neutrino" | U 1 -> "u" | U (-1) -> "ubar" | U 2 -> "c" | U (-2) -> "cbar" | U 3 -> "t" | U (-3) -> "tbar" | U _ -> invalid_arg "Modellib_BSM.Xdim.flavor_to_string: invalid up type quark" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | D _ -> invalid_arg "Modellib_BSM.Xdim.flavor_to_string: invalid down type quark" end | G f -> begin match f with | Gl -> "g" | Ga -> "A" | Z -> "Z" | Wp -> "W+" | Wm -> "W-" end | O f -> begin match f with | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | H -> "H" | Grav -> "GG" end let flavor_to_TeX = function | M f -> begin match f with | L 1 -> "e^-" | L (-1) -> "e^+" | L 2 -> "\\mu^-" | L (-2) -> "\\mu^+" | L 3 -> "\\tau^-" | L (-3) -> "\\tau^+" | L _ -> invalid_arg "Modellib_BSM.Xdim.flavor_to_TeX: invalid lepton" | N 1 -> "\\nu_e" | N (-1) -> "\\bar{\\nu}_e" | N 2 -> "\\nu_\\mu" | N (-2) -> "\\bar{\\nu}_\\mu" | N 3 -> "\\nu_\\tau" | N (-3) -> "\\bar{\\nu}_\\tau" | N _ -> invalid_arg "Modellib_BSM.Xdim.flavor_to_TeX: invalid neutrino" | U 1 -> "u" | U (-1) -> "\\bar{u}" | U 2 -> "c" | U (-2) -> "\\bar{c}" | U 3 -> "t" | U (-3) -> "\\bar{t}" | U _ -> invalid_arg "Modellib_BSM.Xdim.flavor_to_TeX: invalid up type quark" | D 1 -> "d" | D (-1) -> "\\bar{d}" | D 2 -> "s" | D (-2) -> "\\bar{s}" | D 3 -> "b" | D (-3) -> "\\bar{b}" | D _ -> invalid_arg "Modellib_BSM.Xdim.flavor_to_TeX: invalid down type quark" end | G f -> begin match f with | Gl -> "g" | Ga -> "\\gamma" | Z -> "Z" | Wp -> "W^+" | Wm -> "W^-" end | O f -> begin match f with | Phip -> "\\phi^+" | Phim -> "\\phi^-" | Phi0 -> "\\phi^0" | H -> "H" | Grav -> "G" end let flavor_symbol = function | M f -> begin match f with | L n when n > 0 -> "l" ^ string_of_int n | L n -> "l" ^ string_of_int (abs n) ^ "b" | N n when n > 0 -> "n" ^ string_of_int n | N n -> "n" ^ string_of_int (abs n) ^ "b" | U n when n > 0 -> "u" ^ string_of_int n | U n -> "u" ^ string_of_int (abs n) ^ "b" | D n when n > 0 -> "d" ^ string_of_int n | D n -> "d" ^ string_of_int (abs n) ^ "b" end | G f -> begin match f with | Gl -> "gl" | Ga -> "a" | Z -> "z" | Wp -> "wp" | Wm -> "wm" end | O f -> begin match f with | Phip -> "pp" | Phim -> "pm" | Phi0 -> "p0" | H -> "h" | Grav -> "gv" end let pdg = function | M f -> begin match f with | L n when n > 0 -> 9 + 2*n | L n -> - 9 + 2*n | N n when n > 0 -> 10 + 2*n | N n -> - 10 + 2*n | U n when n > 0 -> 2*n | U n -> 2*n | D n when n > 0 -> - 1 + 2*n | D n -> 1 + 2*n end | G f -> begin match f with | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) end | O f -> begin match f with | Phip | Phim -> 27 | Phi0 -> 26 | H -> 25 | Grav -> 39 end let mass_symbol f = "mass(" ^ string_of_int (abs (pdg f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg f)) ^ ")" let constant_symbol = function | Unit -> "unit" | Pi -> "PI" | Alpha_QED -> "alpha" | E -> "e" | G_weak -> "g" | Vev -> "vev" | Sin2thw -> "sin2thw" | Sinthw -> "sinthw" | Costhw -> "costhw" | Q_lepton -> "qlep" | Q_up -> "qup" | Q_down -> "qdwn" | G_NC_lepton -> "gnclep" | G_NC_neutrino -> "gncneu" | G_NC_up -> "gncup" | G_NC_down -> "gncdwn" | Gs -> "gs" | I_Gs -> "igs" | G2 -> "gs**2" | G_CC -> "gcc" | G_CCQ (n1,n2) -> "gccq" ^ string_of_int n1 ^ string_of_int n2 | I_Q_W -> "iqw" | I_G_ZWW -> "igzww" | G_WWWW -> "gw4" | G_ZZWW -> "gzzww" | G_AZWW -> "gazww" | G_AAWW -> "gaaww" | G_HWW -> "ghww" | G_HZZ -> "ghzz" | G_HHWW -> "ghhww" | G_HHZZ -> "ghhzz" | G_Htt -> "ghtt" | G_Hbb -> "ghbb" | G_Htautau -> "ghtautau" | G_Hcc -> "ghcc" | G_HGaZ -> "ghgaz" | G_HGaGa -> "ghgaga" | G_Hgg -> "ghgg" | G_H3 -> "gh3" | G_H4 -> "gh4" | G_Grav -> "ggrav" | Mass f -> "mass" ^ flavor_symbol f | Width f -> "width" ^ flavor_symbol f end module UED (Flags : BSM_flags) = struct open Coupling let default_width = ref Timelike let use_fudged_width = ref false let options = Options.create [ "constant_width", Arg.Unit (fun () -> default_width := Constant), "use constant width (also in t-channel)"; "fudged_width", Arg.Set use_fudged_width, "use fudge factor for charge particle width"; "custom_width", Arg.String (fun f -> default_width := Custom f), "use custom width"; "cancel_widths", Arg.Unit (fun () -> default_width := Vanishing), "use vanishing width"; "cms_width", Arg.Unit (fun () -> default_width := Complex_Mass), - "use complex mass scheme"] + "use complex mass scheme"; + "running_width", Arg.Unit (fun () -> default_width := Running), + "use running width"] type matter_field = L of int | N of int | U of int | D of int | L_K1_L of int | L_K1_R of int | N_K1 of int | L_K2_L of int | L_K2_R of int | N_K2 of int | U_K1_L of int | U_K2_L of int | D_K1_L of int | D_K2_L of int | U_K1_R of int | U_K2_R of int | D_K1_R of int | D_K2_R of int type gauge_boson = Ga | Wp | Wm | Z | Gl | Gl_K1 | Gl_K2 | B1 | B2 | Z1 | Z2 | Wp1 | Wm1 | Wp2 | Wm2 type other = Phip | Phim | Phi0 | H | H1up | H1um | H1dp | H1dm | H2up |H2um | H2dp |H2dm | Grav type flavor = M of matter_field | G of gauge_boson | O of other let matter_field f = M f let gauge_boson f = G f let other f = O f type field = | Matter of matter_field | Gauge of gauge_boson | Other of other let field = function | M f -> Matter f | G f -> Gauge f | O f -> Other f type gauge = unit let gauge_symbol () = failwith "Modellib_BSM.UED.gauge_symbol: internal error" let family n = List.map matter_field [ L n; N n; U n; D n; L_K1_L n; L_K1_R n; L_K2_L n; L_K2_R n; N_K1 n; N_K2 n; U_K1_L n; U_K2_L n; D_K1_L n; D_K2_L n; U_K1_R n; U_K2_R n; D_K1_R n; D_K2_R n] (* We don't introduce a special index for the higher excitations but make them parts of the particles' names. *) let external_flavors () = [ "1st Generation", ThoList.flatmap family [1; -1]; "2nd Generation", ThoList.flatmap family [2; -2]; "3rd Generation", ThoList.flatmap family [3; -3]; "Gauge Bosons", List.map gauge_boson [Ga; Z; Wp; Wm; Gl; Gl_K1; Gl_K2; B1; B2; Z1; Z2; Wp1 ; Wm1; Wp2; Wm2]; "Higgs", List.map other [H; H1up; H1um; H1dp; H1dm; H2up; H2um; H2dp; H2dm]; "Graviton", List.map other [Grav]; "Goldstone Bosons", List.map other [Phip; Phim; Phi0] ] let flavors () = ThoList.flatmap snd (external_flavors ()) let spinor n = if n >= 0 then Spinor else ConjSpinor let lorentz = function | M f -> begin match f with | L n -> spinor n | N n -> spinor n | U n -> spinor n | D n -> spinor n | L_K1_L n -> spinor n | L_K1_R n -> spinor n | L_K2_L n -> spinor n | L_K2_R n -> spinor n | N_K1 n -> spinor n | N_K2 n -> spinor n | U_K1_L n -> spinor n | U_K1_R n -> spinor n | U_K2_L n -> spinor n | U_K2_R n -> spinor n | D_K1_L n -> spinor n | D_K1_R n -> spinor n | D_K2_L n -> spinor n | D_K2_R n -> spinor n end | G f -> begin match f with | Ga | Gl -> Vector | Wp | Wm | Z | Gl_K1 | Gl_K2 | B1 | B2 | Z1 | Z2 | Wp1 | Wm1 | Wp2 | Wm2 -> Massive_Vector end | O f -> begin match f with | Grav -> Tensor_2 | _ -> Scalar end let color = function | M (U n) -> Color.SUN (if n > 0 then 3 else -3) | M (D n) -> Color.SUN (if n > 0 then 3 else -3) | M (U_K1_L n) -> Color.SUN (if n > 0 then 3 else -3) | M (D_K1_L n) -> Color.SUN (if n > 0 then 3 else -3) | M (U_K1_R n) -> Color.SUN (if n > 0 then 3 else -3) | M (D_K1_R n) -> Color.SUN (if n > 0 then 3 else -3) | M (U_K2_L n) -> Color.SUN (if n > 0 then 3 else -3) | M (D_K2_L n) -> Color.SUN (if n > 0 then 3 else -3) | M (U_K2_R n) -> Color.SUN (if n > 0 then 3 else -3) | M (D_K2_R n) -> Color.SUN (if n > 0 then 3 else -3) | G Gl | G Gl_K1 | G Gl_K2 -> Color.AdjSUN 3 | _ -> Color.Singlet let nc () = 3 let prop_spinor n = if n >= 0 then Prop_Spinor else Prop_ConjSpinor let propagator = function | M f -> begin match f with | L n -> prop_spinor n | N n -> prop_spinor n | U n -> prop_spinor n | D n -> prop_spinor n | L_K1_L n -> prop_spinor n | L_K1_R n -> prop_spinor n | L_K2_L n -> prop_spinor n | L_K2_R n -> prop_spinor n | N_K1 n -> prop_spinor n | N_K2 n -> prop_spinor n | U_K1_L n -> prop_spinor n | U_K1_R n -> prop_spinor n | U_K2_L n -> prop_spinor n | U_K2_R n -> prop_spinor n | D_K1_L n -> prop_spinor n | D_K1_R n -> prop_spinor n | D_K2_L n -> prop_spinor n | D_K2_R n -> prop_spinor n end | G f -> begin match f with | Ga | Gl -> Prop_Feynman | Wp | Wm | Z | Gl_K1 | Gl_K2 | B1 | B2 | Z1 | Z2 | Wp1 | Wm1 | Wp2 | Wm2 -> Prop_Unitarity end | O f -> begin match f with | Phip | Phim | Phi0 -> Only_Insertion | H | H1up | H1um | H1dp | H1dm | H2up | H2um | H2dp | H2dm -> Prop_Scalar | Grav -> Prop_Tensor_2 end (* Optionally, ask for the fudge factor treatment for the widths of charged particles. Currently, this only applies to $W^\pm$ and top. *) let width f = if !use_fudged_width then match f with | G Wp | G Wm | M (U 3) | M (U (-3)) | O Grav -> Fudged | _ -> !default_width else !default_width let goldstone = function | G f -> begin match f with | Wp -> Some (O Phip, Coupling.Integer 1) | Wm -> Some (O Phim, Coupling.Integer 1) | Z -> Some (O Phi0, Coupling.Integer 1) | _ -> None end | _ -> None let conjugate = function | M f -> M (begin match f with | L n -> L (-n) | N n -> N (-n) | U n -> U (-n) | D n -> D (-n) | L_K1_L n -> L_K1_L (-n) | L_K1_R n -> L_K1_R (-n) | L_K2_L n -> L_K2_L (-n) | L_K2_R n -> L_K2_R (-n) | N_K1 n -> N_K1 (-n) | N_K2 n -> N_K2 (-n) | U_K1_L n -> U_K1_L (-n) | U_K1_R n -> U_K1_R (-n) | U_K2_L n -> U_K2_L (-n) | U_K2_R n -> U_K2_R (-n) | D_K1_L n -> D_K1_L (-n) | D_K1_R n -> D_K1_R (-n) | D_K2_L n -> D_K2_L (-n) | D_K2_R n -> D_K2_R (-n) end) | G f -> G (begin match f with | Gl -> Gl | Ga -> Ga | Z -> Z | Wp -> Wm | Wm -> Wp | Gl_K1 -> Gl_K1 | Gl_K2 -> Gl_K2 | B1 -> B1 | B2 -> B2 | Z1 -> Z1 | Z2 -> Z2 | Wp1 -> Wm1 | Wm1 -> Wp1 | Wp2 -> Wm2 | Wm2 -> Wp2 end) | O f -> O (begin match f with | Phip -> Phim | Phim -> Phip | Phi0 -> Phi0 | H -> H | H1up -> H1um | H1um -> H1up | H1dp -> H1dm | H1dm -> H1dp | H2up -> H2um | H2um -> H2up | H2dp -> H2dm | H2dm -> H2dp | Grav -> Grav end) let fermion = function | M f -> begin match f with | L n -> if n > 0 then 1 else -1 | N n -> if n > 0 then 1 else -1 | U n -> if n > 0 then 1 else -1 | D n -> if n > 0 then 1 else -1 | L_K1_L n -> if n > 0 then 1 else -1 | L_K2_L n -> if n > 0 then 1 else -1 | L_K1_R n -> if n > 0 then 1 else -1 | L_K2_R n -> if n > 0 then 1 else -1 | U_K1_L n -> if n > 0 then 1 else -1 | U_K2_L n -> if n > 0 then 1 else -1 | U_K1_R n -> if n > 0 then 1 else -1 | U_K2_R n -> if n > 0 then 1 else -1 | D_K1_L n -> if n > 0 then 1 else -1 | D_K2_L n -> if n > 0 then 1 else -1 | D_K1_R n -> if n > 0 then 1 else -1 | D_K2_R n -> if n > 0 then 1 else -1 | N_K1 n -> if n > 0 then 1 else -1 | N_K2 n -> if n > 0 then 1 else -1 end | G f -> begin match f with | Gl | Ga | Z | Wp | Wm | Gl_K1 | Gl_K2 | B1 | B2 | Z1 | Z2 | Wp1 | Wm1 | Wp2 | Wm2 -> 0 end | O _ -> 0 module Ch = Charges.QQ let ( // ) = Algebra.Small_Rational.make let generation' = function | 1 -> [ 1//1; 0//1; 0//1] | 2 -> [ 0//1; 1//1; 0//1] | 3 -> [ 0//1; 0//1; 1//1] | -1 -> [-1//1; 0//1; 0//1] | -2 -> [ 0//1; -1//1; 0//1] | -3 -> [ 0//1; 0//1; -1//1] | n -> invalid_arg ("SM.generation': " ^ string_of_int n) let generation f = match f with | M (L n | N n | U n | D n | L_K1_L n | L_K2_L n | L_K1_R n | L_K2_R n | N_K1 n | N_K2 n | U_K1_L n | U_K2_L n | U_K1_R n | U_K2_R n | D_K1_L n | D_K2_L n | D_K1_R n | D_K2_R n ) -> generation' n | G _ | O _ -> [0//1; 0//1; 0//1] let charge = function | M f -> begin match f with | L n | L_K1_L n | L_K2_L n | L_K1_R n | L_K2_R n -> if n > 0 then -1//1 else 1//1 | N n | N_K1 n | N_K2 n -> 0//1 | U n | U_K1_L n | U_K2_L n | U_K1_R n | U_K2_R n -> if n > 0 then 2//3 else -2//3 | D n | D_K1_L n | D_K2_L n | D_K1_R n | D_K2_R n -> if n > 0 then -1//3 else 1//3 end | G f -> begin match f with | Gl | Gl_K1 | Gl_K2 | Ga | Z | B1 | B2 | Z1 | Z2 -> 0//1 | Wp | Wp1 | Wp2 -> 1//1 | Wm | Wm1 | Wm2 -> -1//1 end | O f -> begin match f with | H | Phi0 | Grav -> 0//1 | H1up | H1dp | H2up | H2dp | Phip -> 1//1 | H1um | H1dm | H2um | H2dm | Phim -> -1//1 end let lepton = function | M f -> begin match f with | L n | N n | L_K1_L n | L_K1_R n | L_K2_L n | L_K2_R n | N_K1 n | N_K2 n -> if n > 0 then 1//1 else -1//1 | U _ | D _ | _ -> 0//1 end | G _ | O _ -> 0//1 let baryon = function | M f -> begin match f with | U n | D n | U_K1_L n | U_K1_R n | U_K2_L n | U_K2_R n | D_K1_L n | D_K1_R n | D_K2_L n | D_K2_R n -> if n > 0 then 1//1 else -1//1 | L _ | N _ | _ -> 0//1 end | G _ | O _ -> 0//1 let charges f = [ charge f; lepton f; baryon f] @ generation f type constant = | Unit | Pi | Alpha_QED | Sin2thw | Sinthw | Costhw | E | G_weak | Vev | Q_lepton | Q_up | Q_down | G_CC | G_CCQ of int*int | G_NC_neutrino | G_NC_lepton | G_NC_up | G_NC_down | I_Q_W | I_G_ZWW | I_Q_W_K | I_G_ZWW_K1 | I_G_ZWW_K2 | I_G_ZWW_K3 | G_WWWW | G_ZZWW | G_AZWW | G_AAWW | G_HWW | G_HHWW | G_HZZ | G_HHZZ | G_Htt | G_Hbb | G_Hcc | G_Htautau | G_H3 | G_H4 | G_HGaZ | G_HGaGa | G_Hgg | Gs | I_Gs | I_GsRt2 | G2 | G22 | G_Grav | Mass of flavor | Width of flavor (* Two integer counters for the QCD and EW order of the couplings. *) type orders = int * int let orders = function | _ -> (0,0) let input_parameters = [] let derived_parameters = [] let g_over_2_costh = Quot (Neg (Atom G_weak), Prod [Integer 2; Atom Costhw]) let nc_coupling c t3 q = (Real_Array c, [Prod [g_over_2_costh; Diff (t3, Prod [Integer 2; q; Atom Sin2thw])]; Prod [g_over_2_costh; t3]]) let half = Quot (Integer 1, Integer 2) let derived_parameter_arrays = [ nc_coupling G_NC_neutrino half (Integer 0); nc_coupling G_NC_lepton (Neg half) (Integer (-1)); nc_coupling G_NC_up half (Quot (Integer 2, Integer 3)); nc_coupling G_NC_down (Neg half) (Quot (Integer (-1), Integer 3)) ] let parameters () = { input = input_parameters; derived = derived_parameters; derived_arrays = derived_parameter_arrays } module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) let mgm ((m1, g, m2), fbf, c) = ((M m1, G g, M m2), fbf, c) let mom ((m1, o, m2), fbf, c) = ((M m1, O o, M m2), fbf, c) let electromagnetic_currents n = List.map mgm [ ((L (-n), Ga, L n), FBF (1, Psibar, V, Psi), Q_lepton); ((U (-n), Ga, U n), FBF (1, Psibar, V, Psi), Q_up); ((D (-n), Ga, D n), FBF (1, Psibar, V, Psi), Q_down) ] let neutral_currents n = List.map mgm [ ((L (-n), Z, L n), FBF (1, Psibar, VA, Psi), G_NC_lepton); ((N (-n), Z, N n), FBF (1, Psibar, VA, Psi), G_NC_neutrino); ((U (-n), Z, U n), FBF (1, Psibar, VA, Psi), G_NC_up); ((D (-n), Z, D n), FBF (1, Psibar, VA, Psi), G_NC_down) ] let charged_currents n = List.map mgm [ ((L (-n), Wm, N n), FBF (1, Psibar, VL, Psi), G_CC); ((N (-n), Wp, L n), FBF (1, Psibar, VL, Psi), G_CC); ((D (-n), Wm, U n), FBF (1, Psibar, VL, Psi), G_CC); ((U (-n), Wp, D n), FBF (1, Psibar, VL, Psi), G_CC) ] let color_currents n = List.map mgm [ ((U (-n), Gl, U n), FBF ((-1), Psibar, V, Psi), Gs); ((D (-n), Gl, D n), FBF ((-1), Psibar, V, Psi), Gs) ] let gravity_currents n = List.map mom [ ((L (-n), Grav, L n), Graviton_Spinor_Spinor 1, G_Grav); ((N (-n), Grav, N n), Graviton_Spinor_Spinor 1, G_Grav); ((U (-n), Grav, U n), Graviton_Spinor_Spinor 1, G_Grav); ((D (-n), Grav, D n), Graviton_Spinor_Spinor 1, G_Grav) ] let yukawa = List.map mom [ ((U (-3), H, U 3), FBF (1, Psibar, S, Psi), G_Htt); ((D (-3), H, D 3), FBF (1, Psibar, S, Psi), G_Hbb); ((U (-2), H, U 2), FBF (1, Psibar, S, Psi), G_Hcc); ((L (-3), H, L 3), FBF (1, Psibar, S, Psi), G_Htautau) ] let tgc ((g1, g2, g3), t, c) = ((G g1, G g2, G g3), t, c) (* Gluons should be included in just that way. *) let standard_triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Gauge_Gauge_Gauge 1, I_Q_W); ((Ga, Wm1, Wp1), Gauge_Gauge_Gauge 1, I_Q_W_K); ((Z, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW); ((Z, Wm1, Wp1), Gauge_Gauge_Gauge 1, I_G_ZWW_K1); ((Z1, Wm, Wp1), Gauge_Gauge_Gauge 1, I_G_ZWW_K2); ((Z1, Wm1, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW_K2); ((Z2, Wm1, Wp2), Gauge_Gauge_Gauge 1, I_G_ZWW_K3); ((Gl, Gl, Gl), Gauge_Gauge_Gauge 1, I_Gs); ((Gl, Gl_K2, Gl_K2), Gauge_Gauge_Gauge (-1), I_Gs); ((Gl, Gl_K1, Gl_K1), Gauge_Gauge_Gauge 1, I_Gs); ((Gl_K2, Gl_K1, Gl_K1), Gauge_Gauge_Gauge 1, I_GsRt2)] let triple_gauge = standard_triple_gauge let qgc ((g1, g2, g3, g4), t, c) = ((G g1, G g2, G g3, G g4), t, c) let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] let standard_quartic_gauge = List.map qgc [ (Wm, Wp, Wm, Wp), gauge4, G_WWWW; (Wm, Z, Wp, Z), minus_gauge4, G_ZZWW; (Wm, Z, Wp, Ga), minus_gauge4, G_AZWW; (Wm, Ga, Wp, Ga), minus_gauge4, G_AAWW; ((Gl, Gl, Gl, Gl), gauge4, G2); ((Gl, Gl, Gl_K1, Gl_K1), gauge4, G2); ((Gl, Gl, Gl_K2, Gl_K2), gauge4, G2); ((Gl_K1, Gl_K1, Gl_K2, Gl_K2), gauge4, G2); ((Gl_K2, Gl_K2, Gl_K2, Gl_K2), gauge4, G22)] let quartic_gauge = standard_quartic_gauge let gravity_gauge = [ (O Grav, G Z, G Z), Graviton_Vector_Vector 1, G_Grav; (O Grav, G Wp, G Wm), Graviton_Vector_Vector 1, G_Grav; (O Grav, G Ga, G Ga), Graviton_Vector_Vector 1, G_Grav; (O Grav, G Gl, G Gl), Graviton_Vector_Vector 1, G_Grav ] let standard_gauge_higgs = [ ((O H, G Wp, G Wm), Scalar_Vector_Vector 1, G_HWW); ((O H, G Z, G Z), Scalar_Vector_Vector 1, G_HZZ) ] let standard_gauge_higgs4 = [ (O H, O H, G Wp, G Wm), Scalar2_Vector2 1, G_HHWW; (O H, O H, G Z, G Z), Scalar2_Vector2 1, G_HHZZ ] let standard_higgs = [ (O H, O H, O H), Scalar_Scalar_Scalar 1, G_H3 ] let standard_higgs4 = [ (O H, O H, O H, O H), Scalar4 1, G_H4 ] let gravity_higgs = [ (O Grav, O H, O H), Graviton_Scalar_Scalar 1, G_Grav] let anomalous_gauge_higgs = [] let anomalous_gauge_higgs4 = [] let anomalous_higgs = [] let anomaly_higgs = [ (O H, G Ga, G Ga), Dim5_Scalar_Gauge2 1, G_HGaGa; (O H, G Ga, G Z), Dim5_Scalar_Gauge2 1, G_HGaZ; (O H, G Gl, G Gl), Dim5_Scalar_Gauge2 1, G_Hgg ] let anomalous_higgs4 = [] let gauge_higgs = standard_gauge_higgs let gauge_higgs4 = standard_gauge_higgs4 let higgs = standard_higgs @ gravity_higgs let higgs4 = standard_higgs4 let goldstone_vertices = [ ((O Phi0, G Wm, G Wp), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phip, G Ga, G Wm), Scalar_Vector_Vector 1, I_Q_W); ((O Phip, G Z, G Wm), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phim, G Wp, G Ga), Scalar_Vector_Vector 1, I_Q_W); ((O Phim, G Wp, G Z), Scalar_Vector_Vector 1, I_G_ZWW) ] let vertices3 = (ThoList.flatmap electromagnetic_currents [1;2;3] @ ThoList.flatmap neutral_currents [1;2;3] @ ThoList.flatmap charged_currents [1;2;3] @ ThoList.flatmap color_currents [1;2;3] @ ThoList.flatmap gravity_currents [1;2;3] @ yukawa @ triple_gauge @ gravity_gauge @ gauge_higgs @ higgs @ anomaly_higgs @ goldstone_vertices) let vertices4 = quartic_gauge @ gauge_higgs4 @ higgs4 let vertices () = (vertices3, vertices4, []) (* For efficiency, make sure that [F.of_vertices vertices] is evaluated only once. *) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 let flavor_of_string = function | "e-" -> M (L 1) | "e+" -> M (L (-1)) | "mu-" -> M (L 2) | "mu+" -> M (L (-2)) | "tau-" -> M (L 3) | "tau+" -> M (L (-3)) | "nue" -> M (N 1) | "nuebar" -> M (N (-1)) | "numu" -> M (N 2) | "numubar" -> M (N (-2)) | "nutau" -> M (N 3) | "nutaubar" -> M (N (-3)) | "u" -> M (U 1) | "ubar" -> M (U (-1)) | "c" -> M (U 2) | "cbar" -> M (U (-2)) | "t" -> M (U 3) | "tbar" -> M (U (-3)) | "d" -> M (D 1) | "dbar" -> M (D (-1)) | "s" -> M (D 2) | "sbar" -> M (D (-2)) | "b" -> M (D 3) | "bbar" -> M (D (-3)) | "uk1l" -> M (U_K1_L 1) | "uk1lbar" -> M (U_K1_L (-1)) | "ck1l" -> M (U_K1_L 2) | "ck1lbar" -> M (U_K1_L (-2)) | "tk1l" -> M (U_K1_L 3) | "tk1lbar" -> M (U_K1_L (-3)) | "dk1l" -> M (D_K1_L 1) | "dk1lbar" -> M (D_K1_L (-1)) | "sk1l" -> M (D_K1_L 2) | "sk1lbar" -> M (D_K1_L (-2)) | "bk1l" -> M (D_K1_L 3) | "bk1lbar" -> M (D_K1_L (-3)) | "uk1r" -> M (U_K1_R 1) | "uk1rbar" -> M (U_K1_R (-1)) | "ck1r" -> M (U_K1_R 2) | "ck1rbar" -> M (U_K1_R (-2)) | "tk1r" -> M (U_K1_R 3) | "tk1rbar" -> M (U_K1_R (-3)) | "dk1r" -> M (D_K1_R 1) | "dk1rbar" -> M (D_K1_R (-1)) | "sk1r" -> M (D_K1_R 2) | "sk1rbar" -> M (D_K1_R (-2)) | "bk1r" -> M (D_K1_R 3) | "bk1rbar" -> M (D_K1_R (-3)) | "uk2l" -> M (U_K2_L 1) | "uk2lbar" -> M (U_K2_L (-1)) | "ck2l" -> M (U_K2_L 2) | "ck2lbar" -> M (U_K2_L (-2)) | "tk2l" -> M (U_K2_L 3) | "tk2lbar" -> M (U_K2_L (-3)) | "dk2l" -> M (D_K2_L 1) | "dk2lbar" -> M (D_K2_L (-1)) | "sk2l" -> M (D_K2_L 2) | "sk2lbar" -> M (D_K2_L (-2)) | "bk2l" -> M (D_K2_L 3) | "bk2lbar" -> M (D_K2_L (-3)) | "uk2r" -> M (U_K2_R 1) | "uk2rbar" -> M (U_K2_R (-1)) | "ck2r" -> M (U_K2_R 2) | "ck2rbar" -> M (U_K2_R (-2)) | "tk2r" -> M (U_K2_R 3) | "tk2rbar" -> M (U_K2_R (-3)) | "dk2r" -> M (D_K2_R 1) | "dk2rbar" -> M (D_K2_R (-1)) | "sk2r" -> M (D_K2_R 2) | "sk2rbar" -> M (D_K2_R (-2)) | "bk2r" -> M (D_K2_R 3) | "bk2rbar" -> M (D_K2_R (-3)) | "g" | "gl" -> G Gl | "g_k1" | "gl_k1" -> G Gl_K1 | "g_k2" | "gl_k2" -> G Gl_K2 | "b1" -> G B1 | "b2" -> G B2 | "z1" -> G Z1 | "z2" -> G Z2 | "W1+" -> G Wp1 | "W1-" -> G Wm1 | "W2+" -> G Wp2 | "W2-" -> G Wm2 | "A" -> G Ga | "Z" | "Z0" -> G Z | "W+" -> G Wp | "W-" -> G Wm | "H" -> O H | "H1u+" -> O H1up | "H1u-" -> O H1um | "H1d+" -> O H1dp | "H1d-" -> O H1dm | "H2u+" -> O H2up | "H2u-" -> O H2um | "H2d+" -> O H2dp | "H2d-" -> O H2dm | "GG" -> O Grav | "ek1l-" -> M (L_K1_L 1) | "ek1l+" -> M (L_K1_L (-1)) | "muk1l-" -> M (L_K1_L 2) | "mu1l+" -> M (L_K1_L (-2)) | "tauk1l-" -> M (L_K1_L 3) | "tauk1l+" -> M (L_K1_L (-3)) | "ek1r-" -> M (L_K1_R 1) | "ek1r+" -> M (L_K1_R (-1)) | "muk1r-" -> M (L_K1_R 2) | "mu1r+" -> M (L_K1_R (-2)) | "tau1r-" -> M (L_K1_R 3) | "tauk1r+" -> M (L_K1_R (-3)) | "ek2l-" -> M (L_K2_L 1) | "ek2l+" -> M (L_K2_L (-1)) | "muk2l-" -> M (L_K2_L 2) | "mu2l+" -> M (L_K2_L (-2)) | "tauk2l-" -> M (L_K2_L 3) | "tauk2l+" -> M (L_K2_L (-3)) | "ek2r-" -> M (L_K2_R 1) | "ek2r+" -> M (L_K2_R (-1)) | "muk2r-" -> M (L_K2_R 2) | "mu2r+" -> M (L_K2_R (-2)) | "tau2r-" -> M (L_K2_R 3) | "tauk2r+" -> M (L_K2_R (-3)) | "nuek1" -> M (N_K1 1) | "nuek1bar" -> M (N_K1 (-1)) | "numuk1" -> M (N_K1 2) | "numuk1bar" -> M (N_K1 (-2)) | "nutauk1" -> M (N_K1 3) | "nutauk1bar" -> M (N_K1 (-3)) | "nuek2" -> M (N_K2 1) | "nuek2bar" -> M (N_K2 (-1)) | "numuk2" -> M (N_K2 2) | "numuk2bar" -> M (N_K2 (-2)) | "nutauk2" -> M (N_K2 3) | "nutauk2bar" -> M (N_K2 (-3)) | _ -> invalid_arg "Modellib_BSM.UED.flavor_of_string" let flavor_to_string = function | M f -> begin match f with | L 1 -> "e-" | L (-1) -> "e+" | L 2 -> "mu-" | L (-2) -> "mu+" | L 3 -> "tau-" | L (-3) -> "tau+" | L _ -> invalid_arg "Modellib_BSM.UED.flavor_to_string: invalid lepton" | N 1 -> "nue" | N (-1) -> "nuebar" | N 2 -> "numu" | N (-2) -> "numubar" | N 3 -> "nutau" | N (-3) -> "nutaubar" | N _ -> invalid_arg "Modellib_BSM.UED.flavor_to_string: invalid neutrino" | U 1 -> "u" | U (-1) -> "ubar" | U 2 -> "c" | U (-2) -> "cbar" | U 3 -> "t" | U (-3) -> "tbar" | U _ -> invalid_arg "Modellib_BSM.UED.flavor_to_string: invalid up type quark" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | D _ -> invalid_arg "Modellib_BSM.UED.flavor_to_string: invalid down type quark" | U_K1_L 1 -> "uk1l" | U_K1_L (-1) -> "uk1lbar" | U_K1_L 2 -> "ck1l" | U_K1_L (-2) -> "ck1lbar" | U_K1_L 3 -> "tk1l" | U_K1_L (-3) -> "tk1lbar" | U_K1_L _ -> invalid_arg "Modellib_BSM.UED.flavor_to_string: invalid up type quark" | D_K1_L 1 -> "dk1l" | D_K1_L (-1) -> "dk1lbar" | D_K1_L 2 -> "sk1l" | D_K1_L (-2) -> "sk1lbar" | D_K1_L 3 -> "bk1l" | D_K1_L (-3) -> "bk1lbar" | D_K1_L _ -> invalid_arg "Modellib_BSM.UED.flavor_to_string: invalid down type quark" | U_K1_R 1 -> "uk1r" | U_K1_R (-1) -> "uk1rbar" | U_K1_R 2 -> "ck1r" | U_K1_R (-2) -> "ck1rbar" | U_K1_R 3 -> "tk1r" | U_K1_R (-3) -> "tk1rbar" | U_K1_R _ -> invalid_arg "Modellib_BSM.UED.flavor_to_string: invalid up type quark" | D_K1_R 1 -> "dk1r" | D_K1_R (-1) -> "dk1rbar" | D_K1_R 2 -> "sk1r" | D_K1_R (-2) -> "sk1rbar" | D_K1_R 3 -> "bk1r" | D_K1_R (-3) -> "bk1rbar" | D_K1_R _ -> invalid_arg "Modellib_BSM.UED.flavor_to_string: invalid down type quark" | U_K2_L 1 -> "uk2l" | U_K2_L (-1) -> "uk2lbar" | U_K2_L 2 -> "ck2l" | U_K2_L (-2) -> "ck2lbar" | U_K2_L 3 -> "tk2l" | U_K2_L (-3) -> "tk2lbar" | U_K2_L _ -> invalid_arg "Modellib_BSM.UED.flavor_to_string: invalid up type quark" | D_K2_L 1 -> "dk2l" | D_K2_L (-1) -> "dk2lbar" | D_K2_L 2 -> "sk2l" | D_K2_L (-2) -> "sk2lbar" | D_K2_L 3 -> "bk2l" | D_K2_L (-3) -> "bk2lbar" | D_K2_L _ -> invalid_arg "Modellib_BSM.UED.flavor_to_string: invalid down type quark" | U_K2_R 1 -> "uk2r" | U_K2_R (-1) -> "uk2rbar" | U_K2_R 2 -> "ck2r" | U_K2_R (-2) -> "ck2rbar" | U_K2_R 3 -> "tk2r" | U_K2_R (-3) -> "tk2rbar" | U_K2_R _ -> invalid_arg "Modellib_BSM.UED.flavor_to_string: invalid up type quark" | D_K2_R 1 -> "dk2r" | D_K2_R (-1) -> "dk2rbar" | D_K2_R 2 -> "sk2r" | D_K2_R (-2) -> "sk2rbar" | D_K2_R 3 -> "bk2r" | D_K2_R (-3) -> "bk2rbar" | D_K2_R _ -> invalid_arg "Modellib_BSM.UED.flavor_to_string: invalid down type quark" | L_K1_L 1 -> "ek1l-" | L_K1_L (-1) -> "ek1l+" | L_K1_L 2 -> "muk1l-" | L_K1_L (-2) -> "muk1l+" | L_K1_L 3 -> "tauk1l-" | L_K1_L (-3) -> "tauk1l+" | L_K1_L _ -> invalid_arg "Modellib_BSM.UED.flavor_to_string: invalid lepton" | L_K1_R 1 -> "ek1r-" | L_K1_R (-1) -> "ek1r+" | L_K1_R 2 -> "muk1r-" | L_K1_R (-2) -> "muk1r+" | L_K1_R 3 -> "tauk1r-" | L_K1_R (-3) -> "tauk1r+" | L_K1_R _ -> invalid_arg "Modellib_BSM.UED.flavor_to_string: invalid lepton" | L_K2_L 1 -> "ek2l-" | L_K2_L (-1) -> "ek2l+" | L_K2_L 2 -> "muk2l-" | L_K2_L (-2) -> "muk2l+" | L_K2_L 3 -> "tauk2l-" | L_K2_L (-3) -> "tauk2l+" | L_K2_L _ -> invalid_arg "Modellib_BSM.UED.flavor_to_string: invalid lepton" | L_K2_R 1 -> "ek2r-" | L_K2_R (-1) -> "ek2r+" | L_K2_R 2 -> "muk2r-" | L_K2_R (-2) -> "muk2r+" | L_K2_R 3 -> "tauk2r-" | L_K2_R (-3) -> "tauk2r+" | L_K2_R _ -> invalid_arg "Modellib_BSM.UED.flavor_to_string: invalid lepton" | N_K1 1 -> "nuek1" | N_K1 (-1) -> "nuek1bar" | N_K1 2 -> "numuk1" | N_K1 (-2) -> "numuk1bar" | N_K1 3 -> "nutauk1" | N_K1 (-3) -> "nutauk1bar" | N_K1 _ -> invalid_arg "Modellib_BSM.UED.flavor_to_string: invalid neutrino" | N_K2 1 -> "nuek2" | N_K2 (-1) -> "nuek2bar" | N_K2 2 -> "numuk2" | N_K2 (-2) -> "numuk2bar" | N_K2 3 -> "nutauk2" | N_K2 (-3) -> "nutauk2bar" | N_K2 _ -> invalid_arg "Modellib_BSM.UED.flavor_to_string: invalid neutrino" end | G f -> begin match f with | Gl -> "g" | Ga -> "A" | Z -> "Z" | Wp -> "W+" | Wm -> "W-" | Gl_K1 -> "gk1" | Gl_K2 -> "gk2" | B1 -> "b1" | B2 -> "b2" | Z1 -> "z1" | Z2 -> "z2" | Wp1 -> "W1+" | Wm1 -> "W1-" | Wp2 -> "W2+" | Wm2 -> "W2-" end | O f -> begin match f with | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | H -> "H" | H1up -> "H1u+" | H1um -> "H1u-" | H1dp -> "H1d+" | H1dm -> "H1d-" | H2up -> "H2u+" | H2um -> "H2u-" | H2dp -> "H2d+" | H2dm -> "H2d-" | Grav -> "GG" end let flavor_to_TeX = function | M f -> begin match f with | L 1 -> "e^-" | L (-1) -> "e^+" | L 2 -> "\\mu^-" | L (-2) -> "\\mu^+" | L 3 -> "\\tau^-" | L (-3) -> "\\tau^+" | L _ -> invalid_arg "Modellib_BSM.UED.flavor_to_TeX: invalid lepton" | N 1 -> "\\nu_e" | N (-1) -> "\\bar{\\nu}_e" | N 2 -> "\\nu_\\mu" | N (-2) -> "\\bar{\\nu}_\\mu" | N 3 -> "\\nu_\\tau" | N (-3) -> "\\bar{\\nu}_\\tau" | N _ -> invalid_arg "Modellib_BSM.UED.flavor_to_TeX: invalid neutrino" | U 1 -> "u" | U (-1) -> "\\bar{u}" | U 2 -> "c" | U (-2) -> "\\bar{c}" | U 3 -> "t" | U (-3) -> "\\bar{t}" | U _ -> invalid_arg "Modellib_BSM.UED.flavor_to_TeX: invalid up type quark" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | D _ -> invalid_arg "Modellib_BSM.UED.flavor_to_TeX: invalid down type quark" | U_K1_L 1 -> "u^\\prime_L" | U_K1_L (-1) -> "\\bar{u}^\\prime_L" | U_K1_L 2 -> "c^\\prime_L" | U_K1_L (-2) -> "\\bar{c}^\\prime_L" | U_K1_L 3 -> "t^\\prime_L" | U_K1_L (-3) -> "\\bar{t}^\\prime_L" | U_K1_L _ -> invalid_arg "Modellib_BSM.UED.flavor_to_TeX: invalid up type quark" | D_K1_L 1 -> "d^\\prime_L" | D_K1_L (-1) -> "\\bar{d}^\\prime_L" | D_K1_L 2 -> "s^\\prime_L" | D_K1_L (-2) -> "\\bar{s}^\\prime_L" | D_K1_L 3 -> "b^\\prime_L" | D_K1_L (-3) -> "\\bar{b}^\\prime_L" | D_K1_L _ -> invalid_arg "Modellib_BSM.UED.flavor_to_TeX: invalid down type quark" | U_K1_R 1 -> "u^\\prime_R" | U_K1_R (-1) -> "\\bar{u}^\\prime_R" | U_K1_R 2 -> "c^\\prime_R" | U_K1_R (-2) -> "\\bar{c}^\\prime_R" | U_K1_R 3 -> "t^\\prime_R" | U_K1_R (-3) -> "\\bar{t}^\\prime_R" | U_K1_R _ -> invalid_arg "Modellib_BSM.UED.flavor_to_TeX: invalid up type quark" | D_K1_R 1 -> "d^\\prime_R" | D_K1_R (-1) -> "\\bar{d}^\\prime_R" | D_K1_R 2 -> "s^\\prime_R" | D_K1_R (-2) -> "\\bar{s}^\\prime_R" | D_K1_R 3 -> "b^\\prime_R" | D_K1_R (-3) -> "\\bar{b}^\\prime_R" | D_K1_R _ -> invalid_arg "Modellib_BSM.UED.flavor_to_TeX: invalid down type quark" | U_K2_L 1 -> "u^{\\prime\\prime}_L" | U_K2_L (-1) -> "\\bar{u}^{\\prime\\prime}_L" | U_K2_L 2 -> "c^{\\prime\\prime}_L" | U_K2_L (-2) -> "\\bar{c}^{\\prime\\prime}_L" | U_K2_L 3 -> "t^{\\prime\\prime}_L" | U_K2_L (-3) -> "\\bar{t}^{\\prime\\prime}_L" | U_K2_L _ -> invalid_arg "Modellib_BSM.UED.flavor_to_TeX: invalid up type quark" | D_K2_L 1 -> "d^{\\prime\\prime}_L" | D_K2_L (-1) -> "\\bar{d}^{\\prime\\prime}_L" | D_K2_L 2 -> "s^{\\prime\\prime}_L" | D_K2_L (-2) -> "\\bar{s}^{\\prime\\prime}_L" | D_K2_L 3 -> "b^{\\prime\\prime}_L" | D_K2_L (-3) -> "\\bar{b}^{\\prime\\prime}_L" | D_K2_L _ -> invalid_arg "Modellib_BSM.UED.flavor_to_TeX: invalid down type quark" | U_K2_R 1 -> "u^{\\prime\\prime}_R" | U_K2_R (-1) -> "\\bar{u}^{\\prime\\prime}_R" | U_K2_R 2 -> "c^{\\prime\\prime}_R" | U_K2_R (-2) -> "\\bar{c}^{\\prime\\prime}_R" | U_K2_R 3 -> "t^{\\prime\\prime}_R" | U_K2_R (-3) -> "\\bar{t}^{\\prime\\prime}_R" | U_K2_R _ -> invalid_arg "Modellib_BSM.UED.flavor_to_TeX: invalid up type quark" | D_K2_R 1 -> "d^\\prime_R" | D_K2_R (-1) -> "\\bar{d}^{\\prime\\prime}_R" | D_K2_R 2 -> "s^\\prime_R" | D_K2_R (-2) -> "\\bar{s}^{\\prime\\prime}_R" | D_K2_R 3 -> "b^\\prime_R" | D_K2_R (-3) -> "\\bar{b}^{\\prime\\prime}_R" | D_K2_R _ -> invalid_arg "Modellib_BSM.UED.flavor_to_TeX: invalid down type quark" | L_K1_L 1 -> "e_L^{\\prime,,-}" | L_K1_L (-1) -> "\\bar{e}_L^{\\prime,,+}" | L_K1_L 2 -> "\\mu_L^{\\prime,,-}" | L_K1_L (-2) -> "\\bar{\\mu}_L^{{\\prime,,+}" | L_K1_L 3 -> "\\tau_L^{\\prime,,-}" | L_K1_L (-3) -> "\\bar{\\tau}_L^{\\prime,,+}" | L_K1_L _ -> invalid_arg "Modellib_BSM.UED.flavor_to_TeX: invalid lepton" | L_K1_R 1 -> "e_R^{\\prime,,-}" | L_K1_R (-1) -> "\\bar{e}_R^{\\prime,,+}" | L_K1_R 2 -> "\\mu_R{\\prime,,-}" | L_K1_R (-2) -> "\\bar{\\mu}_R^{\\prime,,+}" | L_K1_R 3 -> "\\tau_R¬{\\prime,,-}" | L_K1_R (-3) -> "\\bar{\\tau}_R¬{\\prime,,+}" | L_K1_R _ -> invalid_arg "Modellib_BSM.UED.flavor_to_TeX: invalid lepton" | L_K2_L 1 -> "e^{\\prime\\prime,,-}_L" | L_K2_L (-1) -> "\\bar{e}_L^{\\prime\\prime,,+}" | L_K2_L 2 -> "\\mu_L^{\\prime\\prime,,-}" | L_K2_L (-2) -> "\\bar{\\mu}_L^{\\prime\\prime,,+}" | L_K2_L 3 -> "\\tau_L^{\\prime\\prime,,-}" | L_K2_L (-3) -> "\\bar{\\tau}_L^{\\prime\\prime,,+}" | L_K2_L _ -> invalid_arg "Modellib_BSM.UED.flavor_to_TeX: invalid lepton" | L_K2_R 1 -> "e_R^{\\prime\\prime,,-}" | L_K2_R (-1) -> "\\bar{e}_R^{\\prime\\prime,,+}" | L_K2_R 2 -> "\\mu_R^{\\prime\\prime,,-}" | L_K2_R (-2) -> "\\bar{\\mu}_R^{\\prime\\prime,,+}" | L_K2_R 3 -> "\\tau_R{\\prime\\prime,,-}" | L_K2_R (-3) -> "\\bar{\\tau}_R^{\\prime\\prime,,+}" | L_K2_R _ -> invalid_arg "Modellib_BSM.UED.flavor_to_TeX: invalid lepton" | N_K1 1 -> "\\nu_e^\\prime" | N_K1 (-1) -> "\\bar{\\nu}_e^\\prime" | N_K1 2 -> "\\nu_\\mu^\\prime" | N_K1 (-2) -> "\\bar{\\nu}_\\mu^\\prime" | N_K1 3 -> "\\nu_\\tau^\\prime" | N_K1 (-3) -> "\\bar{\\nu}_\\tau^\\prime" | N_K1 _ -> invalid_arg "Modellib_BSM.UED.flavor_to_TeX: invalid neutrino" | N_K2 1 -> "\\nu_e^{\\prime\\prime}" | N_K2 (-1) -> "\\bar{\\nu}_e^{\\prime\\prime}" | N_K2 2 -> "\\nu_\\mu^{\\prime\\prime}" | N_K2 (-2) -> "\\bar{\\nu}_\\mu^{\\prime\\prime}" | N_K2 3 -> "\\nu_\\tau^{\\prime\\prime}" | N_K2 (-3) -> "\\bar{\\nu}_\\tau^{\\prime\\prime}" | N_K2 _ -> invalid_arg "Modellib_BSM.UED.flavor_to_TeX: invalid neutrino" end | G f -> begin match f with | Gl -> "g" | Ga -> "\\gamma" | Z -> "Z" | Wp -> "W^+" | Wm -> "W^-" | Gl_K1 -> "g^\\prime" | Gl_K2 -> "g^{\\prime\\prime}" | B1 -> "B^\\prime" | B2 -> "B^{\\prime\\prime}" | Z1 -> "Z^\\prime" | Z2 -> "Z^{\\prime\\prime}" | Wp1 -> "W^{\\prime,,+}" | Wm1 -> "W^{\\prime,,-}" | Wp2 -> "W^{\\prime\\prime,,+}" | Wm2 -> "W^{\\prime\\prime,,-}" end | O f -> begin match f with | Phip -> "\\phi^+" | Phim -> "\\phi^-" | Phi0 -> "\\phi^0" | H -> "H" | H1up -> "H1u+" | H1um -> "H1u-" | H1dp -> "H1d+" | H1dm -> "H1d-" | H2up -> "H2u+" | H2um -> "H2u-" | H2dp -> "H2d+" | H2dm -> "H2d-" | Grav -> "G^\\prime" end let flavor_symbol = function | M f -> begin match f with | L n when n > 0 -> "l" ^ string_of_int n | L n -> "l" ^ string_of_int (abs n) ^ "b" | N n when n > 0 -> "n" ^ string_of_int n | N n -> "n" ^ string_of_int (abs n) ^ "b" | U n when n > 0 -> "u" ^ string_of_int n | U n -> "u" ^ string_of_int (abs n) ^ "b" | D n when n > 0 -> "d" ^ string_of_int n | D n -> "d" ^ string_of_int (abs n) ^ "b" | L_K1_L n when n > 0 -> "lk1l" ^ string_of_int n | L_K1_L n -> "lk1l" ^ string_of_int (abs n) ^ "b" | L_K1_R n when n > 0 -> "lk1r" ^ string_of_int n | L_K1_R n -> "lk1r" ^ string_of_int (abs n) ^ "b" | L_K2_L n when n > 0 -> "lk2l" ^ string_of_int n | L_K2_L n -> "lk2l" ^ string_of_int (abs n) ^ "b" | L_K2_R n when n > 0 -> "lk2r" ^ string_of_int n | L_K2_R n -> "lk2r" ^ string_of_int (abs n) ^ "b" | U_K1_L n when n > 0 -> "uk1l" ^ string_of_int n | U_K1_L n -> "uk1l" ^ string_of_int (abs n) ^ "b" | U_K1_R n when n > 0 -> "uk1r" ^ string_of_int n | U_K1_R n -> "uk1r" ^ string_of_int (abs n) ^ "b" | U_K2_L n when n > 0 -> "uk2l" ^ string_of_int n | U_K2_L n -> "uk2l" ^ string_of_int (abs n) ^ "b" | U_K2_R n when n > 0 -> "uk2r" ^ string_of_int n | U_K2_R n -> "uk2r" ^ string_of_int (abs n) ^ "b" | D_K1_L n when n > 0 -> "dk1l" ^ string_of_int n | D_K1_L n -> "dk1l" ^ string_of_int (abs n) ^ "b" | D_K1_R n when n > 0 -> "dk1r" ^ string_of_int n | D_K1_R n -> "dk1r" ^ string_of_int (abs n) ^ "b" | D_K2_L n when n > 0 -> "dk2l" ^ string_of_int n | D_K2_L n -> "dk2l" ^ string_of_int (abs n) ^ "b" | D_K2_R n when n > 0 -> "dk2r" ^ string_of_int n | D_K2_R n -> "dk2r" ^ string_of_int (abs n) ^ "b" | N_K1 n when n > 0 -> "nk1" ^ string_of_int n | N_K1 n -> "nk1" ^ string_of_int (abs n) ^ "b" | N_K2 n when n > 0 -> "nk2" ^ string_of_int n | N_K2 n -> "nk2" ^ string_of_int (abs n) ^ "b" end | G f -> begin match f with | Gl -> "gl" | Ga -> "a" | Z -> "z" | Wp -> "wp" | Wm -> "wm" | Gl_K1 -> "gk1" | Gl_K2 -> "gk2" | B1 -> "b1" | B2 -> "b2" | Z1 -> "z1" | Z2 -> "z2" | Wp1 -> "wp1" | Wm1 -> "wm1" | Wp2 -> "wp2" | Wm2 -> "wm2" end | O f -> begin match f with | Phip -> "pp" | Phim -> "pm" | Phi0 -> "p0" | H -> "h" | H1up -> "h1up" | H1um -> "h1um" | H1dp -> "h1dp" | H1dm -> "h1dm" | H2up -> "h2up" | H2um -> "h2um" | H2dp -> "h2dp" | H2dm -> "h2dm" | Grav -> "gv" end let pdg = function | M f -> begin match f with | L n when n > 0 -> 9 + 2*n | L n -> - 9 + 2*n | N n when n > 0 -> 10 + 2*n | N n -> - 10 + 2*n | U n when n > 0 -> 2*n | U n -> 2*n | D n when n > 0 -> - 1 + 2*n | D n -> 1 + 2*n | U_K1_L n when n > 0 -> 4000000 + 2*n | U_K1_L n -> - 4000000 + 2*n | D_K1_L n when n > 0 -> 3999999 + 2*n | D_K1_L n -> - 3999999 + 2*n | U_K1_R n when n > 0 -> 5000000 + 2*n | U_K1_R n -> - 5000000 + 2*n | D_K1_R n when n > 0 -> 4999999 + 2*n | D_K1_R n -> - 4999999 + 2*n | U_K2_L n when n > 0 -> 6000000 + 2*n | U_K2_L n -> - 6000000 + 2*n | D_K2_L n when n > 0 -> 5999999 + 2*n | D_K2_L n -> - 5999999 + 2*n | U_K2_R n when n > 7000000 -> 2*n | U_K2_R n -> - 7000000 + 2*n | D_K2_R n when n > 0 -> 6999999 + 2*n | D_K2_R n -> - 6999999 + 2*n | L_K1_L n when n > 0 -> 4000009 + 2*n | L_K1_L n -> - 4000009 + 2*n | L_K1_R n when n > 0 -> 5000009 + 2*n | L_K1_R n -> - 5000009 + 2*n | L_K2_L n when n > 0 -> 6000009 + 2*n | L_K2_L n -> - 6000009 + 2*n | L_K2_R n when n > 0 -> 7000009 + 2*n | L_K2_R n -> - 7000009 + 2*n | N_K1 n when n > 0 -> 4000010 + 2*n | N_K1 n -> - 4000010 + 2*n | N_K2 n when n > 0 -> 6000010 + 2*n | N_K2 n -> - 6000010 + 2*n end | G f -> begin match f with | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) | Gl_K1 -> 4000021 | Gl_K2 -> 6000021 | B1 -> 4000022 | B2 -> 6000022 | Z1 -> 4000023 | Z2 -> 6000024 | Wp1 -> 4000024 | Wm1 -> (-4000024) | Wp2 -> 6000024 | Wm2 -> (-6000024) end | O f -> begin match f with | Phip | Phim -> 27 | Phi0 -> 26 | H -> 25 | H1up -> 4000036 | H1um -> (-4000036) | H1dp -> 4000037 | H1dm -> (-4000037) | H2up -> 6000036 | H2um -> (-6000036) | H2dp -> 6000037 | H2dm -> (-6000037) | Grav -> 39 end let mass_symbol f = "mass(" ^ string_of_int (abs (pdg f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg f)) ^ ")" let constant_symbol = function | Unit -> "unit" | Pi -> "PI" | Alpha_QED -> "alpha" | E -> "e" | G_weak -> "g" | Vev -> "vev" | Sin2thw -> "sin2thw" | Sinthw -> "sinthw" | Costhw -> "costhw" | Q_lepton -> "qlep" | Q_up -> "qup" | Q_down -> "qdwn" | G_NC_lepton -> "gnclep" | G_NC_neutrino -> "gncneu" | G_NC_up -> "gncup" | G_NC_down -> "gncdwn" | G_CC -> "gcc" | G_CCQ (n1,n2) -> "gccq" ^ string_of_int n1 ^ string_of_int n2 | I_Q_W -> "iqw" | I_G_ZWW -> "igzww" | I_Q_W_K -> "iqwk" | I_G_ZWW_K1 -> "igzwwk1" | I_G_ZWW_K2 -> "igzwwk2" | I_G_ZWW_K3 -> "igzwwk3" | G_WWWW -> "gw4" | G_ZZWW -> "gzzww" | G_AZWW -> "gazww" | G_AAWW -> "gaaww" | G_HWW -> "ghww" | G_HZZ -> "ghzz" | G_HHWW -> "ghhww" | G_HHZZ -> "ghhzz" | G_Htt -> "ghtt" | G_Hbb -> "ghbb" | G_Htautau -> "ghtautau" | G_Hcc -> "ghcc" | G_HGaZ -> "ghgaz" | G_HGaGa -> "ghgaga" | G_Hgg -> "ghgg" | G_H3 -> "gh3" | G_H4 -> "gh4" | G2 -> "gs**2" | Gs -> "gs" | I_Gs -> "igs" | I_GsRt2 -> "igs/sqrt(2.0_default)" | G22 -> "gs**2/2.0_default" | G_Grav -> "ggrav" | Mass f -> "mass" ^ flavor_symbol f | Width f -> "width" ^ flavor_symbol f end module GravTest (Flags : BSM_flags) = struct open Coupling let default_width = ref Timelike let use_fudged_width = ref false let options = Options.create [ "constant_width", Arg.Unit (fun () -> default_width := Constant), "use constant width (also in t-channel)"; "fudged_width", Arg.Set use_fudged_width, "use fudge factor for charge particle width"; "custom_width", Arg.String (fun f -> default_width := Custom f), "use custom width"; "cancel_widths", Arg.Unit (fun () -> default_width := Vanishing), "use vanishing width"; "cms_width", Arg.Unit (fun () -> default_width := Complex_Mass), - "use complex mass scheme"] + "use complex mass scheme"; + "running_width", Arg.Unit (fun () -> default_width := Running), + "use running width"] type matter_field = L of int | N of int | U of int | D of int | SL of int type gauge_boson = Ga | Wp | Wm | Z | Gl | Phino type other = Phip | Phim | Phi0 | H | Grino type flavor = M of matter_field | G of gauge_boson | O of other let matter_field f = M f let gauge_boson f = G f let other f = O f type field = | Matter of matter_field | Gauge of gauge_boson | Other of other let field = function | M f -> Matter f | G f -> Gauge f | O f -> Other f type gauge = unit let gauge_symbol () = failwith "Modellib_BSM.SM.gauge_symbol: internal error" let family n = List.map matter_field [ L n; SL n; N n; U n; D n ] let external_flavors () = [ "1st Generation", ThoList.flatmap family [1; -1]; "2nd Generation", ThoList.flatmap family [2; -2]; "3rd Generation", ThoList.flatmap family [3; -3]; "Gauge Bosons", List.map gauge_boson [Ga; Z; Wp; Wm; Gl; Phino]; "Higgs", List.map other [H]; "Gravitino", List.map other [Grino]; "Goldstone Bosons", List.map other [Phip; Phim; Phi0] ] let flavors () = ThoList.flatmap snd (external_flavors ()) let spinor n = if n >= 0 then Spinor else ConjSpinor let lorentz = function | M f -> begin match f with | L n -> spinor n | N n -> spinor n | U n -> spinor n | D n -> spinor n | SL _ -> Scalar end | G f -> begin match f with | Ga | Gl -> Vector | Wp | Wm | Z -> Massive_Vector | Phino -> Majorana end | O f -> begin match f with | Grino -> Vectorspinor | _ -> Scalar end let color = function | M (U n) -> Color.SUN (if n > 0 then 3 else -3) | M (D n) -> Color.SUN (if n > 0 then 3 else -3) | G Gl -> Color.AdjSUN 3 | _ -> Color.Singlet let nc () = 3 let prop_spinor n = if n >= 0 then Prop_Spinor else Prop_ConjSpinor let propagator = function | M f -> begin match f with | L n -> prop_spinor n | N n -> prop_spinor n | U n -> prop_spinor n | D n -> prop_spinor n | SL n -> Prop_Scalar end | G f -> begin match f with | Ga | Gl -> Prop_Feynman | Wp | Wm | Z -> Prop_Unitarity | Phino -> Prop_Majorana end | O f -> begin match f with | Phip | Phim | Phi0 -> Only_Insertion | H -> Prop_Scalar | Grino -> Prop_Vectorspinor end (* Optionally, ask for the fudge factor treatment for the widths of charged particles. Currently, this only applies to $W^\pm$ and top. *) let width f = if !use_fudged_width then match f with | G Wp | G Wm | M (U 3) | M (U (-3)) | O Grino -> Fudged | _ -> !default_width else !default_width let goldstone = function | G f -> begin match f with | Wp -> Some (O Phip, Coupling.Integer 1) | Wm -> Some (O Phim, Coupling.Integer 1) | Z -> Some (O Phi0, Coupling.Integer 1) | _ -> None end | _ -> None let conjugate = function | M f -> M (begin match f with | L n -> L (-n) | N n -> N (-n) | U n -> U (-n) | D n -> D (-n) | SL n -> SL (-n) end) | G f -> G (begin match f with | Gl -> Gl | Ga -> Ga | Z -> Z | Wp -> Wm | Wm -> Wp | Phino -> Phino end) | O f -> O (begin match f with | Phip -> Phim | Phim -> Phip | Phi0 -> Phi0 | H -> H | Grino -> Grino end) let fermion = function | M f -> begin match f with | L n -> if n > 0 then 1 else -1 | N n -> if n > 0 then 1 else -1 | U n -> if n > 0 then 1 else -1 | D n -> if n > 0 then 1 else -1 | SL _ -> 0 end | G f -> begin match f with | Gl | Ga | Z | Wp | Wm -> 0 | Phino -> 2 end | O f -> begin match f with | Grino -> 2 | _ -> 0 end module Ch = Charges.QQ let ( // ) = Algebra.Small_Rational.make let generation' = function | 1 -> [ 1//1; 0//1; 0//1] | 2 -> [ 0//1; 1//1; 0//1] | 3 -> [ 0//1; 0//1; 1//1] | -1 -> [-1//1; 0//1; 0//1] | -2 -> [ 0//1; -1//1; 0//1] | -3 -> [ 0//1; 0//1; -1//1] | n -> invalid_arg ("SM3.generation': " ^ string_of_int n) let generation f = match f with | M (L n | N n | U n | D n | SL n) -> generation' n | G _ | O _ -> [0//1; 0//1; 0//1] let charge = function | M f -> begin match f with | L n -> if n > 0 then -1//1 else 1//1 | SL n -> if n > 0 then -1//1 else 1//1 | N n -> 0//1 | U n -> if n > 0 then 2//3 else -2//3 | D n -> if n > 0 then -1//3 else 1//3 end | G f -> begin match f with | Gl | Ga | Z | Phino -> 0//1 | Wp -> 1//1 | Wm -> -1//1 end | O f -> begin match f with | H | Phi0 | Grino -> 0//1 | Phip -> 1//1 | Phim -> -1//1 end let lepton = function | M f -> begin match f with | L n | N n | SL n -> if n > 0 then 1//1 else -1//1 | U _ | D _ -> 0//1 end | G _ | O _ -> 0//1 let baryon = function | M f -> begin match f with | L _ | N _ | SL _ -> 0//1 | U n | D n -> if n > 0 then 1//1 else -1//1 end | G _ | O _ -> 0//1 let charges f = [ charge f; lepton f; baryon f] @ generation f type constant = | Unit | Pi | Alpha_QED | Sin2thw | Sinthw | Costhw | E | G_weak | Vev | Q_lepton | Q_up | Q_down | G_CC | G_CCQ of int*int | G_NC_neutrino | G_NC_lepton | G_NC_up | G_NC_down | I_Q_W | I_G_ZWW | G_WWWW | G_ZZWW | G_AZWW | G_AAWW | G_HWW | G_HHWW | G_HZZ | G_HHZZ | G_Htt | G_Hbb | G_Hcc | G_Htautau | G_H3 | G_H4 | G_HGaZ | G_HGaGa | G_Hgg | G_strong | G_Grav | Mass of flavor | Width of flavor (* Two integer counters for the QCD and EW order of the couplings. *) type orders = int * int let orders = function | _ -> (0,0) let input_parameters = [] let derived_parameters = [] let g_over_2_costh = Quot (Neg (Atom G_weak), Prod [Integer 2; Atom Costhw]) let nc_coupling c t3 q = (Real_Array c, [Prod [g_over_2_costh; Diff (t3, Prod [Integer 2; q; Atom Sin2thw])]; Prod [g_over_2_costh; t3]]) let half = Quot (Integer 1, Integer 2) let derived_parameter_arrays = [ nc_coupling G_NC_neutrino half (Integer 0); nc_coupling G_NC_lepton (Neg half) (Integer (-1)); nc_coupling G_NC_up half (Quot (Integer 2, Integer 3)); nc_coupling G_NC_down (Neg half) (Quot (Integer (-1), Integer 3)) ] let parameters () = { input = input_parameters; derived = derived_parameters; derived_arrays = derived_parameter_arrays } module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) let mgm ((m1, g, m2), fbf, c) = ((M m1, G g, M m2), fbf, c) let mom ((m1, o, m2), fbf, c) = ((M m1, O o, M m2), fbf, c) let electromagnetic_currents n = List.map mgm [ ((L (-n), Ga, L n), FBF (1, Psibar, V, Psi), Q_lepton); ((U (-n), Ga, U n), FBF (1, Psibar, V, Psi), Q_up); ((D (-n), Ga, D n), FBF (1, Psibar, V, Psi), Q_down) ] let neutral_currents n = List.map mgm [ ((L (-n), Z, L n), FBF (1, Psibar, VA, Psi), G_NC_lepton); ((N (-n), Z, N n), FBF (1, Psibar, VA, Psi), G_NC_neutrino); ((U (-n), Z, U n), FBF (1, Psibar, VA, Psi), G_NC_up); ((D (-n), Z, D n), FBF (1, Psibar, VA, Psi), G_NC_down) ] let charged_currents n = List.map mgm [ ((L (-n), Wm, N n), FBF (1, Psibar, VL, Psi), G_CC); ((N (-n), Wp, L n), FBF (1, Psibar, VL, Psi), G_CC); ((D (-n), Wm, U n), FBF (1, Psibar, VL, Psi), G_CC); ((U (-n), Wp, D n), FBF (1, Psibar, VL, Psi), G_CC) ] let yukawa = List.map mom [ ((U (-3), H, U 3), FBF (1, Psibar, S, Psi), G_Htt); ((D (-3), H, D 3), FBF (1, Psibar, S, Psi), G_Hbb); ((U (-2), H, U 2), FBF (1, Psibar, S, Psi), G_Hcc); ((L (-3), H, L 3), FBF (1, Psibar, S, Psi), G_Htautau) ] let tgc ((g1, g2, g3), t, c) = ((G g1, G g2, G g3), t, c) let standard_triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW) ] let triple_gauge = standard_triple_gauge let qgc ((g1, g2, g3, g4), t, c) = ((G g1, G g2, G g3, G g4), t, c) let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] let standard_quartic_gauge = List.map qgc [ (Wm, Wp, Wm, Wp), gauge4, G_WWWW; (Wm, Z, Wp, Z), minus_gauge4, G_ZZWW; (Wm, Z, Wp, Ga), minus_gauge4, G_AZWW; (Wm, Ga, Wp, Ga), minus_gauge4, G_AAWW ] let quartic_gauge = standard_quartic_gauge let standard_gauge_higgs = [ ((O H, G Wp, G Wm), Scalar_Vector_Vector 1, G_HWW); ((O H, G Z, G Z), Scalar_Vector_Vector 1, G_HZZ) ] let standard_gauge_higgs4 = [ (O H, O H, G Wp, G Wm), Scalar2_Vector2 1, G_HHWW; (O H, O H, G Z, G Z), Scalar2_Vector2 1, G_HHZZ ] let standard_higgs = [ (O H, O H, O H), Scalar_Scalar_Scalar 1, G_H3 ] let standard_higgs4 = [ (O H, O H, O H, O H), Scalar4 1, G_H4 ] let anomalous_gauge_higgs = [] let anomalous_gauge_higgs4 = [] let anomalous_higgs = [] let anomaly_higgs = [ (O H, G Ga, G Ga), Dim5_Scalar_Gauge2 1, G_HGaGa; (O H, G Ga, G Z), Dim5_Scalar_Gauge2 1, G_HGaZ; (O H, G Gl, G Gl), Dim5_Scalar_Gauge2 1, G_Hgg ] let gravitino_coup n = [ (O Grino, M (SL (-n)), M (L n)), GBG (1, Gravbar, POT, Psi), G_Grav; (M (L (-n)), M (SL n), O Grino), GBG (1, Psibar, POT, Grav), G_Grav] let gravitino_gauge = [ (O Grino, G Ga, G Phino), GBG (1, Gravbar, V, Chi), G_Grav ] let anomalous_higgs4 = [] let gauge_higgs = standard_gauge_higgs let gauge_higgs4 = standard_gauge_higgs4 let higgs = standard_higgs let higgs4 = standard_higgs4 let goldstone_vertices = [ ((O Phi0, G Wm, G Wp), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phip, G Ga, G Wm), Scalar_Vector_Vector 1, I_Q_W); ((O Phip, G Z, G Wm), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phim, G Wp, G Ga), Scalar_Vector_Vector 1, I_Q_W); ((O Phim, G Wp, G Z), Scalar_Vector_Vector 1, I_G_ZWW) ] let vertices3 = (ThoList.flatmap electromagnetic_currents [1;2;3] @ ThoList.flatmap neutral_currents [1;2;3] @ ThoList.flatmap charged_currents [1;2;3] @ ThoList.flatmap gravitino_coup [1;2;3] @ gravitino_gauge @ yukawa @ triple_gauge @ gauge_higgs @ higgs @ anomaly_higgs @ goldstone_vertices) let vertices4 = quartic_gauge @ gauge_higgs4 @ higgs4 let vertices () = (vertices3, vertices4, []) (* For efficiency, make sure that [F.of_vertices vertices] is evaluated only once. *) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 let flavor_of_string = function | "e-" -> M (L 1) | "e+" -> M (L (-1)) | "mu-" -> M (L 2) | "mu+" -> M (L (-2)) | "tau-" -> M (L 3) | "tau+" -> M (L (-3)) | "se-" -> M (SL 1) | "se+" -> M (SL (-1)) | "smu-" -> M (SL 2) | "smu+" -> M (SL (-2)) | "stau-" -> M (SL 3) | "stau+" -> M (SL (-3)) | "nue" -> M (N 1) | "nuebar" -> M (N (-1)) | "numu" -> M (N 2) | "numubar" -> M (N (-2)) | "nutau" -> M (N 3) | "nutaubar" -> M (N (-3)) | "u" -> M (U 1) | "ubar" -> M (U (-1)) | "c" -> M (U 2) | "cbar" -> M (U (-2)) | "t" -> M (U 3) | "tbar" -> M (U (-3)) | "d" -> M (D 1) | "dbar" -> M (D (-1)) | "s" -> M (D 2) | "sbar" -> M (D (-2)) | "b" -> M (D 3) | "bbar" -> M (D (-3)) | "g" | "gl" -> G Gl | "A" -> G Ga | "Z" | "Z0" -> G Z | "W+" -> G Wp | "W-" -> G Wm | "H" -> O H | "GG" -> O Grino | "phino" | "Phino" -> G Phino | _ -> invalid_arg "Modellib_BSM.GravTest.flavor_of_string" let flavor_to_string = function | M f -> begin match f with | L 1 -> "e-" | L (-1) -> "e+" | L 2 -> "mu-" | L (-2) -> "mu+" | L 3 -> "tau-" | L (-3) -> "tau+" | L _ -> invalid_arg "Modellib_BSM.GravTest.flavor_to_string: invalid lepton" | SL 1 -> "se-" | SL (-1) -> "se+" | SL 2 -> "smu-" | SL (-2) -> "smu+" | SL 3 -> "stau-" | SL (-3) -> "stau+" | SL _ -> invalid_arg "Modellib_BSM.GravTest.flavor_to_string: invalid slepton" | N 1 -> "nue" | N (-1) -> "nuebar" | N 2 -> "numu" | N (-2) -> "numubar" | N 3 -> "nutau" | N (-3) -> "nutaubar" | N _ -> invalid_arg "Modellib_BSM.GravTest.flavor_to_string: invalid neutrino" | U 1 -> "u" | U (-1) -> "ubar" | U 2 -> "c" | U (-2) -> "cbar" | U 3 -> "t" | U (-3) -> "tbar" | U _ -> invalid_arg "Modellib_BSM.SM.flavor_to_string: invalid up type quark" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | D _ -> invalid_arg "Modellib_BSM.GravTest.flavor_to_string: invalid down type quark" end | G f -> begin match f with | Gl -> "g" | Ga -> "A" | Z -> "Z" | Wp -> "W+" | Wm -> "W-" | Phino -> "phino" end | O f -> begin match f with | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | H -> "H" | Grino -> "GG" end let flavor_to_TeX = function | M f -> begin match f with | L 1 -> "e^-" | L (-1) -> "e^+" | L 2 -> "\\mu^-" | L (-2) -> "\\mu^+" | L 3 -> "\\tau^-" | L (-3) -> "\\tau^+" | L _ -> invalid_arg "Modellib_BSM.GravTest.flavor_to_TeX: invalid lepton" | SL 1 -> "\\tilde{e}^-" | SL (-1) -> "\\tilde{e}^+" | SL 2 -> "\\tilde{\\mu}^-" | SL (-2) -> "\\tilde{\\mu}^+" | SL 3 -> "\\tilde{\\tau}^-" | SL (-3) -> "\\tilde{\\tau}^+" | SL _ -> invalid_arg "Modellib_BSM.GravTest.flavor_to_TeX: invalid slepton" | N 1 -> "\\nu_e" | N (-1) -> "\\bar{\\nu}_e" | N 2 -> "\\nu_\\mu" | N (-2) -> "\\bar{\\nu}_\\mu" | N 3 -> "\\nu_\\tau" | N (-3) -> "\\bar{\\nu}_\\tau" | N _ -> invalid_arg "Modellib_BSM.GravTest.flavor_to_TeX: invalid neutrino" | U 1 -> "u" | U (-1) -> "\\bar{u}" | U 2 -> "c" | U (-2) -> "\\bar{c}" | U 3 -> "t" | U (-3) -> "\\bar{t}" | U _ -> invalid_arg "Modellib_BSM.SM.flavor_to_TeX: invalid up type quark" | D 1 -> "d" | D (-1) -> "\\bar{d}" | D 2 -> "s" | D (-2) -> "\\bar{s}" | D 3 -> "b" | D (-3) -> "\\bar{b}" | D _ -> invalid_arg "Modellib_BSM.GravTest.flavor_to_TeX: invalid down type quark" end | G f -> begin match f with | Gl -> "g" | Ga -> "\\gamma" | Z -> "Z" | Wp -> "W^+" | Wm -> "W^-" | Phino -> "\\tilde{\\phi}" end | O f -> begin match f with | Phip -> "\\phi^+" | Phim -> "\\phi^-" | Phi0 -> "\\phi^0" | H -> "H" | Grino -> "\\tilde{G}" end let flavor_symbol = function | M f -> begin match f with | L n when n > 0 -> "l" ^ string_of_int n | L n -> "l" ^ string_of_int (abs n) ^ "b" | SL n when n > 0 -> "sl" ^ string_of_int n | SL n -> "sl" ^ string_of_int (abs n) ^ "b" | N n when n > 0 -> "n" ^ string_of_int n | N n -> "n" ^ string_of_int (abs n) ^ "b" | U n when n > 0 -> "u" ^ string_of_int n | U n -> "u" ^ string_of_int (abs n) ^ "b" | D n when n > 0 -> "d" ^ string_of_int n | D n -> "d" ^ string_of_int (abs n) ^ "b" end | G f -> begin match f with | Gl -> "gl" | Ga -> "a" | Z -> "z" | Wp -> "wp" | Wm -> "wm" | Phino -> "phino" end | O f -> begin match f with | Phip -> "pp" | Phim -> "pm" | Phi0 -> "p0" | H -> "h" | Grino -> "gv" end let pdg = function | M f -> begin match f with | L n when n > 0 -> 9 + 2*n | L n -> - 9 + 2*n | SL n when n > 0 -> 39 + 2*n | SL n -> - 39 + 2*n | N n when n > 0 -> 10 + 2*n | N n -> - 10 + 2*n | U n when n > 0 -> 2*n | U n -> 2*n | D n when n > 0 -> - 1 + 2*n | D n -> 1 + 2*n end | G f -> begin match f with | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) | Phino -> 46 end | O f -> begin match f with | Phip | Phim -> 27 | Phi0 -> 26 | H -> 25 | Grino -> 39 end let mass_symbol f = "mass(" ^ string_of_int (abs (pdg f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg f)) ^ ")" let constant_symbol = function | Unit -> "unit" | Pi -> "PI" | Alpha_QED -> "alpha" | E -> "e" | G_weak -> "g" | Vev -> "vev" | Sin2thw -> "sin2thw" | Sinthw -> "sinthw" | Costhw -> "costhw" | Q_lepton -> "qlep" | Q_up -> "qup" | Q_down -> "qdwn" | G_NC_lepton -> "gnclep" | G_NC_neutrino -> "gncneu" | G_NC_up -> "gncup" | G_NC_down -> "gncdwn" | G_CC -> "gcc" | G_CCQ (n1,n2) -> "gccq" ^ string_of_int n1 ^ string_of_int n2 | I_Q_W -> "iqw" | I_G_ZWW -> "igzww" | G_WWWW -> "gw4" | G_ZZWW -> "gzzww" | G_AZWW -> "gazww" | G_AAWW -> "gaaww" | G_HWW -> "ghww" | G_HZZ -> "ghzz" | G_HHWW -> "ghhww" | G_HHZZ -> "ghhzz" | G_Htt -> "ghtt" | G_Hbb -> "ghbb" | G_Htautau -> "ghtautau" | G_Hcc -> "ghcc" | G_HGaZ -> "ghgaz" | G_HGaGa -> "ghgaga" | G_Hgg -> "ghgg" | G_H3 -> "gh3" | G_H4 -> "gh4" | G_strong -> "gs" | G_Grav -> "ggrav" | Mass f -> "mass" ^ flavor_symbol f | Width f -> "width" ^ flavor_symbol f end module Template (Flags : BSM_flags) = struct open Coupling let default_width = ref Timelike let use_fudged_width = ref false let options = Options.create [ "constant_width", Arg.Unit (fun () -> default_width := Constant), "use constant width (also in t-channel)"; "fudged_width", Arg.Set use_fudged_width, "use fudge factor for charge particle width"; "custom_width", Arg.String (fun f -> default_width := Custom f), "use custom width"; "cancel_widths", Arg.Unit (fun () -> default_width := Vanishing), "use vanishing width"; "cms_width", Arg.Unit (fun () -> default_width := Complex_Mass), - "use complex mass scheme"] + "use complex mass scheme"; + "running_width", Arg.Unit (fun () -> default_width := Running), + "use running width"] type matter_field = L of int | N of int | U of int | D of int type gauge_boson = Ga | Wp | Wm | Z | Gl type other = Phip | Phim | Phi0 | H type flavor = M of matter_field | G of gauge_boson | O of other let matter_field f = M f let gauge_boson f = G f let other f = O f type field = | Matter of matter_field | Gauge of gauge_boson | Other of other let field = function | M f -> Matter f | G f -> Gauge f | O f -> Other f type gauge = unit let gauge_symbol () = failwith "Modellib_BSM.Template.gauge_symbol: internal error" let family n = List.map matter_field [ L n; N n; U n; D n ] let external_flavors () = [ "1st Generation", ThoList.flatmap family [1; -1]; "2nd Generation", ThoList.flatmap family [2; -2]; "3rd Generation", ThoList.flatmap family [3; -3]; "Gauge Bosons", List.map gauge_boson [Ga; Z; Wp; Wm; Gl]; "Higgs", List.map other [H]; "Goldstone Bosons", List.map other [Phip; Phim; Phi0] ] let flavors () = ThoList.flatmap snd (external_flavors ()) let spinor n = if n >= 0 then Spinor else ConjSpinor let lorentz = function | M f -> begin match f with | L n -> spinor n | N n -> spinor n | U n -> spinor n | D n -> spinor n end | G f -> begin match f with | Ga | Gl -> Vector | Wp | Wm | Z -> Massive_Vector end | O f -> Scalar let color = function | M (U n) -> Color.SUN (if n > 0 then 3 else -3) | M (D n) -> Color.SUN (if n > 0 then 3 else -3) | G Gl -> Color.AdjSUN 3 | _ -> Color.Singlet let nc () = 3 let prop_spinor n = if n >= 0 then Prop_Spinor else Prop_ConjSpinor let propagator = function | M f -> begin match f with | L n -> prop_spinor n | N n -> prop_spinor n | U n -> prop_spinor n | D n -> prop_spinor n end | G f -> begin match f with | Ga | Gl -> Prop_Feynman | Wp | Wm | Z -> Prop_Unitarity end | O f -> begin match f with | Phip | Phim | Phi0 -> Only_Insertion | H -> Prop_Scalar end (* Optionally, ask for the fudge factor treatment for the widths of charged particles. Currently, this only applies to $W^\pm$ and top. *) let width f = if !use_fudged_width then match f with | G Wp | G Wm | M (U 3) | M (U (-3)) -> Fudged | _ -> !default_width else !default_width let goldstone = function | G f -> begin match f with | Wp -> Some (O Phip, Coupling.Integer 1) | Wm -> Some (O Phim, Coupling.Integer 1) | Z -> Some (O Phi0, Coupling.Integer 1) | _ -> None end | _ -> None let conjugate = function | M f -> M (begin match f with | L n -> L (-n) | N n -> N (-n) | U n -> U (-n) | D n -> D (-n) end) | G f -> G (begin match f with | Gl -> Gl | Ga -> Ga | Z -> Z | Wp -> Wm | Wm -> Wp end) | O f -> O (begin match f with | Phip -> Phim | Phim -> Phip | Phi0 -> Phi0 | H -> H end) let fermion = function | M f -> begin match f with | L n -> if n > 0 then 1 else -1 | N n -> if n > 0 then 1 else -1 | U n -> if n > 0 then 1 else -1 | D n -> if n > 0 then 1 else -1 end | G f -> begin match f with | Gl | Ga | Z | Wp | Wm -> 0 end | O _ -> 0 module Ch = Charges.QQ let ( // ) = Algebra.Small_Rational.make let generation' = function | 1 -> [ 1//1; 0//1; 0//1] | 2 -> [ 0//1; 1//1; 0//1] | 3 -> [ 0//1; 0//1; 1//1] | -1 -> [-1//1; 0//1; 0//1] | -2 -> [ 0//1; -1//1; 0//1] | -3 -> [ 0//1; 0//1; -1//1] | n -> invalid_arg ("Template.generation': " ^ string_of_int n) let generation f = match f with | M (L n | N n | U n | D n) -> generation' n | G _ | O _ -> [0//1; 0//1; 0//1] let charge = function | M f -> begin match f with | L n -> if n > 0 then -1//1 else 1//1 | N n -> 0//1 | U n -> if n > 0 then 2//3 else -2//3 | D n -> if n > 0 then -1//3 else 1//3 end | G f -> begin match f with | Gl | Ga | Z -> 0//1 | Wp -> 1//1 | Wm -> -1//1 end | O f -> begin match f with | H | Phi0 -> 0//1 | Phip -> 1//1 | Phim -> -1//1 end let lepton = function | M f -> begin match f with | L n | N n -> if n > 0 then 1//1 else -1//1 | U _ | D _ -> 0//1 end | G _ | O _ -> 0//1 let baryon = function | M f -> begin match f with | L _ | N _ -> 0//1 | U n | D n -> if n > 0 then 1//1 else -1//1 end | G _ | O _ -> 0//1 let charges f = [ charge f; lepton f; baryon f] @ generation f type constant = | Unit | Pi | Alpha_QED | Sin2thw | Sinthw | Costhw | E | G_weak | Vev | Q_lepton | Q_up | Q_down | G_CC | G_NC_neutrino | G_NC_lepton | G_NC_up | G_NC_down | I_Q_W | I_G_ZWW | G_WWWW | G_ZZWW | G_AZWW | G_AAWW | G_HWW | G_HHWW | G_HZZ | G_HHZZ | G_Htt | G_Hbb | G_Hcc | G_Hmm | G_Htautau | G_H3 | G_H4 | G_HGaZ | G_HGaGa | G_Hgg | Gs | I_Gs | G2 | Mass of flavor | Width of flavor (* Two integer counters for the QCD and EW order of the couplings. *) type orders = int * int let orders = function | _ -> (0,0) let input_parameters = [] let derived_parameters = [] let g_over_2_costh = Quot (Neg (Atom G_weak), Prod [Integer 2; Atom Costhw]) let nc_coupling c t3 q = (Real_Array c, [Prod [g_over_2_costh; Diff (t3, Prod [Integer 2; q; Atom Sin2thw])]; Prod [g_over_2_costh; t3]]) let half = Quot (Integer 1, Integer 2) let derived_parameter_arrays = [ nc_coupling G_NC_neutrino half (Integer 0); nc_coupling G_NC_lepton (Neg half) (Integer (-1)); nc_coupling G_NC_up half (Quot (Integer 2, Integer 3)); nc_coupling G_NC_down (Neg half) (Quot (Integer (-1), Integer 3)) ] let parameters () = { input = input_parameters; derived = derived_parameters; derived_arrays = derived_parameter_arrays } module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) let mgm ((m1, g, m2), fbf, c) = ((M m1, G g, M m2), fbf, c) let electromagnetic_currents n = List.map mgm [ ((L (-n), Ga, L n), FBF (1, Psibar, V, Psi), Q_lepton); ((U (-n), Ga, U n), FBF (1, Psibar, V, Psi), Q_up); ((D (-n), Ga, D n), FBF (1, Psibar, V, Psi), Q_down) ] let color_currents n = List.map mgm [ ((U (-n), Gl, U n), FBF ((-1), Psibar, V, Psi), Gs); ((D (-n), Gl, D n), FBF ((-1), Psibar, V, Psi), Gs) ] let neutral_currents n = List.map mgm [ ((L (-n), Z, L n), FBF (1, Psibar, VA, Psi), G_NC_lepton); ((N (-n), Z, N n), FBF (1, Psibar, VA, Psi), G_NC_neutrino); ((U (-n), Z, U n), FBF (1, Psibar, VA, Psi), G_NC_up); ((D (-n), Z, D n), FBF (1, Psibar, VA, Psi), G_NC_down) ] let charged_currents n = List.map mgm [ ((L (-n), Wm, N n), FBF (1, Psibar, VL, Psi), G_CC); ((N (-n), Wp, L n), FBF (1, Psibar, VL, Psi), G_CC); ((D (-n), Wm, U n), FBF (1, Psibar, VL, Psi), G_CC); ((U (-n), Wp, D n), FBF (1, Psibar, VL, Psi), G_CC) ] let yukawa = [ ((M (U (-3)), O H, M (U 3)), FBF (1, Psibar, S, Psi), G_Htt); ((M (D (-3)), O H, M (D 3)), FBF (1, Psibar, S, Psi), G_Hbb); ((M (U (-2)), O H, M (U 2)), FBF (1, Psibar, S, Psi), G_Hcc); ((M (L (-2)), O H, M (L 2)), FBF (1, Psibar, S, Psi), G_Hmm); ((M (L (-3)), O H, M (L 3)), FBF (1, Psibar, S, Psi), G_Htautau) ] let tgc ((g1, g2, g3), t, c) = ((G g1, G g2, G g3), t, c) let triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW); ((Gl, Gl, Gl), Gauge_Gauge_Gauge 1, I_Gs) ] let qgc ((g1, g2, g3, g4), t, c) = ((G g1, G g2, G g3, G g4), t, c) let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] let quartic_gauge = List.map qgc [ (Wm, Wp, Wm, Wp), gauge4, G_WWWW; (Wm, Z, Wp, Z), minus_gauge4, G_ZZWW; (Wm, Z, Wp, Ga), minus_gauge4, G_AZWW; (Wm, Ga, Wp, Ga), minus_gauge4, G_AAWW; (Gl, Gl, Gl, Gl), gauge4, G2] let gauge_higgs = [ ((O H, G Wp, G Wm), Scalar_Vector_Vector 1, G_HWW); ((O H, G Z, G Z), Scalar_Vector_Vector 1, G_HZZ) ] let gauge_higgs4 = [ (O H, O H, G Wp, G Wm), Scalar2_Vector2 1, G_HHWW; (O H, O H, G Z, G Z), Scalar2_Vector2 1, G_HHZZ ] let higgs = [ (O H, O H, O H), Scalar_Scalar_Scalar 1, G_H3 ] let higgs4 = [ (O H, O H, O H, O H), Scalar4 1, G_H4 ] let anomaly_higgs = [] (* [ (O H, G Ga, G Ga), Dim5_Scalar_Gauge2 1, G_HGaGa; (O H, G Ga, G Z), Dim5_Scalar_Gauge2 1, G_HGaZ; (O H, G Gl, G Gl), Dim5_Scalar_Gauge2 1, G_Hgg] *) let goldstone_vertices = [ ((O Phi0, G Wm, G Wp), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phip, G Ga, G Wm), Scalar_Vector_Vector 1, I_Q_W); ((O Phip, G Z, G Wm), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phim, G Wp, G Ga), Scalar_Vector_Vector 1, I_Q_W); ((O Phim, G Wp, G Z), Scalar_Vector_Vector 1, I_G_ZWW) ] let vertices3 = (ThoList.flatmap electromagnetic_currents [1;2;3] @ ThoList.flatmap color_currents [1;2;3] @ ThoList.flatmap neutral_currents [1;2;3] @ ThoList.flatmap charged_currents [1;2;3] @ yukawa @ triple_gauge @ gauge_higgs @ higgs @ anomaly_higgs @ goldstone_vertices) let vertices4 = quartic_gauge @ gauge_higgs4 @ higgs4 let vertices () = (vertices3, vertices4, []) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 let flavor_of_string = function | "e-" -> M (L 1) | "e+" -> M (L (-1)) | "mu-" -> M (L 2) | "mu+" -> M (L (-2)) | "tau-" -> M (L 3) | "tau+" -> M (L (-3)) | "nue" -> M (N 1) | "nuebar" -> M (N (-1)) | "numu" -> M (N 2) | "numubar" -> M (N (-2)) | "nutau" -> M (N 3) | "nutaubar" -> M (N (-3)) | "u" -> M (U 1) | "ubar" -> M (U (-1)) | "c" -> M (U 2) | "cbar" -> M (U (-2)) | "t" -> M (U 3) | "tbar" -> M (U (-3)) | "d" -> M (D 1) | "dbar" -> M (D (-1)) | "s" -> M (D 2) | "sbar" -> M (D (-2)) | "b" -> M (D 3) | "bbar" -> M (D (-3)) | "g" | "gl" -> G Gl | "A" -> G Ga | "Z" | "Z0" -> G Z | "W+" -> G Wp | "W-" -> G Wm | "H" -> O H | _ -> invalid_arg "Modellib_BSM.Template.flavor_of_string" let flavor_to_string = function | M f -> begin match f with | L 1 -> "e-" | L (-1) -> "e+" | L 2 -> "mu-" | L (-2) -> "mu+" | L 3 -> "tau-" | L (-3) -> "tau+" | L _ -> invalid_arg "Modellib_BSM.Template.flavor_to_string: invalid lepton" | N 1 -> "nue" | N (-1) -> "nuebar" | N 2 -> "numu" | N (-2) -> "numubar" | N 3 -> "nutau" | N (-3) -> "nutaubar" | N _ -> invalid_arg "Modellib_BSM.Template.flavor_to_string: invalid neutrino" | U 1 -> "u" | U (-1) -> "ubar" | U 2 -> "c" | U (-2) -> "cbar" | U 3 -> "t" | U (-3) -> "tbar" | U _ -> invalid_arg "Modellib_BSM.Template.flavor_to_string: invalid up type quark" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | D _ -> invalid_arg "Modellib_BSM.Template.flavor_to_string: invalid down type quark" end | G f -> begin match f with | Gl -> "g" | Ga -> "A" | Z -> "Z" | Wp -> "W+" | Wm -> "W-" end | O f -> begin match f with | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | H -> "H" end let flavor_to_TeX = function | M f -> begin match f with | L 1 -> "e^-" | L (-1) -> "e^+" | L 2 -> "\\mu^-" | L (-2) -> "\\mu^+" | L 3 -> "\\tau^-" | L (-3) -> "\\tau^+" | L _ -> invalid_arg "Modellib_BSM.Template.flavor_to_TeX: invalid lepton" | N 1 -> "\\nu_e" | N (-1) -> "\\bar{\\nu}_e" | N 2 -> "\\nu_\\mu" | N (-2) -> "\\bar{\\nu}_\\mu" | N 3 -> "\\nu_\\tau" | N (-3) -> "\\bar{\\nu}_\\tau" | N _ -> invalid_arg "Modellib_BSM.Template.flavor_to_TeX: invalid neutrino" | U 1 -> "u" | U (-1) -> "\\bar{u}" | U 2 -> "c" | U (-2) -> "\\bar{c}" | U 3 -> "t" | U (-3) -> "\\bar{t}" | U _ -> invalid_arg "Modellib_BSM.Template.flavor_to_TeX: invalid up type quark" | D 1 -> "d" | D (-1) -> "\\bar{d}" | D 2 -> "s" | D (-2) -> "\\bar{s}" | D 3 -> "b" | D (-3) -> "\\bar{b}" | D _ -> invalid_arg "Modellib_BSM.Template.flavor_to_TeX: invalid down type quark" end | G f -> begin match f with | Gl -> "g" | Ga -> "\\gamma" | Z -> "Z" | Wp -> "W^+" | Wm -> "W^-" end | O f -> begin match f with | Phip -> "\\phi^+" | Phim -> "\\phi^-" | Phi0 -> "\\phi^0" | H -> "H" end let flavor_symbol = function | M f -> begin match f with | L n when n > 0 -> "l" ^ string_of_int n | L n -> "l" ^ string_of_int (abs n) ^ "b" | N n when n > 0 -> "n" ^ string_of_int n | N n -> "n" ^ string_of_int (abs n) ^ "b" | U n when n > 0 -> "u" ^ string_of_int n | U n -> "u" ^ string_of_int (abs n) ^ "b" | D n when n > 0 -> "d" ^ string_of_int n | D n -> "d" ^ string_of_int (abs n) ^ "b" end | G f -> begin match f with | Gl -> "gl" | Ga -> "a" | Z -> "z" | Wp -> "wp" | Wm -> "wm" end | O f -> begin match f with | Phip -> "pp" | Phim -> "pm" | Phi0 -> "p0" | H -> "h" end let pdg = function | M f -> begin match f with | L n when n > 0 -> 9 + 2*n | L n -> - 9 + 2*n | N n when n > 0 -> 10 + 2*n | N n -> - 10 + 2*n | U n when n > 0 -> 2*n | U n -> 2*n | D n when n > 0 -> - 1 + 2*n | D n -> 1 + 2*n end | G f -> begin match f with | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) end | O f -> begin match f with | Phip | Phim -> 27 | Phi0 -> 26 | H -> 25 end let mass_symbol f = "mass(" ^ string_of_int (abs (pdg f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg f)) ^ ")" let constant_symbol = function | Unit -> "unit" | Pi -> "PI" | Alpha_QED -> "alpha" | E -> "e" | G_weak -> "g" | Vev -> "vev" | Sin2thw -> "sin2thw" | Sinthw -> "sinthw" | Costhw -> "costhw" | Q_lepton -> "qlep" | Q_up -> "qup" | Q_down -> "qdwn" | G_NC_lepton -> "gnclep" | G_NC_neutrino -> "gncneu" | G_NC_up -> "gncup" | G_NC_down -> "gncdwn" | G_CC -> "gcc" | I_Q_W -> "iqw" | I_G_ZWW -> "igzww" | G_WWWW -> "gw4" | G_ZZWW -> "gzzww" | G_AZWW -> "gazww" | G_AAWW -> "gaaww" | G_HWW -> "ghww" | G_HZZ -> "ghzz" | G_HHWW -> "ghhww" | G_HHZZ -> "ghhzz" | G_Htt -> "ghtt" | G_Hbb -> "ghbb" | G_Htautau -> "ghtautau" | G_Hcc -> "ghcc" | G_Hmm -> "ghmm" | G_HGaZ -> "ghgaz" | G_HGaGa -> "ghgaga" | G_Hgg -> "ghgg" | G_H3 -> "gh3" | G_H4 -> "gh4" | Gs -> "gs" | I_Gs -> "igs" | G2 -> "gs**2" | Mass f -> "mass" ^ flavor_symbol f | Width f -> "width" ^ flavor_symbol f end module HSExt (Flags : BSM_flags) = struct open Coupling let default_width = ref Timelike let use_fudged_width = ref false let options = Options.create [ "constant_width", Arg.Unit (fun () -> default_width := Constant), "use constant width (also in t-channel)"; "fudged_width", Arg.Set use_fudged_width, "use fudge factor for charge particle width"; "custom_width", Arg.String (fun f -> default_width := Custom f), "use custom width"; "cancel_widths", Arg.Unit (fun () -> default_width := Vanishing), "use vanishing width"; "cms_width", Arg.Unit (fun () -> default_width := Complex_Mass), - "use complex mass scheme"] + "use complex mass scheme"; + "running_width", Arg.Unit (fun () -> default_width := Running), + "use running width"] type matter_field = L of int | N of int | U of int | D of int type gauge_boson = Ga | Wp | Wm | Z | Gl type other = Phip | Phim | Phi0 | H | S type flavor = M of matter_field | G of gauge_boson | O of other let matter_field f = M f let gauge_boson f = G f let other f = O f type field = | Matter of matter_field | Gauge of gauge_boson | Other of other let field = function | M f -> Matter f | G f -> Gauge f | O f -> Other f type gauge = unit let gauge_symbol () = failwith "Modellib_BSM.HSExt.gauge_symbol: internal error" let family n = List.map matter_field [ L n; N n; U n; D n ] let external_flavors () = [ "1st Generation", ThoList.flatmap family [1; -1]; "2nd Generation", ThoList.flatmap family [2; -2]; "3rd Generation", ThoList.flatmap family [3; -3]; "Gauge Bosons", List.map gauge_boson [Ga; Z; Wp; Wm; Gl]; "Higgs", List.map other [H; S]; "Goldstone Bosons", List.map other [Phip; Phim; Phi0] ] let flavors () = ThoList.flatmap snd (external_flavors ()) let spinor n = if n >= 0 then Spinor else ConjSpinor let lorentz = function | M f -> begin match f with | L n -> spinor n | N n -> spinor n | U n -> spinor n | D n -> spinor n end | G f -> begin match f with | Ga | Gl -> Vector | Wp | Wm | Z -> Massive_Vector end | O f -> Scalar let color = function | M (U n) -> Color.SUN (if n > 0 then 3 else -3) | M (D n) -> Color.SUN (if n > 0 then 3 else -3) | G Gl -> Color.AdjSUN 3 | _ -> Color.Singlet let nc () = 3 let prop_spinor n = if n >= 0 then Prop_Spinor else Prop_ConjSpinor let propagator = function | M f -> begin match f with | L n -> prop_spinor n | N n -> prop_spinor n | U n -> prop_spinor n | D n -> prop_spinor n end | G f -> begin match f with | Ga | Gl -> Prop_Feynman | Wp | Wm | Z -> Prop_Unitarity end | O f -> begin match f with | Phip | Phim | Phi0 -> Only_Insertion | H | S -> Prop_Scalar end (* Optionally, ask for the fudge factor treatment for the widths of charged particles. Currently, this only applies to $W^\pm$ and top. *) let width f = if !use_fudged_width then match f with | G Wp | G Wm | M (U 3) | M (U (-3)) -> Fudged | _ -> !default_width else !default_width let goldstone = function | G f -> begin match f with | Wp -> Some (O Phip, Coupling.Integer 1) | Wm -> Some (O Phim, Coupling.Integer 1) | Z -> Some (O Phi0, Coupling.Integer 1) | _ -> None end | _ -> None let conjugate = function | M f -> M (begin match f with | L n -> L (-n) | N n -> N (-n) | U n -> U (-n) | D n -> D (-n) end) | G f -> G (begin match f with | Gl -> Gl | Ga -> Ga | Z -> Z | Wp -> Wm | Wm -> Wp end) | O f -> O (begin match f with | Phip -> Phim | Phim -> Phip | Phi0 -> Phi0 | H -> H | S -> S end) let fermion = function | M f -> begin match f with | L n -> if n > 0 then 1 else -1 | N n -> if n > 0 then 1 else -1 | U n -> if n > 0 then 1 else -1 | D n -> if n > 0 then 1 else -1 end | G f -> begin match f with | Gl | Ga | Z | Wp | Wm -> 0 end | O _ -> 0 module Ch = Charges.QQ let ( // ) = Algebra.Small_Rational.make let generation' = function | 1 -> [ 1//1; 0//1; 0//1] | 2 -> [ 0//1; 1//1; 0//1] | 3 -> [ 0//1; 0//1; 1//1] | -1 -> [-1//1; 0//1; 0//1] | -2 -> [ 0//1; -1//1; 0//1] | -3 -> [ 0//1; 0//1; -1//1] | n -> invalid_arg ("HSExt.generation': " ^ string_of_int n) let generation f = match f with | M (L n | N n | U n | D n) -> generation' n | G _ | O _ -> [0//1; 0//1; 0//1] let charge = function | M f -> begin match f with | L n -> if n > 0 then -1//1 else 1//1 | N n -> 0//1 | U n -> if n > 0 then 2//3 else -2//3 | D n -> if n > 0 then -1//3 else 1//3 end | G f -> begin match f with | Gl | Ga | Z -> 0//1 | Wp -> 1//1 | Wm -> -1//1 end | O f -> begin match f with | H | Phi0 | S -> 0//1 | Phip -> 1//1 | Phim -> -1//1 end let lepton = function | M f -> begin match f with | L n | N n -> if n > 0 then 1//1 else -1//1 | U _ | D _ -> 0//1 end | G _ | O _ -> 0//1 let baryon = function | M f -> begin match f with | L _ | N _ -> 0//1 | U n | D n -> if n > 0 then 1//1 else -1//1 end | G _ | O _ -> 0//1 let charges f = [ charge f; lepton f; baryon f] @ generation f type constant = | Unit | Pi | Alpha_QED | Sin2thw | Sinthw | Costhw | E | G_weak | Vev | Q_lepton | Q_up | Q_down | G_CC | G_NC_neutrino | G_NC_lepton | G_NC_up | G_NC_down | I_Q_W | I_G_ZWW | G_WWWW | G_ZZWW | G_AZWW | G_AAWW | G_HWW | G_HHWW | G_HZZ | G_HHZZ | G_SWW | G_SSWW | G_SZZ | G_SSZZ | G_HSWW | G_HSZZ | G_Htt | G_Hbb | G_Hcc | G_Hmm | G_Htautau | G_H3 | G_H4_1 | G_H4_2 | G_H4_3 | G_H4_4 | G_H4_5 | G_Stt | G_Sbb | G_Scc | G_Smm | G_Stautau | G_HSS | G_HHS | G_HGaZ | G_HGaGa | G_Hgg | G_SGaZ | G_SGaGa | G_Sgg | Gs | I_Gs | G2 | Mass of flavor | Width of flavor (* Two integer counters for the QCD and EW order of the couplings. *) type orders = int * int let orders = function | _ -> (0,0) let input_parameters = [] let derived_parameters = [] let g_over_2_costh = Quot (Neg (Atom G_weak), Prod [Integer 2; Atom Costhw]) let nc_coupling c t3 q = (Real_Array c, [Prod [g_over_2_costh; Diff (t3, Prod [Integer 2; q; Atom Sin2thw])]; Prod [g_over_2_costh; t3]]) let half = Quot (Integer 1, Integer 2) let derived_parameter_arrays = [ nc_coupling G_NC_neutrino half (Integer 0); nc_coupling G_NC_lepton (Neg half) (Integer (-1)); nc_coupling G_NC_up half (Quot (Integer 2, Integer 3)); nc_coupling G_NC_down (Neg half) (Quot (Integer (-1), Integer 3)) ] let parameters () = { input = input_parameters; derived = derived_parameters; derived_arrays = derived_parameter_arrays } module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) let mgm ((m1, g, m2), fbf, c) = ((M m1, G g, M m2), fbf, c) let electromagnetic_currents n = List.map mgm [ ((L (-n), Ga, L n), FBF (1, Psibar, V, Psi), Q_lepton); ((U (-n), Ga, U n), FBF (1, Psibar, V, Psi), Q_up); ((D (-n), Ga, D n), FBF (1, Psibar, V, Psi), Q_down) ] let color_currents n = List.map mgm [ ((U (-n), Gl, U n), FBF ((-1), Psibar, V, Psi), Gs); ((D (-n), Gl, D n), FBF ((-1), Psibar, V, Psi), Gs) ] let neutral_currents n = List.map mgm [ ((L (-n), Z, L n), FBF (1, Psibar, VA, Psi), G_NC_lepton); ((N (-n), Z, N n), FBF (1, Psibar, VA, Psi), G_NC_neutrino); ((U (-n), Z, U n), FBF (1, Psibar, VA, Psi), G_NC_up); ((D (-n), Z, D n), FBF (1, Psibar, VA, Psi), G_NC_down) ] let charged_currents n = List.map mgm [ ((L (-n), Wm, N n), FBF (1, Psibar, VL, Psi), G_CC); ((N (-n), Wp, L n), FBF (1, Psibar, VL, Psi), G_CC); ((D (-n), Wm, U n), FBF (1, Psibar, VL, Psi), G_CC); ((U (-n), Wp, D n), FBF (1, Psibar, VL, Psi), G_CC) ] let yukawa = [ ((M (U (-3)), O H, M (U 3)), FBF (1, Psibar, Coupling.S, Psi), G_Htt); ((M (D (-3)), O H, M (D 3)), FBF (1, Psibar, Coupling.S, Psi), G_Hbb); ((M (U (-2)), O H, M (U 2)), FBF (1, Psibar, Coupling.S, Psi), G_Hcc); ((M (L (-2)), O H, M (L 2)), FBF (1, Psibar, Coupling.S, Psi), G_Hmm); ((M (L (-3)), O H, M (L 3)), FBF (1, Psibar, Coupling.S, Psi), G_Htautau); ((M (U (-3)), O S, M (U 3)), FBF (1, Psibar, Coupling.S, Psi), G_Stt); ((M (D (-3)), O S, M (D 3)), FBF (1, Psibar, Coupling.S, Psi), G_Sbb); ((M (U (-2)), O S, M (U 2)), FBF (1, Psibar, Coupling.S, Psi), G_Scc); ((M (L (-2)), O S, M (L 2)), FBF (1, Psibar, Coupling.S, Psi), G_Smm); ((M (L (-3)), O S, M (L 3)), FBF (1, Psibar, Coupling.S, Psi), G_Stautau) ] let tgc ((g1, g2, g3), t, c) = ((G g1, G g2, G g3), t, c) let triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW); ((Gl, Gl, Gl), Gauge_Gauge_Gauge 1, I_Gs) ] let qgc ((g1, g2, g3, g4), t, c) = ((G g1, G g2, G g3, G g4), t, c) let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] let quartic_gauge = List.map qgc [ (Wm, Wp, Wm, Wp), gauge4, G_WWWW; (Wm, Z, Wp, Z), minus_gauge4, G_ZZWW; (Wm, Z, Wp, Ga), minus_gauge4, G_AZWW; (Wm, Ga, Wp, Ga), minus_gauge4, G_AAWW; (Gl, Gl, Gl, Gl), gauge4, G2] let gauge_higgs = [ ((O H, G Wp, G Wm), Scalar_Vector_Vector 1, G_HWW); ((O H, G Z, G Z), Scalar_Vector_Vector 1, G_HZZ); ((O S, G Wp, G Wm), Scalar_Vector_Vector 1, G_SWW); ((O S, G Z, G Z), Scalar_Vector_Vector 1, G_SZZ) ] let gauge_higgs4 = [ (O H, O H, G Wp, G Wm), Scalar2_Vector2 1, G_HHWW; (O H, O H, G Z, G Z), Scalar2_Vector2 1, G_HHZZ; (O H, O S, G Wp, G Wm), Scalar2_Vector2 1, G_HSWW; (O H, O S, G Z, G Z), Scalar2_Vector2 1, G_HSZZ; (O S, O S, G Wp, G Wm), Scalar2_Vector2 1, G_SSWW; (O S, O S, G Z, G Z), Scalar2_Vector2 1, G_SSZZ ] let higgs = [ (O H, O H, O H), Scalar_Scalar_Scalar 1, G_H3; (O S, O H, O H), Scalar_Scalar_Scalar 1, G_HHS; (O S, O S, O H), Scalar_Scalar_Scalar 1, G_HSS ] let higgs4 = [ (O H, O H, O H, O H), Scalar4 1, G_H4_1; (O H, O H, O H, O S), Scalar4 1, G_H4_2; (O H, O H, O S, O S), Scalar4 1, G_H4_3; (O H, O S, O S, O S), Scalar4 1, G_H4_4; (O S, O S, O S, O S), Scalar4 1, G_H4_5 ] let anomaly_higgs = [ (O H, G Ga, G Ga), Dim5_Scalar_Gauge2 1, G_HGaGa; (O H, G Ga, G Z), Dim5_Scalar_Gauge2 1, G_HGaZ; (O H, G Gl, G Gl), Dim5_Scalar_Gauge2 1, G_Hgg; (O S, G Ga, G Ga), Dim5_Scalar_Gauge2 1, G_SGaGa; (O S, G Ga, G Z), Dim5_Scalar_Gauge2 1, G_SGaZ; (O S, G Gl, G Gl), Dim5_Scalar_Gauge2 1, G_Sgg ] let goldstone_vertices = [ ((O Phi0, G Wm, G Wp), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phip, G Ga, G Wm), Scalar_Vector_Vector 1, I_Q_W); ((O Phip, G Z, G Wm), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phim, G Wp, G Ga), Scalar_Vector_Vector 1, I_Q_W); ((O Phim, G Wp, G Z), Scalar_Vector_Vector 1, I_G_ZWW) ] let vertices3 = (ThoList.flatmap electromagnetic_currents [1;2;3] @ ThoList.flatmap color_currents [1;2;3] @ ThoList.flatmap neutral_currents [1;2;3] @ ThoList.flatmap charged_currents [1;2;3] @ yukawa @ triple_gauge @ gauge_higgs @ higgs @ anomaly_higgs @ goldstone_vertices) let vertices4 = quartic_gauge @ gauge_higgs4 @ higgs4 let vertices () = (vertices3, vertices4, []) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 let flavor_of_string = function | "e-" -> M (L 1) | "e+" -> M (L (-1)) | "mu-" -> M (L 2) | "mu+" -> M (L (-2)) | "tau-" -> M (L 3) | "tau+" -> M (L (-3)) | "nue" -> M (N 1) | "nuebar" -> M (N (-1)) | "numu" -> M (N 2) | "numubar" -> M (N (-2)) | "nutau" -> M (N 3) | "nutaubar" -> M (N (-3)) | "u" -> M (U 1) | "ubar" -> M (U (-1)) | "c" -> M (U 2) | "cbar" -> M (U (-2)) | "t" -> M (U 3) | "tbar" -> M (U (-3)) | "d" -> M (D 1) | "dbar" -> M (D (-1)) | "s" -> M (D 2) | "sbar" -> M (D (-2)) | "b" -> M (D 3) | "bbar" -> M (D (-3)) | "g" | "gl" -> G Gl | "A" -> G Ga | "Z" | "Z0" -> G Z | "W+" -> G Wp | "W-" -> G Wm | "H" -> O H | "S" -> O S | _ -> invalid_arg "Modellib_BSM.HSExt.flavor_of_string" let flavor_to_string = function | M f -> begin match f with | L 1 -> "e-" | L (-1) -> "e+" | L 2 -> "mu-" | L (-2) -> "mu+" | L 3 -> "tau-" | L (-3) -> "tau+" | L _ -> invalid_arg "Modellib_BSM.HSExt.flavor_to_string: invalid lepton" | N 1 -> "nue" | N (-1) -> "nuebar" | N 2 -> "numu" | N (-2) -> "numubar" | N 3 -> "nutau" | N (-3) -> "nutaubar" | N _ -> invalid_arg "Modellib_BSM.HSExt.flavor_to_string: invalid neutrino" | U 1 -> "u" | U (-1) -> "ubar" | U 2 -> "c" | U (-2) -> "cbar" | U 3 -> "t" | U (-3) -> "tbar" | U _ -> invalid_arg "Modellib_BSM.HSExt.flavor_to_string: invalid up type quark" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | D _ -> invalid_arg "Modellib_BSM.HSExt.flavor_to_string: invalid down type quark" end | G f -> begin match f with | Gl -> "g" | Ga -> "A" | Z -> "Z" | Wp -> "W+" | Wm -> "W-" end | O f -> begin match f with | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | H -> "H" | S -> "S" end let flavor_to_TeX = function | M f -> begin match f with | L 1 -> "e^-" | L (-1) -> "e^+" | L 2 -> "\\mu^-" | L (-2) -> "\\mu^+" | L 3 -> "\\tau^-" | L (-3) -> "\\tau^+" | L _ -> invalid_arg "Modellib_BSM.HSExt.flavor_to_TeX: invalid lepton" | N 1 -> "\\nu_e" | N (-1) -> "\\bar{\\nu}_e" | N 2 -> "\\nu_\\mu" | N (-2) -> "\\bar{\\nu}_\\mu" | N 3 -> "\\nu_\\tau" | N (-3) -> "\\bar{\\nu}_\\tau" | N _ -> invalid_arg "Modellib_BSM.HSExt.flavor_to_TeX: invalid neutrino" | U 1 -> "u" | U (-1) -> "\\bar{u}" | U 2 -> "c" | U (-2) -> "\\bar{c}" | U 3 -> "t" | U (-3) -> "\\bar{t}" | U _ -> invalid_arg "Modellib_BSM.HSExt.flavor_to_TeX: invalid up type quark" | D 1 -> "d" | D (-1) -> "\\bar{d}" | D 2 -> "s" | D (-2) -> "\\bar{s}" | D 3 -> "b" | D (-3) -> "\\bar{b}" | D _ -> invalid_arg "Modellib_BSM.HSExt.flavor_to_TeX: invalid down type quark" end | G f -> begin match f with | Gl -> "g" | Ga -> "\\gamma" | Z -> "Z" | Wp -> "W^+" | Wm -> "W^-" end | O f -> begin match f with | Phip -> "\\phi^+" | Phim -> "\\phi^-" | Phi0 -> "\\phi^0" | H -> "H" | S -> "S" end let flavor_symbol = function | M f -> begin match f with | L n when n > 0 -> "l" ^ string_of_int n | L n -> "l" ^ string_of_int (abs n) ^ "b" | N n when n > 0 -> "n" ^ string_of_int n | N n -> "n" ^ string_of_int (abs n) ^ "b" | U n when n > 0 -> "u" ^ string_of_int n | U n -> "u" ^ string_of_int (abs n) ^ "b" | D n when n > 0 -> "d" ^ string_of_int n | D n -> "d" ^ string_of_int (abs n) ^ "b" end | G f -> begin match f with | Gl -> "gl" | Ga -> "a" | Z -> "z" | Wp -> "wp" | Wm -> "wm" end | O f -> begin match f with | Phip -> "pp" | Phim -> "pm" | Phi0 -> "p0" | H -> "h" | S -> "s" end let pdg = function | M f -> begin match f with | L n when n > 0 -> 9 + 2*n | L n -> - 9 + 2*n | N n when n > 0 -> 10 + 2*n | N n -> - 10 + 2*n | U n when n > 0 -> 2*n | U n -> 2*n | D n when n > 0 -> - 1 + 2*n | D n -> 1 + 2*n end | G f -> begin match f with | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) end | O f -> begin match f with | Phip | Phim -> 27 | Phi0 -> 26 | H -> 25 | S -> 35 end let mass_symbol f = "mass(" ^ string_of_int (abs (pdg f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg f)) ^ ")" let constant_symbol = function | Unit -> "unit" | Pi -> "PI" | Alpha_QED -> "alpha" | E -> "e" | G_weak -> "g" | Vev -> "vev" | Sin2thw -> "sin2thw" | Sinthw -> "sinthw" | Costhw -> "costhw" | Q_lepton -> "qlep" | Q_up -> "qup" | Q_down -> "qdwn" | G_NC_lepton -> "gnclep" | G_NC_neutrino -> "gncneu" | G_NC_up -> "gncup" | G_NC_down -> "gncdwn" | G_CC -> "gcc" | I_Q_W -> "iqw" | I_G_ZWW -> "igzww" | G_WWWW -> "gw4" | G_ZZWW -> "gzzww" | G_AZWW -> "gazww" | G_AAWW -> "gaaww" | G_HWW -> "ghww" | G_HZZ -> "ghzz" | G_HHWW -> "ghhww" | G_HHZZ -> "ghhzz" | G_SWW -> "gsww" | G_SZZ -> "gszz" | G_SSWW -> "gssww" | G_SSZZ -> "gsszz" | G_HSWW -> "ghsww" | G_HSZZ -> "ghszz" | G_Htt -> "ghtt" | G_Hbb -> "ghbb" | G_Htautau -> "ghtautau" | G_Hcc -> "ghcc" | G_Hmm -> "ghmm" | G_Stt -> "gstt" | G_Sbb -> "gsbb" | G_Stautau -> "gstautau" | G_Scc -> "gscc" | G_Smm -> "gsmm" | G_HGaZ -> "ghgaz" | G_HGaGa -> "ghgaga" | G_Hgg -> "ghgg" | G_SGaZ -> "gsgaz" | G_SGaGa -> "gsgaga" | G_Sgg -> "gsgg" | G_H3 -> "gh3" | G_H4_1 -> "gh4_1" | G_H4_2 -> "gh4_2" | G_H4_3 -> "gh4_3" | G_H4_4 -> "gh4_4" | G_H4_5 -> "gh4_5" | G_HHS -> "ghhs" | G_HSS -> "ghss" | Gs -> "gs" | I_Gs -> "igs" | G2 -> "gs**2" | Mass f -> "mass" ^ flavor_symbol f | Width f -> "width" ^ flavor_symbol f end (* \thocwmodulesection{Three-Site Higgsless Model} *) module type Threeshl_options = sig val include_ckm: bool val include_hf: bool val diet: bool end module Threeshl_no_ckm: Threeshl_options = struct let include_ckm = false let include_hf = true let diet = false end module Threeshl_ckm: Threeshl_options = struct let include_ckm = true let include_hf = true let diet = false end module Threeshl_no_ckm_no_hf: Threeshl_options = struct let include_ckm = false let include_hf = false let diet = false end module Threeshl_ckm_no_hf: Threeshl_options = struct let include_ckm = true let include_hf = false let diet = false end module Threeshl_diet_no_hf: Threeshl_options = struct let include_ckm = false let include_hf = false let diet = true end module Threeshl_diet: Threeshl_options = struct let include_ckm = false let include_hf = true let diet = true end (* We use one generic implementation of the model and implement different features via option modules given to a functor *) module Threeshl (Module_options: Threeshl_options) = struct open Coupling let modname = "Modellib_BSM.Threeshl" (* Shamelessly stolen from Modellib.SM3, but with no support for fudged width yet *) let default_width = ref Timelike (* If this flag is set true, all gauge bosons are assumed to be massless and are assigned feynman gauge propagators. This in conjunction with the unbroken three site model is intended for checking gauge invariance via the ward identites. *) let all_feynman = ref false let options = Options.create [ "constant_width", Arg.Unit (fun _ -> default_width := Constant), "use constant width (also in t-channel)"; "custom_width", Arg.String (fun x -> default_width := Custom x), "use custom width"; "cancel_widths", Arg.Unit (fun _ -> default_width := Vanishing), "use vanishing width"; "all_feynman", Arg.Unit (fun _ -> all_feynman := true), "assign feynman gauge propagators to all gauge bosons\n" ^ "\t(for checking the ward identities); use only if you *really* know\n" ^ "\twhat you are doing"] (* The quantum numbers that are carried by the particles. \verb$csign$ is \emph{not} the charge carried by the particle, but differentiates between particles (\verb$Pos$) and antiparticles (\verb$Neg$) *) type kkmode = Light | Heavy type generation = Gen0 | Gen1 | Gen2 type csign = Pos | Neg type isospin = Iso_up | Iso_down (* Necessary to represent the indices of the couplings defined in FORTRAN *) type kk2 = Light2 | Heavy2 | Light_Heavy (* Map the different types to the constants used in the FORTRAN module *) let fspec_of_kkmode = function Light -> "l_mode" | Heavy -> "h_mode" let fspec_of_kk2 = function Light2 -> "l_mode" | Heavy2 -> "h_mode" | Light_Heavy -> "lh_mode" let fspec_of_gen = function Gen0 -> "gen_0" | Gen1 -> "gen_1" | Gen2 -> "gen_2" let fspec_of_iso = function Iso_up -> "iso_up" | Iso_down -> "iso_down" (* Covert the ``charge sign'' into a numeric sign (used e.g. in the determination of the MCID codes) *) let int_of_csign = function Pos -> 1 | Neg -> -1 (* Convert the generation into an integer (dito) *) let int_of_gen = function Gen0 -> 1 | Gen1 -> 2 | Gen2 -> 3 (* The type \verb$flavor$ is implemented as a variant. Fermions are implemented as a variant differentating between leptons and quarks (seemed the most natural way as this is also the way in which the FORTRAN code is structured). Bosons are implemented as a variant the differentiates between $W$, $Z$ and $A$. All other quantum numbers that are required for identifying the particles are carried by the variant constructors. *) type fermion = | Lepton of (kkmode * csign * generation * isospin) | Quark of (kkmode * csign * generation * isospin) type boson = | W of (kkmode * csign) | Z of kkmode | A | G type flavor = Fermion of fermion | Boson of boson (* Helpers to construct particles from quantum numbers *) let lepton kk cs gen iso = Lepton (kk, cs, gen, iso) let quark kk cs gen iso = Quark (kk, cs, gen, iso) let w kk cs = W (kk, cs) let z kk = Z kk let flavor_of_f x = Fermion x let flavor_of_b x = Boson x (* Map a list of functions to the list (partially) applied to a value *) let revmap funs v = List.map (fun x -> x v) funs (* The same for a list of values; the result is flattened *) let revmap2 funs vals = ThoList.flatmap (revmap funs) vals (* Functions to loop the constructors over quantum numbers for list creation purposes *) let loop_kk flist = revmap2 flist [Light; Heavy] let loop_cs flist = revmap2 flist [Pos; Neg] let loop_gen flist = revmap2 flist [Gen0; Gen1; Gen2] let loop_iso flist = revmap2 flist [Iso_up; Iso_down] let loop_kk2 flist = revmap2 flist [Light2; Heavy2; Light_Heavy] (* Conditional looping over kk modes depending on whether to include heavy fermions *) let cloop_kk flist = match Module_options.include_hf with | true -> loop_kk flist | false -> revmap flist Light let cloop_kk2 flist = match Module_options.include_hf with | true -> loop_kk2 flist | false -> revmap flist Light2 (* Having defined the necessary helpers, the magic of currying makes building lists of particles as easy as nesting the loop functions in the correct order... *) let all_leptons = loop_iso (loop_gen (loop_cs (cloop_kk [lepton] ))) let all_quarks = loop_iso( loop_gen (loop_cs (cloop_kk [quark] ))) let all_bosons = (loop_cs (loop_kk [w] )) @ [Z Light; Z Heavy; A; G] (* Converts a flavor spec to the BCD identifier defined in the FORTRAN module. Splitting the function into two parts \verb$prefix$ and \verb$rump$ removes a lot of redundancy. *) let bcdi_of_flavor = let prefix = function | Fermion (Lepton (Heavy, _, _, _)) | Fermion (Quark (Heavy, _, _, _)) | Boson (W (Heavy, _)) | Boson (Z Heavy) -> "h" | _ -> "" in let rump = function | Fermion (Lepton spec) -> (match spec with | (_, _, Gen0, Iso_up) -> "nue" | (_, _, Gen0, Iso_down) -> "e" | (_, _, Gen1, Iso_up) -> "numu" | (_, _, Gen1, Iso_down) -> "mu" | (_, _, Gen2, Iso_up) -> "nutau" | (_, _, Gen2, Iso_down) -> "tau") | Fermion (Quark spec) -> (match spec with | (_, _, Gen0, Iso_up) -> "u" | (_, _, Gen0, Iso_down) -> "d" | (_, _, Gen1, Iso_up) -> "c" | (_, _, Gen1, Iso_down) -> "s" | (_, _, Gen2, Iso_up) -> "t" | (_, _, Gen2, Iso_down) -> "b") | Boson (W _) -> "w" | Boson (Z _) -> "z" | Boson A -> invalid_arg (modname ^ ".bcd_of_flavor: no bcd for photon!") | Boson G -> invalid_arg (modname ^ ".bcd_of_flavor: no bcd for gluon!") in function x -> (prefix x) ^ (rump x) ^ "_bcd" (* The function defined in the model signature which returns the colour representation of a particle *) let color = let quarkrep = function | (_, Pos, _, _) -> Color.SUN 3 | (_, Neg, _, _) -> Color.SUN (-3) in function | Fermion (Quark x) -> quarkrep x | Boson G -> Color.AdjSUN 3 | _ -> Color.Singlet let nc () = 3 (* Function for calculating the MCID code of a particle. Convenctions have been choosen such that the heavy modes are identified by the same numbers as the light ones, prefixed with \verb$99$. This is supposedly in accord with the conventions for adding new particles to the list of MCID codes. This function is required by the signature. *) let pdg = let iso_delta = function Iso_down -> 0 | Iso_up -> 1 in let gen_delta = function Gen0 -> 0 | Gen1 -> 2 | Gen2 -> 4 in let kk_delta = function Light -> 0 | Heavy -> 9900 in function | Fermion ( Lepton (kk, cs, gen, iso)) -> (int_of_csign cs) * (11 + (gen_delta gen) + (iso_delta iso) + (kk_delta kk)) | Fermion ( Quark (kk, cs, gen, iso)) -> (int_of_csign cs) * (1 + (gen_delta gen) + (iso_delta iso)+ (kk_delta kk)) | Boson (W (kk, cs)) -> (int_of_csign cs) * (24 + (kk_delta kk)) | Boson (Z kk) -> 23 + (kk_delta kk) | Boson A -> 22 | Boson G -> 21 (* Returns the lorentz representation of a particle; required by the signature. *) let lorentz = let spinor = function | (_, Pos, _, _) -> Spinor | (_, Neg, _, _) -> ConjSpinor in function | Fermion (Lepton x) | Fermion (Quark x) -> spinor x | Boson (W _) | Boson (Z _) -> Massive_Vector | Boson A -> Vector | Boson G -> Vector (* O'Mega supports models that allow different gauges; however, we only implement unitary gauge and therefore stub this (SM3 does the same thing). The \verb$gauge$ type as well as \verb$gauge_symbol$ are required by the signature. *) type gauge = unit let gauge_symbol () = failwith (modname ^ ".gauge_symbol: internal error") (* Returns the propagator for a given particle type. Required by signature. *) let propagator = let spinorprop = function | (_, Pos, _, _) -> Prop_Spinor | (_, Neg, _, _) -> Prop_ConjSpinor in function | Fermion (Lepton x) | Fermion (Quark x) -> spinorprop x | Boson (W _) | Boson (Z _) -> (match !all_feynman with false -> Prop_Unitarity | true -> Prop_Feynman) | Boson A -> Prop_Feynman | Boson G -> Prop_Feynman (* Return the width of a particle, required by signature. \\ \emph{TODO:} Refine such that stable particles always are treade via vanishing width, as this might speed up the generated code a bit. *) let width _ = !default_width (* Returns the conjugate particle; required by signature. *) let conjugate = let conj_csign = function | Pos -> Neg | Neg -> Pos in function | Fermion (Lepton (kk, cs, gen, iso)) -> Fermion (Lepton (kk, conj_csign cs, gen, iso)) | Fermion (Quark (kk, cs, gen, iso)) -> Fermion (Quark (kk, conj_csign cs, gen, iso)) | Boson (W (kk, cs)) -> Boson (W (kk, conj_csign cs)) | x -> x (* Tells the diagram generator whether a particle is a fermion, a conjugate fermion or a boson. Required by signature *) let fermion = function | Fermion (Lepton (_, cs, _, _)) | Fermion (Quark (_, cs, _, _)) -> int_of_csign cs | Boson _ -> 0 (* Charges are: charge, lepton number, baryon number, generation. Required by signature *) module Ch = Charges.QQ let ( // ) = Algebra.Small_Rational.make let qn_charge = function | Boson b -> (match b with | W (_, c) -> (int_of_csign (c)) // 1 | _ -> 0//1) | Fermion f -> (match f with | Lepton (_, c, _, Iso_up) -> 0//1 | Lepton (_, c, _, Iso_down) -> (-1 * int_of_csign (c)) // 1 | Quark (_, c, _, Iso_up) -> (2 * int_of_csign (c)) // 3 | Quark (_, c, _, Iso_down) -> (-1 * int_of_csign (c)) // 3) let qn_lepton = function | Fermion (Lepton (_, c, _, _)) -> int_of_csign (c) // 1 | _ -> 0//1 let qn_baryon = function | Fermion (Quark (_, c, _, _)) -> int_of_csign (c) // 1 | _ -> 0//1 (* Generation is conditional: if we enable the nontrivial CKM matrix, all particles carry generation [0; 0; 0] *) let qn_generation x = let qn cs gen = let c = int_of_csign (cs) in match gen with | Gen0 -> [c//1; 0//1; 0//1] | Gen1 -> [0//1; c//1; 0//1] | Gen2 -> [0//1; 0//1; c//1] in if Module_options.include_ckm then [0//1; 0//1; 0//1] else match x with | Fermion (Lepton (_, c, g, _)) -> qn c g | Fermion (Quark (_, c, g, _)) -> qn c g | _ -> [0//1; 0//1; 0//1] let charges x = [qn_charge x; qn_lepton x; qn_baryon x] @ (qn_generation x) (* A variant to represent the different coupling constants, choosen to mimic the FORTRAN part. Required by signature. *) type constant = | G_a_lep | G_a_quark of isospin | G_aww | G_aaww | G_w_lep of (kkmode * kkmode * generation * kkmode * generation) | G_w_quark of (kkmode * kkmode * generation * kkmode * generation) | G_z_lep of (kkmode * kk2 * generation * isospin) | G_z_quark of (kkmode * kk2 * generation * isospin) | G_wwz of (kk2 * kkmode) | G_wwzz of (kk2 * kk2) | G_wwza of (kk2 * kkmode) | G_wwww of int | G_s | IG_s | G_s2 (* Two integer counters for the QCD and EW order of the couplings. *) type orders = int * int let orders = function | _ -> (0,0) (* Functions for the construction of constants from indices *) let g_a_quark x = G_a_quark x let g_w_lep kk1 kk2 gen1 kk3 gen2 = G_w_lep (kk1, kk2, gen1, kk3, gen2) let g_w_quark kk1 kk2 gen1 kk3 gen2 = G_w_quark (kk1, kk2, gen1, kk3, gen2) let g_z_lep kk1 kk2 gen iso = G_z_lep (kk1, kk2, gen, iso) let g_z_quark kk1 kk2 gen iso = G_z_quark (kk1, kk2, gen, iso) let g_wwz kk1 kk2 = G_wwz (kk1, kk2) let g_wwzz kk1 kk2 = G_wwzz (kk1, kk2) let g_wwza kk1 kk2 = G_wwza (kk1, kk2) let g_wwww nhw = if (nhw >= 0) && (nhw <= 4) then G_wwww nhw else failwith (modname ^ ".g_wwww: invalid integer, very bad") (* Build a list of the different constants *) let clist = [G_a_lep; G_aww; G_aaww] @ (loop_iso [g_a_quark]) @ (loop_gen (cloop_kk (loop_gen (cloop_kk (loop_kk [g_w_lep] ))))) @ (loop_gen (cloop_kk (loop_gen (cloop_kk (loop_kk [g_w_quark] ))))) @ (loop_iso (loop_gen (cloop_kk2 (loop_kk [g_z_lep] )))) @ (loop_iso (loop_gen (cloop_kk2 (loop_kk [g_z_quark] )))) @ (loop_kk (loop_kk2 [g_wwz] )) @ (loop_kk2 (loop_kk2 [g_wwzz] )) @ (loop_kk (loop_kk2 [g_wwza] )) @ (List.map g_wwww [0; 1; 2; 3; 4]) (* Maximum number of lines meeting at a vertex, required by signature. *) let max_degree () = 4 (* Transform a pair of kk identifiers into a kk2 identifier *) let get_kk2 = function (Light, Light) -> Light2 | (Heavy, Heavy) -> Heavy2 | (Light, Heavy) | (Heavy, Light) -> Light_Heavy (* Flip isospin *) let conj_iso = function Iso_up -> Iso_down | Iso_down -> Iso_up (* Below, lists of couplings are generated which ultimately are joined into a list of all couplings in the model. The generated lists can be viewed using the \verb$dump.ml$ script in the O'Mega toplevel directory. \\ The individual couplings are defined as 5-tupels resp. 6-tupels consisting in this order of the particles meeting at the vertex, the coupling type (see \verb$couplings.ml$) and the coupling constant. *) (* List of $llA$ type vertices *) let vertices_all = let vgen kk gen = ((Fermion (Lepton (kk, Neg, gen, Iso_down)), Boson A, Fermion (Lepton (kk, Pos, gen, Iso_down))), FBF(1, Psibar, V, Psi), G_a_lep) in loop_gen (cloop_kk [vgen]) (* List of $qqA$ type vertices *) let vertices_aqq = let vgen kk gen iso = ((Fermion (Quark (kk, Neg, gen, iso)), Boson A, Fermion (Quark (kk, Pos, gen, iso))), FBF(1, Psibar, V, Psi), G_a_quark iso) in loop_iso (loop_gen (cloop_kk [vgen])) (* List of $\nu lW$ type vertices *) let vertices_wll = let vgen kkw kk_f kk_fbar iso_f gen = ((Fermion (Lepton (kk_fbar, Neg, gen, conj_iso iso_f)), Boson (W (kkw, (match iso_f with Iso_up -> Neg | _ -> Pos))), Fermion (Lepton (kk_f, Pos, gen, iso_f))), FBF (1, Psibar, VA2, Psi), G_w_lep (kkw, (match iso_f with Iso_up -> kk_f | _ -> kk_fbar), gen, (match iso_f with Iso_up -> kk_fbar | _ -> kk_f), gen) ) in loop_gen (loop_iso (cloop_kk (cloop_kk (loop_kk [vgen] )))) (* The same list, but without couplings between the $W^\prime$ and light fermions *) let vertices_wll_diet = let filter = function | ((Fermion (Lepton (Light, _, _, _)), Boson (W (Heavy, _)), Fermion (Lepton (Light, _, _, _))), _, _) -> false | _ -> true in List.filter filter vertices_wll (* List of $udW$ type vertices, flavor-diagonal *) let vertices_wqq_no_ckm = let vgen kkw kk_f kk_fbar iso_f gen = ((Fermion (Quark (kk_fbar, Neg, gen, conj_iso iso_f)), Boson (W (kkw, (match iso_f with Iso_up -> Neg | _ -> Pos))), Fermion (Quark (kk_f, Pos, gen, iso_f))), FBF (1, Psibar, VA2, Psi), G_w_quark (kkw, (match iso_f with Iso_up -> kk_f | _ -> kk_fbar), gen, (match iso_f with Iso_up -> kk_fbar | _ -> kk_f), gen) ) in loop_gen (loop_iso (cloop_kk (cloop_kk (loop_kk [vgen] )))) (* The same list, but without couplings between the $W^\prime$ and the first two generations of quarks *) let vertices_wqq_no_ckm_diet = let filter = function | ((Fermion (Quark (Light, _, gen, _)), Boson (W (Heavy, _)), Fermion (Quark (Light, _, _, _))), _, _) -> (match gen with Gen2 -> true | _ -> false) | _ -> true in List.filter filter vertices_wqq_no_ckm (* List of $udW$ type vertices, including non flavor-diagonal couplings *) let vertices_wqq = let vgen kkw kk_f gen_f kk_fbar gen_fbar iso_f = ((Fermion (Quark (kk_fbar, Neg, gen_fbar, conj_iso iso_f)), Boson (W (kkw, (match iso_f with Iso_up -> Neg | _ -> Pos))), Fermion (Quark (kk_f, Pos, gen_f, iso_f))), FBF (1, Psibar, VA2, Psi), G_w_quark (match iso_f with | Iso_up -> (kkw, kk_f, gen_f, kk_fbar, gen_fbar) | Iso_down -> (kkw, kk_fbar, gen_fbar, kk_f, gen_f))) in loop_iso (loop_gen (cloop_kk (loop_gen (cloop_kk (loop_kk [vgen] ))))) (* List of $llZ$ / $\nu\nu Z$ type vertices *) let vertices_zll = let vgen kkz kk_f kk_fbar gen iso = ((Fermion (Lepton (kk_fbar, Neg, gen, iso)), Boson (Z kkz), Fermion (Lepton (kk_f, Pos, gen, iso))), FBF (1, Psibar, VA2, Psi), G_z_lep (kkz, get_kk2 (kk_f, kk_fbar), gen, iso)) in loop_iso (loop_gen (cloop_kk (cloop_kk (loop_kk [vgen] )))) (* List of $qqZ$ type vertices *) let vertices_zqq = let vgen kkz kk_f kk_fbar gen iso = ((Fermion (Quark (kk_fbar, Neg, gen, iso)), Boson (Z kkz), Fermion (Quark (kk_f, Pos, gen, iso))), FBF (1, Psibar, VA2, Psi), G_z_quark (kkz, get_kk2 (kk_f, kk_fbar), gen, iso)) in loop_iso (loop_gen (cloop_kk (cloop_kk (loop_kk [vgen] )))) (* $gq\bar{q}$ *) let vertices_gqq = let vgen kk gen iso = ((Fermion (Quark (kk, Neg, gen, iso)), Boson G, Fermion (Quark (kk, Pos, gen, iso))), FBF (1, Psibar, V, Psi), G_s) in loop_iso (loop_gen (cloop_kk [vgen])) (* AWW *) let vertices_aww = let vgen kk = ( (Boson A, Boson (W (kk, Pos)), Boson (W (kk, Neg))), Gauge_Gauge_Gauge 1, G_aww) in loop_kk [vgen] (* ZWW *) let vertices_zww = let vgen kkz kkwp kkwm = ((Boson (Z kkz), Boson (W (kkwp, Pos)), Boson (W (kkwm, Neg))), Gauge_Gauge_Gauge 1, G_wwz (get_kk2 (kkwp, kkwm), kkz)) in loop_kk (loop_kk (loop_kk [vgen])) (* $ggg$ *) let vertices_ggg = [(Boson G, Boson G, Boson G), Gauge_Gauge_Gauge (-1), IG_s] (* Stolen from Modellib.SM; the signs seem to be OK. See \verb$couplings.ml$ for more docs. *) let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] (* AAWW *) let vertices_aaww = let vgen kk = ((Boson A, Boson (W (kk, Pos)), Boson A, Boson (W (kk, Neg))), minus_gauge4, G_aaww) in loop_kk [vgen] (* WWZZ *) let vertices_wwzz = let vgen kkwp kkwm kk2z = ((Boson (Z (match kk2z with Heavy2 -> Heavy | Light2 | Light_Heavy -> Light)), Boson (W (kkwp, Pos)), Boson (Z (match kk2z with Heavy2 | Light_Heavy -> Heavy | Light2 -> Light)), Boson (W (kkwm, Neg))), minus_gauge4, G_wwzz (get_kk2 (kkwp, kkwm), kk2z)) in loop_kk2 (loop_kk (loop_kk [vgen])) (* WWZA *) let vertices_wwza = let vgen kkwp kkwm kkz = ((Boson A, Boson (W (kkwp, Pos)), Boson (Z kkz), Boson (W (kkwm, Neg))), minus_gauge4, G_wwza (get_kk2 (kkwp, kkwm), kkz)) in loop_kk (loop_kk (loop_kk [vgen])) (* WWWW *) let vertices_wwww = let count = function Light2 -> 0 | Light_Heavy -> 1 | Heavy2 -> 2 in let vgen kk2wp kk2wm = ((Boson (W ((match kk2wp with Heavy2 -> Heavy | Light2 | Light_Heavy -> Light), Pos)), Boson (W ((match kk2wm with Heavy2 -> Heavy | Light2 | Light_Heavy -> Light), Neg)), Boson (W ((match kk2wp with Heavy2 | Light_Heavy -> Heavy | Light2 -> Light), Pos)), Boson (W ((match kk2wm with Heavy2 | Light_Heavy -> Heavy | Light2 -> Light), Neg))), gauge4, G_wwww ((count kk2wp) + (count kk2wm))) in loop_kk2 (loop_kk2 [vgen]) (* gggg *) let vertices_gggg = [(Boson G, Boson G, Boson G, Boson G), gauge4, G_s2] (* The list of couplings is transformed into the fusion lists required by the generator by the Model.Fusions functor. *) (* This is copy\& paste from the other models; check again with Thorsten if it is correct *) module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end ) (* Not sure yet whether F.fusex also creates the conjugate vertices; by looking at the implementation of the other models, I assume it doesn't. Still, better ask Thorsten to be sure!!!\\ \emph{Update:} Still didn't get to ask, but since the results are consistent, I suspect my assertion is correct. \\ The stuff below is required by the signature. *) let vertices () = (vertices_all @ vertices_aqq @ (match Module_options.diet with | false -> vertices_wll | true -> vertices_wll_diet) @ (match (Module_options.include_ckm, Module_options.diet) with | (true, false) -> vertices_wqq | (false, false) -> vertices_wqq_no_ckm | (false, true) -> vertices_wqq_no_ckm_diet | (true, true) -> raise (Failure ("Modules4.Threeshl.vertices: CKM matrix together with option diet is not" ^ " implemented yet!"))) @ vertices_zll @ vertices_zqq @ vertices_aww @ vertices_zww @ vertices_gqq @ vertices_ggg, vertices_aaww @ vertices_wwzz @ vertices_wwza @ vertices_wwww @ vertices_gggg , []) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table (* A function that returns a list of a flavours known to the model, required by the signature. *) let flavors () = (List.map flavor_of_f (all_leptons @ all_quarks)) @ (List.map flavor_of_b all_bosons) (* dito, external flavours, also required. *) let external_flavors () = [ "light leptons", List.map flavor_of_f (loop_iso (loop_gen( loop_cs [lepton Light]))); "light quarks", List.map flavor_of_f (loop_iso (loop_gen( loop_cs [quark Light]))); "light gauge bosons", List.map flavor_of_b [W (Light, Pos); W (Light, Neg); Z Light; A]; "heavy gauge bosons", List.map flavor_of_b [W (Heavy, Pos); W (Heavy, Neg); Z Heavy]] @ (match Module_options.include_hf with | true -> [ "heavy leptons", List.map flavor_of_f (loop_iso (loop_gen( loop_cs [lepton Heavy]))); "heavy quarks", List.map flavor_of_f (loop_iso (loop_gen( loop_cs [quark Heavy])))] | false -> [] ) @ ["gluons", [Boson G]] (* Which of the particles are goldstones? $\rightarrow$ none. Required by the signature. *) let goldstone x = None (* This is wrong but handy for debugging the constant identifier generation via -params. Usually, this function would return a record consisting of the parameters as well as expression for the dependent quantities that can be used to generate FORTRAN code for calculating them. However, we have a seperate module for the threeshl, so we can abuse this for debugging. Required by signature. *) let parameters () = {input = List.map (fun x -> (x, 0.)) clist; derived = []; derived_arrays = []} (* Convert a flavour into a ID string with which it will be referred by the user interface of the compiled generator. Required by signature *) let flavor_to_string = let prefix = function | Fermion (Lepton (Heavy, _, _, _)) | Fermion (Quark (Heavy, _, _, _)) | Boson (W (Heavy, _)) | Boson (Z Heavy) -> "H" | _ -> "" in let postfix = function | Fermion (Lepton (_, cs, _, Iso_down)) -> (match cs with Pos -> "-" | Neg -> "+") | Fermion (Quark (_, Neg, _, _)) | Fermion (Lepton (_, Neg, _, Iso_up)) -> "bar" | Boson (W (_, cs)) -> (match cs with Pos -> "+" | Neg -> "-") | _ -> "" in let rump = function | Fermion (Lepton desc) -> (match desc with | (_, _, Gen0, Iso_up) -> "nue" | (_, _, Gen0, Iso_down) -> "e" | (_, _, Gen1, Iso_up) -> "numu" | (_, _, Gen1, Iso_down) -> "mu" | (_, _, Gen2, Iso_up) -> "nutau" | (_, _, Gen2, Iso_down) -> "tau") | Fermion (Quark desc) -> (match desc with | (_, _, Gen0, Iso_up) -> "u" | (_, _, Gen0, Iso_down) -> "d" | (_, _, Gen1, Iso_up) -> "c" | (_, _, Gen1, Iso_down) -> "s" | (_, _, Gen2, Iso_up) -> "t" | (_, _, Gen2, Iso_down) -> "b") | Boson (W _) -> "W" | Boson (Z _) -> "Z" | Boson A -> "A" | Boson G -> "gl" in function x -> (prefix x) ^ (rump x) ^ (postfix x) (* Conversion of the ID string into a particle flavor. Instead of going through all cases again, we generate a ``dictionary'' of flavor / ID pairs which we use to identify the correct flavor. Required by signature. *) let flavor_of_string x = let dict = List.map (fun x -> (x, flavor_to_string x)) (flavors ()) in let get_ident = function (x, _) -> x in try get_ident (List.find (fun (_, y) -> (x = y)) dict) with Not_found -> (match x with | "g" -> Boson G | _ -> invalid_arg (modname ^ ".flavor_of_string") ) (* Converts a flavor into a symbol used as identification in the generated FORTRAN code (has to comply to the conventions of valid FORTRAN identifiers therefore). We stick to the same convenctions as SM3, prefixing heavy modes with a \verb$H$. Required by signature. *) let flavor_symbol = let prefix = function | Fermion (Lepton (Heavy, _, _, _)) | Fermion (Quark (Heavy, _, _, _)) | Boson (W (Heavy, _)) | Boson (Z Heavy) -> "H" | _ -> "" in let postfix = function | Fermion (Lepton (_, Neg, _, _)) | Fermion (Quark (_, Neg, _, _)) -> "b" | _ -> "" in let rump = function | Fermion spec -> (match spec with | Lepton (_, _, gen, Iso_up) -> "n" ^ (string_of_int (int_of_gen gen)) | Lepton (_, _, gen, Iso_down) -> "l" ^ (string_of_int (int_of_gen gen)) | Quark (_, _, gen, Iso_up) -> "u" ^ (string_of_int (int_of_gen gen)) | Quark (_, _, gen, Iso_down) -> "d"^ (string_of_int (int_of_gen gen))) | Boson spec -> (match spec with | W (_, Pos) -> "wp" | W (_, Neg) -> "wm" | Z _ -> "z" | A -> "a" | G -> "gl" ) in function x -> (prefix x) ^ (rump x) ^ (postfix x) (* Generate TeX for a flavor *) let flavor_to_TeX = let bar x y = match x with Neg -> "\\overline{" ^ y ^ "}" | Pos -> y in let pm x y = match x with Neg -> "{" ^ y ^ "}^+" | Pos -> "{" ^ y ^ "}^-" in let prime x y = match x with Light -> y | Heavy -> "{" ^ y ^ "}^\\prime" in function | Fermion (Lepton desc) -> (match desc with | (kk, cs, gen, Iso_up) -> prime kk (bar cs (match gen with | Gen0 -> "\\nu_e" | Gen1 -> "\\nu_\\mu" | Gen2 -> "\\nu_\\tau")) | (kk, cs, gen, Iso_down) -> prime kk (pm cs (match gen with | Gen0 -> "e" | Gen1 -> "\\mu" | Gen2 -> "\\tau"))) | Fermion (Quark (kk, cs, gen, iso)) -> prime kk (bar cs (match (gen, iso) with | (Gen0, Iso_up) -> "u" | (Gen0, Iso_down) -> "d" | (Gen1, Iso_up) -> "c" | (Gen1, Iso_down) -> "s" | (Gen2, Iso_up) -> "t" | (Gen2, Iso_down) -> "b")) | Boson spec -> (match spec with | W (kk, cs) -> prime kk (pm (match cs with Pos -> Neg | Neg -> Pos) "W") | Z kk -> prime kk "Z" | A -> "A" | G -> "g") (* Returns the string referring to the particle mass in the generated FORTRAN code. Required by signature. *) let mass_symbol = function | Boson A | Boson G-> "0._default" | x -> "mass_array(" ^ (bcdi_of_flavor x) ^ ")" (* Dito, for width. Required by signature. *) let width_symbol = function | Boson A | Boson G -> "0._default" | x -> "width_array(" ^ (bcdi_of_flavor x) ^ ")" (* Determines the string referring to a coupling constant in the generated FORTRAN code. Required by signature. *) let constant_symbol = let c = ", " in let g_w_ferm = function (kk1, kk2, gen1, kk3, gen2) -> ":, " ^ (fspec_of_kkmode kk1) ^ c ^ (fspec_of_kkmode kk2) ^ c ^ (fspec_of_gen gen1) ^ c ^ (fspec_of_kkmode kk3) ^ c ^ (fspec_of_gen gen2) in let g_z_ferm = function (kk1, kk2, gen, iso) -> ":, " ^ (fspec_of_kkmode kk1) ^ c ^ (fspec_of_kk2 kk2) ^ c ^ (fspec_of_gen gen) ^ c ^ (fspec_of_iso iso) in function | G_a_lep -> "g_a_lep" | G_s -> "g_s_norm" | IG_s -> "ig_s_norm" | G_s2 -> "g_s_norm2" | G_a_quark iso -> "g_a_quark(" ^ (fspec_of_iso iso) ^ ")" | G_aww -> "ig_aww" | G_aaww -> "g_aaww" | G_w_lep spec -> "g_w_lep_va(" ^ (g_w_ferm spec) ^ ")" | G_w_quark spec -> "g_w_quark_va(" ^ (g_w_ferm spec) ^ ")" | G_z_lep spec -> "g_z_lep_va(" ^ (g_z_ferm spec) ^ ")" | G_z_quark spec -> "g_z_quark_va(" ^ (g_z_ferm spec) ^ ")" | G_wwz (kk1, kk2) -> "ig_wwz(" ^ (fspec_of_kk2 kk1) ^ c ^ (fspec_of_kkmode kk2) ^ ")" | G_wwzz (kk1, kk2) -> "g_wwzz(" ^ (fspec_of_kk2 kk1) ^ c ^ (fspec_of_kk2 kk2) ^ ")" | G_wwza (kk1, kk2) -> "g_wwza(" ^(fspec_of_kk2 kk1) ^ c ^ (fspec_of_kkmode kk2) ^ ")" | G_wwww nhw -> if (0 <= nhw) && (nhw <= 4) then "g_wwww(" ^ (string_of_int nhw) ^ ")" else failwith "Modules4.Threeshl.constant_symbol: invalid int for G_wwww; very bad" end (* \thocwmodulesection{THDM with and without non-trivial flavor structure} *) module type THDM_flags = sig val ckm_present : bool end module THDM : THDM_flags = struct let ckm_present = false end module THDM_CKM : THDM_flags = struct let ckm_present = true end module TwoHiggsDoublet (Flags : THDM_flags) = struct open Coupling let default_width = ref Timelike let use_fudged_width = ref false let options = Options.create [ "constant_width", Arg.Unit (fun () -> default_width := Constant), "use constant width (also in t-channel)"; "fudged_width", Arg.Set use_fudged_width, "use fudge factor for charge particle width"; "custom_width", Arg.String (fun f -> default_width := Custom f), "use custom width"; "cancel_widths", Arg.Unit (fun () -> default_width := Vanishing), "use vanishing width"; "cms_width", Arg.Unit (fun () -> default_width := Complex_Mass), - "use complex mass scheme"] + "use complex mass scheme"; + "running_width", Arg.Unit (fun () -> default_width := Running), + "use running width"] type matter_field = L of int | N of int | U of int | D of int type gauge_boson = Ga | Wp | Wm | Z | Gl type other = Phip | Phim | Phi0 | Hh | HA | HH | Hp | Hm type flavor = M of matter_field | G of gauge_boson | O of other let matter_field f = M f let gauge_boson f = G f let other f = O f type field = | Matter of matter_field | Gauge of gauge_boson | Other of other let field = function | M f -> Matter f | G f -> Gauge f | O f -> Other f type gauge = unit let gauge_symbol () = failwith "Modellib_BSM.TwoHiggsDoublet.gauge_symbol: internal error" let family n = List.map matter_field [ L n; N n; U n; D n ] let external_flavors () = [ "1st Generation", ThoList.flatmap family [1; -1]; "2nd Generation", ThoList.flatmap family [2; -2]; "3rd Generation", ThoList.flatmap family [3; -3]; "Gauge Bosons", List.map gauge_boson [Ga; Z; Wp; Wm; Gl]; "Higgs", List.map other [Hh; HH; HA; Hp; Hm]; "Goldstone Bosons", List.map other [Phip; Phim; Phi0] ] let flavors () = ThoList.flatmap snd (external_flavors ()) let spinor n = if n >= 0 then Spinor else ConjSpinor let lorentz = function | M f -> begin match f with | L n -> spinor n | N n -> spinor n | U n -> spinor n | D n -> spinor n end | G f -> begin match f with | Ga | Gl -> Vector | Wp | Wm | Z -> Massive_Vector end | O f -> Scalar let color = function | M (U n) -> Color.SUN (if n > 0 then 3 else -3) | M (D n) -> Color.SUN (if n > 0 then 3 else -3) | G Gl -> Color.AdjSUN 3 | _ -> Color.Singlet let nc () = 3 let prop_spinor n = if n >= 0 then Prop_Spinor else Prop_ConjSpinor let propagator = function | M f -> begin match f with | L n -> prop_spinor n | N n -> prop_spinor n | U n -> prop_spinor n | D n -> prop_spinor n end | G f -> begin match f with | Ga | Gl -> Prop_Feynman | Wp | Wm | Z -> Prop_Unitarity end | O f -> begin match f with | Phip | Phim | Phi0 -> Only_Insertion | Hh | HH | HA | Hp | Hm -> Prop_Scalar end (* Optionally, ask for the fudge factor treatment for the widths of charged particles. Currently, this only applies to $W^\pm$ and top. *) let width f = if !use_fudged_width then match f with | G Wp | G Wm | M (U 3) | M (U (-3)) -> Fudged | _ -> !default_width else !default_width let goldstone = function | G f -> begin match f with | Wp -> Some (O Phip, Coupling.Integer 1) | Wm -> Some (O Phim, Coupling.Integer 1) | Z -> Some (O Phi0, Coupling.Integer 1) | _ -> None end | _ -> None let conjugate = function | M f -> M (begin match f with | L n -> L (-n) | N n -> N (-n) | U n -> U (-n) | D n -> D (-n) end) | G f -> G (begin match f with | Gl -> Gl | Ga -> Ga | Z -> Z | Wp -> Wm | Wm -> Wp end) | O f -> O (begin match f with | Phip -> Phim | Phim -> Phip | Phi0 -> Phi0 | Hh -> Hh | HH -> HH | HA -> HA | Hp -> Hm | Hm -> Hp end) let fermion = function | M f -> begin match f with | L n -> if n > 0 then 1 else -1 | N n -> if n > 0 then 1 else -1 | U n -> if n > 0 then 1 else -1 | D n -> if n > 0 then 1 else -1 end | G f -> begin match f with | Gl | Ga | Z | Wp | Wm -> 0 end | O _ -> 0 (* Electrical charge, lepton number, baryon number. We could avoid the rationals altogether by multiplying the first and last by 3 \ldots *) module Ch = Charges.QQ let ( // ) = Algebra.Small_Rational.make let generation' = function | 1 -> [ 1//1; 0//1; 0//1] | 2 -> [ 0//1; 1//1; 0//1] | 3 -> [ 0//1; 0//1; 1//1] | -1 -> [-1//1; 0//1; 0//1] | -2 -> [ 0//1; -1//1; 0//1] | -3 -> [ 0//1; 0//1; -1//1] | n -> invalid_arg ("Modellib_BSM.TwoHiggsDoublet.generation': " ^ string_of_int n) let generation f = if Flags.ckm_present then [] else match f with | M (L n | N n | U n | D n) -> generation' n | G _ | O _ -> [ 0//1; 0//1; 0//1] let charge = function | M f -> begin match f with | L n -> if n > 0 then -1//1 else 1//1 | N n -> 0//1 | U n -> if n > 0 then 2//3 else -2//3 | D n -> if n > 0 then -1//3 else 1//3 end | G f -> begin match f with | Gl | Ga | Z -> 0//1 | Wp -> 1//1 | Wm -> -1//1 end | O f -> begin match f with | Hh | HH | HA | Phi0 -> 0//1 | Hp | Phip -> 1//1 | Hm | Phim -> -1//1 end let lepton = function | M f -> begin match f with | L n | N n -> if n > 0 then 1//1 else -1//1 | U _ | D _ -> 0//1 end | G _ | O _ -> 0//1 let baryon = function | M f -> begin match f with | L _ | N _ -> 0//1 | U n | D n -> if n > 0 then 1//1 else -1//1 end | G _ | O _ -> 0//1 let charges f = [ charge f; lepton f; baryon f] @ generation f type constant = | Unit | Pi | Alpha_QED | Sin2thw | Sinthw | Costhw | E | G_weak | Vev | Q_lepton | Q_up | Q_down | G_CC | G_NC_neutrino | G_NC_lepton | G_NC_up | G_NC_down | I_Q_W | I_G_ZWW | I_G_WWW | G_WWWW | G_ZZWW | G_AZWW | G_AAWW | G_htt | G_hbb | G_hcc | G_htautau | G_hmumu | G_Htt | G_Hbb | G_Hcc | G_Htautau | G_Hmumu | I_G_Att | I_G_Abb | I_G_Acc | I_G_Atautau | I_G_Amumu | G_Htb | G_Hcs | G_Htaunu | G_Hmunu | Gs | I_Gs | G2 | G_AHpHm | G_ZHpHm | G_Zh1h2 | G_Zh1h3 | G_Zh2h3 | G_WpHmh1 | G_WpHmh2 | G_WpHmh3 | G_WmHph1 | G_WmHph2 | G_WmHph3 | G_h1ZZ | G_h2ZZ | G_h3ZZ | G_h1WpWm | G_h2WpWm | G_h3WpWm | G_hhWpWm | G_hhZZ | G_HpHmAA | G_HpHmZZ | G_HpHmAZ | G_HpHmWpWm | G_h1HpAWm | G_h2HpAWm | G_h3HpAWm | G_h1HpZWm | G_h2HpZWm | G_h3HpZWm | G_h1HpAWmC | G_h2HpAWmC | G_h3HpAWmC | G_h1HpZWmC | G_h2HpZWmC | G_h3HpZWmC | G_h1HpHm | G_h2HpHm | G_h3HpHm | G_h111 | G_h112 | G_h113 | G_h221 | G_h222 | G_h223 | G_h331 | G_h332 | G_h333 | G_h123 | G_HpHmHpHm | G_HpHm11 | G_HpHm12 | G_HpHm13 | G_HpHm22 | G_HpHm23 | G_HpHm33 | G_h1111 | G_h1112 | G_h1113 | G_h1122 | G_h1123 | G_h1133 | G_h1222 | G_h1223 | G_h1233 | G_h1333 | G_h2222 | G_h2223 | G_h2233 | G_h2333 | G_h3333 | G_h1uu | G_h2uu | G_h3uu | G_h1uc | G_h2uc | G_h3uc | G_h1ut | G_h2ut | G_h3ut | G_h1cu | G_h2cu | G_h3cu | G_h1cc | G_h2cc | G_h3cc | G_h1ct | G_h2ct | G_h3ct | G_h1tu | G_h2tu | G_h3tu | G_h1tc | G_h2tc | G_h3tc | G_h1tt | G_h2tt | G_h3tt | G_h1dd | G_h2dd | G_h3dd | G_h1ds | G_h2ds | G_h3ds | G_h1db | G_h2db | G_h3db | G_h1sd | G_h2sd | G_h3sd | G_h1ss | G_h2ss | G_h3ss | G_h1sb | G_h2sb | G_h3sb | G_h1bd | G_h2bd | G_h3bd | G_h1bs | G_h2bs | G_h3bs | G_h1bb | G_h2bb | G_h3bb | G_hud | G_hus | G_hub | G_hcd | G_hcs | G_hcb | G_htd | G_hts | G_htb | G_hdu | G_hdc | G_hdt | G_hsu | G_hsc | G_hst | G_hbu | G_hbc | G_hbt | G_he1n1 | G_he1n2 | G_he1n3 | G_he2n1 | G_he2n2 | G_he2n3 | G_he3n1 | G_he3n2 | G_he3n3 | G_hn1e1 | G_hn1e2 | G_hn1e3 | G_hn2e1 | G_hn2e2 | G_hn2e3 | G_hn3e1 | G_hn3e2 | G_hn3e3 | G_h1e1e1 | G_h2e1e1 | G_h3e1e1 | G_h1e1e2 | G_h2e1e2 | G_h3e1e2 | G_h1e1e3 | G_h2e1e3 | G_h3e1e3 | G_h1e2e1 | G_h2e2e1 | G_h3e2e1 | G_h1e2e2 | G_h2e2e2 | G_h3e2e2 | G_h1e2e3 | G_h2e2e3 | G_h3e2e3 | G_h1e3e1 | G_h2e3e1 | G_h3e3e1 | G_h1e3e2 | G_h2e3e2 | G_h3e3e2 | G_h1e3e3 | G_h2e3e3 | G_h3e3e3 | Mass of flavor | Width of flavor (* Two integer counters for the QCD and EW order of the couplings. *) type orders = int * int let orders = function | _ -> (0,0) let g_over_2_costh = Quot (Neg (Atom G_weak), Prod [Integer 2; Atom Costhw]) let nc_coupling c t3 q = (Real_Array c, [Prod [g_over_2_costh; Diff (t3, Prod [Integer 2; q; Atom Sin2thw])]; Prod [g_over_2_costh; t3]]) let half = Quot (Integer 1, Integer 2) let array_list = [G_h1uu; G_h2uu; G_h3uu; G_h1uc; G_h2uc; G_h3uc; G_h1ut; G_h2ut; G_h3ut; G_h1cu; G_h2cu; G_h3cu; G_h1cc; G_h2cc; G_h3cc; G_h1ct; G_h2ct; G_h3ct; G_h1tu; G_h2tu; G_h3tu; G_h1tc; G_h2tc; G_h3tc; G_h1tt; G_h2tt; G_h3tt; G_h1dd; G_h2dd; G_h3dd; G_h1ds; G_h2ds; G_h3ds; G_h1db; G_h2db; G_h3db; G_h1sd; G_h2sd; G_h3sd; G_h1ss; G_h2ss; G_h3ss; G_h1sb; G_h2sb; G_h3sb; G_h1bd; G_h2bd; G_h3bd; G_h1bs; G_h2bs; G_h3bs; G_h1bb; G_h2bb; G_h3bb; G_hud; G_hus; G_hub; G_hcd; G_hcs; G_hcb; G_htd; G_hts; G_htb; G_hdu; G_hdc; G_hdt; G_hsu; G_hsc; G_hst; G_hbu; G_hbc; G_hbt; G_he1n1; G_he1n2; G_he1n3; G_he2n1; G_he2n2; G_he2n3; G_he3n1; G_he3n2; G_he3n3; G_hn1e1; G_hn1e2; G_hn1e3; G_hn2e1; G_hn2e2; G_hn2e3; G_hn3e1; G_hn3e2; G_hn3e3; G_h1e1e1; G_h2e1e1; G_h3e1e1; G_h1e1e2; G_h2e1e2; G_h3e1e2; G_h1e1e3; G_h2e1e3; G_h3e1e3; G_h1e2e1; G_h2e2e1; G_h3e2e1; G_h1e2e2; G_h2e2e2; G_h3e2e2; G_h1e2e3; G_h2e2e3; G_h3e2e3; G_h1e3e1; G_h2e3e1; G_h3e3e1; G_h1e3e2; G_h2e3e2; G_h3e3e2; G_h1e3e3; G_h2e3e3; G_h3e3e3] let add_complex_array_tag c = (Complex_Array c, [Integer 0; Integer 0]) let derived_parameter_arrays = [ nc_coupling G_NC_neutrino half (Integer 0); nc_coupling G_NC_lepton (Neg half) (Integer (-1)); nc_coupling G_NC_up half (Quot (Integer 2, Integer 3)); nc_coupling G_NC_down (Neg half) (Quot (Integer (-1), Integer 3)); ] @ (List.map add_complex_array_tag array_list) let parameters () = { input = []; derived = []; derived_arrays = derived_parameter_arrays} module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) (* \begin{equation} \mathcal{L}_{\textrm{EM}} = - e \sum_i q_i \bar\psi_i\fmslash{A}\psi_i \end{equation} *) let mgm ((m1, g, m2), fbf, c) = ((M m1, G g, M m2), fbf, c) let electromagnetic_currents n = List.map mgm [ ((L (-n), Ga, L n), FBF (1, Psibar, V, Psi), Q_lepton); ((U (-n), Ga, U n), FBF (1, Psibar, V, Psi), Q_up); ((D (-n), Ga, D n), FBF (1, Psibar, V, Psi), Q_down) ] let color_currents n = List.map mgm [ ((U (-n), Gl, U n), FBF (1, Psibar, V, Psi), Gs); ((D (-n), Gl, D n), FBF (1, Psibar, V, Psi), Gs) ] (* \begin{equation} \mathcal{L}_{\textrm{NC}} = - \frac{g}{2\cos\theta_W} \sum_i \bar\psi_i\fmslash{Z}(g_V^i-g_A^i\gamma_5)\psi_i \end{equation} *) let neutral_currents n = List.map mgm [ ((L (-n), Z, L n), FBF (1, Psibar, VA, Psi), G_NC_lepton); ((N (-n), Z, N n), FBF (1, Psibar, VA, Psi), G_NC_neutrino); ((U (-n), Z, U n), FBF (1, Psibar, VA, Psi), G_NC_up); ((D (-n), Z, D n), FBF (1, Psibar, VA, Psi), G_NC_down) ] (* \begin{equation} \mathcal{L}_{\textrm{CC}} = - \frac{g}{2\sqrt2} \sum_i \bar\psi_i (T^+\fmslash{W}^+ + T^-\fmslash{W}^-)(1-\gamma_5)\psi_i \end{equation} *) let charged_currents n = List.map mgm [ ((L (-n), Wm, N n), FBF (1, Psibar, VL, Psi), G_CC); ((N (-n), Wp, L n), FBF (1, Psibar, VL, Psi), G_CC); ((D (-n), Wm, U n), FBF (1, Psibar, VL, Psi), G_CC); ((U (-n), Wp, D n), FBF (1, Psibar, VL, Psi), G_CC) ] let yukawa = [ ((M (U (-1)),O Hh,M (U 1)), FBF (1,Psibar,SP,Psi), G_h1uu); ((M (U (-1)),O HH,M (U 1)), FBF (1,Psibar,SP,Psi), G_h2uu); ((M (U (-1)),O HA,M (U 1)), FBF (1,Psibar,SP,Psi), G_h3uu); ((M (U (-2)),O Hh,M (U 2)), FBF (1,Psibar,SP,Psi), G_h1cc); ((M (U (-2)),O HH,M (U 2)), FBF (1,Psibar,SP,Psi), G_h2cc); ((M (U (-2)),O HA,M (U 2)), FBF (1,Psibar,SP,Psi), G_h3cc); ((M (U (-3)),O Hh,M (U 3)), FBF (1,Psibar,SP,Psi), G_h1tt); ((M (U (-3)),O HH,M (U 3)), FBF (1,Psibar,SP,Psi), G_h2tt); ((M (U (-3)),O HA,M (U 3)), FBF (1,Psibar,SP,Psi), G_h3tt); ((M (D (-1)),O Hh,M (D 1)), FBF (1,Psibar,SP,Psi), G_h1dd); ((M (D (-1)),O HH,M (D 1)), FBF (1,Psibar,SP,Psi), G_h2dd); ((M (D (-1)),O HA,M (D 1)), FBF (1,Psibar,SP,Psi), G_h3dd); ((M (D (-2)),O Hh,M (D 2)), FBF (1,Psibar,SP,Psi), G_h1ss); ((M (D (-2)),O HH,M (D 2)), FBF (1,Psibar,SP,Psi), G_h2ss); ((M (D (-2)),O HA,M (D 2)), FBF (1,Psibar,SP,Psi), G_h3ss); ((M (D (-3)),O Hh,M (D 3)), FBF (1,Psibar,SP,Psi), G_h1bb); ((M (D (-3)),O HH,M (D 3)), FBF (1,Psibar,SP,Psi), G_h2bb); ((M (D (-3)),O HA,M (D 3)), FBF (1,Psibar,SP,Psi), G_h3bb); ((M (U (-1)),O Hp,M (D 1)), FBF (1,Psibar,SP,Psi), G_hud); ((M (U (-2)),O Hp,M (D 2)), FBF (1,Psibar,SP,Psi), G_hcs); ((M (U (-3)),O Hp,M (D 3)), FBF (1,Psibar,SP,Psi), G_htb); ((M (D (-1)),O Hm,M (U 1)), FBF (1,Psibar,SP,Psi), G_hdu); ((M (D (-2)),O Hm,M (U 2)), FBF (1,Psibar,SP,Psi), G_hsc); ((M (D (-3)),O Hm,M (U 3)), FBF (1,Psibar,SP,Psi), G_hbt); ((M (L (-1)),O Hh,M (L 1)), FBF (1,Psibar,SP,Psi), G_h1e1e1); ((M (L (-1)),O HH,M (L 1)), FBF (1,Psibar,SP,Psi), G_h2e1e1); ((M (L (-1)),O HA,M (L 1)), FBF (1,Psibar,SP,Psi), G_h3e1e1); ((M (L (-2)),O Hh,M (L 2)), FBF (1,Psibar,SP,Psi), G_h1e2e2); ((M (L (-2)),O HH,M (L 2)), FBF (1,Psibar,SP,Psi), G_h2e2e2); ((M (L (-2)),O HA,M (L 2)), FBF (1,Psibar,SP,Psi), G_h3e2e2); ((M (L (-3)),O Hh,M (L 3)), FBF (1,Psibar,SP,Psi), G_h1e3e3); ((M (L (-3)),O HH,M (L 3)), FBF (1,Psibar,SP,Psi), G_h2e3e3); ((M (L (-3)),O HA,M (L 3)), FBF (1,Psibar,SP,Psi), G_h3e3e3) (*i ((M (N (-1)),O Hp,M (L 1)), FBF (1,Psibar,SR,Psi), G_hn1e1); ((M (N (-2)),O Hp,M (L 2)), FBF (1,Psibar,SR,Psi), G_hn2e2); ((M (N (-3)),O Hp,M (L 3)), FBF (1,Psibar,SR,Psi), G_hn3e3); ((M (L (-1)),O Hm,M (N 1)), FBF (1,Psibar,SL,Psi), G_he1n1); ((M (L (-2)),O Hm,M (N 2)), FBF (1,Psibar,SL,Psi), G_he2n2); ((M (L (-3)),O Hm,M (N 3)), FBF (1,Psibar,SL,Psi), G_he3n3); i*) ] @ if Flags.ckm_present then [((M (U (-1)),O Hh, M (U 2)), FBF (1,Psibar,SP,Psi), G_h1uc); ((M (U (-1)),O Hh, M (U 3)), FBF (1,Psibar,SP,Psi), G_h1ut); ((M (U (-2)),O Hh,M (U 1)), FBF (1,Psibar,SP,Psi), G_h1cu); ((M (U (-2)),O Hh,M (U 3)), FBF (1,Psibar,SP,Psi), G_h1ct); ((M (U (-1)),O HH,M (U 2)), FBF (1,Psibar,SP,Psi), G_h2uc); ((M (U (-1)),O HH,M (U 3)), FBF (1,Psibar,SP,Psi), G_h2ut); ((M (U (-1)),O HA,M (U 2)), FBF (1,Psibar,SP,Psi), G_h3uc); ((M (U (-1)),O HA,M (U 3)), FBF (1,Psibar,SP,Psi), G_h3ut); ((M (U (-2)),O HH,M (U 1)), FBF (1,Psibar,SP,Psi), G_h2cu); ((M (U (-2)),O HH,M (U 3)), FBF (1,Psibar,SP,Psi), G_h2ct); ((M (U (-2)),O HA,M (U 1)), FBF (1,Psibar,SP,Psi), G_h3cu); ((M (U (-2)),O HA,M (U 3)), FBF (1,Psibar,SP,Psi), G_h3ct); ((M (U (-3)),O Hh,M (U 1)), FBF (1,Psibar,SP,Psi), G_h1tu); ((M (U (-3)),O Hh,M (U 2)), FBF (1,Psibar,SP,Psi), G_h1tc); ((M (U (-3)),O HH,M (U 1)), FBF (1,Psibar,SP,Psi), G_h2tu); ((M (U (-3)),O HH,M (U 2)), FBF (1,Psibar,SP,Psi), G_h2tc); ((M (U (-3)),O HA,M (U 1)), FBF (1,Psibar,SP,Psi), G_h3tu); ((M (U (-3)),O HA,M (U 2)), FBF (1,Psibar,SP,Psi), G_h3tc); ((M (D (-1)),O Hh,M (D 2)), FBF (1,Psibar,SP,Psi), G_h1ds); ((M (D (-1)),O Hh,M (D 3)), FBF (1,Psibar,SP,Psi), G_h1db); ((M (D (-1)),O HH,M (D 2)), FBF (1,Psibar,SP,Psi), G_h2ds); ((M (D (-1)),O HH,M (D 3)), FBF (1,Psibar,SP,Psi), G_h2db); ((M (D (-1)),O HA,M (D 2)), FBF (1,Psibar,SP,Psi), G_h3ds); ((M (D (-1)),O HA,M (D 3)), FBF (1,Psibar,SP,Psi), G_h3db); ((M (D (-2)),O Hh,M (D 1)), FBF (1,Psibar,SP,Psi), G_h1sd); ((M (D (-2)),O Hh,M (D 3)), FBF (1,Psibar,SP,Psi), G_h1sb); ((M (D (-2)),O HH,M (D 1)), FBF (1,Psibar,SP,Psi), G_h2sd); ((M (D (-2)),O HH,M (D 3)), FBF (1,Psibar,SP,Psi), G_h2sb); ((M (D (-2)),O HA,M (D 1)), FBF (1,Psibar,SP,Psi), G_h3sd); (*i ((M (N (-1)),O Hp,M (L 2)), FBF (1,Psibar,SR,Psi), G_hn1e2); ((M (N (-1)),O Hp,M (L 3)), FBF (1,Psibar,SR,Psi), G_hn1e3); ((M (N (-2)),O Hp,M (L 1)), FBF (1,Psibar,SR,Psi), G_hn2e1); ((M (N (-2)),O Hp,M (L 3)), FBF (1,Psibar,SR,Psi), G_hn2e3); ((M (N (-3)),O Hp,M (L 1)), FBF (1,Psibar,SR,Psi), G_hn3e1); ((M (N (-3)),O Hp,M (L 2)), FBF (1,Psibar,SR,Psi), G_hn3e2); ((M (L (-1)),O Hm,M (N 2)), FBF (1,Psibar,SL,Psi), G_he1n2); ((M (L (-1)),O Hm,M (N 3)), FBF (1,Psibar,SL,Psi), G_he1n3); ((M (L (-2)),O Hm,M (N 1)), FBF (1,Psibar,SL,Psi), G_he2n1); ((M (L (-2)),O Hm,M (N 3)), FBF (1,Psibar,SL,Psi), G_he2n3); ((M (L (-3)),O Hm,M (N 1)), FBF (1,Psibar,SL,Psi), G_he3n1); ((M (L (-3)),O Hm,M (N 2)), FBF (1,Psibar,SL,Psi), G_he3n2); i*) ((M (L (-1)),O Hh,M (L 2)), FBF (1,Psibar,SP,Psi), G_h1e1e2); ((M (L (-1)),O Hh,M (L 3)), FBF (1,Psibar,SP,Psi), G_h1e1e3); ((M (L (-1)),O HH,M (L 2)), FBF (1,Psibar,SP,Psi), G_h2e1e2); ((M (L (-1)),O HH,M (L 3)), FBF (1,Psibar,SP,Psi), G_h2e1e3); ((M (L (-1)),O HA,M (L 2)), FBF (1,Psibar,SP,Psi), G_h3e1e2); ((M (L (-1)),O HA,M (L 3)), FBF (1,Psibar,SP,Psi), G_h3e1e3); ((M (L (-2)),O Hh,M (L 1)), FBF (1,Psibar,SP,Psi), G_h1e2e1); ((M (L (-2)),O Hh,M (L 3)), FBF (1,Psibar,SP,Psi), G_h1e2e3); ((M (L (-2)),O HH,M (L 1)), FBF (1,Psibar,SP,Psi), G_h2e2e1); ((M (L (-2)),O HH,M (L 3)), FBF (1,Psibar,SP,Psi), G_h2e2e3); ((M (L (-2)),O HA,M (L 1)), FBF (1,Psibar,SP,Psi), G_h3e2e1); ((M (L (-2)),O HA,M (L 3)), FBF (1,Psibar,SP,Psi), G_h3e2e3); ((M (L (-3)),O Hh,M (L 1)), FBF (1,Psibar,SP,Psi), G_h1e3e1); ((M (L (-3)),O Hh,M (L 2)), FBF (1,Psibar,SP,Psi), G_h1e3e2); ((M (L (-3)),O HH,M (L 1)), FBF (1,Psibar,SP,Psi), G_h2e3e1); ((M (L (-3)),O HH,M (L 2)), FBF (1,Psibar,SP,Psi), G_h2e3e2); ((M (L (-3)),O HA,M (L 1)), FBF (1,Psibar,SP,Psi), G_h3e3e1); ((M (L (-3)),O HA,M (L 2)), FBF (1,Psibar,SP,Psi), G_h3e3e2) ] else [] (* \begin{equation} \mathcal{L}_{\textrm{TGC}} = - e \partial_\mu A_\nu W_+^\mu W_-^\nu + \ldots - e \cot\theta_w \partial_\mu Z_\nu W_+^\mu W_-^\nu + \ldots \end{equation} *) let tgc ((g1, g2, g3), t, c) = ((G g1, G g2, G g3), t, c) let triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW); ((Gl, Gl, Gl), Gauge_Gauge_Gauge 1, I_Gs) ] (* \begin{equation} \mathcal{L}_{\textrm{QGC}} = - g^2 W_{+,\mu} W_{-,\nu} W_+^\mu W_-^\nu + \ldots \end{equation} *) (* Actually, quartic gauge couplings are a little bit more straightforward using auxiliary fields. Here we have to impose the antisymmetry manually: \begin{subequations} \begin{multline} (W^{+,\mu}_1 W^{-,\nu}_2 - W^{+,\nu}_1 W^{-,\mu}_2) (W^+_{3,\mu} W^-_{4,\nu} - W^+_{3,\nu} W^-_{4,\mu}) \\ = 2(W^+_1W^+_3)(W^-_2W^-_4) - 2(W^+_1W^-_4)(W^-_2W^+_3) \end{multline} also ($V$ can be $A$ or $Z$) \begin{multline} (W^{+,\mu}_1 V^\nu_2 - W^{+,\nu}_1 V^\mu_2) (W^-_{3,\mu} V_{4,\nu} - W^-_{3,\nu} V_{4,\mu}) \\ = 2(W^+_1W^-_3)(V_2V_4) - 2(W^+_1V_4)(V_2W^-_3) \end{multline} \end{subequations} *) (* \begin{subequations} \begin{multline} W^{+,\mu} W^{-,\nu} W^+_\mu W^-_\nu \end{multline} \end{subequations} *) let qgc ((g1, g2, g3, g4), t, c) = ((G g1, G g2, G g3, G g4), t, c) let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] let quartic_gauge = List.map qgc [ (Wm, Wp, Wm, Wp), gauge4, G_WWWW; (Wm, Z, Wp, Z), minus_gauge4, G_ZZWW; (Wm, Z, Wp, Ga), minus_gauge4, G_AZWW; (Wm, Ga, Wp, Ga), minus_gauge4, G_AAWW; (Gl, Gl, Gl, Gl), gauge4, G2] let gauge_higgs = [ (G Ga, O Hp, O Hm), Vector_Scalar_Scalar 1, G_AHpHm; (G Z, O Hp, O Hm), Vector_Scalar_Scalar 1, G_ZHpHm; (G Z, O Hh, O HH), Vector_Scalar_Scalar 1, G_Zh1h2; (G Z, O Hh, O HA), Vector_Scalar_Scalar 1, G_Zh1h3; (G Z, O HH, O HA), Vector_Scalar_Scalar 1, G_Zh2h3; (G Wp, O Hm, O Hh), Vector_Scalar_Scalar 1, G_WpHmh1; (G Wp, O Hm, O HH), Vector_Scalar_Scalar 1, G_WpHmh2; (G Wp, O Hm, O HA), Vector_Scalar_Scalar 1, G_WpHmh3; (G Wm, O Hp, O Hh), Vector_Scalar_Scalar 1, G_WmHph1; (G Wm, O Hp, O HH), Vector_Scalar_Scalar 1, G_WmHph2; (G Wm, O Hp, O HA), Vector_Scalar_Scalar 1, G_WmHph3; (O Hh, G Z, G Z), Scalar_Vector_Vector 1, G_h1ZZ; (O HH, G Z, G Z), Scalar_Vector_Vector 1, G_h2ZZ; (O HA, G Z, G Z), Scalar_Vector_Vector 1, G_h3ZZ; (O Hh, G Wp, G Wm), Scalar_Vector_Vector 1, G_h1WpWm; (O HH, G Wp, G Wm), Scalar_Vector_Vector 1, G_h2WpWm; (O HA, G Wp, G Wm), Scalar_Vector_Vector 1, G_h3WpWm ] let gauge_higgs4 = [ (O Hh, O Hh, G Wp, G Wm), Scalar2_Vector2 1, G_hhWpWm; (O HH, O HH, G Wp, G Wm), Scalar2_Vector2 1, G_hhWpWm; (O HA, O HA, G Wp, G Wm), Scalar2_Vector2 1, G_hhWpWm; (O Hh, O Hh, G Z, G Z), Scalar2_Vector2 1, G_hhZZ; (O HH, O HH, G Z, G Z), Scalar2_Vector2 1, G_hhZZ; (O HA, O HA, G Z, G Z), Scalar2_Vector2 1, G_hhZZ; (O Hp, O Hm, G Ga, G Ga), Scalar2_Vector2 1, G_HpHmAA; (O Hp, O Hm, G Z, G Z), Scalar2_Vector2 1, G_HpHmZZ; (O Hp, O Hm, G Ga, G Z), Scalar2_Vector2 1, G_HpHmAZ; (O Hp, O Hm, G Wp, G Wm), Scalar2_Vector2 1, G_HpHmWpWm; (O Hh, O Hp, G Ga, G Wm), Scalar2_Vector2 1, G_h1HpAWm; (O HH, O Hp, G Ga, G Wm), Scalar2_Vector2 1, G_h2HpAWm; (O HA, O Hp, G Ga, G Wm), Scalar2_Vector2 1, G_h3HpAWm; (O Hh, O Hp, G Z, G Wm), Scalar2_Vector2 1, G_h1HpZWm; (O HH, O Hp, G Z, G Wm), Scalar2_Vector2 1, G_h2HpZWm; (O HA, O Hp, G Z, G Wm), Scalar2_Vector2 1, G_h3HpZWm; (O Hh, O Hm, G Ga, G Wp), Scalar2_Vector2 1, G_h1HpAWmC; (O HH, O Hm, G Ga, G Wp), Scalar2_Vector2 1, G_h2HpAWmC; (O HA, O Hm, G Ga, G Wp), Scalar2_Vector2 1, G_h3HpAWmC; (O Hh, O Hm, G Z, G Wp), Scalar2_Vector2 1, G_h1HpZWmC; (O HH, O Hm, G Z, G Wp), Scalar2_Vector2 1, G_h2HpZWmC; (O HA, O Hm, G Z, G Wp), Scalar2_Vector2 1, G_h3HpZWmC ] let higgs = [ (O Hh, O Hp, O Hm), Scalar_Scalar_Scalar 1, G_h1HpHm; (O HH, O Hp, O Hm), Scalar_Scalar_Scalar 1, G_h2HpHm; (O HA, O Hp, O Hm), Scalar_Scalar_Scalar 1, G_h3HpHm; (O Hh, O Hh, O Hh), Scalar_Scalar_Scalar 1, G_h111; (O Hh, O Hh, O HH), Scalar_Scalar_Scalar 1, G_h112; (O Hh, O Hh, O HA), Scalar_Scalar_Scalar 1, G_h113; (O HH, O HH, O Hh), Scalar_Scalar_Scalar 1, G_h221; (O HH, O HH, O HH), Scalar_Scalar_Scalar 1, G_h222; (O HH, O HH, O HA), Scalar_Scalar_Scalar 1, G_h223; (O HA, O HA, O Hh), Scalar_Scalar_Scalar 1, G_h331; (O HA, O HA, O HH), Scalar_Scalar_Scalar 1, G_h332; (O HA, O HA, O HA), Scalar_Scalar_Scalar 1, G_h333; (O Hh, O HH, O HA), Scalar_Scalar_Scalar 1, G_h123 ] let higgs4 = [ (O Hp, O Hm, O Hp, O Hm), Scalar4 1, G_HpHmHpHm; (O Hp, O Hm, O Hh, O Hh), Scalar4 1, G_HpHm11; (O Hp, O Hm, O Hh, O HH), Scalar4 1, G_HpHm12; (O Hp, O Hm, O Hh, O HA), Scalar4 1, G_HpHm13; (O Hp, O Hm, O HH, O HH), Scalar4 1, G_HpHm22; (O Hp, O Hm, O HH, O HA), Scalar4 1, G_HpHm23; (O Hp, O Hm, O HA, O HA), Scalar4 1, G_HpHm33; (O Hh, O Hh, O Hh, O Hh), Scalar4 1, G_h1111; (O Hh, O Hh, O Hh, O HH), Scalar4 1, G_h1112; (O Hh, O Hh, O Hh, O HA), Scalar4 1, G_h1113; (O Hh, O Hh, O HH, O HH), Scalar4 1, G_h1122; (O Hh, O Hh, O HH, O HA), Scalar4 1, G_h1123; (O Hh, O Hh, O HA, O HA), Scalar4 1, G_h1133; (O Hh, O HH, O HH, O HH), Scalar4 1, G_h1222; (O Hh, O HH, O HH, O HA), Scalar4 1, G_h1223; (O Hh, O HH, O HA, O HA), Scalar4 1, G_h1233; (O Hh, O HA, O HA, O HA), Scalar4 1, G_h1333; (O HH, O HH, O HH, O HH), Scalar4 1, G_h2222; (O HH, O HH, O HH, O HA), Scalar4 1, G_h2223; (O HH, O HH, O HA, O HA), Scalar4 1, G_h2233; (O HH, O HA, O HA, O HA), Scalar4 1, G_h2333; (O HA, O HA, O HA, O HA), Scalar4 1, G_h3333 ] let goldstone_vertices = [ ((O Phi0, G Wm, G Wp), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phip, G Ga, G Wm), Scalar_Vector_Vector 1, I_Q_W); ((O Phip, G Z, G Wm), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phim, G Wp, G Ga), Scalar_Vector_Vector 1, I_Q_W); ((O Phim, G Wp, G Z), Scalar_Vector_Vector 1, I_G_ZWW) ] let vertices3 = (ThoList.flatmap electromagnetic_currents [1;2;3] @ ThoList.flatmap color_currents [1;2;3] @ ThoList.flatmap neutral_currents [1;2;3] @ ThoList.flatmap charged_currents [1;2;3] @ yukawa @ triple_gauge @ gauge_higgs @ higgs @ goldstone_vertices) let vertices4 = quartic_gauge @ gauge_higgs4 @ higgs4 let vertices () = (vertices3, vertices4, []) (* For efficiency, make sure that [F.of_vertices vertices] is evaluated only once. *) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 let flavor_of_string = function | "e-" -> M (L 1) | "e+" -> M (L (-1)) | "mu-" -> M (L 2) | "mu+" -> M (L (-2)) | "tau-" -> M (L 3) | "tau+" -> M (L (-3)) | "nue" -> M (N 1) | "nuebar" -> M (N (-1)) | "numu" -> M (N 2) | "numubar" -> M (N (-2)) | "nutau" -> M (N 3) | "nutaubar" -> M (N (-3)) | "u" -> M (U 1) | "ubar" -> M (U (-1)) | "c" -> M (U 2) | "cbar" -> M (U (-2)) | "t" -> M (U 3) | "tbar" -> M (U (-3)) | "d" -> M (D 1) | "dbar" -> M (D (-1)) | "s" -> M (D 2) | "sbar" -> M (D (-2)) | "b" -> M (D 3) | "bbar" -> M (D (-3)) | "g" -> G Gl | "A" -> G Ga | "Z" | "Z0" -> G Z | "W+" -> G Wp | "W-" -> G Wm | "h0" -> O Hh | "H0" -> O HH | "A0" -> O HA | _ -> invalid_arg "Modellib_BSM.TwoHiggsDoublet.flavor_of_string" let flavor_to_string = function | M f -> begin match f with | L 1 -> "e-" | L (-1) -> "e+" | L 2 -> "mu-" | L (-2) -> "mu+" | L 3 -> "tau-" | L (-3) -> "tau+" | L _ -> invalid_arg "Modellib_BSM.TwoHiggsDoublet.flavor_to_string: invalid lepton" | N 1 -> "nue" | N (-1) -> "nuebar" | N 2 -> "numu" | N (-2) -> "numubar" | N 3 -> "nutau" | N (-3) -> "nutaubar" | N _ -> invalid_arg "Modellib_BSM.TwoHiggsDoublet.flavor_to_string: invalid neutrino" | U 1 -> "u" | U (-1) -> "ubar" | U 2 -> "c" | U (-2) -> "cbar" | U 3 -> "t" | U (-3) -> "tbar" | U _ -> invalid_arg "Modellib_BSM.TwoHiggsDoublet.flavor_to_string: invalid up type quark" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | D _ -> invalid_arg "Modellib_BSM.TwoHiggsDoublet.flavor_to_string: invalid down type quark" end | G f -> begin match f with | Gl -> "g" | Ga -> "A" | Z -> "Z" | Wp -> "W+" | Wm -> "W-" end | O f -> begin match f with | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | Hh -> "h0" | HH -> "H0" | HA -> "A0" | Hp -> "H+" | Hm -> "H-" end let flavor_to_TeX = function | M f -> begin match f with | L 1 -> "e^-" | L (-1) -> "e^+" | L 2 -> "\\mu^-" | L (-2) -> "\\mu^+" | L 3 -> "\\tau^-" | L (-3) -> "\\tau^+" | L _ -> invalid_arg "Modellib_BSM.TwoHiggsDoublet.flavor_to_TeX: invalid lepton" | N 1 -> "\\nu_e" | N (-1) -> "\\bar{\\nu}_e" | N 2 -> "\\nu_\\mu" | N (-2) -> "\\bar{\\nu}_\\mu" | N 3 -> "\\nu_\\tau" | N (-3) -> "\\bar{\\nu}_\\tau" | N _ -> invalid_arg "Modellib_BSM.TwoHiggsDoublet.flavor_to_TeX: invalid neutrino" | U 1 -> "u" | U (-1) -> "\\bar{u}" | U 2 -> "c" | U (-2) -> "\\bar{c}" | U 3 -> "t" | U (-3) -> "\\bar{t}" | U _ -> invalid_arg "Modellib_BSM.TwoHiggsDoublet.flavor_to_TeX: invalid up type quark" | D 1 -> "d" | D (-1) -> "\\bar{d}" | D 2 -> "s" | D (-2) -> "\\bar{s}" | D 3 -> "b" | D (-3) -> "\\bar{b}" | D _ -> invalid_arg "Modellib_BSM.TwoHiggsDoublet.flavor_to_TeX: invalid down type quark" end | G f -> begin match f with | Gl -> "g" | Ga -> "\\gamma" | Z -> "Z" | Wp -> "W^+" | Wm -> "W^-" end | O f -> begin match f with | Phip -> "\\phi^+" | Phim -> "\\phi^-" | Phi0 -> "\\phi^0" | Hh -> "h^0" | HH -> "H^0" | HA -> "A^0" | Hp -> "H^+" | Hm -> "H^-" end let flavor_symbol = function | M f -> begin match f with | L n when n > 0 -> "l" ^ string_of_int n | L n -> "l" ^ string_of_int (abs n) ^ "b" | N n when n > 0 -> "n" ^ string_of_int n | N n -> "n" ^ string_of_int (abs n) ^ "b" | U n when n > 0 -> "u" ^ string_of_int n | U n -> "u" ^ string_of_int (abs n) ^ "b" | D n when n > 0 -> "d" ^ string_of_int n | D n -> "d" ^ string_of_int (abs n) ^ "b" end | G f -> begin match f with | Gl -> "gl" | Ga -> "a" | Z -> "z" | Wp -> "wp" | Wm -> "wm" end | O f -> begin match f with | Phip -> "pp" | Phim -> "pm" | Phi0 -> "p0" | Hh -> "h" | HH -> "h0" | HA -> "a0" | Hp -> "hp" | Hm -> "hm" end let pdg = function | M f -> begin match f with | L n when n > 0 -> 9 + 2*n | L n -> - 9 + 2*n | N n when n > 0 -> 10 + 2*n | N n -> - 10 + 2*n | U n when n > 0 -> 2*n | U n -> 2*n | D n when n > 0 -> - 1 + 2*n | D n -> 1 + 2*n end | G f -> begin match f with | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) end | O f -> begin match f with | Phip -> 27 | Phim -> -27 | Phi0 -> 26 | Hh -> 25 | HH -> 35 | HA -> 36 | Hp -> 37 | Hm -> -37 end let mass_symbol f = "mass(" ^ string_of_int (abs (pdg f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg f)) ^ ")" let constant_symbol = function | Unit -> "unit" | Pi -> "PI" | Alpha_QED -> "alpha" | E -> "e" | G_weak -> "g" | Vev -> "vev" | Sin2thw -> "sin2thw" | Sinthw -> "sinthw" | Costhw -> "costhw" | Q_lepton -> "qlep" | Q_up -> "qup" | Q_down -> "qdwn" | G_NC_lepton -> "gnclep" | G_NC_neutrino -> "gncneu" | G_NC_up -> "gncup" | G_NC_down -> "gncdwn" | G_CC -> "gcc" | I_Q_W -> "iqw" | I_G_ZWW -> "igzww" | I_G_WWW -> "igwww" | G_WWWW -> "gw4" | G_ZZWW -> "gzzww" | G_AZWW -> "gazww" | G_AAWW -> "gaaww" | G_htt -> "ghtt" | G_hbb -> "ghbb" | G_hcc -> "ghcc" | G_Htt -> "gh0tt" | G_Hbb -> "gh0bb" | G_Hcc -> "gh0cc" | I_G_Att -> "iga0tt" | I_G_Abb -> "iga0bb" | I_G_Acc -> "iga0cc" | G_htautau -> "ghtautau" | G_hmumu -> "ghmumu" | G_Htautau -> "gh0tautau" | G_Hmumu -> "gh0mumu" | I_G_Atautau -> "iga0tautau" | I_G_Amumu -> "iga0mumu" | G_Htb -> "ghptb" | G_Hcs -> "ghpcs" | G_Htaunu -> "ghptaunu" | G_Hmunu -> "ghpmunu" | Gs -> "gs" | I_Gs -> "igs" | G2 -> "gs**2" | G_AHpHm -> "gAHpHm" | G_ZHpHm -> "gZHpHm" | G_Zh1h2 -> "gZh1h2" | G_Zh1h3 -> "gZh1h3" | G_Zh2h3 -> "gZh2h3" | G_WpHmh1 -> "gWpHmh1" | G_WpHmh2 -> "gWpHmh2" | G_WpHmh3 -> "gWpHmh3" | G_WmHph1 -> "gWmHph1" | G_WmHph2 -> "gWmHph2" | G_WmHph3 -> "gWmHph3" | G_h1ZZ -> "gh1ZZ" | G_h2ZZ -> "gh2ZZ" | G_h3ZZ -> "gh3ZZ" | G_h1WpWm -> "gh1WpWm" | G_h2WpWm -> "gh2WpWm" | G_h3WpWm -> "gh3WpWm" | G_hhWpWm -> "ghhWpWm" | G_hhZZ -> "ghhZZ" | G_HpHmAA -> "gHpHmAA" | G_HpHmZZ -> "gHpHmZZ" | G_HpHmAZ -> "gHpHmAZ" | G_HpHmWpWm -> "gHpHmWpWm" | G_h1HpAWm -> "gh1HpAWm" | G_h2HpAWm -> "gh2HpAWm" | G_h3HpAWm -> "gh3HpAWm" | G_h1HpZWm -> "gh1HpZWm" | G_h2HpZWm -> "gh2HpZWm" | G_h3HpZWm -> "gh3HpZWm" | G_h1HpAWmC -> "gh1HpAWmC" | G_h2HpAWmC -> "gh2HpAWmC" | G_h3HpAWmC -> "gh3HpAWmC" | G_h1HpZWmC -> "gh1HpZWmC" | G_h2HpZWmC -> "gh2HpZWmC" | G_h3HpZWmC -> "gh3HpZWmC" | G_h1HpHm -> "gh1HpHm" | G_h2HpHm -> "gh2HpHm" | G_h3HpHm -> "gh3HpHm" | G_h111 -> "gh111" | G_h112 -> "gh112" | G_h113 -> "gh113" | G_h221 -> "gh221" | G_h222 -> "gh222" | G_h223 -> "gh223" | G_h331 -> "gh331" | G_h332 -> "gh332" | G_h333 -> "gh333" | G_h123 -> "gh123" | G_HpHmHpHm -> "gHpHmHpHm" | G_HpHm11 -> "gHpHm11" | G_HpHm12 -> "gHpHm12" | G_HpHm13 -> "gHpHm13" | G_HpHm22 -> "gHpHm22" | G_HpHm23 -> "gHpHm23" | G_HpHm33 -> "gHpHm33" | G_h1111 -> "gh1111" | G_h1112 -> "gh1112" | G_h1113 -> "gh1113" | G_h1122 -> "gh1122" | G_h1123 -> "gh1123" | G_h1133 -> "gh1133" | G_h1222 -> "gh1222" | G_h1223 -> "gh1223" | G_h1233 -> "gh1233" | G_h1333 -> "gh1333" | G_h2222 -> "gh2222" | G_h2223 -> "gh2223" | G_h2233 -> "gh2233" | G_h2333 -> "gh2333" | G_h3333 -> "gh3333" | G_h1uu -> "gh1uu" | G_h2uu -> "gh2uu" | G_h3uu -> "gh3uu" | G_h1uc -> "gh1uc" | G_h2uc -> "gh2uc" | G_h3uc -> "gh3uc" | G_h1ut -> "gh1ut" | G_h2ut -> "gh2ut" | G_h3ut -> "gh3ut" | G_h1cu -> "gh1cu" | G_h2cu -> "gh2cu" | G_h3cu -> "gh3cu" | G_h1cc -> "gh1cc" | G_h2cc -> "gh2cc" | G_h3cc -> "gh3cc" | G_h1ct -> "gh1ct" | G_h2ct -> "gh2ct" | G_h3ct -> "gh3ct" | G_h1tu -> "gh1tu" | G_h2tu -> "gh2tu" | G_h3tu -> "gh3tu" | G_h1tc -> "gh1tc" | G_h2tc -> "gh2tc" | G_h3tc -> "gh3tc" | G_h1tt -> "gh1tt" | G_h2tt -> "gh2tt" | G_h3tt -> "gh3tt" | G_h1dd -> "gh1dd" | G_h2dd -> "gh2dd" | G_h3dd -> "gh3dd" | G_h1ds -> "gh1ds" | G_h2ds -> "gh2ds" | G_h3ds -> "gh3ds" | G_h1db -> "gh1db" | G_h2db -> "gh2db" | G_h3db -> "gh3db" | G_h1sd -> "gh1sd" | G_h2sd -> "gh2sd" | G_h3sd -> "gh3sd" | G_h1ss -> "gh1ss" | G_h2ss -> "gh2ss" | G_h3ss -> "gh3ss" | G_h1sb -> "gh1sb" | G_h2sb -> "gh2sb" | G_h3sb -> "gh3sb" | G_h1bd -> "gh1bd" | G_h2bd -> "gh2bd" | G_h3bd -> "gh3bd" | G_h1bs -> "gh1bs" | G_h2bs -> "gh2bs" | G_h3bs -> "gh3bs" | G_h1bb -> "gh1bb" | G_h2bb -> "gh2bb" | G_h3bb -> "gh3bb" | G_hud -> "ghud" | G_hus -> "ghus" | G_hub -> "ghub" | G_hcd -> "ghcd" | G_hcs -> "ghcs" | G_hcb -> "ghcb" | G_htd -> "ghtd" | G_hts -> "ghts" | G_htb -> "ghtb" | G_hdu -> "ghdu" | G_hdc -> "ghdc" | G_hdt -> "ghdt" | G_hsu -> "ghsu" | G_hsc -> "ghsc" | G_hst -> "ghst" | G_hbu -> "ghbu" | G_hbc -> "ghbc" | G_hbt -> "ghbt" | G_he1n1 -> "ghe1n1" | G_he1n2 -> "ghe1n2" | G_he1n3 -> "ghe1n3" | G_he2n1 -> "ghe2n1" | G_he2n2 -> "ghe2n2" | G_he2n3 -> "ghe2n3" | G_he3n1 -> "ghe3n1" | G_he3n2 -> "ghe3n2" | G_he3n3 -> "ghe3n3" | G_hn1e1 -> "ghn1e1" | G_hn1e2 -> "ghn1e2" | G_hn1e3 -> "ghn1e3" | G_hn2e1 -> "ghn2e1" | G_hn2e2 -> "ghn2e2" | G_hn2e3 -> "ghn2e3" | G_hn3e1 -> "ghn3e1" | G_hn3e2 -> "ghn3e2" | G_hn3e3 -> "ghn3e3" | G_h1e1e1 -> "gh1e1e1" | G_h2e1e1 -> "gh2e1e1" | G_h3e1e1 -> "gh3e1e1" | G_h1e1e2 -> "gh1e1e2" | G_h2e1e2 -> "gh2e1e2" | G_h3e1e2 -> "gh3e1e2" | G_h1e1e3 -> "gh1e1e3" | G_h2e1e3 -> "gh2e1e3" | G_h3e1e3 -> "gh3e1e3" | G_h1e2e1 -> "gh1e2e1" | G_h2e2e1 -> "gh2e2e1" | G_h3e2e1 -> "gh3e2e1" | G_h1e2e2 -> "gh1e2e2" | G_h2e2e2 -> "gh2e2e2" | G_h3e2e2 -> "gh3e2e2" | G_h1e2e3 -> "gh1e2e3" | G_h2e2e3 -> "gh2e2e3" | G_h3e2e3 -> "gh3e2e3" | G_h1e3e1 -> "gh1e3e1" | G_h2e3e1 -> "gh2e3e1" | G_h3e3e1 -> "gh3e3e1" | G_h1e3e2 -> "gh1e3e2" | G_h2e3e2 -> "gh2e3e2" | G_h3e3e2 -> "gh3e3e2" | G_h1e3e3 -> "gh1e3e3" | G_h2e3e3 -> "gh2e3e3" | G_h3e3e3 -> "gh3e3e3" | Mass f -> "mass" ^ flavor_symbol f | Width f -> "width" ^ flavor_symbol f end module type SSC_flags = sig val higgs_triangle : bool (* $H\gamma\gamma$, $Hg\gamma$ and $Hgg$ couplings *) val higgs_hmm : bool val triple_anom : bool val quartic_anom : bool val higgs_anom : bool val k_matrix : bool val k_matrix_tm : bool val ckm_present : bool val top_anom : bool val top_anom_4f : bool val cf_arbitrary : bool val higgs_matrix : bool end module SSC_kmatrix: SSC_flags = struct let higgs_triangle = false let higgs_hmm = false let triple_anom = false let quartic_anom = true let higgs_anom = false let k_matrix = true let k_matrix_tm = false let ckm_present = false let top_anom = false let top_anom_4f = false let cf_arbitrary = false let higgs_matrix = false end module SSC_kmatrix_2: SSC_flags = struct let higgs_triangle = false let higgs_hmm = false let triple_anom = false let quartic_anom = true let higgs_anom = false let k_matrix = true let k_matrix_tm = true let ckm_present = false let top_anom = false let top_anom_4f = false let cf_arbitrary = true let higgs_matrix = true end (* \thocwmodulesection{Complete Minimal Standard Model including additional Resonances} *) module SSC (Flags : SSC_flags) = struct open Coupling let default_width = ref Timelike let use_fudged_width = ref false let options = Options.create [ "constant_width", Arg.Unit (fun () -> default_width := Constant), "use constant width (also in t-channel)"; "fudged_width", Arg.Set use_fudged_width, "use fudge factor for charge particle width"; "custom_width", Arg.String (fun f -> default_width := Custom f), "use custom width"; "cancel_widths", Arg.Unit (fun () -> default_width := Vanishing), "use vanishing width"; "cms_width", Arg.Unit (fun () -> default_width := Complex_Mass), - "use complex mass scheme"] + "use complex mass scheme"; + "running_width", Arg.Unit (fun () -> default_width := Running), + "use running width"] type f_aux_top = TTGG | TBWA | TBWZ | TTWW | BBWW | (*i top auxiliary field "flavors" *) QGUG | QBUB | QW | DL | DR type matter_field = L of int | N of int | U of int | D of int type gauge_boson = Ga | Wp | Wm | Z | Gl type other = Phip | Phim | Phi0 | H | Rsigma | Rphin | Rphisn | Rphip | Rphim | Rphipp | Rphimm | Rf | Rtn | Rtsn | Rtp | Rtm | Rtpp | Rtmm | Aux_top of int*int*int*bool*f_aux_top (*i lorentz*color*charge*top-side*flavor *) type flavor = M of matter_field | G of gauge_boson | O of other let matter_field f = M f let gauge_boson f = G f let other f = O f type field = | Matter of matter_field | Gauge of gauge_boson | Other of other let field = function | M f -> Matter f | G f -> Gauge f | O f -> Other f type gauge = unit let gauge_symbol () = failwith "Modellib_BSM.SSC.gauge_symbol: internal error" let family n = List.map matter_field [ L n; N n; U n; D n ] let rec aux_top_flavors (f,l,co,ch) = List.append ( List.map other [ Aux_top(l,co,ch/2,true,f); Aux_top(l,co,ch/2,false,f) ] ) ( if ch > 1 then List.append ( List.map other [ Aux_top(l,co,-ch/2,true,f); Aux_top(l,co,-ch/2,false,f) ] ) ( aux_top_flavors (f,l,co,(ch-2)) ) else [] ) let external_flavors () = [ "1st Generation", ThoList.flatmap family [1; -1]; "2nd Generation", ThoList.flatmap family [2; -2]; "3rd Generation", ThoList.flatmap family [3; -3]; "Gauge Bosons", List.map gauge_boson [Ga; Z; Wp; Wm; Gl]; "Higgs", List.map other [H]; "Scalar Resonances", List.map other [Rsigma; Rphin; Rphisn; Rphip; Rphim; Rphipp; Rphimm]; "Tensor Resonances", List.map other [Rf; Rtn; Rtsn; Rtp; Rtm; Rtpp; Rtmm]; "Goldstone Bosons", List.map other [Phip; Phim; Phi0] ] let flavors () = List.append ( ThoList.flatmap snd (external_flavors ()) ) ( ThoList.flatmap aux_top_flavors [ (TTGG,2,1,1); (TBWA,2,0,2); (TBWZ,2,0,2); (TTWW,2,0,1); (BBWW,2,0,1); (QGUG,1,1,1); (QBUB,1,0,1); (QW,1,0,3); (DL,0,0,3); (DR,0,0,3) ] ) let spinor n = if n >= 0 then Spinor else ConjSpinor let lorentz_aux = function | 2 -> Tensor_1 | 1 -> Vector | 0 -> Scalar | _ -> invalid_arg ("SM.lorentz_aux: wrong value") let lorentz = function | M f -> begin match f with | L n -> spinor n | N n -> spinor n | U n -> spinor n | D n -> spinor n end | G f -> begin match f with | Ga | Gl -> Vector | Wp | Wm | Z -> Massive_Vector end | O f -> begin match f with | Aux_top (l,_,_,_,_) -> lorentz_aux l | Rf | Rtn | Rtsn | Rtp | Rtm | Rtpp | Rtmm -> Tensor_2 | _ -> Scalar end let color = function | M (U n) -> Color.SUN (if n > 0 then 3 else -3) | M (D n) -> Color.SUN (if n > 0 then 3 else -3) | G Gl -> Color.AdjSUN 3 | O (Aux_top (_,co,_,_,_)) -> if co == 0 then Color.Singlet else Color.AdjSUN 3 | _ -> Color.Singlet let nc () = 3 let prop_spinor n = if n >= 0 then Prop_Spinor else Prop_ConjSpinor let prop_aux = function | 2 -> Aux_Tensor_1 | 1 -> Aux_Vector | 0 -> Aux_Scalar | _ -> invalid_arg ("SM.prop_aux: wrong value") let propagator = function | M f -> begin match f with | L n -> prop_spinor n | N n -> prop_spinor n | U n -> prop_spinor n | D n -> prop_spinor n end | G f -> begin match f with | Ga | Gl -> Prop_Feynman | Wp | Wm | Z -> Prop_Unitarity end | O f -> begin match f with | Phip | Phim | Phi0 -> Only_Insertion | H | Rsigma -> Prop_Scalar | Rphin | Rphisn | Rphip | Rphim | Rphipp | Rphimm -> Prop_Scalar | Rf -> Prop_Tensor_2 | Rtn | Rtsn | Rtp | Rtm | Rtpp | Rtmm -> Prop_Tensor_2 | Aux_top (l,_,_,_,_) -> prop_aux l end (* Optionally, ask for the fudge factor treatment for the widths of charged particles. Currently, this only applies to $W^\pm$ and top. *) let width f = if !use_fudged_width then match f with | G Wp | G Wm | M (U 3) | M (U (-3)) -> Fudged | _ -> !default_width else !default_width let goldstone = function | G f -> begin match f with | Wp -> Some (O Phip, Coupling.Integer 1) | Wm -> Some (O Phim, Coupling.Integer 1) | Z -> Some (O Phi0, Coupling.Integer 1) | _ -> None end | _ -> None let conjugate = function | M f -> M (begin match f with | L n -> L (-n) | N n -> N (-n) | U n -> U (-n) | D n -> D (-n) end) | G f -> G (begin match f with | Gl -> Gl | Ga -> Ga | Z -> Z | Wp -> Wm | Wm -> Wp end) | O f -> O (begin match f with | Phip -> Phim | Phim -> Phip | Phi0 -> Phi0 | H -> H | Rsigma -> Rsigma | Rphin -> Rphin | Rphisn-> Rphisn | Rphip -> Rphim | Rphim -> Rphip | Rphipp -> Rphimm | Rphimm -> Rphipp | Rf -> Rf | Rtn -> Rtn | Rtsn -> Rtsn | Rtp -> Rtm | Rtm -> Rtp | Rtpp -> Rtmm | Rtmm -> Rtpp | Aux_top (l,co,ch,n,f) -> Aux_top (l,co,(-ch),(not n),f) end) let fermion = function | M f -> begin match f with | L n -> if n > 0 then 1 else -1 | N n -> if n > 0 then 1 else -1 | U n -> if n > 0 then 1 else -1 | D n -> if n > 0 then 1 else -1 end | G f -> begin match f with | Gl | Ga | Z | Wp | Wm -> 0 end | O _ -> 0 (* Electrical charge, lepton number, baryon number. We could avoid the rationals altogether by multiplying the first and last by 3 \ldots *) module Ch = Charges.QQ let ( // ) = Algebra.Small_Rational.make let generation' = function | 1 -> [ 1//1; 0//1; 0//1] | 2 -> [ 0//1; 1//1; 0//1] | 3 -> [ 0//1; 0//1; 1//1] | -1 -> [-1//1; 0//1; 0//1] | -2 -> [ 0//1; -1//1; 0//1] | -3 -> [ 0//1; 0//1; -1//1] | n -> invalid_arg ("SM.generation': " ^ string_of_int n) let generation f = if Flags.ckm_present then [] else match f with | M (L n | N n | U n | D n) -> generation' n | G _ | O _ -> [0//1; 0//1; 0//1] let charge = function | M f -> begin match f with | L n -> if n > 0 then -1//1 else 1//1 | N n -> 0//1 | U n -> if n > 0 then 2//3 else -2//3 | D n -> if n > 0 then -1//3 else 1//3 end | G f -> begin match f with | Gl | Ga | Z -> 0//1 | Wp -> 1//1 | Wm -> -1//1 end | O f -> begin match f with | H | Rsigma | Phi0 | Rphin | Rphisn | Rf | Rtn | Rtsn -> 0//1 | Phip | Rphip | Rtp -> 1//1 | Phim | Rphim | Rtm -> -1//1 | Rphipp | Rtpp -> 2//1 | Rphimm | Rtmm -> -2//1 | Aux_top (_,_,ch,_,_) -> ch//1 end let lepton = function | M f -> begin match f with | L n | N n -> if n > 0 then 1//1 else -1//1 | U _ | D _ -> 0//1 end | G _ | O _ -> 0//1 let baryon = function | M f -> begin match f with | L _ | N _ -> 0//1 | U n | D n -> if n > 0 then 1//1 else -1//1 end | G _ | O _ -> 0//1 let charges f = [ charge f; lepton f; baryon f] @ generation f type constant = | Unit | Half | Pi | Alpha_QED | Sin2thw | Sinthw | Costhw | E | G_weak | I_G_weak | Vev | Q_lepton | Q_up | Q_down | G_CC | G_CCQ of int*int | G_NC_neutrino | G_NC_lepton | G_NC_up | G_NC_down | G_TVA_ttA | G_TVA_bbA | G_VLR_ttZ | G_TVA_ttZ | G_TVA_bbZ | G_VLR_btW | G_VLR_tbW | G_TLR_btW | G_TRL_tbW | G_TLR_btWZ | G_TRL_tbWZ | G_TLR_btWA | G_TRL_tbWA | G_TVA_ttWW | G_TVA_bbWW | G_TVA_ttG | G_TVA_ttGG | G_SP_ttH | G_VLR_qGuG | G_VLR_qBuB | G_VLR_qBuB_u | G_VLR_qBuB_d | G_VLR_qBuB_e | G_VL_qBuB_n | G_VL_qW | G_VL_qW_u | G_VL_qW_d | G_SL_DttR | G_SR_DttR | G_SL_DttL | G_SLR_DbtR | G_SL_DbtL | I_Q_W | I_G_ZWW | G_WWWW | G_ZZWW | G_AZWW | G_AAWW | I_G1_AWW | I_G1_ZWW | I_G1_plus_kappa_plus_G4_AWW | I_G1_plus_kappa_plus_G4_ZWW | I_G1_plus_kappa_minus_G4_AWW | I_G1_plus_kappa_minus_G4_ZWW | I_G1_minus_kappa_plus_G4_AWW | I_G1_minus_kappa_plus_G4_ZWW | I_G1_minus_kappa_minus_G4_AWW | I_G1_minus_kappa_minus_G4_ZWW | I_lambda_AWW | I_lambda_ZWW | G5_AWW | G5_ZWW | I_kappa5_AWW | I_kappa5_ZWW | I_lambda5_AWW | I_lambda5_ZWW | FS0_HHWW | FS0_HHZZ | FS1_HHWW | FS1_HHZZ | FM0_HHWW | FM0_HHZZ | FM1_HHWW | FM1_HHZZ | FM7_HHWW | FM7_HHZZ | Alpha_WWWW0 | Alpha_ZZWW1 | Alpha_WWWW2 | Alpha_ZZWW0 | Alpha_ZZZZ | FT0_WWWW0 | FT0_WWWW2 | FT0_ZZWW0 | FT0_ZZWW1 | FT0_ZZZZ | FT0_AAAA | FT0_AAWW0 | FT0_AAWW1 | FT0_AAZZ | FT0_AZWW0 | FT0_AZWW1 | FT0_AAAZ | FT0_AZZZ | FT1_WWWW0 | FT1_WWWW2 | FT1_ZZWW0 | FT1_ZZWW1 | FT1_ZZZZ | FT1_AAAA | FT1_AAWW0 | FT1_AAWW1 | FT1_AAZZ | FT1_AZWW0 | FT1_AZWW1 | FT1_AAAZ | FT1_AZZZ | FT2_WWWW0 | FT2_WWWW2 | FT2_ZZWW0 | FT2_ZZWW1 | FT2_ZZZZ | FT2_AAAA | FT2_AAWW0 | FT2_AAWW1 | FT2_AAZZ | FT2_AZWW0 | FT2_AZWW1 | FT2_AAAZ | FT2_AZZZ | FM0_WWWW0 | FM0_WWWW2 | FM0_ZZWW0 | FM0_ZZWW1 | FM0_ZZZZ | FM1_WWWW0 | FM1_WWWW2 | FM1_ZZWW0 | FM1_ZZWW1 | FM1_ZZZZ | FM7_WWWW0 | FM7_WWWW2 | FM7_ZZWW0 | FM7_ZZWW1 | FM7_ZZZZ | D_Alpha_ZZWW0_S | D_Alpha_ZZWW0_T | D_Alpha_ZZWW1_S | D_Alpha_ZZWW1_T | D_Alpha_ZZWW1_U | D_Alpha_WWWW0_S | D_Alpha_WWWW0_T | D_Alpha_WWWW0_U | D_Alpha_WWWW2_S | D_Alpha_WWWW2_T | D_Alpha_ZZZZ_S | D_Alpha_ZZZZ_T | D_FT0_ZZWW0_S | D_FT0_ZZWW0_T | D_FT0_ZZWW0_U | D_FT0_ZZWW1_S | D_FT0_ZZWW1_T | D_FT0_ZZWW1_U | D_FT0_WWWW0_S | D_FT0_WWWW0_T | D_FT0_WWWW0_U | D_FT0_WWWW2_S | D_FT0_WWWW2_T | D_FT0_WWWW2_U | D_FT0_ZZZZ_S | D_FT0_ZZZZ_T | D_FT0_ZZZZ_U | D_FT0_AAAA_S | D_FT0_AAAA_T | D_FT0_AAAA_U | D_FT0_AAWW0_S | D_FT0_AAWW0_T | D_FT0_AAWW0_U | D_FT0_AAWW1_S | D_FT0_AAWW1_T | D_FT0_AAWW1_U | D_FT0_AAZZ_S | D_FT0_AAZZ_T | D_FT0_AAZZ_U | D_FT0_AZWW0_S | D_FT0_AZWW0_T | D_FT0_AZWW0_U | D_FT0_AZWW1_S | D_FT0_AZWW1_T | D_FT0_AZWW1_U | D_FT0_AAAZ_S | D_FT0_AAAZ_T | D_FT0_AAAZ_U | D_FT0_AZZZ_S | D_FT0_AZZZ_T | D_FT0_AZZZ_U | D_FT1_ZZWW0_S | D_FT1_ZZWW0_T | D_FT1_ZZWW0_U | D_FT1_ZZWW1_S | D_FT1_ZZWW1_T | D_FT1_ZZWW1_U | D_FT1_WWWW0_S | D_FT1_WWWW0_T | D_FT1_WWWW0_U | D_FT1_WWWW2_S | D_FT1_WWWW2_T | D_FT1_WWWW2_U | D_FT1_ZZZZ_S | D_FT1_ZZZZ_T | D_FT1_ZZZZ_U | D_FT1_AAAA_S | D_FT1_AAAA_T | D_FT1_AAAA_U | D_FT1_AAWW0_S | D_FT1_AAWW0_T | D_FT1_AAWW0_U | D_FT1_AAWW1_S | D_FT1_AAWW1_T | D_FT1_AAWW1_U | D_FT1_AAZZ_S | D_FT1_AAZZ_T | D_FT1_AAZZ_U | D_FT1_AZWW0_S | D_FT1_AZWW0_T | D_FT1_AZWW0_U | D_FT1_AZWW1_S | D_FT1_AZWW1_T | D_FT1_AZWW1_U | D_FT1_AAAZ_S | D_FT1_AAAZ_T | D_FT1_AAAZ_U | D_FT1_AZZZ_S | D_FT1_AZZZ_T | D_FT1_AZZZ_U | D_FT2_ZZWW0_S | D_FT2_ZZWW0_T | D_FT2_ZZWW0_U | D_FT2_ZZWW1_S | D_FT2_ZZWW1_T | D_FT2_ZZWW1_U | D_FT2_WWWW0_S | D_FT2_WWWW0_T | D_FT2_WWWW0_U | D_FT2_WWWW2_S | D_FT2_WWWW2_T | D_FT2_WWWW2_U | D_FT2_ZZZZ_S | D_FT2_ZZZZ_T | D_FT2_ZZZZ_U | D_FT2_AAAA_S | D_FT2_AAAA_T | D_FT2_AAAA_U | D_FT2_AAWW0_S | D_FT2_AAWW0_T | D_FT2_AAWW0_U | D_FT2_AAWW1_S | D_FT2_AAWW1_T | D_FT2_AAWW1_U | D_FT2_AAZZ_S | D_FT2_AAZZ_T | D_FT2_AAZZ_U | D_FT2_AZWW0_S | D_FT2_AZWW0_T | D_FT2_AZWW0_U | D_FT2_AZWW1_S | D_FT2_AZWW1_T | D_FT2_AZWW1_U | D_FT2_AAAZ_S | D_FT2_AAAZ_T | D_FT2_AAAZ_U | D_FT2_AZZZ_S | D_FT2_AZZZ_T | D_FT2_AZZZ_U | D_FTrsi_ZZWW0_S | D_FTrsi_ZZWW0_T | D_FTrsi_ZZWW0_U | D_FTrsi_ZZWW1_S | D_FTrsi_ZZWW1_T | D_FTrsi_ZZWW1_U | D_FTrsi_WWWW0_S | D_FTrsi_WWWW0_T | D_FTrsi_WWWW0_U | D_FTrsi_WWWW2_S | D_FTrsi_WWWW2_T | D_FTrsi_WWWW2_U | D_FTrsi_ZZZZ_S | D_FTrsi_ZZZZ_T | D_FTrsi_ZZZZ_U | D_FTrsi_AAAA_S | D_FTrsi_AAAA_T | D_FTrsi_AAAA_U | D_FTrsi_AAWW0_S | D_FTrsi_AAWW0_T | D_FTrsi_AAWW0_U | D_FTrsi_AAWW1_S | D_FTrsi_AAWW1_T | D_FTrsi_AAWW1_U | D_FTrsi_AAZZ_S | D_FTrsi_AAZZ_T | D_FTrsi_AAZZ_U | D_FTrsi_AZWW0_S | D_FTrsi_AZWW0_T | D_FTrsi_AZWW0_U | D_FTrsi_AZWW1_S | D_FTrsi_AZWW1_T | D_FTrsi_AZWW1_U | D_FTrsi_AAAZ_S | D_FTrsi_AAAZ_T | D_FTrsi_AAAZ_U | D_FTrsi_AZZZ_S | D_FTrsi_AZZZ_T | D_FTrsi_AZZZ_U | D_FM0_ZZWW0_S | D_FM0_ZZWW0_T | D_FM0_ZZWW0_U | D_FM0_ZZWW1_S | D_FM0_ZZWW1_T | D_FM0_ZZWW1_U | D_FM0_WWWW0_S | D_FM0_WWWW0_T | D_FM0_WWWW0_U | D_FM0_WWWW2_S | D_FM0_WWWW2_T | D_FM0_WWWW2_U | D_FM0_ZZZZ_S | D_FM0_ZZZZ_T | D_FM0_ZZZZ_U | D_FM1_ZZWW0_S | D_FM1_ZZWW0_T | D_FM1_ZZWW0_U | D_FM1_ZZWW1_S | D_FM1_ZZWW1_T | D_FM1_ZZWW1_U | D_FM1_WWWW0_S | D_FM1_WWWW0_T | D_FM1_WWWW0_U | D_FM1_WWWW2_S | D_FM1_WWWW2_T | D_FM1_WWWW2_U | D_FM1_ZZZZ_S | D_FM1_ZZZZ_T | D_FM1_ZZZZ_U | D_FM7_ZZWW0_S | D_FM7_ZZWW0_T | D_FM7_ZZWW0_U | D_FM7_ZZWW1_S | D_FM7_ZZWW1_T | D_FM7_ZZWW1_U | D_FM7_WWWW0_S | D_FM7_WWWW0_T | D_FM7_WWWW0_U | D_FM7_WWWW2_S | D_FM7_WWWW2_T | D_FM7_WWWW2_U | D_FM7_ZZZZ_S | D_FM7_ZZZZ_T | D_FM7_ZZZZ_U | D_Alpha_HHHH_S | D_Alpha_HHHH_T | D_Alpha_HHZZ0_S | D_Alpha_HHWW0_S | D_Alpha_HHZZ0_T | D_Alpha_HHWW0_T | D_Alpha_HHZZ1_S | D_Alpha_HHWW1_S | D_Alpha_HHZZ1_T | D_Alpha_HHWW1_T | D_Alpha_HHZZ1_U | D_Alpha_HHWW1_U | D_FM0_HHZZ0_S | D_FM0_HHWW0_S | D_FM0_HHZZ0_T | D_FM0_HHWW0_T | D_FM0_HHZZ0_U | D_FM0_HHWW0_U | D_FM0_HHZZ1_S | D_FM0_HHWW1_S | D_FM0_HHZZ1_T | D_FM0_HHWW1_T | D_FM0_HHZZ1_U | D_FM0_HHWW1_U | D_FM1_HHZZ0_S | D_FM1_HHWW0_S | D_FM1_HHZZ0_T | D_FM1_HHWW0_T | D_FM1_HHZZ0_U | D_FM1_HHWW0_U | D_FM1_HHZZ1_S | D_FM1_HHWW1_S | D_FM1_HHZZ1_T | D_FM1_HHWW1_T | D_FM1_HHZZ1_U | D_FM1_HHWW1_U | D_FM7_HHZZ0_S | D_FM7_HHWW0_S | D_FM7_HHZZ0_T | D_FM7_HHWW0_T | D_FM7_HHZZ0_U | D_FM7_HHWW0_U | D_FM7_HHZZ1_S | D_FM7_HHWW1_S | D_FM7_HHZZ1_T | D_FM7_HHWW1_T | D_FM7_HHZZ1_U | D_FM7_HHWW1_U | G_HWW | G_HHWW | G_HZZ | G_HHZZ | G_SWW | G_SWW_T | G_SSWW | G_SZZ | G_SZZ_T | G_SSZZ | G_SHH | G_SAA_T | G_SAZ_T | G_PNWW | G_PNZZ | G_PWZ | G_PWW | G_PSNWW | G_PSNZZ | G_PSNHH | G_FWW | G_FZZ | G_FWW_CF | G_FZZ_CF | G_FWW_T | G_FZZ_T | G_FHH | G_FHH_CF | G_TNWW | G_TNZZ | G_TSNWW | G_TSNZZ | G_TWZ | G_TWW | G_TNWW_CF | G_TNZZ_CF | G_TSNWW_CF | G_TSNZZ_CF | G_TWZ_CF | G_TWW_CF | G_Htt | G_Hbb | G_Hcc | G_Hmm | G_Htautau | G_H3 | G_H4 | FS_H4 | G_HGaZ | G_HGaGa | G_Hgg | G_HGaZ_anom | G_HGaGa_anom | G_HZZ_anom | G_HWW_anom | G_HGaZ_u | G_HZZ_u | G_HWW_u | Gs | I_Gs | G2 | Mass of flavor | Width of flavor | K_Matrix_Coeff of int | K_Matrix_Pole of int (* \begin{dubious} The current abstract syntax for parameter dependencies is admittedly tedious. Later, there will be a parser for a convenient concrete syntax as a part of a concrete syntax for models. But as these examples show, it should include simple functions. \end{dubious} *) type orders = int * int let orders = function | _ -> (0,0) (* \begin{subequations} \begin{align} \alpha_{\text{QED}} &= \frac{1}{137.0359895} \\ \sin^2\theta_w &= 0.23124 \end{align} \end{subequations} *) let input_parameters = [ Alpha_QED, 1. /. 137.0359895; Sin2thw, 0.23124; Mass (G Z), 91.187; Mass (M (N 1)), 0.0; Mass (M (L 1)), 0.51099907e-3; Mass (M (N 2)), 0.0; Mass (M (L 2)), 0.105658389; Mass (M (N 3)), 0.0; Mass (M (L 3)), 1.77705; Mass (M (U 1)), 5.0e-3; Mass (M (D 1)), 3.0e-3; Mass (M (U 2)), 1.2; Mass (M (D 2)), 0.1; Mass (M (U 3)), 174.0; Mass (M (D 3)), 4.2 ] (* \begin{subequations} \begin{align} e &= \sqrt{4\pi\alpha} \\ \sin\theta_w &= \sqrt{\sin^2\theta_w} \\ \cos\theta_w &= \sqrt{1-\sin^2\theta_w} \\ g &= \frac{e}{\sin\theta_w} \\ m_W &= \cos\theta_w m_Z \\ v &= \frac{2m_W}{g} \\ g_{CC} = -\frac{g}{2\sqrt2} &= -\frac{e}{2\sqrt2\sin\theta_w} \\ Q_{\text{lepton}} = -q_{\text{lepton}}e &= e \\ Q_{\text{up}} = -q_{\text{up}}e &= -\frac{2}{3}e \\ Q_{\text{down}} = -q_{\text{down}}e &= \frac{1}{3}e \\ \ii q_We = \ii g_{\gamma WW} &= \ii e \\ \ii g_{ZWW} &= \ii g \cos\theta_w \\ \ii g_{WWW} &= \ii g \end{align} \end{subequations} *) (* \begin{dubious} \ldots{} to be continued \ldots{} The quartic couplings can't be correct, because the dimensions are wrong! \begin{subequations} \begin{align} g_{HWW} &= g m_W = 2 \frac{m_W^2}{v}\\ g_{HHWW} &= 2 \frac{m_W^2}{v^2} = \frac{g^2}{2} \\ g_{HZZ} &= \frac{g}{\cos\theta_w}m_Z \\ g_{HHZZ} &= 2 \frac{m_Z^2}{v^2} = \frac{g^2}{2\cos\theta_w} \\ g_{Htt} &= \lambda_t \\ g_{Hbb} &= \lambda_b=\frac{m_b}{m_t}\lambda_t \\ g_{H^3} &= - \frac{3g}{2}\frac{m_H^2}{m_W} = - 3 \frac{m_H^2}{v} g_{H^4} &= - \frac{3g^2}{4} \frac{m_W^2}{v^2} = -3 \frac{m_H^2}{v^2} \end{align} \end{subequations} \end{dubious} *) let derived_parameters = [ Real E, Sqrt (Prod [Integer 4; Atom Pi; Atom Alpha_QED]); Real Sinthw, Sqrt (Atom Sin2thw); Real Costhw, Sqrt (Diff (Integer 1, Atom Sin2thw)); Real G_weak, Quot (Atom E, Atom Sinthw); Real (Mass (G Wp)), Prod [Atom Costhw; Atom (Mass (G Z))]; Real Vev, Quot (Prod [Integer 2; Atom (Mass (G Wp))], Atom G_weak); Real Q_lepton, Atom E; Real Q_up, Prod [Quot (Integer (-2), Integer 3); Atom E]; Real Q_down, Prod [Quot (Integer 1, Integer 3); Atom E]; Real G_CC, Neg (Quot (Atom G_weak, Prod [Integer 2; Sqrt (Integer 2)])); Complex I_Q_W, Prod [I; Atom E]; Complex I_G_weak, Prod [I; Atom G_weak]; Complex I_G_ZWW, Prod [I; Atom G_weak; Atom Costhw] ] (* \begin{equation} - \frac{g}{2\cos\theta_w} \end{equation} *) let g_over_2_costh = Quot (Neg (Atom G_weak), Prod [Integer 2; Atom Costhw]) (* \begin{subequations} \begin{align} - \frac{g}{2\cos\theta_w} g_V &= - \frac{g}{2\cos\theta_w} (T_3 - 2 q \sin^2\theta_w) \\ - \frac{g}{2\cos\theta_w} g_A &= - \frac{g}{2\cos\theta_w} T_3 \end{align} \end{subequations} *) let nc_coupling c t3 q = (Real_Array c, [Prod [g_over_2_costh; Diff (t3, Prod [Integer 2; q; Atom Sin2thw])]; Prod [g_over_2_costh; t3]]) let half = Quot (Integer 1, Integer 2) let derived_parameter_arrays = [ nc_coupling G_NC_neutrino half (Integer 0); nc_coupling G_NC_lepton (Neg half) (Integer (-1)); nc_coupling G_NC_up half (Quot (Integer 2, Integer 3)); nc_coupling G_NC_down (Neg half) (Quot (Integer (-1), Integer 3)) ] let parameters () = { input = input_parameters; derived = derived_parameters; derived_arrays = derived_parameter_arrays } module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) (* \begin{equation} \mathcal{L}_{\textrm{EM}} = - e \sum_i q_i \bar\psi_i\fmslash{A}\psi_i \end{equation} *) let mgm ((m1, g, m2), fbf, c) = ((M m1, G g, M m2), fbf, c) let mom ((m1, o, m2), fbf, c) = ((M m1, O o, M m2), fbf, c) let electromagnetic_currents n = List.map mgm [ ((L (-n), Ga, L n), FBF (1, Psibar, V, Psi), Q_lepton); ((U (-n), Ga, U n), FBF (1, Psibar, V, Psi), Q_up); ((D (-n), Ga, D n), FBF (1, Psibar, V, Psi), Q_down) ] let color_currents n = List.map mgm [ ((U (-n), Gl, U n), FBF ((-1), Psibar, V, Psi), Gs); ((D (-n), Gl, D n), FBF ((-1), Psibar, V, Psi), Gs) ] (* \begin{equation} \mathcal{L}_{\textrm{NC}} = - \frac{g}{2\cos\theta_W} \sum_i \bar\psi_i\fmslash{Z}(g_V^i-g_A^i\gamma_5)\psi_i \end{equation} *) let neutral_currents n = List.map mgm [ ((L (-n), Z, L n), FBF (1, Psibar, VA, Psi), G_NC_lepton); ((N (-n), Z, N n), FBF (1, Psibar, VA, Psi), G_NC_neutrino); ((U (-n), Z, U n), FBF (1, Psibar, VA, Psi), G_NC_up); ((D (-n), Z, D n), FBF (1, Psibar, VA, Psi), G_NC_down) ] (* \begin{equation} \mathcal{L}_{\textrm{CC}} = - \frac{g}{2\sqrt2} \sum_i \bar\psi_i (T^+\fmslash{W}^+ + T^-\fmslash{W}^-)(1-\gamma_5)\psi_i \end{equation} *) let charged_currents' n = List.map mgm [ ((L (-n), Wm, N n), FBF (1, Psibar, VL, Psi), G_CC); ((N (-n), Wp, L n), FBF (1, Psibar, VL, Psi), G_CC) ] let charged_currents'' n = List.map mgm [ ((D (-n), Wm, U n), FBF (1, Psibar, VL, Psi), G_CC); ((U (-n), Wp, D n), FBF (1, Psibar, VL, Psi), G_CC) ] let charged_currents_triv = ThoList.flatmap charged_currents' [1;2;3] @ ThoList.flatmap charged_currents'' [1;2;3] let charged_currents_ckm = let charged_currents_2 n1 n2 = List.map mgm [ ((D (-n1), Wm, U n2), FBF (1, Psibar, VL, Psi), G_CCQ (n2,n1)); ((U (-n1), Wp, D n2), FBF (1, Psibar, VL, Psi), G_CCQ (n1,n2)) ] in ThoList.flatmap charged_currents' [1;2;3] @ List.flatten (Product.list2 charged_currents_2 [1;2;3] [1;2;3]) let yukawa = [ ((M (U (-3)), O H, M (U 3)), FBF (1, Psibar, S, Psi), G_Htt); ((M (D (-3)), O H, M (D 3)), FBF (1, Psibar, S, Psi), G_Hbb); ((M (U (-2)), O H, M (U 2)), FBF (1, Psibar, S, Psi), G_Hcc); ((M (L (-3)), O H, M (L 3)), FBF (1, Psibar, S, Psi), G_Htautau) ] @ if Flags.higgs_hmm then [ ((M (L (-2)), O H, M (L 2)), FBF (1, Psibar, S, Psi), G_Hmm)] else [] (* \begin{equation} \mathcal{L}_{\textrm{TGC}} = - e \partial_\mu A_\nu W_+^\mu W_-^\nu + \ldots - e \cot\theta_w \partial_\mu Z_\nu W_+^\mu W_-^\nu + \ldots \end{equation} *) let tgc ((g1, g2, g3), t, c) = ((G g1, G g2, G g3), t, c) let standard_triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW); ((Gl, Gl, Gl), Gauge_Gauge_Gauge 1, I_Gs)] (* \begin{multline} \mathcal{L}_{\textrm{TGC}}(g_1,\kappa) = g_1 \mathcal{L}_T(V,W^+,W^-) \\ + \frac{\kappa+g_1}{2} \Bigl(\mathcal{L}_T(W^-,V,W^+) - \mathcal{L}_T(W^+,V,W^-)\Bigr)\\ + \frac{\kappa-g_1}{2} \Bigl(\mathcal{L}_L(W^-,V,W^+) - \mathcal{L}_T(W^+,V,W^-)\Bigr) \end{multline} *) (* \begin{dubious} The whole thing in the LEP2 workshop notation: \begin{multline} \ii\mathcal{L}_{\textrm{TGC},V} / g_{WWV} = \\ g_1^V V^\mu (W^-_{\mu\nu}W^{+,\nu}-W^+_{\mu\nu}W^{-,\nu}) + \kappa_V W^+_\mu W^-_\nu V^{\mu\nu} + \frac{\lambda_V}{m_W^2} V_{\mu\nu} W^-_{\rho\mu} W^{+,\hphantom{\nu}\rho}_{\hphantom{+,}\nu} \\ + \ii g_5^V \epsilon_{\mu\nu\rho\sigma} \left( (\partial^\rho W^{-,\mu}) W^{+,\nu} - W^{-,\mu}(\partial^\rho W^{+,\nu}) \right) V^\sigma \\ + \ii g_4^V W^-_\mu W^+_\nu (\partial^\mu V^\nu + \partial^\nu V^\mu) - \frac{\tilde\kappa_V}{2} W^-_\mu W^+_\nu \epsilon^{\mu\nu\rho\sigma} V_{\rho\sigma} - \frac{\tilde\lambda_V}{2m_W^2} W^-_{\rho\mu} W^{+,\mu}_{\hphantom{+,\mu}\nu} \epsilon^{\nu\rho\alpha\beta} V_{\alpha\beta} \end{multline} using the conventions of Itzykson and Zuber with $\epsilon^{0123} = +1$. \end{dubious} *) (* \begin{dubious} This is equivalent to the notation of Hagiwara et al.~\cite{HPZH87}, if we remember that they have opposite signs for~$g_{WWV}$: \begin{multline} \mathcal{L}_{WWV} / (-g_{WWV}) = \\ \ii g_1^V \left( W^\dagger_{\mu\nu} W^\mu - W^\dagger_\mu W^\mu_{\hphantom{\mu}\nu} \right) V^\nu + \ii \kappa_V W^\dagger_\mu W_\nu V^{\mu\nu} + \ii \frac{\lambda_V}{m_W^2} W^\dagger_{\lambda\mu} W^\mu_{\hphantom{\mu}\nu} V^{\nu\lambda} \\ - g_4^V W^\dagger_\mu W_\nu \left(\partial^\mu V^\nu + \partial^\nu V^\mu \right) + g_5^V \epsilon^{\mu\nu\lambda\sigma} \left( W^\dagger_\mu \stackrel{\leftrightarrow}{\partial_\lambda} W_\nu \right) V_\sigma\\ + \ii \tilde\kappa_V W^\dagger_\mu W_\nu \tilde{V}^{\mu\nu} + \ii\frac{\tilde\lambda_V}{m_W^2} W^\dagger_{\lambda\mu} W^\mu_{\hphantom{\mu}\nu} \tilde{V}^{\nu\lambda} \end{multline} Here $V^\mu$ stands for either the photon or the~$Z$ field, $W^\mu$ is the $W^-$ field, $W_{\mu\nu} = \partial_\mu W_\nu - \partial_\nu W_\mu$, $V_{\mu\nu} = \partial_\mu V_\nu - \partial_\nu V_\mu$, and $\tilde{V}_{\mu\nu} = \frac{1}{2} \epsilon_{\mu\nu\lambda\sigma} V^{\lambda\sigma}$. \end{dubious} *) let anomalous_triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Dim4_Vector_Vector_Vector_T (-1), I_G1_AWW); ((Z, Wm, Wp), Dim4_Vector_Vector_Vector_T (-1), I_G1_ZWW); ((Wm, Ga, Wp), Dim4_Vector_Vector_Vector_T 1, I_G1_plus_kappa_minus_G4_AWW); ((Wm, Z, Wp), Dim4_Vector_Vector_Vector_T 1, I_G1_plus_kappa_minus_G4_ZWW); ((Wp, Ga, Wm), Dim4_Vector_Vector_Vector_T (-1), I_G1_plus_kappa_plus_G4_AWW); ((Wp, Z, Wm), Dim4_Vector_Vector_Vector_T (-1), I_G1_plus_kappa_plus_G4_ZWW); ((Wm, Ga, Wp), Dim4_Vector_Vector_Vector_L (-1), I_G1_minus_kappa_plus_G4_AWW); ((Wm, Z, Wp), Dim4_Vector_Vector_Vector_L (-1), I_G1_minus_kappa_plus_G4_ZWW); ((Wp, Ga, Wm), Dim4_Vector_Vector_Vector_L 1, I_G1_minus_kappa_minus_G4_AWW); ((Wp, Z, Wm), Dim4_Vector_Vector_Vector_L 1, I_G1_minus_kappa_minus_G4_ZWW); ((Ga, Wm, Wp), Dim4_Vector_Vector_Vector_L5 (-1), I_kappa5_AWW); ((Z, Wm, Wp), Dim4_Vector_Vector_Vector_L5 (-1), I_kappa5_ZWW); ((Ga, Wm, Wp), Dim4_Vector_Vector_Vector_T5 (-1), G5_AWW); ((Z, Wm, Wp), Dim4_Vector_Vector_Vector_T5 (-1), G5_ZWW); ((Ga, Wp, Wm), Dim6_Gauge_Gauge_Gauge (-1), I_lambda_AWW); ((Z, Wp, Wm), Dim6_Gauge_Gauge_Gauge (-1), I_lambda_ZWW); ((Ga, Wp, Wm), Dim6_Gauge_Gauge_Gauge_5 (-1), I_lambda5_AWW); ((Z, Wp, Wm), Dim6_Gauge_Gauge_Gauge_5 (-1), I_lambda5_ZWW) ] let triple_gauge = if Flags.triple_anom then anomalous_triple_gauge else standard_triple_gauge (* \begin{equation} \mathcal{L}_{\textrm{QGC}} = - g^2 W_{+,\mu} W_{-,\nu} W_+^\mu W_-^\nu + \ldots \end{equation} *) (* Actually, quartic gauge couplings are a little bit more straightforward using auxiliary fields. Here we have to impose the antisymmetry manually: \begin{subequations} \begin{multline} (W^{+,\mu}_1 W^{-,\nu}_2 - W^{+,\nu}_1 W^{-,\mu}_2) (W^+_{3,\mu} W^-_{4,\nu} - W^+_{3,\nu} W^-_{4,\mu}) \\ = 2(W^+_1W^+_3)(W^-_2W^-_4) - 2(W^+_1W^-_4)(W^-_2W^+_3) \end{multline} also ($V$ can be $A$ or $Z$) \begin{multline} (W^{+,\mu}_1 V^\nu_2 - W^{+,\nu}_1 V^\mu_2) (W^-_{3,\mu} V_{4,\nu} - W^-_{3,\nu} V_{4,\mu}) \\ = 2(W^+_1W^-_3)(V_2V_4) - 2(W^+_1V_4)(V_2W^-_3) \end{multline} \end{subequations} *) (* \begin{subequations} \begin{multline} W^{+,\mu} W^{-,\nu} W^+_\mu W^-_\nu \end{multline} \end{subequations} *) let qgc ((g1, g2, g3, g4), t, c) = ((G g1, G g2, G g3, G g4), t, c) let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] let standard_quartic_gauge = List.map qgc [ (Wm, Wp, Wm, Wp), gauge4, G_WWWW; (Wm, Z, Wp, Z), minus_gauge4, G_ZZWW; (Wm, Z, Wp, Ga), minus_gauge4, G_AZWW; (Wm, Ga, Wp, Ga), minus_gauge4, G_AAWW; (Gl, Gl, Gl, Gl), gauge4, G2 ] (* \begin{subequations} \begin{align} \mathcal{L}_4 &= \alpha_4 \left( \frac{g^4}{2}\left( (W^+_\mu W^{-,\mu})^2 + W^+_\mu W^{+,\mu} W^-_\mu W^{-,\mu} \right)\right.\notag \\ &\qquad\qquad\qquad \left. + \frac{g^4}{\cos^2\theta_w} W^+_\mu Z^\mu W^-_\nu Z^\nu + \frac{g^4}{4\cos^4\theta_w} (Z_\mu Z^\mu)^2 \right) \\ \mathcal{L}_5 &= \alpha_5 \left( g^4 (W^+_\mu W^{-,\mu})^2 + \frac{g^4}{\cos^2\theta_w} W^+_\mu W^{-,\mu} Z_\nu Z^\nu + \frac{g^4}{4\cos^4\theta_w} (Z_\mu Z^\mu)^2 \right) \end{align} \end{subequations} or \begin{multline} \mathcal{L}_4 + \mathcal{L}_5 = (\alpha_4+2\alpha_5) g^4 \frac{1}{2} (W^+_\mu W^{-,\mu})^2 \\ + 2\alpha_4 g^4 \frac{1}{4} W^+_\mu W^{+,\mu} W^-_\mu W^{-,\mu} + \alpha_4 \frac{g^4}{\cos^2\theta_w} W^+_\mu Z^\mu W^-_\nu Z^\nu \\ + 2\alpha_5 \frac{g^4}{\cos^2\theta_w} \frac{1}{2} W^+_\mu W^{-,\mu} Z_\nu Z^\nu + (2\alpha_4 + 2\alpha_5) \frac{g^4}{\cos^4\theta_w} \frac{1}{8} (Z_\mu Z^\mu)^2 \end{multline} and therefore \begin{subequations} \begin{align} \alpha_{(WW)_0} &= (\alpha_4+2\alpha_5) g^4 \\ \alpha_{(WW)_2} &= 2\alpha_4 g^4 \\ \alpha_{(WZ)_0} &= 2\alpha_5 \frac{g^4}{\cos^2\theta_w} \\ \alpha_{(WZ)_1} &= \alpha_4 \frac{g^4}{\cos^2\theta_w} \\ \alpha_{ZZ} &= (2\alpha_4 + 2\alpha_5) \frac{g^4}{\cos^4\theta_w} \end{align} \end{subequations} *) let anomalous_quartic_gauge = if Flags.quartic_anom then List.map qgc [ ((Wm, Wm, Wp, Wp), Vector4 [(1, C_13_42); (1, C_14_23)], Alpha_WWWW0); ((Wm, Wm, Wp, Wp), Vector4 [1, C_12_34], Alpha_WWWW2); ((Z, Z, Z, Z), Vector4 [(1, C_12_34); (1, C_13_42); (1, C_14_23)], Alpha_ZZZZ); ((Wm, Wp, Z, Z), Vector4 [1, C_12_34], Alpha_ZZWW0); ((Wm, Wp, Z, Z), Vector4 [(1, C_13_42); (1, C_14_23)], Alpha_ZZWW1)] @ (if Flags.k_matrix_tm then List.map qgc [((Wm, Wm, Wp, Wp), Dim8_Vector4_t_0 [1, C_13_42], FT0_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_t_0 [1, C_14_23], FT0_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_t_0 [1, C_12_34], FT0_WWWW2); ((Wm, Wm, Wp, Wp), Dim8_Vector4_t_1 [1, C_13_42], FT1_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_t_1 [1, C_14_23], FT1_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_t_1 [1, C_12_34], FT1_WWWW2); ((Wm, Wm, Wp, Wp), Dim8_Vector4_t_2 [1, C_13_42], FT2_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_t_2 [1, C_14_23], FT2_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_t_2 [1, C_12_34], FT2_WWWW2); ((Wm, Wm, Wp, Wp), Dim8_Vector4_m_0 [1, C_13_42], FM0_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_m_0 [1, C_14_23], FM0_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_m_0 [1, C_12_34], FM0_WWWW2); ((Wm, Wm, Wp, Wp), Dim8_Vector4_m_1 [1, C_13_42], FM1_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_m_1 [1, C_14_23], FM1_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_m_1 [1, C_12_34], FM1_WWWW2); ((Wm, Wm, Wp, Wp), Dim8_Vector4_m_7 [1, C_13_42], FM7_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_m_7 [1, C_14_23], FM7_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_m_7 [1, C_12_34], FM7_WWWW2); ((Wm, Wp, Z, Z), Dim8_Vector4_t_0 [1, C_12_34], FT0_ZZWW0); ((Wm, Wp, Z, Z), Dim8_Vector4_t_0 [1, C_13_42], FT0_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_t_0 [1, C_14_23], FT0_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_t_1 [1, C_12_34], FT1_ZZWW0); ((Wm, Wp, Z, Z), Dim8_Vector4_t_1 [1, C_13_42], FT1_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_t_1 [1, C_14_23], FT1_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_t_2 [1, C_12_34], FT2_ZZWW0); ((Wm, Wp, Z, Z), Dim8_Vector4_t_2 [1, C_13_42], FT2_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_t_2 [1, C_14_23], FT2_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_m_0 [1, C_12_34], FM0_ZZWW0); ((Wm, Wp, Z, Z), Dim8_Vector4_m_0 [1, C_13_42], FM0_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_m_0 [1, C_14_23], FM0_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_m_1 [1, C_12_34], FM1_ZZWW0); ((Wm, Wp, Z, Z), Dim8_Vector4_m_1 [1, C_13_42], FM1_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_m_1 [1, C_14_23], FM1_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_m_7 [1, C_12_34], FM7_ZZWW0); ((Wm, Wp, Z, Z), Dim8_Vector4_m_7 [1, C_13_42], FM7_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_m_7 [1, C_14_23], FM7_ZZWW1); ((Z, Z, Z, Z), Dim8_Vector4_t_0 [1, C_12_34], FT0_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_t_0 [1, C_13_42], FT0_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_t_0 [1, C_14_23], FT0_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_t_1 [1, C_12_34], FT1_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_t_1 [1, C_13_42], FT1_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_t_1 [1, C_14_23], FT1_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_t_2 [1, C_12_34], FT2_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_t_2 [1, C_13_42], FT2_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_t_2 [1, C_14_23], FT2_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_m_0 [1, C_12_34], FM0_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_m_0 [1, C_13_42], FM0_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_m_0 [1, C_14_23], FM0_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_m_1 [1, C_12_34], FM1_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_m_1 [1, C_13_42], FM1_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_m_1 [1, C_14_23], FM1_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_m_7 [1, C_12_34], FM7_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_m_7 [1, C_13_42], FM7_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_m_7 [1, C_14_23], FM7_ZZZZ); ((Ga, Ga, Ga, Ga), Dim8_Vector4_t_0 [1, C_12_34], FT0_AAAA); ((Ga, Ga, Ga, Ga), Dim8_Vector4_t_0 [1, C_13_42], FT0_AAAA); ((Ga, Ga, Ga, Ga), Dim8_Vector4_t_0 [1, C_14_23], FT0_AAAA); ((Ga, Ga, Ga, Ga), Dim8_Vector4_t_1 [1, C_12_34], FT1_AAAA); ((Ga, Ga, Ga, Ga), Dim8_Vector4_t_1 [1, C_13_42], FT1_AAAA); ((Ga, Ga, Ga, Ga), Dim8_Vector4_t_1 [1, C_14_23], FT1_AAAA); ((Ga, Ga, Ga, Ga), Dim8_Vector4_t_2 [1, C_12_34], FT2_AAAA); ((Ga, Ga, Ga, Ga), Dim8_Vector4_t_2 [1, C_13_42], FT2_AAAA); ((Ga, Ga, Ga, Ga), Dim8_Vector4_t_2 [1, C_14_23], FT2_AAAA); ((Wm, Wp, Ga, Ga), Dim8_Vector4_t_0 [1, C_12_34], FT0_AAWW0); ((Wm, Wp, Ga, Ga), Dim8_Vector4_t_0 [1, C_13_42], FT0_AAWW1); ((Wm, Wp, Ga, Ga), Dim8_Vector4_t_0 [1, C_14_23], FT0_AAWW1); ((Wm, Wp, Ga, Ga), Dim8_Vector4_t_1 [1, C_12_34], FT1_AAWW0); ((Wm, Wp, Ga, Ga), Dim8_Vector4_t_1 [1, C_13_42], FT1_AAWW1); ((Wm, Wp, Ga, Ga), Dim8_Vector4_t_1 [1, C_14_23], FT1_AAWW1); ((Wm, Wp, Ga, Ga), Dim8_Vector4_t_2 [1, C_12_34], FT2_AAWW0); ((Wm, Wp, Ga, Ga), Dim8_Vector4_t_2 [1, C_13_42], FT2_AAWW1); ((Wm, Wp, Ga, Ga), Dim8_Vector4_t_2 [1, C_14_23], FT2_AAWW1); ((Z, Z, Ga, Ga), Dim8_Vector4_t_0 [1, C_12_34], FT0_AAZZ); ((Z, Z, Ga, Ga), Dim8_Vector4_t_0 [1, C_13_42], FT0_AAZZ); ((Z, Z, Ga, Ga), Dim8_Vector4_t_0 [1, C_14_23], FT0_AAZZ); ((Z, Z, Ga, Ga), Dim8_Vector4_t_1 [1, C_12_34], FT1_AAZZ); ((Z, Z, Ga, Ga), Dim8_Vector4_t_1 [1, C_13_42], FT1_AAZZ); ((Z, Z, Ga, Ga), Dim8_Vector4_t_1 [1, C_14_23], FT1_AAZZ); ((Z, Z, Ga, Ga), Dim8_Vector4_t_2 [1, C_12_34], FT2_AAZZ); ((Z, Z, Ga, Ga), Dim8_Vector4_t_2 [1, C_13_42], FT2_AAZZ); ((Z, Z, Ga, Ga), Dim8_Vector4_t_2 [1, C_14_23], FT2_AAZZ); ((Ga, Z, Wp, Wm), Dim8_Vector4_t_0 [1, C_12_34], FT0_AZWW0); ((Ga, Z, Wp, Wm), Dim8_Vector4_t_0 [1, C_13_42], FT0_AZWW1); ((Ga, Z, Wp, Wm), Dim8_Vector4_t_0 [1, C_14_23], FT0_AZWW1); ((Ga, Z, Wp, Wm), Dim8_Vector4_t_1 [1, C_12_34], FT1_AZWW0); ((Ga, Z, Wp, Wm), Dim8_Vector4_t_1 [1, C_13_42], FT1_AZWW1); ((Ga, Z, Wp, Wm), Dim8_Vector4_t_1 [1, C_14_23], FT1_AZWW1); ((Ga, Z, Wp, Wm), Dim8_Vector4_t_2 [1, C_12_34], FT2_AZWW0); ((Ga, Z, Wp, Wm), Dim8_Vector4_t_2 [1, C_13_42], FT2_AZWW1); ((Ga, Z, Wp, Wm), Dim8_Vector4_t_2 [1, C_14_23], FT2_AZWW1); ((Ga, Ga, Ga, Z), Dim8_Vector4_t_0 [1, C_12_34], FT0_AAAZ); ((Ga, Ga, Ga, Z), Dim8_Vector4_t_0 [1, C_13_42], FT0_AAAZ); ((Ga, Ga, Ga, Z), Dim8_Vector4_t_0 [1, C_14_23], FT0_AAAZ); ((Ga, Ga, Ga, Z), Dim8_Vector4_t_1 [1, C_12_34], FT1_AAAZ); ((Ga, Ga, Ga, Z), Dim8_Vector4_t_1 [1, C_13_42], FT1_AAAZ); ((Ga, Ga, Ga, Z), Dim8_Vector4_t_1 [1, C_14_23], FT1_AAAZ); ((Ga, Ga, Ga, Z), Dim8_Vector4_t_2 [1, C_12_34], FT2_AAAZ); ((Ga, Ga, Ga, Z), Dim8_Vector4_t_2 [1, C_13_42], FT2_AAAZ); ((Ga, Ga, Ga, Z), Dim8_Vector4_t_2 [1, C_14_23], FT2_AAAZ); ((Ga, Z, Z, Z), Dim8_Vector4_t_0 [1, C_12_34], FT0_AZZZ); ((Ga, Z, Z, Z), Dim8_Vector4_t_0 [1, C_13_42], FT0_AZZZ); ((Ga, Z, Z, Z), Dim8_Vector4_t_0 [1, C_14_23], FT0_AZZZ); ((Ga, Z, Z, Z), Dim8_Vector4_t_1 [1, C_12_34], FT1_AZZZ); ((Ga, Z, Z, Z), Dim8_Vector4_t_1 [1, C_13_42], FT1_AZZZ); ((Ga, Z, Z, Z), Dim8_Vector4_t_1 [1, C_14_23], FT1_AZZZ); ((Ga, Z, Z, Z), Dim8_Vector4_t_2 [1, C_12_34], FT2_AZZZ); ((Ga, Z, Z, Z), Dim8_Vector4_t_2 [1, C_13_42], FT2_AZZZ); ((Ga, Z, Z, Z), Dim8_Vector4_t_2 [1, C_14_23], FT2_AZZZ)] else [] ) else [] (* In any diagonal channel~$\chi$, the scattering amplitude~$a_\chi(s)$ is unitary iff\footnote{% Trivial proof: \begin{equation} -1 = \textrm{Im}\left(\frac{1}{a_\chi(s)}\right) = \frac{\textrm{Im}(a_\chi^*(s))}{ |a_\chi(s)|^2 } = - \frac{\textrm{Im}(a_\chi(s))}{ |a_\chi(s)|^2 } \end{equation} i.\,e.~$\textrm{Im}(a_\chi(s)) = |a_\chi(s)|^2$.} \begin{equation} \textrm{Im}\left(\frac{1}{a_\chi(s)}\right) = -1 \end{equation} For a real perturbative scattering amplitude~$r_\chi(s)$ this can be enforced easily--and arbitrarily--by \begin{equation} \frac{1}{a_\chi(s)} = \frac{1}{r_\chi(s)} - \mathrm{i} \end{equation} *) let k_matrix_quartic_gauge = if Flags.k_matrix then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_WWWW0_S); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_jr (0, [(1, C_14_23)]), D_Alpha_WWWW0_T); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_jr (0, [(1, C_13_42)]), D_Alpha_WWWW0_U); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_WWWW0_S); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_jr (0, [(1, C_14_23)]), D_Alpha_WWWW0_T); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_jr (0, [(1, C_13_42)]), D_Alpha_WWWW0_U); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_WWWW2_S); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_jr (0, [(1, C_13_42); (1, C_14_23)]), D_Alpha_WWWW2_T); ((Wm, Wp, Z, Z), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_ZZWW0_S); ((Wm, Wp, Z, Z), Vector4_K_Matrix_jr (0, [(1, C_13_42); (1, C_14_23)]), D_Alpha_ZZWW0_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_ZZWW1_S); ((Wm, Z, Wp, Z), Vector4_K_Matrix_jr (0, [(1, C_13_42)]), D_Alpha_ZZWW1_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_jr (0, [(1, C_14_23)]), D_Alpha_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_jr (1, [(1, C_12_34)]), D_Alpha_ZZWW1_S); ((Wp, Z, Z, Wm), Vector4_K_Matrix_jr (1, [(1, C_13_42)]), D_Alpha_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_jr (1, [(1, C_14_23)]), D_Alpha_ZZWW1_T); ((Z, Wp, Wm, Z), Vector4_K_Matrix_jr (2, [(1, C_12_34)]), D_Alpha_ZZWW1_S); ((Z, Wp, Wm, Z), Vector4_K_Matrix_jr (2, [(1, C_13_42)]), D_Alpha_ZZWW1_U); ((Z, Wp, Wm, Z), Vector4_K_Matrix_jr (2, [(1, C_14_23)]), D_Alpha_ZZWW1_T); ((Z, Z, Z, Z), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_jr (0, [(1, C_13_42); (1, C_14_23)]), D_Alpha_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_jr (3, [(1, C_14_23)]), D_Alpha_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_jr (3, [(1, C_13_42); (1, C_12_34)]), D_Alpha_ZZZZ_T)] else [] let k_matrix_quartic_gauge_t_0 = if Flags.k_matrix_tm then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_WWWW0_S); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_WWWW0_T); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_WWWW0_U); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_WWWW0_S); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_WWWW0_T); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_WWWW0_U); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_WWWW2_S); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_WWWW2_T); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_WWWW2_U); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_ZZWW0_S); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_ZZWW0_T); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_ZZWW0_U); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_ZZWW1_S); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_ZZWW1_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t0 (1, [(1, C_12_34)]), D_FT0_ZZWW1_S); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t0 (1, [(1, C_13_42)]), D_FT0_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t0 (1, [(1, C_14_23)]), D_FT0_ZZWW1_T); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t0 (2, [(1, C_12_34)]), D_FT0_ZZWW1_S); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t0 (2, [(1, C_13_42)]), D_FT0_ZZWW1_U); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t0 (2, [(1, C_14_23)]), D_FT0_ZZWW1_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_ZZZZ_U); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_14_23)]), D_FT0_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_13_42)]), D_FT0_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_12_34)]), D_FT0_ZZZZ_U); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_AAAA_S); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_AAAA_T); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_AAAA_U); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_14_23)]), D_FT0_AAAA_S); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_13_42)]), D_FT0_AAAA_T); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_12_34)]), D_FT0_AAAA_U); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_AAWW0_S); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_AAWW0_T); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_AAWW0_U); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_AAWW1_S); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_AAWW1_T); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_AAWW1_U); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t0 (1, [(1, C_12_34)]), D_FT0_AAWW1_S); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t0 (1, [(1, C_13_42)]), D_FT0_AAWW1_U); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t0 (1, [(1, C_14_23)]), D_FT0_AAWW1_T); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t0 (2, [(1, C_12_34)]), D_FT0_AAWW1_S); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t0 (2, [(1, C_13_42)]), D_FT0_AAWW1_U); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t0 (2, [(1, C_14_23)]), D_FT0_AAWW1_T); ((Ga, Z, Ga, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_AAZZ_S); ((Ga, Z, Ga, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_AAZZ_T); ((Ga, Z, Ga, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_AAZZ_U); ((Z, Ga, Z, Ga), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_AAZZ_S); ((Z, Ga, Z, Ga), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_AAZZ_T); ((Z, Ga, Z, Ga), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_AAZZ_U); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_AAZZ_S); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_AAZZ_T); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_AAZZ_U); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_AZWW0_S); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_AZWW0_T); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_AZWW0_U); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t0 (1, [(1, C_12_34)]), D_FT0_AZWW1_S); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t0 (1, [(1, C_13_42)]), D_FT0_AZWW1_T); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t0 (1, [(1, C_14_23)]), D_FT0_AZWW1_U); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t0 (1, [(1, C_12_34)]), D_FT0_AZWW1_S); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t0 (1, [(1, C_13_42)]), D_FT0_AZWW1_T); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t0 (1, [(1, C_14_23)]), D_FT0_AZWW1_U); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t0 (1, [(1, C_12_34)]), D_FT0_AZWW1_S); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t0 (1, [(1, C_13_42)]), D_FT0_AZWW1_T); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t0 (1, [(1, C_14_23)]), D_FT0_AZWW1_U); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t0 (1, [(1, C_12_34)]), D_FT0_AZWW1_S); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t0 (1, [(1, C_13_42)]), D_FT0_AZWW1_T); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t0 (1, [(1, C_14_23)]), D_FT0_AZWW1_U); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_12_34)]), D_FT0_AAAZ_S); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_13_42)]), D_FT0_AAAZ_T); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_14_23)]), D_FT0_AAAZ_U); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_12_34)]), D_FT0_AAAZ_S); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_13_42)]), D_FT0_AAAZ_T); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_14_23)]), D_FT0_AAAZ_U); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_12_34)]), D_FT0_AAAZ_S); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_13_42)]), D_FT0_AAAZ_T); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_14_23)]), D_FT0_AAAZ_U); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_12_34)]), D_FT0_AZZZ_S); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_13_42)]), D_FT0_AZZZ_T); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_14_23)]), D_FT0_AZZZ_U); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_12_34)]), D_FT0_AZZZ_S); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_13_42)]), D_FT0_AZZZ_T); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_14_23)]), D_FT0_AZZZ_U); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_12_34)]), D_FT0_AZZZ_S); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_13_42)]), D_FT0_AZZZ_T); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_14_23)]), D_FT0_AZZZ_U)] else [] let k_matrix_quartic_gauge_t_1 = if Flags.k_matrix_tm then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t1 (0, [(1, C_12_34)]), D_FT1_WWWW0_S); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_WWWW0_T); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_WWWW0_U); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t1 (0, [(1, C_12_34)]), D_FT1_WWWW0_S); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_WWWW0_T); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_WWWW0_U); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t1 (0, [(1, C_12_34)]), D_FT1_WWWW2_S); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_WWWW2_T); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_WWWW2_U); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_12_34)]), D_FT1_ZZWW0_S); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_ZZWW0_T); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_ZZWW0_U); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_12_34)]), D_FT1_ZZWW1_S); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_ZZWW1_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t1 (1, [(1, C_12_34)]), D_FT1_ZZWW1_S); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t1 (1, [(1, C_13_42)]), D_FT1_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t1 (1, [(1, C_14_23)]), D_FT1_ZZWW1_T); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t1 (2, [(1, C_12_34)]), D_FT1_ZZWW1_S); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t1 (2, [(1, C_13_42)]), D_FT1_ZZWW1_U); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t1 (2, [(1, C_14_23)]), D_FT1_ZZWW1_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_12_34)]), D_FT1_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_ZZZZ_U); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_14_23)]), D_FT1_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_13_42)]), D_FT1_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_12_34)]), D_FT1_ZZZZ_U); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t1 (0, [(1, C_12_34)]), D_FT1_AAAA_S); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_AAAA_T); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_AAAA_U); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_14_23)]), D_FT1_AAAA_S); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_13_42)]), D_FT1_AAAA_T); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_12_34)]), D_FT1_AAAA_U); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t1 (0, [(1, C_12_34)]), D_FT1_AAWW0_S); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_AAWW0_T); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_AAWW0_U); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t1 (0, [(1, C_12_34)]), D_FT1_AAWW1_S); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_AAWW1_T); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_AAWW1_U); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t1 (1, [(1, C_12_34)]), D_FT1_AAWW1_S); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t1 (1, [(1, C_13_42)]), D_FT1_AAWW1_U); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t1 (1, [(1, C_14_23)]), D_FT1_AAWW1_T); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t1 (2, [(1, C_12_34)]), D_FT1_AAWW1_S); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t1 (2, [(1, C_13_42)]), D_FT1_AAWW1_U); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t1 (2, [(1, C_14_23)]), D_FT1_AAWW1_T); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_12_34)]), D_FT1_AAZZ_S); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_AAZZ_T); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_AAZZ_U); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_14_23)]), D_FT1_AAZZ_S); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_13_42)]), D_FT1_AAZZ_T); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_12_34)]), D_FT1_AAZZ_U); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t1 (0, [(1, C_12_34)]), D_FT1_AZWW0_S); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_AZWW0_T); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_AZWW0_U); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t1 (1, [(1, C_12_34)]), D_FT1_AZWW1_S); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t1 (1, [(1, C_13_42)]), D_FT1_AZWW1_T); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t1 (1, [(1, C_14_23)]), D_FT1_AZWW1_U); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t1 (1, [(1, C_12_34)]), D_FT1_AZWW1_S); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t1 (1, [(1, C_13_42)]), D_FT1_AZWW1_T); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t1 (1, [(1, C_14_23)]), D_FT1_AZWW1_U); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t1 (1, [(1, C_12_34)]), D_FT1_AZWW1_S); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t1 (1, [(1, C_13_42)]), D_FT1_AZWW1_T); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t1 (1, [(1, C_14_23)]), D_FT1_AZWW1_U); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t1 (1, [(1, C_12_34)]), D_FT1_AZWW1_S); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t1 (1, [(1, C_13_42)]), D_FT1_AZWW1_T); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t1 (1, [(1, C_14_23)]), D_FT1_AZWW1_U); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_12_34)]), D_FT1_AAAZ_S); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_13_42)]), D_FT1_AAAZ_T); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_14_23)]), D_FT1_AAAZ_U); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_12_34)]), D_FT1_AAAZ_S); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_13_42)]), D_FT1_AAAZ_T); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_14_23)]), D_FT1_AAAZ_U); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_12_34)]), D_FT1_AAAZ_S); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_13_42)]), D_FT1_AAAZ_T); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_14_23)]), D_FT1_AAAZ_U); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_12_34)]), D_FT1_AZZZ_S); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_13_42)]), D_FT1_AZZZ_T); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_14_23)]), D_FT1_AZZZ_U); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_12_34)]), D_FT1_AZZZ_S); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_13_42)]), D_FT1_AZZZ_T); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_14_23)]), D_FT1_AZZZ_U); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_12_34)]), D_FT1_AZZZ_S); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_13_42)]), D_FT1_AZZZ_T); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_14_23)]), D_FT1_AZZZ_U)] else [] let k_matrix_quartic_gauge_t_2 = if Flags.k_matrix_tm then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_WWWW0_S); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_WWWW0_T); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_WWWW0_U); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_WWWW0_S); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_WWWW0_T); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_WWWW0_U); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_WWWW2_S); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_WWWW2_T); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_WWWW2_U); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_ZZWW0_S); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_ZZWW0_T); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_ZZWW0_U); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_ZZWW1_S); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_ZZWW1_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t2 (1, [(1, C_12_34)]), D_FT2_ZZWW1_S); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t2 (1, [(1, C_13_42)]), D_FT2_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t2 (1, [(1, C_14_23)]), D_FT2_ZZWW1_T); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t2 (2, [(1, C_12_34)]), D_FT2_ZZWW1_S); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t2 (2, [(1, C_13_42)]), D_FT2_ZZWW1_U); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t2 (2, [(1, C_14_23)]), D_FT2_ZZWW1_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_ZZZZ_U); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_14_23)]), D_FT2_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_13_42)]), D_FT2_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_12_34)]), D_FT2_ZZZZ_U); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_AAAA_S); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_AAAA_T); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_AAAA_U); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_14_23)]), D_FT2_AAAA_S); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_13_42)]), D_FT2_AAAA_T); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_12_34)]), D_FT2_AAAA_U); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_AAWW0_S); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_AAWW0_T); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_AAWW0_U); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_AAWW1_S); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_AAWW1_T); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_AAWW1_U); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t2 (1, [(1, C_12_34)]), D_FT2_AAWW1_S); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t2 (1, [(1, C_13_42)]), D_FT2_AAWW1_U); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t2 (1, [(1, C_14_23)]), D_FT2_AAWW1_T); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t2 (2, [(1, C_12_34)]), D_FT2_AAWW1_S); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t2 (2, [(1, C_13_42)]), D_FT2_AAWW1_U); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t2 (2, [(1, C_14_23)]), D_FT2_AAWW1_T); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_AAZZ_S); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_AAZZ_T); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_AAZZ_U); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_14_23)]), D_FT2_AAZZ_S); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_13_42)]), D_FT2_AAZZ_T); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_12_34)]), D_FT2_AAZZ_U); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_AZWW0_S); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_AZWW0_T); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_AZWW0_U); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t2 (1, [(1, C_12_34)]), D_FT2_AZWW1_S); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t2 (1, [(1, C_13_42)]), D_FT2_AZWW1_T); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t2 (1, [(1, C_14_23)]), D_FT2_AZWW1_U); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t2 (1, [(1, C_12_34)]), D_FT2_AZWW1_S); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t2 (1, [(1, C_13_42)]), D_FT2_AZWW1_T); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t2 (1, [(1, C_14_23)]), D_FT2_AZWW1_U); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t2 (1, [(1, C_12_34)]), D_FT2_AZWW1_S); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t2 (1, [(1, C_13_42)]), D_FT2_AZWW1_T); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t2 (1, [(1, C_14_23)]), D_FT2_AZWW1_U); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t2 (1, [(1, C_12_34)]), D_FT2_AZWW1_S); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t2 (1, [(1, C_13_42)]), D_FT2_AZWW1_T); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t2 (1, [(1, C_14_23)]), D_FT2_AZWW1_U); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_12_34)]), D_FT2_AAAZ_S); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_13_42)]), D_FT2_AAAZ_T); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_14_23)]), D_FT2_AAAZ_U); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_12_34)]), D_FT2_AAAZ_S); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_13_42)]), D_FT2_AAAZ_T); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_14_23)]), D_FT2_AAAZ_U); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_12_34)]), D_FT2_AAAZ_S); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_13_42)]), D_FT2_AAAZ_T); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_14_23)]), D_FT2_AAAZ_U); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_12_34)]), D_FT2_AZZZ_S); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_13_42)]), D_FT2_AZZZ_T); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_14_23)]), D_FT2_AZZZ_U); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_12_34)]), D_FT2_AZZZ_S); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_13_42)]), D_FT2_AZZZ_T); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_14_23)]), D_FT2_AZZZ_U); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_12_34)]), D_FT2_AZZZ_S); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_13_42)]), D_FT2_AZZZ_T); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_14_23)]), D_FT2_AZZZ_U)] else [] let k_matrix_quartic_gauge_t_rsi = if Flags.k_matrix_tm then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_WWWW0_S); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_WWWW0_T); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_WWWW0_U); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_WWWW0_S); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_WWWW0_T); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_WWWW0_U); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_WWWW2_S); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_WWWW2_T); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_WWWW2_U); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_ZZWW0_S); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_ZZWW0_T); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_ZZWW0_U); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_ZZWW1_S); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_ZZWW1_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_12_34)]), D_FTrsi_ZZWW1_S); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_13_42)]), D_FTrsi_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_14_23)]), D_FTrsi_ZZWW1_T); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t_rsi (2, [(1, C_12_34)]), D_FTrsi_ZZWW1_S); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t_rsi (2, [(1, C_13_42)]), D_FTrsi_ZZWW1_U); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t_rsi (2, [(1, C_14_23)]), D_FTrsi_ZZWW1_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_ZZZZ_U); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_14_23)]), D_FTrsi_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_13_42)]), D_FTrsi_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_12_34)]), D_FTrsi_ZZZZ_U); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_AAAA_S); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_AAAA_T); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_AAAA_U); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_14_23)]), D_FTrsi_AAAA_S); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_13_42)]), D_FTrsi_AAAA_T); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_12_34)]), D_FTrsi_AAAA_U); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_AAWW0_S); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_AAWW0_T); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_AAWW0_U); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_AAWW1_S); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_AAWW1_T); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_AAWW1_U); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_12_34)]), D_FTrsi_AAWW1_S); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_13_42)]), D_FTrsi_AAWW1_U); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_14_23)]), D_FTrsi_AAWW1_T); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t_rsi (2, [(1, C_12_34)]), D_FTrsi_AAWW1_S); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t_rsi (2, [(1, C_13_42)]), D_FTrsi_AAWW1_U); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t_rsi (2, [(1, C_14_23)]), D_FTrsi_AAWW1_T); ((Ga, Z, Ga, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_AAZZ_S); ((Ga, Z, Ga, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_AAZZ_T); ((Ga, Z, Ga, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_AAZZ_U); ((Z, Ga, Z, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_AAZZ_S); ((Z, Ga, Z, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_AAZZ_T); ((Z, Ga, Z, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_AAZZ_U); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_AAZZ_S); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_AAZZ_T); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_AAZZ_U); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_AZWW0_S); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_AZWW0_T); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_AZWW0_U); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_12_34)]), D_FTrsi_AZWW1_S); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_13_42)]), D_FTrsi_AZWW1_T); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_14_23)]), D_FTrsi_AZWW1_U); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_12_34)]), D_FTrsi_AZWW1_S); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_13_42)]), D_FTrsi_AZWW1_T); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_14_23)]), D_FTrsi_AZWW1_U); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_12_34)]), D_FTrsi_AZWW1_S); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_13_42)]), D_FTrsi_AZWW1_T); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_14_23)]), D_FTrsi_AZWW1_U); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_12_34)]), D_FTrsi_AZWW1_S); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_13_42)]), D_FTrsi_AZWW1_T); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_14_23)]), D_FTrsi_AZWW1_U); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_12_34)]), D_FTrsi_AAAZ_S); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_13_42)]), D_FTrsi_AAAZ_T); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_14_23)]), D_FTrsi_AAAZ_U); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_12_34)]), D_FTrsi_AAAZ_S); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_13_42)]), D_FTrsi_AAAZ_T); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_14_23)]), D_FTrsi_AAAZ_U); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_12_34)]), D_FTrsi_AAAZ_S); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_13_42)]), D_FTrsi_AAAZ_T); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_14_23)]), D_FTrsi_AAAZ_U); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_12_34)]), D_FTrsi_AZZZ_S); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_13_42)]), D_FTrsi_AZZZ_T); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_14_23)]), D_FTrsi_AZZZ_U); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_12_34)]), D_FTrsi_AZZZ_S); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_13_42)]), D_FTrsi_AZZZ_T); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_14_23)]), D_FTrsi_AZZZ_U); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_12_34)]), D_FTrsi_AZZZ_S); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_13_42)]), D_FTrsi_AZZZ_T); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_14_23)]), D_FTrsi_AZZZ_U)] else [] let k_matrix_quartic_gauge_m_0 = if Flags.k_matrix_tm then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_m0 (0, [(1, C_12_34)]), D_FM0_WWWW0_S); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_m0 (0, [(1, C_14_23)]), D_FM0_WWWW0_T); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_m0 (0, [(1, C_13_42)]), D_FM0_WWWW0_U); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_m0 (0, [(1, C_12_34)]), D_FM0_WWWW0_S); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_m0 (0, [(1, C_14_23)]), D_FM0_WWWW0_T); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_m0 (0, [(1, C_13_42)]), D_FM0_WWWW0_U); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_m0 (0, [(1, C_12_34)]), D_FM0_WWWW2_S); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_m0 (0, [(1, C_13_42)]), D_FM0_WWWW2_T); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_m0 (0, [(1, C_14_23)]), D_FM0_WWWW2_U); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_m0 (0, [(1, C_12_34)]), D_FM0_ZZWW0_S); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_m0 (0, [(1, C_13_42)]), D_FM0_ZZWW0_T); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_m0 (0, [(1, C_14_23)]), D_FM0_ZZWW0_U); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_m0 (0, [(1, C_12_34)]), D_FM0_ZZWW1_S); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_m0 (0, [(1, C_13_42)]), D_FM0_ZZWW1_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_m0 (0, [(1, C_14_23)]), D_FM0_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_m0 (1, [(1, C_12_34)]), D_FM0_ZZWW1_S); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_m0 (1, [(1, C_13_42)]), D_FM0_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_m0 (1, [(1, C_14_23)]), D_FM0_ZZWW1_T); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_m0 (2, [(1, C_12_34)]), D_FM0_ZZWW1_S); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_m0 (2, [(1, C_13_42)]), D_FM0_ZZWW1_U); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_m0 (2, [(1, C_14_23)]), D_FM0_ZZWW1_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m0 (0, [(1, C_12_34)]), D_FM0_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m0 (0, [(1, C_13_42)]), D_FM0_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m0 (0, [(1, C_14_23)]), D_FM0_ZZZZ_U); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m0 (3, [(1, C_14_23)]), D_FM0_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m0 (3, [(1, C_13_42)]), D_FM0_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m0 (3, [(1, C_12_34)]), D_FM0_ZZZZ_U)] else [] let k_matrix_quartic_gauge_m_1 = if Flags.k_matrix_tm then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_m1 (0, [(1, C_12_34)]), D_FM1_WWWW0_S); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_m1 (0, [(1, C_14_23)]), D_FM1_WWWW0_T); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_m1 (0, [(1, C_13_42)]), D_FM1_WWWW0_U); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_m1 (0, [(1, C_12_34)]), D_FM1_WWWW0_S); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_m1 (0, [(1, C_14_23)]), D_FM1_WWWW0_T); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_m1 (0, [(1, C_13_42)]), D_FM1_WWWW0_U); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_m1 (0, [(1, C_12_34)]), D_FM1_WWWW2_S); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_m1 (0, [(1, C_13_42)]), D_FM1_WWWW2_T); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_m1 (0, [(1, C_14_23)]), D_FM1_WWWW2_U); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_m1 (0, [(1, C_12_34)]), D_FM1_ZZWW0_S); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_m1 (0, [(1, C_13_42)]), D_FM1_ZZWW0_T); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_m1 (0, [(1, C_14_23)]), D_FM1_ZZWW0_U); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_m1 (0, [(1, C_12_34)]), D_FM1_ZZWW1_S); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_m1 (0, [(1, C_13_42)]), D_FM1_ZZWW1_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_m1 (0, [(1, C_14_23)]), D_FM1_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_m1 (1, [(1, C_12_34)]), D_FM1_ZZWW1_S); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_m1 (1, [(1, C_13_42)]), D_FM1_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_m1 (1, [(1, C_14_23)]), D_FM1_ZZWW1_T); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_m1 (2, [(1, C_12_34)]), D_FM1_ZZWW1_S); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_m1 (2, [(1, C_13_42)]), D_FM1_ZZWW1_U); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_m1 (2, [(1, C_14_23)]), D_FM1_ZZWW1_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m1 (0, [(1, C_12_34)]), D_FM1_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m1 (0, [(1, C_13_42)]), D_FM1_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m1 (0, [(1, C_14_23)]), D_FM1_ZZZZ_U); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m1 (3, [(1, C_14_23)]), D_FM1_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m1 (3, [(1, C_13_42)]), D_FM1_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m1 (3, [(1, C_12_34)]), D_FM1_ZZZZ_U)] else [] let k_matrix_quartic_gauge_m_7 = if Flags.k_matrix_tm then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_m7 (0, [(1, C_12_34)]), D_FM7_WWWW0_S); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_m7 (0, [(1, C_14_23)]), D_FM7_WWWW0_T); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_m7 (0, [(1, C_13_42)]), D_FM7_WWWW0_U); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_m7 (0, [(1, C_12_34)]), D_FM7_WWWW0_S); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_m7 (0, [(1, C_14_23)]), D_FM7_WWWW0_T); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_m7 (0, [(1, C_13_42)]), D_FM7_WWWW0_U); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_m7 (0, [(1, C_12_34)]), D_FM7_WWWW2_S); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_m7 (0, [(1, C_13_42)]), D_FM7_WWWW2_T); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_m7 (0, [(1, C_14_23)]), D_FM7_WWWW2_U); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_m7 (0, [(1, C_12_34)]), D_FM7_ZZWW0_S); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_m7 (0, [(1, C_13_42)]), D_FM7_ZZWW0_T); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_m7 (0, [(1, C_14_23)]), D_FM7_ZZWW0_U); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_m7 (0, [(1, C_12_34)]), D_FM7_ZZWW1_S); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_m7 (0, [(1, C_13_42)]), D_FM7_ZZWW1_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_m7 (0, [(1, C_14_23)]), D_FM7_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_m7 (1, [(1, C_12_34)]), D_FM7_ZZWW1_S); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_m7 (1, [(1, C_13_42)]), D_FM7_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_m7 (1, [(1, C_14_23)]), D_FM7_ZZWW1_T); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_m7 (2, [(1, C_12_34)]), D_FM7_ZZWW1_S); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_m7 (2, [(1, C_13_42)]), D_FM7_ZZWW1_U); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_m7 (2, [(1, C_14_23)]), D_FM7_ZZWW1_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m7 (0, [(1, C_12_34)]), D_FM7_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m7 (0, [(1, C_13_42)]), D_FM7_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m7 (0, [(1, C_14_23)]), D_FM7_ZZZZ_U); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m7 (3, [(1, C_14_23)]), D_FM7_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m7 (3, [(1, C_13_42)]), D_FM7_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m7 (3, [(1, C_12_34)]), D_FM7_ZZZZ_U)] else [] let k_matrix_2scalar_2gauge = if Flags.k_matrix_tm then if Flags.higgs_matrix then [ ((O H,O H,G Z,G Z), DScalar2_Vector2_K_Matrix_ms (0, [(1, C_12_34)]), D_Alpha_HHZZ0_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_K_Matrix_ms (0, [(1, C_13_42)]), D_Alpha_HHZZ0_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_K_Matrix_ms (0, [(1, C_14_23)]), D_Alpha_HHZZ0_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_K_Matrix_ms (3, [(1, C_14_23)]), D_Alpha_HHZZ1_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_K_Matrix_ms (3, [(1, C_13_42)]), D_Alpha_HHZZ1_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_K_Matrix_ms (3, [(1, C_12_34)]), D_Alpha_HHZZ1_U); ((O H,O H,G Z,G Z), DScalar2_Vector2_K_Matrix_ms (6, [(1, C_13_42)]), D_Alpha_HHZZ1_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_K_Matrix_ms (6, [(1, C_12_34)]), D_Alpha_HHZZ1_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_K_Matrix_ms (6, [(1, C_14_23)]), D_Alpha_HHZZ1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (0, [(1, C_12_34)]), D_Alpha_HHWW0_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (2, [(1, C_13_42)]), D_Alpha_HHWW0_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (1, [(1, C_14_23)]), D_Alpha_HHWW0_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (1, [(1, C_13_42)]), D_Alpha_HHWW0_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (2, [(1, C_14_23)]), D_Alpha_HHWW0_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (3, [(1, C_14_23)]), D_Alpha_HHWW1_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (6, [(1, C_13_42)]), D_Alpha_HHWW1_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (4, [(1, C_13_42)]), D_Alpha_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (5, [(1, C_12_34)]), D_Alpha_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (8, [(1, C_14_23)]), D_Alpha_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (7, [(1, C_12_34)]), D_Alpha_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (5, [(1, C_13_42)]), D_Alpha_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (4, [(1, C_12_34)]), D_Alpha_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (7, [(1, C_14_23)]), D_Alpha_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (8, [(1, C_12_34)]), D_Alpha_HHWW1_U) ] else [] else [] let k_matrix_2scalar_2gauge_m = if Flags.k_matrix_tm then if Flags.higgs_matrix then [ ((O H,O H,G Z,G Z), DScalar2_Vector2_m_0_K_Matrix_cf (0, [(1, C_12_34)]), D_FM0_HHZZ0_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_0_K_Matrix_cf (0, [(1, C_13_42)]), D_FM0_HHZZ0_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_0_K_Matrix_cf (0, [(1, C_14_23)]), D_FM0_HHZZ0_U); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_0_K_Matrix_cf (3, [(1, C_14_23)]), D_FM0_HHZZ1_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_0_K_Matrix_cf (3, [(1, C_13_42)]), D_FM0_HHZZ1_U); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_0_K_Matrix_cf (3, [(1, C_12_34)]), D_FM0_HHZZ1_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_0_K_Matrix_cf (6, [(1, C_13_42)]), D_FM0_HHZZ1_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_0_K_Matrix_cf (6, [(1, C_12_34)]), D_FM0_HHZZ1_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_0_K_Matrix_cf (6, [(1, C_14_23)]), D_FM0_HHZZ1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (0, [(1, C_12_34)]), D_FM0_HHWW0_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (2, [(1, C_13_42)]), D_FM0_HHWW0_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (1, [(1, C_14_23)]), D_FM0_HHWW0_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (1, [(1, C_13_42)]), D_FM0_HHWW0_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (2, [(1, C_14_23)]), D_FM0_HHWW0_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (3, [(1, C_14_23)]), D_FM0_HHWW1_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (6, [(1, C_13_42)]), D_FM0_HHWW1_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (4, [(1, C_13_42)]), D_FM0_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (5, [(1, C_12_34)]), D_FM0_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (8, [(1, C_14_23)]), D_FM0_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (7, [(1, C_12_34)]), D_FM0_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (5, [(1, C_13_42)]), D_FM0_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (4, [(1, C_12_34)]), D_FM0_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (7, [(1, C_14_23)]), D_FM0_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (8, [(1, C_12_34)]), D_FM0_HHWW1_T) ] else [] else [] let k_matrix_2scalar_2gauge_m_1 = if Flags.k_matrix_tm then if Flags.higgs_matrix then [ ((O H,O H,G Z,G Z), DScalar2_Vector2_m_1_K_Matrix_cf (0, [(1, C_12_34)]), D_FM1_HHZZ0_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_1_K_Matrix_cf (0, [(1, C_13_42)]), D_FM1_HHZZ0_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_1_K_Matrix_cf (0, [(1, C_14_23)]), D_FM1_HHZZ0_U); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_1_K_Matrix_cf (3, [(1, C_14_23)]), D_FM1_HHZZ1_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_1_K_Matrix_cf (3, [(1, C_13_42)]), D_FM1_HHZZ1_U); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_1_K_Matrix_cf (3, [(1, C_12_34)]), D_FM1_HHZZ1_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_1_K_Matrix_cf (6, [(1, C_13_42)]), D_FM1_HHZZ1_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_1_K_Matrix_cf (6, [(1, C_12_34)]), D_FM1_HHZZ1_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_1_K_Matrix_cf (6, [(1, C_14_23)]), D_FM1_HHZZ1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (0, [(1, C_12_34)]), D_FM1_HHWW0_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (2, [(1, C_13_42)]), D_FM1_HHWW0_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (1, [(1, C_14_23)]), D_FM1_HHWW0_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (1, [(1, C_13_42)]), D_FM1_HHWW0_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (2, [(1, C_14_23)]), D_FM1_HHWW0_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (3, [(1, C_14_23)]), D_FM1_HHWW1_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (6, [(1, C_13_42)]), D_FM1_HHWW1_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (4, [(1, C_13_42)]), D_FM1_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (5, [(1, C_12_34)]), D_FM1_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (8, [(1, C_14_23)]), D_FM1_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (7, [(1, C_12_34)]), D_FM1_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (5, [(1, C_13_42)]), D_FM1_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (4, [(1, C_12_34)]), D_FM1_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (7, [(1, C_14_23)]), D_FM1_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (8, [(1, C_12_34)]), D_FM1_HHWW1_T) ] else [] else [] let k_matrix_2scalar_2gauge_m_7 = if Flags.k_matrix_tm then if Flags.higgs_matrix then [ ((O H,O H,G Z,G Z), DScalar2_Vector2_m_7_K_Matrix_cf (0, [(1, C_12_34)]), D_FM7_HHZZ0_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_7_K_Matrix_cf (0, [(1, C_13_42)]), D_FM7_HHZZ0_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_7_K_Matrix_cf (0, [(1, C_14_23)]), D_FM7_HHZZ0_U); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_7_K_Matrix_cf (3, [(1, C_14_23)]), D_FM7_HHZZ1_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_7_K_Matrix_cf (3, [(1, C_13_42)]), D_FM7_HHZZ1_U); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_7_K_Matrix_cf (3, [(1, C_12_34)]), D_FM7_HHZZ1_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_7_K_Matrix_cf (6, [(1, C_13_42)]), D_FM7_HHZZ1_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_7_K_Matrix_cf (6, [(1, C_12_34)]), D_FM7_HHZZ1_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_7_K_Matrix_cf (6, [(1, C_14_23)]), D_FM7_HHZZ1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (0, [(1, C_12_34)]), D_FM7_HHWW0_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (2, [(1, C_13_42)]), D_FM7_HHWW0_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (1, [(1, C_14_23)]), D_FM7_HHWW0_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (1, [(1, C_13_42)]), D_FM7_HHWW0_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (2, [(1, C_14_23)]), D_FM7_HHWW0_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (3, [(1, C_14_23)]), D_FM7_HHWW1_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (6, [(1, C_13_42)]), D_FM7_HHWW1_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (4, [(1, C_13_42)]), D_FM7_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (5, [(1, C_12_34)]), D_FM7_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (8, [(1, C_14_23)]), D_FM7_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (7, [(1, C_12_34)]), D_FM7_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (5, [(1, C_13_42)]), D_FM7_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (4, [(1, C_12_34)]), D_FM7_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (7, [(1, C_14_23)]), D_FM7_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (8, [(1, C_12_34)]), D_FM7_HHWW1_T) ] else [] else [] let k_matrix_4scalar = if Flags.k_matrix then if Flags.higgs_matrix then [ ((O H,O H,O H,O H), DScalar4_K_Matrix_ms (0, [(1, C_12_34)]), D_Alpha_HHHH_S); ((O H,O H,O H,O H), DScalar4_K_Matrix_ms (0, [(1, C_13_42)]), D_Alpha_HHHH_T); ((O H,O H,O H,O H), DScalar4_K_Matrix_ms (0, [(1, C_14_23)]), D_Alpha_HHHH_T); ((O H,O H,O H,O H), DScalar4_K_Matrix_ms (3, [(1, C_14_23)]), D_Alpha_HHHH_S); ((O H,O H,O H,O H), DScalar4_K_Matrix_ms (3, [(1, C_13_42)]), D_Alpha_HHHH_T); ((O H,O H,O H,O H), DScalar4_K_Matrix_ms (3, [(1, C_12_34)]), D_Alpha_HHHH_T) ] else [] else [] (*i Thorsten's original implementation of the K matrix, which we keep since it still might be usefull for the future. let k_matrix_quartic_gauge = if Flags.k_matrix then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 0, K_Matrix_Pole 0]), Alpha_WWWW0); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 2, K_Matrix_Pole 2]), Alpha_WWWW2); ((Wm, Wp, Z, Z), Vector4_K_Matrix_tho (0, [(K_Matrix_Coeff 0, K_Matrix_Pole 0); (K_Matrix_Coeff 2, K_Matrix_Pole 2)]), Alpha_ZZWW0); ((Wm, Z, Wp, Z), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 1, K_Matrix_Pole 1]), Alpha_ZZWW1); ((Z, Z, Z, Z), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 0, K_Matrix_Pole 0]), Alpha_ZZZZ) ] else [] i*) let quartic_gauge = standard_quartic_gauge @ anomalous_quartic_gauge @ k_matrix_quartic_gauge @ k_matrix_quartic_gauge_t_0 @ k_matrix_quartic_gauge_t_1 @ k_matrix_quartic_gauge_t_2 @ k_matrix_quartic_gauge_t_rsi @ k_matrix_quartic_gauge_m_0 @ k_matrix_quartic_gauge_m_1 @ k_matrix_quartic_gauge_m_7 let standard_gauge_higgs = [ ((O H, G Wp, G Wm), Scalar_Vector_Vector 1, G_HWW); ((O H, G Z, G Z), Scalar_Vector_Vector 1, G_HZZ) ] let standard_gauge_higgs4 = [ (O H, O H, G Wp, G Wm), Scalar2_Vector2 1, G_HHWW; (O H, O H, G Z, G Z), Scalar2_Vector2 1, G_HHZZ ] let dim8_gauge_higgs4 = [ (O H, O H, G Wp, G Wm), Dim8_Scalar2_Vector2_1 1, FS0_HHWW; (O H, O H, G Z, G Z), Dim8_Scalar2_Vector2_1 1, FS0_HHZZ; (O H, O H, G Wp, G Wm), Dim8_Scalar2_Vector2_2 1, FS1_HHWW; (O H, O H, G Z, G Z), Dim8_Scalar2_Vector2_2 1, FS1_HHZZ ] let dim8_gauge_higgs4_m = [ (O H, O H, G Wp, G Wm), Dim8_Scalar2_Vector2_m_0 1, FM0_HHWW; (O H, O H, G Z, G Z), Dim8_Scalar2_Vector2_m_0 1, FM0_HHZZ; (O H, O H, G Wp, G Wm), Dim8_Scalar2_Vector2_m_1 1, FM1_HHWW; (O H, O H, G Z, G Z), Dim8_Scalar2_Vector2_m_1 1, FM1_HHZZ; (O H, O H, G Wp, G Wm), Dim8_Scalar2_Vector2_m_7 1, FM7_HHWW; (O H, O H, G Z, G Z), Dim8_Scalar2_Vector2_m_7 1, FM7_HHZZ] let standard_higgs = [ (O H, O H, O H), Scalar_Scalar_Scalar 1, G_H3 ] let standard_higgs4 = [ (O H, O H, O H, O H), Scalar4 1, G_H4 ] let fs_higgs4 = [ (O H, O H, O H, O H), Dim8_Scalar4 1, FS_H4 ] (* WK's couplings (apparently, he still intends to divide by $\Lambda^2_{\text{EWSB}}=16\pi^2v_{\mathrm{F}}^2$): \begin{subequations} \begin{align} \mathcal{L}^{\tau}_4 &= \left\lbrack (\partial_{\mu}H)(\partial^{\mu}H) + \frac{g^2v_{\mathrm{F}}^2}{4} V_{\mu} V^{\mu} \right\rbrack^2 \\ \mathcal{L}^{\tau}_5 &= \left\lbrack (\partial_{\mu}H)(\partial_{\nu}H) + \frac{g^2v_{\mathrm{F}}^2}{4} V_{\mu} V_{\nu} \right\rbrack^2 \end{align} \end{subequations} with \begin{equation} V_{\mu} V_{\nu} = \frac{1}{2} \left( W^+_{\mu} W^-_{\nu} + W^+_{\nu} W^-_{\mu} \right) + \frac{1}{2\cos^2\theta_{w}} Z_{\mu} Z_{\nu} \end{equation} (note the symmetrization!), i.\,e. \begin{subequations} \begin{align} \mathcal{L}_4 &= \alpha_4 \frac{g^4v_{\mathrm{F}}^4}{16} (V_{\mu} V_{\nu})^2 \\ \mathcal{L}_5 &= \alpha_5 \frac{g^4v_{\mathrm{F}}^4}{16} (V_{\mu} V^{\mu})^2 \end{align} \end{subequations} *) (* Breaking thinks up \begin{subequations} \begin{align} \mathcal{L}^{\tau,H^4}_4 &= \left\lbrack (\partial_{\mu}H)(\partial^{\mu}H) \right\rbrack^2 \\ \mathcal{L}^{\tau,H^4}_5 &= \left\lbrack (\partial_{\mu}H)(\partial^{\mu}H) \right\rbrack^2 \end{align} \end{subequations} and \begin{subequations} \begin{align} \mathcal{L}^{\tau,H^2V^2}_4 &= \frac{g^2v_{\mathrm{F}}^2}{2} (\partial_{\mu}H)(\partial^{\mu}H) V_{\mu}V^{\mu} \\ \mathcal{L}^{\tau,H^2V^2}_5 &= \frac{g^2v_{\mathrm{F}}^2}{2} (\partial_{\mu}H)(\partial_{\nu}H) V_{\mu}V_{\nu} \end{align} \end{subequations} i.\,e. \begin{subequations} \begin{align} \mathcal{L}^{\tau,H^2V^2}_4 &= \frac{g^2v_{\mathrm{F}}^2}{2} \left\lbrack (\partial_{\mu}H)(\partial^{\mu}H) W^+_{\nu}W^{-,\nu} + \frac{1}{2\cos^2\theta_{w}} (\partial_{\mu}H)(\partial^{\mu}H) Z_{\nu} Z^{\nu} \right\rbrack \\ \mathcal{L}^{\tau,H^2V^2}_5 &= \frac{g^2v_{\mathrm{F}}^2}{2} \left\lbrack (W^{+,\mu}\partial_{\mu}H) (W^{-,\nu}\partial_{\nu}H) + \frac{1}{2\cos^2\theta_{w}} (Z^{\mu}\partial_{\mu}H)(Z^{\nu}\partial_{\nu}H) \right\rbrack \end{align} \end{subequations} *) (* \begin{multline} \tau^4_8 \mathcal{L}^{\tau,H^2V^2}_4 + \tau^5_8 \mathcal{L}^{\tau,H^2V^2}_5 = \\ - \frac{g^2v_{\mathrm{F}}^2}{2} \Biggl\lbrack 2\tau^4_8 \frac{1}{2}(\ii\partial_{\mu}H)(\ii\partial^{\mu}H) W^+_{\nu}W^{-,\nu} + \tau^5_8 (W^{+,\mu}\ii\partial_{\mu}H) (W^{-,\nu}\ii\partial_{\nu}H) \\ + \frac{2\tau^4_8}{\cos^2\theta_{w}} \frac{1}{4} (\ii\partial_{\mu}H)(\ii\partial^{\mu}H) Z_{\nu} Z^{\nu} + \frac{\tau^5_8}{\cos^2\theta_{w}} \frac{1}{2} (Z^{\mu}\ii\partial_{\mu}H)(Z^{\nu}\ii\partial_{\nu}H) \Biggr\rbrack \end{multline} where the two powers of $\ii$ make the sign conveniently negative, i.\,e. \begin{subequations} \begin{align} \alpha_{(\partial H)^2W^2}^2 &= \tau^4_8 g^2v_{\mathrm{F}}^2\\ \alpha_{(\partial HW)^2}^2 &= \frac{\tau^5_8 g^2v_{\mathrm{F}}^2}{2} \\ \alpha_{(\partial H)^2Z^2}^2 &= \frac{\tau^4_8 g^2v_{\mathrm{F}}^2}{\cos^2\theta_{w}} \\ \alpha_{(\partial HZ)^2}^2 &=\frac{\tau^5_8 g^2v_{\mathrm{F}}^2}{2\cos^2\theta_{w}} \end{align} \end{subequations} *) let anomalous_gauge_higgs = [ (O H, G Ga, G Ga), Dim5_Scalar_Gauge2 1, G_HGaGa_anom; (O H, G Ga, G Z), Dim5_Scalar_Gauge2 1, G_HGaZ_anom; (O H, G Z, G Z), Dim5_Scalar_Gauge2 1, G_HZZ_anom; (O H, G Wp, G Wm), Dim5_Scalar_Gauge2 1, G_HWW_anom; (O H, G Ga, G Z), Dim5_Scalar_Vector_Vector_U 1, G_HGaZ_u; (O H, G Z, G Z), Dim5_Scalar_Vector_Vector_U 1, G_HZZ_u; (O H, G Wp, G Wm), Dim5_Scalar_Vector_Vector_U 1, G_HWW_u; (O H, G Wm, G Wp), Dim5_Scalar_Vector_Vector_U 1, G_HWW_u ] let anomalous_gauge_higgs4 = [] let anomalous_higgs = [] let higgs_triangle_vertices = if Flags.higgs_triangle then [ (O H, G Ga, G Ga), Dim5_Scalar_Gauge2 1, G_HGaGa; (O H, G Ga, G Z), Dim5_Scalar_Gauge2 1, G_HGaZ; (O H, G Gl, G Gl), Dim5_Scalar_Gauge2 1, G_Hgg ] else [] let anomalous_higgs4 = [] let gauge_higgs = if Flags.higgs_anom then standard_gauge_higgs @ anomalous_gauge_higgs else standard_gauge_higgs let gauge_higgs4 = ( if Flags.higgs_anom then standard_gauge_higgs4 @ anomalous_gauge_higgs4 else standard_gauge_higgs4 ) @ ( if Flags.higgs_matrix then (dim8_gauge_higgs4 @ dim8_gauge_higgs4_m @ k_matrix_2scalar_2gauge @ k_matrix_2scalar_2gauge_m @ k_matrix_2scalar_2gauge_m_1 @ k_matrix_2scalar_2gauge_m_7) else [] ) let higgs = if Flags.higgs_anom then standard_higgs @ anomalous_higgs else standard_higgs let higgs4 = ( if Flags.higgs_anom then standard_higgs4 @ anomalous_higgs4 else standard_higgs4 ) @ ( if Flags.higgs_matrix then (fs_higgs4 @ k_matrix_4scalar ) else [] ) let goldstone_vertices = [ ((O Phi0, G Wm, G Wp), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phip, G Ga, G Wm), Scalar_Vector_Vector 1, I_Q_W); ((O Phip, G Z, G Wm), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phim, G Wp, G Ga), Scalar_Vector_Vector 1, I_Q_W); ((O Phim, G Wp, G Z), Scalar_Vector_Vector 1, I_G_ZWW) ] (* New Resonances *) (* \begin{dubious} There is an extra minus in the Lagrangian to have the same sign as HWW or HZZ vertex. Effectivly this doesn't matter for SSC, because $(-1)^2=1$. This is only for completeness. \end{dubious} \begin{subequations} \begin{align} \mathbf{V}_\mu &= -\mathrm{i} g\mathbf{W}_\mu+\mathrm{i} g^\prime\mathbf{B}_\mu \\ \mathbf{W}_\mu &= W_\mu^a\frac{\tau^a}{2} \\ \mathbf{B}_\mu &= W_\mu^a\frac{\tau^3}{2} \\ \tau^{++}&= \tau^+ \otimes \tau^+ \\ \tau^+ &= \frac{1}{2} \left (\tau^+ \otimes \tau^3 + \tau^3+\tau^+ \right ) \\ \tau^0 &= \frac{1}{\sqrt{6}} \left (\tau^3\otimes\tau^3 -\tau^+ \otimes \tau^- - \tau^-+\tau^+ \right ) \\ \tau^- &= \frac{1}{2} \left (\tau^- \otimes \tau^3 + \tau^3+\tau^- \right ) \\ \tau^{--}&= \tau^- \otimes \tau^- \end{align} \end{subequations} *) (* Scalar Isoscalar Old representation \begin{equation} \mathcal{L}_{\sigma}= -\frac{g_\sigma v}{2} \text{tr} \left\lbrack \mathbf{V}_\mu \mathbf{V}^\mu \right\rbrack \sigma \end{equation} *) (* \begin{dubious} Transversal couplings like rsigma3t and rf3t are to be calculated in the new higgs matrix representation. \end{dubious} *) let rsigma3 = [ ((O Rsigma, G Wp, G Wm), Scalar_Vector_Vector 1, G_SWW); ((O Rsigma, G Z, G Z), Scalar_Vector_Vector 1, G_SZZ) ] let rsigma3h = [ ((O Rsigma, O H, O H), Dim5_Scalar_Scalar2 1, G_SHH) ] let rsigma3t = [ ((O Rsigma, G Wp, G Wm), Scalar_Vector_Vector_t 1, G_SWW_T); ((O Rsigma, G Z, G Z), Scalar_Vector_Vector_t 1, G_SZZ_T); ((O Rsigma, G Ga, G Ga), Scalar_Vector_Vector_t 1, G_SAA_T); ((O Rsigma, G Ga, G Z), Scalar_Vector_Vector_t 1, G_SAZ_T) ] let rsigma4 = [ (O Rsigma, O Rsigma, G Wp, G Wm), Scalar2_Vector2 1, G_SSWW; (O Rsigma, O Rsigma, G Z, G Z), Scalar2_Vector2 1, G_SSZZ ] (* Scalar Isotensor \begin{subequations} \begin{align} \mathcal{L}_{\phi}&= \frac{g_\phi v}{4} \text{Tr} \left \lbrack \left ( \mathbf{V}_\mu \otimes \mathbf{V}^\mu - \frac{\tau^{aa}}{6} \text{Tr} \left \lbrack \mathbf{V}_\mu \mathbf{V}^\mu \right \rbrack\right ) {\mathbf{\phi}} \right \rbrack\\ \phi&=\sqrt{2} \left (\phi^{++}\tau^{++}+\phi^+\tau^++\phi^0\tau^0+\phi^-\tau^- + \phi^{--}\tau^{--} \right ) \end{align} \end{subequations} *) let rphi3 = [ ((O Rphin, G Wp, G Wm), Scalar_Vector_Vector 1, G_PNWW); ((O Rphin, G Z, G Z), Scalar_Vector_Vector 1, G_PNZZ) ; ((O Rphisn, G Wp, G Wm), Scalar_Vector_Vector 1, G_PSNWW); ((O Rphisn, G Z, G Z), Scalar_Vector_Vector 1, G_PSNZZ) ; ((O Rphip, G Z, G Wm), Scalar_Vector_Vector 1, G_PWZ) ; ((O Rphipp, G Wm, G Wm), Scalar_Vector_Vector 1, G_PWW) ; ((O Rphim, G Wp, G Z), Scalar_Vector_Vector 1, G_PWZ) ; ((O Rphimm, G Wp, G Wp), Scalar_Vector_Vector 1, G_PWW) ] let rphi3h = [ ((O Rphisn, O H, O H), Dim5_Scalar_Scalar2 1, G_PSNHH) ] (* Tensor IsoScalar *) let rf3 = [ ((O Rf, G Wp, G Wm), Tensor_2_Vector_Vector_1 1, G_FWW); ((O Rf, G Z, G Z), Tensor_2_Vector_Vector_1 1, G_FZZ) ] let rf3cf = [ ((O Rf, G Wp, G Wm), Tensor_2_Vector_Vector 1, G_FWW); ((O Rf, G Z, G Z), Tensor_2_Vector_Vector 1, G_FZZ); ((O Rf, G Wp, G Wm), Tensor_2_Vector_Vector_cf 1, G_FWW_CF); ((O Rf, G Z, G Z), Tensor_2_Vector_Vector_cf 1, G_FZZ_CF) ] let rf3h = [ ((O Rf, O H, O H), Tensor_2_Scalar_Scalar 1, G_FHH); ((O Rf, O H, O H), Tensor_2_Scalar_Scalar_cf 1, G_FHH_CF) ] let rf3t = [ ((O Rf, G Wp, G Wm), Tensor_2_Vector_Vector_t 1, G_FWW_T); ((O Rf, G Z, G Z), Tensor_2_Vector_Vector_t 1, G_FZZ_T) ] (* Tensor Isotensor \begin{subequations} \begin{align} \mathcal{L}_{t} \end{align} \end{subequations} *) let rt3 = [ ((O Rtn, G Wp, G Wm), Tensor_2_Vector_Vector_1 1, G_TNWW); ((O Rtn, G Z, G Z), Tensor_2_Vector_Vector_1 1, G_TNZZ) ; ((O Rtsn, G Wp, G Wm), Tensor_2_Vector_Vector_1 1, G_TSNWW); ((O Rtsn, G Z, G Z), Tensor_2_Vector_Vector_1 1, G_TSNZZ) ; ((O Rtp, G Z, G Wm), Tensor_2_Vector_Vector_1 1, G_TWZ) ; ((O Rtpp, G Wm, G Wm), Tensor_2_Vector_Vector_1 1, G_TWW) ; ((O Rtm, G Wp, G Z), Tensor_2_Vector_Vector_1 1, G_TWZ) ; ((O Rtmm, G Wp, G Wp), Tensor_2_Vector_Vector_1 1, G_TWW) ] let rt3cf = [ ((O Rtn, G Wp, G Wm), Tensor_2_Vector_Vector 1, G_TNWW); ((O Rtn, G Z, G Z), Tensor_2_Vector_Vector 1, G_TNZZ) ; ((O Rtsn, G Wp, G Wm), Tensor_2_Vector_Vector 1, G_TSNWW); ((O Rtsn, G Z, G Z), Tensor_2_Vector_Vector 1, G_TSNZZ) ; ((O Rtp, G Z, G Wm), Tensor_2_Vector_Vector 1, G_TWZ) ; ((O Rtpp, G Wm, G Wm), Tensor_2_Vector_Vector 1, G_TWW) ; ((O Rtm, G Wp, G Z), Tensor_2_Vector_Vector 1, G_TWZ) ; ((O Rtmm, G Wp, G Wp), Tensor_2_Vector_Vector 1, G_TWW); ((O Rtn, G Wp, G Wm), Tensor_2_Vector_Vector_cf 1, G_TNWW_CF); ((O Rtn, G Z, G Z), Tensor_2_Vector_Vector_cf 1, G_TNZZ_CF) ; ((O Rtsn, G Wp, G Wm), Tensor_2_Vector_Vector_cf 1, G_TSNWW_CF); ((O Rtsn, G Z, G Z), Tensor_2_Vector_Vector_cf 1, G_TSNZZ_CF) ; ((O Rtp, G Z, G Wm), Tensor_2_Vector_Vector_cf 1, G_TWZ_CF) ; ((O Rtpp, G Wm, G Wm), Tensor_2_Vector_Vector_cf 1, G_TWW_CF) ; ((O Rtm, G Wp, G Z), Tensor_2_Vector_Vector_cf 1, G_TWZ_CF) ; ((O Rtmm, G Wp, G Wp), Tensor_2_Vector_Vector_cf 1, G_TWW_CF) ] (* Anomalous trilinear interactions $f_i f_j V$ and $ttH$: \begin{equation} \Delta\mathcal{L}_{tt\gamma} = - e \frac{\upsilon}{\Lambda^2} \bar{t} i\sigma^{\mu\nu} k_\nu (d_V(k^2) + i d_A(k^2) \gamma_5) t A_\mu \end{equation} *) let anomalous_ttA = if Flags.top_anom then [ ((M (U (-3)), G Ga, M (U 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_ttA) ] else [] (* \begin{equation} \Delta\mathcal{L}_{bb\gamma} = - e \frac{\upsilon}{\Lambda^2} \bar{b} i\sigma^{\mu\nu} k_\nu (d_V(k^2) + i d_A(k^2) \gamma_5) b A_\mu \end{equation} *) let anomalous_bbA = if Flags.top_anom then [ ((M (D (-3)), G Ga, M (D 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_bbA) ] else [] (* \begin{equation} \Delta\mathcal{L}_{ttg} = - g_s \frac{\upsilon}{\Lambda^2} \bar{t}\lambda^a i\sigma^{\mu\nu}k_\nu (d_V(k^2)+id_A(k^2)\gamma_5)tG^a_\mu \end{equation} *) let anomalous_ttG = if Flags.top_anom then [ ((M (U (-3)), G Gl, M (U 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_ttG) ] else [] (* \begin{equation} \Delta\mathcal{L}_{ttZ} = - \frac{g}{2 c_W} \frac{\upsilon^2}{\Lambda^2}\left\lbrack \bar{t} \fmslash{Z} (X_L(k^2) P_L + X_R(k^2) P_R) t + \bar{t}\frac{i\sigma^{\mu\nu}k_\nu}{m_Z} (d_V(k^2)+id_A(k^2)\gamma_5)tZ_\mu\right\rbrack \end{equation} *) let anomalous_ttZ = if Flags.top_anom then [ ((M (U (-3)), G Z, M (U 3)), FBF (1, Psibar, VLRM, Psi), G_VLR_ttZ); ((M (U (-3)), G Z, M (U 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_ttZ) ] else [] (* \begin{equation} \Delta\mathcal{L}_{bbZ} = - \frac{g}{2 c_W} \frac{\upsilon^2}{\Lambda^2} \bar{b}\frac{i\sigma^{\mu\nu}k_\nu}{m_Z} (d_V(k^2)+id_A(k^2)\gamma_5)bZ_\mu \end{equation} *) let anomalous_bbZ = if Flags.top_anom then [ ((M (D (-3)), G Z, M (D 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_bbZ) ] else [] (* \begin{equation} \Delta\mathcal{L}_{tbW} = - \frac{g}{\sqrt{2}} \frac{\upsilon^2}{\Lambda^2}\left\lbrack \bar{b}\fmslash{W}^-(V_L(k^2) P_L+V_R(k^2) P_R) t + \bar{b}\frac{i\sigma^{\mu\nu}k_\nu}{m_W} (g_L(k^2)P_L+g_R(k^2)P_R)tW^-_\mu\right\rbrack + \textnormal{H.c.} \end{equation} *) let anomalous_tbW = if Flags.top_anom then [ ((M (D (-3)), G Wm, M (U 3)), FBF (1, Psibar, VLRM, Psi), G_VLR_btW); ((M (U (-3)), G Wp, M (D 3)), FBF (1, Psibar, VLRM, Psi), G_VLR_tbW); ((M (D (-3)), G Wm, M (U 3)), FBF (1, Psibar, TLRM, Psi), G_TLR_btW); ((M (U (-3)), G Wp, M (D 3)), FBF (1, Psibar, TRLM, Psi), G_TRL_tbW) ] else [] (* \begin{equation} \Delta\mathcal{L}_{ttH} = - \frac{1}{\sqrt{2}} \bar{t} (Y_V(k^2)+iY_A(k^2)\gamma_5)t H \end{equation} *) let anomalous_ttH = if Flags.top_anom then [ ((M (U (-3)), O H, M (U 3)), FBF (1, Psibar, SPM, Psi), G_SP_ttH) ] else [] (* quartic fermion-gauge interactions $f_i f_j V_1 V_2$ emerging from gauge-invariant effective operators: \begin{equation} \Delta\mathcal{L}_{ttgg} = - \frac{g_s^2}{2} f_{abc} \frac{\upsilon}{\Lambda^2} \bar{t} \lambda^a \sigma^{\mu\nu} (d_V(k^2)+id_A(k^2)\gamma_5)t G^b_\mu G^c_\nu \end{equation} *) let anomalous_ttGG = if Flags.top_anom then [ ((M (U (-3)), O (Aux_top (2,1,0,true,TTGG)), M (U 3)), FBF (1, Psibar, TVA, Psi), G_TVA_ttGG); ((O (Aux_top (2,1,0,false,TTGG)), G Gl, G Gl), Aux_Gauge_Gauge 1, I_Gs) ] else [] (* \begin{equation} \Delta\mathcal{L}_{tbWA} = - i\sin\theta_w \frac{g^2}{2\sqrt{2}} \frac{\upsilon^2}{\Lambda^2}\left\lbrack \bar{b}\frac{\sigma^{\mu\nu}}{m_W} (g_L(k^2)P_L+g_R(k^2)P_R)t A_\mu W^-_\nu \right\rbrack + \textnormal{H.c.} \end{equation} *) let anomalous_tbWA = if Flags.top_anom then [ ((M (D (-3)), O (Aux_top (2,0,-1,true,TBWA)), M (U 3)), FBF (1, Psibar, TLR, Psi), G_TLR_btWA); ((O (Aux_top (2,0,1,false,TBWA)), G Ga, G Wm), Aux_Gauge_Gauge 1, I_G_weak); ((M (U (-3)), O (Aux_top (2,0,1,true,TBWA)), M (D 3)), FBF (1, Psibar, TRL, Psi), G_TRL_tbWA); ((O (Aux_top (2,0,-1,false,TBWA)), G Wp, G Ga), Aux_Gauge_Gauge 1, I_G_weak) ] else [] (* \begin{equation} \Delta\mathcal{L}_{tbWZ} = - i\cos\theta_w \frac{g^2}{2\sqrt{2}} \frac{\upsilon^2}{\Lambda^2}\left\lbrack \bar{b}\frac{\sigma^{\mu\nu}}{m_W} (g_L(k^2)P_L+g_R(k^2)P_R)t Z_\mu W^-_\nu \right\rbrack + \textnormal{H.c.} \end{equation} *) let anomalous_tbWZ = if Flags.top_anom then [ ((M (D (-3)), O (Aux_top (2,0,-1,true,TBWZ)), M (U 3)), FBF (1, Psibar, TLR, Psi), G_TLR_btWZ); ((O (Aux_top (2,0,1,false,TBWZ)), G Z, G Wm), Aux_Gauge_Gauge 1, I_G_weak); ((M (U (-3)), O (Aux_top (2,0,1,true,TBWZ)), M (D 3)), FBF (1, Psibar, TRL, Psi), G_TRL_tbWZ); ((O (Aux_top (2,0,-1,false,TBWZ)), G Wp, G Z), Aux_Gauge_Gauge 1, I_G_weak) ] else [] (* \begin{equation} \Delta\mathcal{L}_{ttWW} = - i \frac{g^2}{2} \frac{\upsilon^2}{\Lambda^2} \bar{t} \frac{\sigma^{\mu\nu}}{m_W} (d_V(k^2)+id_A(k^2)\gamma_5)t W^-_\mu W^+_\nu \end{equation} *) let anomalous_ttWW = if Flags.top_anom then [ ((M (U (-3)), O (Aux_top (2,0,0,true,TTWW)), M (U 3)), FBF (1, Psibar, TVA, Psi), G_TVA_ttWW); ((O (Aux_top (2,0,0,false,TTWW)), G Wm, G Wp), Aux_Gauge_Gauge 1, I_G_weak) ] else [] (* \begin{equation} \Delta\mathcal{L}_{bbWW} = - i \frac{g^2}{2} \frac{\upsilon^2}{\Lambda^2} \bar{b} \frac{\sigma^{\mu\nu}}{m_W} (d_V(k^2)+id_A(k^2)\gamma_5)b W^-_\mu W^+_\nu \end{equation} *) let anomalous_bbWW = if Flags.top_anom then [ ((M (D (-3)), O (Aux_top (2,0,0,true,BBWW)), M (D 3)), FBF (1, Psibar, TVA, Psi), G_TVA_bbWW); ((O (Aux_top (2,0,0,false,BBWW)), G Wm, G Wp), Aux_Gauge_Gauge 1, I_G_weak) ] else [] (* 4-fermion contact terms emerging from operator rewriting: *) let anomalous_top_qGuG_tt = [ ((M (U (-3)), O (Aux_top (1,1,0,true,QGUG)), M (U 3)), FBF (1, Psibar, VLR, Psi), G_VLR_qGuG) ] let anomalous_top_qGuG_ff n = List.map mom [ ((U (-n), Aux_top (1,1,0,false,QGUG), U n), FBF (1, Psibar, V, Psi), Unit); ((D (-n), Aux_top (1,1,0,false,QGUG), D n), FBF (1, Psibar, V, Psi), Unit) ] let anomalous_top_qGuG = if Flags.top_anom_4f then anomalous_top_qGuG_tt @ ThoList.flatmap anomalous_top_qGuG_ff [1;2;3] else [] let anomalous_top_qBuB_tt = [ ((M (U (-3)), O (Aux_top (1,0,0,true,QBUB)), M (U 3)), FBF (1, Psibar, VLR, Psi), G_VLR_qBuB) ] let anomalous_top_qBuB_ff n = List.map mom [ ((U (-n), Aux_top (1,0,0,false,QBUB), U n), FBF (1, Psibar, VLR, Psi), G_VLR_qBuB_u); ((D (-n), Aux_top (1,0,0,false,QBUB), D n), FBF (1, Psibar, VLR, Psi), G_VLR_qBuB_d); ((L (-n), Aux_top (1,0,0,false,QBUB), L n), FBF (1, Psibar, VLR, Psi), G_VLR_qBuB_e); ((N (-n), Aux_top (1,0,0,false,QBUB), N n), FBF (1, Psibar, VL, Psi), G_VL_qBuB_n) ] let anomalous_top_qBuB = if Flags.top_anom_4f then anomalous_top_qBuB_tt @ ThoList.flatmap anomalous_top_qBuB_ff [1;2;3] else [] let anomalous_top_qW_tq = [ ((M (U (-3)), O (Aux_top (1,0,0,true,QW)), M (U 3)), FBF (1, Psibar, VL, Psi), G_VL_qW); ((M (D (-3)), O (Aux_top (1,0,-1,true,QW)), M (U 3)), FBF (1, Psibar, VL, Psi), G_VL_qW); ((M (U (-3)), O (Aux_top (1,0,1,true,QW)), M (D 3)), FBF (1, Psibar, VL, Psi), G_VL_qW) ] let anomalous_top_qW_ff n = List.map mom [ ((U (-n), Aux_top (1,0,0,false,QW), U n), FBF (1, Psibar, VL, Psi), G_VL_qW_u); ((D (-n), Aux_top (1,0,0,false,QW), D n), FBF (1, Psibar, VL, Psi), G_VL_qW_d); ((N (-n), Aux_top (1,0,0,false,QW), N n), FBF (1, Psibar, VL, Psi), G_VL_qW_u); ((L (-n), Aux_top (1,0,0,false,QW), L n), FBF (1, Psibar, VL, Psi), G_VL_qW_d); ((D (-n), Aux_top (1,0,-1,false,QW), U n), FBF (1, Psibar, VL, Psi), Half); ((U (-n), Aux_top (1,0,1,false,QW), D n), FBF (1, Psibar, VL, Psi), Half); ((L (-n), Aux_top (1,0,-1,false,QW), N n), FBF (1, Psibar, VL, Psi), Half); ((N (-n), Aux_top (1,0,1,false,QW), L n), FBF (1, Psibar, VL, Psi), Half) ] let anomalous_top_qW = if Flags.top_anom_4f then anomalous_top_qW_tq @ ThoList.flatmap anomalous_top_qW_ff [1;2;3] else [] let anomalous_top_DuDd = if Flags.top_anom_4f then [ ((M (U (-3)), O (Aux_top (0,0,0,true,DR)), M (U 3)), FBF (1, Psibar, SR, Psi), Half); ((M (U (-3)), O (Aux_top (0,0,0,false,DR)), M (U 3)), FBF (1, Psibar, SL, Psi), G_SL_DttR); ((M (D (-3)), O (Aux_top (0,0,0,false,DR)), M (D 3)), FBF (1, Psibar, SR, Psi), G_SR_DttR); ((M (U (-3)), O (Aux_top (0,0,0,true,DL)), M (U 3)), FBF (1, Psibar, SL, Psi), Half); ((M (D (-3)), O (Aux_top (0,0,0,false,DL)), M (D 3)), FBF (1, Psibar, SL, Psi), G_SL_DttL); ((M (D (-3)), O (Aux_top (0,0,-1,true,DR)), M (U 3)), FBF (1, Psibar, SR, Psi), Half); ((M (U (-3)), O (Aux_top (0,0,1,false,DR)), M (D 3)), FBF (1, Psibar, SLR, Psi), G_SLR_DbtR); ((M (D (-3)), O (Aux_top (0,0,-1,true,DL)), M (U 3)), FBF (1, Psibar, SL, Psi), Half); ((M (U (-3)), O (Aux_top (0,0,1,false,DL)), M (D 3)), FBF (1, Psibar, SL, Psi), G_SL_DbtL) ] else [] let vertices3 = (ThoList.flatmap electromagnetic_currents [1;2;3] @ ThoList.flatmap color_currents [1;2;3] @ ThoList.flatmap neutral_currents [1;2;3] @ (if Flags.ckm_present then charged_currents_ckm else charged_currents_triv) @ yukawa @ triple_gauge @ gauge_higgs @ higgs @ higgs_triangle_vertices @ goldstone_vertices @ rsigma3 @ rsigma3t @ rphi3 @ ( if Flags.cf_arbitrary then (rf3cf @ rt3cf) else (rf3 @ rt3) ) @ rf3t @ ( if Flags.higgs_matrix then (rsigma3h @ rphi3h @ rf3h ) else [] ) @ anomalous_ttA @ anomalous_bbA @ anomalous_ttZ @ anomalous_bbZ @ anomalous_tbW @ anomalous_tbWA @ anomalous_tbWZ @ anomalous_ttWW @ anomalous_bbWW @ anomalous_ttG @ anomalous_ttGG @ anomalous_ttH @ anomalous_top_qGuG @ anomalous_top_qBuB @ anomalous_top_qW @ anomalous_top_DuDd) let vertices4 = quartic_gauge @ gauge_higgs4 @ higgs4 let vertices () = (vertices3, vertices4, []) (* For efficiency, make sure that [F.of_vertices vertices] is evaluated only once. *) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 let flavor_of_string = function | "e-" -> M (L 1) | "e+" -> M (L (-1)) | "mu-" -> M (L 2) | "mu+" -> M (L (-2)) | "tau-" -> M (L 3) | "tau+" -> M (L (-3)) | "nue" -> M (N 1) | "nuebar" -> M (N (-1)) | "numu" -> M (N 2) | "numubar" -> M (N (-2)) | "nutau" -> M (N 3) | "nutaubar" -> M (N (-3)) | "u" -> M (U 1) | "ubar" -> M (U (-1)) | "c" -> M (U 2) | "cbar" -> M (U (-2)) | "t" -> M (U 3) | "tbar" -> M (U (-3)) | "d" -> M (D 1) | "dbar" -> M (D (-1)) | "s" -> M (D 2) | "sbar" -> M (D (-2)) | "b" -> M (D 3) | "bbar" -> M (D (-3)) | "g" | "gl" -> G Gl | "A" -> G Ga | "Z" | "Z0" -> G Z | "W+" -> G Wp | "W-" -> G Wm | "H" -> O H | "Rsigma" -> O Rsigma | "Rphi0" -> O Rphin | "Rphis0" -> O Rphisn | "Rphi+" -> O Rphip | "Rphi-" -> O Rphim | "Rphi++" -> O Rphip | "Rphi--" -> O Rphimm | "Rf" -> O Rf | "Rt0" -> O Rtn | "Rts0" -> O Rtsn | "Rt+" -> O Rtp | "Rt-" -> O Rtm | "Rt++" -> O Rtp | "Rt--" -> O Rtmm | "Aux_t_ttGG0" -> O (Aux_top (2,1, 0,true,TTGG)) | "Aux_ttGG0" -> O (Aux_top (2,1, 0,false,TTGG)) | "Aux_t_tbWA+" -> O (Aux_top (2,0, 1,true,TBWA)) | "Aux_tbWA+" -> O (Aux_top (2,0, 1,false,TBWA)) | "Aux_t_tbWA-" -> O (Aux_top (2,0,-1,true,TBWA)) | "Aux_tbWA-" -> O (Aux_top (2,0,-1,false,TBWA)) | "Aux_t_tbWZ+" -> O (Aux_top (2,0, 1,true,TBWZ)) | "Aux_tbWZ+" -> O (Aux_top (2,0, 1,false,TBWZ)) | "Aux_t_tbWZ-" -> O (Aux_top (2,0,-1,true,TBWZ)) | "Aux_tbWZ-" -> O (Aux_top (2,0,-1,false,TBWZ)) | "Aux_t_ttWW0" -> O (Aux_top (2,0, 0,true,TTWW)) | "Aux_ttWW0" -> O (Aux_top (2,0, 0,false,TTWW)) | "Aux_t_bbWW0" -> O (Aux_top (2,0, 0,true,BBWW)) | "Aux_bbWW0" -> O (Aux_top (2,0, 0,false,BBWW)) | "Aux_t_qGuG0" -> O (Aux_top (1,1, 0,true,QGUG)) | "Aux_qGuG0" -> O (Aux_top (1,1, 0,false,QGUG)) | "Aux_t_qBuB0" -> O (Aux_top (1,0, 0,true,QBUB)) | "Aux_qBuB0" -> O (Aux_top (1,0, 0,false,QBUB)) | "Aux_t_qW0" -> O (Aux_top (1,0, 0,true,QW)) | "Aux_qW0" -> O (Aux_top (1,0, 0,false,QW)) | "Aux_t_qW+" -> O (Aux_top (1,0, 1,true,QW)) | "Aux_qW+" -> O (Aux_top (1,0, 1,false,QW)) | "Aux_t_qW-" -> O (Aux_top (1,0,-1,true,QW)) | "Aux_qW-" -> O (Aux_top (1,0,-1,false,QW)) | "Aux_t_dL0" -> O (Aux_top (0,0, 0,true,DL)) | "Aux_dL0" -> O (Aux_top (0,0, 0,false,DL)) | "Aux_t_dL+" -> O (Aux_top (0,0, 1,true,DL)) | "Aux_dL+" -> O (Aux_top (0,0, 1,false,DL)) | "Aux_t_dL-" -> O (Aux_top (0,0,-1,true,DL)) | "Aux_dL-" -> O (Aux_top (0,0,-1,false,DL)) | "Aux_t_dR0" -> O (Aux_top (0,0, 0,true,DR)) | "Aux_dR0" -> O (Aux_top (0,0, 0,false,DR)) | "Aux_t_dR+" -> O (Aux_top (0,0, 1,true,DR)) | "Aux_dR+" -> O (Aux_top (0,0, 1,false,DR)) | "Aux_t_dR-" -> O (Aux_top (0,0,-1,true,DR)) | "Aux_dR-" -> O (Aux_top (0,0,-1,false,DR)) | _ -> invalid_arg "Modellib_BSM.SSC.flavor_of_string" let flavor_to_string = function | M f -> begin match f with | L 1 -> "e-" | L (-1) -> "e+" | L 2 -> "mu-" | L (-2) -> "mu+" | L 3 -> "tau-" | L (-3) -> "tau+" | L _ -> invalid_arg "Modellib_BSM.SSC.flavor_to_string: invalid lepton" | N 1 -> "nue" | N (-1) -> "nuebar" | N 2 -> "numu" | N (-2) -> "numubar" | N 3 -> "nutau" | N (-3) -> "nutaubar" | N _ -> invalid_arg "Modellib_BSM.SSC.flavor_to_string: invalid neutrino" | U 1 -> "u" | U (-1) -> "ubar" | U 2 -> "c" | U (-2) -> "cbar" | U 3 -> "t" | U (-3) -> "tbar" | U _ -> invalid_arg "Modellib_BSM.SSC.flavor_to_string: invalid up type quark" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | D _ -> invalid_arg "Modellib_BSM.SSC.flavor_to_string: invalid down type quark" end | G f -> begin match f with | Gl -> "gl" | Ga -> "A" | Z -> "Z" | Wp -> "W+" | Wm -> "W-" end | O f -> begin match f with | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | H -> "H" | Rsigma -> "Rsigma" | Rphin -> "Rphin" | Rphisn -> "Rphisn" | Rphip -> "Rphi+" | Rphim -> "Rphi-" | Rphipp -> "Rphi++" | Rphimm -> "Rphi--" | Rf -> "Rf" | Rtn -> "Rtn" | Rtsn -> "Rtsn" | Rtp -> "Rt+" | Rtm -> "Rt-" | Rtpp -> "Rt++" | Rtmm -> "Rt--" | Aux_top (_,_,ch,n,v) -> "Aux_" ^ (if n then "t_" else "") ^ ( begin match v with | TTGG -> "ttGG" | TBWA -> "tbWA" | TBWZ -> "tbWZ" | TTWW -> "ttWW" | BBWW -> "bbWW" | QGUG -> "qGuG" | QBUB -> "qBuB" | QW -> "qW" | DL -> "dL" | DR -> "dR" end ) ^ ( if ch > 0 then "+" else if ch < 0 then "-" else "0" ) end let flavor_to_TeX = function | M f -> begin match f with | L 1 -> "e^-" | L (-1) -> "e^+" | L 2 -> "\\mu^-" | L (-2) -> "\\mu^+" | L 3 -> "\\tau^-" | L (-3) -> "\\tau^+" | L _ -> invalid_arg "Modellib_BSM.SSC.flavor_to_TeX: invalid lepton" | N 1 -> "\\nu_e" | N (-1) -> "\\bar{\\nu}_e" | N 2 -> "\\nu_\\mu" | N (-2) -> "\\bar{\\nu}_\\mu" | N 3 -> "\\nu_\\tau" | N (-3) -> "\\bar{\\nu}_\\tau" | N _ -> invalid_arg "Modellib_BSM.SSC.flavor_to_TeX: invalid neutrino" | U 1 -> "u" | U (-1) -> "\\bar{u}" | U 2 -> "c" | U (-2) -> "\\bar{c}" | U 3 -> "t" | U (-3) -> "\\bar{t}" | U _ -> invalid_arg "Modellib_BSM.SSC.flavor_to_TeX: invalid up type quark" | D 1 -> "d" | D (-1) -> "\\bar{d}" | D 2 -> "s" | D (-2) -> "\\bar{s}" | D 3 -> "b" | D (-3) -> "\\bar{b}" | D _ -> invalid_arg "Modellib_BSM.SSC.flavor_to_TeX: invalid down type quark" end | G f -> begin match f with | Gl -> "g" | Ga -> "\\gamma" | Z -> "Z" | Wp -> "W^+" | Wm -> "W^-" end | O f -> begin match f with | Phip -> "\\phi^+" | Phim -> "\\phi^-" | Phi0 -> "\\phi^0" | H -> "H" | Rsigma -> "\\sigma" | Rphip -> "\\phi^+" | Rphim -> "\\phi^-" | Rphin -> "\\phi^0" | Rphisn -> "\\phi_s^0" | Rphipp -> "\\phi^{++}" | Rphimm -> "\\phi^{--}" | Rf -> "f" | Rtp -> "t^+" | Rtm -> "t^-" | Rtn -> "t^0" | Rtsn -> "t_s^0" | Rtpp -> "t^{++}" | Rtmm -> "t^{--}" | Aux_top (_,_,ch,n,v) -> "\\textnormal{Aux_" ^ (if n then "t_" else "") ^ ( begin match v with | TTGG -> "ttGG" | TBWA -> "tbWA" | TBWZ -> "tbWZ" | TTWW -> "ttWW" | BBWW -> "bbWW" | QGUG -> "qGuG" | QBUB -> "qBuB" | QW -> "qW" | DL -> "dL" | DR -> "dR" end ) ^ ( if ch > 0 then "^+" else if ch < 0 then "^-" else "^0" ) ^ "}" end let flavor_symbol = function | M f -> begin match f with | L n when n > 0 -> "l" ^ string_of_int n | L n -> "l" ^ string_of_int (abs n) ^ "b" | N n when n > 0 -> "n" ^ string_of_int n | N n -> "n" ^ string_of_int (abs n) ^ "b" | U n when n > 0 -> "u" ^ string_of_int n | U n -> "u" ^ string_of_int (abs n) ^ "b" | D n when n > 0 -> "d" ^ string_of_int n | D n -> "d" ^ string_of_int (abs n) ^ "b" end | G f -> begin match f with | Gl -> "gl" | Ga -> "a" | Z -> "z" | Wp -> "wp" | Wm -> "wm" end | O f -> begin match f with | Phip -> "pp" | Phim -> "pm" | Phi0 -> "p0" | H -> "h" | Rsigma -> "rsi" | Rphip -> "rpp" | Rphim -> "rpm" | Rphin -> "rpn" | Rphisn -> "rpsn" | Rphipp -> "rppp" | Rphimm -> "rpmm" | Rf -> "rf" | Rtp -> "rtp" | Rtm -> "rtm" | Rtn -> "rtn" | Rtsn -> "rtsn" | Rtpp -> "rtpp" | Rtmm -> "rtmm" | Aux_top (_,_,ch,n,v) -> "aux_" ^ (if n then "t_" else "") ^ ( begin match v with | TTGG -> "ttgg" | TBWA -> "tbwa" | TBWZ -> "tbwz" | TTWW -> "ttww" | BBWW -> "bbww" | QGUG -> "qgug" | QBUB -> "qbub" | QW -> "qw" | DL -> "dl" | DR -> "dr" end ) ^ "_" ^ ( if ch > 0 then "p" else if ch < 0 then "m" else "0" ) end (* Introducing new Resonances from 45, there are no PDG values *) let pdg = function | M f -> begin match f with | L n when n > 0 -> 9 + 2*n | L n -> - 9 + 2*n | N n when n > 0 -> 10 + 2*n | N n -> - 10 + 2*n | U n when n > 0 -> 2*n | U n -> 2*n | D n when n > 0 -> - 1 + 2*n | D n -> 1 + 2*n end | G f -> begin match f with | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) end | O f -> begin match f with | Phip | Phim -> 27 | Phi0 -> 26 | H -> 25 | Rsigma -> 45 | Rphin -> 46 | Rphip | Rphim -> 47 | Rphipp | Rphimm -> 48 | Rphisn -> 49 | Rf -> 52 | Rtn -> 53 | Rtp | Rtm -> 54 | Rtpp | Rtmm -> 55 | Rtsn -> 59 | Aux_top (_,_,_,_,_) -> 81 end let mass_symbol f = "mass(" ^ string_of_int (abs (pdg f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg f)) ^ ")" let constant_symbol = function | Unit -> "unit" | Half -> "half" | Pi -> "PI" | Alpha_QED -> "alpha" | E -> "e" | G_weak -> "g" | Vev -> "vev" | I_G_weak -> "ig" | Sin2thw -> "sin2thw" | Sinthw -> "sinthw" | Costhw -> "costhw" | Q_lepton -> "qlep" | Q_up -> "qup" | Q_down -> "qdwn" | G_NC_lepton -> "gnclep" | G_NC_neutrino -> "gncneu" | G_NC_up -> "gncup" | G_NC_down -> "gncdwn" | G_TVA_ttA -> "gtva_tta" | G_TVA_bbA -> "gtva_bba" | G_VLR_ttZ -> "gvlr_ttz" | G_TVA_ttZ -> "gtva_ttz" | G_TVA_bbZ -> "gtva_bbz" | G_VLR_btW -> "gvlr_btw" | G_VLR_tbW -> "gvlr_tbw" | G_TLR_btW -> "gtlr_btw" | G_TRL_tbW -> "gtrl_tbw" | G_TLR_btWA -> "gtlr_btwa" | G_TRL_tbWA -> "gtrl_tbwa" | G_TLR_btWZ -> "gtlr_btwz" | G_TRL_tbWZ -> "gtrl_tbwz" | G_TVA_ttWW -> "gtva_ttww" | G_TVA_bbWW -> "gtva_bbww" | G_TVA_ttG -> "gtva_ttg" | G_TVA_ttGG -> "gtva_ttgg" | G_SP_ttH -> "gsp_tth" | G_VLR_qGuG -> "gvlr_qgug" | G_VLR_qBuB -> "gvlr_qbub" | G_VLR_qBuB_u -> "gvlr_qbub_u" | G_VLR_qBuB_d -> "gvlr_qbub_d" | G_VLR_qBuB_e -> "gvlr_qbub_e" | G_VL_qBuB_n -> "gvl_qbub_n" | G_VL_qW -> "gvl_qw" | G_VL_qW_u -> "gvl_qw_u" | G_VL_qW_d -> "gvl_qw_d" | G_SL_DttR -> "gsl_dttr" | G_SR_DttR -> "gsr_dttr" | G_SL_DttL -> "gsl_dttl" | G_SLR_DbtR -> "gslr_dbtr" | G_SL_DbtL -> "gsl_dbtl" | G_CC -> "gcc" | G_CCQ (n1,n2) -> "gccq" ^ string_of_int n1 ^ string_of_int n2 | I_Q_W -> "iqw" | I_G_ZWW -> "igzww" | G_WWWW -> "gw4" | G_ZZWW -> "gzzww" | G_AZWW -> "gazww" | G_AAWW -> "gaaww" | I_G1_AWW -> "ig1a" | I_G1_ZWW -> "ig1z" | I_G1_plus_kappa_plus_G4_AWW -> "ig1pkpg4a" | I_G1_plus_kappa_plus_G4_ZWW -> "ig1pkpg4z" | I_G1_plus_kappa_minus_G4_AWW -> "ig1pkmg4a" | I_G1_plus_kappa_minus_G4_ZWW -> "ig1pkmg4z" | I_G1_minus_kappa_plus_G4_AWW -> "ig1mkpg4a" | I_G1_minus_kappa_plus_G4_ZWW -> "ig1mkpg4z" | I_G1_minus_kappa_minus_G4_AWW -> "ig1mkmg4a" | I_G1_minus_kappa_minus_G4_ZWW -> "ig1mkmg4z" | I_lambda_AWW -> "ila" | I_lambda_ZWW -> "ilz" | G5_AWW -> "rg5a" | G5_ZWW -> "rg5z" | I_kappa5_AWW -> "ik5a" | I_kappa5_ZWW -> "ik5z" | I_lambda5_AWW -> "il5a" | I_lambda5_ZWW -> "il5z" | Alpha_WWWW0 -> "alww0" | Alpha_WWWW2 -> "alww2" | Alpha_ZZWW0 -> "alzw0" | Alpha_ZZWW1 -> "alzw1" | Alpha_ZZZZ -> "alzz" | FT0_WWWW0 -> "at0ww0" | FT0_WWWW2 -> "at0ww2" | FT0_ZZWW0 -> "at0zw0" | FT0_ZZWW1 -> "at0zw1" | FT0_ZZZZ -> "at0zz" | FT0_AAAA -> "at0aa" | FT0_AAWW0 -> "at0aw0" | FT0_AAWW1 -> "at0aw1" | FT0_AAZZ -> "at0az" | FT0_AZWW0 -> "at0azw0" | FT0_AZWW1 -> "at0azw1" | FT0_AAAZ -> "at03az" | FT0_AZZZ -> "at0a3z" | FT1_WWWW0 -> "at1ww0" | FT1_WWWW2 -> "at1ww2" | FT1_ZZWW0 -> "at1zw0" | FT1_ZZWW1 -> "at1zw1" | FT1_ZZZZ -> "at1zz" | FT1_AAAA -> "at1aa" | FT1_AAWW0 -> "at1aw0" | FT1_AAWW1 -> "at1aw1" | FT1_AAZZ -> "at1az" | FT1_AZWW0 -> "at1azw0" | FT1_AZWW1 -> "at1azw1" | FT1_AAAZ -> "at13az" | FT1_AZZZ -> "at1a3z" | FT2_WWWW0 -> "at2ww0" | FT2_WWWW2 -> "at2ww2" | FT2_ZZWW0 -> "at2zw0" | FT2_ZZWW1 -> "at2zw1" | FT2_ZZZZ -> "at2zz" | FT2_AAAA -> "at2aa" | FT2_AAWW0 -> "at2aw0" | FT2_AAWW1 -> "at2aw1" | FT2_AAZZ -> "at2az" | FT2_AZWW0 -> "at2azw0" | FT2_AZWW1 -> "at2azw1" | FT2_AAAZ -> "at23az" | FT2_AZZZ -> "at2a3z" | FM0_WWWW0 -> "am0ww0,am0ww0" | FM0_WWWW2 -> "am0ww2,am0ww2" | FM0_ZZWW0 -> "am0zw0/costhw**2,am0zw0*costhw**2" | FM0_ZZWW1 -> "am0zw1/costhw**2,am0zw1*costhw**2" | FM0_ZZZZ -> "am0zz,am0zz" | FM1_WWWW0 -> "am1ww0,am1ww0" | FM1_WWWW2 -> "am1ww2,am1ww2" | FM1_ZZWW0 -> "am1zw0/costhw**2,am1zw0*costhw**2" | FM1_ZZWW1 -> "am1zw1/costhw**2,am1zw1*costhw**2" | FM1_ZZZZ -> "am1zz,am1zz" | FM7_WWWW0 -> "am7ww0,am7ww0,am7ww0" | FM7_WWWW2 -> "am7ww2,am7ww2,am7ww2" | FM7_ZZWW0 -> "am7zw0/costhw**2,am7zw0,am7zw0*costhw**2" | FM7_ZZWW1 -> "am7zw1/costhw**2,am7zw1,am7zw1*costhw**2" | FM7_ZZZZ -> "am7zz,am7zz,am7zz" | FS0_HHWW -> "fs0hhww" | FS0_HHZZ -> "fs0hhzz" | FS1_HHWW -> "fs1hhww" | FS1_HHZZ -> "fs1hhzz" | FS_H4 -> "fsh4" | FM0_HHWW -> "fm0hhww" | FM0_HHZZ -> "fm0hhzz" | FM1_HHWW -> "fm1hhww" | FM1_HHZZ -> "fm1hhzz" | FM7_HHWW -> "fm7hhww" | FM7_HHZZ -> "fm7hhzz" | D_Alpha_ZZWW0_S -> "dalzz0_s(gkm,mkm," | D_Alpha_ZZWW0_T -> "dalzz0_t(gkm,mkm," | D_Alpha_ZZWW1_S -> "dalzz1_s(gkm,mkm," | D_Alpha_ZZWW1_T -> "dalzz1_t(gkm,mkm," | D_Alpha_ZZWW1_U -> "dalzz1_u(gkm,mkm," | D_Alpha_WWWW0_S -> "dalww0_s(gkm,mkm," | D_Alpha_WWWW0_T -> "dalww0_t(gkm,mkm," | D_Alpha_WWWW0_U -> "dalww0_u(gkm,mkm," | D_Alpha_WWWW2_S -> "dalww2_s(gkm,mkm," | D_Alpha_WWWW2_T -> "dalww2_t(gkm,mkm," | D_Alpha_ZZZZ_S -> "dalz4_s(gkm,mkm," | D_Alpha_ZZZZ_T -> "dalz4_t(gkm,mkm," | D_FT0_ZZWW0_S -> "datzz0_s_0(gkm,mkm," | D_FT0_ZZWW0_T -> "datzz0_t_0(gkm,mkm," | D_FT0_ZZWW0_U -> "datzz0_u_0(gkm,mkm," | D_FT0_ZZWW1_S -> "datzz1_s_0(gkm,mkm," | D_FT0_ZZWW1_T -> "datzz1_t_0(gkm,mkm," | D_FT0_ZZWW1_U -> "datzz1_u_0(gkm,mkm," | D_FT0_WWWW0_S -> "datww0_s_0(gkm,mkm," | D_FT0_WWWW0_T -> "datww0_t_0(gkm,mkm," | D_FT0_WWWW0_U -> "datww0_u_0(gkm,mkm," | D_FT0_WWWW2_S -> "datww2_s_0(gkm,mkm," | D_FT0_WWWW2_T -> "datww2_t_0(gkm,mkm," | D_FT0_WWWW2_U -> "datww2_u_0(gkm,mkm," | D_FT0_ZZZZ_S -> "datz4_s_0(gkm,mkm," | D_FT0_ZZZZ_T -> "datz4_t_0(gkm,mkm," | D_FT0_ZZZZ_U -> "datz4_u_0(gkm,mkm," | D_FT0_AAAA_S -> "data4_s_0(gkm,mkm," | D_FT0_AAAA_T -> "data4_t_0(gkm,mkm," | D_FT0_AAAA_U -> "data4_u_0(gkm,mkm," | D_FT0_AAWW0_S -> "dataw0_s_0(gkm,mkm," | D_FT0_AAWW0_T -> "dataw0_t_0(gkm,mkm," | D_FT0_AAWW0_U -> "dataw0_u_0(gkm,mkm," | D_FT0_AAWW1_S -> "dataw1_s_0(gkm,mkm," | D_FT0_AAWW1_T -> "dataw1_t_0(gkm,mkm," | D_FT0_AAWW1_U -> "dataw1_u_0(gkm,mkm," | D_FT0_AAZZ_S -> "dataz_s_0(gkm,mkm," | D_FT0_AAZZ_T -> "dataz_t_0(gkm,mkm," | D_FT0_AAZZ_U -> "dataz_u_0(gkm,mkm," | D_FT0_AZWW0_S -> "datazw0_s_0(gkm,mkm," | D_FT0_AZWW0_T -> "datazw0_t_0(gkm,mkm," | D_FT0_AZWW0_U -> "datazw0_u_0(gkm,mkm," | D_FT0_AZWW1_S -> "datazw1_s_0(gkm,mkm," | D_FT0_AZWW1_T -> "datazw1_t_0(gkm,mkm," | D_FT0_AZWW1_U -> "datazw1_u_0(gkm,mkm," | D_FT0_AAAZ_S -> "dat3az_s_0(gkm,mkm," | D_FT0_AAAZ_T -> "dat3az_t_0(gkm,mkm," | D_FT0_AAAZ_U -> "dat3az_u_0(gkm,mkm," | D_FT0_AZZZ_S -> "data3z_s_0(gkm,mkm," | D_FT0_AZZZ_T -> "data3z_t_0(gkm,mkm," | D_FT0_AZZZ_U -> "data3z_u_0(gkm,mkm," | D_FT1_ZZWW0_S -> "datzz0_s_1(gkm,mkm," | D_FT1_ZZWW0_T -> "datzz0_t_1(gkm,mkm," | D_FT1_ZZWW0_U -> "datzz0_u_1(gkm,mkm," | D_FT1_ZZWW1_S -> "datzz1_s_1(gkm,mkm," | D_FT1_ZZWW1_T -> "datzz1_t_1(gkm,mkm," | D_FT1_ZZWW1_U -> "datzz1_u_1(gkm,mkm," | D_FT1_WWWW0_S -> "datww0_s_1(gkm,mkm," | D_FT1_WWWW0_T -> "datww0_t_1(gkm,mkm," | D_FT1_WWWW0_U -> "datww0_u_1(gkm,mkm," | D_FT1_WWWW2_S -> "datww2_s_1(gkm,mkm," | D_FT1_WWWW2_T -> "datww2_t_1(gkm,mkm," | D_FT1_WWWW2_U -> "datww2_u_1(gkm,mkm," | D_FT1_ZZZZ_S -> "datz4_s_1(gkm,mkm," | D_FT1_ZZZZ_T -> "datz4_t_1(gkm,mkm," | D_FT1_ZZZZ_U -> "datz4_u_1(gkm,mkm," | D_FT1_AAAA_S -> "data4_s_1(gkm,mkm," | D_FT1_AAAA_T -> "data4_t_1(gkm,mkm," | D_FT1_AAAA_U -> "data4_u_1(gkm,mkm," | D_FT1_AAWW0_S -> "dataw0_s_1(gkm,mkm," | D_FT1_AAWW0_T -> "dataw0_t_1(gkm,mkm," | D_FT1_AAWW0_U -> "dataw0_u_1(gkm,mkm," | D_FT1_AAWW1_S -> "dataw1_s_1(gkm,mkm," | D_FT1_AAWW1_T -> "dataw1_t_1(gkm,mkm," | D_FT1_AAWW1_U -> "dataw1_u_1(gkm,mkm," | D_FT1_AAZZ_S -> "dataz_s_1(gkm,mkm," | D_FT1_AAZZ_T -> "dataz_t_1(gkm,mkm," | D_FT1_AAZZ_U -> "dataz_u_1(gkm,mkm," | D_FT1_AZWW0_S -> "datazw0_s_1(gkm,mkm," | D_FT1_AZWW0_T -> "datazw0_t_1(gkm,mkm," | D_FT1_AZWW0_U -> "datazw0_u_1(gkm,mkm," | D_FT1_AZWW1_S -> "datazw1_s_1(gkm,mkm," | D_FT1_AZWW1_T -> "datazw1_t_1(gkm,mkm," | D_FT1_AZWW1_U -> "datazw1_u_1(gkm,mkm," | D_FT1_AAAZ_S -> "dat3az_s_1(gkm,mkm," | D_FT1_AAAZ_T -> "dat3az_t_1(gkm,mkm," | D_FT1_AAAZ_U -> "dat3az_u_1(gkm,mkm," | D_FT1_AZZZ_S -> "data3z_s_1(gkm,mkm," | D_FT1_AZZZ_T -> "data3z_t_1(gkm,mkm," | D_FT1_AZZZ_U -> "data3z_u_1(gkm,mkm," | D_FT2_ZZWW0_S -> "datzz0_s_2(gkm,mkm," | D_FT2_ZZWW0_T -> "datzz0_t_2(gkm,mkm," | D_FT2_ZZWW0_U -> "datzz0_u_2(gkm,mkm," | D_FT2_ZZWW1_S -> "datzz1_s_2(gkm,mkm," | D_FT2_ZZWW1_T -> "datzz1_t_2(gkm,mkm," | D_FT2_ZZWW1_U -> "datzz1_u_2(gkm,mkm," | D_FT2_WWWW0_S -> "datww0_s_2(gkm,mkm," | D_FT2_WWWW0_T -> "datww0_t_2(gkm,mkm," | D_FT2_WWWW0_U -> "datww0_u_2(gkm,mkm," | D_FT2_WWWW2_S -> "datww2_s_2(gkm,mkm," | D_FT2_WWWW2_T -> "datww2_t_2(gkm,mkm," | D_FT2_WWWW2_U -> "datww2_u_2(gkm,mkm," | D_FT2_ZZZZ_S -> "datz4_s_2(gkm,mkm," | D_FT2_ZZZZ_T -> "datz4_t_2(gkm,mkm," | D_FT2_ZZZZ_U -> "datz4_u_2(gkm,mkm," | D_FT2_AAAA_S -> "data4_s_2(gkm,mkm," | D_FT2_AAAA_T -> "data4_t_2(gkm,mkm," | D_FT2_AAAA_U -> "data4_u_2(gkm,mkm," | D_FT2_AAWW0_S -> "dataw0_s_2(gkm,mkm," | D_FT2_AAWW0_T -> "dataw0_t_2(gkm,mkm," | D_FT2_AAWW0_U -> "dataw0_u_2(gkm,mkm," | D_FT2_AAWW1_S -> "dataw1_s_2(gkm,mkm," | D_FT2_AAWW1_T -> "dataw1_t_2(gkm,mkm," | D_FT2_AAWW1_U -> "dataw1_u_2(gkm,mkm," | D_FT2_AAZZ_S -> "dataz_s_2(gkm,mkm," | D_FT2_AAZZ_T -> "dataz_t_2(gkm,mkm," | D_FT2_AAZZ_U -> "dataz_u_2(gkm,mkm," | D_FT2_AZWW0_S -> "datazw0_s_2(gkm,mkm," | D_FT2_AZWW0_T -> "datazw0_t_2(gkm,mkm," | D_FT2_AZWW0_U -> "datazw0_u_2(gkm,mkm," | D_FT2_AZWW1_S -> "datazw1_s_2(gkm,mkm," | D_FT2_AZWW1_T -> "datazw1_t_2(gkm,mkm," | D_FT2_AZWW1_U -> "datazw1_u_2(gkm,mkm," | D_FT2_AAAZ_S -> "dat3az_s_2(gkm,mkm," | D_FT2_AAAZ_T -> "dat3az_t_2(gkm,mkm," | D_FT2_AAAZ_U -> "dat3az_u_2(gkm,mkm," | D_FT2_AZZZ_S -> "data3z_s_2(gkm,mkm," | D_FT2_AZZZ_T -> "data3z_t_2(gkm,mkm," | D_FT2_AZZZ_U -> "data3z_u_2(gkm,mkm," | D_FTrsi_ZZWW0_S -> "datzz0_s_rsi(gkm,mkm," | D_FTrsi_ZZWW0_T -> "datzz0_t_rsi(gkm,mkm," | D_FTrsi_ZZWW0_U -> "datzz0_u_rsi(gkm,mkm," | D_FTrsi_ZZWW1_S -> "datzz1_s_rsi(gkm,mkm," | D_FTrsi_ZZWW1_T -> "datzz1_t_rsi(gkm,mkm," | D_FTrsi_ZZWW1_U -> "datzz1_u_rsi(gkm,mkm," | D_FTrsi_WWWW0_S -> "datww0_s_rsi(gkm,mkm," | D_FTrsi_WWWW0_T -> "datww0_t_rsi(gkm,mkm," | D_FTrsi_WWWW0_U -> "datww0_u_rsi(gkm,mkm," | D_FTrsi_WWWW2_S -> "datww2_s_rsi(gkm,mkm," | D_FTrsi_WWWW2_T -> "datww2_t_rsi(gkm,mkm," | D_FTrsi_WWWW2_U -> "datww2_u_rsi(gkm,mkm," | D_FTrsi_ZZZZ_S -> "datz4_s_rsi(gkm,mkm," | D_FTrsi_ZZZZ_T -> "datz4_t_rsi(gkm,mkm," | D_FTrsi_ZZZZ_U -> "datz4_u_rsi(gkm,mkm," | D_FTrsi_AAAA_S -> "data4_s_rsi(gkm,mkm," | D_FTrsi_AAAA_T -> "data4_t_rsi(gkm,mkm," | D_FTrsi_AAAA_U -> "data4_u_rsi(gkm,mkm," | D_FTrsi_AAWW0_S -> "dataw0_s_rsi(gkm,mkm," | D_FTrsi_AAWW0_T -> "dataw0_t_rsi(gkm,mkm," | D_FTrsi_AAWW0_U -> "dataw0_u_rsi(gkm,mkm," | D_FTrsi_AAWW1_S -> "dataw1_s_rsi(gkm,mkm," | D_FTrsi_AAWW1_T -> "dataw1_t_rsi(gkm,mkm," | D_FTrsi_AAWW1_U -> "dataw1_u_rsi(gkm,mkm," | D_FTrsi_AAZZ_S -> "dataz_s_rsi(gkm,mkm," | D_FTrsi_AAZZ_T -> "dataz_t_rsi(gkm,mkm," | D_FTrsi_AAZZ_U -> "dataz_u_rsi(gkm,mkm," | D_FTrsi_AZWW0_S -> "datazw0_s_rsi(gkm,mkm," | D_FTrsi_AZWW0_T -> "datazw0_t_rsi(gkm,mkm," | D_FTrsi_AZWW0_U -> "datazw0_u_rsi(gkm,mkm," | D_FTrsi_AZWW1_S -> "datazw1_s_rsi(gkm,mkm," | D_FTrsi_AZWW1_T -> "datazw1_t_rsi(gkm,mkm," | D_FTrsi_AZWW1_U -> "datazw1_u_rsi(gkm,mkm," | D_FTrsi_AAAZ_S -> "dat3az_s_rsi(gkm,mkm," | D_FTrsi_AAAZ_T -> "dat3az_t_rsi(gkm,mkm," | D_FTrsi_AAAZ_U -> "dat3az_u_rsi(gkm,mkm," | D_FTrsi_AZZZ_S -> "data3z_s_rsi(gkm,mkm," | D_FTrsi_AZZZ_T -> "data3z_t_rsi(gkm,mkm," | D_FTrsi_AZZZ_U -> "data3z_u_rsi(gkm,mkm," | D_FM0_ZZWW0_S -> "damzz0_s_0(gkm,mkm," | D_FM0_ZZWW0_T -> "damzz0_t_0(gkm,mkm," | D_FM0_ZZWW0_U -> "damzz0_u_0(gkm,mkm," | D_FM0_ZZWW1_S -> "damzz1_s_0(gkm,mkm," | D_FM0_ZZWW1_T -> "damzz1_t_0(gkm,mkm," | D_FM0_ZZWW1_U -> "damzz1_u_0(gkm,mkm," | D_FM0_WWWW0_S -> "damww0_s_0(gkm,mkm," | D_FM0_WWWW0_T -> "damww0_t_0(gkm,mkm," | D_FM0_WWWW0_U -> "damww0_u_0(gkm,mkm," | D_FM0_WWWW2_S -> "damww2_s_0(gkm,mkm," | D_FM0_WWWW2_T -> "damww2_t_0(gkm,mkm," | D_FM0_WWWW2_U -> "damww2_u_0(gkm,mkm," | D_FM0_ZZZZ_S -> "damz4_s_0(gkm,mkm," | D_FM0_ZZZZ_T -> "damz4_t_0(gkm,mkm," | D_FM0_ZZZZ_U -> "damz4_u_0(gkm,mkm," | D_FM1_ZZWW0_S -> "damzz0_s_1(gkm,mkm," | D_FM1_ZZWW0_T -> "damzz0_t_1(gkm,mkm," | D_FM1_ZZWW0_U -> "damzz0_u_1(gkm,mkm," | D_FM1_ZZWW1_S -> "damzz1_s_1(gkm,mkm," | D_FM1_ZZWW1_T -> "damzz1_t_1(gkm,mkm," | D_FM1_ZZWW1_U -> "damzz1_u_1(gkm,mkm," | D_FM1_WWWW0_S -> "damww0_s_1(gkm,mkm," | D_FM1_WWWW0_T -> "damww0_t_1(gkm,mkm," | D_FM1_WWWW0_U -> "damww0_u_1(gkm,mkm," | D_FM1_WWWW2_S -> "damww2_s_1(gkm,mkm," | D_FM1_WWWW2_T -> "damww2_t_1(gkm,mkm," | D_FM1_WWWW2_U -> "damww2_u_1(gkm,mkm," | D_FM1_ZZZZ_S -> "damz4_s_1(gkm,mkm," | D_FM1_ZZZZ_T -> "damz4_t_1(gkm,mkm," | D_FM1_ZZZZ_U -> "damz4_u_1(gkm,mkm," | D_FM7_ZZWW0_S -> "damzz0_s_7(gkm,mkm," | D_FM7_ZZWW0_T -> "damzz0_t_7(gkm,mkm," | D_FM7_ZZWW0_U -> "damzz0_u_7(gkm,mkm," | D_FM7_ZZWW1_S -> "damzz1_s_7(gkm,mkm," | D_FM7_ZZWW1_T -> "damzz1_t_7(gkm,mkm," | D_FM7_ZZWW1_U -> "damzz1_u_7(gkm,mkm," | D_FM7_WWWW0_S -> "damww0_s_7(gkm,mkm," | D_FM7_WWWW0_T -> "damww0_t_7(gkm,mkm," | D_FM7_WWWW0_U -> "damww0_u_7(gkm,mkm," | D_FM7_WWWW2_S -> "damww2_s_7(gkm,mkm," | D_FM7_WWWW2_T -> "damww2_t_7(gkm,mkm," | D_FM7_WWWW2_U -> "damww2_u_7(gkm,mkm," | D_FM7_ZZZZ_S -> "damz4_s_7(gkm,mkm," | D_FM7_ZZZZ_T -> "damz4_t_7(gkm,mkm," | D_FM7_ZZZZ_U -> "damz4_u_7(gkm,mkm," | D_Alpha_HHHH_S -> "dalh4_s(gkm,mkm," | D_Alpha_HHHH_T -> "dalh4_t(gkm,mkm," | D_Alpha_HHWW0_S -> "dalhw0_s(gkm,mkm," | D_Alpha_HHWW0_T -> "dalhw0_t(gkm,mkm," | D_Alpha_HHZZ0_S -> "dalhz0_s(gkm,mkm," | D_Alpha_HHZZ0_T -> "dalhz0_t(gkm,mkm," | D_Alpha_HHWW1_S -> "dalhw1_s(gkm,mkm," | D_Alpha_HHWW1_T -> "dalhw1_t(gkm,mkm," | D_Alpha_HHWW1_U -> "dalhw1_u(gkm,mkm," | D_Alpha_HHZZ1_S -> "dalhz1_s(gkm,mkm," | D_Alpha_HHZZ1_T -> "dalhz1_t(gkm,mkm," | D_Alpha_HHZZ1_U -> "dalhz1_u(gkm,mkm," | D_FM0_HHWW0_S -> "damhw0_s_0(gkm,mkm," | D_FM0_HHWW0_T -> "damhw0_t_0(gkm,mkm," | D_FM0_HHWW0_U -> "damhw0_u_0(gkm,mkm," | D_FM0_HHZZ0_S -> "damhz0_s_0(gkm,mkm," | D_FM0_HHZZ0_T -> "damhz0_t_0(gkm,mkm," | D_FM0_HHZZ0_U -> "damhz0_u_0(gkm,mkm," | D_FM0_HHWW1_S -> "damhw1_s_0(gkm,mkm," | D_FM0_HHWW1_T -> "damhw1_t_0(gkm,mkm," | D_FM0_HHWW1_U -> "damhw1_u_0(gkm,mkm," | D_FM0_HHZZ1_S -> "damhz1_s_0(gkm,mkm," | D_FM0_HHZZ1_T -> "damhz1_t_0(gkm,mkm," | D_FM0_HHZZ1_U -> "damhz1_u_0(gkm,mkm," | D_FM1_HHWW0_S -> "damhw0_s_1(gkm,mkm," | D_FM1_HHWW0_T -> "damhw0_t_1(gkm,mkm," | D_FM1_HHWW0_U -> "damhw0_u_1(gkm,mkm," | D_FM1_HHZZ0_S -> "damhz0_s_1(gkm,mkm," | D_FM1_HHZZ0_T -> "damhz0_t_1(gkm,mkm," | D_FM1_HHZZ0_U -> "damhz0_u_1(gkm,mkm," | D_FM1_HHWW1_S -> "damhw1_s_1(gkm,mkm," | D_FM1_HHWW1_T -> "damhw1_t_1(gkm,mkm," | D_FM1_HHWW1_U -> "damhw1_u_1(gkm,mkm," | D_FM1_HHZZ1_S -> "damhz1_s_1(gkm,mkm," | D_FM1_HHZZ1_T -> "damhz1_t_1(gkm,mkm," | D_FM1_HHZZ1_U -> "damhz1_u_1(gkm,mkm," | D_FM7_HHWW0_S -> "damhw0_s_7(gkm,mkm," | D_FM7_HHWW0_T -> "damhw0_t_7(gkm,mkm," | D_FM7_HHWW0_U -> "damhw0_u_7(gkm,mkm," | D_FM7_HHZZ0_S -> "damhz0_s_7(gkm,mkm," | D_FM7_HHZZ0_T -> "damhz0_t_7(gkm,mkm," | D_FM7_HHZZ0_U -> "damhz0_u_7(gkm,mkm," | D_FM7_HHWW1_S -> "damhw1_s_7(gkm,mkm," | D_FM7_HHWW1_T -> "damhw1_t_7(gkm,mkm," | D_FM7_HHWW1_U -> "damhw1_u_7(gkm,mkm," | D_FM7_HHZZ1_S -> "damhz1_s_7(gkm,mkm," | D_FM7_HHZZ1_T -> "damhz1_t_7(gkm,mkm," | D_FM7_HHZZ1_U -> "damhz1_u_7(gkm,mkm," | G_HWW -> "ghww" | G_HZZ -> "ghzz" | G_HHWW -> "ghhww" | G_HHZZ -> "ghhzz" | G_SWW -> "gsww" | G_SZZ -> "gszz" | G_SHH -> "gshh" | G_SWW_T -> "gswwt" | G_SZZ_T -> "gszzt" | G_SAA_T -> "gsaat" | G_SAZ_T -> "gsazt" | G_PNWW -> "gpnww" | G_PNZZ -> "gpnzz" | G_PSNWW -> "gpsnww" | G_PSNZZ -> "gpsnzz" | G_PSNHH -> "gpsnhh" | G_PWZ -> "gpwz" | G_PWW -> "gpww" | G_FWW -> "gfww" | G_FZZ -> "gfzz" | G_FWW_CF -> "gfwwcf" | G_FZZ_CF -> "gfzzcf" | G_FHH -> "gfhh" | G_FHH_CF -> "gfhhcf" | G_FWW_T -> "gfwwt" | G_FZZ_T -> "gfzzt" | G_TNWW -> "gtnww" | G_TNZZ -> "gtnzz" | G_TNWW_CF -> "gtnwwcf" | G_TNZZ_CF -> "gtnzzcf" | G_TSNWW -> "gtsnww" | G_TSNZZ -> "gtsnzz" | G_TSNWW_CF -> "gtsnwwcf" | G_TSNZZ_CF -> "gtsnzzcf" | G_TWZ -> "gtwz" | G_TWW -> "gtww" | G_TWZ_CF -> "gtwzcf" | G_TWW_CF -> "gtwwcf" | G_SSWW -> "gssww" | G_SSZZ -> "gsszz" | G_Htt -> "ghtt" | G_Hbb -> "ghbb" | G_Htautau -> "ghtautau" | G_Hcc -> "ghcc" | G_Hmm -> "ghmm" | G_HGaZ -> "ghgaz" | G_HGaGa -> "ghgaga" | G_Hgg -> "ghgg" | G_HGaGa_anom -> "ghgaga_ac" | G_HGaZ_anom -> "ghgaz_ac" | G_HZZ_anom -> "ghzz_ac" | G_HWW_anom -> "ghww_ac" | G_HGaZ_u -> "ghgaz_u" | G_HZZ_u -> "ghzz_u" | G_HWW_u -> "ghww_u" | G_H3 -> "gh3" | G_H4 -> "gh4" | Gs -> "gs" | I_Gs -> "igs" | G2 -> "gs**2" | Mass f -> "mass" ^ flavor_symbol f | Width f -> "width" ^ flavor_symbol f | K_Matrix_Coeff i -> "kc" ^ string_of_int i | K_Matrix_Pole i -> "kp" ^ string_of_int i end (* \thocwmodulesection{Complete Minimal Standard Model including additional Resonances (alternate Tensor)} *) module SSC_AltT (Flags : SSC_flags) = struct open Coupling let default_width = ref Timelike let use_fudged_width = ref false let options = Options.create [ "constant_width", Arg.Unit (fun () -> default_width := Constant), "use constant width (also in t-channel)"; "fudged_width", Arg.Set use_fudged_width, "use fudge factor for charge particle width"; "custom_width", Arg.String (fun f -> default_width := Custom f), "use custom width"; "cancel_widths", Arg.Unit (fun () -> default_width := Vanishing), "use vanishing width"; "cms_width", Arg.Unit (fun () -> default_width := Complex_Mass), - "use complex mass scheme"] + "use complex mass scheme"; + "running_width", Arg.Unit (fun () -> default_width := Running), + "use running width"] type f_aux_top = TTGG | TBWA | TBWZ | TTWW | BBWW | (*i top auxiliary field "flavors" *) QGUG | QBUB | QW | DL | DR type matter_field = L of int | N of int | U of int | D of int type gauge_boson = Ga | Wp | Wm | Z | Gl type other = Phip | Phim | Phi0 | H | Rsigma | Rphin | Rphisn | Rphip | Rphim | Rphipp | Rphimm | Rf | Rtn | Rtsn | Rtp | Rtm | Rtpp | Rtmm | Rff | Rfv | Rfphi | Aux_top of int*int*int*bool*f_aux_top (*i lorentz*color*charge*top-side*flavor *) type flavor = M of matter_field | G of gauge_boson | O of other let matter_field f = M f let gauge_boson f = G f let other f = O f type field = | Matter of matter_field | Gauge of gauge_boson | Other of other let field = function | M f -> Matter f | G f -> Gauge f | O f -> Other f type gauge = unit let gauge_symbol () = failwith "Modellib_BSM.SSC_AltT.gauge_symbol: internal error" let family n = List.map matter_field [ L n; N n; U n; D n ] let rec aux_top_flavors (f,l,co,ch) = List.append ( List.map other [ Aux_top(l,co,ch/2,true,f); Aux_top(l,co,ch/2,false,f) ] ) ( if ch > 1 then List.append ( List.map other [ Aux_top(l,co,-ch/2,true,f); Aux_top(l,co,-ch/2,false,f) ] ) ( aux_top_flavors (f,l,co,(ch-2)) ) else [] ) let external_flavors () = [ "1st Generation", ThoList.flatmap family [1; -1]; "2nd Generation", ThoList.flatmap family [2; -2]; "3rd Generation", ThoList.flatmap family [3; -3]; "Gauge Bosons", List.map gauge_boson [Ga; Z; Wp; Wm; Gl]; "Higgs", List.map other [H]; "Scalar Resonances", List.map other [Rsigma; Rphin; Rphisn; Rphip; Rphim; Rphipp; Rphimm]; "Tensor Resonances", List.map other [Rf; Rtn; Rtsn; Rtp; Rtm; Rtpp; Rtmm]; "Alternate Tensor", List.map other [Rff; Rfv; Rfphi]; "Goldstone Bosons", List.map other [Phip; Phim; Phi0] ] let flavors () = List.append ( ThoList.flatmap snd (external_flavors ()) ) ( ThoList.flatmap aux_top_flavors [ (TTGG,2,1,1); (TBWA,2,0,2); (TBWZ,2,0,2); (TTWW,2,0,1); (BBWW,2,0,1); (QGUG,1,1,1); (QBUB,1,0,1); (QW,1,0,3); (DL,0,0,3); (DR,0,0,3) ] ) let spinor n = if n >= 0 then Spinor else ConjSpinor let lorentz_aux = function | 2 -> Tensor_1 | 1 -> Vector | 0 -> Scalar | _ -> invalid_arg ("SM.lorentz_aux: wrong value") let lorentz = function | M f -> begin match f with | L n -> spinor n | N n -> spinor n | U n -> spinor n | D n -> spinor n end | G f -> begin match f with | Ga | Gl -> Vector | Wp | Wm | Z -> Massive_Vector end | O f -> begin match f with | Aux_top (l,_,_,_,_) -> lorentz_aux l | Rf | Rtn | Rtsn | Rtp | Rtm | Rtpp | Rtmm -> Tensor_2 | Rff -> Tensor_2 | Rfv -> Vector | _ -> Scalar end let color = function | M (U n) -> Color.SUN (if n > 0 then 3 else -3) | M (D n) -> Color.SUN (if n > 0 then 3 else -3) | G Gl -> Color.AdjSUN 3 | O (Aux_top (_,co,_,_,_)) -> if co == 0 then Color.Singlet else Color.AdjSUN 3 | _ -> Color.Singlet let nc () = 3 let prop_spinor n = if n >= 0 then Prop_Spinor else Prop_ConjSpinor let prop_aux = function | 2 -> Aux_Tensor_1 | 1 -> Aux_Vector | 0 -> Aux_Scalar | _ -> invalid_arg ("SM.prop_aux: wrong value") let propagator = function | M f -> begin match f with | L n -> prop_spinor n | N n -> prop_spinor n | U n -> prop_spinor n | D n -> prop_spinor n end | G f -> begin match f with | Ga | Gl -> Prop_Feynman | Wp | Wm | Z -> Prop_Unitarity end | O f -> begin match f with | Phip | Phim | Phi0 -> Only_Insertion | H | Rsigma -> Prop_Scalar | Rphin | Rphisn | Rphip | Rphim | Rphipp | Rphimm -> Prop_Scalar | Rf -> Prop_Tensor_2 | Rff -> Prop_Tensor_pure | Rfv -> Prop_Vector_pure | Rfphi -> Prop_Scalar | Rtn | Rtsn | Rtp | Rtm | Rtpp | Rtmm -> Prop_Tensor_2 | Aux_top (l,_,_,_,_) -> prop_aux l end (* Optionally, ask for the fudge factor treatment for the widths of charged particles. Currently, this only applies to $W^\pm$ and top. *) let width f = if !use_fudged_width then match f with | G Wp | G Wm | M (U 3) | M (U (-3)) -> Fudged | _ -> !default_width else !default_width let goldstone = function | G f -> begin match f with | Wp -> Some (O Phip, Coupling.Integer 1) | Wm -> Some (O Phim, Coupling.Integer 1) | Z -> Some (O Phi0, Coupling.Integer 1) | _ -> None end | _ -> None let conjugate = function | M f -> M (begin match f with | L n -> L (-n) | N n -> N (-n) | U n -> U (-n) | D n -> D (-n) end) | G f -> G (begin match f with | Gl -> Gl | Ga -> Ga | Z -> Z | Wp -> Wm | Wm -> Wp end) | O f -> O (begin match f with | Phip -> Phim | Phim -> Phip | Phi0 -> Phi0 | H -> H | Rsigma -> Rsigma | Rphin -> Rphin | Rphip -> Rphim | Rphim -> Rphip | Rphisn -> Rphisn | Rphipp -> Rphimm | Rphimm -> Rphipp | Rf -> Rf | Rff -> Rff | Rfv -> Rfv | Rfphi -> Rfphi | Rtn -> Rtn | Rtsn -> Rtsn | Rtp -> Rtm | Rtm -> Rtp | Rtpp -> Rtmm | Rtmm -> Rtpp | Aux_top (l,co,ch,n,f) -> Aux_top (l,co,(-ch),(not n),f) end) let fermion = function | M f -> begin match f with | L n -> if n > 0 then 1 else -1 | N n -> if n > 0 then 1 else -1 | U n -> if n > 0 then 1 else -1 | D n -> if n > 0 then 1 else -1 end | G f -> begin match f with | Gl | Ga | Z | Wp | Wm -> 0 end | O _ -> 0 (* Electrical charge, lepton number, baryon number. We could avoid the rationals altogether by multiplying the first and last by 3 \ldots *) module Ch = Charges.QQ let ( // ) = Algebra.Small_Rational.make let generation' = function | 1 -> [ 1//1; 0//1; 0//1] | 2 -> [ 0//1; 1//1; 0//1] | 3 -> [ 0//1; 0//1; 1//1] | -1 -> [-1//1; 0//1; 0//1] | -2 -> [ 0//1; -1//1; 0//1] | -3 -> [ 0//1; 0//1; -1//1] | n -> invalid_arg ("SM.generation': " ^ string_of_int n) let generation f = if Flags.ckm_present then [] else match f with | M (L n | N n | U n | D n) -> generation' n | G _ | O _ -> [0//1; 0//1; 0//1] let charge = function | M f -> begin match f with | L n -> if n > 0 then -1//1 else 1//1 | N n -> 0//1 | U n -> if n > 0 then 2//3 else -2//3 | D n -> if n > 0 then -1//3 else 1//3 end | G f -> begin match f with | Gl | Ga | Z -> 0//1 | Wp -> 1//1 | Wm -> -1//1 end | O f -> begin match f with | H | Rsigma | Phi0 | Rphin | Rphisn | Rf | Rff | Rfv | Rfphi | Rtn | Rtsn -> 0//1 | Phip | Rphip | Rtp -> 1//1 | Phim | Rphim | Rtm -> -1//1 | Rphipp | Rtpp -> 2//1 | Rphimm | Rtmm -> -2//1 | Aux_top (_,_,ch,_,_) -> ch//1 end let lepton = function | M f -> begin match f with | L n | N n -> if n > 0 then 1//1 else -1//1 | U _ | D _ -> 0//1 end | G _ | O _ -> 0//1 let baryon = function | M f -> begin match f with | L _ | N _ -> 0//1 | U n | D n -> if n > 0 then 1//1 else -1//1 end | G _ | O _ -> 0//1 let charges f = [ charge f; lepton f; baryon f] @ generation f type constant = | Unit | Half | Pi | Alpha_QED | Sin2thw | Sinthw | Costhw | E | G_weak | I_G_weak | Vev | Q_lepton | Q_up | Q_down | G_CC | G_CCQ of int*int | G_NC_neutrino | G_NC_lepton | G_NC_up | G_NC_down | G_TVA_ttA | G_TVA_bbA | G_VLR_ttZ | G_TVA_ttZ | G_TVA_bbZ | G_VLR_btW | G_VLR_tbW | G_TLR_btW | G_TRL_tbW | G_TLR_btWZ | G_TRL_tbWZ | G_TLR_btWA | G_TRL_tbWA | G_TVA_ttWW | G_TVA_bbWW | G_TVA_ttG | G_TVA_ttGG | G_SP_ttH | G_VLR_qGuG | G_VLR_qBuB | G_VLR_qBuB_u | G_VLR_qBuB_d | G_VLR_qBuB_e | G_VL_qBuB_n | G_VL_qW | G_VL_qW_u | G_VL_qW_d | G_SL_DttR | G_SR_DttR | G_SL_DttL | G_SLR_DbtR | G_SL_DbtL | I_Q_W | I_G_ZWW | G_WWWW | G_ZZWW | G_AZWW | G_AAWW | I_G1_AWW | I_G1_ZWW | I_G1_plus_kappa_plus_G4_AWW | I_G1_plus_kappa_plus_G4_ZWW | I_G1_plus_kappa_minus_G4_AWW | I_G1_plus_kappa_minus_G4_ZWW | I_G1_minus_kappa_plus_G4_AWW | I_G1_minus_kappa_plus_G4_ZWW | I_G1_minus_kappa_minus_G4_AWW | I_G1_minus_kappa_minus_G4_ZWW | I_lambda_AWW | I_lambda_ZWW | G5_AWW | G5_ZWW | I_kappa5_AWW | I_kappa5_ZWW | I_lambda5_AWW | I_lambda5_ZWW | FS0_HHWW | FS0_HHZZ | FS1_HHWW | FS1_HHZZ | FM0_HHWW | FM0_HHZZ | FM1_HHWW | FM1_HHZZ | FM7_HHWW | FM7_HHZZ | Alpha_WWWW0 | Alpha_ZZWW1 | Alpha_WWWW2 | Alpha_ZZWW0 | Alpha_ZZZZ | FT0_WWWW0 | FT0_WWWW2 | FT0_ZZWW0 | FT0_ZZWW1 | FT0_ZZZZ | FT0_AAAA | FT0_AAWW0 | FT0_AAWW1 | FT0_AAZZ | FT0_AZWW0 | FT0_AZWW1 | FT0_AAAZ | FT0_AZZZ | FT1_WWWW0 | FT1_WWWW2 | FT1_ZZWW0 | FT1_ZZWW1 | FT1_ZZZZ | FT1_AAAA | FT1_AAWW0 | FT1_AAWW1 | FT1_AAZZ | FT1_AZWW0 | FT1_AZWW1 | FT1_AAAZ | FT1_AZZZ | FT2_WWWW0 | FT2_WWWW2 | FT2_ZZWW0 | FT2_ZZWW1 | FT2_ZZZZ | FT2_AAAA | FT2_AAWW0 | FT2_AAWW1 | FT2_AAZZ | FT2_AZWW0 | FT2_AZWW1 | FT2_AAAZ | FT2_AZZZ | FM0_WWWW0 | FM0_WWWW2 | FM0_ZZWW0 | FM0_ZZWW1 | FM0_ZZZZ | FM1_WWWW0 | FM1_WWWW2 | FM1_ZZWW0 | FM1_ZZWW1 | FM1_ZZZZ | FM7_WWWW0 | FM7_WWWW2 | FM7_ZZWW0 | FM7_ZZWW1 | FM7_ZZZZ | D_Alpha_ZZWW0_S | D_Alpha_ZZWW0_T | D_Alpha_ZZWW1_S | D_Alpha_ZZWW1_T | D_Alpha_ZZWW1_U | D_Alpha_WWWW0_S | D_Alpha_WWWW0_T | D_Alpha_WWWW0_U | D_Alpha_WWWW2_S | D_Alpha_WWWW2_T | D_Alpha_ZZZZ_S | D_Alpha_ZZZZ_T | D_FT0_ZZWW0_S | D_FT0_ZZWW0_T | D_FT0_ZZWW0_U | D_FT0_ZZWW1_S | D_FT0_ZZWW1_T | D_FT0_ZZWW1_U | D_FT0_WWWW0_S | D_FT0_WWWW0_T | D_FT0_WWWW0_U | D_FT0_WWWW2_S | D_FT0_WWWW2_T | D_FT0_WWWW2_U | D_FT0_ZZZZ_S | D_FT0_ZZZZ_T | D_FT0_ZZZZ_U | D_FT0_AAAA_S | D_FT0_AAAA_T | D_FT0_AAAA_U | D_FT0_AAWW0_S | D_FT0_AAWW0_T | D_FT0_AAWW0_U | D_FT0_AAWW1_S | D_FT0_AAWW1_T | D_FT0_AAWW1_U | D_FT0_AAZZ_S | D_FT0_AAZZ_T | D_FT0_AAZZ_U | D_FT0_AZWW0_S | D_FT0_AZWW0_T | D_FT0_AZWW0_U | D_FT0_AZWW1_S | D_FT0_AZWW1_T | D_FT0_AZWW1_U | D_FT0_AAAZ_S | D_FT0_AAAZ_T | D_FT0_AAAZ_U | D_FT0_AZZZ_S | D_FT0_AZZZ_T | D_FT0_AZZZ_U | D_FT1_ZZWW0_S | D_FT1_ZZWW0_T | D_FT1_ZZWW0_U | D_FT1_ZZWW1_S | D_FT1_ZZWW1_T | D_FT1_ZZWW1_U | D_FT1_WWWW0_S | D_FT1_WWWW0_T | D_FT1_WWWW0_U | D_FT1_WWWW2_S | D_FT1_WWWW2_T | D_FT1_WWWW2_U | D_FT1_ZZZZ_S | D_FT1_ZZZZ_T | D_FT1_ZZZZ_U | D_FT1_AAAA_S | D_FT1_AAAA_T | D_FT1_AAAA_U | D_FT1_AAWW0_S | D_FT1_AAWW0_T | D_FT1_AAWW0_U | D_FT1_AAWW1_S | D_FT1_AAWW1_T | D_FT1_AAWW1_U | D_FT1_AAZZ_S | D_FT1_AAZZ_T | D_FT1_AAZZ_U | D_FT1_AZWW0_S | D_FT1_AZWW0_T | D_FT1_AZWW0_U | D_FT1_AZWW1_S | D_FT1_AZWW1_T | D_FT1_AZWW1_U | D_FT1_AAAZ_S | D_FT1_AAAZ_T | D_FT1_AAAZ_U | D_FT1_AZZZ_S | D_FT1_AZZZ_T | D_FT1_AZZZ_U | D_FT2_ZZWW0_S | D_FT2_ZZWW0_T | D_FT2_ZZWW0_U | D_FT2_ZZWW1_S | D_FT2_ZZWW1_T | D_FT2_ZZWW1_U | D_FT2_WWWW0_S | D_FT2_WWWW0_T | D_FT2_WWWW0_U | D_FT2_WWWW2_S | D_FT2_WWWW2_T | D_FT2_WWWW2_U | D_FT2_ZZZZ_S | D_FT2_ZZZZ_T | D_FT2_ZZZZ_U | D_FT2_AAAA_S | D_FT2_AAAA_T | D_FT2_AAAA_U | D_FT2_AAWW0_S | D_FT2_AAWW0_T | D_FT2_AAWW0_U | D_FT2_AAWW1_S | D_FT2_AAWW1_T | D_FT2_AAWW1_U | D_FT2_AAZZ_S | D_FT2_AAZZ_T | D_FT2_AAZZ_U | D_FT2_AZWW0_S | D_FT2_AZWW0_T | D_FT2_AZWW0_U | D_FT2_AZWW1_S | D_FT2_AZWW1_T | D_FT2_AZWW1_U | D_FT2_AAAZ_S | D_FT2_AAAZ_T | D_FT2_AAAZ_U | D_FT2_AZZZ_S | D_FT2_AZZZ_T | D_FT2_AZZZ_U | D_FTrsi_ZZWW0_S | D_FTrsi_ZZWW0_T | D_FTrsi_ZZWW0_U | D_FTrsi_ZZWW1_S | D_FTrsi_ZZWW1_T | D_FTrsi_ZZWW1_U | D_FTrsi_WWWW0_S | D_FTrsi_WWWW0_T | D_FTrsi_WWWW0_U | D_FTrsi_WWWW2_S | D_FTrsi_WWWW2_T | D_FTrsi_WWWW2_U | D_FTrsi_ZZZZ_S | D_FTrsi_ZZZZ_T | D_FTrsi_ZZZZ_U | D_FTrsi_AAAA_S | D_FTrsi_AAAA_T | D_FTrsi_AAAA_U | D_FTrsi_AAWW0_S | D_FTrsi_AAWW0_T | D_FTrsi_AAWW0_U | D_FTrsi_AAWW1_S | D_FTrsi_AAWW1_T | D_FTrsi_AAWW1_U | D_FTrsi_AAZZ_S | D_FTrsi_AAZZ_T | D_FTrsi_AAZZ_U | D_FTrsi_AZWW0_S | D_FTrsi_AZWW0_T | D_FTrsi_AZWW0_U | D_FTrsi_AZWW1_S | D_FTrsi_AZWW1_T | D_FTrsi_AZWW1_U | D_FTrsi_AAAZ_S | D_FTrsi_AAAZ_T | D_FTrsi_AAAZ_U | D_FTrsi_AZZZ_S | D_FTrsi_AZZZ_T | D_FTrsi_AZZZ_U | D_FM0_ZZWW0_S | D_FM0_ZZWW0_T | D_FM0_ZZWW0_U | D_FM0_ZZWW1_S | D_FM0_ZZWW1_T | D_FM0_ZZWW1_U | D_FM0_WWWW0_S | D_FM0_WWWW0_T | D_FM0_WWWW0_U | D_FM0_WWWW2_S | D_FM0_WWWW2_T | D_FM0_WWWW2_U | D_FM0_ZZZZ_S | D_FM0_ZZZZ_T | D_FM0_ZZZZ_U | D_FM1_ZZWW0_S | D_FM1_ZZWW0_T | D_FM1_ZZWW0_U | D_FM1_ZZWW1_S | D_FM1_ZZWW1_T | D_FM1_ZZWW1_U | D_FM1_WWWW0_S | D_FM1_WWWW0_T | D_FM1_WWWW0_U | D_FM1_WWWW2_S | D_FM1_WWWW2_T | D_FM1_WWWW2_U | D_FM1_ZZZZ_S | D_FM1_ZZZZ_T | D_FM1_ZZZZ_U | D_FM7_ZZWW0_S | D_FM7_ZZWW0_T | D_FM7_ZZWW0_U | D_FM7_ZZWW1_S | D_FM7_ZZWW1_T | D_FM7_ZZWW1_U | D_FM7_WWWW0_S | D_FM7_WWWW0_T | D_FM7_WWWW0_U | D_FM7_WWWW2_S | D_FM7_WWWW2_T | D_FM7_WWWW2_U | D_FM7_ZZZZ_S | D_FM7_ZZZZ_T | D_FM7_ZZZZ_U | D_Alpha_HHHH_S | D_Alpha_HHHH_T | D_Alpha_HHZZ0_S | D_Alpha_HHWW0_S | D_Alpha_HHZZ0_T | D_Alpha_HHWW0_T | D_Alpha_HHZZ1_S | D_Alpha_HHWW1_S | D_Alpha_HHZZ1_T | D_Alpha_HHWW1_T | D_Alpha_HHZZ1_U | D_Alpha_HHWW1_U | D_FM0_HHZZ0_S | D_FM0_HHWW0_S | D_FM0_HHZZ0_T | D_FM0_HHWW0_T | D_FM0_HHZZ0_U | D_FM0_HHWW0_U | D_FM0_HHZZ1_S | D_FM0_HHWW1_S | D_FM0_HHZZ1_T | D_FM0_HHWW1_T | D_FM0_HHZZ1_U | D_FM0_HHWW1_U | D_FM1_HHZZ0_S | D_FM1_HHWW0_S | D_FM1_HHZZ0_T | D_FM1_HHWW0_T | D_FM1_HHZZ0_U | D_FM1_HHWW0_U | D_FM1_HHZZ1_S | D_FM1_HHWW1_S | D_FM1_HHZZ1_T | D_FM1_HHWW1_T | D_FM1_HHZZ1_U | D_FM1_HHWW1_U | D_FM7_HHZZ0_S | D_FM7_HHWW0_S | D_FM7_HHZZ0_T | D_FM7_HHWW0_T | D_FM7_HHZZ0_U | D_FM7_HHWW0_U | D_FM7_HHZZ1_S | D_FM7_HHWW1_S | D_FM7_HHZZ1_T | D_FM7_HHWW1_T | D_FM7_HHZZ1_U | D_FM7_HHWW1_U | G_HWW | G_HHWW | G_HZZ | G_HHZZ | G_SWW | G_SWW_T | G_SSWW | G_SZZ | G_SZZ_T | G_SSZZ | G_SHH | G_SAA_T | G_SAZ_T | G_PNWW | G_PNZZ | G_PWZ | G_PWW | G_PSNWW | G_PSNZZ | G_PSNHH | G_FWW | G_FZZ | G_FWW_CF | G_FZZ_CF | G_FWW_T | G_FZZ_T | G_FHH | G_FHH_CF | G_FFWW | G_FFZZ | G_FFWW_CF | G_FFZZ_CF | G_FFHH | G_FFHH_CF | G_FVWW | G_FVZZ | G_FVHH | G_FVWW_CF | G_FVZZ_CF | G_FVHH_CF | G_FDDSWW | G_FDDSZZ | G_FDDSHH | G_FDDSWW_CF | G_FDDSZZ_CF | G_FDDSHH_CF | G_FSWW | G_FSZZ | G_FSHH | G_TNWW | G_TNZZ | G_TSNWW | G_TSNZZ | G_TWZ | G_TWW | G_TNWW_CF | G_TNZZ_CF | G_TSNWW_CF | G_TSNZZ_CF | G_TWZ_CF | G_TWW_CF | G_Htt | G_Hbb | G_Hcc | G_Hmm | G_Htautau | G_H3 | G_H4 | FS_H4 | G_HGaZ | G_HGaGa | G_Hgg | G_HGaZ_anom | G_HGaGa_anom | G_HZZ_anom | G_HWW_anom | G_HGaZ_u | G_HZZ_u | G_HWW_u | Gs | I_Gs | G2 | Mass of flavor | Width of flavor | K_Matrix_Coeff of int | K_Matrix_Pole of int (* \begin{dubious} The current abstract syntax for parameter dependencies is admittedly tedious. Later, there will be a parser for a convenient concrete syntax as a part of a concrete syntax for models. But as these examples show, it should include simple functions. \end{dubious} *) type orders = int * int let orders = function | _ -> (0,0) (* \begin{subequations} \begin{align} \alpha_{\text{QED}} &= \frac{1}{137.0359895} \\ \sin^2\theta_w &= 0.23124 \end{align} \end{subequations} *) let input_parameters = [ Alpha_QED, 1. /. 137.0359895; Sin2thw, 0.23124; Mass (G Z), 91.187; Mass (M (N 1)), 0.0; Mass (M (L 1)), 0.51099907e-3; Mass (M (N 2)), 0.0; Mass (M (L 2)), 0.105658389; Mass (M (N 3)), 0.0; Mass (M (L 3)), 1.77705; Mass (M (U 1)), 5.0e-3; Mass (M (D 1)), 3.0e-3; Mass (M (U 2)), 1.2; Mass (M (D 2)), 0.1; Mass (M (U 3)), 174.0; Mass (M (D 3)), 4.2 ] (* \begin{subequations} \begin{align} e &= \sqrt{4\pi\alpha} \\ \sin\theta_w &= \sqrt{\sin^2\theta_w} \\ \cos\theta_w &= \sqrt{1-\sin^2\theta_w} \\ g &= \frac{e}{\sin\theta_w} \\ m_W &= \cos\theta_w m_Z \\ v &= \frac{2m_W}{g} \\ g_{CC} = -\frac{g}{2\sqrt2} &= -\frac{e}{2\sqrt2\sin\theta_w} \\ Q_{\text{lepton}} = -q_{\text{lepton}}e &= e \\ Q_{\text{up}} = -q_{\text{up}}e &= -\frac{2}{3}e \\ Q_{\text{down}} = -q_{\text{down}}e &= \frac{1}{3}e \\ \ii q_We = \ii g_{\gamma WW} &= \ii e \\ \ii g_{ZWW} &= \ii g \cos\theta_w \\ \ii g_{WWW} &= \ii g \end{align} \end{subequations} *) (* \begin{dubious} \ldots{} to be continued \ldots{} The quartic couplings can't be correct, because the dimensions are wrong! \begin{subequations} \begin{align} g_{HWW} &= g m_W = 2 \frac{m_W^2}{v}\\ g_{HHWW} &= 2 \frac{m_W^2}{v^2} = \frac{g^2}{2} \\ g_{HZZ} &= \frac{g}{\cos\theta_w}m_Z \\ g_{HHZZ} &= 2 \frac{m_Z^2}{v^2} = \frac{g^2}{2\cos\theta_w} \\ g_{Htt} &= \lambda_t \\ g_{Hbb} &= \lambda_b=\frac{m_b}{m_t}\lambda_t \\ g_{H^3} &= - \frac{3g}{2}\frac{m_H^2}{m_W} = - 3 \frac{m_H^2}{v} g_{H^4} &= - \frac{3g^2}{4} \frac{m_W^2}{v^2} = -3 \frac{m_H^2}{v^2} \end{align} \end{subequations} \end{dubious} *) let derived_parameters = [ Real E, Sqrt (Prod [Integer 4; Atom Pi; Atom Alpha_QED]); Real Sinthw, Sqrt (Atom Sin2thw); Real Costhw, Sqrt (Diff (Integer 1, Atom Sin2thw)); Real G_weak, Quot (Atom E, Atom Sinthw); Real (Mass (G Wp)), Prod [Atom Costhw; Atom (Mass (G Z))]; Real Vev, Quot (Prod [Integer 2; Atom (Mass (G Wp))], Atom G_weak); Real Q_lepton, Atom E; Real Q_up, Prod [Quot (Integer (-2), Integer 3); Atom E]; Real Q_down, Prod [Quot (Integer 1, Integer 3); Atom E]; Real G_CC, Neg (Quot (Atom G_weak, Prod [Integer 2; Sqrt (Integer 2)])); Complex I_Q_W, Prod [I; Atom E]; Complex I_G_weak, Prod [I; Atom G_weak]; Complex I_G_ZWW, Prod [I; Atom G_weak; Atom Costhw] ] (* \begin{equation} - \frac{g}{2\cos\theta_w} \end{equation} *) let g_over_2_costh = Quot (Neg (Atom G_weak), Prod [Integer 2; Atom Costhw]) (* \begin{subequations} \begin{align} - \frac{g}{2\cos\theta_w} g_V &= - \frac{g}{2\cos\theta_w} (T_3 - 2 q \sin^2\theta_w) \\ - \frac{g}{2\cos\theta_w} g_A &= - \frac{g}{2\cos\theta_w} T_3 \end{align} \end{subequations} *) let nc_coupling c t3 q = (Real_Array c, [Prod [g_over_2_costh; Diff (t3, Prod [Integer 2; q; Atom Sin2thw])]; Prod [g_over_2_costh; t3]]) let half = Quot (Integer 1, Integer 2) let derived_parameter_arrays = [ nc_coupling G_NC_neutrino half (Integer 0); nc_coupling G_NC_lepton (Neg half) (Integer (-1)); nc_coupling G_NC_up half (Quot (Integer 2, Integer 3)); nc_coupling G_NC_down (Neg half) (Quot (Integer (-1), Integer 3)) ] let parameters () = { input = input_parameters; derived = derived_parameters; derived_arrays = derived_parameter_arrays } module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) (* \begin{equation} \mathcal{L}_{\textrm{EM}} = - e \sum_i q_i \bar\psi_i\fmslash{A}\psi_i \end{equation} *) let mgm ((m1, g, m2), fbf, c) = ((M m1, G g, M m2), fbf, c) let mom ((m1, o, m2), fbf, c) = ((M m1, O o, M m2), fbf, c) let electromagnetic_currents n = List.map mgm [ ((L (-n), Ga, L n), FBF (1, Psibar, V, Psi), Q_lepton); ((U (-n), Ga, U n), FBF (1, Psibar, V, Psi), Q_up); ((D (-n), Ga, D n), FBF (1, Psibar, V, Psi), Q_down) ] let color_currents n = List.map mgm [ ((U (-n), Gl, U n), FBF ((-1), Psibar, V, Psi), Gs); ((D (-n), Gl, D n), FBF ((-1), Psibar, V, Psi), Gs) ] (* \begin{equation} \mathcal{L}_{\textrm{NC}} = - \frac{g}{2\cos\theta_W} \sum_i \bar\psi_i\fmslash{Z}(g_V^i-g_A^i\gamma_5)\psi_i \end{equation} *) let neutral_currents n = List.map mgm [ ((L (-n), Z, L n), FBF (1, Psibar, VA, Psi), G_NC_lepton); ((N (-n), Z, N n), FBF (1, Psibar, VA, Psi), G_NC_neutrino); ((U (-n), Z, U n), FBF (1, Psibar, VA, Psi), G_NC_up); ((D (-n), Z, D n), FBF (1, Psibar, VA, Psi), G_NC_down) ] (* \begin{equation} \mathcal{L}_{\textrm{CC}} = - \frac{g}{2\sqrt2} \sum_i \bar\psi_i (T^+\fmslash{W}^+ + T^-\fmslash{W}^-)(1-\gamma_5)\psi_i \end{equation} *) let charged_currents' n = List.map mgm [ ((L (-n), Wm, N n), FBF (1, Psibar, VL, Psi), G_CC); ((N (-n), Wp, L n), FBF (1, Psibar, VL, Psi), G_CC) ] let charged_currents'' n = List.map mgm [ ((D (-n), Wm, U n), FBF (1, Psibar, VL, Psi), G_CC); ((U (-n), Wp, D n), FBF (1, Psibar, VL, Psi), G_CC) ] let charged_currents_triv = ThoList.flatmap charged_currents' [1;2;3] @ ThoList.flatmap charged_currents'' [1;2;3] let charged_currents_ckm = let charged_currents_2 n1 n2 = List.map mgm [ ((D (-n1), Wm, U n2), FBF (1, Psibar, VL, Psi), G_CCQ (n2,n1)); ((U (-n1), Wp, D n2), FBF (1, Psibar, VL, Psi), G_CCQ (n1,n2)) ] in ThoList.flatmap charged_currents' [1;2;3] @ List.flatten (Product.list2 charged_currents_2 [1;2;3] [1;2;3]) let yukawa = [ ((M (U (-3)), O H, M (U 3)), FBF (1, Psibar, S, Psi), G_Htt); ((M (D (-3)), O H, M (D 3)), FBF (1, Psibar, S, Psi), G_Hbb); ((M (U (-2)), O H, M (U 2)), FBF (1, Psibar, S, Psi), G_Hcc); ((M (L (-3)), O H, M (L 3)), FBF (1, Psibar, S, Psi), G_Htautau) ] @ if Flags.higgs_hmm then [ ((M (L (-2)), O H, M (L 2)), FBF (1, Psibar, S, Psi), G_Hmm)] else [] (* \begin{equation} \mathcal{L}_{\textrm{TGC}} = - e \partial_\mu A_\nu W_+^\mu W_-^\nu + \ldots - e \cot\theta_w \partial_\mu Z_\nu W_+^\mu W_-^\nu + \ldots \end{equation} *) let tgc ((g1, g2, g3), t, c) = ((G g1, G g2, G g3), t, c) let standard_triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW); ((Gl, Gl, Gl), Gauge_Gauge_Gauge 1, I_Gs)] (* \begin{multline} \mathcal{L}_{\textrm{TGC}}(g_1,\kappa) = g_1 \mathcal{L}_T(V,W^+,W^-) \\ + \frac{\kappa+g_1}{2} \Bigl(\mathcal{L}_T(W^-,V,W^+) - \mathcal{L}_T(W^+,V,W^-)\Bigr)\\ + \frac{\kappa-g_1}{2} \Bigl(\mathcal{L}_L(W^-,V,W^+) - \mathcal{L}_T(W^+,V,W^-)\Bigr) \end{multline} *) (* \begin{dubious} The whole thing in the LEP2 workshop notation: \begin{multline} \ii\mathcal{L}_{\textrm{TGC},V} / g_{WWV} = \\ g_1^V V^\mu (W^-_{\mu\nu}W^{+,\nu}-W^+_{\mu\nu}W^{-,\nu}) + \kappa_V W^+_\mu W^-_\nu V^{\mu\nu} + \frac{\lambda_V}{m_W^2} V_{\mu\nu} W^-_{\rho\mu} W^{+,\hphantom{\nu}\rho}_{\hphantom{+,}\nu} \\ + \ii g_5^V \epsilon_{\mu\nu\rho\sigma} \left( (\partial^\rho W^{-,\mu}) W^{+,\nu} - W^{-,\mu}(\partial^\rho W^{+,\nu}) \right) V^\sigma \\ + \ii g_4^V W^-_\mu W^+_\nu (\partial^\mu V^\nu + \partial^\nu V^\mu) - \frac{\tilde\kappa_V}{2} W^-_\mu W^+_\nu \epsilon^{\mu\nu\rho\sigma} V_{\rho\sigma} - \frac{\tilde\lambda_V}{2m_W^2} W^-_{\rho\mu} W^{+,\mu}_{\hphantom{+,\mu}\nu} \epsilon^{\nu\rho\alpha\beta} V_{\alpha\beta} \end{multline} using the conventions of Itzykson and Zuber with $\epsilon^{0123} = +1$. \end{dubious} *) (* \begin{dubious} This is equivalent to the notation of Hagiwara et al.~\cite{HPZH87}, if we remember that they have opposite signs for~$g_{WWV}$: \begin{multline} \mathcal{L}_{WWV} / (-g_{WWV}) = \\ \ii g_1^V \left( W^\dagger_{\mu\nu} W^\mu - W^\dagger_\mu W^\mu_{\hphantom{\mu}\nu} \right) V^\nu + \ii \kappa_V W^\dagger_\mu W_\nu V^{\mu\nu} + \ii \frac{\lambda_V}{m_W^2} W^\dagger_{\lambda\mu} W^\mu_{\hphantom{\mu}\nu} V^{\nu\lambda} \\ - g_4^V W^\dagger_\mu W_\nu \left(\partial^\mu V^\nu + \partial^\nu V^\mu \right) + g_5^V \epsilon^{\mu\nu\lambda\sigma} \left( W^\dagger_\mu \stackrel{\leftrightarrow}{\partial_\lambda} W_\nu \right) V_\sigma\\ + \ii \tilde\kappa_V W^\dagger_\mu W_\nu \tilde{V}^{\mu\nu} + \ii\frac{\tilde\lambda_V}{m_W^2} W^\dagger_{\lambda\mu} W^\mu_{\hphantom{\mu}\nu} \tilde{V}^{\nu\lambda} \end{multline} Here $V^\mu$ stands for either the photon or the~$Z$ field, $W^\mu$ is the $W^-$ field, $W_{\mu\nu} = \partial_\mu W_\nu - \partial_\nu W_\mu$, $V_{\mu\nu} = \partial_\mu V_\nu - \partial_\nu V_\mu$, and $\tilde{V}_{\mu\nu} = \frac{1}{2} \epsilon_{\mu\nu\lambda\sigma} V^{\lambda\sigma}$. \end{dubious} *) let anomalous_triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Dim4_Vector_Vector_Vector_T (-1), I_G1_AWW); ((Z, Wm, Wp), Dim4_Vector_Vector_Vector_T (-1), I_G1_ZWW); ((Wm, Ga, Wp), Dim4_Vector_Vector_Vector_T 1, I_G1_plus_kappa_minus_G4_AWW); ((Wm, Z, Wp), Dim4_Vector_Vector_Vector_T 1, I_G1_plus_kappa_minus_G4_ZWW); ((Wp, Ga, Wm), Dim4_Vector_Vector_Vector_T (-1), I_G1_plus_kappa_plus_G4_AWW); ((Wp, Z, Wm), Dim4_Vector_Vector_Vector_T (-1), I_G1_plus_kappa_plus_G4_ZWW); ((Wm, Ga, Wp), Dim4_Vector_Vector_Vector_L (-1), I_G1_minus_kappa_plus_G4_AWW); ((Wm, Z, Wp), Dim4_Vector_Vector_Vector_L (-1), I_G1_minus_kappa_plus_G4_ZWW); ((Wp, Ga, Wm), Dim4_Vector_Vector_Vector_L 1, I_G1_minus_kappa_minus_G4_AWW); ((Wp, Z, Wm), Dim4_Vector_Vector_Vector_L 1, I_G1_minus_kappa_minus_G4_ZWW); ((Ga, Wm, Wp), Dim4_Vector_Vector_Vector_L5 (-1), I_kappa5_AWW); ((Z, Wm, Wp), Dim4_Vector_Vector_Vector_L5 (-1), I_kappa5_ZWW); ((Ga, Wm, Wp), Dim4_Vector_Vector_Vector_T5 (-1), G5_AWW); ((Z, Wm, Wp), Dim4_Vector_Vector_Vector_T5 (-1), G5_ZWW); ((Ga, Wp, Wm), Dim6_Gauge_Gauge_Gauge (-1), I_lambda_AWW); ((Z, Wp, Wm), Dim6_Gauge_Gauge_Gauge (-1), I_lambda_ZWW); ((Ga, Wp, Wm), Dim6_Gauge_Gauge_Gauge_5 (-1), I_lambda5_AWW); ((Z, Wp, Wm), Dim6_Gauge_Gauge_Gauge_5 (-1), I_lambda5_ZWW) ] let triple_gauge = if Flags.triple_anom then anomalous_triple_gauge else standard_triple_gauge (* \begin{equation} \mathcal{L}_{\textrm{QGC}} = - g^2 W_{+,\mu} W_{-,\nu} W_+^\mu W_-^\nu + \ldots \end{equation} *) (* Actually, quartic gauge couplings are a little bit more straightforward using auxiliary fields. Here we have to impose the antisymmetry manually: \begin{subequations} \begin{multline} (W^{+,\mu}_1 W^{-,\nu}_2 - W^{+,\nu}_1 W^{-,\mu}_2) (W^+_{3,\mu} W^-_{4,\nu} - W^+_{3,\nu} W^-_{4,\mu}) \\ = 2(W^+_1W^+_3)(W^-_2W^-_4) - 2(W^+_1W^-_4)(W^-_2W^+_3) \end{multline} also ($V$ can be $A$ or $Z$) \begin{multline} (W^{+,\mu}_1 V^\nu_2 - W^{+,\nu}_1 V^\mu_2) (W^-_{3,\mu} V_{4,\nu} - W^-_{3,\nu} V_{4,\mu}) \\ = 2(W^+_1W^-_3)(V_2V_4) - 2(W^+_1V_4)(V_2W^-_3) \end{multline} \end{subequations} *) (* \begin{subequations} \begin{multline} W^{+,\mu} W^{-,\nu} W^+_\mu W^-_\nu \end{multline} \end{subequations} *) let qgc ((g1, g2, g3, g4), t, c) = ((G g1, G g2, G g3, G g4), t, c) let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] let standard_quartic_gauge = List.map qgc [ (Wm, Wp, Wm, Wp), gauge4, G_WWWW; (Wm, Z, Wp, Z), minus_gauge4, G_ZZWW; (Wm, Z, Wp, Ga), minus_gauge4, G_AZWW; (Wm, Ga, Wp, Ga), minus_gauge4, G_AAWW; (Gl, Gl, Gl, Gl), gauge4, G2 ] (* \begin{subequations} \begin{align} \mathcal{L}_4 &= \alpha_4 \left( \frac{g^4}{2}\left( (W^+_\mu W^{-,\mu})^2 + W^+_\mu W^{+,\mu} W^-_\mu W^{-,\mu} \right)\right.\notag \\ &\qquad\qquad\qquad \left. + \frac{g^4}{\cos^2\theta_w} W^+_\mu Z^\mu W^-_\nu Z^\nu + \frac{g^4}{4\cos^4\theta_w} (Z_\mu Z^\mu)^2 \right) \\ \mathcal{L}_5 &= \alpha_5 \left( g^4 (W^+_\mu W^{-,\mu})^2 + \frac{g^4}{\cos^2\theta_w} W^+_\mu W^{-,\mu} Z_\nu Z^\nu + \frac{g^4}{4\cos^4\theta_w} (Z_\mu Z^\mu)^2 \right) \end{align} \end{subequations} or \begin{multline} \mathcal{L}_4 + \mathcal{L}_5 = (\alpha_4+2\alpha_5) g^4 \frac{1}{2} (W^+_\mu W^{-,\mu})^2 \\ + 2\alpha_4 g^4 \frac{1}{4} W^+_\mu W^{+,\mu} W^-_\mu W^{-,\mu} + \alpha_4 \frac{g^4}{\cos^2\theta_w} W^+_\mu Z^\mu W^-_\nu Z^\nu \\ + 2\alpha_5 \frac{g^4}{\cos^2\theta_w} \frac{1}{2} W^+_\mu W^{-,\mu} Z_\nu Z^\nu + (2\alpha_4 + 2\alpha_5) \frac{g^4}{\cos^4\theta_w} \frac{1}{8} (Z_\mu Z^\mu)^2 \end{multline} and therefore \begin{subequations} \begin{align} \alpha_{(WW)_0} &= (\alpha_4+2\alpha_5) g^4 \\ \alpha_{(WW)_2} &= 2\alpha_4 g^4 \\ \alpha_{(WZ)_0} &= 2\alpha_5 \frac{g^4}{\cos^2\theta_w} \\ \alpha_{(WZ)_1} &= \alpha_4 \frac{g^4}{\cos^2\theta_w} \\ \alpha_{ZZ} &= (2\alpha_4 + 2\alpha_5) \frac{g^4}{\cos^4\theta_w} \end{align} \end{subequations} *) let anomalous_quartic_gauge = if Flags.quartic_anom then List.map qgc [ ((Wm, Wm, Wp, Wp), Vector4 [(1, C_13_42); (1, C_14_23)], Alpha_WWWW0); ((Wm, Wm, Wp, Wp), Vector4 [1, C_12_34], Alpha_WWWW2); ((Z, Z, Z, Z), Vector4 [(1, C_12_34); (1, C_13_42); (1, C_14_23)], Alpha_ZZZZ); ((Wm, Wp, Z, Z), Vector4 [1, C_12_34], Alpha_ZZWW0); ((Wm, Wp, Z, Z), Vector4 [(1, C_13_42); (1, C_14_23)], Alpha_ZZWW1)] @ (if Flags.k_matrix_tm then List.map qgc [((Wm, Wm, Wp, Wp), Dim8_Vector4_t_0 [1, C_13_42], FT0_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_t_0 [1, C_14_23], FT0_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_t_0 [1, C_12_34], FT0_WWWW2); ((Wm, Wm, Wp, Wp), Dim8_Vector4_t_1 [1, C_13_42], FT1_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_t_1 [1, C_14_23], FT1_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_t_1 [1, C_12_34], FT1_WWWW2); ((Wm, Wm, Wp, Wp), Dim8_Vector4_t_2 [1, C_13_42], FT2_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_t_2 [1, C_14_23], FT2_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_t_2 [1, C_12_34], FT2_WWWW2); ((Wm, Wm, Wp, Wp), Dim8_Vector4_m_0 [1, C_13_42], FM0_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_m_0 [1, C_14_23], FM0_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_m_0 [1, C_12_34], FM0_WWWW2); ((Wm, Wm, Wp, Wp), Dim8_Vector4_m_1 [1, C_13_42], FM1_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_m_1 [1, C_14_23], FM1_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_m_1 [1, C_12_34], FM1_WWWW2); ((Wm, Wm, Wp, Wp), Dim8_Vector4_m_7 [1, C_13_42], FM7_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_m_7 [1, C_14_23], FM7_WWWW0); ((Wm, Wm, Wp, Wp), Dim8_Vector4_m_7 [1, C_12_34], FM7_WWWW2); ((Wm, Wp, Z, Z), Dim8_Vector4_t_0 [1, C_12_34], FT0_ZZWW0); ((Wm, Wp, Z, Z), Dim8_Vector4_t_0 [1, C_13_42], FT0_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_t_0 [1, C_14_23], FT0_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_t_1 [1, C_12_34], FT1_ZZWW0); ((Wm, Wp, Z, Z), Dim8_Vector4_t_1 [1, C_13_42], FT1_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_t_1 [1, C_14_23], FT1_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_t_2 [1, C_12_34], FT2_ZZWW0); ((Wm, Wp, Z, Z), Dim8_Vector4_t_2 [1, C_13_42], FT2_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_t_2 [1, C_14_23], FT2_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_m_0 [1, C_12_34], FM0_ZZWW0); ((Wm, Wp, Z, Z), Dim8_Vector4_m_0 [1, C_13_42], FM0_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_m_0 [1, C_14_23], FM0_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_m_1 [1, C_12_34], FM1_ZZWW0); ((Wm, Wp, Z, Z), Dim8_Vector4_m_1 [1, C_13_42], FM1_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_m_1 [1, C_14_23], FM1_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_m_7 [1, C_12_34], FM7_ZZWW0); ((Wm, Wp, Z, Z), Dim8_Vector4_m_7 [1, C_13_42], FM7_ZZWW1); ((Wm, Wp, Z, Z), Dim8_Vector4_m_7 [1, C_14_23], FM7_ZZWW1); ((Z, Z, Z, Z), Dim8_Vector4_t_0 [1, C_12_34], FT0_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_t_0 [1, C_13_42], FT0_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_t_0 [1, C_14_23], FT0_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_t_1 [1, C_12_34], FT1_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_t_1 [1, C_13_42], FT1_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_t_1 [1, C_14_23], FT1_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_t_2 [1, C_12_34], FT2_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_t_2 [1, C_13_42], FT2_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_t_2 [1, C_14_23], FT2_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_m_0 [1, C_12_34], FM0_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_m_0 [1, C_13_42], FM0_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_m_0 [1, C_14_23], FM0_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_m_1 [1, C_12_34], FM1_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_m_1 [1, C_13_42], FM1_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_m_1 [1, C_14_23], FM1_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_m_7 [1, C_12_34], FM7_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_m_7 [1, C_13_42], FM7_ZZZZ); ((Z, Z, Z, Z), Dim8_Vector4_m_7 [1, C_14_23], FM7_ZZZZ); ((Ga, Ga, Ga, Ga), Dim8_Vector4_t_0 [1, C_12_34], FT0_AAAA); ((Ga, Ga, Ga, Ga), Dim8_Vector4_t_0 [1, C_13_42], FT0_AAAA); ((Ga, Ga, Ga, Ga), Dim8_Vector4_t_0 [1, C_14_23], FT0_AAAA); ((Ga, Ga, Ga, Ga), Dim8_Vector4_t_1 [1, C_12_34], FT1_AAAA); ((Ga, Ga, Ga, Ga), Dim8_Vector4_t_1 [1, C_13_42], FT1_AAAA); ((Ga, Ga, Ga, Ga), Dim8_Vector4_t_1 [1, C_14_23], FT1_AAAA); ((Ga, Ga, Ga, Ga), Dim8_Vector4_t_2 [1, C_12_34], FT2_AAAA); ((Ga, Ga, Ga, Ga), Dim8_Vector4_t_2 [1, C_13_42], FT2_AAAA); ((Ga, Ga, Ga, Ga), Dim8_Vector4_t_2 [1, C_14_23], FT2_AAAA); ((Wm, Wp, Ga, Ga), Dim8_Vector4_t_0 [1, C_12_34], FT0_AAWW0); ((Wm, Wp, Ga, Ga), Dim8_Vector4_t_0 [1, C_13_42], FT0_AAWW1); ((Wm, Wp, Ga, Ga), Dim8_Vector4_t_0 [1, C_14_23], FT0_AAWW1); ((Wm, Wp, Ga, Ga), Dim8_Vector4_t_1 [1, C_12_34], FT1_AAWW0); ((Wm, Wp, Ga, Ga), Dim8_Vector4_t_1 [1, C_13_42], FT1_AAWW1); ((Wm, Wp, Ga, Ga), Dim8_Vector4_t_1 [1, C_14_23], FT1_AAWW1); ((Wm, Wp, Ga, Ga), Dim8_Vector4_t_2 [1, C_12_34], FT2_AAWW0); ((Wm, Wp, Ga, Ga), Dim8_Vector4_t_2 [1, C_13_42], FT2_AAWW1); ((Wm, Wp, Ga, Ga), Dim8_Vector4_t_2 [1, C_14_23], FT2_AAWW1); ((Z, Z, Ga, Ga), Dim8_Vector4_t_0 [1, C_12_34], FT0_AAZZ); ((Z, Z, Ga, Ga), Dim8_Vector4_t_0 [1, C_13_42], FT0_AAZZ); ((Z, Z, Ga, Ga), Dim8_Vector4_t_0 [1, C_14_23], FT0_AAZZ); ((Z, Z, Ga, Ga), Dim8_Vector4_t_1 [1, C_12_34], FT1_AAZZ); ((Z, Z, Ga, Ga), Dim8_Vector4_t_1 [1, C_13_42], FT1_AAZZ); ((Z, Z, Ga, Ga), Dim8_Vector4_t_1 [1, C_14_23], FT1_AAZZ); ((Z, Z, Ga, Ga), Dim8_Vector4_t_2 [1, C_12_34], FT2_AAZZ); ((Z, Z, Ga, Ga), Dim8_Vector4_t_2 [1, C_13_42], FT2_AAZZ); ((Z, Z, Ga, Ga), Dim8_Vector4_t_2 [1, C_14_23], FT2_AAZZ); ((Ga, Z, Wp, Wm), Dim8_Vector4_t_0 [1, C_12_34], FT0_AZWW0); ((Ga, Z, Wp, Wm), Dim8_Vector4_t_0 [1, C_13_42], FT0_AZWW1); ((Ga, Z, Wp, Wm), Dim8_Vector4_t_0 [1, C_14_23], FT0_AZWW1); ((Ga, Z, Wp, Wm), Dim8_Vector4_t_1 [1, C_12_34], FT1_AZWW0); ((Ga, Z, Wp, Wm), Dim8_Vector4_t_1 [1, C_13_42], FT1_AZWW1); ((Ga, Z, Wp, Wm), Dim8_Vector4_t_1 [1, C_14_23], FT1_AZWW1); ((Ga, Z, Wp, Wm), Dim8_Vector4_t_2 [1, C_12_34], FT2_AZWW0); ((Ga, Z, Wp, Wm), Dim8_Vector4_t_2 [1, C_13_42], FT2_AZWW1); ((Ga, Z, Wp, Wm), Dim8_Vector4_t_2 [1, C_14_23], FT2_AZWW1); ((Ga, Ga, Ga, Z), Dim8_Vector4_t_0 [1, C_12_34], FT0_AAAZ); ((Ga, Ga, Ga, Z), Dim8_Vector4_t_0 [1, C_13_42], FT0_AAAZ); ((Ga, Ga, Ga, Z), Dim8_Vector4_t_0 [1, C_14_23], FT0_AAAZ); ((Ga, Ga, Ga, Z), Dim8_Vector4_t_1 [1, C_12_34], FT1_AAAZ); ((Ga, Ga, Ga, Z), Dim8_Vector4_t_1 [1, C_13_42], FT1_AAAZ); ((Ga, Ga, Ga, Z), Dim8_Vector4_t_1 [1, C_14_23], FT1_AAAZ); ((Ga, Ga, Ga, Z), Dim8_Vector4_t_2 [1, C_12_34], FT2_AAAZ); ((Ga, Ga, Ga, Z), Dim8_Vector4_t_2 [1, C_13_42], FT2_AAAZ); ((Ga, Ga, Ga, Z), Dim8_Vector4_t_2 [1, C_14_23], FT2_AAAZ); ((Ga, Z, Z, Z), Dim8_Vector4_t_0 [1, C_12_34], FT0_AZZZ); ((Ga, Z, Z, Z), Dim8_Vector4_t_0 [1, C_13_42], FT0_AZZZ); ((Ga, Z, Z, Z), Dim8_Vector4_t_0 [1, C_14_23], FT0_AZZZ); ((Ga, Z, Z, Z), Dim8_Vector4_t_1 [1, C_12_34], FT1_AZZZ); ((Ga, Z, Z, Z), Dim8_Vector4_t_1 [1, C_13_42], FT1_AZZZ); ((Ga, Z, Z, Z), Dim8_Vector4_t_1 [1, C_14_23], FT1_AZZZ); ((Ga, Z, Z, Z), Dim8_Vector4_t_2 [1, C_12_34], FT2_AZZZ); ((Ga, Z, Z, Z), Dim8_Vector4_t_2 [1, C_13_42], FT2_AZZZ); ((Ga, Z, Z, Z), Dim8_Vector4_t_2 [1, C_14_23], FT2_AZZZ)] else [] ) else [] (* In any diagonal channel~$\chi$, the scattering amplitude~$a_\chi(s)$ is unitary iff\footnote{% Trivial proof: \begin{equation} -1 = \textrm{Im}\left(\frac{1}{a_\chi(s)}\right) = \frac{\textrm{Im}(a_\chi^*(s))}{ |a_\chi(s)|^2 } = - \frac{\textrm{Im}(a_\chi(s))}{ |a_\chi(s)|^2 } \end{equation} i.\,e.~$\textrm{Im}(a_\chi(s)) = |a_\chi(s)|^2$.} \begin{equation} \textrm{Im}\left(\frac{1}{a_\chi(s)}\right) = -1 \end{equation} For a real perturbative scattering amplitude~$r_\chi(s)$ this can be enforced easily--and arbitrarily--by \begin{equation} \frac{1}{a_\chi(s)} = \frac{1}{r_\chi(s)} - \mathrm{i} \end{equation} *) let k_matrix_quartic_gauge = if Flags.k_matrix then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_WWWW0_S); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_jr (0, [(1, C_14_23)]), D_Alpha_WWWW0_T); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_jr (0, [(1, C_13_42)]), D_Alpha_WWWW0_U); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_WWWW0_S); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_jr (0, [(1, C_14_23)]), D_Alpha_WWWW0_T); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_jr (0, [(1, C_13_42)]), D_Alpha_WWWW0_U); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_WWWW2_S); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_jr (0, [(1, C_13_42); (1, C_14_23)]), D_Alpha_WWWW2_T); ((Wm, Wp, Z, Z), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_ZZWW0_S); ((Wm, Wp, Z, Z), Vector4_K_Matrix_jr (0, [(1, C_13_42); (1, C_14_23)]), D_Alpha_ZZWW0_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_ZZWW1_S); ((Wm, Z, Wp, Z), Vector4_K_Matrix_jr (0, [(1, C_13_42)]), D_Alpha_ZZWW1_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_jr (0, [(1, C_14_23)]), D_Alpha_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_jr (1, [(1, C_12_34)]), D_Alpha_ZZWW1_S); ((Wp, Z, Z, Wm), Vector4_K_Matrix_jr (1, [(1, C_13_42)]), D_Alpha_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_jr (1, [(1, C_14_23)]), D_Alpha_ZZWW1_T); ((Z, Wp, Wm, Z), Vector4_K_Matrix_jr (2, [(1, C_12_34)]), D_Alpha_ZZWW1_S); ((Z, Wp, Wm, Z), Vector4_K_Matrix_jr (2, [(1, C_13_42)]), D_Alpha_ZZWW1_U); ((Z, Wp, Wm, Z), Vector4_K_Matrix_jr (2, [(1, C_14_23)]), D_Alpha_ZZWW1_T); ((Z, Z, Z, Z), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_jr (0, [(1, C_13_42); (1, C_14_23)]), D_Alpha_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_jr (3, [(1, C_14_23)]), D_Alpha_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_jr (3, [(1, C_13_42); (1, C_12_34)]), D_Alpha_ZZZZ_T)] else [] let k_matrix_quartic_gauge_t_0 = if Flags.k_matrix_tm then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_WWWW0_S); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_WWWW0_T); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_WWWW0_U); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_WWWW0_S); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_WWWW0_T); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_WWWW0_U); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_WWWW2_S); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_WWWW2_T); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_WWWW2_U); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_ZZWW0_S); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_ZZWW0_T); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_ZZWW0_U); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_ZZWW1_S); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_ZZWW1_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t0 (1, [(1, C_12_34)]), D_FT0_ZZWW1_S); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t0 (1, [(1, C_13_42)]), D_FT0_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t0 (1, [(1, C_14_23)]), D_FT0_ZZWW1_T); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t0 (2, [(1, C_12_34)]), D_FT0_ZZWW1_S); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t0 (2, [(1, C_13_42)]), D_FT0_ZZWW1_U); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t0 (2, [(1, C_14_23)]), D_FT0_ZZWW1_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_ZZZZ_U); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_14_23)]), D_FT0_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_13_42)]), D_FT0_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_12_34)]), D_FT0_ZZZZ_U); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_AAAA_S); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_AAAA_T); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_AAAA_U); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_14_23)]), D_FT0_AAAA_S); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_13_42)]), D_FT0_AAAA_T); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_12_34)]), D_FT0_AAAA_U); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_AAWW0_S); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_AAWW0_T); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_AAWW0_U); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_AAWW1_S); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_AAWW1_T); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_AAWW1_U); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t0 (1, [(1, C_12_34)]), D_FT0_AAWW1_S); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t0 (1, [(1, C_13_42)]), D_FT0_AAWW1_U); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t0 (1, [(1, C_14_23)]), D_FT0_AAWW1_T); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t0 (2, [(1, C_12_34)]), D_FT0_AAWW1_S); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t0 (2, [(1, C_13_42)]), D_FT0_AAWW1_U); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t0 (2, [(1, C_14_23)]), D_FT0_AAWW1_T); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_AAZZ_S); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_AAZZ_T); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_AAZZ_U); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_14_23)]), D_FT0_AAZZ_S); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_13_42)]), D_FT0_AAZZ_T); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_12_34)]), D_FT0_AAZZ_U); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t0 (0, [(1, C_12_34)]), D_FT0_AZWW0_S); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t0 (0, [(1, C_13_42)]), D_FT0_AZWW0_T); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t0 (0, [(1, C_14_23)]), D_FT0_AZWW0_U); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t0 (1, [(1, C_12_34)]), D_FT0_AZWW1_S); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t0 (1, [(1, C_13_42)]), D_FT0_AZWW1_T); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t0 (1, [(1, C_14_23)]), D_FT0_AZWW1_U); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t0 (1, [(1, C_12_34)]), D_FT0_AZWW1_S); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t0 (1, [(1, C_13_42)]), D_FT0_AZWW1_T); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t0 (1, [(1, C_14_23)]), D_FT0_AZWW1_U); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t0 (1, [(1, C_12_34)]), D_FT0_AZWW1_S); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t0 (1, [(1, C_13_42)]), D_FT0_AZWW1_T); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t0 (1, [(1, C_14_23)]), D_FT0_AZWW1_U); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t0 (1, [(1, C_12_34)]), D_FT0_AZWW1_S); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t0 (1, [(1, C_13_42)]), D_FT0_AZWW1_T); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t0 (1, [(1, C_14_23)]), D_FT0_AZWW1_U); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_12_34)]), D_FT0_AAAZ_S); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_13_42)]), D_FT0_AAAZ_T); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_14_23)]), D_FT0_AAAZ_U); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_12_34)]), D_FT0_AAAZ_S); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_13_42)]), D_FT0_AAAZ_T); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_14_23)]), D_FT0_AAAZ_U); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_12_34)]), D_FT0_AAAZ_S); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_13_42)]), D_FT0_AAAZ_T); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_14_23)]), D_FT0_AAAZ_U); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_12_34)]), D_FT0_AZZZ_S); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_13_42)]), D_FT0_AZZZ_T); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t0 (3, [(1, C_14_23)]), D_FT0_AZZZ_U); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_12_34)]), D_FT0_AZZZ_S); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_13_42)]), D_FT0_AZZZ_T); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_14_23)]), D_FT0_AZZZ_U); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_12_34)]), D_FT0_AZZZ_S); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_13_42)]), D_FT0_AZZZ_T); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t0 (3, [(1, C_14_23)]), D_FT0_AZZZ_U)] else [] let k_matrix_quartic_gauge_t_1 = if Flags.k_matrix_tm then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t1 (0, [(1, C_12_34)]), D_FT1_WWWW0_S); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_WWWW0_T); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_WWWW0_U); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t1 (0, [(1, C_12_34)]), D_FT1_WWWW0_S); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_WWWW0_T); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_WWWW0_U); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t1 (0, [(1, C_12_34)]), D_FT1_WWWW2_S); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_WWWW2_T); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_WWWW2_U); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_12_34)]), D_FT1_ZZWW0_S); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_ZZWW0_T); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_ZZWW0_U); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_12_34)]), D_FT1_ZZWW1_S); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_ZZWW1_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t1 (1, [(1, C_12_34)]), D_FT1_ZZWW1_S); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t1 (1, [(1, C_13_42)]), D_FT1_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t1 (1, [(1, C_14_23)]), D_FT1_ZZWW1_T); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t1 (2, [(1, C_12_34)]), D_FT1_ZZWW1_S); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t1 (2, [(1, C_13_42)]), D_FT1_ZZWW1_U); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t1 (2, [(1, C_14_23)]), D_FT1_ZZWW1_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_12_34)]), D_FT1_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_ZZZZ_U); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_14_23)]), D_FT1_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_13_42)]), D_FT1_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_12_34)]), D_FT1_ZZZZ_U); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t1(0, [(1, C_12_34)]), D_FT1_AAAA_S); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_AAAA_T); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_AAAA_U); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_14_23)]), D_FT1_AAAA_S); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_13_42)]), D_FT1_AAAA_T); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_12_34)]), D_FT1_AAAA_U); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t1 (0, [(1, C_12_34)]), D_FT1_AAWW0_S); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_AAWW0_T); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_AAWW0_U); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t1 (0, [(1, C_12_34)]), D_FT1_AAWW1_S); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_AAWW1_T); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_AAWW1_U); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t1 (1, [(1, C_12_34)]), D_FT1_AAWW1_S); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t1 (1, [(1, C_13_42)]), D_FT1_AAWW1_U); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t1 (1, [(1, C_14_23)]), D_FT1_AAWW1_T); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t1 (2, [(1, C_12_34)]), D_FT1_AAWW1_S); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t1 (2, [(1, C_13_42)]), D_FT1_AAWW1_U); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t1 (2, [(1, C_14_23)]), D_FT1_AAWW1_T); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_12_34)]), D_FT1_AAZZ_S); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_AAZZ_T); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_AAZZ_U); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_14_23)]), D_FT1_AAZZ_S); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_13_42)]), D_FT1_AAZZ_T); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_12_34)]), D_FT1_AAZZ_U); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t1 (0, [(1, C_12_34)]), D_FT1_AZWW0_S); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t1 (0, [(1, C_13_42)]), D_FT1_AZWW0_T); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t1 (0, [(1, C_14_23)]), D_FT1_AZWW0_U); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t1 (1, [(1, C_12_34)]), D_FT1_AZWW1_S); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t1 (1, [(1, C_13_42)]), D_FT1_AZWW1_T); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t1 (1, [(1, C_14_23)]), D_FT1_AZWW1_U); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t1 (1, [(1, C_12_34)]), D_FT1_AZWW1_S); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t1 (1, [(1, C_13_42)]), D_FT1_AZWW1_T); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t1 (1, [(1, C_14_23)]), D_FT1_AZWW1_U); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t1 (1, [(1, C_12_34)]), D_FT1_AZWW1_S); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t1 (1, [(1, C_13_42)]), D_FT1_AZWW1_T); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t1 (1, [(1, C_14_23)]), D_FT1_AZWW1_U); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t1 (1, [(1, C_12_34)]), D_FT1_AZWW1_S); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t1 (1, [(1, C_13_42)]), D_FT1_AZWW1_T); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t1 (1, [(1, C_14_23)]), D_FT1_AZWW1_U); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_12_34)]), D_FT1_AAAZ_S); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_13_42)]), D_FT1_AAAZ_T); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_14_23)]), D_FT1_AAAZ_U); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_12_34)]), D_FT1_AAAZ_S); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_13_42)]), D_FT1_AAAZ_T); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_14_23)]), D_FT1_AAAZ_U); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_12_34)]), D_FT1_AAAZ_S); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_13_42)]), D_FT1_AAAZ_T); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_14_23)]), D_FT1_AAAZ_U); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_12_34)]), D_FT1_AZZZ_S); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_13_42)]), D_FT1_AZZZ_T); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t1 (3, [(1, C_14_23)]), D_FT1_AZZZ_U); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_12_34)]), D_FT1_AZZZ_S); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_13_42)]), D_FT1_AZZZ_T); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_14_23)]), D_FT1_AZZZ_U); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_12_34)]), D_FT1_AZZZ_S); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_13_42)]), D_FT1_AZZZ_T); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t1 (3, [(1, C_14_23)]), D_FT1_AZZZ_U)] else [] let k_matrix_quartic_gauge_t_2 = if Flags.k_matrix_tm then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_WWWW0_S); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_WWWW0_T); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_WWWW0_U); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_WWWW0_S); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_WWWW0_T); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_WWWW0_U); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_WWWW2_S); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_WWWW2_T); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_WWWW2_U); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_ZZWW0_S); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_ZZWW0_T); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_ZZWW0_U); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_ZZWW1_S); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_ZZWW1_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t2 (1, [(1, C_12_34)]), D_FT2_ZZWW1_S); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t2 (1, [(1, C_13_42)]), D_FT2_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t2 (1, [(1, C_14_23)]), D_FT2_ZZWW1_T); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t2 (2, [(1, C_12_34)]), D_FT2_ZZWW1_S); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t2 (2, [(1, C_13_42)]), D_FT2_ZZWW1_U); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t2 (2, [(1, C_14_23)]), D_FT2_ZZWW1_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_ZZZZ_U); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_14_23)]), D_FT2_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_13_42)]), D_FT2_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_12_34)]), D_FT2_ZZZZ_U); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_AAAA_S); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_AAAA_T); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_AAAA_U); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_14_23)]), D_FT2_AAAA_S); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_13_42)]), D_FT2_AAAA_T); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_12_34)]), D_FT2_AAAA_U); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_AAWW0_S); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_AAWW0_T); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_AAWW0_U); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_AAWW1_S); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_AAWW1_T); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_AAWW1_U); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t2 (1, [(1, C_12_34)]), D_FT2_AAWW1_S); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t2 (1, [(1, C_13_42)]), D_FT2_AAWW1_U); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t2 (1, [(1, C_14_23)]), D_FT2_AAWW1_T); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t2 (2, [(1, C_12_34)]), D_FT2_AAWW1_S); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t2 (2, [(1, C_13_42)]), D_FT2_AAWW1_U); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t2 (2, [(1, C_14_23)]), D_FT2_AAWW1_T); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_AAZZ_S); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_AAZZ_T); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_AAZZ_U); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_14_23)]), D_FT2_AAZZ_S); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_13_42)]), D_FT2_AAZZ_T); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_12_34)]), D_FT2_AAZZ_U); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t2 (0, [(1, C_12_34)]), D_FT2_AZWW0_S); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t2 (0, [(1, C_13_42)]), D_FT2_AZWW0_T); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t2 (0, [(1, C_14_23)]), D_FT2_AZWW0_U); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t2 (1, [(1, C_12_34)]), D_FT2_AZWW1_S); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t2 (1, [(1, C_13_42)]), D_FT2_AZWW1_T); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t2 (1, [(1, C_14_23)]), D_FT2_AZWW1_U); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t2 (1, [(1, C_12_34)]), D_FT2_AZWW1_S); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t2 (1, [(1, C_13_42)]), D_FT2_AZWW1_T); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t2 (1, [(1, C_14_23)]), D_FT2_AZWW1_U); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t2 (1, [(1, C_12_34)]), D_FT2_AZWW1_S); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t2 (1, [(1, C_13_42)]), D_FT2_AZWW1_T); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t2 (1, [(1, C_14_23)]), D_FT2_AZWW1_U); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t2 (1, [(1, C_12_34)]), D_FT2_AZWW1_S); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t2 (1, [(1, C_13_42)]), D_FT2_AZWW1_T); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t2 (1, [(1, C_14_23)]), D_FT2_AZWW1_U); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_12_34)]), D_FT2_AAAZ_S); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_13_42)]), D_FT2_AAAZ_T); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_14_23)]), D_FT2_AAAZ_U); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_12_34)]), D_FT2_AAAZ_S); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_13_42)]), D_FT2_AAAZ_T); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_14_23)]), D_FT2_AAAZ_U); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_12_34)]), D_FT2_AAAZ_S); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_13_42)]), D_FT2_AAAZ_T); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_14_23)]), D_FT2_AAAZ_U); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_12_34)]), D_FT2_AZZZ_S); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_13_42)]), D_FT2_AZZZ_T); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t2 (3, [(1, C_14_23)]), D_FT2_AZZZ_U); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_12_34)]), D_FT2_AZZZ_S); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_13_42)]), D_FT2_AZZZ_T); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_14_23)]), D_FT2_AZZZ_U); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_12_34)]), D_FT2_AZZZ_S); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_13_42)]), D_FT2_AZZZ_T); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t2 (3, [(1, C_14_23)]), D_FT2_AZZZ_U)] else [] let k_matrix_quartic_gauge_t_rsi = if Flags.k_matrix_tm then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_WWWW0_S); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_WWWW0_T); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_WWWW0_U); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_WWWW0_S); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_WWWW0_T); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_WWWW0_U); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_WWWW2_S); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_WWWW2_T); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_WWWW2_U); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_ZZWW0_S); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_ZZWW0_T); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_ZZWW0_U); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_ZZWW1_S); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_ZZWW1_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_12_34)]), D_FTrsi_ZZWW1_S); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_13_42)]), D_FTrsi_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_14_23)]), D_FTrsi_ZZWW1_T); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t_rsi (2, [(1, C_12_34)]), D_FTrsi_ZZWW1_S); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t_rsi (2, [(1, C_13_42)]), D_FTrsi_ZZWW1_U); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_t_rsi (2, [(1, C_14_23)]), D_FTrsi_ZZWW1_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_ZZZZ_U); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_14_23)]), D_FTrsi_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_13_42)]), D_FTrsi_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_12_34)]), D_FTrsi_ZZZZ_U); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_AAAA_S); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_AAAA_T); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_AAAA_U); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_14_23)]), D_FTrsi_AAAA_S); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_13_42)]), D_FTrsi_AAAA_T); ((Ga, Ga, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_12_34)]), D_FTrsi_AAAA_U); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_AAWW0_S); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_AAWW0_T); ((Wm, Wp, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_AAWW0_U); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_AAWW1_S); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_AAWW1_T); ((Wm, Ga, Wp, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_AAWW1_U); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_12_34)]), D_FTrsi_AAWW1_S); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_13_42)]), D_FTrsi_AAWW1_U); ((Wp, Ga, Ga, Wm), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_14_23)]), D_FTrsi_AAWW1_T); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t_rsi (2, [(1, C_12_34)]), D_FTrsi_AAWW1_S); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t_rsi (2, [(1, C_13_42)]), D_FTrsi_AAWW1_U); ((Ga, Wp, Wm, Ga), Vector4_K_Matrix_cf_t_rsi (2, [(1, C_14_23)]), D_FTrsi_AAWW1_T); ((Ga, Z, Ga, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_AAZZ_S); ((Ga, Z, Ga, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_AAZZ_T); ((Ga, Z, Ga, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_AAZZ_U); ((Z, Ga, Z, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_AAZZ_S); ((Z, Ga, Z, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_AAZZ_T); ((Z, Ga, Z, Ga), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_AAZZ_U); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_AAZZ_S); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_AAZZ_T); ((Ga, Ga, Z, Z), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_AAZZ_U); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_12_34)]), D_FTrsi_AZWW0_S); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_13_42)]), D_FTrsi_AZWW0_T); ((Ga, Z, Wp, Wm), Vector4_K_Matrix_cf_t_rsi (0, [(1, C_14_23)]), D_FTrsi_AZWW0_U); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_12_34)]), D_FTrsi_AZWW1_S); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_13_42)]), D_FTrsi_AZWW1_T); ((Wp, Ga, Wm, Z), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_14_23)]), D_FTrsi_AZWW1_U); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_12_34)]), D_FTrsi_AZWW1_S); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_13_42)]), D_FTrsi_AZWW1_T); ((Wm, Ga, Wp, Z), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_14_23)]), D_FTrsi_AZWW1_U); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_12_34)]), D_FTrsi_AZWW1_S); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_13_42)]), D_FTrsi_AZWW1_T); ((Z, Wm, Ga, Wp), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_14_23)]), D_FTrsi_AZWW1_U); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_12_34)]), D_FTrsi_AZWW1_S); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_13_42)]), D_FTrsi_AZWW1_T); ((Wp, Z, Wm, Ga), Vector4_K_Matrix_cf_t_rsi (1, [(1, C_14_23)]), D_FTrsi_AZWW1_U); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_12_34)]), D_FTrsi_AAAZ_S); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_13_42)]), D_FTrsi_AAAZ_T); ((Ga, Ga, Ga, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_14_23)]), D_FTrsi_AAAZ_U); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_12_34)]), D_FTrsi_AAAZ_S); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_13_42)]), D_FTrsi_AAAZ_T); ((Z, Ga, Ga, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_14_23)]), D_FTrsi_AAAZ_U); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_12_34)]), D_FTrsi_AAAZ_S); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_13_42)]), D_FTrsi_AAAZ_T); ((Ga, Ga, Z, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_14_23)]), D_FTrsi_AAAZ_U); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_12_34)]), D_FTrsi_AZZZ_S); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_13_42)]), D_FTrsi_AZZZ_T); ((Z, Z, Z, Ga), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_14_23)]), D_FTrsi_AZZZ_U); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_12_34)]), D_FTrsi_AZZZ_S); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_13_42)]), D_FTrsi_AZZZ_T); ((Ga, Z, Z, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_14_23)]), D_FTrsi_AZZZ_U); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_12_34)]), D_FTrsi_AZZZ_S); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_13_42)]), D_FTrsi_AZZZ_T); ((Z, Z, Ga, Z), Vector4_K_Matrix_cf_t_rsi (3, [(1, C_14_23)]), D_FTrsi_AZZZ_U)] else [] let k_matrix_quartic_gauge_m_0 = if Flags.k_matrix_tm then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_m0 (0, [(1, C_12_34)]), D_FM0_WWWW0_S); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_m0 (0, [(1, C_14_23)]), D_FM0_WWWW0_T); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_m0 (0, [(1, C_13_42)]), D_FM0_WWWW0_U); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_m0 (0, [(1, C_12_34)]), D_FM0_WWWW0_S); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_m0 (0, [(1, C_14_23)]), D_FM0_WWWW0_T); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_m0 (0, [(1, C_13_42)]), D_FM0_WWWW0_U); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_m0 (0, [(1, C_12_34)]), D_FM0_WWWW2_S); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_m0 (0, [(1, C_13_42)]), D_FM0_WWWW2_T); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_m0 (0, [(1, C_14_23)]), D_FM0_WWWW2_U); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_m0 (0, [(1, C_12_34)]), D_FM0_ZZWW0_S); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_m0 (0, [(1, C_13_42)]), D_FM0_ZZWW0_T); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_m0 (0, [(1, C_14_23)]), D_FM0_ZZWW0_U); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_m0 (0, [(1, C_12_34)]), D_FM0_ZZWW1_S); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_m0 (0, [(1, C_13_42)]), D_FM0_ZZWW1_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_m0 (0, [(1, C_14_23)]), D_FM0_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_m0 (1, [(1, C_12_34)]), D_FM0_ZZWW1_S); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_m0 (1, [(1, C_13_42)]), D_FM0_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_m0 (1, [(1, C_14_23)]), D_FM0_ZZWW1_T); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_m0 (2, [(1, C_12_34)]), D_FM0_ZZWW1_S); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_m0 (2, [(1, C_13_42)]), D_FM0_ZZWW1_U); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_m0 (2, [(1, C_14_23)]), D_FM0_ZZWW1_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m0 (0, [(1, C_12_34)]), D_FM0_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m0 (0, [(1, C_13_42)]), D_FM0_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m0 (0, [(1, C_14_23)]), D_FM0_ZZZZ_U); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m0 (3, [(1, C_14_23)]), D_FM0_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m0 (3, [(1, C_13_42)]), D_FM0_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m0 (3, [(1, C_12_34)]), D_FM0_ZZZZ_U)] else [] let k_matrix_quartic_gauge_m_1 = if Flags.k_matrix_tm then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_m1 (0, [(1, C_12_34)]), D_FM1_WWWW0_S); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_m1 (0, [(1, C_14_23)]), D_FM1_WWWW0_T); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_m1 (0, [(1, C_13_42)]), D_FM1_WWWW0_U); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_m1 (0, [(1, C_12_34)]), D_FM1_WWWW0_S); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_m1 (0, [(1, C_14_23)]), D_FM1_WWWW0_T); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_m1 (0, [(1, C_13_42)]), D_FM1_WWWW0_U); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_m1 (0, [(1, C_12_34)]), D_FM1_WWWW2_S); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_m1 (0, [(1, C_13_42)]), D_FM1_WWWW2_T); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_m1 (0, [(1, C_14_23)]), D_FM1_WWWW2_U); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_m1 (0, [(1, C_12_34)]), D_FM1_ZZWW0_S); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_m1 (0, [(1, C_13_42)]), D_FM1_ZZWW0_T); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_m1 (0, [(1, C_14_23)]), D_FM1_ZZWW0_U); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_m1 (0, [(1, C_12_34)]), D_FM1_ZZWW1_S); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_m1 (0, [(1, C_13_42)]), D_FM1_ZZWW1_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_m1 (0, [(1, C_14_23)]), D_FM1_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_m1 (1, [(1, C_12_34)]), D_FM1_ZZWW1_S); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_m1 (1, [(1, C_13_42)]), D_FM1_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_m1 (1, [(1, C_14_23)]), D_FM1_ZZWW1_T); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_m1 (2, [(1, C_12_34)]), D_FM1_ZZWW1_S); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_m1 (2, [(1, C_13_42)]), D_FM1_ZZWW1_U); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_m1 (2, [(1, C_14_23)]), D_FM1_ZZWW1_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m1 (0, [(1, C_12_34)]), D_FM1_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m1 (0, [(1, C_13_42)]), D_FM1_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m1 (0, [(1, C_14_23)]), D_FM1_ZZZZ_U); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m1 (3, [(1, C_14_23)]), D_FM1_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m1 (3, [(1, C_13_42)]), D_FM1_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m1 (3, [(1, C_12_34)]), D_FM1_ZZZZ_U)] else [] let k_matrix_quartic_gauge_m_7 = if Flags.k_matrix_tm then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_m7 (0, [(1, C_12_34)]), D_FM7_WWWW0_S); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_m7 (0, [(1, C_14_23)]), D_FM7_WWWW0_T); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_cf_m7 (0, [(1, C_13_42)]), D_FM7_WWWW0_U); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_m7 (0, [(1, C_12_34)]), D_FM7_WWWW0_S); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_m7 (0, [(1, C_14_23)]), D_FM7_WWWW0_T); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_cf_m7 (0, [(1, C_13_42)]), D_FM7_WWWW0_U); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_m7 (0, [(1, C_12_34)]), D_FM7_WWWW2_S); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_m7 (0, [(1, C_13_42)]), D_FM7_WWWW2_T); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_cf_m7 (0, [(1, C_14_23)]), D_FM7_WWWW2_U); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_m7 (0, [(1, C_12_34)]), D_FM7_ZZWW0_S); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_m7 (0, [(1, C_13_42)]), D_FM7_ZZWW0_T); ((Wm, Wp, Z, Z), Vector4_K_Matrix_cf_m7 (0, [(1, C_14_23)]), D_FM7_ZZWW0_U); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_m7 (0, [(1, C_12_34)]), D_FM7_ZZWW1_S); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_m7 (0, [(1, C_13_42)]), D_FM7_ZZWW1_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_cf_m7 (0, [(1, C_14_23)]), D_FM7_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_m7 (1, [(1, C_12_34)]), D_FM7_ZZWW1_S); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_m7 (1, [(1, C_13_42)]), D_FM7_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_cf_m7 (1, [(1, C_14_23)]), D_FM7_ZZWW1_T); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_m7 (2, [(1, C_12_34)]), D_FM7_ZZWW1_S); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_m7 (2, [(1, C_13_42)]), D_FM7_ZZWW1_U); ((Z, Wp, Wm, Z), Vector4_K_Matrix_cf_m7 (2, [(1, C_14_23)]), D_FM7_ZZWW1_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m7 (0, [(1, C_12_34)]), D_FM7_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m7 (0, [(1, C_13_42)]), D_FM7_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m7 (0, [(1, C_14_23)]), D_FM7_ZZZZ_U); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m7 (3, [(1, C_14_23)]), D_FM7_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m7 (3, [(1, C_13_42)]), D_FM7_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_cf_m7 (3, [(1, C_12_34)]), D_FM7_ZZZZ_U)] else [] let k_matrix_2scalar_2gauge = if Flags.k_matrix_tm then if Flags.higgs_matrix then [ ((O H,O H,G Z,G Z), DScalar2_Vector2_K_Matrix_ms (0, [(1, C_12_34)]), D_Alpha_HHZZ0_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_K_Matrix_ms (0, [(1, C_13_42)]), D_Alpha_HHZZ0_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_K_Matrix_ms (0, [(1, C_14_23)]), D_Alpha_HHZZ0_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_K_Matrix_ms (3, [(1, C_14_23)]), D_Alpha_HHZZ1_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_K_Matrix_ms (3, [(1, C_13_42)]), D_Alpha_HHZZ1_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_K_Matrix_ms (3, [(1, C_12_34)]), D_Alpha_HHZZ1_U); ((O H,O H,G Z,G Z), DScalar2_Vector2_K_Matrix_ms (6, [(1, C_13_42)]), D_Alpha_HHZZ1_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_K_Matrix_ms (6, [(1, C_12_34)]), D_Alpha_HHZZ1_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_K_Matrix_ms (6, [(1, C_14_23)]), D_Alpha_HHZZ1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (0, [(1, C_12_34)]), D_Alpha_HHWW0_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (2, [(1, C_13_42)]), D_Alpha_HHWW0_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (1, [(1, C_14_23)]), D_Alpha_HHWW0_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (1, [(1, C_13_42)]), D_Alpha_HHWW0_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (2, [(1, C_14_23)]), D_Alpha_HHWW0_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (3, [(1, C_14_23)]), D_Alpha_HHWW1_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (6, [(1, C_13_42)]), D_Alpha_HHWW1_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (4, [(1, C_13_42)]), D_Alpha_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (5, [(1, C_12_34)]), D_Alpha_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (8, [(1, C_14_23)]), D_Alpha_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (7, [(1, C_12_34)]), D_Alpha_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (5, [(1, C_13_42)]), D_Alpha_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (4, [(1, C_12_34)]), D_Alpha_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (7, [(1, C_14_23)]), D_Alpha_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_K_Matrix_ms (8, [(1, C_12_34)]), D_Alpha_HHWW1_U) ] else [] else [] let k_matrix_2scalar_2gauge_m = if Flags.k_matrix_tm then if Flags.higgs_matrix then [ ((O H,O H,G Z,G Z), DScalar2_Vector2_m_0_K_Matrix_cf (0, [(1, C_12_34)]), D_FM0_HHZZ0_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_0_K_Matrix_cf (0, [(1, C_13_42)]), D_FM0_HHZZ0_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_0_K_Matrix_cf (0, [(1, C_14_23)]), D_FM0_HHZZ0_U); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_0_K_Matrix_cf (3, [(1, C_14_23)]), D_FM0_HHZZ1_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_0_K_Matrix_cf (3, [(1, C_13_42)]), D_FM0_HHZZ1_U); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_0_K_Matrix_cf (3, [(1, C_12_34)]), D_FM0_HHZZ1_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_0_K_Matrix_cf (6, [(1, C_13_42)]), D_FM0_HHZZ1_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_0_K_Matrix_cf (6, [(1, C_12_34)]), D_FM0_HHZZ1_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_0_K_Matrix_cf (6, [(1, C_14_23)]), D_FM0_HHZZ1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (0, [(1, C_12_34)]), D_FM0_HHWW0_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (2, [(1, C_13_42)]), D_FM0_HHWW0_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (1, [(1, C_14_23)]), D_FM0_HHWW0_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (1, [(1, C_13_42)]), D_FM0_HHWW0_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (2, [(1, C_14_23)]), D_FM0_HHWW0_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (3, [(1, C_14_23)]), D_FM0_HHWW1_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (6, [(1, C_13_42)]), D_FM0_HHWW1_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (4, [(1, C_13_42)]), D_FM0_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (5, [(1, C_12_34)]), D_FM0_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (8, [(1, C_14_23)]), D_FM0_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (7, [(1, C_12_34)]), D_FM0_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (5, [(1, C_13_42)]), D_FM0_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (4, [(1, C_12_34)]), D_FM0_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (7, [(1, C_14_23)]), D_FM0_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_0_K_Matrix_cf (8, [(1, C_12_34)]), D_FM0_HHWW1_T) ] else [] else [] let k_matrix_2scalar_2gauge_m_1 = if Flags.k_matrix_tm then if Flags.higgs_matrix then [ ((O H,O H,G Z,G Z), DScalar2_Vector2_m_1_K_Matrix_cf (0, [(1, C_12_34)]), D_FM1_HHZZ0_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_1_K_Matrix_cf (0, [(1, C_13_42)]), D_FM1_HHZZ0_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_1_K_Matrix_cf (0, [(1, C_14_23)]), D_FM1_HHZZ0_U); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_1_K_Matrix_cf (3, [(1, C_14_23)]), D_FM1_HHZZ1_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_1_K_Matrix_cf (3, [(1, C_13_42)]), D_FM1_HHZZ1_U); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_1_K_Matrix_cf (3, [(1, C_12_34)]), D_FM1_HHZZ1_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_1_K_Matrix_cf (6, [(1, C_13_42)]), D_FM1_HHZZ1_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_1_K_Matrix_cf (6, [(1, C_12_34)]), D_FM1_HHZZ1_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_1_K_Matrix_cf (6, [(1, C_14_23)]), D_FM1_HHZZ1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (0, [(1, C_12_34)]), D_FM1_HHWW0_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (2, [(1, C_13_42)]), D_FM1_HHWW0_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (1, [(1, C_14_23)]), D_FM1_HHWW0_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (1, [(1, C_13_42)]), D_FM1_HHWW0_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (2, [(1, C_14_23)]), D_FM1_HHWW0_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (3, [(1, C_14_23)]), D_FM1_HHWW1_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (6, [(1, C_13_42)]), D_FM1_HHWW1_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (4, [(1, C_13_42)]), D_FM1_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (5, [(1, C_12_34)]), D_FM1_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (8, [(1, C_14_23)]), D_FM1_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (7, [(1, C_12_34)]), D_FM1_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (5, [(1, C_13_42)]), D_FM1_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (4, [(1, C_12_34)]), D_FM1_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (7, [(1, C_14_23)]), D_FM1_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_1_K_Matrix_cf (8, [(1, C_12_34)]), D_FM1_HHWW1_T) ] else [] else [] let k_matrix_2scalar_2gauge_m_7 = if Flags.k_matrix_tm then if Flags.higgs_matrix then [ ((O H,O H,G Z,G Z), DScalar2_Vector2_m_7_K_Matrix_cf (0, [(1, C_12_34)]), D_FM7_HHZZ0_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_7_K_Matrix_cf (0, [(1, C_13_42)]), D_FM7_HHZZ0_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_7_K_Matrix_cf (0, [(1, C_14_23)]), D_FM7_HHZZ0_U); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_7_K_Matrix_cf (3, [(1, C_14_23)]), D_FM7_HHZZ1_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_7_K_Matrix_cf (3, [(1, C_13_42)]), D_FM7_HHZZ1_U); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_7_K_Matrix_cf (3, [(1, C_12_34)]), D_FM7_HHZZ1_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_7_K_Matrix_cf (6, [(1, C_13_42)]), D_FM7_HHZZ1_S); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_7_K_Matrix_cf (6, [(1, C_12_34)]), D_FM7_HHZZ1_T); ((O H,O H,G Z,G Z), DScalar2_Vector2_m_7_K_Matrix_cf (6, [(1, C_14_23)]), D_FM7_HHZZ1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (0, [(1, C_12_34)]), D_FM7_HHWW0_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (2, [(1, C_13_42)]), D_FM7_HHWW0_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (1, [(1, C_14_23)]), D_FM7_HHWW0_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (1, [(1, C_13_42)]), D_FM7_HHWW0_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (2, [(1, C_14_23)]), D_FM7_HHWW0_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (3, [(1, C_14_23)]), D_FM7_HHWW1_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (6, [(1, C_13_42)]), D_FM7_HHWW1_S); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (4, [(1, C_13_42)]), D_FM7_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (5, [(1, C_12_34)]), D_FM7_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (8, [(1, C_14_23)]), D_FM7_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (7, [(1, C_12_34)]), D_FM7_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (5, [(1, C_13_42)]), D_FM7_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (4, [(1, C_12_34)]), D_FM7_HHWW1_T); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (7, [(1, C_14_23)]), D_FM7_HHWW1_U); ((O H,O H,G Wp,G Wm), DScalar2_Vector2_m_7_K_Matrix_cf (8, [(1, C_12_34)]), D_FM7_HHWW1_T) ] else [] else [] let k_matrix_4scalar = if Flags.k_matrix then if Flags.higgs_matrix then [ ((O H,O H,O H,O H), DScalar4_K_Matrix_ms (0, [(1, C_12_34)]), D_Alpha_HHHH_S); ((O H,O H,O H,O H), DScalar4_K_Matrix_ms (0, [(1, C_13_42)]), D_Alpha_HHHH_T); ((O H,O H,O H,O H), DScalar4_K_Matrix_ms (0, [(1, C_14_23)]), D_Alpha_HHHH_T); ((O H,O H,O H,O H), DScalar4_K_Matrix_ms (3, [(1, C_14_23)]), D_Alpha_HHHH_S); ((O H,O H,O H,O H), DScalar4_K_Matrix_ms (3, [(1, C_13_42)]), D_Alpha_HHHH_T); ((O H,O H,O H,O H), DScalar4_K_Matrix_ms (3, [(1, C_12_34)]), D_Alpha_HHHH_T) ] else [] else [] (*i Thorsten's original implementation of the K matrix, which we keep since it still might be usefull for the future. let k_matrix_quartic_gauge = if Flags.k_matrix then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 0, K_Matrix_Pole 0]), Alpha_WWWW0); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 2, K_Matrix_Pole 2]), Alpha_WWWW2); ((Wm, Wp, Z, Z), Vector4_K_Matrix_tho (0, [(K_Matrix_Coeff 0, K_Matrix_Pole 0); (K_Matrix_Coeff 2, K_Matrix_Pole 2)]), Alpha_ZZWW0); ((Wm, Z, Wp, Z), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 1, K_Matrix_Pole 1]), Alpha_ZZWW1); ((Z, Z, Z, Z), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 0, K_Matrix_Pole 0]), Alpha_ZZZZ) ] else [] i*) let quartic_gauge = standard_quartic_gauge @ anomalous_quartic_gauge @ k_matrix_quartic_gauge @ k_matrix_quartic_gauge_t_0 @ k_matrix_quartic_gauge_t_1 @ k_matrix_quartic_gauge_t_2 @ k_matrix_quartic_gauge_t_rsi @ k_matrix_quartic_gauge_m_0 @ k_matrix_quartic_gauge_m_1 @ k_matrix_quartic_gauge_m_7 let standard_gauge_higgs = [ ((O H, G Wp, G Wm), Scalar_Vector_Vector 1, G_HWW); ((O H, G Z, G Z), Scalar_Vector_Vector 1, G_HZZ) ] let standard_gauge_higgs4 = [ (O H, O H, G Wp, G Wm), Scalar2_Vector2 1, G_HHWW; (O H, O H, G Z, G Z), Scalar2_Vector2 1, G_HHZZ ] let dim8_gauge_higgs4 = [ (O H, O H, G Wp, G Wm), Dim8_Scalar2_Vector2_1 1, FS0_HHWW; (O H, O H, G Z, G Z), Dim8_Scalar2_Vector2_1 1, FS0_HHZZ; (O H, O H, G Wp, G Wm), Dim8_Scalar2_Vector2_2 1, FS1_HHWW; (O H, O H, G Z, G Z), Dim8_Scalar2_Vector2_2 1, FS1_HHZZ ] let dim8_gauge_higgs4_m = [ (O H, O H, G Wp, G Wm), Dim8_Scalar2_Vector2_m_0 1, FM0_HHWW; (O H, O H, G Z, G Z), Dim8_Scalar2_Vector2_m_0 1, FM0_HHZZ; (O H, O H, G Wp, G Wm), Dim8_Scalar2_Vector2_m_1 1, FM1_HHWW; (O H, O H, G Z, G Z), Dim8_Scalar2_Vector2_m_1 1, FM1_HHZZ; (O H, O H, G Wp, G Wm), Dim8_Scalar2_Vector2_m_7 1, FM7_HHWW; (O H, O H, G Z, G Z), Dim8_Scalar2_Vector2_m_7 1, FM7_HHZZ] let standard_higgs = [ (O H, O H, O H), Scalar_Scalar_Scalar 1, G_H3 ] let standard_higgs4 = [ (O H, O H, O H, O H), Scalar4 1, G_H4 ] let fs_higgs4 = [ (O H, O H, O H, O H), Dim8_Scalar4 1, FS_H4 ] (* WK's couplings (apparently, he still intends to divide by $\Lambda^2_{\text{EWSB}}=16\pi^2v_{\mathrm{F}}^2$): \begin{subequations} \begin{align} \mathcal{L}^{\tau}_4 &= \left\lbrack (\partial_{\mu}H)(\partial^{\mu}H) + \frac{g^2v_{\mathrm{F}}^2}{4} V_{\mu} V^{\mu} \right\rbrack^2 \\ \mathcal{L}^{\tau}_5 &= \left\lbrack (\partial_{\mu}H)(\partial_{\nu}H) + \frac{g^2v_{\mathrm{F}}^2}{4} V_{\mu} V_{\nu} \right\rbrack^2 \end{align} \end{subequations} with \begin{equation} V_{\mu} V_{\nu} = \frac{1}{2} \left( W^+_{\mu} W^-_{\nu} + W^+_{\nu} W^-_{\mu} \right) + \frac{1}{2\cos^2\theta_{w}} Z_{\mu} Z_{\nu} \end{equation} (note the symmetrization!), i.\,e. \begin{subequations} \begin{align} \mathcal{L}_4 &= \alpha_4 \frac{g^4v_{\mathrm{F}}^4}{16} (V_{\mu} V_{\nu})^2 \\ \mathcal{L}_5 &= \alpha_5 \frac{g^4v_{\mathrm{F}}^4}{16} (V_{\mu} V^{\mu})^2 \end{align} \end{subequations} *) (* Breaking thinks up \begin{subequations} \begin{align} \mathcal{L}^{\tau,H^4}_4 &= \left\lbrack (\partial_{\mu}H)(\partial^{\mu}H) \right\rbrack^2 \\ \mathcal{L}^{\tau,H^4}_5 &= \left\lbrack (\partial_{\mu}H)(\partial^{\mu}H) \right\rbrack^2 \end{align} \end{subequations} and \begin{subequations} \begin{align} \mathcal{L}^{\tau,H^2V^2}_4 &= \frac{g^2v_{\mathrm{F}}^2}{2} (\partial_{\mu}H)(\partial^{\mu}H) V_{\mu}V^{\mu} \\ \mathcal{L}^{\tau,H^2V^2}_5 &= \frac{g^2v_{\mathrm{F}}^2}{2} (\partial_{\mu}H)(\partial_{\nu}H) V_{\mu}V_{\nu} \end{align} \end{subequations} i.\,e. \begin{subequations} \begin{align} \mathcal{L}^{\tau,H^2V^2}_4 &= \frac{g^2v_{\mathrm{F}}^2}{2} \left\lbrack (\partial_{\mu}H)(\partial^{\mu}H) W^+_{\nu}W^{-,\nu} + \frac{1}{2\cos^2\theta_{w}} (\partial_{\mu}H)(\partial^{\mu}H) Z_{\nu} Z^{\nu} \right\rbrack \\ \mathcal{L}^{\tau,H^2V^2}_5 &= \frac{g^2v_{\mathrm{F}}^2}{2} \left\lbrack (W^{+,\mu}\partial_{\mu}H) (W^{-,\nu}\partial_{\nu}H) + \frac{1}{2\cos^2\theta_{w}} (Z^{\mu}\partial_{\mu}H)(Z^{\nu}\partial_{\nu}H) \right\rbrack \end{align} \end{subequations} *) (* \begin{multline} \tau^4_8 \mathcal{L}^{\tau,H^2V^2}_4 + \tau^5_8 \mathcal{L}^{\tau,H^2V^2}_5 = \\ - \frac{g^2v_{\mathrm{F}}^2}{2} \Biggl\lbrack 2\tau^4_8 \frac{1}{2}(\ii\partial_{\mu}H)(\ii\partial^{\mu}H) W^+_{\nu}W^{-,\nu} + \tau^5_8 (W^{+,\mu}\ii\partial_{\mu}H) (W^{-,\nu}\ii\partial_{\nu}H) \\ + \frac{2\tau^4_8}{\cos^2\theta_{w}} \frac{1}{4} (\ii\partial_{\mu}H)(\ii\partial^{\mu}H) Z_{\nu} Z^{\nu} + \frac{\tau^5_8}{\cos^2\theta_{w}} \frac{1}{2} (Z^{\mu}\ii\partial_{\mu}H)(Z^{\nu}\ii\partial_{\nu}H) \Biggr\rbrack \end{multline} where the two powers of $\ii$ make the sign conveniently negative, i.\,e. \begin{subequations} \begin{align} \alpha_{(\partial H)^2W^2}^2 &= \tau^4_8 g^2v_{\mathrm{F}}^2\\ \alpha_{(\partial HW)^2}^2 &= \frac{\tau^5_8 g^2v_{\mathrm{F}}^2}{2} \\ \alpha_{(\partial H)^2Z^2}^2 &= \frac{\tau^4_8 g^2v_{\mathrm{F}}^2}{\cos^2\theta_{w}} \\ \alpha_{(\partial HZ)^2}^2 &=\frac{\tau^5_8 g^2v_{\mathrm{F}}^2}{2\cos^2\theta_{w}} \end{align} \end{subequations} *) let anomalous_gauge_higgs = [ (O H, G Ga, G Ga), Dim5_Scalar_Gauge2 1, G_HGaGa_anom; (O H, G Ga, G Z), Dim5_Scalar_Gauge2 1, G_HGaZ_anom; (O H, G Z, G Z), Dim5_Scalar_Gauge2 1, G_HZZ_anom; (O H, G Wp, G Wm), Dim5_Scalar_Gauge2 1, G_HWW_anom; (O H, G Ga, G Z), Dim5_Scalar_Vector_Vector_U 1, G_HGaZ_u; (O H, G Z, G Z), Dim5_Scalar_Vector_Vector_U 1, G_HZZ_u; (O H, G Wp, G Wm), Dim5_Scalar_Vector_Vector_U 1, G_HWW_u; (O H, G Wm, G Wp), Dim5_Scalar_Vector_Vector_U 1, G_HWW_u ] let anomalous_gauge_higgs4 = [] let anomalous_higgs = [] let higgs_triangle_vertices = if Flags.higgs_triangle then [ (O H, G Ga, G Ga), Dim5_Scalar_Gauge2 1, G_HGaGa; (O H, G Ga, G Z), Dim5_Scalar_Gauge2 1, G_HGaZ; (O H, G Gl, G Gl), Dim5_Scalar_Gauge2 1, G_Hgg ] else [] let anomalous_higgs4 = [] let gauge_higgs = if Flags.higgs_anom then standard_gauge_higgs @ anomalous_gauge_higgs else standard_gauge_higgs let gauge_higgs4 = ( if Flags.higgs_anom then standard_gauge_higgs4 @ anomalous_gauge_higgs4 else standard_gauge_higgs4 ) @ ( if Flags.higgs_matrix then (dim8_gauge_higgs4 @ dim8_gauge_higgs4_m @ k_matrix_2scalar_2gauge @ k_matrix_2scalar_2gauge_m @ k_matrix_2scalar_2gauge_m_1 @ k_matrix_2scalar_2gauge_m_7) else [] ) let higgs = if Flags.higgs_anom then standard_higgs @ anomalous_higgs else standard_higgs let higgs4 = ( if Flags.higgs_anom then standard_higgs4 @ anomalous_higgs4 else standard_higgs4 ) @ ( if Flags.higgs_matrix then (fs_higgs4 @ k_matrix_4scalar ) else [] ) let goldstone_vertices = [ ((O Phi0, G Wm, G Wp), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phip, G Ga, G Wm), Scalar_Vector_Vector 1, I_Q_W); ((O Phip, G Z, G Wm), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phim, G Wp, G Ga), Scalar_Vector_Vector 1, I_Q_W); ((O Phim, G Wp, G Z), Scalar_Vector_Vector 1, I_G_ZWW) ] (* New Resonances *) (* \begin{dubious} There is an extra minus in the Lagrangian to have the same sign as HWW or HZZ vertex. Effectivly this doesn't matter for SSC, because $(-1)^2=1$. This is only for completeness. \end{dubious} \begin{subequations} \begin{align} \mathbf{V}_\mu &= -\mathrm{i} g\mathbf{W}_\mu+\mathrm{i} g^\prime\mathbf{B}_\mu \\ \mathbf{W}_\mu &= W_\mu^a\frac{\tau^a}{2} \\ \mathbf{B}_\mu &= W_\mu^a\frac{\tau^3}{2} \\ \tau^{++}&= \tau^+ \otimes \tau^+ \\ \tau^+ &= \frac{1}{2} \left (\tau^+ \otimes \tau^3 + \tau^3+\tau^+ \right ) \\ \tau^0 &= \frac{1}{\sqrt{6}} \left (\tau^3\otimes\tau^3 -\tau^+ \otimes \tau^- - \tau^-+\tau^+ \right ) \\ \tau^- &= \frac{1}{2} \left (\tau^- \otimes \tau^3 + \tau^3+\tau^- \right ) \\ \tau^{--}&= \tau^- \otimes \tau^- \end{align} \end{subequations} *) (* Scalar Isoscalar Old representation \begin{equation} \mathcal{L}_{\sigma}= -\frac{g_\sigma v}{2} \text{tr} \left\lbrack \mathbf{V}_\mu \mathbf{V}^\mu \right\rbrack \sigma \end{equation} *) (* \begin{dubious} Transversal couplings like rsigma3t and rf3t are to be calculated in the new higgs matrix representation. \end{dubious} *) let rsigma3 = [ ((O Rsigma, G Wp, G Wm), Scalar_Vector_Vector 1, G_SWW); ((O Rsigma, G Z, G Z), Scalar_Vector_Vector 1, G_SZZ) ] let rsigma3h = [ ((O Rsigma, O H, O H), Dim5_Scalar_Scalar2 1, G_SHH) ] let rsigma3t = [ ((O Rsigma, G Wp, G Wm), Scalar_Vector_Vector_t 1, G_SWW_T); ((O Rsigma, G Z, G Z), Scalar_Vector_Vector_t 1, G_SZZ_T); ((O Rsigma, G Ga, G Ga), Scalar_Vector_Vector_t 1, G_SAA_T); ((O Rsigma, G Ga, G Z), Scalar_Vector_Vector_t 1, G_SAZ_T) ] let rsigma4 = [ (O Rsigma, O Rsigma, G Wp, G Wm), Scalar2_Vector2 1, G_SSWW; (O Rsigma, O Rsigma, G Z, G Z), Scalar2_Vector2 1, G_SSZZ ] (* Scalar Isotensor \begin{subequations} \begin{align} \mathcal{L}_{\phi}&= \frac{g_\phi v}{4} \text{Tr} \left \lbrack \left ( \mathbf{V}_\mu \otimes \mathbf{V}^\mu - \frac{\tau^{aa}}{6} \text{Tr} \left \lbrack \mathbf{V}_\mu \mathbf{V}^\mu \right \rbrack\right ) {\mathbf{\phi}} \right \rbrack\\ \phi&=\sqrt{2} \left (\phi^{++}\tau^{++}+\phi^+\tau^++\phi^0\tau^0+\phi^-\tau^- + \phi^{--}\tau^{--} \right ) \end{align} \end{subequations} *) let rphi3 = [ ((O Rphin, G Wp, G Wm), Scalar_Vector_Vector 1, G_PNWW); ((O Rphin, G Z, G Z), Scalar_Vector_Vector 1, G_PNZZ) ; ((O Rphisn, G Wp, G Wm), Scalar_Vector_Vector 1, G_PSNWW); ((O Rphisn, G Z, G Z), Scalar_Vector_Vector 1, G_PSNZZ) ; ((O Rphip, G Z, G Wm), Scalar_Vector_Vector 1, G_PWZ) ; ((O Rphipp, G Wm, G Wm), Scalar_Vector_Vector 1, G_PWW) ; ((O Rphim, G Wp, G Z), Scalar_Vector_Vector 1, G_PWZ) ; ((O Rphimm, G Wp, G Wp), Scalar_Vector_Vector 1, G_PWW) ] let rphi3h = [ ((O Rphisn, O H, O H), Dim5_Scalar_Scalar2 1, G_PSNHH) ] (* Tensor IsoScalar *) let rf3 = [ ((O Rf, G Wp, G Wm), Tensor_2_Vector_Vector_1 1, G_FWW); ((O Rf, G Z, G Z), Tensor_2_Vector_Vector_1 1, G_FZZ) ] let rf3cf = [ ((O Rf, G Wp, G Wm), Tensor_2_Vector_Vector 1, G_FWW); ((O Rf, G Z, G Z), Tensor_2_Vector_Vector 1, G_FZZ); ((O Rf, G Wp, G Wm), Tensor_2_Vector_Vector_cf 1, G_FWW_CF); ((O Rf, G Z, G Z), Tensor_2_Vector_Vector_cf 1, G_FZZ_CF) ] let rff3cf = [ ((O Rff, G Wp, G Wm), Tensor_2_Vector_Vector 1, G_FFWW); ((O Rff, G Z, G Z), Tensor_2_Vector_Vector 1, G_FFZZ); ((O Rff, G Wp, G Wm), Tensor_2_Vector_Vector_cf 1, G_FFWW_CF); ((O Rff, G Z, G Z), Tensor_2_Vector_Vector_cf 1, G_FFZZ_CF) ] let rfv3cf = [ ((O Rfv, G Wp, G Wm), TensorVector_Vector_Vector 1, G_FVWW); ((O Rfv, G Z, G Z), TensorVector_Vector_Vector 1, G_FVZZ); ((O Rfv, G Wp, G Wm), TensorVector_Vector_Vector_cf 1, G_FVWW_CF); ((O Rfv, G Z, G Z), TensorVector_Vector_Vector_cf 1, G_FVZZ_CF) ] let rfddphi3cf = [ ((O Rfphi, G Wp, G Wm), TensorScalar_Vector_Vector 1, G_FDDSWW); ((O Rfphi, G Z, G Z), TensorScalar_Vector_Vector 1, G_FDDSZZ); ((O Rfphi, G Wp, G Wm), TensorScalar_Vector_Vector_cf 1, G_FDDSWW_CF); ((O Rfphi, G Z, G Z), TensorScalar_Vector_Vector_cf 1, G_FDDSZZ_CF) ] let rfphi3cf = [ ((O Rfphi, G Wp, G Wm), Scalar_Vector_Vector 1, G_FSWW); ((O Rfphi, G Z, G Z), Scalar_Vector_Vector 1, G_FSZZ) ] let rf3h = [ ((O Rf, O H, O H), Tensor_2_Scalar_Scalar 1, G_FHH); ((O Rf, O H, O H), Tensor_2_Scalar_Scalar_cf 1, G_FHH_CF) ] let rff3h = [ ((O Rff, O H, O H), Tensor_2_Scalar_Scalar 1, G_FFHH); ((O Rff, O H, O H), Tensor_2_Scalar_Scalar_cf 1, G_FFHH_CF); ((O Rfv, O H, O H), TensorVector_Scalar_Scalar 1, G_FVHH); ((O Rfv, O H, O H), TensorVector_Scalar_Scalar_cf 1, G_FVHH_CF); ((O Rfphi, O H, O H), TensorScalar_Scalar_Scalar 1, G_FDDSHH); ((O Rfphi, O H, O H), TensorScalar_Scalar_Scalar_cf 1, G_FDDSHH_CF); ((O Rfphi, O H, O H), Dim5_Scalar_Scalar2 1, G_FSHH) ] let rf3t = [ ((O Rf, G Wp, G Wm), Tensor_2_Vector_Vector_t 1, G_FWW_T); ((O Rf, G Z, G Z), Tensor_2_Vector_Vector_t 1, G_FZZ_T) ] (* Tensor Isotensor \begin{subequations} \begin{align} \mathcal{L}_{t} \end{align} \end{subequations} *) let rt3 = [ ((O Rtn, G Wp, G Wm), Tensor_2_Vector_Vector_1 1, G_TNWW); ((O Rtn, G Z, G Z), Tensor_2_Vector_Vector_1 1, G_TNZZ) ; ((O Rtsn, G Wp, G Wm), Tensor_2_Vector_Vector_1 1, G_TSNWW); ((O Rtsn, G Z, G Z), Tensor_2_Vector_Vector_1 1, G_TSNZZ) ; ((O Rtp, G Z, G Wm), Tensor_2_Vector_Vector_1 1, G_TWZ) ; ((O Rtpp, G Wm, G Wm), Tensor_2_Vector_Vector_1 1, G_TWW) ; ((O Rtm, G Wp, G Z), Tensor_2_Vector_Vector_1 1, G_TWZ) ; ((O Rtmm, G Wp, G Wp), Tensor_2_Vector_Vector_1 1, G_TWW) ] let rt3cf = [ ((O Rtn, G Wp, G Wm), Tensor_2_Vector_Vector 1, G_TNWW); ((O Rtn, G Z, G Z), Tensor_2_Vector_Vector 1, G_TNZZ) ; ((O Rtsn, G Wp, G Wm), Tensor_2_Vector_Vector 1, G_TSNWW); ((O Rtsn, G Z, G Z), Tensor_2_Vector_Vector 1, G_TSNZZ) ; ((O Rtp, G Z, G Wm), Tensor_2_Vector_Vector 1, G_TWZ) ; ((O Rtpp, G Wm, G Wm), Tensor_2_Vector_Vector 1, G_TWW) ; ((O Rtm, G Wp, G Z), Tensor_2_Vector_Vector 1, G_TWZ) ; ((O Rtmm, G Wp, G Wp), Tensor_2_Vector_Vector 1, G_TWW); ((O Rtn, G Wp, G Wm), Tensor_2_Vector_Vector_cf 1, G_TNWW_CF); ((O Rtn, G Z, G Z), Tensor_2_Vector_Vector_cf 1, G_TNZZ_CF) ; ((O Rtsn, G Wp, G Wm), Tensor_2_Vector_Vector_cf 1, G_TSNWW_CF); ((O Rtsn, G Z, G Z), Tensor_2_Vector_Vector_cf 1, G_TSNZZ_CF) ; ((O Rtp, G Z, G Wm), Tensor_2_Vector_Vector_cf 1, G_TWZ_CF) ; ((O Rtpp, G Wm, G Wm), Tensor_2_Vector_Vector_cf 1, G_TWW_CF) ; ((O Rtm, G Wp, G Z), Tensor_2_Vector_Vector_cf 1, G_TWZ_CF) ; ((O Rtmm, G Wp, G Wp), Tensor_2_Vector_Vector_cf 1, G_TWW_CF) ] (* Anomalous trilinear interactions $f_i f_j V$ and $ttH$: \begin{equation} \Delta\mathcal{L}_{tt\gamma} = - e \frac{\upsilon}{\Lambda^2} \bar{t} i\sigma^{\mu\nu} k_\nu (d_V(k^2) + i d_A(k^2) \gamma_5) t A_\mu \end{equation} *) let anomalous_ttA = if Flags.top_anom then [ ((M (U (-3)), G Ga, M (U 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_ttA) ] else [] (* \begin{equation} \Delta\mathcal{L}_{bb\gamma} = - e \frac{\upsilon}{\Lambda^2} \bar{b} i\sigma^{\mu\nu} k_\nu (d_V(k^2) + i d_A(k^2) \gamma_5) b A_\mu \end{equation} *) let anomalous_bbA = if Flags.top_anom then [ ((M (D (-3)), G Ga, M (D 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_bbA) ] else [] (* \begin{equation} \Delta\mathcal{L}_{ttg} = - g_s \frac{\upsilon}{\Lambda^2} \bar{t}\lambda^a i\sigma^{\mu\nu}k_\nu (d_V(k^2)+id_A(k^2)\gamma_5)tG^a_\mu \end{equation} *) let anomalous_ttG = if Flags.top_anom then [ ((M (U (-3)), G Gl, M (U 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_ttG) ] else [] (* \begin{equation} \Delta\mathcal{L}_{ttZ} = - \frac{g}{2 c_W} \frac{\upsilon^2}{\Lambda^2}\left\lbrack \bar{t} \fmslash{Z} (X_L(k^2) P_L + X_R(k^2) P_R) t + \bar{t}\frac{i\sigma^{\mu\nu}k_\nu}{m_Z} (d_V(k^2)+id_A(k^2)\gamma_5)tZ_\mu\right\rbrack \end{equation} *) let anomalous_ttZ = if Flags.top_anom then [ ((M (U (-3)), G Z, M (U 3)), FBF (1, Psibar, VLRM, Psi), G_VLR_ttZ); ((M (U (-3)), G Z, M (U 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_ttZ) ] else [] (* \begin{equation} \Delta\mathcal{L}_{bbZ} = - \frac{g}{2 c_W} \frac{\upsilon^2}{\Lambda^2} \bar{b}\frac{i\sigma^{\mu\nu}k_\nu}{m_Z} (d_V(k^2)+id_A(k^2)\gamma_5)bZ_\mu \end{equation} *) let anomalous_bbZ = if Flags.top_anom then [ ((M (D (-3)), G Z, M (D 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_bbZ) ] else [] (* \begin{equation} \Delta\mathcal{L}_{tbW} = - \frac{g}{\sqrt{2}} \frac{\upsilon^2}{\Lambda^2}\left\lbrack \bar{b}\fmslash{W}^-(V_L(k^2) P_L+V_R(k^2) P_R) t + \bar{b}\frac{i\sigma^{\mu\nu}k_\nu}{m_W} (g_L(k^2)P_L+g_R(k^2)P_R)tW^-_\mu\right\rbrack + \textnormal{H.c.} \end{equation} *) let anomalous_tbW = if Flags.top_anom then [ ((M (D (-3)), G Wm, M (U 3)), FBF (1, Psibar, VLRM, Psi), G_VLR_btW); ((M (U (-3)), G Wp, M (D 3)), FBF (1, Psibar, VLRM, Psi), G_VLR_tbW); ((M (D (-3)), G Wm, M (U 3)), FBF (1, Psibar, TLRM, Psi), G_TLR_btW); ((M (U (-3)), G Wp, M (D 3)), FBF (1, Psibar, TRLM, Psi), G_TRL_tbW) ] else [] (* \begin{equation} \Delta\mathcal{L}_{ttH} = - \frac{1}{\sqrt{2}} \bar{t} (Y_V(k^2)+iY_A(k^2)\gamma_5)t H \end{equation} *) let anomalous_ttH = if Flags.top_anom then [ ((M (U (-3)), O H, M (U 3)), FBF (1, Psibar, SPM, Psi), G_SP_ttH) ] else [] (* quartic fermion-gauge interactions $f_i f_j V_1 V_2$ emerging from gauge-invariant effective operators: \begin{equation} \Delta\mathcal{L}_{ttgg} = - \frac{g_s^2}{2} f_{abc} \frac{\upsilon}{\Lambda^2} \bar{t} \lambda^a \sigma^{\mu\nu} (d_V(k^2)+id_A(k^2)\gamma_5)t G^b_\mu G^c_\nu \end{equation} *) let anomalous_ttGG = if Flags.top_anom then [ ((M (U (-3)), O (Aux_top (2,1,0,true,TTGG)), M (U 3)), FBF (1, Psibar, TVA, Psi), G_TVA_ttGG); ((O (Aux_top (2,1,0,false,TTGG)), G Gl, G Gl), Aux_Gauge_Gauge 1, I_Gs) ] else [] (* \begin{equation} \Delta\mathcal{L}_{tbWA} = - i\sin\theta_w \frac{g^2}{2\sqrt{2}} \frac{\upsilon^2}{\Lambda^2}\left\lbrack \bar{b}\frac{\sigma^{\mu\nu}}{m_W} (g_L(k^2)P_L+g_R(k^2)P_R)t A_\mu W^-_\nu \right\rbrack + \textnormal{H.c.} \end{equation} *) let anomalous_tbWA = if Flags.top_anom then [ ((M (D (-3)), O (Aux_top (2,0,-1,true,TBWA)), M (U 3)), FBF (1, Psibar, TLR, Psi), G_TLR_btWA); ((O (Aux_top (2,0,1,false,TBWA)), G Ga, G Wm), Aux_Gauge_Gauge 1, I_G_weak); ((M (U (-3)), O (Aux_top (2,0,1,true,TBWA)), M (D 3)), FBF (1, Psibar, TRL, Psi), G_TRL_tbWA); ((O (Aux_top (2,0,-1,false,TBWA)), G Wp, G Ga), Aux_Gauge_Gauge 1, I_G_weak) ] else [] (* \begin{equation} \Delta\mathcal{L}_{tbWZ} = - i\cos\theta_w \frac{g^2}{2\sqrt{2}} \frac{\upsilon^2}{\Lambda^2}\left\lbrack \bar{b}\frac{\sigma^{\mu\nu}}{m_W} (g_L(k^2)P_L+g_R(k^2)P_R)t Z_\mu W^-_\nu \right\rbrack + \textnormal{H.c.} \end{equation} *) let anomalous_tbWZ = if Flags.top_anom then [ ((M (D (-3)), O (Aux_top (2,0,-1,true,TBWZ)), M (U 3)), FBF (1, Psibar, TLR, Psi), G_TLR_btWZ); ((O (Aux_top (2,0,1,false,TBWZ)), G Z, G Wm), Aux_Gauge_Gauge 1, I_G_weak); ((M (U (-3)), O (Aux_top (2,0,1,true,TBWZ)), M (D 3)), FBF (1, Psibar, TRL, Psi), G_TRL_tbWZ); ((O (Aux_top (2,0,-1,false,TBWZ)), G Wp, G Z), Aux_Gauge_Gauge 1, I_G_weak) ] else [] (* \begin{equation} \Delta\mathcal{L}_{ttWW} = - i \frac{g^2}{2} \frac{\upsilon^2}{\Lambda^2} \bar{t} \frac{\sigma^{\mu\nu}}{m_W} (d_V(k^2)+id_A(k^2)\gamma_5)t W^-_\mu W^+_\nu \end{equation} *) let anomalous_ttWW = if Flags.top_anom then [ ((M (U (-3)), O (Aux_top (2,0,0,true,TTWW)), M (U 3)), FBF (1, Psibar, TVA, Psi), G_TVA_ttWW); ((O (Aux_top (2,0,0,false,TTWW)), G Wm, G Wp), Aux_Gauge_Gauge 1, I_G_weak) ] else [] (* \begin{equation} \Delta\mathcal{L}_{bbWW} = - i \frac{g^2}{2} \frac{\upsilon^2}{\Lambda^2} \bar{b} \frac{\sigma^{\mu\nu}}{m_W} (d_V(k^2)+id_A(k^2)\gamma_5)b W^-_\mu W^+_\nu \end{equation} *) let anomalous_bbWW = if Flags.top_anom then [ ((M (D (-3)), O (Aux_top (2,0,0,true,BBWW)), M (D 3)), FBF (1, Psibar, TVA, Psi), G_TVA_bbWW); ((O (Aux_top (2,0,0,false,BBWW)), G Wm, G Wp), Aux_Gauge_Gauge 1, I_G_weak) ] else [] (* 4-fermion contact terms emerging from operator rewriting: *) let anomalous_top_qGuG_tt = [ ((M (U (-3)), O (Aux_top (1,1,0,true,QGUG)), M (U 3)), FBF (1, Psibar, VLR, Psi), G_VLR_qGuG) ] let anomalous_top_qGuG_ff n = List.map mom [ ((U (-n), Aux_top (1,1,0,false,QGUG), U n), FBF (1, Psibar, V, Psi), Unit); ((D (-n), Aux_top (1,1,0,false,QGUG), D n), FBF (1, Psibar, V, Psi), Unit) ] let anomalous_top_qGuG = if Flags.top_anom_4f then anomalous_top_qGuG_tt @ ThoList.flatmap anomalous_top_qGuG_ff [1;2;3] else [] let anomalous_top_qBuB_tt = [ ((M (U (-3)), O (Aux_top (1,0,0,true,QBUB)), M (U 3)), FBF (1, Psibar, VLR, Psi), G_VLR_qBuB) ] let anomalous_top_qBuB_ff n = List.map mom [ ((U (-n), Aux_top (1,0,0,false,QBUB), U n), FBF (1, Psibar, VLR, Psi), G_VLR_qBuB_u); ((D (-n), Aux_top (1,0,0,false,QBUB), D n), FBF (1, Psibar, VLR, Psi), G_VLR_qBuB_d); ((L (-n), Aux_top (1,0,0,false,QBUB), L n), FBF (1, Psibar, VLR, Psi), G_VLR_qBuB_e); ((N (-n), Aux_top (1,0,0,false,QBUB), N n), FBF (1, Psibar, VL, Psi), G_VL_qBuB_n) ] let anomalous_top_qBuB = if Flags.top_anom_4f then anomalous_top_qBuB_tt @ ThoList.flatmap anomalous_top_qBuB_ff [1;2;3] else [] let anomalous_top_qW_tq = [ ((M (U (-3)), O (Aux_top (1,0,0,true,QW)), M (U 3)), FBF (1, Psibar, VL, Psi), G_VL_qW); ((M (D (-3)), O (Aux_top (1,0,-1,true,QW)), M (U 3)), FBF (1, Psibar, VL, Psi), G_VL_qW); ((M (U (-3)), O (Aux_top (1,0,1,true,QW)), M (D 3)), FBF (1, Psibar, VL, Psi), G_VL_qW) ] let anomalous_top_qW_ff n = List.map mom [ ((U (-n), Aux_top (1,0,0,false,QW), U n), FBF (1, Psibar, VL, Psi), G_VL_qW_u); ((D (-n), Aux_top (1,0,0,false,QW), D n), FBF (1, Psibar, VL, Psi), G_VL_qW_d); ((N (-n), Aux_top (1,0,0,false,QW), N n), FBF (1, Psibar, VL, Psi), G_VL_qW_u); ((L (-n), Aux_top (1,0,0,false,QW), L n), FBF (1, Psibar, VL, Psi), G_VL_qW_d); ((D (-n), Aux_top (1,0,-1,false,QW), U n), FBF (1, Psibar, VL, Psi), Half); ((U (-n), Aux_top (1,0,1,false,QW), D n), FBF (1, Psibar, VL, Psi), Half); ((L (-n), Aux_top (1,0,-1,false,QW), N n), FBF (1, Psibar, VL, Psi), Half); ((N (-n), Aux_top (1,0,1,false,QW), L n), FBF (1, Psibar, VL, Psi), Half) ] let anomalous_top_qW = if Flags.top_anom_4f then anomalous_top_qW_tq @ ThoList.flatmap anomalous_top_qW_ff [1;2;3] else [] let anomalous_top_DuDd = if Flags.top_anom_4f then [ ((M (U (-3)), O (Aux_top (0,0,0,true,DR)), M (U 3)), FBF (1, Psibar, SR, Psi), Half); ((M (U (-3)), O (Aux_top (0,0,0,false,DR)), M (U 3)), FBF (1, Psibar, SL, Psi), G_SL_DttR); ((M (D (-3)), O (Aux_top (0,0,0,false,DR)), M (D 3)), FBF (1, Psibar, SR, Psi), G_SR_DttR); ((M (U (-3)), O (Aux_top (0,0,0,true,DL)), M (U 3)), FBF (1, Psibar, SL, Psi), Half); ((M (D (-3)), O (Aux_top (0,0,0,false,DL)), M (D 3)), FBF (1, Psibar, SL, Psi), G_SL_DttL); ((M (D (-3)), O (Aux_top (0,0,-1,true,DR)), M (U 3)), FBF (1, Psibar, SR, Psi), Half); ((M (U (-3)), O (Aux_top (0,0,1,false,DR)), M (D 3)), FBF (1, Psibar, SLR, Psi), G_SLR_DbtR); ((M (D (-3)), O (Aux_top (0,0,-1,true,DL)), M (U 3)), FBF (1, Psibar, SL, Psi), Half); ((M (U (-3)), O (Aux_top (0,0,1,false,DL)), M (D 3)), FBF (1, Psibar, SL, Psi), G_SL_DbtL) ] else [] let vertices3 = (ThoList.flatmap electromagnetic_currents [1;2;3] @ ThoList.flatmap color_currents [1;2;3] @ ThoList.flatmap neutral_currents [1;2;3] @ (if Flags.ckm_present then charged_currents_ckm else charged_currents_triv) @ yukawa @ triple_gauge @ gauge_higgs @ higgs @ higgs_triangle_vertices @ goldstone_vertices @ rsigma3 @ rsigma3t @ rphi3 @ ( if Flags.cf_arbitrary then ( rt3cf @ rff3cf @ rfv3cf @ rfphi3cf @ rfddphi3cf ) else (rf3 @ rt3 ) ) @ rf3t @ ( if Flags.higgs_matrix then (rsigma3h @ rff3h ) else [] ) @ anomalous_ttA @ anomalous_bbA @ anomalous_ttZ @ anomalous_bbZ @ anomalous_tbW @ anomalous_tbWA @ anomalous_tbWZ @ anomalous_ttWW @ anomalous_bbWW @ anomalous_ttG @ anomalous_ttGG @ anomalous_ttH @ anomalous_top_qGuG @ anomalous_top_qBuB @ anomalous_top_qW @ anomalous_top_DuDd) let vertices4 = quartic_gauge @ gauge_higgs4 @ higgs4 let vertices () = (vertices3, vertices4, []) (* For efficiency, make sure that [F.of_vertices vertices] is evaluated only once. *) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 let flavor_of_string = function | "e-" -> M (L 1) | "e+" -> M (L (-1)) | "mu-" -> M (L 2) | "mu+" -> M (L (-2)) | "tau-" -> M (L 3) | "tau+" -> M (L (-3)) | "nue" -> M (N 1) | "nuebar" -> M (N (-1)) | "numu" -> M (N 2) | "numubar" -> M (N (-2)) | "nutau" -> M (N 3) | "nutaubar" -> M (N (-3)) | "u" -> M (U 1) | "ubar" -> M (U (-1)) | "c" -> M (U 2) | "cbar" -> M (U (-2)) | "t" -> M (U 3) | "tbar" -> M (U (-3)) | "d" -> M (D 1) | "dbar" -> M (D (-1)) | "s" -> M (D 2) | "sbar" -> M (D (-2)) | "b" -> M (D 3) | "bbar" -> M (D (-3)) | "g" | "gl" -> G Gl | "A" -> G Ga | "Z" | "Z0" -> G Z | "W+" -> G Wp | "W-" -> G Wm | "H" -> O H | "Rsigma" -> O Rsigma | "Rphi0" -> O Rphin | "Rphis0" -> O Rphisn | "Rphi+" -> O Rphip | "Rphi-" -> O Rphim | "Rphi++" -> O Rphip | "Rphi--" -> O Rphimm | "Rf" -> O Rf | "Rff" -> O Rff | "Rfv" -> O Rfv | "Rfphi" -> O Rfphi | "Rt0" -> O Rtn | "Rts0" -> O Rtsn | "Rt+" -> O Rtp | "Rt-" -> O Rtm | "Rt++" -> O Rtp | "Rt--" -> O Rtmm | "Aux_t_ttGG0" -> O (Aux_top (2,1, 0,true,TTGG)) | "Aux_ttGG0" -> O (Aux_top (2,1, 0,false,TTGG)) | "Aux_t_tbWA+" -> O (Aux_top (2,0, 1,true,TBWA)) | "Aux_tbWA+" -> O (Aux_top (2,0, 1,false,TBWA)) | "Aux_t_tbWA-" -> O (Aux_top (2,0,-1,true,TBWA)) | "Aux_tbWA-" -> O (Aux_top (2,0,-1,false,TBWA)) | "Aux_t_tbWZ+" -> O (Aux_top (2,0, 1,true,TBWZ)) | "Aux_tbWZ+" -> O (Aux_top (2,0, 1,false,TBWZ)) | "Aux_t_tbWZ-" -> O (Aux_top (2,0,-1,true,TBWZ)) | "Aux_tbWZ-" -> O (Aux_top (2,0,-1,false,TBWZ)) | "Aux_t_ttWW0" -> O (Aux_top (2,0, 0,true,TTWW)) | "Aux_ttWW0" -> O (Aux_top (2,0, 0,false,TTWW)) | "Aux_t_bbWW0" -> O (Aux_top (2,0, 0,true,BBWW)) | "Aux_bbWW0" -> O (Aux_top (2,0, 0,false,BBWW)) | "Aux_t_qGuG0" -> O (Aux_top (1,1, 0,true,QGUG)) | "Aux_qGuG0" -> O (Aux_top (1,1, 0,false,QGUG)) | "Aux_t_qBuB0" -> O (Aux_top (1,0, 0,true,QBUB)) | "Aux_qBuB0" -> O (Aux_top (1,0, 0,false,QBUB)) | "Aux_t_qW0" -> O (Aux_top (1,0, 0,true,QW)) | "Aux_qW0" -> O (Aux_top (1,0, 0,false,QW)) | "Aux_t_qW+" -> O (Aux_top (1,0, 1,true,QW)) | "Aux_qW+" -> O (Aux_top (1,0, 1,false,QW)) | "Aux_t_qW-" -> O (Aux_top (1,0,-1,true,QW)) | "Aux_qW-" -> O (Aux_top (1,0,-1,false,QW)) | "Aux_t_dL0" -> O (Aux_top (0,0, 0,true,DL)) | "Aux_dL0" -> O (Aux_top (0,0, 0,false,DL)) | "Aux_t_dL+" -> O (Aux_top (0,0, 1,true,DL)) | "Aux_dL+" -> O (Aux_top (0,0, 1,false,DL)) | "Aux_t_dL-" -> O (Aux_top (0,0,-1,true,DL)) | "Aux_dL-" -> O (Aux_top (0,0,-1,false,DL)) | "Aux_t_dR0" -> O (Aux_top (0,0, 0,true,DR)) | "Aux_dR0" -> O (Aux_top (0,0, 0,false,DR)) | "Aux_t_dR+" -> O (Aux_top (0,0, 1,true,DR)) | "Aux_dR+" -> O (Aux_top (0,0, 1,false,DR)) | "Aux_t_dR-" -> O (Aux_top (0,0,-1,true,DR)) | "Aux_dR-" -> O (Aux_top (0,0,-1,false,DR)) | _ -> invalid_arg "Modellib_BSM.SSC_AltT.flavor_of_string" let flavor_to_string = function | M f -> begin match f with | L 1 -> "e-" | L (-1) -> "e+" | L 2 -> "mu-" | L (-2) -> "mu+" | L 3 -> "tau-" | L (-3) -> "tau+" | L _ -> invalid_arg "Modellib_BSM.SSC_AltT.flavor_to_string: invalid lepton" | N 1 -> "nue" | N (-1) -> "nuebar" | N 2 -> "numu" | N (-2) -> "numubar" | N 3 -> "nutau" | N (-3) -> "nutaubar" | N _ -> invalid_arg "Modellib_BSM.SSC_AltT.flavor_to_string: invalid neutrino" | U 1 -> "u" | U (-1) -> "ubar" | U 2 -> "c" | U (-2) -> "cbar" | U 3 -> "t" | U (-3) -> "tbar" | U _ -> invalid_arg "Modellib_BSM.SSC_AltT.flavor_to_string: invalid up type quark" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | D _ -> invalid_arg "Modellib_BSM.SSC_AltT.flavor_to_string: invalid down type quark" end | G f -> begin match f with | Gl -> "gl" | Ga -> "A" | Z -> "Z" | Wp -> "W+" | Wm -> "W-" end | O f -> begin match f with | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | H -> "H" | Rsigma -> "Rsigma" | Rphin -> "Rphin" | Rphip -> "Rphi+" | Rphim -> "Rphi-" | Rphipp -> "Rphi++" | Rphimm -> "Rphi--" | Rphisn -> "Rphisn" | Rf -> "Rf" | Rff -> "Rff" | Rfv -> "Rfv" | Rfphi -> "Rfphi" | Rtn -> "Rtn" | Rtsn -> "Rtsn" | Rtp -> "Rt+" | Rtm -> "Rt-" | Rtpp -> "Rt++" | Rtmm -> "Rt--" | Aux_top (_,_,ch,n,v) -> "Aux_" ^ (if n then "t_" else "") ^ ( begin match v with | TTGG -> "ttGG" | TBWA -> "tbWA" | TBWZ -> "tbWZ" | TTWW -> "ttWW" | BBWW -> "bbWW" | QGUG -> "qGuG" | QBUB -> "qBuB" | QW -> "qW" | DL -> "dL" | DR -> "dR" end ) ^ ( if ch > 0 then "+" else if ch < 0 then "-" else "0" ) end let flavor_to_TeX = function | M f -> begin match f with | L 1 -> "e^-" | L (-1) -> "e^+" | L 2 -> "\\mu^-" | L (-2) -> "\\mu^+" | L 3 -> "\\tau^-" | L (-3) -> "\\tau^+" | L _ -> invalid_arg "Modellib_BSM.SSC_AltT.flavor_to_TeX: invalid lepton" | N 1 -> "\\nu_e" | N (-1) -> "\\bar{\\nu}_e" | N 2 -> "\\nu_\\mu" | N (-2) -> "\\bar{\\nu}_\\mu" | N 3 -> "\\nu_\\tau" | N (-3) -> "\\bar{\\nu}_\\tau" | N _ -> invalid_arg "Modellib_BSM.SSC_AltT.flavor_to_TeX: invalid neutrino" | U 1 -> "u" | U (-1) -> "\\bar{u}" | U 2 -> "c" | U (-2) -> "\\bar{c}" | U 3 -> "t" | U (-3) -> "\\bar{t}" | U _ -> invalid_arg "Modellib_BSM.SSC_AltT.flavor_to_TeX: invalid up type quark" | D 1 -> "d" | D (-1) -> "\\bar{d}" | D 2 -> "s" | D (-2) -> "\\bar{s}" | D 3 -> "b" | D (-3) -> "\\bar{b}" | D _ -> invalid_arg "Modellib_BSM.SSC_AltT.flavor_to_TeX: invalid down type quark" end | G f -> begin match f with | Gl -> "g" | Ga -> "\\gamma" | Z -> "Z" | Wp -> "W^+" | Wm -> "W^-" end | O f -> begin match f with | Phip -> "\\phi^+" | Phim -> "\\phi^-" | Phi0 -> "\\phi^0" | H -> "H" | Rsigma -> "\\sigma" | Rphip -> "\\phi^+" | Rphim -> "\\phi^-" | Rphin -> "\\phi^0" | Rphisn -> "\\phi_s^0" | Rphipp -> "\\phi^{++}" | Rphimm -> "\\phi^{--}" | Rf -> "f" | Rff -> "f^f" | Rfv -> "f^v" | Rfphi -> "f^s" | Rtp -> "t^+" | Rtm -> "t^-" | Rtn -> "t^0" | Rtsn -> "t_s^0" | Rtpp -> "t^{++}" | Rtmm -> "t^{--}" | Aux_top (_,_,ch,n,v) -> "\\textnormal{Aux_" ^ (if n then "t_" else "") ^ ( begin match v with | TTGG -> "ttGG" | TBWA -> "tbWA" | TBWZ -> "tbWZ" | TTWW -> "ttWW" | BBWW -> "bbWW" | QGUG -> "qGuG" | QBUB -> "qBuB" | QW -> "qW" | DL -> "dL" | DR -> "dR" end ) ^ ( if ch > 0 then "^+" else if ch < 0 then "^-" else "^0" ) ^ "}" end let flavor_symbol = function | M f -> begin match f with | L n when n > 0 -> "l" ^ string_of_int n | L n -> "l" ^ string_of_int (abs n) ^ "b" | N n when n > 0 -> "n" ^ string_of_int n | N n -> "n" ^ string_of_int (abs n) ^ "b" | U n when n > 0 -> "u" ^ string_of_int n | U n -> "u" ^ string_of_int (abs n) ^ "b" | D n when n > 0 -> "d" ^ string_of_int n | D n -> "d" ^ string_of_int (abs n) ^ "b" end | G f -> begin match f with | Gl -> "gl" | Ga -> "a" | Z -> "z" | Wp -> "wp" | Wm -> "wm" end | O f -> begin match f with | Phip -> "pp" | Phim -> "pm" | Phi0 -> "p0" | H -> "h" | Rsigma -> "rsi" | Rphip -> "rpp" | Rphim -> "rpm" | Rphin -> "rpn" | Rphisn -> "rpsn" | Rphipp -> "rppp" | Rphimm -> "rpmm" | Rf -> "rf" | Rff -> "rff" | Rfv -> "rfv" | Rfphi -> "rfphi" | Rtp -> "rtp" | Rtm -> "rtm" | Rtn -> "rtn" | Rtsn -> "rtsn" | Rtpp -> "rtpp" | Rtmm -> "rtmm" | Aux_top (_,_,ch,n,v) -> "aux_" ^ (if n then "t_" else "") ^ ( begin match v with | TTGG -> "ttgg" | TBWA -> "tbwa" | TBWZ -> "tbwz" | TTWW -> "ttww" | BBWW -> "bbww" | QGUG -> "qgug" | QBUB -> "qbub" | QW -> "qw" | DL -> "dl" | DR -> "dr" end ) ^ "_" ^ ( if ch > 0 then "p" else if ch < 0 then "m" else "0" ) end (* Introducing new Resonances from 45, there are no PDG values *) let pdg = function | M f -> begin match f with | L n when n > 0 -> 9 + 2*n | L n -> - 9 + 2*n | N n when n > 0 -> 10 + 2*n | N n -> - 10 + 2*n | U n when n > 0 -> 2*n | U n -> 2*n | D n when n > 0 -> - 1 + 2*n | D n -> 1 + 2*n end | G f -> begin match f with | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) end | O f -> begin match f with | Phip | Phim -> 27 | Phi0 -> 26 | H -> 25 | Rsigma -> 45 | Rphin -> 46 | Rphip | Rphim -> 47 | Rphipp | Rphimm -> 48 | Rphisn -> 49 | Rf -> 52 | Rtn -> 53 | Rtp | Rtm -> 54 | Rtpp | Rtmm -> 55 | Rff -> 56 | Rfv -> 57 | Rfphi -> 58 | Rtsn -> 59 | Aux_top (_,_,_,_,_) -> 81 end let mass_symbol f = "mass(" ^ string_of_int (abs (pdg f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg f)) ^ ")" let constant_symbol = function | Unit -> "unit" | Half -> "half" | Pi -> "PI" | Alpha_QED -> "alpha" | E -> "e" | G_weak -> "g" | Vev -> "vev" | I_G_weak -> "ig" | Sin2thw -> "sin2thw" | Sinthw -> "sinthw" | Costhw -> "costhw" | Q_lepton -> "qlep" | Q_up -> "qup" | Q_down -> "qdwn" | G_NC_lepton -> "gnclep" | G_NC_neutrino -> "gncneu" | G_NC_up -> "gncup" | G_NC_down -> "gncdwn" | G_TVA_ttA -> "gtva_tta" | G_TVA_bbA -> "gtva_bba" | G_VLR_ttZ -> "gvlr_ttz" | G_TVA_ttZ -> "gtva_ttz" | G_TVA_bbZ -> "gtva_bbz" | G_VLR_btW -> "gvlr_btw" | G_VLR_tbW -> "gvlr_tbw" | G_TLR_btW -> "gtlr_btw" | G_TRL_tbW -> "gtrl_tbw" | G_TLR_btWA -> "gtlr_btwa" | G_TRL_tbWA -> "gtrl_tbwa" | G_TLR_btWZ -> "gtlr_btwz" | G_TRL_tbWZ -> "gtrl_tbwz" | G_TVA_ttWW -> "gtva_ttww" | G_TVA_bbWW -> "gtva_bbww" | G_TVA_ttG -> "gtva_ttg" | G_TVA_ttGG -> "gtva_ttgg" | G_SP_ttH -> "gsp_tth" | G_VLR_qGuG -> "gvlr_qgug" | G_VLR_qBuB -> "gvlr_qbub" | G_VLR_qBuB_u -> "gvlr_qbub_u" | G_VLR_qBuB_d -> "gvlr_qbub_d" | G_VLR_qBuB_e -> "gvlr_qbub_e" | G_VL_qBuB_n -> "gvl_qbub_n" | G_VL_qW -> "gvl_qw" | G_VL_qW_u -> "gvl_qw_u" | G_VL_qW_d -> "gvl_qw_d" | G_SL_DttR -> "gsl_dttr" | G_SR_DttR -> "gsr_dttr" | G_SL_DttL -> "gsl_dttl" | G_SLR_DbtR -> "gslr_dbtr" | G_SL_DbtL -> "gsl_dbtl" | G_CC -> "gcc" | G_CCQ (n1,n2) -> "gccq" ^ string_of_int n1 ^ string_of_int n2 | I_Q_W -> "iqw" | I_G_ZWW -> "igzww" | G_WWWW -> "gw4" | G_ZZWW -> "gzzww" | G_AZWW -> "gazww" | G_AAWW -> "gaaww" | I_G1_AWW -> "ig1a" | I_G1_ZWW -> "ig1z" | I_G1_plus_kappa_plus_G4_AWW -> "ig1pkpg4a" | I_G1_plus_kappa_plus_G4_ZWW -> "ig1pkpg4z" | I_G1_plus_kappa_minus_G4_AWW -> "ig1pkmg4a" | I_G1_plus_kappa_minus_G4_ZWW -> "ig1pkmg4z" | I_G1_minus_kappa_plus_G4_AWW -> "ig1mkpg4a" | I_G1_minus_kappa_plus_G4_ZWW -> "ig1mkpg4z" | I_G1_minus_kappa_minus_G4_AWW -> "ig1mkmg4a" | I_G1_minus_kappa_minus_G4_ZWW -> "ig1mkmg4z" | I_lambda_AWW -> "ila" | I_lambda_ZWW -> "ilz" | G5_AWW -> "rg5a" | G5_ZWW -> "rg5z" | I_kappa5_AWW -> "ik5a" | I_kappa5_ZWW -> "ik5z" | I_lambda5_AWW -> "il5a" | I_lambda5_ZWW -> "il5z" | Alpha_WWWW0 -> "alww0" | Alpha_WWWW2 -> "alww2" | Alpha_ZZWW0 -> "alzw0" | Alpha_ZZWW1 -> "alzw1" | Alpha_ZZZZ -> "alzz" | FT0_WWWW0 -> "at0ww0" | FT0_WWWW2 -> "at0ww2" | FT0_ZZWW0 -> "at0zw0" | FT0_ZZWW1 -> "at0zw1" | FT0_ZZZZ -> "at0zz" | FT0_AAAA -> "at0aa" | FT0_AAWW0 -> "at0aw0" | FT0_AAWW1 -> "at0aw1" | FT0_AAZZ -> "at0az" | FT0_AZWW0 -> "at0azw0" | FT0_AZWW1 -> "at0azw1" | FT0_AAAZ -> "at03az" | FT0_AZZZ -> "at0a3z" | FT1_WWWW0 -> "at1ww0" | FT1_WWWW2 -> "at1ww2" | FT1_ZZWW0 -> "at1zw0" | FT1_ZZWW1 -> "at1zw1" | FT1_ZZZZ -> "at1zz" | FT1_AAAA -> "at1aa" | FT1_AAWW0 -> "at1aw0" | FT1_AAWW1 -> "at1aw1" | FT1_AAZZ -> "at1az" | FT1_AZWW0 -> "at1azw0" | FT1_AZWW1 -> "at1azw1" | FT1_AAAZ -> "at13az" | FT1_AZZZ -> "at1a3z" | FT2_WWWW0 -> "at2ww0" | FT2_WWWW2 -> "at2ww2" | FT2_ZZWW0 -> "at2zw0" | FT2_ZZWW1 -> "at2zw1" | FT2_ZZZZ -> "at2zz" | FT2_AAAA -> "at2aa" | FT2_AAWW0 -> "at2aw0" | FT2_AAWW1 -> "at2aw1" | FT2_AAZZ -> "at2az" | FT2_AZWW0 -> "at2azw0" | FT2_AZWW1 -> "at2azw1" | FT2_AAAZ -> "at23az" | FT2_AZZZ -> "at2a3z" | FM0_WWWW0 -> "am0ww0,am0ww0" | FM0_WWWW2 -> "am0ww2,am0ww2" | FM0_ZZWW0 -> "am0zw0/costhw**2,am0zw0*costhw**2" | FM0_ZZWW1 -> "am0zw1/costhw**2,am0zw1*costhw**2" | FM0_ZZZZ -> "am0zz,am0zz" | FM1_WWWW0 -> "am1ww0,am1ww0" | FM1_WWWW2 -> "am1ww2,am1ww2" | FM1_ZZWW0 -> "am1zw0/costhw**2,am1zw0*costhw**2" | FM1_ZZWW1 -> "am1zw1/costhw**2,am1zw1*costhw**2" | FM1_ZZZZ -> "am1zz,am1zz" | FM7_WWWW0 -> "am7ww0,am7ww0,am7ww0" | FM7_WWWW2 -> "am7ww2,am7ww2,am7ww2" | FM7_ZZWW0 -> "am7zw0/costhw**2,am7zw0,am7zw0*costhw**2" | FM7_ZZWW1 -> "am7zw1/costhw**2,am7zw1,am7zw1*costhw**2" | FM7_ZZZZ -> "am7zz,am7zz,am7zz" | FS0_HHWW -> "fs0hhww" | FS0_HHZZ -> "fs0hhzz" | FS1_HHWW -> "fs1hhww" | FS1_HHZZ -> "fs1hhzz" | FS_H4 -> "fsh4" | FM0_HHWW -> "fm0hhww" | FM0_HHZZ -> "fm0hhzz" | FM1_HHWW -> "fm1hhww" | FM1_HHZZ -> "fm1hhzz" | FM7_HHWW -> "fm7hhww" | FM7_HHZZ -> "fm7hhzz" | D_Alpha_ZZWW0_S -> "dalzz0_s(gkm,mkm," | D_Alpha_ZZWW0_T -> "dalzz0_t(gkm,mkm," | D_Alpha_ZZWW1_S -> "dalzz1_s(gkm,mkm," | D_Alpha_ZZWW1_T -> "dalzz1_t(gkm,mkm," | D_Alpha_ZZWW1_U -> "dalzz1_u(gkm,mkm," | D_Alpha_WWWW0_S -> "dalww0_s(gkm,mkm," | D_Alpha_WWWW0_T -> "dalww0_t(gkm,mkm," | D_Alpha_WWWW0_U -> "dalww0_u(gkm,mkm," | D_Alpha_WWWW2_S -> "dalww2_s(gkm,mkm," | D_Alpha_WWWW2_T -> "dalww2_t(gkm,mkm," | D_Alpha_ZZZZ_S -> "dalz4_s(gkm,mkm," | D_Alpha_ZZZZ_T -> "dalz4_t(gkm,mkm," | D_FT0_ZZWW0_S -> "datzz0_s_0(gkm,mkm," | D_FT0_ZZWW0_T -> "datzz0_t_0(gkm,mkm," | D_FT0_ZZWW0_U -> "datzz0_u_0(gkm,mkm," | D_FT0_ZZWW1_S -> "datzz1_s_0(gkm,mkm," | D_FT0_ZZWW1_T -> "datzz1_t_0(gkm,mkm," | D_FT0_ZZWW1_U -> "datzz1_u_0(gkm,mkm," | D_FT0_WWWW0_S -> "datww0_s_0(gkm,mkm," | D_FT0_WWWW0_T -> "datww0_t_0(gkm,mkm," | D_FT0_WWWW0_U -> "datww0_u_0(gkm,mkm," | D_FT0_WWWW2_S -> "datww2_s_0(gkm,mkm," | D_FT0_WWWW2_T -> "datww2_t_0(gkm,mkm," | D_FT0_WWWW2_U -> "datww2_u_0(gkm,mkm," | D_FT0_ZZZZ_S -> "datz4_s_0(gkm,mkm," | D_FT0_ZZZZ_T -> "datz4_t_0(gkm,mkm," | D_FT0_ZZZZ_U -> "datz4_u_0(gkm,mkm," | D_FT0_AAAA_S -> "data4_s_0(gkm,mkm," | D_FT0_AAAA_T -> "data4_t_0(gkm,mkm," | D_FT0_AAAA_U -> "data4_u_0(gkm,mkm," | D_FT0_AAWW0_S -> "dataw0_s_0(gkm,mkm," | D_FT0_AAWW0_T -> "dataw0_t_0(gkm,mkm," | D_FT0_AAWW0_U -> "dataw0_u_0(gkm,mkm," | D_FT0_AAWW1_S -> "dataw1_s_0(gkm,mkm," | D_FT0_AAWW1_T -> "dataw1_t_0(gkm,mkm," | D_FT0_AAWW1_U -> "dataw1_u_0(gkm,mkm," | D_FT0_AAZZ_S -> "dataz_s_0(gkm,mkm," | D_FT0_AAZZ_T -> "dataz_t_0(gkm,mkm," | D_FT0_AAZZ_U -> "dataz_u_0(gkm,mkm," | D_FT0_AZWW0_S -> "datazw0_s_0(gkm,mkm," | D_FT0_AZWW0_T -> "datazw0_t_0(gkm,mkm," | D_FT0_AZWW0_U -> "datazw0_u_0(gkm,mkm," | D_FT0_AZWW1_S -> "datazw0_s_1(gkm,mkm," | D_FT0_AZWW1_T -> "datazw0_t_1(gkm,mkm," | D_FT0_AZWW1_U -> "datazw0_u_1(gkm,mkm," | D_FT0_AAAZ_S -> "dat3az_s_0(gkm,mkm," | D_FT0_AAAZ_T -> "dat3az_t_0(gkm,mkm," | D_FT0_AAAZ_U -> "dat3az_u_0(gkm,mkm," | D_FT0_AZZZ_S -> "data3z_s_0(gkm,mkm," | D_FT0_AZZZ_T -> "data3z_t_0(gkm,mkm," | D_FT0_AZZZ_U -> "data3z_u_0(gkm,mkm," | D_FT1_ZZWW0_S -> "datzz0_s_1(gkm,mkm," | D_FT1_ZZWW0_T -> "datzz0_t_1(gkm,mkm," | D_FT1_ZZWW0_U -> "datzz0_u_1(gkm,mkm," | D_FT1_ZZWW1_S -> "datzz1_s_1(gkm,mkm," | D_FT1_ZZWW1_T -> "datzz1_t_1(gkm,mkm," | D_FT1_ZZWW1_U -> "datzz1_u_1(gkm,mkm," | D_FT1_WWWW0_S -> "datww0_s_1(gkm,mkm," | D_FT1_WWWW0_T -> "datww0_t_1(gkm,mkm," | D_FT1_WWWW0_U -> "datww0_u_1(gkm,mkm," | D_FT1_WWWW2_S -> "datww2_s_1(gkm,mkm," | D_FT1_WWWW2_T -> "datww2_t_1(gkm,mkm," | D_FT1_WWWW2_U -> "datww2_u_1(gkm,mkm," | D_FT1_ZZZZ_S -> "datz4_s_1(gkm,mkm," | D_FT1_ZZZZ_T -> "datz4_t_1(gkm,mkm," | D_FT1_ZZZZ_U -> "datz4_u_1(gkm,mkm," | D_FT1_AAAA_S -> "data4_s_1(gkm,mkm," | D_FT1_AAAA_T -> "data4_t_1(gkm,mkm," | D_FT1_AAAA_U -> "data4_u_1(gkm,mkm," | D_FT1_AAWW0_S -> "dataw0_s_1(gkm,mkm," | D_FT1_AAWW0_T -> "dataw0_t_1(gkm,mkm," | D_FT1_AAWW0_U -> "dataw0_u_1(gkm,mkm," | D_FT1_AAWW1_S -> "dataw1_s_1(gkm,mkm," | D_FT1_AAWW1_T -> "dataw1_t_1(gkm,mkm," | D_FT1_AAWW1_U -> "dataw1_u_1(gkm,mkm," | D_FT1_AAZZ_S -> "dataz_s_1(gkm,mkm," | D_FT1_AAZZ_T -> "dataz_t_1(gkm,mkm," | D_FT1_AAZZ_U -> "dataz_u_1(gkm,mkm," | D_FT1_AZWW0_S -> "datazw0_s_1(gkm,mkm," | D_FT1_AZWW0_T -> "datazw0_t_1(gkm,mkm," | D_FT1_AZWW0_U -> "datazw0_u_1(gkm,mkm," | D_FT1_AZWW1_S -> "datazw1_s_1(gkm,mkm," | D_FT1_AZWW1_T -> "datazw1_t_1(gkm,mkm," | D_FT1_AZWW1_U -> "datazw1_u_1(gkm,mkm," | D_FT1_AAAZ_S -> "dat3az_s_1(gkm,mkm," | D_FT1_AAAZ_T -> "dat3az_t_1(gkm,mkm," | D_FT1_AAAZ_U -> "dat3az_u_1(gkm,mkm," | D_FT1_AZZZ_S -> "data3z_s_1(gkm,mkm," | D_FT1_AZZZ_T -> "data3z_t_1(gkm,mkm," | D_FT1_AZZZ_U -> "data3z_u_1(gkm,mkm," | D_FT2_ZZWW0_S -> "datzz0_s_2(gkm,mkm," | D_FT2_ZZWW0_T -> "datzz0_t_2(gkm,mkm," | D_FT2_ZZWW0_U -> "datzz0_u_2(gkm,mkm," | D_FT2_ZZWW1_S -> "datzz1_s_2(gkm,mkm," | D_FT2_ZZWW1_T -> "datzz1_t_2(gkm,mkm," | D_FT2_ZZWW1_U -> "datzz1_u_2(gkm,mkm," | D_FT2_WWWW0_S -> "datww0_s_2(gkm,mkm," | D_FT2_WWWW0_T -> "datww0_t_2(gkm,mkm," | D_FT2_WWWW0_U -> "datww0_u_2(gkm,mkm," | D_FT2_WWWW2_S -> "datww2_s_2(gkm,mkm," | D_FT2_WWWW2_T -> "datww2_t_2(gkm,mkm," | D_FT2_WWWW2_U -> "datww2_u_2(gkm,mkm," | D_FT2_ZZZZ_S -> "datz4_s_2(gkm,mkm," | D_FT2_ZZZZ_T -> "datz4_t_2(gkm,mkm," | D_FT2_ZZZZ_U -> "datz4_u_2(gkm,mkm," | D_FT2_AAAA_S -> "data4_s_2(gkm,mkm," | D_FT2_AAAA_T -> "data4_t_2(gkm,mkm," | D_FT2_AAAA_U -> "data4_u_2(gkm,mkm," | D_FT2_AAWW0_S -> "dataw0_s_2(gkm,mkm," | D_FT2_AAWW0_T -> "dataw0_t_2(gkm,mkm," | D_FT2_AAWW0_U -> "dataw0_u_2(gkm,mkm," | D_FT2_AAWW1_S -> "dataw1_s_2(gkm,mkm," | D_FT2_AAWW1_T -> "dataw1_t_2(gkm,mkm," | D_FT2_AAWW1_U -> "dataw1_u_2(gkm,mkm," | D_FT2_AAZZ_S -> "dataz_s_2(gkm,mkm," | D_FT2_AAZZ_T -> "dataz_t_2(gkm,mkm," | D_FT2_AAZZ_U -> "dataz_u_2(gkm,mkm," | D_FT2_AZWW0_S -> "datazw0_s_2(gkm,mkm," | D_FT2_AZWW0_T -> "datazw0_t_2(gkm,mkm," | D_FT2_AZWW0_U -> "datazw0_u_2(gkm,mkm," | D_FT2_AZWW1_S -> "datazw1_s_2(gkm,mkm," | D_FT2_AZWW1_T -> "datazw1_t_2(gkm,mkm," | D_FT2_AZWW1_U -> "datazw1_u_2(gkm,mkm," | D_FT2_AAAZ_S -> "dat3az_s_2(gkm,mkm," | D_FT2_AAAZ_T -> "dat3az_t_2(gkm,mkm," | D_FT2_AAAZ_U -> "dat3az_u_2(gkm,mkm," | D_FT2_AZZZ_S -> "data3z_s_2(gkm,mkm," | D_FT2_AZZZ_T -> "data3z_t_2(gkm,mkm," | D_FT2_AZZZ_U -> "data3z_u_2(gkm,mkm," | D_FTrsi_ZZWW0_S -> "datzz0_s_rsi(gkm,mkm," | D_FTrsi_ZZWW0_T -> "datzz0_t_rsi(gkm,mkm," | D_FTrsi_ZZWW0_U -> "datzz0_u_rsi(gkm,mkm," | D_FTrsi_ZZWW1_S -> "datzz1_s_rsi(gkm,mkm," | D_FTrsi_ZZWW1_T -> "datzz1_t_rsi(gkm,mkm," | D_FTrsi_ZZWW1_U -> "datzz1_u_rsi(gkm,mkm," | D_FTrsi_WWWW0_S -> "datww0_s_rsi(gkm,mkm," | D_FTrsi_WWWW0_T -> "datww0_t_rsi(gkm,mkm," | D_FTrsi_WWWW0_U -> "datww0_u_rsi(gkm,mkm," | D_FTrsi_WWWW2_S -> "datww2_s_rsi(gkm,mkm," | D_FTrsi_WWWW2_T -> "datww2_t_rsi(gkm,mkm," | D_FTrsi_WWWW2_U -> "datww2_u_rsi(gkm,mkm," | D_FTrsi_ZZZZ_S -> "datz4_s_rsi(gkm,mkm," | D_FTrsi_ZZZZ_T -> "datz4_t_rsi(gkm,mkm," | D_FTrsi_ZZZZ_U -> "datz4_u_rsi(gkm,mkm," | D_FTrsi_AAAA_S -> "data4_s_rsi(gkm,mkm," | D_FTrsi_AAAA_T -> "data4_t_rsi(gkm,mkm," | D_FTrsi_AAAA_U -> "data4_u_rsi(gkm,mkm," | D_FTrsi_AAWW0_S -> "dataw0_s_rsi(gkm,mkm," | D_FTrsi_AAWW0_T -> "dataw0_t_rsi(gkm,mkm," | D_FTrsi_AAWW0_U -> "dataw0_u_rsi(gkm,mkm," | D_FTrsi_AAWW1_S -> "dataw1_s_rsi(gkm,mkm," | D_FTrsi_AAWW1_T -> "dataw1_t_rsi(gkm,mkm," | D_FTrsi_AAWW1_U -> "dataw1_u_rsi(gkm,mkm," | D_FTrsi_AAZZ_S -> "dataz_s_rsi(gkm,mkm," | D_FTrsi_AAZZ_T -> "dataz_t_rsi(gkm,mkm," | D_FTrsi_AAZZ_U -> "dataz_u_rsi(gkm,mkm," | D_FTrsi_AZWW0_S -> "datazw0_s_rsi(gkm,mkm," | D_FTrsi_AZWW0_T -> "datazw0_t_rsi(gkm,mkm," | D_FTrsi_AZWW0_U -> "datazw0_u_rsi(gkm,mkm," | D_FTrsi_AZWW1_S -> "datazw1_s_rsi(gkm,mkm," | D_FTrsi_AZWW1_T -> "datazw1_t_rsi(gkm,mkm," | D_FTrsi_AZWW1_U -> "datazw1_u_rsi(gkm,mkm," | D_FTrsi_AAAZ_S -> "dat3az_s_rsi(gkm,mkm," | D_FTrsi_AAAZ_T -> "dat3az_t_rsi(gkm,mkm," | D_FTrsi_AAAZ_U -> "dat3az_u_rsi(gkm,mkm," | D_FTrsi_AZZZ_S -> "data3z_s_rsi(gkm,mkm," | D_FTrsi_AZZZ_T -> "data3z_t_rsi(gkm,mkm," | D_FTrsi_AZZZ_U -> "data3z_u_rsi(gkm,mkm," | D_FM0_ZZWW0_S -> "damzz0_s_0(gkm,mkm," | D_FM0_ZZWW0_T -> "damzz0_t_0(gkm,mkm," | D_FM0_ZZWW0_U -> "damzz0_u_0(gkm,mkm," | D_FM0_ZZWW1_S -> "damzz1_s_0(gkm,mkm," | D_FM0_ZZWW1_T -> "damzz1_t_0(gkm,mkm," | D_FM0_ZZWW1_U -> "damzz1_u_0(gkm,mkm," | D_FM0_WWWW0_S -> "damww0_s_0(gkm,mkm," | D_FM0_WWWW0_T -> "damww0_t_0(gkm,mkm," | D_FM0_WWWW0_U -> "damww0_u_0(gkm,mkm," | D_FM0_WWWW2_S -> "damww2_s_0(gkm,mkm," | D_FM0_WWWW2_T -> "damww2_t_0(gkm,mkm," | D_FM0_WWWW2_U -> "damww2_u_0(gkm,mkm," | D_FM0_ZZZZ_S -> "damz4_s_0(gkm,mkm," | D_FM0_ZZZZ_T -> "damz4_t_0(gkm,mkm," | D_FM0_ZZZZ_U -> "damz4_u_0(gkm,mkm," | D_FM1_ZZWW0_S -> "damzz0_s_1(gkm,mkm," | D_FM1_ZZWW0_T -> "damzz0_t_1(gkm,mkm," | D_FM1_ZZWW0_U -> "damzz0_u_1(gkm,mkm," | D_FM1_ZZWW1_S -> "damzz1_s_1(gkm,mkm," | D_FM1_ZZWW1_T -> "damzz1_t_1(gkm,mkm," | D_FM1_ZZWW1_U -> "damzz1_u_1(gkm,mkm," | D_FM1_WWWW0_S -> "damww0_s_1(gkm,mkm," | D_FM1_WWWW0_T -> "damww0_t_1(gkm,mkm," | D_FM1_WWWW0_U -> "damww0_u_1(gkm,mkm," | D_FM1_WWWW2_S -> "damww2_s_1(gkm,mkm," | D_FM1_WWWW2_T -> "damww2_t_1(gkm,mkm," | D_FM1_WWWW2_U -> "damww2_u_1(gkm,mkm," | D_FM1_ZZZZ_S -> "damz4_s_1(gkm,mkm," | D_FM1_ZZZZ_T -> "damz4_t_1(gkm,mkm," | D_FM1_ZZZZ_U -> "damz4_u_1(gkm,mkm," | D_FM7_ZZWW0_S -> "damzz0_s_7(gkm,mkm," | D_FM7_ZZWW0_T -> "damzz0_t_7(gkm,mkm," | D_FM7_ZZWW0_U -> "damzz0_u_7(gkm,mkm," | D_FM7_ZZWW1_S -> "damzz1_s_7(gkm,mkm," | D_FM7_ZZWW1_T -> "damzz1_t_7(gkm,mkm," | D_FM7_ZZWW1_U -> "damzz1_u_7(gkm,mkm," | D_FM7_WWWW0_S -> "damww0_s_7(gkm,mkm," | D_FM7_WWWW0_T -> "damww0_t_7(gkm,mkm," | D_FM7_WWWW0_U -> "damww0_u_7(gkm,mkm," | D_FM7_WWWW2_S -> "damww2_s_7(gkm,mkm," | D_FM7_WWWW2_T -> "damww2_t_7(gkm,mkm," | D_FM7_WWWW2_U -> "damww2_u_7(gkm,mkm," | D_FM7_ZZZZ_S -> "damz4_s_7(gkm,mkm," | D_FM7_ZZZZ_T -> "damz4_t_7(gkm,mkm," | D_FM7_ZZZZ_U -> "damz4_u_7(gkm,mkm," | D_Alpha_HHHH_S -> "dalh4_s(gkm,mkm," | D_Alpha_HHHH_T -> "dalh4_t(gkm,mkm," | D_Alpha_HHWW0_S -> "dalhw0_s(gkm,mkm," | D_Alpha_HHWW0_T -> "dalhw0_t(gkm,mkm," | D_Alpha_HHZZ0_S -> "dalhz0_s(gkm,mkm," | D_Alpha_HHZZ0_T -> "dalhz0_t(gkm,mkm," | D_Alpha_HHWW1_S -> "dalhw1_s(gkm,mkm," | D_Alpha_HHWW1_T -> "dalhw1_t(gkm,mkm," | D_Alpha_HHWW1_U -> "dalhw1_u(gkm,mkm," | D_Alpha_HHZZ1_S -> "dalhz1_s(gkm,mkm," | D_Alpha_HHZZ1_T -> "dalhz1_t(gkm,mkm," | D_Alpha_HHZZ1_U -> "dalhz1_u(gkm,mkm," | D_FM0_HHWW0_S -> "damhw0_s_0(gkm,mkm," | D_FM0_HHWW0_T -> "damhw0_t_0(gkm,mkm," | D_FM0_HHWW0_U -> "damhw0_u_0(gkm,mkm," | D_FM0_HHZZ0_S -> "damhz0_s_0(gkm,mkm," | D_FM0_HHZZ0_T -> "damhz0_t_0(gkm,mkm," | D_FM0_HHZZ0_U -> "damhz0_u_0(gkm,mkm," | D_FM0_HHWW1_S -> "damhw1_s_0(gkm,mkm," | D_FM0_HHWW1_T -> "damhw1_t_0(gkm,mkm," | D_FM0_HHWW1_U -> "damhw1_u_0(gkm,mkm," | D_FM0_HHZZ1_S -> "damhz1_s_0(gkm,mkm," | D_FM0_HHZZ1_T -> "damhz1_t_0(gkm,mkm," | D_FM0_HHZZ1_U -> "damhz1_u_0(gkm,mkm," | D_FM1_HHWW0_S -> "damhw0_s_1(gkm,mkm," | D_FM1_HHWW0_T -> "damhw0_t_1(gkm,mkm," | D_FM1_HHWW0_U -> "damhw0_u_1(gkm,mkm," | D_FM1_HHZZ0_S -> "damhz0_s_1(gkm,mkm," | D_FM1_HHZZ0_T -> "damhz0_t_1(gkm,mkm," | D_FM1_HHZZ0_U -> "damhz0_u_1(gkm,mkm," | D_FM1_HHWW1_S -> "damhw1_s_1(gkm,mkm," | D_FM1_HHWW1_T -> "damhw1_t_1(gkm,mkm," | D_FM1_HHWW1_U -> "damhw1_u_1(gkm,mkm," | D_FM1_HHZZ1_S -> "damhz1_s_1(gkm,mkm," | D_FM1_HHZZ1_T -> "damhz1_t_1(gkm,mkm," | D_FM1_HHZZ1_U -> "damhz1_u_1(gkm,mkm," | D_FM7_HHWW0_S -> "damhw0_s_1(gkm,mkm," | D_FM7_HHWW0_T -> "damhw0_t_1(gkm,mkm," | D_FM7_HHWW0_U -> "damhw0_u_1(gkm,mkm," | D_FM7_HHZZ0_S -> "damhz0_s_1(gkm,mkm," | D_FM7_HHZZ0_T -> "damhz0_t_1(gkm,mkm," | D_FM7_HHZZ0_U -> "damhz0_u_1(gkm,mkm," | D_FM7_HHWW1_S -> "damhw1_s_1(gkm,mkm," | D_FM7_HHWW1_T -> "damhw1_t_1(gkm,mkm," | D_FM7_HHWW1_U -> "damhw1_u_1(gkm,mkm," | D_FM7_HHZZ1_S -> "damhz1_s_1(gkm,mkm," | D_FM7_HHZZ1_T -> "damhz1_t_1(gkm,mkm," | D_FM7_HHZZ1_U -> "damhz1_u_1(gkm,mkm," | G_HWW -> "ghww" | G_HZZ -> "ghzz" | G_HHWW -> "ghhww" | G_HHZZ -> "ghhzz" | G_SWW -> "gsww" | G_SZZ -> "gszz" | G_SHH -> "gshh" | G_SWW_T -> "gswwt" | G_SZZ_T -> "gszzt" | G_SAA_T -> "gsaat" | G_SAZ_T -> "gsazt" | G_PNWW -> "gpnww" | G_PNZZ -> "gpnzz" | G_PSNWW -> "gpsnww" | G_PSNZZ -> "gpsnzz" | G_PSNHH -> "gpsnhh" | G_PWZ -> "gpwz" | G_PWW -> "gpww" | G_FWW -> "gfww" | G_FZZ -> "gfzz" | G_FWW_CF -> "gfwwcf" | G_FZZ_CF -> "gfzzcf" | G_FHH -> "gfhh" | G_FHH_CF -> "gfhhcf" | G_FWW_T -> "gfwwt" | G_FZZ_T -> "gfzzt" | G_FFWW -> "gffww" | G_FFZZ -> "gffzz" | G_FFWW_CF -> "gffwwcf" | G_FFZZ_CF -> "gffzzcf" | G_FFHH -> "gffhh" | G_FFHH_CF -> "gffhhcf" | G_FVWW -> "gfvww" | G_FVZZ -> "gfvzz" | G_FVWW_CF -> "gfvwwcf" | G_FVZZ_CF -> "gfvzzcf" | G_FVHH -> "gfvhh" | G_FVHH_CF -> "gfvhhcf" | G_FDDSWW -> "gfddsww" | G_FDDSZZ -> "gfddszz" | G_FDDSWW_CF -> "gfddswwcf" | G_FDDSZZ_CF -> "gfddszzcf" | G_FDDSHH -> "gfddshh" | G_FDDSHH_CF -> "gfddshhcf" | G_FSWW -> "gfsww" | G_FSZZ -> "gfszz" | G_FSHH -> "gfshh" | G_TNWW -> "gtnww" | G_TNZZ -> "gtnzz" | G_TNWW_CF -> "gtnwwcf" | G_TNZZ_CF -> "gtnzzcf" | G_TSNWW -> "gtsnww" | G_TSNZZ -> "gtsnzz" | G_TSNWW_CF -> "gtsnwwcf" | G_TSNZZ_CF -> "gtsnzzcf" | G_TWZ -> "gtwz" | G_TWW -> "gtww" | G_TWZ_CF -> "gtwzcf" | G_TWW_CF -> "gtwwcf" | G_SSWW -> "gssww" | G_SSZZ -> "gsszz" | G_Htt -> "ghtt" | G_Hbb -> "ghbb" | G_Htautau -> "ghtautau" | G_Hcc -> "ghcc" | G_Hmm -> "ghmm" | G_HGaZ -> "ghgaz" | G_HGaGa -> "ghgaga" | G_Hgg -> "ghgg" | G_HGaGa_anom -> "ghgaga_ac" | G_HGaZ_anom -> "ghgaz_ac" | G_HZZ_anom -> "ghzz_ac" | G_HWW_anom -> "ghww_ac" | G_HGaZ_u -> "ghgaz_u" | G_HZZ_u -> "ghzz_u" | G_HWW_u -> "ghww_u" | G_H3 -> "gh3" | G_H4 -> "gh4" | Gs -> "gs" | I_Gs -> "igs" | G2 -> "gs**2" | Mass f -> "mass" ^ flavor_symbol f | Width f -> "width" ^ flavor_symbol f | K_Matrix_Coeff i -> "kc" ^ string_of_int i | K_Matrix_Pole i -> "kp" ^ string_of_int i end Index: trunk/omega/src/omega_SM_top.ml =================================================================== --- trunk/omega/src/omega_SM_top.ml (revision 8413) +++ trunk/omega/src/omega_SM_top.ml (revision 8414) @@ -1,626 +1,628 @@ (* omega_SM_top.ml -- Copyright (C) 1999-2020 by Wolfgang Kilian Thorsten Ohl Juergen Reuter with contributions from Christian Speckner WHIZARD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. WHIZARD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *) (* \thocwmodulesection{SM with charge $4/3$ top} *) module type SM_flags = sig val include_anomalous : bool val k_matrix : bool end module SM_no_anomalous : SM_flags = struct let include_anomalous = false let k_matrix = false end module SM_gluons : SM_flags = struct let include_anomalous = false let k_matrix = false end module Anomtop (Flags : SM_flags) = struct open Coupling let default_width = ref Timelike let use_fudged_width = ref false let options = Options.create [ "constant_width", Arg.Unit (fun () -> default_width := Constant), "use constant width (also in t-channel)"; "fudged_width", Arg.Set use_fudged_width, "use fudge factor for charge particle width"; "custom_width", Arg.String (fun f -> default_width := Custom f), "use custom width"; "cancel_widths", Arg.Unit (fun () -> default_width := Vanishing), - "use vanishing width" ] + "use vanishing width"; + "running_width", Arg.Unit (fun () -> default_width := Running), + "use running width" ] type matter_field = L of int | N of int | U of int | D of int type gauge_boson = Ga | Wp | Wm | Z | Gl type other = Phip | Phim | Phi0 | H type flavor = M of matter_field | G of gauge_boson | O of other let matter_field f = M f let gauge_boson f = G f let other f = O f type field = | Matter of matter_field | Gauge of gauge_boson | Other of other let field = function | M f -> Matter f | G f -> Gauge f | O f -> Other f type gauge = unit let gauge_symbol () = failwith "Models.Anomtop.gauge_symbol: internal error" let family n = List.map matter_field [ L n; N n; U n; D n ] let external_flavors () = [ "1st Generation", ThoList.flatmap family [1; -1]; "2nd Generation", ThoList.flatmap family [2; -2]; "3rd Generation", ThoList.flatmap family [3; -3]; "Gauge Bosons", List.map gauge_boson [Ga; Z; Wp; Wm; Gl]; "Higgs", [O H]; "Goldstone Bosons", List.map other [Phip; Phim; Phi0] ] let flavors () = ThoList.flatmap snd (external_flavors ()) let spinor n = if n >= 0 then Spinor else ConjSpinor let lorentz = function | M f -> begin match f with | L n -> spinor n | N n -> spinor n | U n -> spinor n | D n -> spinor n end | G f -> begin match f with | Ga | Gl -> Vector | Wp | Wm | Z -> Massive_Vector end | O f -> Scalar let color = function | M (U n) -> Color.SUN (if n > 0 then 3 else -3) | M (D n) -> Color.SUN (if n > 0 then 3 else -3) | G Gl -> Color.AdjSUN 3 | _ -> Color.Singlet let nc () = 3 let prop_spinor n = if n >= 0 then Prop_Spinor else Prop_ConjSpinor let propagator = function | M f -> begin match f with | L n -> prop_spinor n | N n -> prop_spinor n | U n -> prop_spinor n | D n -> prop_spinor n end | G f -> begin match f with | Ga | Gl -> Prop_Feynman | Wp | Wm | Z -> Prop_Unitarity end | O f -> begin match f with | Phip | Phim | Phi0 -> Only_Insertion | H -> Prop_Scalar end (* Optionally, ask for the fudge factor treatment for the widths of charged particles. Currently, this only applies to $W^\pm$ and top. *) let width f = if !use_fudged_width then match f with | G Wp | G Wm | M (U 3) | M (U (-3)) -> Fudged | _ -> !default_width else !default_width let goldstone = function | G f -> begin match f with | Wp -> Some (O Phip, Coupling.Integer 1) | Wm -> Some (O Phim, Coupling.Integer 1) | Z -> Some (O Phi0, Coupling.Integer 1) | _ -> None end | _ -> None let conjugate = function | M f -> M (begin match f with | L n -> L (-n) | N n -> N (-n) | U n -> U (-n) | D n -> D (-n) end) | G f -> G (begin match f with | Gl -> Gl | Ga -> Ga | Z -> Z | Wp -> Wm | Wm -> Wp end) | O f -> O (begin match f with | Phip -> Phim | Phim -> Phip | Phi0 -> Phi0 | H -> H end) let fermion = function | M f -> begin match f with | L n -> if n > 0 then 1 else -1 | N n -> if n > 0 then 1 else -1 | U n -> if n > 0 then 1 else -1 | D n -> if n > 0 then 1 else -1 end | G f -> begin match f with | Gl | Ga | Z | Wp | Wm -> 0 end | O _ -> 0 (* Electrical charge, lepton number, baryon number. We could avoid the rationals altogether by multiplying the first and last by 3 \ldots *) module Ch = Charges.QQ let ( // ) = Algebra.Small_Rational.make let generation' = function | 1 -> [ 1//1; 0//1; 0//1] | 2 -> [ 0//1; 1//1; 0//1] | 3 -> [ 0//1; 0//1; 1//1] | -1 -> [-1//1; 0//1; 0//1] | -2 -> [ 0//1; -1//1; 0//1] | -3 -> [ 0//1; 0//1; -1//1] | n -> invalid_arg ("SM_top.generation': " ^ string_of_int n) let generation f = match f with | M (L n | N n | U n | D n) -> generation' n | G _ | O _ -> [0//1; 0//1; 0//1] let charge = function | M f -> begin match f with | L n -> if n > 0 then -1//1 else 1//1 | N n -> 0//1 | U (1|2) -> 2//3 | U ((-1)|(-2)) -> -2//3 | U 3 -> -4//3 | U (-3) -> 4//3 | U n -> invalid_arg ("SM_top.charge: up quark " ^ string_of_int n) | D n -> if n > 0 then -1//3 else 1//3 end | G f -> begin match f with | Gl | Ga | Z -> 0//1 | Wp -> 1//1 | Wm -> -1//1 end | O f -> begin match f with | H | Phi0 -> 0//1 | Phip -> 1//1 | Phim -> -1//1 end let lepton = function | M f -> begin match f with | L n | N n -> if n > 0 then 1//1 else -1//1 | U _ | D _ -> 0//1 end | G _ | O _ -> 0//1 let baryon = function | M f -> begin match f with | L _ | N _ -> 0//1 | U n | D n -> if n > 0 then 1//1 else -1//1 end | G _ | O _ -> 0//1 let charges f = [ charge f; lepton f; baryon f] @ generation f type constant = | Unit | Pi | Alpha_QED | Sin2thw | Sinthw | Costhw | E | G_weak | Vev | Q_lepton | Q_up | Q_down | Q_top | G_CC | G_NC_neutrino | G_NC_lepton | G_NC_up | G_NC_down | G_NC_top | I_Q_W | I_G_ZWW | G_WWWW | G_ZZWW | G_AZWW | G_AAWW | G_HWW | G_HHWW | G_HZZ | G_HHZZ | G_Htt | G_Hbb | G_Hcc | G_Htautau | G_H3 | G_H4 | Gs | I_Gs | G2 | Mass of flavor | Width of flavor (* Two integer counters for the QCD and EW order of the couplings. *) type orders = int * int let orders = function | _ -> (0,0) let input_parameters = [] let derived_parameters = [] let derived_parameter_arrays = [] let parameters () = { input = input_parameters; derived = derived_parameters; derived_arrays = derived_parameter_arrays } module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) (* \begin{equation} \mathcal{L}_{\textrm{EM}} = - e \sum_i q_i \bar\psi_i\fmslash{A}\psi_i \end{equation} *) let mgm ((m1, g, m2), fbf, c) = ((M m1, G g, M m2), fbf, c) let electromagnetic_currents' n = List.map mgm [ ((L (-n), Ga, L n), FBF (1, Psibar, V, Psi), Q_lepton); ((D (-n), Ga, D n), FBF (1, Psibar, V, Psi), Q_down) ] let em_up_type_currents = List.map mgm [ ((U (-1), Ga, U 1), FBF (1, Psibar, V, Psi), Q_up); ((U (-2), Ga, U 2), FBF (1, Psibar, V, Psi), Q_up); ((U (-3), Ga, U 3), FBF (1, Psibar, V, Psi), Q_top)] let electromagnetic_currents = ThoList.flatmap electromagnetic_currents' [1;2;3] @ em_up_type_currents let color_currents n = List.map mgm [ ((U (-n), Gl, U n), FBF ((-1), Psibar, V, Psi), Gs); ((D (-n), Gl, D n), FBF ((-1), Psibar, V, Psi), Gs) ] (* \begin{equation} \mathcal{L}_{\textrm{NC}} = - \frac{g}{2\cos\theta_W} \sum_i \bar\psi_i\fmslash{Z}(g_V^i-g_A^i\gamma_5)\psi_i \end{equation} *) let neutral_currents' n = List.map mgm [ ((L (-n), Z, L n), FBF (1, Psibar, VA, Psi), G_NC_lepton); ((N (-n), Z, N n), FBF (1, Psibar, VA, Psi), G_NC_neutrino); ((D (-n), Z, D n), FBF (1, Psibar, VA, Psi), G_NC_down) ] let neutral_up_type_currents = List.map mgm [ ((U (-1), Z, U 1), FBF (1, Psibar, VA, Psi), G_NC_up); ((U (-2), Z, U 2), FBF (1, Psibar, VA, Psi), G_NC_up); ((U (-3), Z, U 3), FBF (1, Psibar, VA, Psi), G_NC_top) ] let neutral_currents = ThoList.flatmap neutral_currents' [1;2;3] @ neutral_up_type_currents (* \begin{equation} \mathcal{L}_{\textrm{CC}} = - \frac{g}{2\sqrt2} \sum_i \bar\psi_i (T^+\fmslash{W}^+ + T^-\fmslash{W}^-)(1-\gamma_5)\psi_i \end{equation} *) let charged_currents' n = List.map mgm [ ((L (-n), Wm, N n), FBF (1, Psibar, VL, Psi), G_CC); ((N (-n), Wp, L n), FBF (1, Psibar, VL, Psi), G_CC) ] let charged_up_currents = List.map mgm [ ((U (-1), Wp, D 1), FBF (1, Psibar, VL, Psi), G_CC); ((U (-2), Wp, D 2), FBF (1, Psibar, VL, Psi), G_CC); ((U (-3), Wm, D 3), FBF (1, Psibar, VL, Psi), G_CC); ((D (-1), Wm, U 1), FBF (1, Psibar, VL, Psi), G_CC); ((D (-2), Wm, U 2), FBF (1, Psibar, VL, Psi), G_CC); ((D (-3), Wp, U 3), FBF (1, Psibar, VL, Psi), G_CC) ] let charged_currents = ThoList.flatmap charged_currents' [1;2;3] @ charged_up_currents let yukawa = [ ((M (U (-3)), O H, M (U 3)), FBF (1, Psibar, S, Psi), G_Htt); ((M (D (-3)), O H, M (D 3)), FBF (1, Psibar, S, Psi), G_Hbb); ((M (U (-2)), O H, M (U 2)), FBF (1, Psibar, S, Psi), G_Hcc); ((M (L (-3)), O H, M (L 3)), FBF (1, Psibar, S, Psi), G_Htautau) ] (* \begin{equation} \mathcal{L}_{\textrm{TGC}} = - e \partial_\mu A_\nu W_+^\mu W_-^\nu + \ldots - e \cot\theta_w \partial_\mu Z_\nu W_+^\mu W_-^\nu + \ldots \end{equation} *) let tgc ((g1, g2, g3), t, c) = ((G g1, G g2, G g3), t, c) let triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW); ((Gl, Gl, Gl), Gauge_Gauge_Gauge 1, I_Gs)] let qgc ((g1, g2, g3, g4), t, c) = ((G g1, G g2, G g3, G g4), t, c) let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] let quartic_gauge = List.map qgc [ (Wm, Wp, Wm, Wp), gauge4, G_WWWW; (Wm, Z, Wp, Z), minus_gauge4, G_ZZWW; (Wm, Z, Wp, Ga), minus_gauge4, G_AZWW; (Wm, Ga, Wp, Ga), minus_gauge4, G_AAWW; (Gl, Gl, Gl, Gl), gauge4, G2 ] let gauge_higgs = [ ((O H, G Wp, G Wm), Scalar_Vector_Vector 1, G_HWW); ((O H, G Z, G Z), Scalar_Vector_Vector 1, G_HZZ) ] let gauge_higgs4 = [ (O H, O H, G Wp, G Wm), Scalar2_Vector2 1, G_HHWW; (O H, O H, G Z, G Z), Scalar2_Vector2 1, G_HHZZ ] let higgs = [ (O H, O H, O H), Scalar_Scalar_Scalar 1, G_H3 ] let higgs4 = [ (O H, O H, O H, O H), Scalar4 1, G_H4 ] let goldstone_vertices = [ ((O Phi0, G Wm, G Wp), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phip, G Ga, G Wm), Scalar_Vector_Vector 1, I_Q_W); ((O Phip, G Z, G Wm), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phim, G Wp, G Ga), Scalar_Vector_Vector 1, I_Q_W); ((O Phim, G Wp, G Z), Scalar_Vector_Vector 1, I_G_ZWW) ] let vertices3 = (electromagnetic_currents @ ThoList.flatmap color_currents [1;2;3] @ neutral_currents @ charged_currents @ yukawa @ triple_gauge @ gauge_higgs @ higgs @ goldstone_vertices) let vertices4 = quartic_gauge @ gauge_higgs4 @ higgs4 let vertices () = (vertices3, vertices4, []) (* For efficiency, make sure that [F.of_vertices vertices] is evaluated only once. *) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 let flavor_of_string = function | "e-" -> M (L 1) | "e+" -> M (L (-1)) | "mu-" -> M (L 2) | "mu+" -> M (L (-2)) | "tau-" -> M (L 3) | "tau+" -> M (L (-3)) | "nue" -> M (N 1) | "nuebar" -> M (N (-1)) | "numu" -> M (N 2) | "numubar" -> M (N (-2)) | "nutau" -> M (N 3) | "nutaubar" -> M (N (-3)) | "u" -> M (U 1) | "ubar" -> M (U (-1)) | "c" -> M (U 2) | "cbar" -> M (U (-2)) | "t" -> M (U 3) | "tbar" -> M (U (-3)) | "d" -> M (D 1) | "dbar" -> M (D (-1)) | "s" -> M (D 2) | "sbar" -> M (D (-2)) | "b" -> M (D 3) | "bbar" -> M (D (-3)) | "g" | "gl" -> G Gl | "A" -> G Ga | "Z" | "Z0" -> G Z | "W+" -> G Wp | "W-" -> G Wm | "H" -> O H | _ -> invalid_arg "Models.Anomtop.flavor_of_string" let flavor_to_string = function | M f -> begin match f with | L 1 -> "e-" | L (-1) -> "e+" | L 2 -> "mu-" | L (-2) -> "mu+" | L 3 -> "tau-" | L (-3) -> "tau+" | L _ -> invalid_arg "Models.Anomtop.flavor_to_string: invalid lepton" | N 1 -> "nue" | N (-1) -> "nuebar" | N 2 -> "numu" | N (-2) -> "numubar" | N 3 -> "nutau" | N (-3) -> "nutaubar" | N _ -> invalid_arg "Models.Anomtop.flavor_to_string: invalid neutrino" | U 1 -> "u" | U (-1) -> "ubar" | U 2 -> "c" | U (-2) -> "cbar" | U 3 -> "t" | U (-3) -> "tbar" | U _ -> invalid_arg "Models.Anomtop.flavor_to_string: invalid up type quark" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | D _ -> invalid_arg "Models.Anomtop.flavor_to_string: invalid down type quark" end | G f -> begin match f with | Gl -> "g" | Ga -> "A" | Z -> "Z" | Wp -> "W+" | Wm -> "W-" end | O f -> begin match f with | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | H -> "H" end let flavor_to_TeX = function | M f -> begin match f with | L 1 -> "e^-" | L (-1) -> "e^+" | L 2 -> "\\mu^-" | L (-2) -> "\\mu^+" | L 3 -> "\\tau^-" | L (-3) -> "\\tau^+" | L _ -> invalid_arg "Models.Anomtop.flavor_to_TeX: invalid lepton" | N 1 -> "\\nu_e" | N (-1) -> "\\bar{\\nu}_e" | N 2 -> "\\nu_\\mu" | N (-2) -> "\\bar{\\nu}_\\mu" | N 3 -> "\\nu_\\tau" | N (-3) -> "\\bar{\\nu}_\\tau" | N _ -> invalid_arg "Models.Anomtop.flavor_to_TeX: invalid neutrino" | U 1 -> "u" | U (-1) -> "\\bar{u}" | U 2 -> "c" | U (-2) -> "\\bar{c}" | U 3 -> "t" | U (-3) -> "\\bar{t}" | U _ -> invalid_arg "Models.Anomtop.flavor_to_TeX: invalid up type quark" | D 1 -> "d" | D (-1) -> "\\bar{d}" | D 2 -> "s" | D (-2) -> "\\bar{s}" | D 3 -> "b" | D (-3) -> "\\bar{b}" | D _ -> invalid_arg "Models.Anomtop.flavor_to_TeX: invalid down type quark" end | G f -> begin match f with | Gl -> "g" | Ga -> "\\gamma" | Z -> "Z" | Wp -> "W^+" | Wm -> "W^-" end | O f -> begin match f with | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | H -> "H" end let flavor_symbol = function | M f -> begin match f with | L n when n > 0 -> "l" ^ string_of_int n | L n -> "l" ^ string_of_int (abs n) ^ "b" | N n when n > 0 -> "n" ^ string_of_int n | N n -> "n" ^ string_of_int (abs n) ^ "b" | U n when n > 0 -> "u" ^ string_of_int n | U n -> "u" ^ string_of_int (abs n) ^ "b" | D n when n > 0 -> "d" ^ string_of_int n | D n -> "d" ^ string_of_int (abs n) ^ "b" end | G f -> begin match f with | Gl -> "gl" | Ga -> "a" | Z -> "z" | Wp -> "wp" | Wm -> "wm" end | O f -> begin match f with | Phip -> "pp" | Phim -> "pm" | Phi0 -> "p0" | H -> "h" end let pdg = function | M f -> begin match f with | L n when n > 0 -> 9 + 2*n | L n -> - 9 + 2*n | N n when n > 0 -> 10 + 2*n | N n -> - 10 + 2*n | U n when n > 0 -> 2*n | U n -> 2*n | D n when n > 0 -> - 1 + 2*n | D n -> 1 + 2*n end | G f -> begin match f with | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) end | O f -> begin match f with | Phip | Phim -> 27 | Phi0 -> 26 | H -> 25 end let mass_symbol f = "mass(" ^ string_of_int (abs (pdg f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg f)) ^ ")" let constant_symbol = function | Unit -> "unit" | Pi -> "PI" | Alpha_QED -> "alpha" | E -> "e" | G_weak -> "g" | Vev -> "vev" | Sin2thw -> "sin2thw" | Sinthw -> "sinthw" | Costhw -> "costhw" | Q_lepton -> "qlep" | Q_up -> "qup" | Q_down -> "qdwn" | Q_top -> "qtop" | G_NC_lepton -> "gnclep" | G_NC_neutrino -> "gncneu" | G_NC_up -> "gncup" | G_NC_down -> "gncdwn" | G_NC_top -> "gnctop" | G_CC -> "gcc" | I_Q_W -> "iqw" | I_G_ZWW -> "igzww" | G_WWWW -> "gw4" | G_ZZWW -> "gzzww" | G_AZWW -> "gazww" | G_AAWW -> "gaaww" | G_HWW -> "ghww" | G_HZZ -> "ghzz" | G_HHWW -> "ghhww" | G_HHZZ -> "ghhzz" | G_Htt -> "ghtt" | G_Hbb -> "ghbb" | G_Htautau -> "ghtautau" | G_Hcc -> "ghcc" | G_H3 -> "gh3" | G_H4 -> "gh4" | Gs -> "gs" | I_Gs -> "igs" | G2 -> "gs**2" | Mass f -> "mass" ^ flavor_symbol f | Width f -> "width" ^ flavor_symbol f end module O = Omega.Make(Fusion.Mixed23)(Targets.Fortran) (Anomtop(SM_no_anomalous)) let _ = O.main () (*i * Local Variables: * mode:caml * indent-tabs-mode:nil * page-delimiter:"^(\\* .*\n" * End: i*) Index: trunk/omega/src/targets.ml =================================================================== --- trunk/omega/src/targets.ml (revision 8413) +++ trunk/omega/src/targets.ml (revision 8414) @@ -1,8293 +1,8292 @@ (* targets.ml -- Copyright (C) 1999-2020 by Wolfgang Kilian Thorsten Ohl Juergen Reuter with contributions from Christian Speckner Fabian Bach (only parts of this file) Marco Sekulla (only parts of this file) Bijan Chokoufe Nejad (only parts of this file) So Young Shim WHIZARD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. WHIZARD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *) module Dummy (F : Fusion.Maker) (P : Momentum.T) (M : Model.T) = struct type amplitudes = Fusion.Multi(F)(P)(M).amplitudes type diagnostic = All | Arguments | Momenta | Gauge let options = Options.empty let amplitudes_to_channel _ _ _ = failwith "Targets.Dummy" let parameters_to_channel _ = failwith "Targets.Dummy" end (* \thocwmodulesection{O'Mega Virtual Machine with \texttt{Fortran\;90/95}} *) (* \thocwmodulesubsection{Preliminaries} *) module VM (Fusion_Maker : Fusion.Maker) (P : Momentum.T) (M : Model.T) = struct open Coupling open Format module CM = Colorize.It(M) module F = Fusion_Maker(P)(M) module CF = Fusion.Multi(Fusion_Maker)(P)(M) module CFlow = Color.Flow type amplitudes = CF.amplitudes (* Options. *) type diagnostic = All | Arguments | Momenta | Gauge let wrapper_module = ref "ovm_wrapper" let parameter_module_external = ref "some_external_module_with_model_info" let bytecode_file = ref "bytecode.hbc" let md5sum = ref None let openmp = ref false let kind = ref "default" let whizard = ref false let options = Options.create [ "wrapper_module", Arg.String (fun s -> wrapper_module := s), "name of wrapper module"; "bytecode_file", Arg.String (fun s -> bytecode_file := s), "bytecode file to be used in wrapper"; "parameter_module_external", Arg.String (fun s -> parameter_module_external := s), "external parameter module to be used in wrapper"; "md5sum", Arg.String (fun s -> md5sum := Some s), "transfer MD5 checksum in wrapper"; "whizard", Arg.Set whizard, "include WHIZARD interface in wrapper"; "openmp", Arg.Set openmp, "activate parallel computation of amplitude with OpenMP"] (* Integers encode the opcodes (operation codes). *) let ovm_ADD_MOMENTA = 1 let ovm_CALC_BRAKET = 2 let ovm_LOAD_SCALAR = 10 let ovm_LOAD_SPINOR_INC = 11 let ovm_LOAD_SPINOR_OUT = 12 let ovm_LOAD_CONJSPINOR_INC = 13 let ovm_LOAD_CONJSPINOR_OUT = 14 let ovm_LOAD_MAJORANA_INC = 15 let ovm_LOAD_MAJORANA_OUT = 16 let ovm_LOAD_VECTOR_INC = 17 let ovm_LOAD_VECTOR_OUT = 18 let ovm_LOAD_VECTORSPINOR_INC = 19 let ovm_LOAD_VECTORSPINOR_OUT = 20 let ovm_LOAD_TENSOR2_INC = 21 let ovm_LOAD_TENSOR2_OUT = 22 let ovm_LOAD_BRS_SCALAR = 30 let ovm_LOAD_BRS_SPINOR_INC = 31 let ovm_LOAD_BRS_SPINOR_OUT = 32 let ovm_LOAD_BRS_CONJSPINOR_INC = 33 let ovm_LOAD_BRS_CONJSPINOR_OUT = 34 let ovm_LOAD_BRS_VECTOR_INC = 37 let ovm_LOAD_BRS_VECTOR_OUT = 38 let ovm_LOAD_MAJORANA_GHOST_INC = 23 let ovm_LOAD_MAJORANA_GHOST_OUT = 24 let ovm_LOAD_BRS_MAJORANA_INC = 35 let ovm_LOAD_BRS_MAJORANA_OUT = 36 let ovm_PROPAGATE_SCALAR = 51 let ovm_PROPAGATE_COL_SCALAR = 52 let ovm_PROPAGATE_GHOST = 53 let ovm_PROPAGATE_SPINOR = 54 let ovm_PROPAGATE_CONJSPINOR = 55 let ovm_PROPAGATE_MAJORANA = 56 let ovm_PROPAGATE_COL_MAJORANA = 57 let ovm_PROPAGATE_UNITARITY = 58 let ovm_PROPAGATE_COL_UNITARITY = 59 let ovm_PROPAGATE_FEYNMAN = 60 let ovm_PROPAGATE_COL_FEYNMAN = 61 let ovm_PROPAGATE_VECTORSPINOR = 62 let ovm_PROPAGATE_TENSOR2 = 63 (* \begin{dubious} [ovm_PROPAGATE_NONE] has to be split up to different types to work in conjunction with color MC \dots \end{dubious} *) let ovm_PROPAGATE_NONE = 64 let ovm_FUSE_V_FF = -1 let ovm_FUSE_F_VF = -2 let ovm_FUSE_F_FV = -3 let ovm_FUSE_VA_FF = -4 let ovm_FUSE_F_VAF = -5 let ovm_FUSE_F_FVA = -6 let ovm_FUSE_VA2_FF = -7 let ovm_FUSE_F_VA2F = -8 let ovm_FUSE_F_FVA2 = -9 let ovm_FUSE_A_FF = -10 let ovm_FUSE_F_AF = -11 let ovm_FUSE_F_FA = -12 let ovm_FUSE_VL_FF = -13 let ovm_FUSE_F_VLF = -14 let ovm_FUSE_F_FVL = -15 let ovm_FUSE_VR_FF = -16 let ovm_FUSE_F_VRF = -17 let ovm_FUSE_F_FVR = -18 let ovm_FUSE_VLR_FF = -19 let ovm_FUSE_F_VLRF = -20 let ovm_FUSE_F_FVLR = -21 let ovm_FUSE_SP_FF = -22 let ovm_FUSE_F_SPF = -23 let ovm_FUSE_F_FSP = -24 let ovm_FUSE_S_FF = -25 let ovm_FUSE_F_SF = -26 let ovm_FUSE_F_FS = -27 let ovm_FUSE_P_FF = -28 let ovm_FUSE_F_PF = -29 let ovm_FUSE_F_FP = -30 let ovm_FUSE_SL_FF = -31 let ovm_FUSE_F_SLF = -32 let ovm_FUSE_F_FSL = -33 let ovm_FUSE_SR_FF = -34 let ovm_FUSE_F_SRF = -35 let ovm_FUSE_F_FSR = -36 let ovm_FUSE_SLR_FF = -37 let ovm_FUSE_F_SLRF = -38 let ovm_FUSE_F_FSLR = -39 let ovm_FUSE_G_GG = -40 let ovm_FUSE_V_SS = -41 let ovm_FUSE_S_VV = -42 let ovm_FUSE_S_VS = -43 let ovm_FUSE_V_SV = -44 let ovm_FUSE_S_SS = -45 let ovm_FUSE_S_SVV = -46 let ovm_FUSE_V_SSV = -47 let ovm_FUSE_S_SSS = -48 let ovm_FUSE_V_VVV = -49 let ovm_FUSE_S_G2 = -50 let ovm_FUSE_G_SG = -51 let ovm_FUSE_G_GS = -52 let ovm_FUSE_S_G2_SKEW = -53 let ovm_FUSE_G_SG_SKEW = -54 let ovm_FUSE_G_GS_SKEW = -55 let inst_length = 8 (* Some helper functions. *) let printi ~lhs:l ~rhs1:r1 ?coupl:(cp = 0) ?coeff:(co = 0) ?rhs2:(r2 = 0) ?rhs3:(r3 = 0) ?rhs4:(r4 = 0) code = printf "@\n%d %d %d %d %d %d %d %d" code cp co l r1 r2 r3 r4 let nl () = printf "@\n" let print_int_lst lst = nl (); lst |> List.iter (printf "%d ") let print_str_lst lst = nl (); lst |> List.iter (printf "%s ") let break () = printi ~lhs:0 ~rhs1:0 0 (* Copied from below. Needed for header. *) (* \begin{dubious} Could be fused with [lorentz_ordering]. \end{dubious} *) type declarations = { scalars : F.wf list; spinors : F.wf list; conjspinors : F.wf list; realspinors : F.wf list; ghostspinors : F.wf list; vectorspinors : F.wf list; vectors : F.wf list; ward_vectors : F.wf list; massive_vectors : F.wf list; tensors_1 : F.wf list; tensors_2 : F.wf list; brs_scalars : F.wf list; brs_spinors : F.wf list; brs_conjspinors : F.wf list; brs_realspinors : F.wf list; brs_vectorspinors : F.wf list; brs_vectors : F.wf list; brs_massive_vectors : F.wf list } let rec classify_wfs' acc = function | [] -> acc | wf :: rest -> classify_wfs' (match CM.lorentz (F.flavor wf) with | Scalar -> {acc with scalars = wf :: acc.scalars} | Spinor -> {acc with spinors = wf :: acc.spinors} | ConjSpinor -> {acc with conjspinors = wf :: acc.conjspinors} | Majorana -> {acc with realspinors = wf :: acc.realspinors} | Maj_Ghost -> {acc with ghostspinors = wf :: acc.ghostspinors} | Vectorspinor -> {acc with vectorspinors = wf :: acc.vectorspinors} | Vector -> {acc with vectors = wf :: acc.vectors} | Massive_Vector -> {acc with massive_vectors = wf :: acc.massive_vectors} | Tensor_1 -> {acc with tensors_1 = wf :: acc.tensors_1} | Tensor_2 -> {acc with tensors_2 = wf :: acc.tensors_2} | BRS Scalar -> {acc with brs_scalars = wf :: acc.brs_scalars} | BRS Spinor -> {acc with brs_spinors = wf :: acc.brs_spinors} | BRS ConjSpinor -> {acc with brs_conjspinors = wf :: acc.brs_conjspinors} | BRS Majorana -> {acc with brs_realspinors = wf :: acc.brs_realspinors} | BRS Vectorspinor -> {acc with brs_vectorspinors = wf :: acc.brs_vectorspinors} | BRS Vector -> {acc with brs_vectors = wf :: acc.brs_vectors} | BRS Massive_Vector -> {acc with brs_massive_vectors = wf :: acc.brs_massive_vectors} | BRS _ -> invalid_arg "Targets.classify_wfs': not needed here") rest let classify_wfs wfs = classify_wfs' { scalars = []; spinors = []; conjspinors = []; realspinors = []; ghostspinors = []; vectorspinors = []; vectors = []; ward_vectors = []; massive_vectors = []; tensors_1 = []; tensors_2 = []; brs_scalars = []; brs_spinors = []; brs_conjspinors = []; brs_realspinors = []; brs_vectorspinors = []; brs_vectors = []; brs_massive_vectors = [] } wfs (* \thocwmodulesubsection{Sets and maps} *) (* The OVM identifies all objects via integers. Therefore, we need maps which assign the abstract object a unique ID. *) (* I want [int list]s with less elements to come first. Used in conjunction with the int list representation of momenta, this will set the outer particles at first position and allows the OVM to set them without further instructions. *) (* \begin{dubious} Using the Momentum module might give better performance than integer lists? \end{dubious} *) let rec int_lst_compare (e1 : int list) (e2 : int list) = match e1,e2 with | [], [] -> 0 | _, [] -> +1 | [], _ -> -1 | [_;_], [_] -> +1 | [_], [_;_] -> -1 | hd1 :: tl1, hd2 :: tl2 -> let c = compare hd1 hd2 in if (c != 0 && List.length tl1 = List.length tl2) then c else int_lst_compare tl1 tl2 (* We need a canonical ordering for the different types of wfs. Copied, and slightly modified to order [wf]s, from \texttt{fusion.ml}. *) let lorentz_ordering wf = match CM.lorentz (F.flavor wf) with | Scalar -> 0 | Spinor -> 1 | ConjSpinor -> 2 | Majorana -> 3 | Vector -> 4 | Massive_Vector -> 5 | Tensor_2 -> 6 | Tensor_1 -> 7 | Vectorspinor -> 8 | BRS Scalar -> 9 | BRS Spinor -> 10 | BRS ConjSpinor -> 11 | BRS Majorana -> 12 | BRS Vector -> 13 | BRS Massive_Vector -> 14 | BRS Tensor_2 -> 15 | BRS Tensor_1 -> 16 | BRS Vectorspinor -> 17 | Maj_Ghost -> invalid_arg "lorentz_ordering: not implemented" | BRS _ -> invalid_arg "lorentz_ordering: not needed" let wf_compare (wf1, mult1) (wf2, mult2) = let c1 = compare (lorentz_ordering wf1) (lorentz_ordering wf2) in if c1 <> 0 then c1 else let c2 = compare wf1 wf2 in if c2 <> 0 then c2 else compare mult1 mult2 let amp_compare amp1 amp2 = let cflow a = CM.flow (F.incoming a) (F.outgoing a) in let c1 = compare (cflow amp1) (cflow amp2) in if c1 <> 0 then c1 else let process_sans_color a = (List.map CM.flavor_sans_color (F.incoming a), List.map CM.flavor_sans_color (F.outgoing a)) in compare (process_sans_color amp1) (process_sans_color amp2) let level_compare (f1, amp1) (f2, amp2) = let p1 = F.momentum_list (F.lhs f1) and p2 = F.momentum_list (F.lhs f2) in let c1 = int_lst_compare p1 p2 in if c1 <> 0 then c1 else let c2 = compare f1 f2 in if c2 <> 0 then c2 else amp_compare amp1 amp2 module ISet = Set.Make (struct type t = int list let compare = int_lst_compare end) module WFSet = Set.Make (struct type t = CF.wf * int let compare = wf_compare end) module CSet = Set.Make (struct type t = CM.constant let compare = compare end) module FSet = Set.Make (struct type t = F.fusion * F.amplitude let compare = level_compare end) (* \begin{dubious} It might be preferable to use a [PMap] which maps mom to int, instead of this way. More standard functions like [mem] could be used. Also, [get_ID] would be faster, $\mathcal{O}(\log N)$ instead of $\mathcal{O}(N)$, and simpler. For 8 gluons: N=127 momenta. Minor performance issue. \end{dubious} *) module IMap = Map.Make (struct type t = int let compare = compare end) (* For [wf]s it is crucial for the performance to use a different type of [Map]s. *) module WFMap = Map.Make (struct type t = CF.wf * int let compare = wf_compare end) type lookups = { pmap : int list IMap.t; wfmap : int WFMap.t; cmap : CM.constant IMap.t * CM.constant IMap.t; amap : F.amplitude IMap.t; n_wfs : int list; amplitudes : CF.amplitudes; dict : F.amplitude -> F.wf -> int } let largest_key imap = if (IMap.is_empty imap) then failwith "largest_key: Map is empty!" else fst (IMap.max_binding imap) (* OCaml's [compare] from pervasives cannot compare functional types, e.g. for type [amplitude], if no specific equality function is given ("equal: functional value"). Therefore, we allow to specify the ordering. *) let get_ID' comp map elt : int = let smallmap = IMap.filter (fun _ x -> (comp x elt) = 0 ) map in if IMap.is_empty smallmap then raise Not_found else fst (IMap.min_binding smallmap) (* \begin{dubious} Trying to curry [map] here leads to type errors of the polymorphic function [get_ID]? \end{dubious} *) let get_ID map = match map with | map -> get_ID' compare map let get_const_ID map x = match map with | (map1, map2) -> try get_ID' compare map1 x with _ -> try get_ID' compare map2 x with _ -> failwith "Impossible" (* Creating an integer map of a list with an optional argument that indicates where the map should start counting. *) let map_of_list ?start:(st=1) lst = let g (ind, map) wf = (succ ind, IMap.add ind wf map) in lst |> List.fold_left g (st, IMap.empty) |> snd let wf_map_of_list ?start:(st=1) lst = let g (ind, map) wf = (succ ind, WFMap.add wf ind map) in lst |> List.fold_left g (st, WFMap.empty) |> snd (* \thocwmodulesubsection{Header} *) (* \begin{dubious} It would be nice to safe the creation date as comment. However, the Unix module doesn't seem to be loaded on default. \end{dubious} *) let version = String.concat " " [Config.version; Config.status; Config.date] let model_name = let basename = Filename.basename Sys.executable_name in try Filename.chop_extension basename with | _ -> basename let print_description cmdline = printf "Model %s\n" model_name; printf "OVM %s\n" version; printf "@\nBytecode file generated automatically by O'Mega for OVM"; printf "@\nDo not delete any lines. You called O'Mega with"; printf "@\n %s" cmdline; (*i let t = Unix.localtime (Unix.time() ) in printf "@\n on %5d %5d %5d" (succ t.Unix.tm_mon) t.Unix.tm_mday t.Unix.tm_year; i*) printf "@\n" let num_classified_wfs wfs = let wfs' = classify_wfs wfs in List.map List.length [ wfs'.scalars @ wfs'.brs_scalars; wfs'.spinors @ wfs'.brs_spinors; wfs'.conjspinors @ wfs'.brs_conjspinors; wfs'.realspinors @ wfs'.brs_realspinors @ wfs'.ghostspinors; wfs'.vectors @ wfs'.massive_vectors @ wfs'.brs_vectors @ wfs'.brs_massive_vectors @ wfs'.ward_vectors; wfs'.tensors_2; wfs'.tensors_1; wfs'.vectorspinors ] let description_classified_wfs = [ "N_scalars"; "N_spinors"; "N_conjspinors"; "N_bispinors"; "N_vectors"; "N_tensors_2"; "N_tensors_1"; "N_vectorspinors" ] let num_particles_in amp = match CF.flavors amp with | [] -> 0 | (fin, _) :: _ -> List.length fin let num_particles_out amp = match CF.flavors amp with | [] -> 0 | (_, fout) :: _ -> List.length fout let num_particles amp = match CF.flavors amp with | [] -> 0 | (fin, fout) :: _ -> List.length fin + List.length fout let num_color_indices_default = 2 (* Standard model and non-color-exotica *) let num_color_indices amp = try CFlow.rank (List.hd (CF.color_flows amp)) with _ -> num_color_indices_default let num_color_factors amp = let table = CF.color_factors amp in let n_cflow = Array.length table and n_cfactors = ref 0 in for c1 = 0 to pred n_cflow do for c2 = 0 to pred n_cflow do if c1 <= c2 then begin match table.(c1).(c2) with | [] -> () | _ -> incr n_cfactors end done done; !n_cfactors let num_helicities amp = amp |> CF.helicities |> List.length let num_flavors amp = amp |> CF.flavors |> List.length let num_ks amp = amp |> CF.processes |> List.length let num_color_flows amp = amp |> CF.color_flows |> List.length (* Use [fst] since [WFSet.t = F.wf * int]. *) let num_wfs wfset = wfset |> WFSet.elements |> List.map fst |> num_classified_wfs (* [largest_key] gives the number of momenta if applied to [pmap]. *) let num_lst lookups wfset = [ largest_key lookups.pmap; num_particles lookups.amplitudes; num_particles_in lookups.amplitudes; num_particles_out lookups.amplitudes; num_ks lookups.amplitudes; num_helicities lookups.amplitudes; num_color_flows lookups.amplitudes; num_color_indices lookups.amplitudes; num_flavors lookups.amplitudes; num_color_factors lookups.amplitudes ] @ num_wfs wfset let description_lst = [ "N_momenta"; "N_particles"; "N_prt_in"; "N_prt_out"; "N_amplitudes"; "N_helicities"; "N_col_flows"; "N_col_indices"; "N_flavors"; "N_col_factors" ] @ description_classified_wfs let print_header' numbers = let chopped_num_lst = ThoList.chopn inst_length numbers and chopped_desc_lst = ThoList.chopn inst_length description_lst and printer a b = print_str_lst a; print_int_lst b in List.iter2 printer chopped_desc_lst chopped_num_lst let print_header lookups wfset = print_header' (num_lst lookups wfset) let print_zero_header () = let rec zero_list' j = if j < 1 then [] else 0 :: zero_list' (j - 1) in let zero_list i = zero_list' (i + 1) in description_lst |> List.length |> zero_list |> print_header' (* \thocwmodulesubsection{Tables} *) let print_spin_table' tuples = match tuples with | [] -> () | _ -> tuples |> List.iter ( fun (tuple1, tuple2) -> tuple1 @ tuple2 |> List.map (Printf.sprintf "%d ") |> String.concat "" |> printf "@\n%s" ) let print_spin_table amplitudes = printf "@\nSpin states table"; print_spin_table' @@ CF.helicities amplitudes let print_flavor_table tuples = match tuples with | [] -> () | _ -> List.iter ( fun tuple -> tuple |> List.map (fun f -> Printf.sprintf "%d " @@ M.pdg f) |> String.concat "" |> printf "@\n%s" ) tuples let print_flavor_tables amplitudes = printf "@\nFlavor states table"; print_flavor_table @@ List.map (fun (fin, fout) -> fin @ fout) @@ CF.flavors amplitudes let print_color_flows_table' tuple = match CFlow.to_lists tuple with | [] -> () | cfs -> printf "@\n%s" @@ String.concat "" @@ List.map ( fun cf -> cf |> List.map (Printf.sprintf "%d ") |> String.concat "" ) cfs let print_color_flows_table tuples = match tuples with | [] -> () | _ -> List.iter print_color_flows_table' tuples let print_ghost_flags_table tuples = match tuples with | [] -> () | _ -> List.iter (fun tuple -> match CFlow.ghost_flags tuple with | [] -> () | gfs -> printf "@\n"; List.iter (fun gf -> printf "%s " (if gf then "1" else "0") ) gfs ) tuples let format_power { CFlow.num = num; CFlow.den = den; CFlow.power = pwr } = match num, den, pwr with | _, 0, _ -> invalid_arg "targets.format_power: zero denominator" | n, d, p -> [n; d; p] let format_powers = function | [] -> [0] | powers -> List.flatten (List.map format_power powers) (*i (* We go through the array line by line and collect all colorfactors which * are nonzero because their corresponding color flows match. * With the gained intset, we would be able to print only the necessary * coefficients of the symmetric matrix and indicate from where the OVM * can copy the rest. However, this approach gets really slow for many * gluons and we can save at most 3 numbers per line.*) let print_color_factor_table_funct table = let n_cflow = Array.length table in let (intset, _, _ ) = let rec fold_array (set, cf1, cf2) = if cf1 > pred n_cflow then (set, 0, 0) else let returnset = match table.(cf1).(cf2) with | [] -> set | cf -> ISet.add ([succ cf1; succ cf2] @ (format_powers cf)) set in if cf2 < pred n_cflow then fold_array (returnset, cf1, succ cf2) else fold_array (returnset, succ cf1, 0) in fold_array (ISet.empty, 0, 0) in let map = map_of_list (ISet.elements intset) in List.iter (fun x -> printf "@\n"; let xth = List.nth x in if (xth 0 <= xth 1) then List.iter (printf "%d ") x else printf "%d %d" 0 (get_ID map x)) (ISet.elements intset) let print_color_factor_table_old table = let n_cflow = Array.length table in let (intlsts, _, _ ) = let rec fold_array (lsts, cf1, cf2) = if cf1 > pred n_cflow then (lsts, 0, 0) else let returnlsts = match table.(cf1).(cf2) with | [] -> lsts | cf -> ([succ cf1; succ cf2] @ (format_powers cf)) :: lsts in if cf2 < pred n_cflow then fold_array (returnlsts, cf1, succ cf2) else fold_array (returnlsts, succ cf1, 0) in fold_array ([], 0, 0) in let intlsts = List.rev intlsts in List.iter (fun x -> printf "@\n"; List.iter (printf "%d ") x ) intlsts i*) (* Straightforward iteration gives a great speedup compared to the fancier approach which only collects nonzero colorfactors. *) let print_color_factor_table table = let n_cflow = Array.length table in if n_cflow > 0 then begin for c1 = 0 to pred n_cflow do for c2 = 0 to pred n_cflow do if c1 <= c2 then begin match table.(c1).(c2) with | [] -> () | cf -> printf "@\n"; List.iter (printf "%9d") ([succ c1; succ c2] @ (format_powers cf)); end done done end let option_to_binary = function | Some _ -> "1" | None -> "0" let print_flavor_color_table n_flv n_cflow table = if n_flv > 0 then begin for c = 0 to pred n_cflow do printf "@\n"; for f = 0 to pred n_flv do printf "%s " (option_to_binary table.(f).(c)) done; done; end let print_color_tables amplitudes = let cflows = CF.color_flows amplitudes and cfactors = CF.color_factors amplitudes in printf "@\nColor flows table: [ (i, j) (k, l) -> (m, n) ...]"; print_color_flows_table cflows; printf "@\nColor ghost flags table:"; print_ghost_flags_table cflows; printf "@\nColor factors table: [ i, j: num den power], %s" "i, j are indexed color flows"; print_color_factor_table cfactors; printf "@\nFlavor color combination is allowed:"; print_flavor_color_table (num_flavors amplitudes) (List.length (CF.color_flows amplitudes)) (CF.process_table amplitudes) (* \thocwmodulesubsection{Momenta} *) (* Add the momenta of a WFSet to a Iset. For now, we are throwing away the information to which amplitude the momentum belongs. This could be optimized for random color flow computations. *) let momenta_set wfset = let get_mom wf = wf |> fst |> F.momentum_list in let momenta = List.map get_mom (WFSet.elements wfset) in momenta |> List.fold_left (fun set x -> set |> ISet.add x) ISet.empty let chop_in_3 lst = let ceil_div i j = if (i mod j = 0) then i/j else i/j + 1 in ThoList.chopn (ceil_div (List.length lst) 3) lst (* Assign momenta via instruction code. External momenta [[_]] are already set by the OVM. To avoid unnecessary look-ups of IDs we seperate two cases. If we have more, we split up in two or three parts. *) let add_mom p pmap = let print_mom lhs rhs1 rhs2 rhs3 = if (rhs1!= 0) then printi ~lhs:lhs ~rhs1:rhs1 ~rhs2:rhs2 ~rhs3:rhs3 ovm_ADD_MOMENTA in let get_p_ID = get_ID pmap in match p with | [] | [_] -> print_mom 0 0 0 0 | [rhs1;rhs2] -> print_mom (get_p_ID [rhs1;rhs2]) rhs1 rhs2 0 | [rhs1;rhs2;rhs3] -> print_mom (get_p_ID [rhs1;rhs2;rhs3]) rhs1 rhs2 rhs3 | more -> let ids = List.map get_p_ID (chop_in_3 more) in if (List.length ids = 3) then print_mom (get_p_ID more) (List.nth ids 0) (List.nth ids 1) (List.nth ids 2) else print_mom (get_p_ID more) (List.nth ids 0) (List.nth ids 1) 0 (* Hand through the current level and print level seperators if necessary. *) let add_all_mom lookups pset = let add_all' level p = let level' = List.length p in if (level' > level && level' > 3) then break (); add_mom p lookups.pmap; level' in ignore (pset |> ISet.elements |> List.fold_left add_all' 1) (* Expand a set of momenta to contain all needed momenta for the computation in the OVM. For this, we create a list of sets which contains the chopped momenta and unify them afterwards. If the set has become larger, we expand again. *) let rec expand_pset p = let momlst = ISet.elements p in let pset_of lst = List.fold_left (fun s x -> ISet.add x s) ISet.empty lst in let sets = List.map (fun x -> pset_of (chop_in_3 x) ) momlst in let bigset = List.fold_left ISet.union ISet.empty sets in let biggerset = ISet.union bigset p in if (List.length momlst < List.length (ISet.elements biggerset) ) then expand_pset biggerset else biggerset let mom_ID pmap wf = get_ID pmap (F.momentum_list wf) (* \thocwmodulesubsection{Wavefunctions and externals} *) (* [mult_wf] is needed because the [wf] with same combination of flavor and momentum can have different dependencies and content. *) let mult_wf dict amplitude wf = try wf, dict amplitude wf with | Not_found -> wf, 0 (* Build the union of all [wf]s of all amplitudes and a map of the amplitudes. *) let wfset_amps amplitudes = let amap = amplitudes |> CF.processes |> List.sort amp_compare |> map_of_list and dict = CF.dictionary amplitudes in let wfset_amp amp = let f = mult_wf dict amp in let lst = List.map f ((F.externals amp) @ (F.variables amp)) in lst |> List.fold_left (fun s x -> WFSet.add x s) WFSet.empty in let list_of_sets = amplitudes |> CF.processes |> List.map wfset_amp in List.fold_left WFSet.union WFSet.empty list_of_sets, amap (* To obtain the Fortran index, we substract the number of precedent wave functions. *) let lorentz_ordering_reduced wf = match CM.lorentz (F.flavor wf) with | Scalar | BRS Scalar -> 0 | Spinor | BRS Spinor -> 1 | ConjSpinor | BRS ConjSpinor -> 2 | Majorana | BRS Majorana -> 3 | Vector | BRS Vector | Massive_Vector | BRS Massive_Vector -> 4 | Tensor_2 | BRS Tensor_2 -> 5 | Tensor_1 | BRS Tensor_1 -> 6 | Vectorspinor | BRS Vectorspinor -> 7 | Maj_Ghost -> invalid_arg "lorentz_ordering: not implemented" | BRS _ -> invalid_arg "lorentz_ordering: not needed" let wf_index wfmap num_lst (wf, i) = let wf_ID = WFMap.find (wf, i) wfmap and sum lst = List.fold_left (fun x y -> x+y) 0 lst in wf_ID - sum (ThoList.hdn (lorentz_ordering_reduced wf) num_lst) let print_ext lookups amp_ID inc (wf, i) = let mom = (F.momentum_list wf) in let outer_index = if List.length mom = 1 then List.hd mom else failwith "targets.print_ext: called with non-external particle" and f = F.flavor wf in let pdg = CM.pdg f and wf_code = match CM.lorentz f with | Scalar -> ovm_LOAD_SCALAR | BRS Scalar -> ovm_LOAD_BRS_SCALAR | Spinor -> if inc then ovm_LOAD_SPINOR_INC else ovm_LOAD_SPINOR_OUT | BRS Spinor -> if inc then ovm_LOAD_BRS_SPINOR_INC else ovm_LOAD_BRS_SPINOR_OUT | ConjSpinor -> if inc then ovm_LOAD_CONJSPINOR_INC else ovm_LOAD_CONJSPINOR_OUT | BRS ConjSpinor -> if inc then ovm_LOAD_BRS_CONJSPINOR_INC else ovm_LOAD_BRS_CONJSPINOR_OUT | Vector | Massive_Vector -> if inc then ovm_LOAD_VECTOR_INC else ovm_LOAD_VECTOR_OUT | BRS Vector | BRS Massive_Vector -> if inc then ovm_LOAD_BRS_VECTOR_INC else ovm_LOAD_BRS_VECTOR_OUT | Tensor_2 -> if inc then ovm_LOAD_TENSOR2_INC else ovm_LOAD_TENSOR2_OUT | Vectorspinor | BRS Vectorspinor -> if inc then ovm_LOAD_VECTORSPINOR_INC else ovm_LOAD_VECTORSPINOR_OUT | Majorana -> if inc then ovm_LOAD_MAJORANA_INC else ovm_LOAD_MAJORANA_OUT | BRS Majorana -> if inc then ovm_LOAD_BRS_MAJORANA_INC else ovm_LOAD_BRS_MAJORANA_OUT | Maj_Ghost -> if inc then ovm_LOAD_MAJORANA_GHOST_INC else ovm_LOAD_MAJORANA_GHOST_OUT | Tensor_1 -> invalid_arg "targets.print_ext: Tensor_1 only internal" | BRS _ -> failwith "targets.print_ext: Not implemented" and wf_ind = wf_index lookups.wfmap lookups.n_wfs (wf, i) in printi wf_code ~lhs:wf_ind ~coupl:(abs(pdg)) ~rhs1:outer_index ~rhs4:amp_ID let print_ext_amp lookups amplitude = let incoming = (List.map (fun _ -> true) (F.incoming amplitude) @ List.map (fun _ -> false) (F.outgoing amplitude)) and amp_ID = get_ID' amp_compare lookups.amap amplitude in let wf_tpl wf = mult_wf lookups.dict amplitude wf in let print_ext_wf inc wf = wf |> wf_tpl |> print_ext lookups amp_ID inc in List.iter2 print_ext_wf incoming (F.externals amplitude) let print_externals lookups seen_wfs amplitude = let externals = List.combine (F.externals amplitude) (List.map (fun _ -> true) (F.incoming amplitude) @ List.map (fun _ -> false) (F.outgoing amplitude)) in List.fold_left (fun seen (wf, incoming) -> let amp_ID = get_ID' amp_compare lookups.amap amplitude in let wf_tpl = mult_wf lookups.dict amplitude wf in if not (WFSet.mem wf_tpl seen) then begin wf_tpl |> print_ext lookups amp_ID incoming end; WFSet.add wf_tpl seen) seen_wfs externals (* [print_externals] and [print_ext_amp] do in principle the same thing but [print_externals] filters out dublicate external wave functions. Even with [print_externals] the same (numerically) external wave function will be loaded if it belongs to a different color flow, just as in the native Fortran code. For color MC, [print_ext_amp] has to be used (redundant instructions but only one flow is computed) and the filtering of duplicate fusions has to be disabled. *) let print_ext_amps lookups = let print_external_amp s x = print_externals lookups s x in ignore ( List.fold_left print_external_amp WFSet.empty (CF.processes lookups.amplitudes) ) (*i List.iter (print_ext_amp lookups) (CF.processes lookups.amplitudes) i*) (* \thocwmodulesubsection{Currents} *) (* Parallelization issues: All fusions have to be completed before the propagation takes place. Preferably each fusion and propagation is done by one thread. Solution: All fusions are subinstructions, i.e. if they are read by the main loop they are skipped. If a propagation occurs, all fusions have to be computed first. The additional control bit is the sign of the first int of an instruction. *) (*i TODO: (bcn 2014-07-21) Majorana support will come some day maybe i*) let print_fermion_current code_a code_b code_c coeff lhs c wf1 wf2 fusion = let printc code r1 r2 = printi code ~lhs:lhs ~coupl:c ~coeff:coeff ~rhs1:r1 ~rhs2:r2 in match fusion with | F13 -> printc code_a wf1 wf2 | F31 -> printc code_a wf2 wf1 | F23 -> printc code_b wf1 wf2 | F32 -> printc code_b wf2 wf1 | F12 -> printc code_c wf1 wf2 | F21 -> printc code_c wf2 wf1 let ferm_print_current = function | coeff, Psibar, V, Psi -> print_fermion_current ovm_FUSE_V_FF ovm_FUSE_F_VF ovm_FUSE_F_FV coeff | coeff, Psibar, VA, Psi -> print_fermion_current ovm_FUSE_VA_FF ovm_FUSE_F_VAF ovm_FUSE_F_FVA coeff | coeff, Psibar, VA2, Psi -> print_fermion_current ovm_FUSE_VA2_FF ovm_FUSE_F_VA2F ovm_FUSE_F_FVA2 coeff | coeff, Psibar, A, Psi -> print_fermion_current ovm_FUSE_A_FF ovm_FUSE_F_AF ovm_FUSE_F_FA coeff | coeff, Psibar, VL, Psi -> print_fermion_current ovm_FUSE_VL_FF ovm_FUSE_F_VLF ovm_FUSE_F_FVL coeff | coeff, Psibar, VR, Psi -> print_fermion_current ovm_FUSE_VR_FF ovm_FUSE_F_VRF ovm_FUSE_F_FVR coeff | coeff, Psibar, VLR, Psi -> print_fermion_current ovm_FUSE_VLR_FF ovm_FUSE_F_VLRF ovm_FUSE_F_FVLR coeff | coeff, Psibar, SP, Psi -> print_fermion_current ovm_FUSE_SP_FF ovm_FUSE_F_SPF ovm_FUSE_F_FSP coeff | coeff, Psibar, S, Psi -> print_fermion_current ovm_FUSE_S_FF ovm_FUSE_F_SF ovm_FUSE_F_FS coeff | coeff, Psibar, P, Psi -> print_fermion_current ovm_FUSE_P_FF ovm_FUSE_F_PF ovm_FUSE_F_FP coeff | coeff, Psibar, SL, Psi -> print_fermion_current ovm_FUSE_SL_FF ovm_FUSE_F_SLF ovm_FUSE_F_FSL coeff | coeff, Psibar, SR, Psi -> print_fermion_current ovm_FUSE_SR_FF ovm_FUSE_F_SRF ovm_FUSE_F_FSR coeff | coeff, Psibar, SLR, Psi -> print_fermion_current ovm_FUSE_SLR_FF ovm_FUSE_F_SLRF ovm_FUSE_F_FSLR coeff | _, Psibar, _, Psi -> invalid_arg "Targets.Fortran.VM: no superpotential here" | _, Chibar, _, _ | _, _, _, Chi -> invalid_arg "Targets.Fortran.VM: Majorana spinors not handled" | _, Gravbar, _, _ | _, _, _, Grav -> invalid_arg "Targets.Fortran.VM: Gravitinos not handled" let children2 rhs = match F.children rhs with | [wf1; wf2] -> (wf1, wf2) | _ -> failwith "Targets.children2: can't happen" let children3 rhs = match F.children rhs with | [wf1; wf2; wf3] -> (wf1, wf2, wf3) | _ -> invalid_arg "Targets.children3: can't happen" let print_vector4 c lhs wf1 wf2 wf3 fusion (coeff, contraction) = let printc r1 r2 r3 = printi ovm_FUSE_V_VVV ~lhs:lhs ~coupl:c ~coeff:coeff ~rhs1:r1 ~rhs2:r2 ~rhs3:r3 in match contraction, fusion with | C_12_34, (F341|F431|F342|F432|F123|F213|F124|F214) | C_13_42, (F241|F421|F243|F423|F132|F312|F134|F314) | C_14_23, (F231|F321|F234|F324|F142|F412|F143|F413) -> printc wf1 wf2 wf3 | C_12_34, (F134|F143|F234|F243|F312|F321|F412|F421) | C_13_42, (F124|F142|F324|F342|F213|F231|F413|F431) | C_14_23, (F123|F132|F423|F432|F214|F241|F314|F341) -> printc wf2 wf3 wf1 | C_12_34, (F314|F413|F324|F423|F132|F231|F142|F241) | C_13_42, (F214|F412|F234|F432|F123|F321|F143|F341) | C_14_23, (F213|F312|F243|F342|F124|F421|F134|F431) -> printc wf1 wf3 wf2 let print_current lookups lhs amplitude rhs = let f = mult_wf lookups.dict amplitude in match F.coupling rhs with | V3 (vertex, fusion, constant) -> let ch1, ch2 = children2 rhs in let wf1 = wf_index lookups.wfmap lookups.n_wfs (f ch1) and wf2 = wf_index lookups.wfmap lookups.n_wfs (f ch2) and p1 = mom_ID lookups.pmap ch1 and p2 = mom_ID lookups.pmap ch2 and const_ID = get_const_ID lookups.cmap constant in let c = if (F.sign rhs) < 0 then - const_ID else const_ID in begin match vertex with | FBF (coeff, fb, b, f) -> begin match coeff, fb, b, f with | _, Psibar, VLRM, Psi | _, Psibar, SPM, Psi | _, Psibar, TVA, Psi | _, Psibar, TVAM, Psi | _, Psibar, TLR, Psi | _, Psibar, TLRM, Psi | _, Psibar, TRL, Psi | _, Psibar, TRLM, Psi -> failwith "print_current: V3: Momentum dependent fermion couplings not implemented" | _, _, _, _ -> ferm_print_current (coeff, fb, b, f) lhs c wf1 wf2 fusion end | PBP (_, _, _, _) -> failwith "print_current: V3: PBP not implemented" | BBB (_, _, _, _) -> failwith "print_current: V3: BBB not implemented" | GBG (_, _, _, _) -> failwith "print_current: V3: GBG not implemented" | Gauge_Gauge_Gauge coeff -> let printc r1 r2 r3 r4 = printi ovm_FUSE_G_GG ~lhs:lhs ~coupl:c ~coeff:coeff ~rhs1:r1 ~rhs2:r2 ~rhs3:r3 ~rhs4:r4 in begin match fusion with | (F23|F31|F12) -> printc wf1 p1 wf2 p2 | (F32|F13|F21) -> printc wf2 p2 wf1 p1 end | I_Gauge_Gauge_Gauge _ -> failwith "print_current: I_Gauge_Gauge_Gauge: not implemented" | Scalar_Vector_Vector coeff -> let printc code r1 r2 = printi code ~lhs:lhs ~coupl:c ~coeff:coeff ~rhs1:r1 ~rhs2:r2 in begin match fusion with | (F23|F32) -> printc ovm_FUSE_S_VV wf1 wf2 | (F12|F13) -> printc ovm_FUSE_V_SV wf1 wf2 | (F21|F31) -> printc ovm_FUSE_V_SV wf2 wf1 end | Scalar_Scalar_Scalar coeff -> printi ovm_FUSE_S_SS ~lhs:lhs ~coupl:c ~coeff:coeff ~rhs1:wf1 ~rhs2:wf2 | Vector_Scalar_Scalar coeff -> let printc code ?flip:(f = 1) r1 r2 r3 r4 = printi code ~lhs:lhs ~coupl:(c*f) ~coeff:coeff ~rhs1:r1 ~rhs2:r2 ~rhs3:r3 ~rhs4:r4 in begin match fusion with | F23 -> printc ovm_FUSE_V_SS wf1 p1 wf2 p2 | F32 -> printc ovm_FUSE_V_SS wf2 p2 wf1 p1 | F12 -> printc ovm_FUSE_S_VS wf1 p1 wf2 p2 | F21 -> printc ovm_FUSE_S_VS wf2 p2 wf1 p1 | F13 -> printc ovm_FUSE_S_VS wf1 p1 wf2 p2 ~flip:(-1) | F31 -> printc ovm_FUSE_S_VS wf2 p2 wf1 p1 ~flip:(-1) end | Aux_Vector_Vector _ -> failwith "print_current: V3: not implemented" | Aux_Scalar_Scalar _ -> failwith "print_current: V3: not implemented" | Aux_Scalar_Vector _ -> failwith "print_current: V3: not implemented" | Graviton_Scalar_Scalar _ -> failwith "print_current: V3: not implemented" | Graviton_Vector_Vector _ -> failwith "print_current: V3: not implemented" | Graviton_Spinor_Spinor _ -> failwith "print_current: V3: not implemented" | Dim4_Vector_Vector_Vector_T _ -> failwith "print_current: V3: not implemented" | Dim4_Vector_Vector_Vector_L _ -> failwith "print_current: V3: not implemented" | Dim6_Gauge_Gauge_Gauge _ -> failwith "print_current: V3: not implemented" | Dim4_Vector_Vector_Vector_T5 _ -> failwith "print_current: V3: not implemented" | Dim4_Vector_Vector_Vector_L5 _ -> failwith "print_current: V3: not implemented" | Dim6_Gauge_Gauge_Gauge_5 _ -> failwith "print_current: V3: not implemented" | Aux_DScalar_DScalar _ -> failwith "print_current: V3: not implemented" | Aux_Vector_DScalar _ -> failwith "print_current: V3: not implemented" | Dim5_Scalar_Gauge2 coeff -> let printc code r1 r2 r3 r4 = printi code ~lhs:lhs ~coupl:c ~coeff:coeff ~rhs1:r1 ~rhs2:r2 ~rhs3:r3 ~rhs4:r4 in begin match fusion with | (F23|F32) -> printc ovm_FUSE_S_G2 wf1 p1 wf2 p2 | (F12|F13) -> printc ovm_FUSE_G_SG wf1 p1 wf2 p2 | (F21|F31) -> printc ovm_FUSE_G_GS wf2 p2 wf1 p1 end | Dim5_Scalar_Gauge2_Skew coeff -> let printc code ?flip:(f = 1) r1 r2 r3 r4 = printi code ~lhs:lhs ~coupl:(c*f) ~coeff:coeff ~rhs1:r1 ~rhs2:r2 ~rhs3:r3 ~rhs4:r4 in begin match fusion with | (F23|F32) -> printc ovm_FUSE_S_G2_SKEW wf1 p1 wf2 p2 | (F12|F13) -> printc ovm_FUSE_G_SG_SKEW wf1 p1 wf2 p2 | (F21|F31) -> printc ovm_FUSE_G_GS_SKEW wf2 p1 wf1 p2 ~flip:(-1) end | Dim5_Scalar_Vector_Vector_T _ -> failwith "print_current: V3: not implemented" | Dim5_Scalar_Vector_Vector_U _ -> failwith "print_current: V3: not implemented" | Dim5_Scalar_Scalar2 _ -> failwith "print_current: V3: not implemented" | Dim6_Vector_Vector_Vector_T _ -> failwith "print_current: V3: not implemented" | Tensor_2_Vector_Vector _ -> failwith "print_current: V3: not implemented" | Tensor_2_Scalar_Scalar _ -> failwith "print_current: V3: not implemented" | Dim5_Tensor_2_Vector_Vector_1 _ -> failwith "print_current: V3: not implemented" | Dim5_Tensor_2_Vector_Vector_2 _ -> failwith "print_current: V3: not implemented" | Dim7_Tensor_2_Vector_Vector_T _ -> failwith "print_current: V3: not implemented" | Dim5_Scalar_Vector_Vector_TU _ -> failwith "print_current: V3: not implemented" | Scalar_Vector_Vector_t _ -> failwith "print_current: V3: not implemented" | Tensor_2_Vector_Vector_cf _ -> failwith "print_current: V3: not implemented" | Tensor_2_Scalar_Scalar_cf _ -> failwith "print_current: V3: not implemented" | Tensor_2_Vector_Vector_1 _ -> failwith "print_current: V3: not implemented" | Tensor_2_Vector_Vector_t _ -> failwith "print_current: V3: not implemented" | TensorVector_Vector_Vector _ -> failwith "print_current: V3: not implemented" | TensorVector_Vector_Vector_cf _ -> failwith "print_current: V3: not implemented" | TensorVector_Scalar_Scalar _ -> failwith "print_current: V3: not implemented" | TensorVector_Scalar_Scalar_cf _ -> failwith "print_current: V3: not implemented" | TensorScalar_Vector_Vector _ -> failwith "print_current: V3: not implemented" | TensorScalar_Vector_Vector_cf _ -> failwith "print_current: V3: not implemented" | TensorScalar_Scalar_Scalar _ -> failwith "print_current: V3: not implemented" | TensorScalar_Scalar_Scalar_cf _ -> failwith "print_current: V3: not implemented" | Dim6_Scalar_Vector_Vector_D _ -> failwith "print_current: V3: not implemented" | Dim6_Scalar_Vector_Vector_DP _ -> failwith "print_current: V3: not implemented" | Dim6_HAZ_D _ -> failwith "print_current: V3: not implemented" | Dim6_HAZ_DP _ -> failwith "print_current: V3: not implemented" | Dim6_HHH _ -> failwith "print_current: V3: not implemented" | Dim6_Gauge_Gauge_Gauge_i _ -> failwith "print_current: V3: not implemented" | Gauge_Gauge_Gauge_i _ -> failwith "print_current: V3: not implemented" | Dim6_GGG _ -> failwith "print_current: V3: not implemented" | Dim6_AWW_DP _ -> failwith "print_current: V3: not implemented" | Dim6_AWW_DW _ -> failwith "print_current: V3: not implemented" | Dim6_WWZ_DPWDW _ -> failwith "print_current: V3: not implemented" | Dim6_WWZ_DW _ -> failwith "print_current: V3: not implemented" | Dim6_WWZ_D _ -> failwith "print_current: V3: not implemented" | Aux_Gauge_Gauge _ -> failwith "print_current: V3 (Aux_Gauge_Gauge): not implemented" end (* Flip the sign in [c] to account for the~$\mathrm{i}^2$ relative to diagrams with only cubic couplings. *) | V4 (vertex, fusion, constant) -> let ch1, ch2, ch3 = children3 rhs in let wf1 = wf_index lookups.wfmap lookups.n_wfs (f ch1) and wf2 = wf_index lookups.wfmap lookups.n_wfs (f ch2) and wf3 = wf_index lookups.wfmap lookups.n_wfs (f ch3) (*i (*and p1 = mom_ID lookups.pmap ch1*) (*and p2 = mom_ID lookups.pmap ch2*) (*and p3 = mom_ID lookups.pmap ch2*) i*) and const_ID = get_const_ID lookups.cmap constant in let c = if (F.sign rhs) < 0 then const_ID else - const_ID in begin match vertex with | Scalar4 coeff -> printi ovm_FUSE_S_SSS ~lhs:lhs ~coupl:c ~coeff:coeff ~rhs1:wf1 ~rhs2:wf2 ~rhs3:wf3 | Scalar2_Vector2 coeff -> let printc code r1 r2 r3 = printi code ~lhs:lhs ~coupl:c ~coeff:coeff ~rhs1:r1 ~rhs2:r2 ~rhs3:r3 in begin match fusion with | F134 | F143 | F234 | F243 -> printc ovm_FUSE_S_SVV wf1 wf2 wf3 | F314 | F413 | F324 | F423 -> printc ovm_FUSE_S_SVV wf2 wf1 wf3 | F341 | F431 | F342 | F432 -> printc ovm_FUSE_S_SVV wf3 wf1 wf2 | F312 | F321 | F412 | F421 -> printc ovm_FUSE_V_SSV wf2 wf3 wf1 | F231 | F132 | F241 | F142 -> printc ovm_FUSE_V_SSV wf1 wf3 wf2 | F123 | F213 | F124 | F214 -> printc ovm_FUSE_V_SSV wf1 wf2 wf3 end | Vector4 contractions -> List.iter (print_vector4 c lhs wf1 wf2 wf3 fusion) contractions | Vector4_K_Matrix_tho _ | Vector4_K_Matrix_jr _ | Vector4_K_Matrix_cf_t0 _ | Vector4_K_Matrix_cf_t1 _ | Vector4_K_Matrix_cf_t2 _ | Vector4_K_Matrix_cf_t_rsi _ | Vector4_K_Matrix_cf_m0 _ | Vector4_K_Matrix_cf_m1 _ | Vector4_K_Matrix_cf_m7 _ | DScalar2_Vector2_K_Matrix_ms _ | DScalar2_Vector2_m_0_K_Matrix_cf _ | DScalar2_Vector2_m_1_K_Matrix_cf _ | DScalar2_Vector2_m_7_K_Matrix_cf _ | DScalar4_K_Matrix_ms _ -> failwith "print_current: V4: K_Matrix not implemented" | Dim8_Scalar2_Vector2_1 _ | Dim8_Scalar2_Vector2_2 _ | Dim8_Scalar2_Vector2_m_0 _ | Dim8_Scalar2_Vector2_m_1 _ | Dim8_Scalar2_Vector2_m_7 _ | Dim8_Scalar4 _ -> failwith "print_current: V4: not implemented" | Dim8_Vector4_t_0 _ -> failwith "print_current: V4: not implemented" | Dim8_Vector4_t_1 _ -> failwith "print_current: V4: not implemented" | Dim8_Vector4_t_2 _ -> failwith "print_current: V4: not implemented" | Dim8_Vector4_m_0 _ -> failwith "print_current: V4: not implemented" | Dim8_Vector4_m_1 _ -> failwith "print_current: V4: not implemented" | Dim8_Vector4_m_7 _ -> failwith "print_current: V4: not implemented" | GBBG _ -> failwith "print_current: V4: GBBG not implemented" | DScalar4 _ | DScalar2_Vector2 _ -> failwith "print_current: V4: DScalars not implemented" | Dim6_H4_P2 _ -> failwith "print_current: V4: not implemented" | Dim6_AHWW_DPB _ -> failwith "print_current: V4: not implemented" | Dim6_AHWW_DPW _ -> failwith "print_current: V4: not implemented" | Dim6_AHWW_DW _ -> failwith "print_current: V4: not implemented" | Dim6_Vector4_DW _ -> failwith "print_current: V4: not implemented" | Dim6_Vector4_W _ -> failwith "print_current: V4: not implemented" | Dim6_Scalar2_Vector2_D _ -> failwith "print_current: V4: not implemented" | Dim6_Scalar2_Vector2_DP _ -> failwith "print_current: V4: not implemented" | Dim6_HWWZ_DW _ -> failwith "print_current: V4: not implemented" | Dim6_HWWZ_DPB _ -> failwith "print_current: V4: not implemented" | Dim6_HWWZ_DDPW _ -> failwith "print_current: V4: not implemented" | Dim6_HWWZ_DPW _ -> failwith "print_current: V4: not implemented" | Dim6_AHHZ_D _ -> failwith "print_current: V4: not implemented" | Dim6_AHHZ_DP _ -> failwith "print_current: V4: not implemented" | Dim6_AHHZ_PB _ -> failwith "print_current: V4: not implemented" | Dim6_Scalar2_Vector2_PB _ -> failwith "print_current: V4: not implemented" | Dim6_HHZZ_T _ -> failwith "print_current: V4: not implemented" end | Vn (_, _, _) -> invalid_arg "Targets.print_current: n-ary fusion." (* \thocwmodulesubsection{Fusions} *) let print_fusion lookups lhs_momID fusion amplitude = if F.on_shell amplitude (F.lhs fusion) then failwith "print_fusion: on_shell projectors not implemented!"; if F.is_gauss amplitude (F.lhs fusion) then failwith "print_fusion: gauss amplitudes not implemented!"; let lhs_wf = mult_wf lookups.dict amplitude (F.lhs fusion) in let lhs_wfID = wf_index lookups.wfmap lookups.n_wfs lhs_wf in let f = F.flavor (F.lhs fusion) in let pdg = CM.pdg f in let w = begin match CM.width f with | Vanishing | Fudged -> 0 | Constant -> 1 | Timelike -> 2 | Complex_Mass -> 3 - | Running -> failwith "Targets.VM: running width not available" + | Running -> 4 | Custom _ -> failwith "Targets.VM: custom width not available" end in let propagate code = printi code ~lhs:lhs_wfID ~rhs1:lhs_momID ~coupl:(abs(pdg)) ~coeff:w ~rhs4:(get_ID' amp_compare lookups.amap amplitude) in begin match CM.propagator f with | Prop_Scalar -> propagate ovm_PROPAGATE_SCALAR | Prop_Col_Scalar -> propagate ovm_PROPAGATE_COL_SCALAR | Prop_Ghost -> propagate ovm_PROPAGATE_GHOST | Prop_Spinor -> propagate ovm_PROPAGATE_SPINOR | Prop_ConjSpinor -> propagate ovm_PROPAGATE_CONJSPINOR | Prop_Majorana -> propagate ovm_PROPAGATE_MAJORANA | Prop_Col_Majorana -> propagate ovm_PROPAGATE_COL_MAJORANA | Prop_Unitarity -> propagate ovm_PROPAGATE_UNITARITY | Prop_Col_Unitarity -> propagate ovm_PROPAGATE_COL_UNITARITY | Prop_Feynman -> propagate ovm_PROPAGATE_FEYNMAN | Prop_Col_Feynman -> propagate ovm_PROPAGATE_COL_FEYNMAN | Prop_Vectorspinor -> propagate ovm_PROPAGATE_VECTORSPINOR | Prop_Tensor_2 -> propagate ovm_PROPAGATE_TENSOR2 | Aux_Col_Scalar | Aux_Col_Vector | Aux_Col_Tensor_1 -> failwith "print_fusion: Aux_Col_* not implemented!" | Aux_Vector | Aux_Tensor_1 | Aux_Scalar | Aux_Spinor | Aux_ConjSpinor | Aux_Majorana | Only_Insertion -> propagate ovm_PROPAGATE_NONE | Prop_Gauge _ -> failwith "print_fusion: Prop_Gauge not implemented!" | Prop_Tensor_pure -> failwith "print_fusion: Prop_Tensor_pure not implemented!" | Prop_Vector_pure -> failwith "print_fusion: Prop_Vector_pure not implemented!" | Prop_Rxi _ -> failwith "print_fusion: Prop_Rxi not implemented!" | Prop_UFO _ -> failwith "print_fusion: Prop_UFO not implemented!" end; (* Since the OVM knows that we want to propagate a wf, we can send the necessary fusions now. *) List.iter (print_current lookups lhs_wfID amplitude) (F.rhs fusion) let print_all_fusions lookups = let fusions = CF.fusions lookups.amplitudes in let fset = List.fold_left (fun s x -> FSet.add x s) FSet.empty fusions in ignore (List.fold_left (fun level (f, amplitude) -> let wf = F.lhs f in let lhs_momID = mom_ID lookups.pmap wf in let level' = List.length (F.momentum_list wf) in if (level' > level && level' > 2) then break (); print_fusion lookups lhs_momID f amplitude; level') 1 (FSet.elements fset) ) (* \thocwmodulesubsection{Brakets} *) let print_braket lookups amplitude braket = let bra = F.bra braket and ket = F.ket braket in let braID = wf_index lookups.wfmap lookups.n_wfs (mult_wf lookups.dict amplitude bra) in List.iter (print_current lookups braID amplitude) ket (* \begin{equation} \ii T = \ii^{\#\text{vertices}}\ii^{\#\text{propagators}} \cdots = \ii^{n-2}\ii^{n-3} \cdots = -\ii(-1)^n \cdots \end{equation} *) (* All brakets for one cflow amplitude should be calculated by one thread to avoid multiple access on the same memory (amplitude).*) let print_brakets lookups (amplitude, i) = let n = List.length (F.externals amplitude) in let sign = if n mod 2 = 0 then -1 else 1 and sym = F.symmetry amplitude in printi ovm_CALC_BRAKET ~lhs:i ~rhs1:sym ~coupl:sign; amplitude |> F.brakets |> List.iter (print_braket lookups amplitude) (* Fortran arrays/OCaml lists start on 1/0. The amplitude list is sorted by [amp_compare] according to their color flows. In this way the amp array is sorted in the same way as [table_color_factors]. *) let print_all_brakets lookups = let g i elt = print_brakets lookups (elt, i+1) in lookups.amplitudes |> CF.processes |> List.sort amp_compare |> ThoList.iteri g 0 (* \thocwmodulesubsection{Couplings} *) (* For now we only care to catch the arrays [gncneu], [gnclep], [gncup] and [gncdown] of the SM. This will need an overhaul when it is clear how we store the type information of coupling constants. *) let strip_array_tag = function | Real_Array x -> x | Complex_Array x -> x let array_constants_list = let params = M.parameters() and strip_to_constant (lhs, _) = strip_array_tag lhs in List.map strip_to_constant params.derived_arrays let is_array x = List.mem x array_constants_list let constants_map = let first = fun (x, _, _) -> x in let second = fun (_, y, _) -> y in let third = fun (_, _, z) -> z in let v3 = List.map third (first (M.vertices () )) and v4 = List.map third (second (M.vertices () )) in let set = List.fold_left (fun s x -> CSet.add x s) CSet.empty (v3 @ v4) in let (arrays, singles) = CSet.partition is_array set in (singles |> CSet.elements |> map_of_list, arrays |> CSet.elements |> map_of_list) (* \thocwmodulesubsection{Output calls} *) let amplitudes_to_channel (cmdline : string) (oc : out_channel) (diagnostics : (diagnostic * bool) list ) (amplitudes : CF.amplitudes) = set_formatter_out_channel oc; if (num_particles amplitudes = 0) then begin print_description cmdline; print_zero_header (); nl () end else begin let (wfset, amap) = wfset_amps amplitudes in let pset = expand_pset (momenta_set wfset) and n_wfs = num_wfs wfset in let wfmap = wf_map_of_list (WFSet.elements wfset) and pmap = map_of_list (ISet.elements pset) and cmap = constants_map in let lookups = {pmap = pmap; wfmap = wfmap; cmap = cmap; amap = amap; n_wfs = n_wfs; amplitudes = amplitudes; dict = CF.dictionary amplitudes} in print_description cmdline; print_header lookups wfset; print_spin_table amplitudes; print_flavor_tables amplitudes; print_color_tables amplitudes; printf "@\n%s" ("OVM instructions for momenta addition," ^ " fusions and brakets start here: "); break (); add_all_mom lookups pset; print_ext_amps lookups; break (); print_all_fusions lookups; break (); print_all_brakets lookups; break (); nl (); print_flush () end let parameters_to_fortran oc _ = (*i The -params options is used as wrapper between OVM and Whizard. Most * trouble for the OVM comes from the array dimensionalities of couplings * but O'Mega should also know whether a constant is real or complex. * Hopefully all will be clearer with the fully general Lorentz structures * and UFO support. For now, we stick with this brute-force solution. i*) set_formatter_out_channel oc; let arrays_to_set = not (IMap.is_empty (snd constants_map)) in let set_coupl ty dim cmap = IMap.iter (fun key elt -> printf " %s(%s%d) = %s" ty dim key (M.constant_symbol elt); nl () ) cmap in let declarations () = printf " complex(%s), dimension(%d) :: ovm_coupl_cmplx" !kind (constants_map |> fst |> largest_key); nl (); if arrays_to_set then printf " complex(%s), dimension(2, %d) :: ovm_coupl_cmplx2" !kind (constants_map |> snd |> largest_key); nl () in let print_line str = printf "%s" str; nl() in let print_md5sum = function | Some s -> print_line " function md5sum ()"; print_line " character(len=32) :: md5sum"; print_line (" bytecode_file = '" ^ !bytecode_file ^ "'"); print_line " call initialize_vm (vm, bytecode_file)"; print_line " ! DON'T EVEN THINK of modifying the following line!"; print_line (" md5sum = '" ^ s ^ "'"); print_line " end function md5sum"; | None -> () in let print_inquiry_function_openmp () = begin print_line " pure function openmp_supported () result (status)"; print_line " logical :: status"; print_line (" status = " ^ (if !openmp then ".true." else ".false.")); print_line " end function openmp_supported"; nl () end in let print_interface whizard = if whizard then begin print_line " subroutine init (par, scheme)"; print_line " real(kind=default), dimension(*), intent(in) :: par"; print_line " integer, intent(in) :: scheme"; print_line (" bytecode_file = '" ^ !bytecode_file ^ "'"); print_line " call import_from_whizard (par, scheme)"; print_line " call initialize_vm (vm, bytecode_file)"; print_line " end subroutine init"; nl (); print_line " subroutine final ()"; print_line " call vm%final ()"; print_line " end subroutine final"; nl (); print_line " subroutine update_alpha_s (alpha_s)"; print_line (" real(kind=" ^ !kind ^ "), intent(in) :: alpha_s"); print_line " call model_update_alpha_s (alpha_s)"; print_line " end subroutine update_alpha_s"; nl () end else begin print_line " subroutine init ()"; print_line (" bytecode_file = '" ^ !bytecode_file ^ "'"); print_line " call init_parameters ()"; print_line " call initialize_vm (vm, bytecode_file)"; print_line " end subroutine" end in let print_lookup_functions () = begin print_line " pure function number_particles_in () result (n)"; print_line " integer :: n"; print_line " n = vm%number_particles_in ()"; print_line " end function number_particles_in"; nl(); print_line " pure function number_particles_out () result (n)"; print_line " integer :: n"; print_line " n = vm%number_particles_out ()"; print_line " end function number_particles_out"; nl(); print_line " pure function number_spin_states () result (n)"; print_line " integer :: n"; print_line " n = vm%number_spin_states ()"; print_line " end function number_spin_states"; nl(); print_line " pure subroutine spin_states (a)"; print_line " integer, dimension(:,:), intent(out) :: a"; print_line " call vm%spin_states (a)"; print_line " end subroutine spin_states"; nl(); print_line " pure function number_flavor_states () result (n)"; print_line " integer :: n"; print_line " n = vm%number_flavor_states ()"; print_line " end function number_flavor_states"; nl(); print_line " pure subroutine flavor_states (a)"; print_line " integer, dimension(:,:), intent(out) :: a"; print_line " call vm%flavor_states (a)"; print_line " end subroutine flavor_states"; nl(); print_line " pure function number_color_indices () result (n)"; print_line " integer :: n"; print_line " n = vm%number_color_indices ()"; print_line " end function number_color_indices"; nl(); print_line " pure function number_color_flows () result (n)"; print_line " integer :: n"; print_line " n = vm%number_color_flows ()"; print_line " end function number_color_flows"; nl(); print_line " pure subroutine color_flows (a, g)"; print_line " integer, dimension(:,:,:), intent(out) :: a"; print_line " logical, dimension(:,:), intent(out) :: g"; print_line " call vm%color_flows (a, g)"; print_line " end subroutine color_flows"; nl(); print_line " pure function number_color_factors () result (n)"; print_line " integer :: n"; print_line " n = vm%number_color_factors ()"; print_line " end function number_color_factors"; nl(); print_line " pure subroutine color_factors (cf)"; print_line " use omega_color"; print_line " type(omega_color_factor), dimension(:), intent(out) :: cf"; print_line " call vm%color_factors (cf)"; print_line " end subroutine color_factors"; nl(); print_line " !pure unless OpenMP"; print_line " !pure function color_sum (flv, hel) result (amp2)"; print_line " function color_sum (flv, hel) result (amp2)"; print_line " use kinds"; print_line " integer, intent(in) :: flv, hel"; print_line " real(kind=default) :: amp2"; print_line " amp2 = vm%color_sum (flv, hel)"; print_line " end function color_sum"; nl(); print_line " subroutine new_event (p)"; print_line " use kinds"; print_line " real(kind=default), dimension(0:3,*), intent(in) :: p"; print_line " call vm%new_event (p)"; print_line " end subroutine new_event"; nl(); print_line " subroutine reset_helicity_selection (threshold, cutoff)"; print_line " use kinds"; print_line " real(kind=default), intent(in) :: threshold"; print_line " integer, intent(in) :: cutoff"; print_line " call vm%reset_helicity_selection (threshold, cutoff)"; print_line " end subroutine reset_helicity_selection"; nl(); print_line " pure function is_allowed (flv, hel, col) result (yorn)"; print_line " logical :: yorn"; print_line " integer, intent(in) :: flv, hel, col"; print_line " yorn = vm%is_allowed (flv, hel, col)"; print_line " end function is_allowed"; nl(); print_line " pure function get_amplitude (flv, hel, col) result (amp_result)"; print_line " use kinds"; print_line " complex(kind=default) :: amp_result"; print_line " integer, intent(in) :: flv, hel, col"; print_line " amp_result = vm%get_amplitude(flv, hel, col)"; print_line " end function get_amplitude"; nl(); end in print_line ("module " ^ !wrapper_module); print_line (" use " ^ !parameter_module_external); print_line " use iso_varying_string, string_t => varying_string"; print_line " use kinds"; print_line " use omegavm95"; print_line " implicit none"; print_line " private"; print_line " type(vm_t) :: vm"; print_line " type(string_t) :: bytecode_file"; print_line (" public :: number_particles_in, number_particles_out," ^ " number_spin_states, &"); print_line (" spin_states, number_flavor_states, flavor_states," ^ " number_color_indices, &"); print_line (" number_color_flows, color_flows," ^ " number_color_factors, color_factors, &"); print_line (" color_sum, new_event, reset_helicity_selection," ^ " is_allowed, get_amplitude, &"); print_line (" init, " ^ (match !md5sum with Some _ -> "md5sum, " | None -> "") ^ "openmp_supported"); if !whizard then print_line (" public :: final, update_alpha_s") else print_line (" public :: initialize_vm"); declarations (); print_line "contains"; print_line " subroutine setup_couplings ()"; set_coupl "ovm_coupl_cmplx" "" (fst constants_map); if arrays_to_set then set_coupl "ovm_coupl_cmplx2" ":," (snd constants_map); print_line " end subroutine setup_couplings"; print_line " subroutine initialize_vm (vm, bytecode_file)"; print_line " class(vm_t), intent(out) :: vm"; print_line " type(string_t), intent(in) :: bytecode_file"; print_line " type(string_t) :: version"; print_line " type(string_t) :: model"; print_line (" version = 'OVM " ^ version ^ "'"); print_line (" model = 'Model " ^ model_name ^ "'"); print_line " call setup_couplings ()"; print_line " call vm%init (bytecode_file, version, model, verbose=.False., &"; print_line " coupl_cmplx=ovm_coupl_cmplx, &"; if arrays_to_set then print_line " coupl_cmplx2=ovm_coupl_cmplx2, &"; print_line (" mass=mass, width=width, openmp=" ^ (if !openmp then ".true." else ".false.") ^ ")"); print_line " end subroutine initialize_vm"; nl(); print_md5sum !md5sum; print_inquiry_function_openmp (); print_interface !whizard; print_lookup_functions (); print_line ("end module " ^ !wrapper_module) let parameters_to_channel oc = parameters_to_fortran oc (CM.parameters ()) end (* \thocwmodulesection{\texttt{Fortran\,90/95}} *) (* \thocwmodulesubsection{Dirac Fermions} We factor out the code for fermions so that we can use the simpler implementation for Dirac fermions if the model contains no Majorana fermions. *) module type Fermions = sig open Coupling val psi_type : string val psibar_type : string val chi_type : string val grav_type : string val psi_incoming : string val brs_psi_incoming : string val psibar_incoming : string val brs_psibar_incoming : string val chi_incoming : string val brs_chi_incoming : string val grav_incoming : string val psi_outgoing : string val brs_psi_outgoing : string val psibar_outgoing : string val brs_psibar_outgoing : string val chi_outgoing : string val brs_chi_outgoing : string val grav_outgoing : string val psi_propagator : string val psibar_propagator : string val chi_propagator : string val grav_propagator : string val psi_projector : string val psibar_projector : string val chi_projector : string val grav_projector : string val psi_gauss : string val psibar_gauss : string val chi_gauss : string val grav_gauss : string val print_current : int * fermionbar * boson * fermion -> string -> string -> string -> fuse2 -> unit val print_current_mom : int * fermionbar * boson * fermion -> string -> string -> string -> string -> string -> string -> fuse2 -> unit val print_current_p : int * fermion * boson * fermion -> string -> string -> string -> fuse2 -> unit val print_current_b : int * fermionbar * boson * fermionbar -> string -> string -> string -> fuse2 -> unit val print_current_g : int * fermionbar * boson * fermion -> string -> string -> string -> string -> string -> string -> fuse2 -> unit val print_current_g4 : int * fermionbar * boson2 * fermion -> string -> string -> string -> string -> fuse3 -> unit val reverse_braket : lorentz -> bool val use_module : string val require_library : string list end module Fortran_Fermions : Fermions = struct open Coupling open Format let psi_type = "spinor" let psibar_type = "conjspinor" let chi_type = "???" let grav_type = "???" let psi_incoming = "u" let brs_psi_incoming = "brs_u" let psibar_incoming = "vbar" let brs_psibar_incoming = "brs_vbar" let chi_incoming = "???" let brs_chi_incoming = "???" let grav_incoming = "???" let psi_outgoing = "v" let brs_psi_outgoing = "brs_v" let psibar_outgoing = "ubar" let brs_psibar_outgoing = "brs_ubar" let chi_outgoing = "???" let brs_chi_outgoing = "???" let grav_outgoing = "???" let psi_propagator = "pr_psi" let psibar_propagator = "pr_psibar" let chi_propagator = "???" let grav_propagator = "???" let psi_projector = "pj_psi" let psibar_projector = "pj_psibar" let chi_projector = "???" let grav_projector = "???" let psi_gauss = "pg_psi" let psibar_gauss = "pg_psibar" let chi_gauss = "???" let grav_gauss = "???" let format_coupling coeff c = match coeff with | 1 -> c | -1 -> "(-" ^ c ^")" | coeff -> string_of_int coeff ^ "*" ^ c let format_coupling_2 coeff c = match coeff with | 1 -> c | -1 -> "-" ^ c | coeff -> string_of_int coeff ^ "*" ^ c (* \begin{dubious} JR's coupling constant HACK, necessitated by tho's bad design descition. \end{dubious} *) let fastener s i ?p ?q () = try let offset = (String.index s '(') in if ((String.get s (String.length s - 1)) != ')') then failwith "fastener: wrong usage of parentheses" else let func_name = (String.sub s 0 offset) and tail = (String.sub s (succ offset) (String.length s - offset - 2)) in if (String.contains func_name ')') || (String.contains tail '(') || (String.contains tail ')') then failwith "fastener: wrong usage of parentheses" else func_name ^ "(" ^ string_of_int i ^ "," ^ tail ^ ")" with | Not_found -> if (String.contains s ')') then failwith "fastener: wrong usage of parentheses" else match p with | None -> s ^ "(" ^ string_of_int i ^ ")" | Some p -> match q with | None -> s ^ "(" ^ p ^ "*" ^ p ^ "," ^ string_of_int i ^ ")" | Some q -> s ^ "(" ^ p ^ "," ^ q ^ "," ^ string_of_int i ^ ")" let print_fermion_current coeff f c wf1 wf2 fusion = let c = format_coupling coeff c in match fusion with | F13 -> printf "%s_ff(%s,%s,%s)" f c wf1 wf2 | F31 -> printf "%s_ff(%s,%s,%s)" f c wf2 wf1 | F23 -> printf "f_%sf(%s,%s,%s)" f c wf1 wf2 | F32 -> printf "f_%sf(%s,%s,%s)" f c wf2 wf1 | F12 -> printf "f_f%s(%s,%s,%s)" f c wf1 wf2 | F21 -> printf "f_f%s(%s,%s,%s)" f c wf2 wf1 (* \begin{dubious} Using a two element array for the combined vector-axial and scalar-pseudo couplings helps to support HELAS as well. Since we will probably never support general boson couplings with HELAS, it might be retired in favor of two separate variables. For this [Model.constant_symbol] has to be generalized. \end{dubious} *) (* \begin{dubious} NB: passing the array instead of two separate constants would be a \emph{bad} idea, because the support for Majorana spinors below will have to flip signs! \end{dubious} *) let print_fermion_current2 coeff f c wf1 wf2 fusion = let c = format_coupling_2 coeff c in let c1 = fastener c 1 () and c2 = fastener c 2 () in match fusion with | F13 -> printf "%s_ff(%s,%s,%s,%s)" f c1 c2 wf1 wf2 | F31 -> printf "%s_ff(%s,%s,%s,%s)" f c1 c2 wf2 wf1 | F23 -> printf "f_%sf(%s,%s,%s,%s)" f c1 c2 wf1 wf2 | F32 -> printf "f_%sf(%s,%s,%s,%s)" f c1 c2 wf2 wf1 | F12 -> printf "f_f%s(%s,%s,%s,%s)" f c1 c2 wf1 wf2 | F21 -> printf "f_f%s(%s,%s,%s,%s)" f c1 c2 wf2 wf1 let print_fermion_current_mom_v1 coeff f c wf1 wf2 p1 p2 p12 fusion = let c = format_coupling coeff c in let c1 = fastener c 1 and c2 = fastener c 2 in match fusion with | F13 -> printf "%s_ff(%s,%s,%s,%s)" f (c1 ~p:p12 ()) (c2 ~p:p12 ()) wf1 wf2 | F31 -> printf "%s_ff(%s,%s,%s,%s)" f (c1 ~p:p12 ()) (c2 ~p:p12 ()) wf2 wf1 | F23 -> printf "f_%sf(%s,%s,%s,%s)" f (c1 ~p:p1 ()) (c2 ~p:p1 ()) wf1 wf2 | F32 -> printf "f_%sf(%s,%s,%s,%s)" f (c1 ~p:p2 ()) (c2 ~p:p2 ()) wf2 wf1 | F12 -> printf "f_f%s(%s,%s,%s,%s)" f (c1 ~p:p2 ()) (c2 ~p:p2 ()) wf1 wf2 | F21 -> printf "f_f%s(%s,%s,%s,%s)" f (c1 ~p:p1 ()) (c2 ~p:p1 ()) wf2 wf1 let print_fermion_current_mom_v2 coeff f c wf1 wf2 p1 p2 p12 fusion = let c = format_coupling coeff c in let c1 = fastener c 1 and c2 = fastener c 2 in match fusion with | F13 -> printf "%s_ff(%s,%s,@,%s,%s,%s)" f (c1 ~p:p12 ()) (c2 ~p:p12 ()) wf1 wf2 p12 | F31 -> printf "%s_ff(%s,%s,@,%s,%s,%s)" f (c1 ~p:p12 ()) (c2 ~p:p12 ()) wf2 wf1 p12 | F23 -> printf "f_%sf(%s,%s,@,%s,%s,%s)" f (c1 ~p:p1 ()) (c2 ~p:p1 ()) wf1 wf2 p1 | F32 -> printf "f_%sf(%s,%s,@,%s,%s,%s)" f (c1 ~p:p2 ()) (c2 ~p:p2 ()) wf2 wf1 p2 | F12 -> printf "f_f%s(%s,%s,@,%s,%s,%s)" f (c1 ~p:p2 ()) (c2 ~p:p2 ()) wf1 wf2 p2 | F21 -> printf "f_f%s(%s,%s,@,%s,%s,%s)" f (c1 ~p:p1 ()) (c2 ~p:p1 ()) wf2 wf1 p1 let print_fermion_current_mom_ff coeff f c wf1 wf2 p1 p2 p12 fusion = let c = format_coupling coeff c in let c1 = fastener c 1 and c2 = fastener c 2 in match fusion with | F13 -> printf "%s_ff(%s,%s,%s,%s)" f (c1 ~p:p1 ~q:p2 ()) (c2 ~p:p1 ~q:p2 ()) wf1 wf2 | F31 -> printf "%s_ff(%s,%s,%s,%s)" f (c1 ~p:p1 ~q:p2 ()) (c2 ~p:p1 ~q:p2 ()) wf2 wf1 | F23 -> printf "f_%sf(%s,%s,%s,%s)" f (c1 ~p:p12 ~q:p2 ()) (c2 ~p:p12 ~q:p2 ()) wf1 wf2 | F32 -> printf "f_%sf(%s,%s,%s,%s)" f (c1 ~p:p12 ~q:p1 ()) (c2 ~p:p12 ~q:p1 ()) wf2 wf1 | F12 -> printf "f_f%s(%s,%s,%s,%s)" f (c1 ~p:p12 ~q:p1 ()) (c2 ~p:p12 ~q:p1 ()) wf1 wf2 | F21 -> printf "f_f%s(%s,%s,%s,%s)" f (c1 ~p:p12 ~q:p2 ()) (c2 ~p:p12 ~q:p2 ()) wf2 wf1 let print_current = function | coeff, Psibar, VA, Psi -> print_fermion_current2 coeff "va" | coeff, Psibar, VA2, Psi -> print_fermion_current coeff "va2" | coeff, Psibar, VA3, Psi -> print_fermion_current coeff "va3" | coeff, Psibar, V, Psi -> print_fermion_current coeff "v" | coeff, Psibar, A, Psi -> print_fermion_current coeff "a" | coeff, Psibar, VL, Psi -> print_fermion_current coeff "vl" | coeff, Psibar, VR, Psi -> print_fermion_current coeff "vr" | coeff, Psibar, VLR, Psi -> print_fermion_current2 coeff "vlr" | coeff, Psibar, SP, Psi -> print_fermion_current2 coeff "sp" | coeff, Psibar, S, Psi -> print_fermion_current coeff "s" | coeff, Psibar, P, Psi -> print_fermion_current coeff "p" | coeff, Psibar, SL, Psi -> print_fermion_current coeff "sl" | coeff, Psibar, SR, Psi -> print_fermion_current coeff "sr" | coeff, Psibar, SLR, Psi -> print_fermion_current2 coeff "slr" | _, Psibar, _, Psi -> invalid_arg "Targets.Fortran_Fermions: no superpotential here" | _, Chibar, _, _ | _, _, _, Chi -> invalid_arg "Targets.Fortran_Fermions: Majorana spinors not handled" | _, Gravbar, _, _ | _, _, _, Grav -> invalid_arg "Targets.Fortran_Fermions: Gravitinos not handled" let print_current_mom = function | coeff, Psibar, VLRM, Psi -> print_fermion_current_mom_v1 coeff "vlr" | coeff, Psibar, VAM, Psi -> print_fermion_current_mom_ff coeff "va" | coeff, Psibar, VA3M, Psi -> print_fermion_current_mom_ff coeff "va3" | coeff, Psibar, SPM, Psi -> print_fermion_current_mom_v1 coeff "sp" | coeff, Psibar, TVA, Psi -> print_fermion_current_mom_v1 coeff "tva" | coeff, Psibar, TVAM, Psi -> print_fermion_current_mom_v2 coeff "tvam" | coeff, Psibar, TLR, Psi -> print_fermion_current_mom_v1 coeff "tlr" | coeff, Psibar, TLRM, Psi -> print_fermion_current_mom_v2 coeff "tlrm" | coeff, Psibar, TRL, Psi -> print_fermion_current_mom_v1 coeff "trl" | coeff, Psibar, TRLM, Psi -> print_fermion_current_mom_v2 coeff "trlm" | _, Psibar, _, Psi -> invalid_arg "Targets.Fortran_Fermions: only sigma tensor coupling here" | _, Chibar, _, _ | _, _, _, Chi -> invalid_arg "Targets.Fortran_Fermions: Majorana spinors not handled" | _, Gravbar, _, _ | _, _, _, Grav -> invalid_arg "Targets.Fortran_Fermions: Gravitinos not handled" let print_current_p = function | _, _, _, _ -> invalid_arg "Targets.Fortran_Fermions: No clashing arrows here" let print_current_b = function | _, _, _, _ -> invalid_arg "Targets.Fortran_Fermions: No clashing arrows here" let print_current_g = function | _, _, _, _ -> invalid_arg "Targets.Fortran_Fermions: No gravitinos here" let print_current_g4 = function | _, _, _, _ -> invalid_arg "Targets.Fortran_Fermions: No gravitinos here" let reverse_braket= function | Spinor -> true | _ -> false let use_module = "omega95" let require_library = ["omega_spinors_2010_01_A"; "omega_spinor_cpls_2010_01_A"] end (* \thocwmodulesubsection{Main Functor} *) module Make_Fortran (Fermions : Fermions) (Fusion_Maker : Fusion.Maker) (P : Momentum.T) (M : Model.T) = struct let require_library = Fermions.require_library @ [ "omega_vectors_2010_01_A"; "omega_polarizations_2010_01_A"; "omega_couplings_2010_01_A"; "omega_color_2010_01_A"; "omega_utils_2010_01_A" ] module CM = Colorize.It(M) module F = Fusion_Maker(P)(M) module CF = Fusion.Multi(Fusion_Maker)(P)(M) type amplitudes = CF.amplitudes open Coupling open Format type output_mode = | Single_Function | Single_Module of int | Single_File of int | Multi_File of int let line_length = ref 80 let continuation_lines = ref (-1) (* 255 *) let kind = ref "default" let fortran95 = ref true let module_name = ref "omega_amplitude" let output_mode = ref (Single_Module 10) let use_modules = ref [] let whizard = ref false let amp_triv = ref false let parameter_module = ref "" let md5sum = ref None let no_write = ref false let km_write = ref false let km_pure = ref false let km_2_write = ref false let km_2_pure = ref false let openmp = ref false let pure_unless_openmp = false let options = Options.create [ "90", Arg.Clear fortran95, "don't use Fortran95 features that are not in Fortran90"; "kind", Arg.String (fun s -> kind := s), "real and complex kind (default: " ^ !kind ^ ")"; "width", Arg.Int (fun w -> line_length := w), "maximum line length"; "continuation", Arg.Int (fun l -> continuation_lines := l), "maximum # of continuation lines"; "module", Arg.String (fun s -> module_name := s), "module name"; "single_function", Arg.Unit (fun () -> output_mode := Single_Function), "compute the matrix element(s) in a monolithic function"; "split_function", Arg.Int (fun n -> output_mode := Single_Module n), "split the matrix element(s) into small functions [default, size = 10]"; "split_module", Arg.Int (fun n -> output_mode := Single_File n), "split the matrix element(s) into small modules"; "split_file", Arg.Int (fun n -> output_mode := Multi_File n), "split the matrix element(s) into small files"; "use", Arg.String (fun s -> use_modules := s :: !use_modules), "use module"; "parameter_module", Arg.String (fun s -> parameter_module := s), "parameter_module"; "md5sum", Arg.String (fun s -> md5sum := Some s), "transfer MD5 checksum"; "whizard", Arg.Set whizard, "include WHIZARD interface"; "amp_triv", Arg.Set amp_triv, "only print trivial amplitude"; "no_write", Arg.Set no_write, "no 'write' statements"; "kmatrix_write", Arg.Set km_2_write, "write K matrix functions"; "kmatrix_2_write", Arg.Set km_write, "write K matrix 2 functions"; "kmatrix_write_pure", Arg.Set km_pure, "write K matrix pure functions"; "kmatrix_2_write_pure", Arg.Set km_2_pure, "write Kmatrix2pure functions"; "openmp", Arg.Set openmp, "activate OpenMP support in generated code"] (* Fortran style line continuation: *) let nl = Format_Fortran.newline let print_list = function | [] -> () | a :: rest -> print_string a; List.iter (fun s -> printf ",@ %s" s) rest (* \thocwmodulesubsection{Variables and Declarations} *) (* ["NC"] is already used up in the module ["constants"]: *) let nc_parameter = "N_" let omega_color_factor_abbrev = "OCF" let openmp_tld_type = "thread_local_data" let openmp_tld = "tld" let flavors_symbol ?(decl = false) flavors = (if !openmp && not decl then openmp_tld ^ "%" else "" ) ^ "oks_" ^ String.concat "" (List.map CM.flavor_symbol flavors) let p2s p = if p >= 0 && p <= 9 then string_of_int p else if p <= 36 then String.make 1 (Char.chr (Char.code 'A' + p - 10)) else "_" let format_momentum p = "p" ^ String.concat "" (List.map p2s p) let format_p wf = String.concat "" (List.map p2s (F.momentum_list wf)) let ext_momentum wf = match F.momentum_list wf with | [n] -> n | _ -> invalid_arg "Targets.Fortran.ext_momentum" module PSet = Set.Make (struct type t = int list let compare = compare end) module WFSet = Set.Make (struct type t = F.wf let compare = compare end) let add_tag wf name = match F.wf_tag wf with | None -> name | Some tag -> name ^ "_" ^ tag let variable ?(decl = false) wf = (if !openmp && not decl then openmp_tld ^ "%" else "") ^ add_tag wf ("owf_" ^ CM.flavor_symbol (F.flavor wf) ^ "_" ^ format_p wf) let momentum wf = "p" ^ format_p wf let spin wf = "s(" ^ string_of_int (ext_momentum wf) ^ ")" let format_multiple_variable ?(decl = false) wf i = variable ~decl wf ^ "_X" ^ string_of_int i let multiple_variable ?(decl = false) amplitude dictionary wf = try format_multiple_variable ~decl wf (dictionary amplitude wf) with | Not_found -> variable wf let multiple_variables ?(decl = false) multiplicity wf = try List.map (format_multiple_variable ~decl wf) (ThoList.range 1 (multiplicity wf)) with | Not_found -> [variable ~decl wf] let declaration_chunk_size = 64 let declare_list_chunk multiplicity t = function | [] -> () | wfs -> printf " @[<2>%s :: " t; print_list (ThoList.flatmap (multiple_variables ~decl:true multiplicity) wfs); nl () let declare_list multiplicity t = function | [] -> () | wfs -> List.iter (declare_list_chunk multiplicity t) (ThoList.chopn declaration_chunk_size wfs) type declarations = { scalars : F.wf list; spinors : F.wf list; conjspinors : F.wf list; realspinors : F.wf list; ghostspinors : F.wf list; vectorspinors : F.wf list; vectors : F.wf list; ward_vectors : F.wf list; massive_vectors : F.wf list; tensors_1 : F.wf list; tensors_2 : F.wf list; brs_scalars : F.wf list; brs_spinors : F.wf list; brs_conjspinors : F.wf list; brs_realspinors : F.wf list; brs_vectorspinors : F.wf list; brs_vectors : F.wf list; brs_massive_vectors : F.wf list } let rec classify_wfs' acc = function | [] -> acc | wf :: rest -> classify_wfs' (match CM.lorentz (F.flavor wf) with | Scalar -> {acc with scalars = wf :: acc.scalars} | Spinor -> {acc with spinors = wf :: acc.spinors} | ConjSpinor -> {acc with conjspinors = wf :: acc.conjspinors} | Majorana -> {acc with realspinors = wf :: acc.realspinors} | Maj_Ghost -> {acc with ghostspinors = wf :: acc.ghostspinors} | Vectorspinor -> {acc with vectorspinors = wf :: acc.vectorspinors} | Vector -> {acc with vectors = wf :: acc.vectors} (*i | Ward_Vector -> {acc with ward_vectors = wf :: acc.ward_vectors} i*) | Massive_Vector -> {acc with massive_vectors = wf :: acc.massive_vectors} | Tensor_1 -> {acc with tensors_1 = wf :: acc.tensors_1} | Tensor_2 -> {acc with tensors_2 = wf :: acc.tensors_2} | BRS Scalar -> {acc with brs_scalars = wf :: acc.brs_scalars} | BRS Spinor -> {acc with brs_spinors = wf :: acc.brs_spinors} | BRS ConjSpinor -> {acc with brs_conjspinors = wf :: acc.brs_conjspinors} | BRS Majorana -> {acc with brs_realspinors = wf :: acc.brs_realspinors} | BRS Vectorspinor -> {acc with brs_vectorspinors = wf :: acc.brs_vectorspinors} | BRS Vector -> {acc with brs_vectors = wf :: acc.brs_vectors} | BRS Massive_Vector -> {acc with brs_massive_vectors = wf :: acc.brs_massive_vectors} | BRS _ -> invalid_arg "Targets.wfs_classify': not needed here") rest let classify_wfs wfs = classify_wfs' { scalars = []; spinors = []; conjspinors = []; realspinors = []; ghostspinors = []; vectorspinors = []; vectors = []; ward_vectors = []; massive_vectors = []; tensors_1 = []; tensors_2 = []; brs_scalars = [] ; brs_spinors = []; brs_conjspinors = []; brs_realspinors = []; brs_vectorspinors = []; brs_vectors = []; brs_massive_vectors = []} wfs (* \thocwmodulesubsection{Parameters} *) type 'a parameters = { real_singles : 'a list; real_arrays : ('a * int) list; complex_singles : 'a list; complex_arrays : ('a * int) list } let rec classify_singles acc = function | [] -> acc | Real p :: rest -> classify_singles { acc with real_singles = p :: acc.real_singles } rest | Complex p :: rest -> classify_singles { acc with complex_singles = p :: acc.complex_singles } rest let rec classify_arrays acc = function | [] -> acc | (Real_Array p, rhs) :: rest -> classify_arrays { acc with real_arrays = (p, List.length rhs) :: acc.real_arrays } rest | (Complex_Array p, rhs) :: rest -> classify_arrays { acc with complex_arrays = (p, List.length rhs) :: acc.complex_arrays } rest let classify_parameters params = classify_arrays (classify_singles { real_singles = []; real_arrays = []; complex_singles = []; complex_arrays = [] } (List.map fst params.derived)) params.derived_arrays let schisma = ThoList.chopn let schisma_num i n l = ThoList.enumerate i (schisma n l) let declare_parameters' t = function | [] -> () | plist -> printf " @[<2>%s(kind=%s), public, save :: " t !kind; print_list (List.map CM.constant_symbol plist); nl () let declare_parameters t plist = List.iter (declare_parameters' t) plist let declare_parameter_array t (p, n) = printf " @[<2>%s(kind=%s), dimension(%d), public, save :: %s" t !kind n (CM.constant_symbol p); nl () (* NB: we use [string_of_float] to make sure that a decimal point is included to make Fortran compilers happy. *) let default_parameter (x, v) = printf "@ %s = %s_%s" (CM.constant_symbol x) (string_of_float v) !kind let declare_default_parameters t = function | [] -> () | p :: plist -> printf " @[<2>%s(kind=%s), public, save ::" t !kind; default_parameter p; List.iter (fun p' -> printf ","; default_parameter p') plist; nl () let format_constant = function | I -> "(0,1)" | Integer c -> if c < 0 then sprintf "(%d.0_%s)" c !kind else sprintf "%d.0_%s" c !kind | Float x -> if x < 0. then sprintf "(%g_%s)" x !kind else sprintf "%g_%s" x !kind | _ -> invalid_arg "format_constant" let rec eval_parameter' = function | (I | Integer _ | Float _) as c -> printf "%s" (format_constant c) | Atom x -> printf "%s" (CM.constant_symbol x) | Sum [] -> printf "0.0_%s" !kind | Sum [x] -> eval_parameter' x | Sum (x :: xs) -> printf "@,("; eval_parameter' x; List.iter (fun x -> printf "@, + "; eval_parameter' x) xs; printf ")" | Diff (x, y) -> printf "@,("; eval_parameter' x; printf " - "; eval_parameter' y; printf ")" | Neg x -> printf "@,( - "; eval_parameter' x; printf ")" | Prod [] -> printf "1.0_%s" !kind | Prod [x] -> eval_parameter' x | Prod (x :: xs) -> printf "@,("; eval_parameter' x; List.iter (fun x -> printf " * "; eval_parameter' x) xs; printf ")" | Quot (x, y) -> printf "@,("; eval_parameter' x; printf " / "; eval_parameter' y; printf ")" | Rec x -> printf "@, (1.0_%s / " !kind; eval_parameter' x; printf ")" | Pow (x, n) -> printf "@,("; eval_parameter' x; printf "**%d" n; printf ")" | PowX (x, y) -> printf "@,("; eval_parameter' x; printf "**"; eval_parameter' y; printf ")" | Sqrt x -> printf "@,sqrt ("; eval_parameter' x; printf ")" | Sin x -> printf "@,sin ("; eval_parameter' x; printf ")" | Cos x -> printf "@,cos ("; eval_parameter' x; printf ")" | Tan x -> printf "@,tan ("; eval_parameter' x; printf ")" | Cot x -> printf "@,cot ("; eval_parameter' x; printf ")" | Asin x -> printf "@,asin ("; eval_parameter' x; printf ")" | Acos x -> printf "@,acos ("; eval_parameter' x; printf ")" | Atan x -> printf "@,atan ("; eval_parameter' x; printf ")" | Atan2 (y, x) -> printf "@,atan2 ("; eval_parameter' y; printf ",@ "; eval_parameter' x; printf ")" | Sinh x -> printf "@,sinh ("; eval_parameter' x; printf ")" | Cosh x -> printf "@,cosh ("; eval_parameter' x; printf ")" | Tanh x -> printf "@,tanh ("; eval_parameter' x; printf ")" | Exp x -> printf "@,exp ("; eval_parameter' x; printf ")" | Log x -> printf "@,log ("; eval_parameter' x; printf ")" | Log10 x -> printf "@,log10 ("; eval_parameter' x; printf ")" | Conj (Integer _ | Float _ as x) -> eval_parameter' x | Conj x -> printf "@,cconjg ("; eval_parameter' x; printf ")" let strip_single_tag = function | Real x -> x | Complex x -> x let strip_array_tag = function | Real_Array x -> x | Complex_Array x -> x let eval_parameter (lhs, rhs) = let x = CM.constant_symbol (strip_single_tag lhs) in printf " @[<2>%s = " x; eval_parameter' rhs; nl () let eval_para_list n l = printf " subroutine setup_parameters_%03d ()" n; nl (); List.iter eval_parameter l; printf " end subroutine setup_parameters_%03d" n; nl () let eval_parameter_pair (lhs, rhs) = let x = CM.constant_symbol (strip_array_tag lhs) in let _ = List.fold_left (fun i rhs' -> printf " @[<2>%s(%d) = " x i; eval_parameter' rhs'; nl (); succ i) 1 rhs in () let eval_para_pair_list n l = printf " subroutine setup_parameters_%03d ()" n; nl (); List.iter eval_parameter_pair l; printf " end subroutine setup_parameters_%03d" n; nl () let print_echo fmt p = let s = CM.constant_symbol p in printf " write (unit = *, fmt = fmt_%s) \"%s\", %s" fmt s s; nl () let print_echo_array fmt (p, n) = let s = CM.constant_symbol p in for i = 1 to n do printf " write (unit = *, fmt = fmt_%s_array) " fmt ; printf "\"%s\", %d, %s(%d)" s i s i; nl () done let contains params couplings = List.exists (fun (name, _) -> List.mem (CM.constant_symbol name) params) couplings.input let rec depends_on params = function | I | Integer _ | Float _ -> false | Atom name -> List.mem (CM.constant_symbol name) params | Sum es | Prod es -> List.exists (depends_on params) es | Diff (e1, e2) | Quot (e1, e2) | PowX (e1, e2) -> depends_on params e1 || depends_on params e2 | Neg e | Rec e | Pow (e, _) -> depends_on params e | Sqrt e | Exp e | Log e | Log10 e | Sin e | Cos e | Tan e | Cot e | Asin e | Acos e | Atan e | Sinh e | Cosh e | Tanh e | Conj e -> depends_on params e | Atan2 (e1, e2) -> depends_on params e1 || depends_on params e2 let dependencies params couplings = if contains params couplings then List.rev (fst (List.fold_left (fun (deps, plist) (param, v) -> match param with | Real name | Complex name -> if depends_on plist v then ((param, v) :: deps, CM.constant_symbol name :: plist) else (deps, plist)) ([], params) couplings.derived)) else [] let dependencies_arrays params couplings = if contains params couplings then List.rev (fst (List.fold_left (fun (deps, plist) (param, vlist) -> match param with | Real_Array name | Complex_Array name -> if List.exists (depends_on plist) vlist then ((param, vlist) :: deps, CM.constant_symbol name :: plist) else (deps, plist)) ([], params) couplings.derived_arrays)) else [] let parameters_to_fortran oc params = Format_Fortran.set_formatter_out_channel ~width:!line_length oc; let declarations = classify_parameters params in printf "module %s" !parameter_module; nl (); printf " use kinds"; nl (); printf " use constants"; nl (); printf " implicit none"; nl (); printf " private"; nl (); printf " @[<2>public :: setup_parameters"; printf ",@ import_from_whizard"; printf ",@ model_update_alpha_s"; if !no_write then begin printf "! No print_parameters"; end else begin printf ",@ print_parameters"; end; nl (); declare_default_parameters "real" params.input; declare_parameters "real" (schisma 69 declarations.real_singles); List.iter (declare_parameter_array "real") declarations.real_arrays; declare_parameters "complex" (schisma 69 declarations.complex_singles); List.iter (declare_parameter_array "complex") declarations.complex_arrays; printf " interface cconjg"; nl (); printf " module procedure cconjg_real, cconjg_complex"; nl (); printf " end interface"; nl (); printf " private :: cconjg_real, cconjg_complex"; nl (); printf "contains"; nl (); printf " function cconjg_real (x) result (xc)"; nl (); printf " real(kind=default), intent(in) :: x"; nl (); printf " real(kind=default) :: xc"; nl (); printf " xc = x"; nl (); printf " end function cconjg_real"; nl (); printf " function cconjg_complex (z) result (zc)"; nl (); printf " complex(kind=default), intent(in) :: z"; nl (); printf " complex(kind=default) :: zc"; nl (); printf " zc = conjg (z)"; nl (); printf " end function cconjg_complex"; nl (); printf " ! derived parameters:"; nl (); let shredded = schisma_num 1 120 params.derived in let shredded_arrays = schisma_num 1 120 params.derived_arrays in let num_sub = List.length shredded in let num_sub_arrays = List.length shredded_arrays in List.iter (fun (i,l) -> eval_para_list i l) shredded; List.iter (fun (i,l) -> eval_para_pair_list (num_sub + i) l) shredded_arrays; printf " subroutine setup_parameters ()"; nl (); for i = 1 to num_sub + num_sub_arrays do printf " call setup_parameters_%03d ()" i; nl (); done; printf " end subroutine setup_parameters"; nl (); printf " subroutine import_from_whizard (par_array, scheme)"; nl (); printf " real(%s), dimension(%d), intent(in) :: par_array" !kind (List.length params.input); nl (); printf " integer, intent(in) :: scheme"; nl (); let i = ref 1 in List.iter (fun (p, _) -> printf " %s = par_array(%d)" (CM.constant_symbol p) !i; nl (); incr i) params.input; printf " call setup_parameters ()"; nl (); printf " end subroutine import_from_whizard"; nl (); printf " subroutine model_update_alpha_s (alpha_s)"; nl (); printf " real(%s), intent(in) :: alpha_s" !kind; nl (); begin match (dependencies ["aS"] params, dependencies_arrays ["aS"] params) with | [], [] -> printf " ! 'aS' not among the input parameters"; nl (); | deps, deps_arrays -> printf " aS = alpha_s"; nl (); List.iter eval_parameter deps; List.iter eval_parameter_pair deps_arrays end; printf " end subroutine model_update_alpha_s"; nl (); if !no_write then begin printf "! No print_parameters"; nl (); end else begin printf " subroutine print_parameters ()"; nl (); printf " @[<2>character(len=*), parameter ::"; printf "@ fmt_real = \"(A12,4X,' = ',E25.18)\","; printf "@ fmt_complex = \"(A12,4X,' = ',E25.18,' + i*',E25.18)\","; printf "@ fmt_real_array = \"(A12,'(',I2.2,')',' = ',E25.18)\","; printf "@ fmt_complex_array = "; printf "\"(A12,'(',I2.2,')',' = ',E25.18,' + i*',E25.18)\""; nl (); printf " @[<2>write (unit = *, fmt = \"(A)\") @,"; printf "\"default values for the input parameters:\""; nl (); List.iter (fun (p, _) -> print_echo "real" p) params.input; printf " @[<2>write (unit = *, fmt = \"(A)\") @,"; printf "\"derived parameters:\""; nl (); List.iter (print_echo "real") declarations.real_singles; List.iter (print_echo "complex") declarations.complex_singles; List.iter (print_echo_array "real") declarations.real_arrays; List.iter (print_echo_array "complex") declarations.complex_arrays; printf " end subroutine print_parameters"; nl (); end; printf "end module %s" !parameter_module; nl () (* \thocwmodulesubsection{Run-Time Diagnostics} *) type diagnostic = All | Arguments | Momenta | Gauge type diagnostic_mode = Off | Warn | Panic let warn mode = match !mode with | Off -> false | Warn -> true | Panic -> true let panic mode = match !mode with | Off -> false | Warn -> false | Panic -> true let suffix mode = if panic mode then "panic" else "warn" let diagnose_arguments = ref Off let diagnose_momenta = ref Off let diagnose_gauge = ref Off let rec parse_diagnostic = function | All, panic -> parse_diagnostic (Arguments, panic); parse_diagnostic (Momenta, panic); parse_diagnostic (Gauge, panic) | Arguments, panic -> diagnose_arguments := if panic then Panic else Warn | Momenta, panic -> diagnose_momenta := if panic then Panic else Warn | Gauge, panic -> diagnose_gauge := if panic then Panic else Warn (* If diagnostics are required, we have to switch off Fortran95 features like pure functions. *) let parse_diagnostics = function | [] -> () | diagnostics -> fortran95 := false; List.iter parse_diagnostic diagnostics (* \thocwmodulesubsection{Amplitude} *) let declare_momenta_chunk = function | [] -> () | momenta -> printf " @[<2>type(momentum) :: "; print_list (List.map format_momentum momenta); nl () let declare_momenta = function | [] -> () | momenta -> List.iter declare_momenta_chunk (ThoList.chopn declaration_chunk_size momenta) let declare_wavefunctions multiplicity wfs = let wfs' = classify_wfs wfs in declare_list multiplicity ("complex(kind=" ^ !kind ^ ")") (wfs'.scalars @ wfs'.brs_scalars); declare_list multiplicity ("type(" ^ Fermions.psi_type ^ ")") (wfs'.spinors @ wfs'.brs_spinors); declare_list multiplicity ("type(" ^ Fermions.psibar_type ^ ")") (wfs'.conjspinors @ wfs'.brs_conjspinors); declare_list multiplicity ("type(" ^ Fermions.chi_type ^ ")") (wfs'.realspinors @ wfs'.brs_realspinors @ wfs'.ghostspinors); declare_list multiplicity ("type(" ^ Fermions.grav_type ^ ")") wfs'.vectorspinors; declare_list multiplicity "type(vector)" (wfs'.vectors @ wfs'.massive_vectors @ wfs'.brs_vectors @ wfs'.brs_massive_vectors @ wfs'.ward_vectors); declare_list multiplicity "type(tensor2odd)" wfs'.tensors_1; declare_list multiplicity "type(tensor)" wfs'.tensors_2 let flavors a = F.incoming a @ F.outgoing a let declare_brakets_chunk = function | [] -> () | amplitudes -> printf " @[<2>complex(kind=%s) :: " !kind; print_list (List.map (fun a -> flavors_symbol ~decl:true (flavors a)) amplitudes); nl () let declare_brakets = function | [] -> () | amplitudes -> List.iter declare_brakets_chunk (ThoList.chopn declaration_chunk_size amplitudes) let print_variable_declarations amplitudes = let multiplicity = CF.multiplicity amplitudes and processes = CF.processes amplitudes in if not !amp_triv then begin declare_momenta (PSet.elements (List.fold_left (fun set a -> PSet.union set (List.fold_right (fun wf -> PSet.add (F.momentum_list wf)) (F.externals a) PSet.empty)) PSet.empty processes)); declare_momenta (PSet.elements (List.fold_left (fun set a -> PSet.union set (List.fold_right (fun wf -> PSet.add (F.momentum_list wf)) (F.variables a) PSet.empty)) PSet.empty processes)); if !openmp then begin printf " type %s@[<2>" openmp_tld_type; nl (); end ; declare_wavefunctions multiplicity (WFSet.elements (List.fold_left (fun set a -> WFSet.union set (List.fold_right WFSet.add (F.externals a) WFSet.empty)) WFSet.empty processes)); declare_wavefunctions multiplicity (WFSet.elements (List.fold_left (fun set a -> WFSet.union set (List.fold_right WFSet.add (F.variables a) WFSet.empty)) WFSet.empty processes)); declare_brakets processes; if !openmp then begin printf "@] end type %s\n" openmp_tld_type; printf " type(%s) :: %s" openmp_tld_type openmp_tld; nl (); end; end (* [print_current] is the most important function that has to match the functions in \verb+omega95+ (see appendix~\ref{sec:fortran}). It offers plentiful opportunities for making mistakes, in particular those related to signs. We start with a few auxiliary functions: *) let children2 rhs = match F.children rhs with | [wf1; wf2] -> (wf1, wf2) | _ -> failwith "Targets.children2: can't happen" let children3 rhs = match F.children rhs with | [wf1; wf2; wf3] -> (wf1, wf2, wf3) | _ -> invalid_arg "Targets.children3: can't happen" (* Note that it is (marginally) faster to multiply the two scalar products with the coupling constant than the four vector components. \begin{dubious} This could be part of \verb+omegalib+ as well \ldots \end{dubious} *) let format_coeff = function | 1 -> "" | -1 -> "-" | coeff -> "(" ^ string_of_int coeff ^ ")*" let format_coupling coeff c = match coeff with | 1 -> c | -1 -> "(-" ^ c ^")" | coeff -> string_of_int coeff ^ "*" ^ c (* \begin{dubious} The following is error prone and should be generated automagically. \end{dubious} *) let print_vector4 c wf1 wf2 wf3 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F341|F431|F342|F432|F123|F213|F124|F214) | C_13_42, (F241|F421|F243|F423|F132|F312|F134|F314) | C_14_23, (F231|F321|F234|F324|F142|F412|F143|F413) -> printf "((%s%s)*(%s*%s))*%s" (format_coeff coeff) c wf1 wf2 wf3 | C_12_34, (F134|F143|F234|F243|F312|F321|F412|F421) | C_13_42, (F124|F142|F324|F342|F213|F231|F413|F431) | C_14_23, (F123|F132|F423|F432|F214|F241|F314|F341) -> printf "((%s%s)*(%s*%s))*%s" (format_coeff coeff) c wf2 wf3 wf1 | C_12_34, (F314|F413|F324|F423|F132|F231|F142|F241) | C_13_42, (F214|F412|F234|F432|F123|F321|F143|F341) | C_14_23, (F213|F312|F243|F342|F124|F421|F134|F431) -> printf "((%s%s)*(%s*%s))*%s" (format_coeff coeff) c wf1 wf3 wf2 let print_vector4_t_0 c wf1 p1 wf2 p2 wf3 p3 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F234|F243|F134|F143|F421|F321|F412|F312) | C_13_42, (F324|F342|F124|F142|F431|F231|F413|F213) | C_14_23, (F423|F432|F123|F132|F341|F241|F314|F214) -> printf "g_dim8g3_t_0(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | C_12_34, (F324|F314|F423|F413|F142|F132|F241|F231) | C_13_42, (F234|F214|F432|F412|F143|F123|F341|F321) | C_14_23, (F243|F213|F342|F312|F134|F124|F431|F421) -> printf "g_dim8g3_t_0(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | C_12_34, (F342|F341|F432|F431|F124|F123|F214|F213) | C_13_42, (F243|F241|F423|F421|F134|F132|F314|F312) | C_14_23, (F234|F231|F324|F321|F143|F142|F413|F412) -> printf "g_dim8g3_t_0(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 let print_vector4_t_1 c wf1 p1 wf2 p2 wf3 p3 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F234|F243|F134|F143|F421|F321|F412|F312) | C_13_42, (F324|F342|F124|F142|F431|F231|F413|F213) | C_14_23, (F423|F432|F123|F132|F341|F241|F314|F214) -> printf "g_dim8g3_t_1(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | C_12_34, (F324|F314|F423|F413|F142|F132|F241|F231) | C_13_42, (F234|F214|F432|F412|F143|F123|F341|F321) | C_14_23, (F243|F213|F342|F312|F134|F124|F431|F421) -> printf "g_dim8g3_t_1(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | C_12_34, (F342|F341|F432|F431|F124|F123|F214|F213) | C_13_42, (F243|F241|F423|F421|F134|F132|F314|F312) | C_14_23, (F234|F231|F324|F321|F143|F142|F413|F412) -> printf "g_dim8g3_t_1(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 let print_vector4_t_2 c wf1 p1 wf2 p2 wf3 p3 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F234|F243|F134|F143|F421|F321|F412|F312) | C_13_42, (F324|F342|F124|F142|F431|F231|F413|F213) | C_14_23, (F423|F432|F123|F132|F341|F241|F314|F214) -> printf "g_dim8g3_t_2(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | C_12_34, (F324|F314|F423|F413|F142|F132|F241|F231) | C_13_42, (F234|F214|F432|F412|F143|F123|F341|F321) | C_14_23, (F243|F213|F342|F312|F134|F124|F431|F421) -> printf "g_dim8g3_t_2(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | C_12_34, (F342|F341|F432|F431|F124|F123|F214|F213) | C_13_42, (F243|F241|F423|F421|F134|F132|F314|F312) | C_14_23, (F234|F231|F324|F321|F143|F142|F413|F412) -> printf "g_dim8g3_t_2(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 let print_vector4_m_0 c wf1 p1 wf2 p2 wf3 p3 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F234|F243|F134|F143|F421|F321|F412|F312) | C_13_42, (F324|F342|F124|F142|F431|F231|F413|F213) | C_14_23, (F423|F432|F123|F132|F341|F241|F314|F214) -> printf "g_dim8g3_m_0(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | C_12_34, (F324|F314|F423|F413|F142|F132|F241|F231) | C_13_42, (F234|F214|F432|F412|F143|F123|F341|F321) | C_14_23, (F243|F213|F342|F312|F134|F124|F431|F421) -> printf "g_dim8g3_m_0(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | C_12_34, (F342|F341|F432|F431|F124|F123|F214|F213) | C_13_42, (F243|F241|F423|F421|F134|F132|F314|F312) | C_14_23, (F234|F231|F324|F321|F143|F142|F413|F412) -> printf "g_dim8g3_m_0(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 let print_vector4_m_1 c wf1 p1 wf2 p2 wf3 p3 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F234|F243|F134|F143|F421|F321|F412|F312) | C_13_42, (F324|F342|F124|F142|F431|F231|F413|F213) | C_14_23, (F423|F432|F123|F132|F341|F241|F314|F214) -> printf "g_dim8g3_m_1(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | C_12_34, (F324|F314|F423|F413|F142|F132|F241|F231) | C_13_42, (F234|F214|F432|F412|F143|F123|F341|F321) | C_14_23, (F243|F213|F342|F312|F134|F124|F431|F421) -> printf "g_dim8g3_m_1(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | C_12_34, (F342|F341|F432|F431|F124|F123|F214|F213) | C_13_42, (F243|F241|F423|F421|F134|F132|F314|F312) | C_14_23, (F234|F231|F324|F321|F143|F142|F413|F412) -> printf "g_dim8g3_m_1(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 let print_vector4_m_7 c wf1 p1 wf2 p2 wf3 p3 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F234|F243|F134|F143|F421|F321|F412|F312) | C_13_42, (F324|F342|F124|F142|F431|F231|F413|F213) | C_14_23, (F423|F432|F123|F132|F341|F241|F314|F214) -> printf "g_dim8g3_m_7(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | C_12_34, (F324|F314|F423|F413|F142|F132|F241|F231) | C_13_42, (F234|F214|F432|F412|F143|F123|F341|F321) | C_14_23, (F243|F213|F342|F312|F134|F124|F431|F421) -> printf "g_dim8g3_m_7(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | C_12_34, (F342|F341|F432|F431|F124|F123|F214|F213) | C_13_42, (F243|F241|F423|F421|F134|F132|F314|F312) | C_14_23, (F234|F231|F324|F321|F143|F142|F413|F412) -> printf "g_dim8g3_m_7(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 let print_add_vector4 c wf1 wf2 wf3 fusion (coeff, contraction) = printf "@ + "; print_vector4 c wf1 wf2 wf3 fusion (coeff, contraction) let print_vector4_km c pa pb wf1 wf2 wf3 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F341|F431|F342|F432|F123|F213|F124|F214) | C_13_42, (F241|F421|F243|F423|F132|F312|F134|F314) | C_14_23, (F231|F321|F234|F324|F142|F412|F143|F413) -> printf "((%s%s%s+%s))*(%s*%s))*%s" (format_coeff coeff) c pa pb wf1 wf2 wf3 | C_12_34, (F134|F143|F234|F243|F312|F321|F412|F421) | C_13_42, (F124|F142|F324|F342|F213|F231|F413|F431) | C_14_23, (F123|F132|F423|F432|F214|F241|F314|F341) -> printf "((%s%s%s+%s))*(%s*%s))*%s" (format_coeff coeff) c pa pb wf2 wf3 wf1 | C_12_34, (F314|F413|F324|F423|F132|F231|F142|F241) | C_13_42, (F214|F412|F234|F432|F123|F321|F143|F341) | C_14_23, (F213|F312|F243|F342|F124|F421|F134|F431) -> printf "((%s%s%s+%s))*(%s*%s))*%s" (format_coeff coeff) c pa pb wf1 wf3 wf2 let print_vector4_km_t_0 c pa pb wf1 p1 wf2 p2 wf3 p3 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F234|F243|F134|F143|F421|F321|F412|F312) | C_13_42, (F324|F342|F124|F142|F431|F231|F413|F213) | C_14_23, (F423|F432|F123|F132|F341|F241|F314|F214) -> printf "@[(%s%s%s+%s)*g_dim8g3_t_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf2 p2 wf3 p3 | C_12_34, (F324|F314|F423|F413|F142|F132|F241|F231) | C_13_42, (F234|F214|F432|F412|F143|F123|F341|F321) | C_14_23, (F243|F213|F342|F312|F134|F124|F431|F421) -> printf "@[(%s%s%s+%s)*g_dim8g3_t_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p2 wf1 p1 wf3 p3 | C_12_34, (F342|F341|F432|F431|F124|F123|F214|F213) | C_13_42, (F243|F241|F423|F421|F134|F132|F314|F312) | C_14_23, (F234|F231|F324|F321|F143|F142|F413|F412) -> printf "@[(%s%s%s+%s)*g_dim8g3_t_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p3 wf1 p1 wf2 p2 let print_vector4_km_t_1 c pa pb wf1 p1 wf2 p2 wf3 p3 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F234|F243|F134|F143|F421|F321|F412|F312) | C_13_42, (F324|F342|F124|F142|F431|F231|F413|F213) | C_14_23, (F423|F432|F123|F132|F341|F241|F314|F214) -> printf "@[(%s%s%s+%s)*g_dim8g3_t_1(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf2 p2 wf3 p3 | C_12_34, (F324|F314|F423|F413|F142|F132|F241|F231) | C_13_42, (F234|F214|F432|F412|F143|F123|F341|F321) | C_14_23, (F243|F213|F342|F312|F134|F124|F431|F421) -> printf "@[(%s%s%s+%s)*g_dim8g3_t_1(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p2 wf1 p1 wf3 p3 | C_12_34, (F342|F341|F432|F431|F124|F123|F214|F213) | C_13_42, (F243|F241|F423|F421|F134|F132|F314|F312) | C_14_23, (F234|F231|F324|F321|F143|F142|F413|F412) -> printf "@[(%s%s%s+%s)*g_dim8g3_t_1(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p3 wf1 p1 wf2 p2 let print_vector4_km_t_2 c pa pb wf1 p1 wf2 p2 wf3 p3 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F234|F243|F134|F143|F421|F321|F412|F312) | C_13_42, (F324|F342|F124|F142|F431|F231|F413|F213) | C_14_23, (F423|F432|F123|F132|F341|F241|F314|F214) -> printf "@[(%s%s%s+%s)*g_dim8g3_t_2(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf2 p2 wf3 p3 | C_12_34, (F324|F314|F423|F413|F142|F132|F241|F231) | C_13_42, (F234|F214|F432|F412|F143|F123|F341|F321) | C_14_23, (F243|F213|F342|F312|F134|F124|F431|F421) -> printf "@[(%s%s%s+%s)*g_dim8g3_t_2(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p2 wf1 p1 wf3 p3 | C_12_34, (F342|F341|F432|F431|F124|F123|F214|F213) | C_13_42, (F243|F241|F423|F421|F134|F132|F314|F312) | C_14_23, (F234|F231|F324|F321|F143|F142|F413|F412) -> printf "@[(%s%s%s+%s)*g_dim8g3_t_2(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p3 wf1 p1 wf2 p2 let print_vector4_km_t_rsi c pa pb pc wf1 p1 wf2 p2 wf3 p3 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F234|F243|F134|F143|F421|F321|F412|F312) | C_13_42, (F324|F342|F124|F142|F431|F231|F413|F213) | C_14_23, (F423|F432|F123|F132|F341|F241|F314|F214) -> printf "@[(%s%s%s+%s)*g_dim8g3_t_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf2 p2 wf3 p3 | C_12_34, (F324|F314|F423|F413|F142|F132|F241|F231) | C_13_42, (F234|F214|F432|F412|F143|F123|F341|F321) | C_14_23, (F243|F213|F342|F312|F134|F124|F431|F421) -> printf "@[(%s%s%s+%s)*g_dim8g3_t_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))*((%s+%s)*(%s+%s)/((%s+%s)*(%s+%s)))@]" (format_coeff coeff) c pa pb wf2 p2 wf1 p1 wf3 p3 pa pb pa pb pb pc pb pc | C_12_34, (F342|F341|F432|F431|F124|F123|F214|F213) | C_13_42, (F243|F241|F423|F421|F134|F132|F314|F312) | C_14_23, (F234|F231|F324|F321|F143|F142|F413|F412) -> printf "@[(%s%s%s+%s)*g_dim8g3_t_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))*((%s+%s)*(%s+%s)/((%s+%s)*(%s+%s)))@]" (format_coeff coeff) c pa pb wf3 p3 wf1 p1 wf2 p2 pa pb pa pb pa pc pa pc let print_vector4_km_m_0 c pa pb wf1 p1 wf2 p2 wf3 p3 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F234|F243|F134|F143|F421|F321|F412|F312) | C_13_42, (F324|F342|F124|F142|F431|F231|F413|F213) | C_14_23, (F423|F432|F123|F132|F341|F241|F314|F214) -> if (String.contains c 'w' || String.contains c '4') then printf "@[(%s%s%s+%s)*g_dim8g3_m_0(cmplx(1,kind=default),cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf2 p2 wf3 p3 else printf "@[((%s%s%s+%s))*g_dim8g3_m_0(cmplx(costhw**(-2),kind=default),cmplx(costhw**2,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf2 p2 wf3 p3 | C_12_34, (F324|F314|F423|F413|F142|F132|F241|F231) | C_13_42, (F234|F214|F432|F412|F143|F123|F341|F321) | C_14_23, (F243|F213|F342|F312|F134|F124|F431|F421) -> if (String.contains c 'w' || String.contains c '4') then printf "@[(%s%s%s+%s)*g_dim8g3_m_0(cmplx(1,kind=default),cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p2 wf1 p1 wf3 p3 else printf "@[(%s%s%s+%s)*g_dim8g3_m_0(cmplx(costhw**(-2),kind=default),cmplx(costhw**2,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p2 wf1 p1 wf3 p3 | C_12_34, (F342|F341|F432|F431|F124|F123|F214|F213) | C_13_42, (F243|F241|F423|F421|F134|F132|F314|F312) | C_14_23, (F234|F231|F324|F321|F143|F142|F413|F412) -> if (String.contains c 'w' || String.contains c '4') then printf "@[(%s%s%s+%s)*g_dim8g3_m_0(cmplx(1,kind=default),cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p3 wf1 p1 wf2 p2 else printf "@[(%s%s%s+%s)*g_dim8g3_m_0(cmplx(costhw**(-2),kind=default),cmplx(costhw**2,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p3 wf1 p1 wf2 p2 let print_vector4_km_m_1 c pa pb wf1 p1 wf2 p2 wf3 p3 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F234|F243|F134|F143|F421|F321|F412|F312) | C_13_42, (F324|F342|F124|F142|F431|F231|F413|F213) | C_14_23, (F423|F432|F123|F132|F341|F241|F314|F214) -> if (String.contains c 'w' || String.contains c '4') then printf "@[(%s%s%s+%s)*g_dim8g3_m_1(cmplx(1,kind=default),cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf2 p2 wf3 p3 else printf "@[(%s%s%s+%s)*g_dim8g3_m_1(cmplx(costhw**(-2),kind=default),cmplx(costhw**2,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf2 p2 wf3 p3 | C_12_34, (F324|F314|F423|F413|F142|F132|F241|F231) | C_13_42, (F234|F214|F432|F412|F143|F123|F341|F321) | C_14_23, (F243|F213|F342|F312|F134|F124|F431|F421) -> if (String.contains c 'w' || String.contains c '4') then printf "@[(%s%s%s+%s)*g_dim8g3_m_1(cmplx(1,kind=default),cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p2 wf1 p1 wf3 p3 else printf "@[(%s%s%s+%s)*g_dim8g3_m_1(cmplx(costhw**(-2),kind=default),cmplx(costhw**2,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p2 wf1 p1 wf3 p3 | C_12_34, (F342|F341|F432|F431|F124|F123|F214|F213) | C_13_42, (F243|F241|F423|F421|F134|F132|F314|F312) | C_14_23, (F234|F231|F324|F321|F143|F142|F413|F412) -> if (String.contains c 'w' || String.contains c '4') then printf "@[(%s%s%s+%s)*g_dim8g3_m_1(cmplx(1,kind=default),cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p3 wf1 p1 wf2 p2 else printf "@[(%s%s%s+%s)*g_dim8g3_m_1(cmplx(costhw**(-2),kind=default),cmplx(costhw**2,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p3 wf1 p1 wf2 p2 let print_vector4_km_m_7 c pa pb wf1 p1 wf2 p2 wf3 p3 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F234|F243|F134|F143|F421|F321|F412|F312) | C_13_42, (F324|F342|F124|F142|F431|F231|F413|F213) | C_14_23, (F423|F432|F123|F132|F341|F241|F314|F214) -> if (String.contains c 'w' || String.contains c '4') then printf "@[(%s%s%s+%s)*@ g_dim8g3_m_7(cmplx(1,kind=default),cmplx(1,kind=default),cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf2 p2 wf3 p3 else printf "@[(%s%s%s+%s)*@ g_dim8g3_m_7(cmplx(costhw**(-2),kind=default),cmplx(1,kind=default),cmplx(costhw**2,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf2 p2 wf3 p3 | C_12_34, (F324|F314|F423|F413|F142|F132|F241|F231) | C_13_42, (F234|F214|F432|F412|F143|F123|F341|F321) | C_14_23, (F243|F213|F342|F312|F134|F124|F431|F421) -> if (String.contains c 'w' || String.contains c '4') then printf "@[(%s%s%s+%s)*@ g_dim8g3_m_7(cmplx(1,kind=default),cmplx(1,kind=default),cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p2 wf1 p1 wf3 p3 else printf "@[(%s%s%s+%s)*@ g_dim8g3_m_7(cmplx(costhw**(-2),kind=default),cmplx(1,kind=default),cmplx(costhw**2,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p2 wf1 p1 wf3 p3 | C_12_34, (F342|F341|F432|F431|F124|F123|F214|F213) | C_13_42, (F243|F241|F423|F421|F134|F132|F314|F312) | C_14_23, (F234|F231|F324|F321|F143|F142|F413|F412) -> if (String.contains c 'w' || String.contains c '4') then printf "@[(%s%s%s+%s)*@ g_dim8g3_m_7(cmplx(1,kind=default),cmplx(1,kind=default),cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p3 wf1 p1 wf2 p2 else printf "@[(%s%s%s+%s)*@ g_dim8g3_m_7(cmplx(costhw**(-2),kind=default),cmplx(1,kind=default),cmplx(costhw**2,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p3 wf1 p1 wf2 p2 let print_add_vector4_km c pa pb wf1 wf2 wf3 fusion (coeff, contraction) = printf "@ + "; print_vector4_km c pa pb wf1 wf2 wf3 fusion (coeff, contraction) let print_dscalar4 c wf1 wf2 wf3 p1 p2 p3 p123 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F341|F431|F342|F432|F123|F213|F124|F214) | C_13_42, (F241|F421|F243|F423|F132|F312|F134|F314) | C_14_23, (F231|F321|F234|F324|F142|F412|F143|F413) -> printf "((%s%s)*(%s*%s)*(%s*%s)*%s*%s*%s)" (format_coeff coeff) c p1 p2 p3 p123 wf1 wf2 wf3 | C_12_34, (F134|F143|F234|F243|F312|F321|F412|F421) | C_13_42, (F124|F142|F324|F342|F213|F231|F413|F431) | C_14_23, (F123|F132|F423|F432|F214|F241|F314|F341) -> printf "((%s%s)*(%s*%s)*(%s*%s)*%s*%s*%s)" (format_coeff coeff) c p2 p3 p1 p123 wf1 wf2 wf3 | C_12_34, (F314|F413|F324|F423|F132|F231|F142|F241) | C_13_42, (F214|F412|F234|F432|F123|F321|F143|F341) | C_14_23, (F213|F312|F243|F342|F124|F421|F134|F431) -> printf "((%s%s)*(%s*%s)*(%s*%s)*%s*%s*%s)" (format_coeff coeff) c p1 p3 p2 p123 wf1 wf2 wf3 let print_add_dscalar4 c wf1 wf2 wf3 p1 p2 p3 p123 fusion (coeff, contraction) = printf "@ + "; print_dscalar4 c wf1 wf2 wf3 p1 p2 p3 p123 fusion (coeff, contraction) let print_dscalar2_vector2 c wf1 wf2 wf3 p1 p2 p3 p123 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F123|F213|F124|F214) -> printf "(%s%s)*(%s*%s)*(%s*%s)*%s" (format_coeff coeff) c p1 p2 wf1 wf2 wf3 | C_12_34, (F134|F143|F234|F243) -> printf "(%s%s)*(%s*%s)*(%s*%s)*%s" (format_coeff coeff) c p1 p123 wf2 wf3 wf1 | C_12_34, (F132|F231|F142|F241) -> printf "(%s%s)*(%s*%s)*(%s*%s)*%s" (format_coeff coeff) c p1 p3 wf1 wf3 wf2 | C_12_34, (F312|F321|F412|F421) -> printf "(%s%s)*(%s*%s)*(%s*%s)*%s" (format_coeff coeff) c p2 p3 wf2 wf3 wf1 | C_12_34, (F314|F413|F324|F423) -> printf "(%s%s)*(%s*%s)*(%s*%s)*%s" (format_coeff coeff) c p2 p123 wf1 wf3 wf2 | C_12_34, (F341|F431|F342|F432) -> printf "(%s%s)*(%s*%s)*(%s*%s)*%s" (format_coeff coeff) c p3 p123 wf1 wf2 wf3 | C_13_42, (F123|F214) | C_14_23, (F124|F213) -> printf "((%s%s)*(%s*%s*%s)*%s*%s)" (format_coeff coeff) c wf1 p1 wf3 wf2 p2 | C_13_42, (F124|F213) | C_14_23, (F123|F214) -> printf "((%s%s)*(%s*%s*%s)*%s*%s)" (format_coeff coeff) c wf2 p2 wf3 wf1 p1 | C_13_42, (F132|F241) | C_14_23, (F142|F231) -> printf "((%s%s)*(%s*%s*%s)*%s*%s)" (format_coeff coeff) c wf1 p1 wf2 wf3 p3 | C_13_42, (F142|F231) | C_14_23, (F132|F241) -> printf "((%s%s)*(%s*%s*%s)*%s*%s)" (format_coeff coeff) c wf3 p3 wf2 wf1 p1 | C_13_42, (F312|F421) | C_14_23, (F412|F321) -> printf "((%s%s)*(%s*%s*%s)*%s*%s)" (format_coeff coeff) c wf2 p2 wf1 wf3 p3 | C_13_42, (F321|F412) | C_14_23, (F421|F312) -> printf "((%s%s)*(%s*%s*%s)*%s*%s)" (format_coeff coeff) c wf3 p3 wf1 wf2 p2 | C_13_42, (F134|F243) | C_14_23, (F143|F234) -> printf "((%s%s)*(%s*%s)*(%s*%s*%s))" (format_coeff coeff) c wf3 p123 wf1 p1 wf2 | C_13_42, (F143|F234) | C_14_23, (F134|F243) -> printf "((%s%s)*(%s*%s)*(%s*%s*%s))" (format_coeff coeff) c wf2 p123 wf1 p1 wf3 | C_13_42, (F314|F423) | C_14_23, (F413|F324) -> printf "((%s%s)*(%s*%s)*(%s*%s*%s))" (format_coeff coeff) c wf3 p123 wf2 p2 wf1 | C_13_42, (F324|F413) | C_14_23, (F423|F314) -> printf "((%s%s)*(%s*%s)*(%s*%s*%s))" (format_coeff coeff) c wf1 p123 wf2 p2 wf3 | C_13_42, (F341|F432) | C_14_23, (F431|F342) -> printf "((%s%s)*(%s*%s)*(%s*%s*%s))" (format_coeff coeff) c wf2 p123 wf3 p3 wf1 | C_13_42, (F342|F431) | C_14_23, (F432|F341) -> printf "((%s%s)*(%s*%s)*(%s*%s*%s))" (format_coeff coeff) c wf1 p123 wf3 p3 wf2 let print_add_dscalar2_vector2 c wf1 wf2 wf3 p1 p2 p3 p123 fusion (coeff, contraction) = printf "@ + "; print_dscalar2_vector2 c wf1 wf2 wf3 p1 p2 p3 p123 fusion (coeff, contraction) let print_dscalar2_vector2_km c pa pb wf1 wf2 wf3 p1 p2 p3 p123 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F123|F213|F124|F214) -> printf "(%s%s%s+%s))*(%s*%s)*(%s*%s)*%s" (format_coeff coeff) c pa pb p1 p2 wf1 wf2 wf3 | C_12_34, (F134|F143|F234|F243) -> printf "(%s%s%s+%s))*(%s*%s)*(%s*%s)*%s" (format_coeff coeff) c pa pb p1 p123 wf2 wf3 wf1 | C_12_34, (F132|F231|F142|F241) -> printf "(%s%s%s+%s))*(%s*%s)*(%s*%s)*%s" (format_coeff coeff) c pa pb p1 p3 wf1 wf3 wf2 | C_12_34, (F312|F321|F412|F421) -> printf "(%s%s%s+%s))*(%s*%s)*(%s*%s)*%s" (format_coeff coeff) c pa pb p2 p3 wf2 wf3 wf1 | C_12_34, (F314|F413|F324|F423) -> printf "(%s%s%s+%s))*(%s*%s)*(%s*%s)*%s" (format_coeff coeff) c pa pb p2 p123 wf1 wf3 wf2 | C_12_34, (F341|F431|F342|F432) -> printf "(%s%s%s+%s))*(%s*%s)*(%s*%s)*%s" (format_coeff coeff) c pa pb p3 p123 wf1 wf2 wf3 | C_13_42, (F123|F214) | C_14_23, (F124|F213) -> printf "((%s%s%s+%s))*(%s*%s*%s)*%s*%s)" (format_coeff coeff) c pa pb wf1 p1 wf3 wf2 p2 | C_13_42, (F124|F213) | C_14_23, (F123|F214) -> printf "((%s%s%s+%s))*(%s*%s*%s)*%s*%s)" (format_coeff coeff) c pa pb wf2 p2 wf3 wf1 p1 | C_13_42, (F132|F241) | C_14_23, (F142|F231) -> printf "((%s%s%s+%s))*(%s*%s*%s)*%s*%s)" (format_coeff coeff) c pa pb wf1 p1 wf2 wf3 p3 | C_13_42, (F142|F231) | C_14_23, (F132|F241) -> printf "((%s%s%s+%s))*(%s*%s*%s)*%s*%s)" (format_coeff coeff) c pa pb wf3 p3 wf2 wf1 p1 | C_13_42, (F312|F421) | C_14_23, (F412|F321) -> printf "((%s%s%s+%s))*(%s*%s*%s)*%s*%s)" (format_coeff coeff) c pa pb wf2 p2 wf1 wf3 p3 | C_13_42, (F321|F412) | C_14_23, (F421|F312) -> printf "((%s%s%s+%s))*(%s*%s*%s)*%s*%s)" (format_coeff coeff) c pa pb wf3 p3 wf1 wf2 p2 | C_13_42, (F134|F243) | C_14_23, (F143|F234) -> printf "((%s%s%s+%s))*(%s*%s)*(%s*%s*%s))" (format_coeff coeff) c pa pb wf3 p123 wf1 p1 wf2 | C_13_42, (F143|F234) | C_14_23, (F134|F243) -> printf "((%s%s%s+%s))*(%s*%s)*(%s*%s*%s))" (format_coeff coeff) c pa pb wf2 p123 wf1 p1 wf3 | C_13_42, (F314|F423) | C_14_23, (F413|F324) -> printf "((%s%s%s+%s))*(%s*%s)*(%s*%s*%s))" (format_coeff coeff) c pa pb wf3 p123 wf2 p2 wf1 | C_13_42, (F324|F413) | C_14_23, (F423|F314) -> printf "((%s%s%s+%s))*(%s*%s)*(%s*%s*%s))" (format_coeff coeff) c pa pb wf1 p123 wf2 p2 wf3 | C_13_42, (F341|F432) | C_14_23, (F431|F342) -> printf "((%s%s%s+%s))*(%s*%s)*(%s*%s*%s))" (format_coeff coeff) c pa pb wf2 p123 wf3 p3 wf1 | C_13_42, (F342|F431) | C_14_23, (F432|F341) -> printf "((%s%s%s+%s))*(%s*%s)*(%s*%s*%s))" (format_coeff coeff) c pa pb wf1 p123 wf3 p3 wf2 let print_add_dscalar2_vector2_km c pa pb wf1 wf2 wf3 p1 p2 p3 p123 fusion (coeff, contraction) = printf "@ + "; print_dscalar2_vector2_km c pa pb wf1 wf2 wf3 p1 p2 p3 p123 fusion (coeff, contraction) let print_dscalar2_vector2_m_0_km c pa pb wf1 wf2 wf3 p1 p2 p3 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F123|F213|F124|F214) -> printf "@[((%s%s%s+%s))*v_phi2v_m_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf2 p2 wf3 p3 | C_12_34, (F134|F143|F234|F243) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf2 p2 wf3 p3 | C_12_34, (F132|F231|F142|F241) -> printf "@[((%s%s%s+%s))*v_phi2v_m_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf3 p3 wf2 p2 | C_12_34, (F312|F321|F412|F421) -> printf "@[((%s%s%s+%s))*v_phi2v_m_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p3 wf2 p2 wf1 p1 | C_12_34, (F314|F413|F324|F423) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p2 wf1 p1 wf3 p3 | C_12_34, (F341|F431|F342|F432) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p3 wf2 p2 wf1 p1 | C_13_42, (F123|F214) | C_14_23, (F124|F213) -> printf "@[((%s%s%s+%s))*v_phi2v_m_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf2 p3 wf3 p2 | C_13_42, (F124|F213) | C_14_23, (F123|F214) -> printf "@[((%s%s%s+%s))*v_phi2v_m_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p2 wf1 p3 wf3 p1 | C_13_42, (F132|F241) | C_14_23, (F142|F231) -> printf "@[((%s%s%s+%s))*v_phi2v_m_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf3 p2 wf2 p3 | C_13_42, (F142|F231) | C_14_23, (F132|F241) -> printf "@[((%s%s%s+%s))*v_phi2v_m_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p3 wf1 p2 wf2 p1 | C_13_42, (F312|F421) | C_14_23, (F412|F321) -> printf "@[((%s%s%s+%s))*v_phi2v_m_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p2 wf3 p1 wf1 p3 | C_13_42, (F321|F412) | C_14_23, (F421|F312) -> printf "@[((%s%s%s+%s))*v_phi2v_m_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p3 wf2 p1 wf1 p2 | C_13_42, (F134|F243) | C_14_23, (F143|F234) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p3 wf3 p1 wf2 p2 | C_13_42, (F143|F234) | C_14_23, (F134|F243) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p2 wf2 p1 wf3 p3 | C_13_42, (F314|F423) | C_14_23, (F413|F324) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p3 wf3 p2 wf1 p1 | C_13_42, (F324|F413) | C_14_23, (F423|F314) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p1 wf1 p2 wf3 p3 | C_13_42, (F341|F432) | C_14_23, (F431|F342) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p2 wf2 p3 wf1 p1 | C_13_42, (F342|F431) | C_14_23, (F432|F341) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_0(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p1 wf1 p3 wf2 p2 let print_add_dscalar2_vector2_m_0_km c pa pb wf1 wf2 wf3 p1 p2 p3 fusion (coeff, contraction) = printf "@ + "; print_dscalar2_vector2_m_0_km c pa pb wf1 wf2 wf3 p1 p2 p3 fusion (coeff, contraction) let print_dscalar2_vector2_m_1_km c pa pb wf1 wf2 wf3 p1 p2 p3 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F123|F213|F124|F214) -> printf "@[((%s%s%s+%s))*v_phi2v_m_1(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf2 p2 wf3 p3 | C_12_34, (F134|F143|F234|F243) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_1(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf2 p2 wf3 p3 | C_12_34, (F132|F231|F142|F241) -> printf "@[((%s%s%s+%s))*v_phi2v_m_1(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf3 p3 wf2 p2 | C_12_34, (F312|F321|F412|F421) -> printf "@[((%s%s%s+%s))*v_phi2v_m_1(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p3 wf2 p2 wf1 p1 | C_12_34, (F314|F413|F324|F423) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_1(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p2 wf1 p1 wf3 p3 | C_12_34, (F341|F431|F342|F432) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_1(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p3 wf2 p2 wf1 p1 | C_13_42, (F123|F214) | C_14_23, (F124|F213) -> printf "@[((%s%s%s+%s))*v_phi2v_m_1(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf2 p3 wf3 p2 | C_13_42, (F124|F213) | C_14_23, (F123|F214) -> printf "@[((%s%s%s+%s))*v_phi2v_m_1(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p2 wf1 p3 wf3 p1 | C_13_42, (F132|F241) | C_14_23, (F142|F231) -> printf "@[((%s%s%s+%s))*v_phi2v_m_1(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf3 p2 wf2 p3 | C_13_42, (F142|F231) | C_14_23, (F132|F241) -> printf "@[((%s%s%s+%s))*v_phi2v_m_1(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p3 wf1 p2 wf2 p1 | C_13_42, (F312|F421) | C_14_23, (F412|F321) -> printf "@[((%s%s%s+%s))*v_phi2v_m_1(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p2 wf3 p1 wf1 p3 | C_13_42, (F321|F412) | C_14_23, (F421|F312) -> printf "@[((%s%s%s+%s))*v_phi2v_m_1(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p3 wf2 p1 wf1 p2 | C_13_42, (F134|F243) | C_14_23, (F143|F234) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_1(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p3 wf3 p1 wf2 p2 | C_13_42, (F143|F234) | C_14_23, (F134|F243) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_1(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p2 wf2 p1 wf3 p3 | C_13_42, (F314|F423) | C_14_23, (F413|F324) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_1(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p3 wf3 p2 wf1 p1 | C_13_42, (F324|F413) | C_14_23, (F423|F314) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_1(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p1 wf1 p2 wf3 p3 | C_13_42, (F341|F432) | C_14_23, (F431|F342) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_1(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p2 wf2 p3 wf1 p1 | C_13_42, (F342|F431) | C_14_23, (F432|F341) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_1(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p1 wf1 p3 wf2 p2 let print_add_dscalar2_vector2_m_1_km c pa pb wf1 wf2 wf3 p1 p2 p3 fusion (coeff, contraction) = printf "@ + "; print_dscalar2_vector2_m_1_km c pa pb wf1 wf2 wf3 p1 p2 p3 fusion (coeff, contraction) let print_dscalar2_vector2_m_7_km c pa pb wf1 wf2 wf3 p1 p2 p3 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F123|F213|F124|F214) -> printf "@[((%s%s%s+%s))*v_phi2v_m_7(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf2 p2 wf3 p3 | C_12_34, (F134|F143|F234|F243) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_7(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf2 p2 wf3 p3 | C_12_34, (F132|F231|F142|F241) -> printf "@[((%s%s%s+%s))*v_phi2v_m_7(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf3 p3 wf2 p2 | C_12_34, (F312|F321|F412|F421) -> printf "@[((%s%s%s+%s))*v_phi2v_m_7(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p3 wf2 p2 wf1 p1 | C_12_34, (F314|F413|F324|F423) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_7(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p2 wf1 p1 wf3 p3 | C_12_34, (F341|F431|F342|F432) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_7(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p3 wf2 p2 wf1 p1 | C_13_42, (F123|F214) | C_14_23, (F124|F213) -> printf "@[((%s%s%s+%s))*v_phi2v_m_7(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf2 p3 wf3 p2 | C_13_42, (F124|F213) | C_14_23, (F123|F214) -> printf "@[((%s%s%s+%s))*v_phi2v_m_7(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p2 wf1 p3 wf3 p1 | C_13_42, (F132|F241) | C_14_23, (F142|F231) -> printf "@[((%s%s%s+%s))*v_phi2v_m_7(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p1 wf3 p2 wf2 p3 | C_13_42, (F142|F231) | C_14_23, (F132|F241) -> printf "@[((%s%s%s+%s))*v_phi2v_m_7(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p3 wf1 p2 wf2 p1 | C_13_42, (F312|F421) | C_14_23, (F412|F321) -> printf "@[((%s%s%s+%s))*v_phi2v_m_7(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p2 wf3 p1 wf1 p3 | C_13_42, (F321|F412) | C_14_23, (F421|F312) -> printf "@[((%s%s%s+%s))*v_phi2v_m_7(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p3 wf2 p1 wf1 p2 | C_13_42, (F134|F243) | C_14_23, (F143|F234) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_7(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p3 wf3 p1 wf2 p2 | C_13_42, (F143|F234) | C_14_23, (F134|F243) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_7(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf1 p2 wf2 p1 wf3 p3 | C_13_42, (F314|F423) | C_14_23, (F413|F324) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_7(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p3 wf3 p2 wf1 p1 | C_13_42, (F324|F413) | C_14_23, (F423|F314) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_7(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf2 p1 wf1 p2 wf3 p3 | C_13_42, (F341|F432) | C_14_23, (F431|F342) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_7(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p2 wf2 p3 wf1 p1 | C_13_42, (F342|F431) | C_14_23, (F432|F341) -> printf "@[((%s%s%s+%s))*phi_phi2v_m_7(cmplx(1,kind=default),@ %s,%s,%s,%s,%s,%s))@]" (format_coeff coeff) c pa pb wf3 p1 wf1 p3 wf2 p2 let print_add_dscalar2_vector2_m_7_km c pa pb wf1 wf2 wf3 p1 p2 p3 fusion (coeff, contraction) = printf "@ + "; print_dscalar2_vector2_m_7_km c pa pb wf1 wf2 wf3 p1 p2 p3 fusion (coeff, contraction) let print_dscalar4_km c pa pb wf1 wf2 wf3 p1 p2 p3 p123 fusion (coeff, contraction) = match contraction, fusion with | C_12_34, (F341|F431|F342|F432|F123|F213|F124|F214) | C_13_42, (F241|F421|F243|F423|F132|F312|F134|F314) | C_14_23, (F231|F321|F234|F324|F142|F412|F143|F413) -> printf "((%s%s%s+%s))*(%s*%s)*(%s*%s)*%s*%s*%s)" (format_coeff coeff) c pa pb p1 p2 p3 p123 wf1 wf2 wf3 | C_12_34, (F134|F143|F234|F243|F312|F321|F412|F421) | C_13_42, (F124|F142|F324|F342|F213|F231|F413|F431) | C_14_23, (F123|F132|F423|F432|F214|F241|F314|F341) -> printf "((%s%s%s+%s))*(%s*%s)*(%s*%s)*%s*%s*%s)" (format_coeff coeff) c pa pb p2 p3 p1 p123 wf1 wf2 wf3 | C_12_34, (F314|F413|F324|F423|F132|F231|F142|F241) | C_13_42, (F214|F412|F234|F432|F123|F321|F143|F341) | C_14_23, (F213|F312|F243|F342|F124|F421|F134|F431) -> printf "((%s%s%s+%s))*(%s*%s)*(%s*%s)*%s*%s*%s)" (format_coeff coeff) c pa pb p1 p3 p2 p123 wf1 wf2 wf3 let print_add_dscalar4_km c pa pb wf1 wf2 wf3 p1 p2 p3 p123 fusion (coeff, contraction) = printf "@ + "; print_dscalar4_km c pa pb wf1 wf2 wf3 p1 p2 p3 p123 fusion (coeff, contraction) let print_current amplitude dictionary rhs = match F.coupling rhs with | V3 (vertex, fusion, constant) -> let ch1, ch2 = children2 rhs in let wf1 = multiple_variable amplitude dictionary ch1 and wf2 = multiple_variable amplitude dictionary ch2 and p1 = momentum ch1 and p2 = momentum ch2 and m1 = CM.mass_symbol (F.flavor ch1) and m2 = CM.mass_symbol (F.flavor ch2) in let c = CM.constant_symbol constant in printf "@, %s " (if (F.sign rhs) < 0 then "-" else "+"); begin match vertex with (* Fermionic currents $\bar\psi\fmslash{A}\psi$ and $\bar\psi\phi\psi$ are handled by the [Fermions] module, since they depend on the choice of Feynman rules: Dirac or Majorana. *) | FBF (coeff, fb, b, f) -> begin match coeff, fb, b, f with | _, _, (VLRM|SPM|VAM|VA3M|TVA|TVAM|TLR|TLRM|TRL|TRLM), _ -> let p12 = Printf.sprintf "(-%s-%s)" p1 p2 in Fermions.print_current_mom (coeff, fb, b, f) c wf1 wf2 p1 p2 p12 fusion | _, _, _, _ -> Fermions.print_current (coeff, fb, b, f) c wf1 wf2 fusion end | PBP (coeff, f1, b, f2) -> Fermions.print_current_p (coeff, f1, b, f2) c wf1 wf2 fusion | BBB (coeff, fb1, b, fb2) -> Fermions.print_current_b (coeff, fb1, b, fb2) c wf1 wf2 fusion | GBG (coeff, fb, b, f) -> let p12 = Printf.sprintf "(-%s-%s)" p1 p2 in Fermions.print_current_g (coeff, fb, b, f) c wf1 wf2 p1 p2 p12 fusion (* Table~\ref{tab:dim4-bosons} is a bit misleading, since if includes totally antisymmetric structure constants. The space-time part alone is also totally antisymmetric: *) | Gauge_Gauge_Gauge coeff -> let c = format_coupling coeff c in begin match fusion with | (F23|F31|F12) -> printf "g_gg(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F32|F13|F21) -> printf "g_gg(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | I_Gauge_Gauge_Gauge coeff -> let c = format_coupling coeff c in begin match fusion with | (F23|F31|F12) -> printf "g_gg((0,1)*(%s),%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F32|F13|F21) -> printf "g_gg((0,1)*(%s),%s,%s,%s,%s)" c wf2 p2 wf1 p1 end (* In [Aux_Gauge_Gauge], we can not rely on antisymmetry alone, because of the different Lorentz representations of the auxialiary and the gauge field. Instead we have to provide the sign in \begin{equation} (V_2 \wedge V_3) \cdot T_1 = \begin{cases} V_2 \cdot (T_1 \cdot V_3) = - V_2 \cdot (V_3 \cdot T_1) & \\ V_3 \cdot (V_2 \cdot T_1) = - V_3 \cdot (T_1 \cdot V_2) & \end{cases} \end{equation} ourselves. Alternatively, one could provide \verb+g_xg+ mirroring \verb+g_gx+. *) | Aux_Gauge_Gauge coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "x_gg(%s,%s,%s)" c wf1 wf2 | F32 -> printf "x_gg(%s,%s,%s)" c wf2 wf1 | F12 -> printf "g_gx(%s,%s,%s)" c wf2 wf1 | F21 -> printf "g_gx(%s,%s,%s)" c wf1 wf2 | F13 -> printf "(-1)*g_gx(%s,%s,%s)" c wf2 wf1 | F31 -> printf "(-1)*g_gx(%s,%s,%s)" c wf1 wf2 end (* These cases are symmetric and we just have to juxtapose the correct fields and provide parentheses to minimize the number of multiplications. *) | Scalar_Vector_Vector coeff -> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "%s*(%s*%s)" c wf1 wf2 | (F12|F13) -> printf "(%s*%s)*%s" c wf1 wf2 | (F21|F31) -> printf "(%s*%s)*%s" c wf2 wf1 end | Aux_Vector_Vector coeff -> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "%s*(%s*%s)" c wf1 wf2 | (F12|F13) -> printf "(%s*%s)*%s" c wf1 wf2 | (F21|F31) -> printf "(%s*%s)*%s" c wf2 wf1 end (* Even simpler: *) | Scalar_Scalar_Scalar coeff -> printf "(%s*%s*%s)" (format_coupling coeff c) wf1 wf2 | Aux_Scalar_Scalar coeff -> printf "(%s*%s*%s)" (format_coupling coeff c) wf1 wf2 | Aux_Scalar_Vector coeff -> let c = format_coupling coeff c in begin match fusion with | (F13|F31) -> printf "%s*(%s*%s)" c wf1 wf2 | (F23|F21) -> printf "(%s*%s)*%s" c wf1 wf2 | (F32|F12) -> printf "(%s*%s)*%s" c wf2 wf1 end | Vector_Scalar_Scalar coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "v_ss(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F32 -> printf "v_ss(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F12 -> printf "s_vs(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F21 -> printf "s_vs(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F13 -> printf "(-1)*s_vs(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F31 -> printf "(-1)*s_vs(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | Graviton_Scalar_Scalar coeff -> let c = format_coupling coeff c in begin match fusion with | F12 -> printf "s_gravs(%s,%s,-(%s+%s),%s,%s,%s)" c m2 p1 p2 p2 wf1 wf2 | F21 -> printf "s_gravs(%s,%s,-(%s+%s),%s,%s,%s)" c m1 p1 p2 p1 wf2 wf1 | F13 -> printf "s_gravs(%s,%s,%s,-(%s+%s),%s,%s)" c m2 p2 p1 p2 wf1 wf2 | F31 -> printf "s_gravs(%s,%s,%s,-(%s+%s),%s,%s)" c m1 p1 p1 p2 wf2 wf1 | F23 -> printf "grav_ss(%s,%s,%s,%s,%s,%s)" c m1 p1 p2 wf1 wf2 | F32 -> printf "grav_ss(%s,%s,%s,%s,%s,%s)" c m1 p2 p1 wf2 wf1 end (* In producing a vector in the fusion we always contract the rightmost index with the vector wavefunction from [rhs]. So the first momentum is always the one of the vector boson produced in the fusion, while the second one is that from the [rhs]. This makes the cases [F12] and [F13] as well as [F21] and [F31] equal. In principle, we could have already done this for the [Graviton_Scalar_Scalar] case. *) | Graviton_Vector_Vector coeff -> let c = format_coupling coeff c in begin match fusion with | (F12|F13) -> printf "v_gravv(%s,%s,-(%s+%s),%s,%s,%s)" c m2 p1 p2 p2 wf1 wf2 | (F21|F31) -> printf "v_gravv(%s,%s,-(%s+%s),%s,%s,%s)" c m1 p1 p2 p1 wf2 wf1 | F23 -> printf "grav_vv(%s,%s,%s,%s,%s,%s)" c m1 p1 p2 wf1 wf2 | F32 -> printf "grav_vv(%s,%s,%s,%s,%s,%s)" c m1 p2 p1 wf2 wf1 end | Graviton_Spinor_Spinor coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "f_gravf(%s,%s,-(%s+%s),(-%s),%s,%s)" c m2 p1 p2 p2 wf1 wf2 | F32 -> printf "f_gravf(%s,%s,-(%s+%s),(-%s),%s,%s)" c m1 p1 p2 p1 wf2 wf1 | F12 -> printf "f_fgrav(%s,%s,%s,%s+%s,%s,%s)" c m1 p1 p1 p2 wf1 wf2 | F21 -> printf "f_fgrav(%s,%s,%s,%s+%s,%s,%s)" c m2 p2 p1 p2 wf2 wf1 | F13 -> printf "grav_ff(%s,%s,%s,(-%s),%s,%s)" c m1 p1 p2 wf1 wf2 | F31 -> printf "grav_ff(%s,%s,%s,(-%s),%s,%s)" c m1 p2 p1 wf2 wf1 end | Dim4_Vector_Vector_Vector_T coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "tkv_vv(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F32 -> printf "tkv_vv(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F12 -> printf "tv_kvv(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F21 -> printf "tv_kvv(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F13 -> printf "(-1)*tv_kvv(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F31 -> printf "(-1)*tv_kvv(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | Dim4_Vector_Vector_Vector_L coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "lkv_vv(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F32 -> printf "lkv_vv(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F12 | F13 -> printf "lv_kvv(%s,%s,%s,%s)" c wf1 p1 wf2 | F21 | F31 -> printf "lv_kvv(%s,%s,%s,%s)" c wf2 p2 wf1 end | Dim6_Gauge_Gauge_Gauge coeff -> let c = format_coupling coeff c in begin match fusion with | F23 | F31 | F12 -> printf "kg_kgkg(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F32 | F13 | F21 -> printf "kg_kgkg(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | Dim4_Vector_Vector_Vector_T5 coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "t5kv_vv(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F32 -> printf "t5kv_vv(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F12 | F13 -> printf "t5v_kvv(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F21 | F31 -> printf "t5v_kvv(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | Dim4_Vector_Vector_Vector_L5 coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "l5kv_vv(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F32 -> printf "l5kv_vv(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F12 -> printf "l5v_kvv(%s,%s,%s,%s)" c wf1 p1 wf2 | F21 -> printf "l5v_kvv(%s,%s,%s,%s)" c wf2 p2 wf1 | F13 -> printf "(-1)*l5v_kvv(%s,%s,%s,%s)" c wf1 p1 wf2 | F31 -> printf "(-1)*l5v_kvv(%s,%s,%s,%s)" c wf2 p2 wf1 end | Dim6_Gauge_Gauge_Gauge_5 coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "kg5_kgkg(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F32 -> printf "kg5_kgkg(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F12 -> printf "kg_kg5kg(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F21 -> printf "kg_kg5kg(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F13 -> printf "(-1)*kg_kg5kg(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F31 -> printf "(-1)*kg_kg5kg(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | Aux_DScalar_DScalar coeff -> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "%s*(%s*%s)*(%s*%s)" c p1 p2 wf1 wf2 | (F12|F13) -> printf "%s*(-((%s+%s)*%s))*(%s*%s)" c p1 p2 p2 wf1 wf2 | (F21|F31) -> printf "%s*(-((%s+%s)*%s))*(%s*%s)" c p1 p2 p1 wf1 wf2 end | Aux_Vector_DScalar coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "%s*(%s*%s)*%s" c wf1 p2 wf2 | F32 -> printf "%s*(%s*%s)*%s" c wf2 p1 wf1 | F12 -> printf "%s*(-((%s+%s)*%s))*%s" c p1 p2 wf2 wf1 | F21 -> printf "%s*(-((%s+%s)*%s))*%s" c p1 p2 wf1 wf2 | (F13|F31) -> printf "(-(%s+%s))*(%s*%s*%s)" p1 p2 c wf1 wf2 end | Dim5_Scalar_Gauge2 coeff -> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "(%s)*((%s*%s)*(%s*%s) - (%s*%s)*(%s*%s))" c p1 wf2 p2 wf1 p1 p2 wf2 wf1 | (F12|F13) -> printf "(%s)*%s*((-((%s+%s)*%s))*%s - ((-(%s+%s)*%s))*%s)" c wf1 p1 p2 wf2 p2 p1 p2 p2 wf2 | (F21|F31) -> printf "(%s)*%s*((-((%s+%s)*%s))*%s - ((-(%s+%s)*%s))*%s)" c wf2 p2 p1 wf1 p1 p1 p2 p1 wf1 end | Dim5_Scalar_Gauge2_Skew coeff -> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "(- phi_vv (%s, %s, %s, %s, %s))" c p1 p2 wf1 wf2 | (F12|F13) -> printf "(- v_phiv (%s, %s, %s, %s, %s))" c wf1 p1 p2 wf2 | (F21|F31) -> printf "v_phiv (%s, %s, %s, %s, %s)" c wf2 p1 p2 wf1 end | Dim5_Scalar_Vector_Vector_T coeff -> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "(%s)*(%s*%s)*(%s*%s)" c p1 wf2 p2 wf1 | (F12|F13) -> printf "(%s)*%s*(-((%s+%s)*%s))*%s" c wf1 p1 p2 wf2 p2 | (F21|F31) -> printf "(%s)*%s*(-((%s+%s)*%s))*%s" c wf2 p2 p1 wf1 p1 end | Dim5_Scalar_Vector_Vector_U coeff -> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "phi_u_vv (%s, %s, %s, %s, %s)" c p1 p2 wf1 wf2 | (F12|F13) -> printf "v_u_phiv (%s, %s, %s, %s, %s)" c wf1 p1 p2 wf2 | (F21|F31) -> printf "v_u_phiv (%s, %s, %s, %s, %s)" c wf2 p2 p1 wf1 end | Dim5_Scalar_Vector_Vector_TU coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "(%s)*((%s*%s)*(-(%s+%s)*%s) - (-(%s+%s)*%s)*(%s*%s))" c p1 wf2 p1 p2 wf1 p1 p2 p1 wf1 wf2 | F32 -> printf "(%s)*((%s*%s)*(-(%s+%s)*%s) - (-(%s+%s)*%s)*(%s*%s))" c p2 wf1 p1 p2 wf2 p1 p2 p2 wf1 wf2 | F12 -> printf "(%s)*%s*((%s*%s)*%s - (%s*%s)*%s)" c wf1 p1 wf2 p2 p1 p2 wf2 | F21 -> printf "(%s)*%s*((%s*%s)*%s - (%s*%s)*%s)" c wf2 p2 wf1 p1 p1 p2 wf1 | F13 -> printf "(%s)*%s*((-(%s+%s)*%s)*%s - (-(%s+%s)*%s)*%s)" c wf1 p1 p2 wf2 p1 p1 p2 p1 wf2 | F31 -> printf "(%s)*%s*((-(%s+%s)*%s)*%s - (-(%s+%s)*%s)*%s)" c wf2 p1 p2 wf1 p2 p1 p2 p2 wf1 end | Dim5_Scalar_Scalar2 coeff-> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "phi_dim5s2(%s, %s ,%s, %s, %s)" c wf1 p1 wf2 p2 | (F12|F13) -> let p12 = Printf.sprintf "(-%s-%s)" p1 p2 in printf "phi_dim5s2(%s,%s,%s,%s,%s)" c wf1 p12 wf2 p2 | (F21|F31) -> let p12 = Printf.sprintf "(-%s-%s)" p1 p2 in printf "phi_dim5s2(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p12 end | Scalar_Vector_Vector_t coeff -> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "s_vv_t(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F12|F13) -> printf "v_sv_t(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F21|F31) -> printf "v_sv_t(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | Dim6_Vector_Vector_Vector_T coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "(%s)*(%s*%s)*(%s*%s)*(%s-%s)" c p2 wf1 p1 wf2 p1 p2 | F32 -> printf "(%s)*(%s*%s)*(%s*%s)*(%s-%s)" c p1 wf2 p2 wf1 p2 p1 | (F12|F13) -> printf "(%s)*((%s+2*%s)*%s)*(-((%s+%s)*%s))*%s" c p1 p2 wf1 p1 p2 wf2 p2 | (F21|F31) -> printf "(%s)*((-((%s+%s)*%s))*(%s+2*%s)*%s)*%s" c p2 p1 wf1 p2 p1 wf2 p1 end | Tensor_2_Vector_Vector coeff -> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "t2_vv(%s,%s,%s)" c wf1 wf2 | (F12|F13) -> printf "v_t2v(%s,%s,%s)" c wf1 wf2 | (F21|F31) -> printf "v_t2v(%s,%s,%s)" c wf2 wf1 end | Tensor_2_Scalar_Scalar coeff-> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "t2_phi2(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F12|F13) -> printf "phi_t2phi(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F21|F31) -> printf "phi_t2phi(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | Tensor_2_Vector_Vector_1 coeff -> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "t2_vv_1(%s,%s,%s)" c wf1 wf2 | (F12|F13) -> printf "v_t2v_1(%s,%s,%s)" c wf1 wf2 | (F21|F31) -> printf "v_t2v_1(%s,%s,%s)" c wf2 wf1 end | Tensor_2_Vector_Vector_cf coeff-> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "t2_vv_cf(%s,%s,%s)" c wf1 wf2 | (F12|F13) -> printf "v_t2v_cf(%s,%s,%s)" c wf1 wf2 | (F21|F31) -> printf "v_t2v_cf(%s,%s,%s)" c wf2 wf1 end | Tensor_2_Scalar_Scalar_cf coeff-> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "t2_phi2_cf(%s,%s,%s,%s, %s)" c wf1 p1 wf2 p2 | (F12|F13) -> printf "phi_t2phi_cf(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F21|F31) -> printf "phi_t2phi_cf(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | Dim5_Tensor_2_Vector_Vector_1 coeff -> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "t2_vv_d5_1(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F12|F13) -> printf "v_t2v_d5_1(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F21|F31) -> printf "v_t2v_d5_1(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | Tensor_2_Vector_Vector_t coeff -> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "t2_vv_t(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F12|F13) -> printf "v_t2v_t(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F21|F31) -> printf "v_t2v_t(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | Dim5_Tensor_2_Vector_Vector_2 coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "t2_vv_d5_2(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F32 -> printf "t2_vv_d5_2(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | (F12|F13) -> printf "v_t2v_d5_2(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F21|F31) -> printf "v_t2v_d5_2(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | TensorVector_Vector_Vector coeff-> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "dv_vv(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F12|F13) -> printf "v_dvv(%s,%s,%s,%s)" c wf1 p1 wf2 | (F21|F31) -> printf "v_dvv(%s,%s,%s,%s)" c wf2 p2 wf1 end | TensorVector_Vector_Vector_cf coeff-> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "dv_vv_cf(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F12|F13) -> printf "v_dvv_cf(%s,%s,%s,%s)" c wf1 p1 wf2 | (F21|F31) -> printf "v_dvv_cf(%s,%s,%s,%s)" c wf2 p2 wf1 end | TensorVector_Scalar_Scalar coeff-> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "dv_phi2(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F12|F13) -> printf "phi_dvphi(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F21|F31) -> printf "phi_dvphi(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | TensorVector_Scalar_Scalar_cf coeff-> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "dv_phi2_cf(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F12|F13) -> printf "phi_dvphi_cf(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F21|F31) -> printf "phi_dvphi_cf(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | TensorScalar_Vector_Vector coeff-> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "tphi_vv(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F12|F13) -> printf "v_tphiv(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F21|F31) -> printf "v_tphiv(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | TensorScalar_Vector_Vector_cf coeff-> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "tphi_vv_cf(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F12|F13) -> printf "v_tphiv_cf(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F21|F31) -> printf "v_tphiv_cf(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | TensorScalar_Scalar_Scalar coeff-> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "tphi_ss(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F12|F13) -> printf "s_tphis(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F21|F31) -> printf "s_tphis(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | TensorScalar_Scalar_Scalar_cf coeff-> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "tphi_ss_cf(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F12|F13) -> printf "s_tphis_cf(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F21|F31) -> printf "s_tphis_cf(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | Dim7_Tensor_2_Vector_Vector_T coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "t2_vv_d7(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F32 -> printf "t2_vv_d7(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | (F12|F13) -> printf "v_t2v_d7(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F21|F31) -> printf "v_t2v_d7(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | Dim6_Scalar_Vector_Vector_D coeff -> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "s_vv_6D(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F12|F13) -> printf "v_sv_6D(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F21|F31) -> printf "v_sv_6D(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | Dim6_Scalar_Vector_Vector_DP coeff -> let c = format_coupling coeff c in begin match fusion with | (F23|F32) -> printf "s_vv_6DP(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F12|F13) -> printf "v_sv_6DP(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F21|F31) -> printf "v_sv_6DP(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | Dim6_HAZ_D coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "h_az_D(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F32 -> printf "h_az_D(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F13 -> printf "a_hz_D(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F31 -> printf "a_hz_D(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F12 -> printf "z_ah_D(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F21 -> printf "z_ah_D(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 end | Dim6_HAZ_DP coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "h_az_DP(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F32 -> printf "h_az_DP(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F13 -> printf "a_hz_DP(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F31 -> printf "a_hz_DP(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F12 -> printf "z_ah_DP(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F21 -> printf "z_ah_DP(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 end | Gauge_Gauge_Gauge_i coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "g_gg_23(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F32 -> printf "g_gg_23(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F13 -> printf "g_gg_13(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F31 -> printf "g_gg_13(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F12 -> printf "(-1) * g_gg_13(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F21 -> printf "(-1) * g_gg_13(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | Dim6_GGG coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "g_gg_6(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F32 -> printf "g_gg_6(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F12 -> printf "g_gg_6(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F21 -> printf "g_gg_6(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F13 -> printf "(-1) * g_gg_6(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F31 -> printf "(-1) * g_gg_6(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | Dim6_AWW_DP coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "a_ww_DP(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F32 -> printf "a_ww_DP(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F13 -> printf "w_aw_DP(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F31 -> printf "w_aw_DP(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F12 -> printf "(-1) * w_aw_DP(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F21 -> printf "(-1) * w_aw_DP(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | Dim6_AWW_DW coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "a_ww_DW(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F32 -> printf "a_ww_DW(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F13 -> printf "(-1) * a_ww_DW(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F31 -> printf "(-1) * a_ww_DW(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F12 -> printf "a_ww_DW(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F21 -> printf "a_ww_DW(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | Dim6_Gauge_Gauge_Gauge_i coeff -> let c = format_coupling coeff c in begin match fusion with | F23 | F31 | F12 -> printf "kg_kgkg_i(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F32 | F13 | F21 -> printf "kg_kgkg_i(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | Dim6_HHH coeff -> let c = format_coupling coeff c in begin match fusion with | (F23|F32|F12|F21|F13|F31) -> printf "h_hh_6(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 end | Dim6_WWZ_DPWDW coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "w_wz_DPW(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F32 -> printf "w_wz_DPW(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F13 -> printf "(-1) * w_wz_DPW(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F31 -> printf "(-1) * w_wz_DPW(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F12 -> printf "z_ww_DPW(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F21 -> printf "z_ww_DPW(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | Dim6_WWZ_DW coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "w_wz_DW(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F32 -> printf "w_wz_DW(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F13 -> printf "(-1) * w_wz_DW(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F31 -> printf "(-1) * w_wz_DW(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F12 -> printf "z_ww_DW(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F21 -> printf "z_ww_DW(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end | Dim6_WWZ_D coeff -> let c = format_coupling coeff c in begin match fusion with | F23 -> printf "w_wz_D(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F32 -> printf "w_wz_D(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F13 -> printf "(-1) * w_wz_D(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F31 -> printf "(-1) * w_wz_D(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 | F12 -> printf "z_ww_D(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | F21 -> printf "z_ww_D(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end (*i | Dim6_Glu_Glu_Glu coeff -> let c = format_coupling coeff c in begin match fusion with | (F23|F31|F12) -> printf "g_gg_glu(%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 | (F32|F13|F21) -> printf "g_gg_glu(%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 end i*) end (* Flip the sign to account for the~$\mathrm{i}^2$ relative to diagrams with only cubic couplings. \label{hack:sign(V4)} *) (* \begin{dubious} That's an \emph{slightly dangerous} hack!!! How do we accnount for such signs when treating $n$-ary vertices uniformly? \end{dubious} *) | V4 (vertex, fusion, constant) -> let c = CM.constant_symbol constant and ch1, ch2, ch3 = children3 rhs in let wf1 = multiple_variable amplitude dictionary ch1 and wf2 = multiple_variable amplitude dictionary ch2 and wf3 = multiple_variable amplitude dictionary ch3 and p1 = momentum ch1 and p2 = momentum ch2 and p3 = momentum ch3 in printf "@, %s " (if (F.sign rhs) < 0 then "+" else "-"); begin match vertex with | Scalar4 coeff -> printf "(%s*%s*%s*%s)" (format_coupling coeff c) wf1 wf2 wf3 | Scalar2_Vector2 coeff -> let c = format_coupling coeff c in begin match fusion with | F134 | F143 | F234 | F243 -> printf "%s*%s*(%s*%s)" c wf1 wf2 wf3 | F314 | F413 | F324 | F423 -> printf "%s*%s*(%s*%s)" c wf2 wf1 wf3 | F341 | F431 | F342 | F432 -> printf "%s*%s*(%s*%s)" c wf3 wf1 wf2 | F312 | F321 | F412 | F421 -> printf "(%s*%s*%s)*%s" c wf2 wf3 wf1 | F231 | F132 | F241 | F142 -> printf "(%s*%s*%s)*%s" c wf1 wf3 wf2 | F123 | F213 | F124 | F214 -> printf "(%s*%s*%s)*%s" c wf1 wf2 wf3 end | Vector4 contractions -> begin match contractions with | [] -> invalid_arg "Targets.print_current: Vector4 []" | head :: tail -> printf "("; print_vector4 c wf1 wf2 wf3 fusion head; List.iter (print_add_vector4 c wf1 wf2 wf3 fusion) tail; printf ")" end | Dim8_Vector4_t_0 contractions -> begin match contractions with | [] -> invalid_arg "Targets.print_current: Vector4 []" | head :: tail -> print_vector4_t_0 c wf1 p1 wf2 p2 wf3 p3 fusion head; List.iter (print_add_vector4 c wf1 wf2 wf3 fusion) tail; end | Dim8_Vector4_t_1 contractions -> begin match contractions with | [] -> invalid_arg "Targets.print_current: Vector4 []" | head :: tail -> print_vector4_t_1 c wf1 p1 wf2 p2 wf3 p3 fusion head; List.iter (print_add_vector4 c wf1 wf2 wf3 fusion) tail; end | Dim8_Vector4_t_2 contractions -> begin match contractions with | [] -> invalid_arg "Targets.print_current: Vector4 []" | head :: tail -> print_vector4_t_2 c wf1 p1 wf2 p2 wf3 p3 fusion head; List.iter (print_add_vector4 c wf1 wf2 wf3 fusion) tail; end | Dim8_Vector4_m_0 contractions -> begin match contractions with | [] -> invalid_arg "Targets.print_current: Vector4 []" | head :: tail -> print_vector4_m_0 c wf1 p1 wf2 p2 wf3 p3 fusion head; List.iter (print_add_vector4 c wf1 wf2 wf3 fusion) tail; end | Dim8_Vector4_m_1 contractions -> begin match contractions with | [] -> invalid_arg "Targets.print_current: Vector4 []" | head :: tail -> print_vector4_m_1 c wf1 p1 wf2 p2 wf3 p3 fusion head; List.iter (print_add_vector4 c wf1 wf2 wf3 fusion) tail; end | Dim8_Vector4_m_7 contractions -> begin match contractions with | [] -> invalid_arg "Targets.print_current: Vector4 []" | head :: tail -> print_vector4_m_7 c wf1 p1 wf2 p2 wf3 p3 fusion head; List.iter (print_add_vector4 c wf1 wf2 wf3 fusion) tail; end | Vector4_K_Matrix_tho (_, poles) -> let pa, pb = begin match fusion with | (F341|F431|F342|F432|F123|F213|F124|F214) -> (p1, p2) | (F134|F143|F234|F243|F312|F321|F412|F421) -> (p2, p3) | (F314|F413|F324|F423|F132|F231|F142|F241) -> (p1, p3) end in printf "(%s*(%s*%s)*(%s*%s)*(%s*%s)@,*(" c p1 wf1 p2 wf2 p3 wf3; List.iter (fun (coeff, pole) -> printf "+%s/((%s+%s)*(%s+%s)-%s)" (CM.constant_symbol coeff) pa pb pa pb (CM.constant_symbol pole)) poles; printf ")*(-%s-%s-%s))" p1 p2 p3 | Vector4_K_Matrix_jr (disc, contractions) -> let pa, pb = begin match disc, fusion with | 3, (F143|F413|F142|F412|F321|F231|F324|F234) -> (p1, p2) | 3, (F314|F341|F214|F241|F132|F123|F432|F423) -> (p2, p3) | 3, (F134|F431|F124|F421|F312|F213|F342|F243) -> (p1, p3) | _, (F341|F431|F342|F432|F123|F213|F124|F214) -> (p1, p2) | _, (F134|F143|F234|F243|F312|F321|F412|F421) -> (p2, p3) | _, (F314|F413|F324|F423|F132|F231|F142|F241) -> (p1, p3) end in begin match contractions with | [] -> invalid_arg "Targets.print_current: Vector4_K_Matrix_jr []" | head :: tail -> printf "("; print_vector4_km c pa pb wf1 wf2 wf3 fusion head; List.iter (print_add_vector4_km c pa pb wf1 wf2 wf3 fusion) tail; printf ")" end | Vector4_K_Matrix_cf_t0 (disc, contractions) -> let pa, pb, pc = begin match disc, fusion with | 3, (F143|F413|F142|F412|F321|F231|F324|F234) -> (p1, p2, p3) | 3, (F314|F341|F214|F241|F132|F123|F432|F423) -> (p2, p3, p1) | 3, (F134|F431|F124|F421|F312|F213|F342|F243) -> (p1, p3, p2) | _, (F341|F431|F342|F432|F123|F213|F124|F214) -> (p1, p2, p3) | _, (F134|F143|F234|F243|F312|F321|F412|F421) -> (p2, p3, p1) | _, (F314|F413|F324|F423|F132|F231|F142|F241) -> (p1, p3, p2) end in begin match contractions with | [] -> invalid_arg "Targets.print_current: Vector4_K_Matrix_cf_t0 []" | head :: tail -> printf "("; print_vector4_km_t_0 c pa pb wf1 p1 wf2 p2 wf3 p3 fusion head; List.iter (print_add_vector4_km c pa pb wf1 wf2 wf3 fusion) tail; printf ")" end | Vector4_K_Matrix_cf_t1 (disc, contractions) -> let pa, pb = begin match disc, fusion with | 3, (F143|F413|F142|F412|F321|F231|F324|F234) -> (p1, p2) | 3, (F314|F341|F214|F241|F132|F123|F432|F423) -> (p2, p3) | 3, (F134|F431|F124|F421|F312|F213|F342|F243) -> (p1, p3) | _, (F341|F431|F342|F432|F123|F213|F124|F214) -> (p1, p2) | _, (F134|F143|F234|F243|F312|F321|F412|F421) -> (p2, p3) | _, (F314|F413|F324|F423|F132|F231|F142|F241) -> (p1, p3) end in begin match contractions with | [] -> invalid_arg "Targets.print_current: Vector4_K_Matrix_cf_t1 []" | head :: tail -> printf "("; print_vector4_km_t_1 c pa pb wf1 p1 wf2 p2 wf3 p3 fusion head; List.iter (print_add_vector4_km c pa pb wf1 wf2 wf3 fusion) tail; printf ")" end | Vector4_K_Matrix_cf_t2 (disc, contractions) -> let pa, pb = begin match disc, fusion with | 3, (F143|F413|F142|F412|F321|F231|F324|F234) -> (p1, p2) | 3, (F314|F341|F214|F241|F132|F123|F432|F423) -> (p2, p3) | 3, (F134|F431|F124|F421|F312|F213|F342|F243) -> (p1, p3) | _, (F341|F431|F342|F432|F123|F213|F124|F214) -> (p1, p2) | _, (F134|F143|F234|F243|F312|F321|F412|F421) -> (p2, p3) | _, (F314|F413|F324|F423|F132|F231|F142|F241) -> (p1, p3) end in begin match contractions with | [] -> invalid_arg "Targets.print_current: Vector4_K_Matrix_cf_t2 []" | head :: tail -> printf "("; print_vector4_km_t_2 c pa pb wf1 p1 wf2 p2 wf3 p3 fusion head; List.iter (print_add_vector4_km c pa pb wf1 wf2 wf3 fusion) tail; printf ")" end | Vector4_K_Matrix_cf_t_rsi (disc, contractions) -> let pa, pb, pc = begin match disc, fusion with | 3, (F143|F413|F142|F412|F321|F231|F324|F234) -> (p1, p2, p3) | 3, (F314|F341|F214|F241|F132|F123|F432|F423) -> (p2, p3, p1) | 3, (F134|F431|F124|F421|F312|F213|F342|F243) -> (p1, p3, p2) | _, (F341|F431|F342|F432|F123|F213|F124|F214) -> (p1, p2, p3) | _, (F134|F143|F234|F243|F312|F321|F412|F421) -> (p2, p3, p1) | _, (F314|F413|F324|F423|F132|F231|F142|F241) -> (p1, p3, p2) end in begin match contractions with | [] -> invalid_arg "Targets.print_current: Vector4_K_Matrix_cf_t_rsi []" | head :: tail -> printf "("; print_vector4_km_t_rsi c pa pb pc wf1 p1 wf2 p2 wf3 p3 fusion head; List.iter (print_add_vector4_km c pa pb wf1 wf2 wf3 fusion) tail; printf ")" end | Vector4_K_Matrix_cf_m0 (disc, contractions) -> let pa, pb = begin match disc, fusion with | 3, (F143|F413|F142|F412|F321|F231|F324|F234) -> (p1, p2) | 3, (F314|F341|F214|F241|F132|F123|F432|F423) -> (p2, p3) | 3, (F134|F431|F124|F421|F312|F213|F342|F243) -> (p1, p3) | _, (F341|F431|F342|F432|F123|F213|F124|F214) -> (p1, p2) | _, (F134|F143|F234|F243|F312|F321|F412|F421) -> (p2, p3) | _, (F314|F413|F324|F423|F132|F231|F142|F241) -> (p1, p3) end in begin match contractions with | [] -> invalid_arg "Targets.print_current: Vector4_K_Matrix_cf_m0 []" | head :: tail -> printf "("; print_vector4_km_m_0 c pa pb wf1 p1 wf2 p2 wf3 p3 fusion head; List.iter (print_add_vector4_km c pa pb wf1 wf2 wf3 fusion) tail; printf ")" end | Vector4_K_Matrix_cf_m1 (disc, contractions) -> let pa, pb = begin match disc, fusion with | 3, (F143|F413|F142|F412|F321|F231|F324|F234) -> (p1, p2) | 3, (F314|F341|F214|F241|F132|F123|F432|F423) -> (p2, p3) | 3, (F134|F431|F124|F421|F312|F213|F342|F243) -> (p1, p3) | _, (F341|F431|F342|F432|F123|F213|F124|F214) -> (p1, p2) | _, (F134|F143|F234|F243|F312|F321|F412|F421) -> (p2, p3) | _, (F314|F413|F324|F423|F132|F231|F142|F241) -> (p1, p3) end in begin match contractions with | [] -> invalid_arg "Targets.print_current: Vector4_K_Matrix_cf_m1 []" | head :: tail -> printf "("; print_vector4_km_m_1 c pa pb wf1 p1 wf2 p2 wf3 p3 fusion head; List.iter (print_add_vector4_km c pa pb wf1 wf2 wf3 fusion) tail; printf ")" end | Vector4_K_Matrix_cf_m7 (disc, contractions) -> let pa, pb = begin match disc, fusion with | 3, (F143|F413|F142|F412|F321|F231|F324|F234) -> (p1, p2) | 3, (F314|F341|F214|F241|F132|F123|F432|F423) -> (p2, p3) | 3, (F134|F431|F124|F421|F312|F213|F342|F243) -> (p1, p3) | _, (F341|F431|F342|F432|F123|F213|F124|F214) -> (p1, p2) | _, (F134|F143|F234|F243|F312|F321|F412|F421) -> (p2, p3) | _, (F314|F413|F324|F423|F132|F231|F142|F241) -> (p1, p3) end in begin match contractions with | [] -> invalid_arg "Targets.print_current: Vector4_K_Matrix_cf_m7 []" | head :: tail -> printf "("; print_vector4_km_m_7 c pa pb wf1 p1 wf2 p2 wf3 p3 fusion head; List.iter (print_add_vector4_km c pa pb wf1 wf2 wf3 fusion) tail; printf ")" end | DScalar2_Vector2_K_Matrix_ms (disc, contractions) -> let p123 = Printf.sprintf "(-%s-%s-%s)" p1 p2 p3 in let pa, pb = begin match disc, fusion with | 3, (F143|F413|F142|F412|F321|F231|F324|F234) -> (p1, p2) | 3, (F314|F341|F214|F241|F132|F123|F432|F423) -> (p2, p3) | 3, (F134|F431|F124|F421|F312|F213|F342|F243) -> (p1, p3) | 4, (F143|F413|F142|F412|F321|F231|F324|F234) -> (p1, p2) | 4, (F314|F341|F214|F241|F132|F123|F432|F423) -> (p2, p3) | 4, (F134|F431|F124|F421|F312|F213|F342|F243) -> (p1, p3) | 5, (F143|F413|F142|F412|F321|F231|F324|F234) -> (p1, p2) | 5, (F314|F341|F214|F241|F132|F123|F432|F423) -> (p2, p3) | 5, (F134|F431|F124|F421|F312|F213|F342|F243) -> (p1, p3) | 6, (F134|F132|F314|F312|F241|F243|F421|F423) -> (p1, p2) | 6, (F213|F413|F231|F431|F124|F324|F142|F342) -> (p2, p3) | 6, (F143|F123|F341|F321|F412|F214|F432|F234) -> (p1, p3) | 7, (F134|F132|F314|F312|F241|F243|F421|F423) -> (p1, p2) | 7, (F213|F413|F231|F431|F124|F324|F142|F342) -> (p2, p3) | 7, (F143|F123|F341|F321|F412|F214|F432|F234) -> (p1, p3) | 8, (F134|F132|F314|F312|F241|F243|F421|F423) -> (p1, p2) | 8, (F213|F413|F231|F431|F124|F324|F142|F342) -> (p2, p3) | 8, (F143|F123|F341|F321|F412|F214|F432|F234) -> (p1, p3) | _, (F341|F431|F342|F432|F123|F213|F124|F214) -> (p1, p2) | _, (F134|F143|F234|F243|F312|F321|F412|F421) -> (p2, p3) | _, (F314|F413|F324|F423|F132|F231|F142|F241) -> (p1, p3) end in begin match contractions with | [] -> invalid_arg "Targets.print_current: DScalar2_Vector4_K_Matrix_ms []" | head :: tail -> printf "("; print_dscalar2_vector2_km c pa pb wf1 wf2 wf3 p1 p2 p3 p123 fusion head; List.iter (print_add_dscalar2_vector2_km c pa pb wf1 wf2 wf3 p1 p2 p3 p123 fusion) tail; printf ")" end | DScalar2_Vector2_m_0_K_Matrix_cf (disc, contractions) -> let pa, pb = begin match disc, fusion with | 3, (F143|F413|F142|F412|F321|F231|F324|F234) -> (p1, p2) | 3, (F314|F341|F214|F241|F132|F123|F432|F423) -> (p2, p3) | 3, (F134|F431|F124|F421|F312|F213|F342|F243) -> (p1, p3) | 4, (F143|F413|F142|F412|F321|F231|F324|F234) -> (p1, p2) | 4, (F314|F341|F214|F241|F132|F123|F432|F423) -> (p2, p3) | 4, (F134|F431|F124|F421|F312|F213|F342|F243) -> (p1, p3) | 5, (F143|F413|F142|F412|F321|F231|F324|F234) -> (p1, p2) | 5, (F314|F341|F214|F241|F132|F123|F432|F423) -> (p2, p3) | 5, (F134|F431|F124|F421|F312|F213|F342|F243) -> (p1, p3) | 6, (F134|F132|F314|F312|F241|F243|F421|F423) -> (p1, p2) | 6, (F213|F413|F231|F431|F124|F324|F142|F342) -> (p2, p3) | 6, (F143|F123|F341|F321|F412|F214|F432|F234) -> (p1, p3) | 7, (F134|F132|F314|F312|F241|F243|F421|F423) -> (p1, p2) | 7, (F213|F413|F231|F431|F124|F324|F142|F342) -> (p2, p3) | 7, (F143|F123|F341|F321|F412|F214|F432|F234) -> (p1, p3) | 8, (F134|F132|F314|F312|F241|F243|F421|F423) -> (p1, p2) | 8, (F213|F413|F231|F431|F124|F324|F142|F342) -> (p2, p3) | 8, (F143|F123|F341|F321|F412|F214|F432|F234) -> (p1, p3) | _, (F341|F431|F342|F432|F123|F213|F124|F214) -> (p1, p2) | _, (F134|F143|F234|F243|F312|F321|F412|F421) -> (p2, p3) | _, (F314|F413|F324|F423|F132|F231|F142|F241) -> (p1, p3) end in begin match contractions with | [] -> invalid_arg "Targets.print_current: DScalar2_Vector4_K_Matrix_cf_m0 []" | head :: tail -> printf "("; print_dscalar2_vector2_m_0_km c pa pb wf1 wf2 wf3 p1 p2 p3 fusion head; List.iter (print_add_dscalar2_vector2_m_0_km c pa pb wf1 wf2 wf3 p1 p2 p3 fusion) tail; printf ")" end | DScalar2_Vector2_m_1_K_Matrix_cf (disc, contractions) -> let pa, pb = begin match disc, fusion with | 3, (F143|F413|F142|F412|F321|F231|F324|F234) -> (p1, p2) | 3, (F314|F341|F214|F241|F132|F123|F432|F423) -> (p2, p3) | 3, (F134|F431|F124|F421|F312|F213|F342|F243) -> (p1, p3) | 4, (F143|F413|F142|F412|F321|F231|F324|F234) -> (p1, p2) | 4, (F314|F341|F214|F241|F132|F123|F432|F423) -> (p2, p3) | 4, (F134|F431|F124|F421|F312|F213|F342|F243) -> (p1, p3) | 5, (F143|F413|F142|F412|F321|F231|F324|F234) -> (p1, p2) | 5, (F314|F341|F214|F241|F132|F123|F432|F423) -> (p2, p3) | 5, (F134|F431|F124|F421|F312|F213|F342|F243) -> (p1, p3) | 6, (F134|F132|F314|F312|F241|F243|F421|F423) -> (p1, p2) | 6, (F213|F413|F231|F431|F124|F324|F142|F342) -> (p2, p3) | 6, (F143|F123|F341|F321|F412|F214|F432|F234) -> (p1, p3) | 7, (F134|F132|F314|F312|F241|F243|F421|F423) -> (p1, p2) | 7, (F213|F413|F231|F431|F124|F324|F142|F342) -> (p2, p3) | 7, (F143|F123|F341|F321|F412|F214|F432|F234) -> (p1, p3) | 8, (F134|F132|F314|F312|F241|F243|F421|F423) -> (p1, p2) | 8, (F213|F413|F231|F431|F124|F324|F142|F342) -> (p2, p3) | 8, (F143|F123|F341|F321|F412|F214|F432|F234) -> (p1, p3) | _, (F341|F431|F342|F432|F123|F213|F124|F214) -> (p1, p2) | _, (F134|F143|F234|F243|F312|F321|F412|F421) -> (p2, p3) | _, (F314|F413|F324|F423|F132|F231|F142|F241) -> (p1, p3) end in begin match contractions with | [] -> invalid_arg "Targets.print_current: DScalar2_Vector4_K_Matrix_cf_m1 []" | head :: tail -> printf "("; print_dscalar2_vector2_m_1_km c pa pb wf1 wf2 wf3 p1 p2 p3 fusion head; List.iter (print_add_dscalar2_vector2_m_1_km c pa pb wf1 wf2 wf3 p1 p2 p3 fusion) tail; printf ")" end | DScalar2_Vector2_m_7_K_Matrix_cf (disc, contractions) -> let pa, pb = begin match disc, fusion with | 3, (F143|F413|F142|F412|F321|F231|F324|F234) -> (p1, p2) | 3, (F314|F341|F214|F241|F132|F123|F432|F423) -> (p2, p3) | 3, (F134|F431|F124|F421|F312|F213|F342|F243) -> (p1, p3) | 4, (F143|F413|F142|F412|F321|F231|F324|F234) -> (p1, p2) | 4, (F314|F341|F214|F241|F132|F123|F432|F423) -> (p2, p3) | 4, (F134|F431|F124|F421|F312|F213|F342|F243) -> (p1, p3) | 5, (F143|F413|F142|F412|F321|F231|F324|F234) -> (p1, p2) | 5, (F314|F341|F214|F241|F132|F123|F432|F423) -> (p2, p3) | 5, (F134|F431|F124|F421|F312|F213|F342|F243) -> (p1, p3) | 6, (F134|F132|F314|F312|F241|F243|F421|F423) -> (p1, p2) | 6, (F213|F413|F231|F431|F124|F324|F142|F342) -> (p2, p3) | 6, (F143|F123|F341|F321|F412|F214|F432|F234) -> (p1, p3) | 7, (F134|F132|F314|F312|F241|F243|F421|F423) -> (p1, p2) | 7, (F213|F413|F231|F431|F124|F324|F142|F342) -> (p2, p3) | 7, (F143|F123|F341|F321|F412|F214|F432|F234) -> (p1, p3) | 8, (F134|F132|F314|F312|F241|F243|F421|F423) -> (p1, p2) | 8, (F213|F413|F231|F431|F124|F324|F142|F342) -> (p2, p3) | 8, (F143|F123|F341|F321|F412|F214|F432|F234) -> (p1, p3) | _, (F341|F431|F342|F432|F123|F213|F124|F214) -> (p1, p2) | _, (F134|F143|F234|F243|F312|F321|F412|F421) -> (p2, p3) | _, (F314|F413|F324|F423|F132|F231|F142|F241) -> (p1, p3) end in begin match contractions with | [] -> invalid_arg "Targets.print_current: DScalar2_Vector4_K_Matrix_cf_m7 []" | head :: tail -> printf "("; print_dscalar2_vector2_m_7_km c pa pb wf1 wf2 wf3 p1 p2 p3 fusion head; List.iter (print_add_dscalar2_vector2_m_7_km c pa pb wf1 wf2 wf3 p1 p2 p3 fusion) tail; printf ")" end | DScalar4_K_Matrix_ms (disc, contractions) -> let p123 = Printf.sprintf "(-%s-%s-%s)" p1 p2 p3 in let pa, pb = begin match disc, fusion with | 3, (F143|F413|F142|F412|F321|F231|F324|F234) -> (p1, p2) | 3, (F314|F341|F214|F241|F132|F123|F432|F423) -> (p2, p3) | 3, (F134|F431|F124|F421|F312|F213|F342|F243) -> (p1, p3) | _, (F341|F431|F342|F432|F123|F213|F124|F214) -> (p1, p2) | _, (F134|F143|F234|F243|F312|F321|F412|F421) -> (p2, p3) | _, (F314|F413|F324|F423|F132|F231|F142|F241) -> (p1, p3) end in begin match contractions with | [] -> invalid_arg "Targets.print_current: DScalar4_K_Matrix_ms []" | head :: tail -> printf "("; print_dscalar4_km c pa pb wf1 wf2 wf3 p1 p2 p3 p123 fusion head; List.iter (print_add_dscalar4_km c pa pb wf1 wf2 wf3 p1 p2 p3 p123 fusion) tail; printf ")" end | Dim8_Scalar2_Vector2_1 coeff -> let c = format_coupling coeff c in begin match fusion with | F134 | F143 | F234 | F243 -> printf "phi_phi2v_1(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F314 | F413 | F324 | F423 -> printf "phi_phi2v_1(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F341 | F431 | F342 | F432 -> printf "phi_phi2v_1(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F312 | F321 | F412 | F421 -> printf "v_phi2v_1(%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 | F231 | F132 | F241 | F142 -> printf "v_phi2v_1(%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 | F123 | F213 | F124 | F214 -> printf "v_phi2v_1(%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 end | Dim8_Scalar2_Vector2_2 coeff -> let c = format_coupling coeff c in begin match fusion with | F134 | F143 | F234 | F243 -> printf "phi_phi2v_2(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F314 | F413 | F324 | F423 -> printf "phi_phi2v_2(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F341 | F431 | F342 | F432 -> printf "phi_phi2v_2(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F312 | F321 | F412 | F421 -> printf "v_phi2v_2(%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 | F231 | F132 | F241 | F142 -> printf "v_phi2v_2(%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 | F123 | F213 | F124 | F214 -> printf "v_phi2v_2(%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 end | Dim8_Scalar2_Vector2_m_0 coeff -> let c = format_coupling coeff c in begin match fusion with | F134 | F143 | F234 | F243 -> printf "phi_phi2v_m_0(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F314 | F413 | F324 | F423 -> printf "phi_phi2v_m_0(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F341 | F431 | F342 | F432 -> printf "phi_phi2v_m_0(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F312 | F321 | F412 | F421 -> printf "v_phi2v_m_0(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F231 | F132 | F241 | F142 -> printf "v_phi2v_m_0(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F123 | F213 | F124 | F214 -> printf "v_phi2v_m_0(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 end | Dim8_Scalar2_Vector2_m_1 coeff -> let c = format_coupling coeff c in begin match fusion with | F134 | F143 | F234 | F243 -> printf "phi_phi2v_m_1(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F314 | F413 | F324 | F423 -> printf "phi_phi2v_m_1(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F341 | F431 | F342 | F432 -> printf "phi_phi2v_m_1(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F312 | F321 | F412 | F421 -> printf "v_phi2v_m_1(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F231 | F132 | F241 | F142 -> printf "v_phi2v_m_1(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F123 | F213 | F124 | F214 -> printf "v_phi2v_m_1(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 end | Dim8_Scalar2_Vector2_m_7 coeff -> let c = format_coupling coeff c in begin match fusion with | F134 | F143 | F234 | F243 -> printf "phi_phi2v_m_7(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F314 | F413 | F324 | F423 -> printf "phi_phi2v_m_7(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F341 | F431 | F342 | F432 -> printf "phi_phi2v_m_7(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F312 | F321 | F412 | F421 -> printf "v_phi2v_m_7(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F231 | F132 | F241 | F142 -> printf "v_phi2v_m_7(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F123 | F213 | F124 | F214 -> printf "v_phi2v_m_7(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 end | Dim8_Scalar4 coeff -> let c = format_coupling coeff c in begin match fusion with | F134 | F143 | F234 | F243 | F314 | F413 | F324 | F423 | F341 | F431 | F342 | F432 | F312 | F321 | F412 | F421 | F231 | F132 | F241 | F142 | F123 | F213 | F124 | F214 -> printf "s_dim8s3 (%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 end | GBBG (coeff, fb, b, f) -> Fermions.print_current_g4 (coeff, fb, b, f) c wf1 wf2 wf3 fusion | Dim6_H4_P2 coeff -> let c = format_coupling coeff c in begin match fusion with | F134 | F143 | F234 | F243 | F314 | F413 | F324 | F423 | F341 | F431 | F342 | F432 | F312 | F321 | F412 | F421 | F231 | F132 | F241 | F142 | F123 | F213 | F124 | F214 -> printf "hhhh_p2 (%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 end | Dim6_AHWW_DPB coeff -> let c = format_coupling coeff c in begin match fusion with | F234 -> printf "a_hww_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F243 -> printf "a_hww_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F342 -> printf "a_hww_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F324 -> printf "a_hww_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F423 -> printf "a_hww_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F432 -> printf "a_hww_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F134 -> printf "h_aww_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F143 -> printf "h_aww_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F341 -> printf "h_aww_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F314 -> printf "h_aww_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F413 -> printf "h_aww_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F431 -> printf "h_aww_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F124 -> printf "w_ahw_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F142 -> printf "w_ahw_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F241 -> printf "w_ahw_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F214 -> printf "w_ahw_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F412 -> printf "w_ahw_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F421 -> printf "w_ahw_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F123 -> printf "(-1)*w_ahw_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F132 -> printf "(-1)*w_ahw_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F231 -> printf "(-1)*w_ahw_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F213 -> printf "(-1)*w_ahw_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F312 -> printf "(-1)*w_ahw_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F321 -> printf "(-1)*w_ahw_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 end | Dim6_AHWW_DPW coeff -> let c = format_coupling coeff c in begin match fusion with | F234 -> printf "a_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F243 -> printf "a_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F342 -> printf "a_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F324 -> printf "a_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F423 -> printf "a_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F432 -> printf "a_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F134 -> printf "h_aww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F143 -> printf "h_aww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F341 -> printf "h_aww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F314 -> printf "h_aww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F413 -> printf "h_aww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F431 -> printf "h_aww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F124 -> printf "w_ahw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F142 -> printf "w_ahw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F241 -> printf "w_ahw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F214 -> printf "w_ahw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F412 -> printf "w_ahw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F421 -> printf "w_ahw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F123 -> printf "(-1)*w_ahw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F132 -> printf "(-1)*w_ahw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F231 -> printf "(-1)*w_ahw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F213 -> printf "(-1)*w_ahw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F312 -> printf "(-1)*w_ahw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F321 -> printf "(-1)*w_ahw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 end | Dim6_AHWW_DW coeff -> let c = format_coupling coeff c in begin match fusion with | F234 -> printf "a_hww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F243 -> printf "a_hww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F342 -> printf "a_hww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F324 -> printf "a_hww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F423 -> printf "a_hww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F432 -> printf "a_hww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F134 -> printf "h_aww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F143 -> printf "h_aww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F341 -> printf "h_aww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F314 -> printf "h_aww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F413 -> printf "h_aww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F431 -> printf "h_aww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F124 -> printf "w3_ahw_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F142 -> printf "w3_ahw_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F241 -> printf "w3_ahw_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F214 -> printf "w3_ahw_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F412 -> printf "w3_ahw_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F421 -> printf "w3_ahw_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F123 -> printf "w4_ahw_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F132 -> printf "w4_ahw_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F231 -> printf "w4_ahw_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F213 -> printf "w4_ahw_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F312 -> printf "w4_ahw_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F321 -> printf "w4_ahw_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 (*i | F234 | F134 | F124 | F123 -> printf "a_hww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F243 | F143 | F142 | F132 -> printf "a_hww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F342 | F341 | F241 | F231 -> printf "a_hww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F324 | F314 | F214 | F213 -> printf "a_hww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F423 | F413 | F412 | F312 -> printf "a_hww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F432 | F431 | F421 | F321 -> printf "a_hww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 i*) end | Dim6_Scalar2_Vector2_D coeff -> let c = format_coupling coeff c in begin match fusion with | F234 | F134 -> printf "h_hww_D(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F243 | F143 -> printf "h_hww_D(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F342 | F341 -> printf "h_hww_D(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F324 | F314 -> printf "h_hww_D(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F423 | F413 -> printf "h_hww_D(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F432 | F431 -> printf "h_hww_D(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F124 | F123 -> printf "w_hhw_D(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F142 | F132 -> printf "w_hhw_D(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F241 | F231 -> printf "w_hhw_D(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F214 | F213 -> printf "w_hhw_D(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F412 | F312 -> printf "w_hhw_D(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F421 | F321 -> printf "w_hhw_D(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 end | Dim6_Scalar2_Vector2_DP coeff -> let c = format_coupling coeff c in begin match fusion with | F234 | F134 -> printf "h_hww_DP(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F342 | F341 -> printf "h_hww_DP(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F423 | F413 -> printf "h_hww_DP(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F243 | F143 -> printf "h_hww_DP(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F324 | F314 -> printf "h_hww_DP(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F432 | F431 -> printf "h_hww_DP(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F123 | F124 -> printf "w_hhw_DP(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F231 | F241-> printf "w_hhw_DP(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F312 | F412 -> printf "w_hhw_DP(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F132 | F142-> printf "w_hhw_DP(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F213 | F214 -> printf "w_hhw_DP(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F321 | F421 -> printf "w_hhw_DP(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 (*i | F234 -> printf "h_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F243 -> printf "h_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F342 -> printf "h_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F324 -> printf "h_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F423 -> printf "h_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F432 -> printf "h_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F124 -> printf "w_hhw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F142 -> printf "w_hhw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F241 -> printf "w_hhw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F214 -> printf "w_hhw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F412 -> printf "w_hhw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F421 -> printf "w_hhw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F134 -> printf "h_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F143 -> printf "h_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F341 -> printf "h_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F314 -> printf "h_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F413 -> printf "h_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F431 -> printf "h_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F123 -> printf "w_hhw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F132 -> printf "w_hhw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F231 -> printf "w_hhw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F213 -> printf "w_hhw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F312 -> printf "w_hhw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F321 -> printf "w_hhw_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 i*) end | Dim6_Scalar2_Vector2_PB coeff -> let c = format_coupling coeff c in begin match fusion with | F234 | F134 -> printf "h_hvv_PB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F342 | F341 -> printf "h_hvv_PB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F423 | F413 -> printf "h_hvv_PB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F243 | F143 -> printf "h_hvv_PB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F324 | F314 -> printf "h_hvv_PB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F432 | F431 -> printf "h_hvv_PB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F123 | F124 -> printf "v_hhv_PB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F231 | F241-> printf "v_hhv_PB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F312 | F412 -> printf "v_hhv_PB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F132 | F142-> printf "v_hhv_PB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F213 | F214 -> printf "v_hhv_PB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F321 | F421 -> printf "v_hhv_PB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 end | Dim6_HHZZ_T coeff -> let c = format_coupling coeff c in begin match fusion with | F234 | F134 -> printf "(%s)*(%s)*(%s)*(%s)" c wf1 wf2 wf3 | F342 | F341 -> printf "(%s)*(%s)*(%s)*(%s)" c wf3 wf1 wf2 | F423 | F413 -> printf "(%s)*(%s)*(%s)*(%s)" c wf2 wf3 wf1 | F243 | F143 -> printf "(%s)*(%s)*(%s)*(%s)" c wf1 wf3 wf2 | F324 | F314 -> printf "(%s)*(%s)*(%s)*(%s)" c wf2 wf1 wf3 | F432 | F431 -> printf "(%s)*(%s)*(%s)*(%s)" c wf3 wf2 wf1 | F123 | F124 | F231 | F241 | F312 | F412 -> printf "(%s)*(%s)*(%s)*(%s)" c wf1 wf2 wf3 | F132 | F142 | F213 | F214 | F321 | F421 -> printf "(%s)*(%s)*(%s)*(%s)" c wf1 wf2 wf3 end | Dim6_Vector4_DW coeff -> let c = format_coupling coeff c in begin match fusion with | F234 | F134 -> printf "a_aww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F342 | F341 -> printf "a_aww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F423 | F413 -> printf "a_aww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F243 | F143 -> printf "a_aww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F324 | F314 -> printf "a_aww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F432 | F431 -> printf "a_aww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F124 | F123 -> printf "w_aaw_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F241 | F231 -> printf "w_aaw_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F412 | F312 -> printf "w_aaw_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F142 | F132 -> printf "w_aaw_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F214 | F213 -> printf "w_aaw_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F421 | F321 -> printf "w_aaw_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 end | Dim6_Vector4_W coeff -> let c = format_coupling coeff c in begin match fusion with | F234 | F134 -> printf "a_aww_W(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F342 | F341 -> printf "a_aww_W(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F423 | F413 -> printf "a_aww_W(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F243 | F143 -> printf "a_aww_W(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F324 | F314 -> printf "a_aww_W(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F432 | F431 -> printf "a_aww_W(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F123 | F124 -> printf "w_aaw_W(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F231 | F241-> printf "w_aaw_W(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F312 | F412 -> printf "w_aaw_W(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F132 | F142-> printf "w_aaw_W(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F213 | F214 -> printf "w_aaw_W(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F321 | F421 -> printf "w_aaw_W(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 end | Dim6_HWWZ_DW coeff -> let c = format_coupling coeff c in begin match fusion with | F234 -> printf "h_wwz_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F243 -> printf "h_wwz_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F342 -> printf "h_wwz_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F324 -> printf "h_wwz_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F423 -> printf "h_wwz_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F432 -> printf "h_wwz_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F124 -> printf "(-1)*w_hwz_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F142 -> printf "(-1)*w_hwz_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F241 -> printf "(-1)*w_hwz_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F214 -> printf "(-1)*w_hwz_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F412 -> printf "(-1)*w_hwz_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F421 -> printf "(-1)*w_hwz_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F134 -> printf "w_hwz_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F143 -> printf "w_hwz_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F341 -> printf "w_hwz_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F314 -> printf "w_hwz_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F413 -> printf "w_hwz_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F431 -> printf "w_hwz_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F123 -> printf "z_hww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F132 -> printf "z_hww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F231 -> printf "z_hww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F213 -> printf "z_hww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F312 -> printf "z_hww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F321 -> printf "z_hww_DW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 end | Dim6_HWWZ_DPB coeff -> let c = format_coupling coeff c in begin match fusion with | F234 -> printf "h_wwz_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F243 -> printf "h_wwz_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F342 -> printf "h_wwz_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F324 -> printf "h_wwz_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F423 -> printf "h_wwz_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F432 -> printf "h_wwz_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F124 -> printf "(-1)*w_hwz_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F142 -> printf "(-1)*w_hwz_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F241 -> printf "(-1)*w_hwz_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F214 -> printf "(-1)*w_hwz_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F412 -> printf "(-1)*w_hwz_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F421 -> printf "(-1)*w_hwz_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F134 -> printf "w_hwz_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F143 -> printf "w_hwz_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F341 -> printf "w_hwz_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F314 -> printf "w_hwz_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F413 -> printf "w_hwz_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F431 -> printf "w_hwz_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F123 -> printf "z_hww_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F132 -> printf "z_hww_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F231 -> printf "z_hww_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F213 -> printf "z_hww_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F312 -> printf "z_hww_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F321 -> printf "z_hww_DPB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 end | Dim6_HWWZ_DDPW coeff -> let c = format_coupling coeff c in begin match fusion with | F234 -> printf "h_wwz_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F243 -> printf "h_wwz_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F342 -> printf "h_wwz_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F324 -> printf "h_wwz_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F423 -> printf "h_wwz_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F432 -> printf "h_wwz_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F124 -> printf "(-1)*w_hwz_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F142 -> printf "(-1)*w_hwz_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F241 -> printf "(-1)*w_hwz_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F214 -> printf "(-1)*w_hwz_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F412 -> printf "(-1)*w_hwz_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F421 -> printf "(-1)*w_hwz_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F134 -> printf "w_hwz_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F143 -> printf "w_hwz_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F341 -> printf "w_hwz_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F314 -> printf "w_hwz_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F413 -> printf "w_hwz_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F431 -> printf "w_hwz_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F123 -> printf "z_hww_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F132 -> printf "z_hww_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F231 -> printf "z_hww_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F213 -> printf "z_hww_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F312 -> printf "z_hww_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F321 -> printf "z_hww_DDPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 end | Dim6_HWWZ_DPW coeff -> let c = format_coupling coeff c in begin match fusion with | F234 -> printf "h_wwz_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F243 -> printf "h_wwz_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F342 -> printf "h_wwz_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F324 -> printf "h_wwz_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F423 -> printf "h_wwz_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F432 -> printf "h_wwz_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F124 -> printf "(-1)*w_hwz_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F142 -> printf "(-1)*w_hwz_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F241 -> printf "(-1)*w_hwz_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F214 -> printf "(-1)*w_hwz_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F412 -> printf "(-1)*w_hwz_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F421 -> printf "(-1)*w_hwz_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F134 -> printf "w_hwz_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F143 -> printf "w_hwz_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F341 -> printf "w_hwz_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F314 -> printf "w_hwz_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F413 -> printf "w_hwz_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F431 -> printf "w_hwz_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F123 -> printf "z_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F132 -> printf "z_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F231 -> printf "z_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F213 -> printf "z_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F312 -> printf "z_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F321 -> printf "z_hww_DPW(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 end | Dim6_AHHZ_D coeff -> let c = format_coupling coeff c in begin match fusion with | F234 -> printf "a_hhz_D(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F243 -> printf "a_hhz_D(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F342 -> printf "a_hhz_D(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F324 -> printf "a_hhz_D(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F423 -> printf "a_hhz_D(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F432 -> printf "a_hhz_D(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F124 -> printf "h_ahz_D(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F142 -> printf "h_ahz_D(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F241 -> printf "h_ahz_D(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F214 -> printf "h_ahz_D(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F412 -> printf "h_ahz_D(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F421 -> printf "h_ahz_D(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F134 -> printf "h_ahz_D(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F143 -> printf "h_ahz_D(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F341 -> printf "h_ahz_D(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F314 -> printf "h_ahz_D(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F413 -> printf "h_ahz_D(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F431 -> printf "h_ahz_D(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F123 -> printf "z_ahh_D(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F132 -> printf "z_ahh_D(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F231 -> printf "z_ahh_D(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F213 -> printf "z_ahh_D(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F312 -> printf "z_ahh_D(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F321 -> printf "z_ahh_D(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 end | Dim6_AHHZ_DP coeff -> let c = format_coupling coeff c in begin match fusion with | F234 -> printf "a_hhz_DP(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F243 -> printf "a_hhz_DP(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F342 -> printf "a_hhz_DP(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F324 -> printf "a_hhz_DP(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F423 -> printf "a_hhz_DP(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F432 -> printf "a_hhz_DP(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F124 -> printf "h_ahz_DP(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F142 -> printf "h_ahz_DP(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F241 -> printf "h_ahz_DP(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F214 -> printf "h_ahz_DP(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F412 -> printf "h_ahz_DP(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F421 -> printf "h_ahz_DP(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F134 -> printf "h_ahz_DP(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F143 -> printf "h_ahz_DP(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F341 -> printf "h_ahz_DP(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F314 -> printf "h_ahz_DP(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F413 -> printf "h_ahz_DP(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F431 -> printf "h_ahz_DP(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F123 -> printf "z_ahh_DP(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F132 -> printf "z_ahh_DP(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F231 -> printf "z_ahh_DP(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F213 -> printf "z_ahh_DP(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F312 -> printf "z_ahh_DP(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F321 -> printf "z_ahh_DP(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 end | Dim6_AHHZ_PB coeff -> let c = format_coupling coeff c in begin match fusion with | F234 -> printf "a_hhz_PB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F243 -> printf "a_hhz_PB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F342 -> printf "a_hhz_PB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F324 -> printf "a_hhz_PB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F423 -> printf "a_hhz_PB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F432 -> printf "a_hhz_PB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F124 -> printf "h_ahz_PB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F142 -> printf "h_ahz_PB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F241 -> printf "h_ahz_PB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F214 -> printf "h_ahz_PB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F412 -> printf "h_ahz_PB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F421 -> printf "h_ahz_PB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F134 -> printf "h_ahz_PB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F143 -> printf "h_ahz_PB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F341 -> printf "h_ahz_PB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F314 -> printf "h_ahz_PB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F413 -> printf "h_ahz_PB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F431 -> printf "h_ahz_PB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 | F123 -> printf "z_ahh_PB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf2 p2 wf3 p3 | F132 -> printf "z_ahh_PB(%s,%s,%s,%s,%s,%s,%s)" c wf1 p1 wf3 p3 wf2 p2 | F231 -> printf "z_ahh_PB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf1 p1 wf2 p2 | F213 -> printf "z_ahh_PB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf1 p1 wf3 p3 | F312 -> printf "z_ahh_PB(%s,%s,%s,%s,%s,%s,%s)" c wf2 p2 wf3 p3 wf1 p1 | F321 -> printf "z_ahh_PB(%s,%s,%s,%s,%s,%s,%s)" c wf3 p3 wf2 p2 wf1 p1 end (* \begin{dubious} In principle, [p4] could be obtained from the left hand side \ldots \end{dubious} *) | DScalar4 contractions -> let p123 = Printf.sprintf "(-%s-%s-%s)" p1 p2 p3 in begin match contractions with | [] -> invalid_arg "Targets.print_current: DScalar4 []" | head :: tail -> printf "("; print_dscalar4 c wf1 wf2 wf3 p1 p2 p3 p123 fusion head; List.iter (print_add_dscalar4 c wf1 wf2 wf3 p1 p2 p3 p123 fusion) tail; printf ")" end | DScalar2_Vector2 contractions -> let p123 = Printf.sprintf "(-%s-%s-%s)" p1 p2 p3 in begin match contractions with | [] -> invalid_arg "Targets.print_current: DScalar4 []" | head :: tail -> printf "("; print_dscalar2_vector2 c wf1 wf2 wf3 p1 p2 p3 p123 fusion head; List.iter (print_add_dscalar2_vector2 c wf1 wf2 wf3 p1 p2 p3 p123 fusion) tail; printf ")" end end (* \begin{dubious} This reproduces the hack on page~\pageref{hack:sign(V4)} and gives the correct results up to quartic vertices. Make sure that it is also correct in light of~\eqref{eq:factors-of-i}, i.\,e. \begin{equation*} \ii T = \ii^{\#\text{vertices}}\ii^{\#\text{propagators}} \cdots = \ii^{n-2}\ii^{n-3} \cdots = -\ii(-1)^n \cdots \end{equation*} \end{dubious} *) | Vn (UFO (c, v, s, _, color), fusion, constant) -> if Color.Vertex.trivial color then let g = CM.constant_symbol constant and chn = F.children rhs in let wfs = List.map (multiple_variable amplitude dictionary) chn and ps = List.map momentum chn in let n = List.length fusion in let eps = if n mod 2 = 0 then -1 else 1 in printf "@, %s " (if (eps * F.sign rhs) < 0 then "-" else "+"); UFO.Targets.Fortran.fuse c v s g wfs ps fusion else failwith "print_current: nontrivial color structure" let print_propagator f p m gamma = let minus_third = "(-1.0_" ^ !kind ^ "/3.0_" ^ !kind ^ ")" in let w = begin match CM.width f with | Vanishing | Fudged -> "0.0_" ^ !kind | Constant | Complex_Mass -> gamma | Timelike -> "wd_tl(" ^ p ^ "," ^ gamma ^ ")" - | Running -> - failwith "Targets.Fortran: running width not yet available" + | Running -> "wd_run(" ^ p ^ "," ^ m ^ "," ^ gamma ^ ")" | Custom f -> f ^ "(" ^ p ^ "," ^ gamma ^ ")" end in let cms = begin match CM.width f with | Complex_Mass -> ".true." | _ -> ".false." end in match CM.propagator f with | Prop_Scalar -> printf "pr_phi(%s,%s,%s," p m w | Prop_Col_Scalar -> printf "%s * pr_phi(%s,%s,%s," minus_third p m w | Prop_Ghost -> printf "(0,1) * pr_phi(%s, %s, %s," p m w | Prop_Spinor -> printf "%s(%s,%s,%s,%s," Fermions.psi_propagator p m w cms | Prop_ConjSpinor -> printf "%s(%s,%s,%s,%s," Fermions.psibar_propagator p m w cms | Prop_Majorana -> printf "%s(%s,%s,%s,%s," Fermions.chi_propagator p m w cms | Prop_Col_Majorana -> printf "%s * %s(%s,%s,%s,%s," minus_third Fermions.chi_propagator p m w cms | Prop_Unitarity -> printf "pr_unitarity(%s,%s,%s,%s," p m w cms | Prop_Col_Unitarity -> printf "%s * pr_unitarity(%s,%s,%s,%s," minus_third p m w cms | Prop_Feynman -> printf "pr_feynman(%s," p | Prop_Col_Feynman -> printf "%s * pr_feynman(%s," minus_third p | Prop_Gauge xi -> printf "pr_gauge(%s,%s," p (CM.gauge_symbol xi) | Prop_Rxi xi -> printf "pr_rxi(%s,%s,%s,%s," p m w (CM.gauge_symbol xi) | Prop_Tensor_2 -> printf "pr_tensor(%s,%s,%s," p m w | Prop_Tensor_pure -> printf "pr_tensor_pure(%s,%s,%s," p m w | Prop_Vector_pure -> printf "pr_vector_pure(%s,%s,%s," p m w | Prop_Vectorspinor -> printf "pr_grav(%s,%s,%s," p m w | Aux_Scalar | Aux_Spinor | Aux_ConjSpinor | Aux_Majorana | Aux_Vector | Aux_Tensor_1 -> printf "(" | Aux_Col_Scalar | Aux_Col_Vector | Aux_Col_Tensor_1 -> printf "%s * (" minus_third | Only_Insertion -> printf "(" | Prop_UFO name -> printf "pr_U_%s(%s,%s,%s," name p m w let print_projector f p m gamma = let minus_third = "(-1.0_" ^ !kind ^ "/3.0_" ^ !kind ^ ")" in match CM.propagator f with | Prop_Scalar -> printf "pj_phi(%s,%s," m gamma | Prop_Col_Scalar -> printf "%s * pj_phi(%s,%s," minus_third m gamma | Prop_Ghost -> printf "(0,1) * pj_phi(%s,%s," m gamma | Prop_Spinor -> printf "%s(%s,%s,%s," Fermions.psi_projector p m gamma | Prop_ConjSpinor -> printf "%s(%s,%s,%s," Fermions.psibar_projector p m gamma | Prop_Majorana -> printf "%s(%s,%s,%s," Fermions.chi_projector p m gamma | Prop_Col_Majorana -> printf "%s * %s(%s,%s,%s," minus_third Fermions.chi_projector p m gamma | Prop_Unitarity -> printf "pj_unitarity(%s,%s,%s," p m gamma | Prop_Col_Unitarity -> printf "%s * pj_unitarity(%s,%s,%s," minus_third p m gamma | Prop_Feynman | Prop_Col_Feynman -> invalid_arg "no on-shell Feynman propagator!" | Prop_Gauge _ -> invalid_arg "no on-shell massless gauge propagator!" | Prop_Rxi _ -> invalid_arg "no on-shell Rxi propagator!" | Prop_Vectorspinor -> printf "pj_grav(%s,%s,%s," p m gamma | Prop_Tensor_2 -> printf "pj_tensor(%s,%s,%s," p m gamma | Prop_Tensor_pure -> invalid_arg "no on-shell pure Tensor propagator!" | Prop_Vector_pure -> invalid_arg "no on-shell pure Vector propagator!" | Aux_Scalar | Aux_Spinor | Aux_ConjSpinor | Aux_Majorana | Aux_Vector | Aux_Tensor_1 -> printf "(" | Aux_Col_Scalar | Aux_Col_Vector | Aux_Col_Tensor_1 -> printf "%s * (" minus_third | Only_Insertion -> printf "(" | Prop_UFO name -> invalid_arg "no on shell UFO propagator" let print_gauss f p m gamma = let minus_third = "(-1.0_" ^ !kind ^ "/3.0_" ^ !kind ^ ")" in match CM.propagator f with | Prop_Scalar -> printf "pg_phi(%s,%s,%s," p m gamma | Prop_Ghost -> printf "(0,1) * pg_phi(%s,%s,%s," p m gamma | Prop_Spinor -> printf "%s(%s,%s,%s," Fermions.psi_projector p m gamma | Prop_ConjSpinor -> printf "%s(%s,%s,%s," Fermions.psibar_projector p m gamma | Prop_Majorana -> printf "%s(%s,%s,%s," Fermions.chi_projector p m gamma | Prop_Col_Majorana -> printf "%s * %s(%s,%s,%s," minus_third Fermions.chi_projector p m gamma | Prop_Unitarity -> printf "pg_unitarity(%s,%s,%s," p m gamma | Prop_Feynman | Prop_Col_Feynman -> invalid_arg "no on-shell Feynman propagator!" | Prop_Gauge _ -> invalid_arg "no on-shell massless gauge propagator!" | Prop_Rxi _ -> invalid_arg "no on-shell Rxi propagator!" | Prop_Tensor_2 -> printf "pg_tensor(%s,%s,%s," p m gamma | Prop_Tensor_pure -> invalid_arg "no pure tensor propagator!" | Prop_Vector_pure -> invalid_arg "no pure vector propagator!" | Aux_Scalar | Aux_Spinor | Aux_ConjSpinor | Aux_Majorana | Aux_Vector | Aux_Tensor_1 -> printf "(" | Only_Insertion -> printf "(" | Prop_UFO name -> invalid_arg "no UFO gauss insertion" | _ -> invalid_arg "targets:print_gauss: not available" let print_fusion_diagnostics amplitude dictionary fusion = if warn diagnose_gauge then begin let lhs = F.lhs fusion in let f = F.flavor lhs and v = variable lhs and p = momentum lhs in let mass = CM.mass_symbol f in match CM.propagator f with | Prop_Gauge _ | Prop_Feynman | Prop_Rxi _ | Prop_Unitarity -> printf " @[<2>%s =" v; List.iter (print_current amplitude dictionary) (F.rhs fusion); nl (); begin match CM.goldstone f with | None -> printf " call omega_ward_%s(\"%s\",%s,%s,%s)" (suffix diagnose_gauge) v mass p v; nl () | Some (g, phase) -> let gv = add_tag lhs (CM.flavor_symbol g ^ "_" ^ format_p lhs) in printf " call omega_slavnov_%s" (suffix diagnose_gauge); printf "(@[\"%s\",%s,%s,%s,@,%s*%s)" v mass p v (format_constant phase) gv; nl () end | _ -> () end let print_fusion amplitude dictionary fusion = let lhs = F.lhs fusion in let f = F.flavor lhs in printf " @[<2>%s =@, " (multiple_variable amplitude dictionary lhs); if F.on_shell amplitude lhs then print_projector f (momentum lhs) (CM.mass_symbol f) (CM.width_symbol f) else if F.is_gauss amplitude lhs then print_gauss f (momentum lhs) (CM.mass_symbol f) (CM.width_symbol f) else print_propagator f (momentum lhs) (CM.mass_symbol f) (CM.width_symbol f); List.iter (print_current amplitude dictionary) (F.rhs fusion); printf ")"; nl () let print_momenta seen_momenta amplitude = List.fold_left (fun seen f -> let wf = F.lhs f in let p = F.momentum_list wf in if not (PSet.mem p seen) then begin let rhs1 = List.hd (F.rhs f) in printf " %s = %s" (momentum wf) (String.concat " + " (List.map momentum (F.children rhs1))); nl () end; PSet.add p seen) seen_momenta (F.fusions amplitude) let print_fusions dictionary fusions = List.iter (fun (f, amplitude) -> print_fusion_diagnostics amplitude dictionary f; print_fusion amplitude dictionary f) fusions let print_braket amplitude dictionary name braket = let bra = F.bra braket and ket = F.ket braket in printf " @[<2>%s = %s@, + " name name; begin match Fermions.reverse_braket (CM.lorentz (F.flavor bra)) with | false -> printf "%s*@,(" (multiple_variable amplitude dictionary bra); List.iter (print_current amplitude dictionary) ket; printf ")" | true -> printf "@,("; List.iter (print_current amplitude dictionary) ket; printf ")*%s" (multiple_variable amplitude dictionary bra) end; nl () (* \begin{equation} \label{eq:factors-of-i} \ii T = \ii^{\#\text{vertices}}\ii^{\#\text{propagators}} \cdots = \ii^{n-2}\ii^{n-3} \cdots = -\ii(-1)^n \cdots \end{equation} *) (* \begin{dubious} [tho:] we write some brakets twice using different names. Is it useful to cache them? \end{dubious} *) let print_brakets dictionary amplitude = let name = flavors_symbol (flavors amplitude) in printf " %s = 0" name; nl (); List.iter (print_braket amplitude dictionary name) (F.brakets amplitude); let n = List.length (F.externals amplitude) in if n mod 2 = 0 then begin printf " @[<2>%s =@, - %s ! %d vertices, %d propagators" name name (n - 2) (n - 3); nl () end else begin printf " ! %s = %s ! %d vertices, %d propagators" name name (n - 2) (n - 3); nl () end; let s = F.symmetry amplitude in if s > 1 then printf " @[<2>%s =@, %s@, / sqrt(%d.0_%s) ! symmetry factor" name name s !kind else printf " ! unit symmetry factor"; nl () let print_incoming wf = let p = momentum wf and s = spin wf and f = F.flavor wf in let m = CM.mass_symbol f in match CM.lorentz f with | Scalar -> printf "1" | BRS Scalar -> printf "(0,-1) * (%s * %s - %s**2)" p p m | Spinor -> printf "%s (%s, - %s, %s)" Fermions.psi_incoming m p s | BRS Spinor -> printf "%s (%s, - %s, %s)" Fermions.brs_psi_incoming m p s | ConjSpinor -> printf "%s (%s, - %s, %s)" Fermions.psibar_incoming m p s | BRS ConjSpinor -> printf "%s (%s, - %s, %s)" Fermions.brs_psibar_incoming m p s | Majorana -> printf "%s (%s, - %s, %s)" Fermions.chi_incoming m p s | Maj_Ghost -> printf "ghost (%s, - %s, %s)" m p s | BRS Majorana -> printf "%s (%s, - %s, %s)" Fermions.brs_chi_incoming m p s | Vector | Massive_Vector -> printf "eps (%s, - %s, %s)" m p s (*i | Ward_Vector -> printf "%s" p i*) | BRS Vector | BRS Massive_Vector -> printf "(0,1) * (%s * %s - %s**2) * eps (%s, -%s, %s)" p p m m p s | Vectorspinor | BRS Vectorspinor -> printf "%s (%s, - %s, %s)" Fermions.grav_incoming m p s | Tensor_1 -> invalid_arg "Tensor_1 only internal" | Tensor_2 -> printf "eps2 (%s, - %s, %s)" m p s | _ -> invalid_arg "no such BRST transformations" let print_outgoing wf = let p = momentum wf and s = spin wf and f = F.flavor wf in let m = CM.mass_symbol f in match CM.lorentz f with | Scalar -> printf "1" | BRS Scalar -> printf "(0,-1) * (%s * %s - %s**2)" p p m | Spinor -> printf "%s (%s, %s, %s)" Fermions.psi_outgoing m p s | BRS Spinor -> printf "%s (%s, %s, %s)" Fermions.brs_psi_outgoing m p s | ConjSpinor -> printf "%s (%s, %s, %s)" Fermions.psibar_outgoing m p s | BRS ConjSpinor -> printf "%s (%s, %s, %s)" Fermions.brs_psibar_outgoing m p s | Majorana -> printf "%s (%s, %s, %s)" Fermions.chi_outgoing m p s | BRS Majorana -> printf "%s (%s, %s, %s)" Fermions.brs_chi_outgoing m p s | Maj_Ghost -> printf "ghost (%s, %s, %s)" m p s | Vector | Massive_Vector -> printf "conjg (eps (%s, %s, %s))" m p s (*i | Ward_Vector -> printf "%s" p i*) | BRS Vector | BRS Massive_Vector -> printf "(0,1) * (%s*%s-%s**2) * (conjg (eps (%s, %s, %s)))" p p m m p s | Vectorspinor | BRS Vectorspinor -> printf "%s (%s, %s, %s)" Fermions.grav_incoming m p s | Tensor_1 -> invalid_arg "Tensor_1 only internal" | Tensor_2 -> printf "conjg (eps2 (%s, %s, %s))" m p s | BRS _ -> invalid_arg "no such BRST transformations" (*i unused value let twice_spin wf = match CM.lorentz (F.flavor wf) with | Scalar | BRS Scalar -> "0" | Spinor | ConjSpinor | Majorana | Maj_Ghost | Vectorspinor | BRS Spinor | BRS ConjSpinor | BRS Majorana | BRS Vectorspinor -> "1" | Vector | BRS Vector | Massive_Vector | BRS Massive_Vector -> "2" | Tensor_1 -> "2" | Tensor_2 -> "4" | BRS _ -> invalid_arg "Targets.twice_spin: no such BRST transformation" i*) (*i unused value let print_argument_diagnostics amplitude = let externals = (F.externals amplitude) in let n = List.length externals and masses = List.map (fun wf -> CM.mass_symbol (F.flavor wf)) externals in if warn diagnose_arguments then begin printf " call omega_check_arguments_%s (%d, k)" (suffix diagnose_arguments) n; nl () end; if warn diagnose_momenta then begin printf " @[<2>call omega_check_momenta_%s ((/ " (suffix diagnose_momenta); print_list masses; printf " /), k)"; nl () end i*) let print_external_momenta amplitude = let externals = List.combine (F.externals amplitude) (List.map (fun _ -> true) (F.incoming amplitude) @ List.map (fun _ -> false) (F.outgoing amplitude)) in List.iter (fun (wf, incoming) -> if incoming then printf " %s = - k(:,%d) ! incoming" (momentum wf) (ext_momentum wf) else printf " %s = k(:,%d) ! outgoing" (momentum wf) (ext_momentum wf); nl ()) externals let print_externals seen_wfs amplitude = let externals = List.combine (F.externals amplitude) (List.map (fun _ -> true) (F.incoming amplitude) @ List.map (fun _ -> false) (F.outgoing amplitude)) in List.fold_left (fun seen (wf, incoming) -> if not (WFSet.mem wf seen) then begin printf " @[<2>%s =@, " (variable wf); (if incoming then print_incoming else print_outgoing) wf; nl () end; WFSet.add wf seen) seen_wfs externals (*i unused value let flavors_to_string flavors = String.concat " " (List.map CM.flavor_to_string flavors) i*) (*i unused value let process_to_string amplitude = flavors_to_string (F.incoming amplitude) ^ " -> " ^ flavors_to_string (F.outgoing amplitude) i*) let flavors_sans_color_to_string flavors = String.concat " " (List.map M.flavor_to_string flavors) let process_sans_color_to_string (fin, fout) = flavors_sans_color_to_string fin ^ " -> " ^ flavors_sans_color_to_string fout let print_fudge_factor amplitude = let name = flavors_symbol (flavors amplitude) in List.iter (fun wf -> let p = momentum wf and f = F.flavor wf in match CM.width f with | Fudged -> let m = CM.mass_symbol f and w = CM.width_symbol f in printf " if (%s > 0.0_%s) then" w !kind; nl (); printf " @[<2>%s = %s@ * (%s*%s - %s**2)" name name p p m; printf "@ / cmplx (%s*%s - %s**2, %s*%s, kind=%s)" p p m m w !kind; nl (); printf " end if"; nl () | _ -> ()) (F.s_channel amplitude) let num_helicities amplitudes = List.length (CF.helicities amplitudes) (* \thocwmodulesubsection{Spin, Flavor \&\ Color Tables} *) (* The following abomination is required to keep the number of continuation lines as low as possible. FORTRAN77-style \texttt{DATA} statements are actually a bit nicer here, but they are nor available for \emph{constant} arrays. *) (* \begin{dubious} We used to have a more elegant design with a sentinel~0 added to each initializer, but some revisions of the Compaq/Digital Compiler have a bug that causes it to reject this variant. \end{dubious} *) (* \begin{dubious} The actual table writing code using \texttt{reshape} should be factored, since it's the same algorithm every time. \end{dubious} *) let print_integer_parameter name value = printf " @[<2>integer, parameter :: %s = %d" name value; nl () let print_real_parameter name value = printf " @[<2>real(kind=%s), parameter :: %s = %d" !kind name value; nl () let print_logical_parameter name value = printf " @[<2>logical, parameter :: %s = .%s." name (if value then "true" else "false"); nl () let num_particles_in amplitudes = match CF.flavors amplitudes with | [] -> 0 | (fin, _) :: _ -> List.length fin let num_particles_out amplitudes = match CF.flavors amplitudes with | [] -> 0 | (_, fout) :: _ -> List.length fout let num_particles amplitudes = match CF.flavors amplitudes with | [] -> 0 | (fin, fout) :: _ -> List.length fin + List.length fout module CFlow = Color.Flow let num_color_flows amplitudes = List.length (CF.color_flows amplitudes) let num_color_indices_default = 2 (* Standard model *) let num_color_indices amplitudes = try CFlow.rank (List.hd (CF.color_flows amplitudes)) with _ -> num_color_indices_default let color_to_string c = "(" ^ (String.concat "," (List.map (Printf.sprintf "%3d") c)) ^ ")" let cflow_to_string cflow = String.concat " " (List.map color_to_string (CFlow.in_to_lists cflow)) ^ " -> " ^ String.concat " " (List.map color_to_string (CFlow.out_to_lists cflow)) let protected = ", protected" (* Fortran 2003! *) (*i unused value let print_spin_table_old abbrev name = function | [] -> printf " @[<2>integer, dimension(n_prt,0) ::"; printf "@ table_spin_%s" name; nl () | _ :: tuples' as tuples -> ignore (List.fold_left (fun i (tuple1, tuple2) -> printf " @[<2>integer, dimension(n_prt), parameter, private ::"; printf "@ %s%04d = (/ %s /)" abbrev i (String.concat ", " (List.map (Printf.sprintf "%2d") (tuple1 @ tuple2))); nl (); succ i) 1 tuples); printf " @[<2>integer, dimension(n_prt,n_hel), parameter ::"; printf "@ table_spin_%s =@ reshape ( (/" name; printf "@ %s%04d" abbrev 1; ignore (List.fold_left (fun i tuple -> printf ",@ %s%04d" abbrev i; succ i) 2 tuples'); printf "@ /), (/ n_prt, n_hel /) )"; nl () i*) let print_spin_table name tuples = printf " @[<2>integer, dimension(n_prt,n_hel), save%s :: table_spin_%s" protected name; nl (); match tuples with | [] -> () | _ -> ignore (List.fold_left (fun i (tuple1, tuple2) -> printf " @[<2>data table_spin_%s(:,%4d) / %s /" name i (String.concat ", " (List.map (Printf.sprintf "%2d") (tuple1 @ tuple2))); nl (); succ i) 1 tuples) let print_spin_tables amplitudes = (* [print_spin_table_old "s" "states_old" (CF.helicities amplitudes);] *) print_spin_table "states" (CF.helicities amplitudes); nl () (*i unused value let print_flavor_table_old n abbrev name = function | [] -> printf " @[<2>integer, dimension(n_prt,0) ::"; printf "@ table_flavor_%s" name; nl () | _ :: tuples' as tuples -> ignore (List.fold_left (fun i tuple -> printf " @[<2>integer, dimension(n_prt), parameter, private ::"; printf "@ %s%04d = (/ %s /) ! %s" abbrev i (String.concat ", " (List.map (fun f -> Printf.sprintf "%3d" (M.pdg f)) tuple)) (String.concat " " (List.map M.flavor_to_string tuple)); nl (); succ i) 1 tuples); printf " @[<2>integer, dimension(n_prt,n_flv), parameter ::"; printf "@ table_flavor_%s =@ reshape ( (/" name; printf "@ %s%04d" abbrev 1; ignore (List.fold_left (fun i tuple -> printf ",@ %s%04d" abbrev i; succ i) 2 tuples'); printf "@ /), (/ n_prt, n_flv /) )"; nl () i*) let print_flavor_table name tuples = printf " @[<2>integer, dimension(n_prt,n_flv), save%s :: table_flavor_%s" protected name; nl (); match tuples with | [] -> () | _ -> ignore (List.fold_left (fun i tuple -> printf " @[<2>data table_flavor_%s(:,%4d) / %s / ! %s" name i (String.concat ", " (List.map (fun f -> Printf.sprintf "%3d" (M.pdg f)) tuple)) (String.concat " " (List.map M.flavor_to_string tuple)); nl (); succ i) 1 tuples) let print_flavor_tables amplitudes = (* [let n = num_particles amplitudes in] *) (* [print_flavor_table_old n "f" "states_old" (List.map (fun (fin, fout) -> fin @ fout) (CF.flavors amplitudes));] *) print_flavor_table "states" (List.map (fun (fin, fout) -> fin @ fout) (CF.flavors amplitudes)); nl () let num_flavors amplitudes = List.length (CF.flavors amplitudes) (*i unused value let print_color_flows_table_old abbrev = function | [] -> printf " @[<2>integer, dimension(n_cindex, n_prt, n_cflow) ::"; printf "@ table_color_flows"; nl () | _ :: tuples' as tuples -> ignore (List.fold_left (fun i tuple -> printf " @[<2>integer, dimension(n_cindex, n_prt), parameter, private ::"; printf "@ %s%04d = reshape ( (/ " abbrev i; begin match CFlow.to_lists tuple with | [] -> () | cf1 :: cfn -> printf "@ %s" (String.concat "," (List.map string_of_int cf1)); List.iter (function cf -> printf ",@ %s" (String.concat "," (List.map string_of_int cf))) cfn end; printf "@ /),@ (/ n_cindex, n_prt /) )"; nl (); succ i) 1 tuples); printf " @[<2>integer, dimension(n_cindex, n_prt, n_cflow), parameter ::"; printf "@ table_color_flows_old =@ reshape ( (/"; printf "@ %s%04d" abbrev 1; ignore (List.fold_left (fun i tuple -> printf ",@ %s%04d" abbrev i; succ i) 2 tuples'); printf "@ /),@ (/ n_cindex, n_prt, n_cflow /) )"; nl () i*) (*i unused value let print_ghost_flags_table_old abbrev = function | [] -> printf " @[<2>logical, dimension(n_prt, n_cflow) ::"; printf "@ table_ghost_flags"; nl () | _ :: tuples' as tuples -> ignore (List.fold_left (fun i tuple -> printf " @[<2>logical, dimension(n_prt), parameter, private ::"; printf "@ %s%04d = (/ " abbrev i; begin match CFlow.ghost_flags tuple with | [] -> () | gf1 :: gfn -> printf "@ %s" (if gf1 then "T" else "F"); List.iter (function gf -> printf ",@ %s" (if gf then "T" else "F")) gfn end; printf "@ /)"; nl (); succ i) 1 tuples); printf " @[<2>logical, dimension(n_prt, n_cflow), parameter ::"; printf "@ table_ghost_flags_old =@ reshape ( (/"; printf "@ %s%04d" abbrev 1; ignore (List.fold_left (fun i tuple -> printf ",@ %s%04d" abbrev i; succ i) 2 tuples'); printf "@ /),@ (/ n_prt, n_cflow /) )"; nl () i*) let print_color_flows_table tuples = printf " @[<2>integer, dimension(n_cindex,n_prt,n_cflow), save%s :: table_color_flows" protected; nl (); match tuples with | [] -> () | _ :: _ as tuples -> ignore (List.fold_left (fun i tuple -> begin match CFlow.to_lists tuple with | [] -> () | cf1 :: cfn -> printf " @[<2>data table_color_flows(:,:,%4d) /" i; printf "@ %s" (String.concat "," (List.map string_of_int cf1)); List.iter (function cf -> printf ",@ %s" (String.concat "," (List.map string_of_int cf))) cfn; printf "@ /"; nl () end; succ i) 1 tuples) let print_ghost_flags_table tuples = printf " @[<2>logical, dimension(n_prt,n_cflow), save%s :: table_ghost_flags" protected; nl (); match tuples with | [] -> () | _ -> ignore (List.fold_left (fun i tuple -> begin match CFlow.ghost_flags tuple with | [] -> () | gf1 :: gfn -> printf " @[<2>data table_ghost_flags(:,%4d) /" i; printf "@ %s" (if gf1 then "T" else "F"); List.iter (function gf -> printf ",@ %s" (if gf then "T" else "F")) gfn; printf " /"; nl () end; succ i) 1 tuples) let format_power_of x { Color.Flow.num = num; Color.Flow.den = den; Color.Flow.power = pwr } = match num, den, pwr with | _, 0, _ -> invalid_arg "format_power_of: zero denominator" | 0, _, _ -> "+zero" | 1, 1, 0 | -1, -1, 0 -> "+one" | -1, 1, 0 | 1, -1, 0 -> "-one" | 1, 1, 1 | -1, -1, 1 -> "+" ^ x | -1, 1, 1 | 1, -1, 1 -> "-" ^ x | 1, 1, -1 | -1, -1, -1 -> "+1/" ^ x | -1, 1, -1 | 1, -1, -1 -> "-1/" ^ x | 1, 1, p | -1, -1, p -> "+" ^ (if p > 0 then "" else "1/") ^ x ^ "**" ^ string_of_int (abs p) | -1, 1, p | 1, -1, p -> "-" ^ (if p > 0 then "" else "1/") ^ x ^ "**" ^ string_of_int (abs p) | n, 1, 0 -> (if n < 0 then "-" else "+") ^ string_of_int (abs n) ^ ".0_" ^ !kind | n, d, 0 -> (if n * d < 0 then "-" else "+") ^ string_of_int (abs n) ^ ".0_" ^ !kind ^ "/" ^ string_of_int (abs d) | n, 1, 1 -> (if n < 0 then "-" else "+") ^ string_of_int (abs n) ^ "*" ^ x | n, 1, -1 -> (if n < 0 then "-" else "+") ^ string_of_int (abs n) ^ "/" ^ x | n, d, 1 -> (if n * d < 0 then "-" else "+") ^ string_of_int (abs n) ^ ".0_" ^ !kind ^ "/" ^ string_of_int (abs d) ^ "*" ^ x | n, d, -1 -> (if n * d < 0 then "-" else "+") ^ string_of_int (abs n) ^ ".0_" ^ !kind ^ "/" ^ string_of_int (abs d) ^ "/" ^ x | n, 1, p -> (if n < 0 then "-" else "+") ^ string_of_int (abs n) ^ (if p > 0 then "*" else "/") ^ x ^ "**" ^ string_of_int (abs p) | n, d, p -> (if n * d < 0 then "-" else "+") ^ string_of_int (abs n) ^ ".0_" ^ !kind ^ "/" ^ string_of_int (abs d) ^ (if p > 0 then "*" else "/") ^ x ^ "**" ^ string_of_int (abs p) let format_powers_of x = function | [] -> "zero" | powers -> String.concat "" (List.map (format_power_of x) powers) (*i unused value let print_color_factor_table_old table = let n_cflow = Array.length table in let n_cfactors = ref 0 in for c1 = 0 to pred n_cflow do for c2 = 0 to pred n_cflow do match table.(c1).(c2) with | [] -> () | _ -> incr n_cfactors done done; print_integer_parameter "n_cfactors" !n_cfactors; if n_cflow <= 0 then begin printf " @[<2>type(%s), dimension(n_cfactors) ::" omega_color_factor_abbrev; printf "@ table_color_factors"; nl () end else begin printf " @[<2>type(%s), dimension(n_cfactors), parameter ::" omega_color_factor_abbrev; printf "@ table_color_factors = (/@ "; let comma = ref "" in for c1 = 0 to pred n_cflow do for c2 = 0 to pred n_cflow do match table.(c1).(c2) with | [] -> () | cf -> printf "%s@ %s(%d,%d,%s)" !comma omega_color_factor_abbrev (succ c1) (succ c2) (format_powers_of nc_parameter cf); comma := "," done done; printf "@ /)"; nl () end i*) (* \begin{dubious} We can optimize the following slightly by reusing common color factor [parameter]s. \end{dubious} *) let print_color_factor_table table = let n_cflow = Array.length table in let n_cfactors = ref 0 in for c1 = 0 to pred n_cflow do for c2 = 0 to pred n_cflow do match table.(c1).(c2) with | [] -> () | _ -> incr n_cfactors done done; print_integer_parameter "n_cfactors" !n_cfactors; printf " @[<2>type(%s), dimension(n_cfactors), save%s ::" omega_color_factor_abbrev protected; printf "@ table_color_factors"; nl (); let i = ref 1 in if n_cflow > 0 then begin for c1 = 0 to pred n_cflow do for c2 = 0 to pred n_cflow do match table.(c1).(c2) with | [] -> () | cf -> printf " @[<2>real(kind=%s), parameter, private :: color_factor_%06d = %s" !kind !i (format_powers_of nc_parameter cf); nl (); printf " @[<2>data table_color_factors(%6d) / %s(%d,%d,color_factor_%06d) /" !i omega_color_factor_abbrev (succ c1) (succ c2) !i; incr i; nl (); done done end let print_color_tables amplitudes = let cflows = CF.color_flows amplitudes and cfactors = CF.color_factors amplitudes in (* [print_color_flows_table_old "c" cflows; nl ();] *) print_color_flows_table cflows; nl (); (* [print_ghost_flags_table_old "g" cflows; nl ();] *) print_ghost_flags_table cflows; nl (); (* [print_color_factor_table_old cfactors; nl ();] *) print_color_factor_table cfactors; nl () let option_to_logical = function | Some _ -> "T" | None -> "F" (*i unused value let print_flavor_color_table_old abbrev n_flv n_cflow table = if n_flv <= 0 || n_cflow <= 0 then begin printf " @[<2>logical, dimension(n_flv, n_cflow) ::"; printf "@ flv_col_is_allowed"; nl () end else begin for c = 0 to pred n_cflow do printf " @[<2>logical, dimension(n_flv), parameter, private ::"; printf "@ %s%04d = (/@ %s" abbrev (succ c) (option_to_logical table.(0).(c)); for f = 1 to pred n_flv do printf ",@ %s" (option_to_logical table.(f).(c)) done; printf "@ /)"; nl () done; printf " @[<2>logical, dimension(n_flv, n_cflow), parameter ::"; printf "@ flv_col_is_allowed_old =@ reshape ( (/@ %s%04d" abbrev 1; for c = 1 to pred n_cflow do printf ",@ %s%04d" abbrev (succ c) done; printf "@ /),@ (/ n_flv, n_cflow /) )"; nl () end i*) let print_flavor_color_table n_flv n_cflow table = printf " @[<2>logical, dimension(n_flv, n_cflow), save%s :: @ flv_col_is_allowed" protected; nl (); if n_flv > 0 then begin for c = 0 to pred n_cflow do printf " @[<2>data flv_col_is_allowed(:,%4d) /" (succ c); printf "@ %s" (option_to_logical table.(0).(c)); for f = 1 to pred n_flv do printf ",@ %s" (option_to_logical table.(f).(c)) done; printf "@ /"; nl () done; end let print_amplitude_table a = (* [print_flavor_color_table_old "a" (num_flavors a) (List.length (CF.color_flows a)) (CF.process_table a); nl ();] *) print_flavor_color_table (num_flavors a) (List.length (CF.color_flows a)) (CF.process_table a); nl (); printf " @[<2>complex(kind=%s), dimension(n_flv, n_cflow, n_hel), save :: amp" !kind; nl (); nl () let print_helicity_selection_table () = printf " @[<2>logical, dimension(n_hel), save :: "; printf "hel_is_allowed = T"; nl (); printf " @[<2>real(kind=%s), dimension(n_hel), save :: " !kind; printf "hel_max_abs = 0"; nl (); printf " @[<2>real(kind=%s), save :: " !kind; printf "hel_sum_abs = 0, "; printf "hel_threshold = 1E10_%s" !kind; nl (); printf " @[<2>integer, save :: "; printf "hel_count = 0, "; printf "hel_cutoff = 100"; nl (); printf " @[<2>integer :: "; printf "i"; nl (); printf " @[<2>integer, save, dimension(n_hel) :: "; printf "hel_map = (/(i, i = 1, n_hel)/)"; nl (); printf " @[<2>integer, save :: hel_finite = n_hel"; nl (); nl () (* \thocwmodulesubsection{Optional MD5 sum function} *) let print_md5sum_functions = function | Some s -> printf " @[<5>"; if !fortran95 then printf "pure "; printf "function md5sum ()"; nl (); printf " character(len=32) :: md5sum"; nl (); printf " ! DON'T EVEN THINK of modifying the following line!"; nl (); printf " md5sum = \"%s\"" s; nl (); printf " end function md5sum"; nl (); nl () | None -> () (* \thocwmodulesubsection{Maintenance \&\ Inquiry Functions} *) let print_maintenance_functions () = if !whizard then begin printf " subroutine init (par, scheme)"; nl (); printf " real(kind=%s), dimension(*), intent(in) :: par" !kind; nl (); printf " integer, intent(in) :: scheme"; nl (); printf " call import_from_whizard (par, scheme)"; nl (); printf " end subroutine init"; nl (); nl (); printf " subroutine final ()"; nl (); printf " end subroutine final"; nl (); nl (); printf " subroutine update_alpha_s (alpha_s)"; nl (); printf " real(kind=%s), intent(in) :: alpha_s" !kind; nl (); printf " call model_update_alpha_s (alpha_s)"; nl (); printf " end subroutine update_alpha_s"; nl (); nl () end let print_inquiry_function_openmp () = begin printf " pure function openmp_supported () result (status)"; nl (); printf " logical :: status"; nl (); printf " status = %s" (if !openmp then ".true." else ".false."); nl (); printf " end function openmp_supported"; nl (); nl () end (*i unused value let print_inquiry_function_declarations name = printf " @[<2>public :: number_%s,@ %s" name name; nl () i*) (*i unused value let print_numeric_inquiry_functions () = printf " @[<5>"; if !fortran95 then printf "pure "; printf "function number_particles_in () result (n)"; nl (); printf " integer :: n"; nl (); printf " n = n_in"; nl (); printf " end function number_particles_in"; nl (); nl (); printf " @[<5>"; if !fortran95 then printf "pure "; printf "function number_particles_out () result (n)"; nl (); printf " integer :: n"; nl (); printf " n = n_out"; nl (); printf " end function number_particles_out"; nl (); nl () i*) let print_numeric_inquiry_functions (f, v) = printf " @[<5>"; if !fortran95 then printf "pure "; printf "function %s () result (n)" f; nl (); printf " integer :: n"; nl (); printf " n = %s" v; nl (); printf " end function %s" f; nl (); nl () let print_inquiry_functions name = printf " @[<5>"; if !fortran95 then printf "pure "; printf "function number_%s () result (n)" name; nl (); printf " integer :: n"; nl (); printf " n = size (table_%s, dim=2)" name; nl (); printf " end function number_%s" name; nl (); nl (); printf " @[<5>"; if !fortran95 then printf "pure "; printf "subroutine %s (a)" name; nl (); printf " integer, dimension(:,:), intent(out) :: a"; nl (); printf " a = table_%s" name; nl (); printf " end subroutine %s" name; nl (); nl () let print_color_flows () = printf " @[<5>"; if !fortran95 then printf "pure "; printf "function number_color_indices () result (n)"; nl (); printf " integer :: n"; nl (); printf " n = size (table_color_flows, dim=1)"; nl (); printf " end function number_color_indices"; nl (); nl (); printf " @[<5>"; if !fortran95 then printf "pure "; printf "function number_color_flows () result (n)"; nl (); printf " integer :: n"; nl (); printf " n = size (table_color_flows, dim=3)"; nl (); printf " end function number_color_flows"; nl (); nl (); printf " @[<5>"; if !fortran95 then printf "pure "; printf "subroutine color_flows (a, g)"; nl (); printf " integer, dimension(:,:,:), intent(out) :: a"; nl (); printf " logical, dimension(:,:), intent(out) :: g"; nl (); printf " a = table_color_flows"; nl (); printf " g = table_ghost_flags"; nl (); printf " end subroutine color_flows"; nl (); nl () let print_color_factors () = printf " @[<5>"; if !fortran95 then printf "pure "; printf "function number_color_factors () result (n)"; nl (); printf " integer :: n"; nl (); printf " n = size (table_color_factors)"; nl (); printf " end function number_color_factors"; nl (); nl (); printf " @[<5>"; if !fortran95 then printf "pure "; printf "subroutine color_factors (cf)"; nl (); printf " type(%s), dimension(:), intent(out) :: cf" omega_color_factor_abbrev; nl (); printf " cf = table_color_factors"; nl (); printf " end subroutine color_factors"; nl (); nl (); printf " @[<5>"; if !fortran95 && pure_unless_openmp then printf "pure "; printf "function color_sum (flv, hel) result (amp2)"; nl (); printf " integer, intent(in) :: flv, hel"; nl (); printf " real(kind=%s) :: amp2" !kind; nl (); printf " amp2 = real (omega_color_sum (flv, hel, amp, table_color_factors))"; nl (); printf " end function color_sum"; nl (); nl () let print_dispatch_functions () = printf " @[<5>"; printf "subroutine new_event (p)"; nl (); printf " real(kind=%s), dimension(0:3,*), intent(in) :: p" !kind; nl (); printf " logical :: mask_dirty"; nl (); printf " integer :: hel"; nl (); printf " call calculate_amplitudes (amp, p, hel_is_allowed)"; nl (); printf " if ((hel_threshold .gt. 0) .and. (hel_count .le. hel_cutoff)) then"; nl (); printf " call @[<3>omega_update_helicity_selection@ (hel_count,@ amp,@ "; printf "hel_max_abs,@ hel_sum_abs,@ hel_is_allowed,@ hel_threshold,@ hel_cutoff,@ mask_dirty)"; nl (); printf " if (mask_dirty) then"; nl (); printf " hel_finite = 0"; nl (); printf " do hel = 1, n_hel"; nl (); printf " if (hel_is_allowed(hel)) then"; nl (); printf " hel_finite = hel_finite + 1"; nl (); printf " hel_map(hel_finite) = hel"; nl (); printf " end if"; nl (); printf " end do"; nl (); printf " end if"; nl (); printf " end if"; nl (); printf " end subroutine new_event"; nl (); nl (); printf " @[<5>"; printf "subroutine reset_helicity_selection (threshold, cutoff)"; nl (); printf " real(kind=%s), intent(in) :: threshold" !kind; nl (); printf " integer, intent(in) :: cutoff"; nl (); printf " integer :: i"; nl (); printf " hel_is_allowed = T"; nl (); printf " hel_max_abs = 0"; nl (); printf " hel_sum_abs = 0"; nl (); printf " hel_count = 0"; nl (); printf " hel_threshold = threshold"; nl (); printf " hel_cutoff = cutoff"; nl (); printf " hel_map = (/(i, i = 1, n_hel)/)"; nl (); printf " hel_finite = n_hel"; nl (); printf " end subroutine reset_helicity_selection"; nl (); nl (); printf " @[<5>"; if !fortran95 then printf "pure "; printf "function is_allowed (flv, hel, col) result (yorn)"; nl (); printf " logical :: yorn"; nl (); printf " integer, intent(in) :: flv, hel, col"; nl (); printf " yorn = hel_is_allowed(hel) .and. "; printf "flv_col_is_allowed(flv,col)"; nl (); printf " end function is_allowed"; nl (); nl (); printf " @[<5>"; if !fortran95 then printf "pure "; printf "function get_amplitude (flv, hel, col) result (amp_result)"; nl (); printf " complex(kind=%s) :: amp_result" !kind; nl (); printf " integer, intent(in) :: flv, hel, col"; nl (); printf " amp_result = amp(flv, col, hel)"; nl (); printf " end function get_amplitude"; nl (); nl () (* \thocwmodulesubsection{Main Function} *) let format_power_of_nc { Color.Flow.num = num; Color.Flow.den = den; Color.Flow.power = pwr } = match num, den, pwr with | _, 0, _ -> invalid_arg "format_power_of_nc: zero denominator" | 0, _, _ -> "" | 1, 1, 0 | -1, -1, 0 -> "+ 1" | -1, 1, 0 | 1, -1, 0 -> "- 1" | 1, 1, 1 | -1, -1, 1 -> "+ N" | -1, 1, 1 | 1, -1, 1 -> "- N" | 1, 1, -1 | -1, -1, -1 -> "+ 1/N" | -1, 1, -1 | 1, -1, -1 -> "- 1/N" | 1, 1, p | -1, -1, p -> "+ " ^ (if p > 0 then "" else "1/") ^ "N^" ^ string_of_int (abs p) | -1, 1, p | 1, -1, p -> "- " ^ (if p > 0 then "" else "1/") ^ "N^" ^ string_of_int (abs p) | n, 1, 0 -> (if n < 0 then "- " else "+ ") ^ string_of_int (abs n) | n, d, 0 -> (if n * d < 0 then "- " else "+ ") ^ string_of_int (abs n) ^ "/" ^ string_of_int (abs d) | n, 1, 1 -> (if n < 0 then "- " else "+ ") ^ string_of_int (abs n) ^ "N" | n, 1, -1 -> (if n < 0 then "- " else "+ ") ^ string_of_int (abs n) ^ "/N" | n, d, 1 -> (if n * d < 0 then "- " else "+ ") ^ string_of_int (abs n) ^ "/" ^ string_of_int (abs d) ^ "N" | n, d, -1 -> (if n * d < 0 then "- " else "+ ") ^ string_of_int (abs n) ^ "/" ^ string_of_int (abs d) ^ "/N" | n, 1, p -> (if n < 0 then "- " else "+ ") ^ string_of_int (abs n) ^ (if p > 0 then "*" else "/") ^ "N^" ^ string_of_int (abs p) | n, d, p -> (if n * d < 0 then "- " else "+ ") ^ string_of_int (abs n) ^ "/" ^ string_of_int (abs d) ^ (if p > 0 then "*" else "/") ^ "N^" ^ string_of_int (abs p) let format_powers_of_nc = function | [] -> "0" | powers -> String.concat " " (List.map format_power_of_nc powers) let print_description cmdline amplitudes () = printf "! File generated automatically by O'Mega %s %s %s" Config.version Config.status Config.date; nl (); printf "!"; nl (); printf "! %s" cmdline; nl (); printf "!"; nl (); printf "! with all scattering amplitudes for the process(es)"; nl (); printf "!"; nl (); printf "! flavor combinations:"; nl (); printf "!"; nl (); ThoList.iteri (fun i process -> printf "! %3d: %s" i (process_sans_color_to_string process); nl ()) 1 (CF.flavors amplitudes); printf "!"; nl (); printf "! color flows:"; nl (); if not !amp_triv then begin printf "!"; nl (); ThoList.iteri (fun i cflow -> printf "! %3d: %s" i (cflow_to_string cflow); nl ()) 1 (CF.color_flows amplitudes); printf "!"; nl (); printf "! NB: i.g. not all color flows contribute to all flavor"; nl (); printf "! combinations. Consult the array FLV_COL_IS_ALLOWED"; nl (); printf "! below for the allowed combinations."; nl (); end; printf "!"; nl (); printf "! Color Factors:"; nl (); printf "!"; nl (); if not !amp_triv then begin let cfactors = CF.color_factors amplitudes in for c1 = 0 to pred (Array.length cfactors) do for c2 = 0 to c1 do match cfactors.(c1).(c2) with | [] -> () | cfactor -> printf "! (%3d,%3d): %s" (succ c1) (succ c2) (format_powers_of_nc cfactor); nl () done done; end; printf "!"; nl (); printf "! vanishing or redundant flavor combinations:"; nl (); printf "!"; nl (); List.iter (fun process -> printf "! %s" (process_sans_color_to_string process); nl ()) (CF.vanishing_flavors amplitudes); printf "!"; nl (); begin match CF.constraints amplitudes with | None -> () | Some s -> printf "! diagram selection (MIGHT BREAK GAUGE INVARIANCE!!!):"; nl (); printf "!"; nl (); printf "! %s" s; nl (); printf "!"; nl () end; printf "!"; nl () (* \thocwmodulesubsection{Printing Modules} *) type accessibility = | Public | Private | Protected (* Fortran 2003 *) let accessibility_to_string = function | Public -> "public" | Private -> "private" | Protected -> "protected" type used_symbol = | As_Is of string | Aliased of string * string let print_used_symbol = function | As_Is name -> printf "%s" name | Aliased (orig, alias) -> printf "%s => %s" alias orig type used_module = | Full of string | Full_Aliased of string * (string * string) list | Subset of string * used_symbol list let print_used_module = function | Full name | Full_Aliased (name, []) | Subset (name, []) -> printf " use %s" name; nl () | Full_Aliased (name, aliases) -> printf " @[<5>use %s" name; List.iter (fun (orig, alias) -> printf ", %s => %s" alias orig) aliases; nl () | Subset (name, used_symbol :: used_symbols) -> printf " @[<5>use %s, only: " name; print_used_symbol used_symbol; List.iter (fun s -> printf ", "; print_used_symbol s) used_symbols; nl () type fortran_module = { module_name : string; default_accessibility : accessibility; used_modules : used_module list; public_symbols : string list; print_declarations : (unit -> unit) list; print_implementations : (unit -> unit) list } let print_public = function | name1 :: names -> printf " @[<2>public :: %s" name1; List.iter (fun n -> printf ",@ %s" n) names; nl () | [] -> () (*i unused value let print_public_interface generic procedures = printf " public :: %s" generic; nl (); begin match procedures with | name1 :: names -> printf " interface %s" generic; nl (); printf " @[<2>module procedure %s" name1; List.iter (fun n -> printf ",@ %s" n) names; nl (); printf " end interface"; nl (); print_public procedures | [] -> () end i*) let print_module m = printf "module %s" m.module_name; nl (); List.iter print_used_module m.used_modules; printf " implicit none"; nl (); printf " %s" (accessibility_to_string m.default_accessibility); nl (); print_public m.public_symbols; nl (); begin match m.print_declarations with | [] -> () | print_declarations -> List.iter (fun f -> f ()) print_declarations; nl () end; begin match m.print_implementations with | [] -> () | print_implementations -> printf "contains"; nl (); nl (); List.iter (fun f -> f ()) print_implementations; nl (); end; printf "end module %s" m.module_name; nl () let print_modules modules = List.iter print_module modules; print_flush () let module_to_file line_length oc prelude m = output_string oc (m.module_name ^ "\n"); let filename = m.module_name ^ ".f90" in let channel = open_out filename in Format_Fortran.set_formatter_out_channel ~width:line_length channel; prelude (); print_modules [m]; close_out channel let modules_to_file line_length oc prelude = function | [] -> () | m :: mlist -> module_to_file line_length oc prelude m; List.iter (module_to_file line_length oc (fun () -> ())) mlist (* \thocwmodulesubsection{Chopping Up Amplitudes} *) let num_fusions_brakets size amplitudes = let num_fusions = max 1 size in let count_brakets = List.fold_left (fun sum process -> sum + List.length (F.brakets process)) 0 (CF.processes amplitudes) and count_processes = List.length (CF.processes amplitudes) in if count_brakets > 0 then let num_brakets = max 1 ((num_fusions * count_processes) / count_brakets) in (num_fusions, num_brakets) else (num_fusions, 1) let chop_amplitudes size amplitudes = let num_fusions, num_brakets = num_fusions_brakets size amplitudes in (ThoList.enumerate 1 (ThoList.chopn num_fusions (CF.fusions amplitudes)), ThoList.enumerate 1 (ThoList.chopn num_brakets (CF.processes amplitudes))) let print_compute_fusions1 dictionary (n, fusions) = if not !amp_triv then begin if !openmp then begin printf " subroutine compute_fusions_%04d (%s)" n openmp_tld; nl (); printf " @[<5>type(%s), intent(inout) :: %s" openmp_tld_type openmp_tld; nl (); end else begin printf " @[<5>subroutine compute_fusions_%04d ()" n; nl (); end; print_fusions dictionary fusions; printf " end subroutine compute_fusions_%04d" n; nl (); end and print_compute_brakets1 dictionary (n, processes) = if not !amp_triv then begin if !openmp then begin printf " subroutine compute_brakets_%04d (%s)" n openmp_tld; nl (); printf " @[<5>type(%s), intent(inout) :: %s" openmp_tld_type openmp_tld; nl (); end else begin printf " @[<5>subroutine compute_brakets_%04d ()" n; nl (); end; List.iter (print_brakets dictionary) processes; printf " end subroutine compute_brakets_%04d" n; nl (); end (* \thocwmodulesubsection{Common Stuff} *) let omega_public_symbols = ["number_particles_in"; "number_particles_out"; "number_color_indices"; "reset_helicity_selection"; "new_event"; "is_allowed"; "get_amplitude"; "color_sum"; "openmp_supported"] @ ThoList.flatmap (fun n -> ["number_" ^ n; n]) ["spin_states"; "flavor_states"; "color_flows"; "color_factors"] let whizard_public_symbols md5sum = ["init"; "final"; "update_alpha_s"] @ (match md5sum with Some _ -> ["md5sum"] | None -> []) let used_modules () = [Full "kinds"; Full Fermions.use_module; Full_Aliased ("omega_color", ["omega_color_factor", omega_color_factor_abbrev])] @ List.map (fun m -> Full m) (match !parameter_module with | "" -> !use_modules | pm -> pm :: !use_modules) let public_symbols () = if !whizard then omega_public_symbols @ (whizard_public_symbols !md5sum) else omega_public_symbols let print_constants amplitudes = printf " ! DON'T EVEN THINK of removing the following!"; nl (); printf " ! If the compiler complains about undeclared"; nl (); printf " ! or undefined variables, you are compiling"; nl (); printf " ! against an incompatible omega95 module!"; nl (); printf " @[<2>integer, dimension(%d), parameter, private :: " (List.length require_library); printf "require =@ (/ @["; print_list require_library; printf " /)"; nl (); nl (); (* Using these parameters makes sense for documentation, but in practice, there is no need to ever change them. *) List.iter (function name, value -> print_integer_parameter name (value amplitudes)) [ ("n_prt", num_particles); ("n_in", num_particles_in); ("n_out", num_particles_out); ("n_cflow", num_color_flows); (* Number of different color amplitudes. *) ("n_cindex", num_color_indices); (* Maximum rank of color tensors. *) ("n_flv", num_flavors); (* Number of different flavor amplitudes. *) ("n_hel", num_helicities) (* Number of different helicty amplitudes. *) ]; nl (); (* Abbreviations. *) printf " ! NB: you MUST NOT change the value of %s here!!!" nc_parameter; nl (); printf " ! It is defined here for convenience only and must be"; nl (); printf " ! compatible with hardcoded values in the amplitude!"; nl (); print_real_parameter nc_parameter (CM.nc ()); (* $N_C$ *) List.iter (function name, value -> print_logical_parameter name value) [ ("F", false); ("T", true) ]; nl (); print_spin_tables amplitudes; print_flavor_tables amplitudes; print_color_tables amplitudes; print_amplitude_table amplitudes; print_helicity_selection_table () let print_interface () = print_md5sum_functions !md5sum; print_maintenance_functions (); List.iter print_numeric_inquiry_functions [("number_particles_in", "n_in"); ("number_particles_out", "n_out")]; List.iter print_inquiry_functions ["spin_states"; "flavor_states"]; print_inquiry_function_openmp (); print_color_flows (); print_color_factors (); print_dispatch_functions (); nl (); (* Is this really necessary? *) Format_Fortran.switch_line_continuation false; if !km_write || !km_pure then (Targets_Kmatrix.Fortran.print !km_pure); if !km_2_write || !km_2_pure then (Targets_Kmatrix_2.Fortran.print !km_2_pure); Format_Fortran.switch_line_continuation true; nl () let print_calculate_amplitudes declarations computations amplitudes = printf " @[<5>subroutine calculate_amplitudes (amp, k, mask)"; nl (); printf " complex(kind=%s), dimension(:,:,:), intent(out) :: amp" !kind; nl (); printf " real(kind=%s), dimension(0:3,*), intent(in) :: k" !kind; nl (); printf " logical, dimension(:), intent(in) :: mask"; nl (); printf " integer, dimension(n_prt) :: s"; nl (); printf " integer :: h, hi"; nl (); declarations (); if not !amp_triv then begin begin match CF.processes amplitudes with | p :: _ -> print_external_momenta p | _ -> () end; ignore (List.fold_left print_momenta PSet.empty (CF.processes amplitudes)); end; printf " amp = 0"; nl (); if not !amp_triv then begin if num_helicities amplitudes > 0 then begin printf " if (hel_finite == 0) return"; nl (); if !openmp then begin printf "!$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(s, h, %s) SCHEDULE(STATIC)" openmp_tld; nl (); end; printf " do hi = 1, hel_finite"; nl (); printf " h = hel_map(hi)"; nl (); printf " s = table_spin_states(:,h)"; nl (); ignore (List.fold_left print_externals WFSet.empty (CF.processes amplitudes)); computations (); List.iter print_fudge_factor (CF.processes amplitudes); (* This sorting should slightly improve cache locality. *) let triple_snd = fun (_, x, _) -> x in let triple_fst = fun (x, _, _) -> x in let rec builder1 flvi flowi flows = match flows with | (Some a) :: tl -> (flvi, flowi, flavors_symbol (flavors a)) :: (builder1 flvi (flowi + 1) tl) | None :: tl -> builder1 flvi (flowi + 1) tl | [] -> [] in let rec builder2 flvi flvs = match flvs with | flv :: tl -> (builder1 flvi 1 flv) @ (builder2 (flvi + 1) tl) | [] -> [] in let unsorted = builder2 1 (List.map Array.to_list (Array.to_list (CF.process_table amplitudes))) in let sorted = List.sort (fun a b -> if (triple_snd a != triple_snd b) then triple_snd a - triple_snd b else (triple_fst a - triple_fst b)) unsorted in List.iter (fun (flvi, flowi, flv) -> (printf " amp(%d,%d,h) = %s" flvi flowi flv; nl ();)) sorted; (*i printf " else"; nl (); printf " amp(:,h,:) = 0"; nl (); i*) printf " end do"; nl (); if !openmp then begin printf "!$OMP END PARALLEL DO"; nl (); end; end; end; printf " end subroutine calculate_amplitudes"; nl () let print_compute_chops chopped_fusions chopped_brakets () = List.iter (fun (i, _) -> printf " call compute_fusions_%04d (%s)" i (if !openmp then openmp_tld else ""); nl ()) chopped_fusions; List.iter (fun (i, _) -> printf " call compute_brakets_%04d (%s)" i (if !openmp then openmp_tld else ""); nl ()) chopped_brakets (* \thocwmodulesubsection{UFO Fusions} *) module VSet = Set.Make (struct type t = F.constant Coupling.t let compare = compare end) let ufo_fusions_used amplitudes = let couplings = List.fold_left (fun acc p -> let fusions = ThoList.flatmap F.rhs (F.fusions p) and brakets = ThoList.flatmap F.ket (F.brakets p) in let couplings = VSet.of_list (List.map F.coupling (fusions @ brakets)) in VSet.union acc couplings) VSet.empty (CF.processes amplitudes) in VSet.fold (fun v acc -> match v with | Coupling.Vn (Coupling.UFO (_, v, _, _, _), _, _) -> Sets.String.add v acc | _ -> acc) couplings Sets.String.empty (* \thocwmodulesubsection{Single Function} *) let amplitudes_to_channel_single_function cmdline oc amplitudes = let print_declarations () = print_constants amplitudes and print_implementations () = print_interface (); print_calculate_amplitudes (fun () -> print_variable_declarations amplitudes) (fun () -> print_fusions (CF.dictionary amplitudes) (CF.fusions amplitudes); List.iter (print_brakets (CF.dictionary amplitudes)) (CF.processes amplitudes)) amplitudes in let fortran_module = { module_name = !module_name; used_modules = used_modules (); default_accessibility = Private; public_symbols = public_symbols (); print_declarations = [print_declarations]; print_implementations = [print_implementations] } in Format_Fortran.set_formatter_out_channel ~width:!line_length oc; print_description cmdline amplitudes (); print_modules [fortran_module] (* \thocwmodulesubsection{Single Module} *) let amplitudes_to_channel_single_module cmdline oc size amplitudes = let print_declarations () = print_constants amplitudes; print_variable_declarations amplitudes and print_implementations () = print_interface () in let chopped_fusions, chopped_brakets = chop_amplitudes size amplitudes in let dictionary = CF.dictionary amplitudes in let print_compute_amplitudes () = print_calculate_amplitudes (fun () -> ()) (print_compute_chops chopped_fusions chopped_brakets) amplitudes and print_compute_fusions () = List.iter (print_compute_fusions1 dictionary) chopped_fusions and print_compute_brakets () = List.iter (print_compute_brakets1 dictionary) chopped_brakets in let fortran_module = { module_name = !module_name; used_modules = used_modules (); default_accessibility = Private; public_symbols = public_symbols (); print_declarations = [print_declarations]; print_implementations = [print_implementations; print_compute_amplitudes; print_compute_fusions; print_compute_brakets] } in Format_Fortran.set_formatter_out_channel ~width:!line_length oc; print_description cmdline amplitudes (); print_modules [fortran_module] (* \thocwmodulesubsection{Multiple Modules} *) let modules_of_amplitudes _ _ size amplitudes = let name = !module_name in let print_declarations () = print_constants amplitudes and print_variables () = print_variable_declarations amplitudes in let constants_module = { module_name = name ^ "_constants"; used_modules = used_modules (); default_accessibility = Public; public_symbols = []; print_declarations = [print_declarations]; print_implementations = [] } in let variables_module = { module_name = name ^ "_variables"; used_modules = used_modules (); default_accessibility = Public; public_symbols = []; print_declarations = [print_variables]; print_implementations = [] } in let dictionary = CF.dictionary amplitudes in let print_compute_fusions (n, fusions) () = if not !amp_triv then begin if !openmp then begin printf " subroutine compute_fusions_%04d (%s)" n openmp_tld; nl (); printf " @[<5>type(%s), intent(inout) :: %s" openmp_tld_type openmp_tld; nl (); end else begin printf " @[<5>subroutine compute_fusions_%04d ()" n; nl (); end; print_fusions dictionary fusions; printf " end subroutine compute_fusions_%04d" n; nl (); end in let print_compute_brakets (n, processes) () = if not !amp_triv then begin if !openmp then begin printf " subroutine compute_brakets_%04d (%s)" n openmp_tld; nl (); printf " @[<5>type(%s), intent(inout) :: %s" openmp_tld_type openmp_tld; nl (); end else begin printf " @[<5>subroutine compute_brakets_%04d ()" n; nl (); end; List.iter (print_brakets dictionary) processes; printf " end subroutine compute_brakets_%04d" n; nl (); end in let fusions_module (n, _ as fusions) = let tag = Printf.sprintf "_fusions_%04d" n in { module_name = name ^ tag; used_modules = (used_modules () @ [Full constants_module.module_name; Full variables_module.module_name]); default_accessibility = Private; public_symbols = ["compute" ^ tag]; print_declarations = []; print_implementations = [print_compute_fusions fusions] } in let brakets_module (n, _ as processes) = let tag = Printf.sprintf "_brakets_%04d" n in { module_name = name ^ tag; used_modules = (used_modules () @ [Full constants_module.module_name; Full variables_module.module_name]); default_accessibility = Private; public_symbols = ["compute" ^ tag]; print_declarations = []; print_implementations = [print_compute_brakets processes] } in let chopped_fusions, chopped_brakets = chop_amplitudes size amplitudes in let fusions_modules = List.map fusions_module chopped_fusions in let brakets_modules = List.map brakets_module chopped_brakets in let print_implementations () = print_interface (); print_calculate_amplitudes (fun () -> ()) (print_compute_chops chopped_fusions chopped_brakets) amplitudes in let public_module = { module_name = name; used_modules = (used_modules () @ [Full constants_module.module_name; Full variables_module.module_name ] @ List.map (fun m -> Full m.module_name) (fusions_modules @ brakets_modules)); default_accessibility = Private; public_symbols = public_symbols (); print_declarations = []; print_implementations = [print_implementations] } and private_modules = [constants_module; variables_module] @ fusions_modules @ brakets_modules in (public_module, private_modules) let amplitudes_to_channel_single_file cmdline oc size amplitudes = let public_module, private_modules = modules_of_amplitudes cmdline oc size amplitudes in Format_Fortran.set_formatter_out_channel ~width:!line_length oc; print_description cmdline amplitudes (); print_modules (private_modules @ [public_module]) let amplitudes_to_channel_multi_file cmdline oc size amplitudes = let public_module, private_modules = modules_of_amplitudes cmdline oc size amplitudes in modules_to_file !line_length oc (print_description cmdline amplitudes) (public_module :: private_modules) (* \thocwmodulesubsection{Dispatch} *) let amplitudes_to_channel cmdline oc diagnostics amplitudes = parse_diagnostics diagnostics; let ufo_fusions = let ufo_fusions_set = ufo_fusions_used amplitudes in if Sets.String.is_empty ufo_fusions_set then None else Some ufo_fusions_set in begin match ufo_fusions with | Some only -> let name = !module_name ^ "_ufo" and fortran_module = Fermions.use_module in use_modules := name :: !use_modules; UFO.Targets.Fortran.lorentz_module ~only ~name ~fortran_module (Format_Fortran.formatter_of_out_channel oc) () | None -> () end; match !output_mode with | Single_Function -> amplitudes_to_channel_single_function cmdline oc amplitudes | Single_Module size -> amplitudes_to_channel_single_module cmdline oc size amplitudes | Single_File size -> amplitudes_to_channel_single_file cmdline oc size amplitudes | Multi_File size -> amplitudes_to_channel_multi_file cmdline oc size amplitudes let parameters_to_channel oc = parameters_to_fortran oc (CM.parameters ()) end module Fortran = Make_Fortran(Fortran_Fermions) (* \thocwmodulesubsection{Majorana Fermions} *) (* \begin{JR} For this function we need a different approach due to our aim of implementing the fermion vertices with the right line as ingoing (in a calculational sense) and the left line in a fusion as outgoing. In defining all external lines and the fermionic wavefunctions built out of them as ingoing we have to invert the left lines to make them outgoing. This happens by multiplying them with the inverse charge conjugation matrix in an appropriate representation and then transposing it. We must distinguish whether the direction of calculation and the physical direction of the fermion number flow are parallel or antiparallel. In the first case we can use the "normal" Feynman rules for Dirac particles, while in the second, according to the paper of Denner et al., we have to reverse the sign of the vector and antisymmetric bilinears of the Dirac spinors, cf. the [Coupling] module. Note the subtlety for the left- and righthanded couplings: Only the vector part of these couplings changes in the appropriate cases its sign, changing the chirality to the negative of the opposite. \end{JR} *) module Fortran_Majorana_Fermions : Fermions = struct open Coupling open Format let psi_type = "bispinor" let psibar_type = "bispinor" let chi_type = "bispinor" let grav_type = "vectorspinor" (* \begin{JR} Because of our rules for fermions we are going to give all incoming fermions a [u] spinor and all outgoing fermions a [v] spinor, no matter whether they are Dirac fermions, antifermions or Majorana fermions. \end{JR} *) let psi_incoming = "u" let brs_psi_incoming = "brs_u" let psibar_incoming = "u" let brs_psibar_incoming = "brs_u" let chi_incoming = "u" let brs_chi_incoming = "brs_u" let grav_incoming = "ueps" let psi_outgoing = "v" let brs_psi_outgoing = "brs_v" let psibar_outgoing = "v" let brs_psibar_outgoing = "brs_v" let chi_outgoing = "v" let brs_chi_outgoing = "brs_v" let grav_outgoing = "veps" let psi_propagator = "pr_psi" let psibar_propagator = "pr_psi" let chi_propagator = "pr_psi" let grav_propagator = "pr_grav" let psi_projector = "pj_psi" let psibar_projector = "pj_psi" let chi_projector = "pj_psi" let grav_projector = "pj_grav" let psi_gauss = "pg_psi" let psibar_gauss = "pg_psi" let chi_gauss = "pg_psi" let grav_gauss = "pg_grav" let format_coupling coeff c = match coeff with | 1 -> c | -1 -> "(-" ^ c ^")" | coeff -> string_of_int coeff ^ "*" ^ c let format_coupling_2 coeff c = match coeff with | 1 -> c | -1 -> "-" ^ c | coeff -> string_of_int coeff ^ "*" ^ c (* \begin{dubious} JR's coupling constant HACK, necessitated by tho's bad design descition. \end{dubious} *) let fastener s i = try let offset = (String.index s '(') in if ((String.get s (String.length s - 1)) != ')') then failwith "fastener: wrong usage of parentheses" else let func_name = (String.sub s 0 offset) and tail = (String.sub s (succ offset) (String.length s - offset - 2)) in if (String.contains func_name ')') || (String.contains tail '(') || (String.contains tail ')') then failwith "fastener: wrong usage of parentheses" else func_name ^ "(" ^ string_of_int i ^ "," ^ tail ^ ")" with | Not_found -> if (String.contains s ')') then failwith "fastener: wrong usage of parentheses" else s ^ "(" ^ string_of_int i ^ ")" let print_fermion_current coeff f c wf1 wf2 fusion = let c = format_coupling coeff c in match fusion with | F13 | F31 -> printf "%s_ff(%s,%s,%s)" f c wf1 wf2 | F23 | F21 -> printf "f_%sf(%s,%s,%s)" f c wf1 wf2 | F32 | F12 -> printf "f_%sf(%s,%s,%s)" f c wf2 wf1 let print_fermion_current2 coeff f c wf1 wf2 fusion = let c = format_coupling_2 coeff c in let c1 = fastener c 1 and c2 = fastener c 2 in match fusion with | F13 | F31 -> printf "%s_ff(%s,%s,%s,%s)" f c1 c2 wf1 wf2 | F23 | F21 -> printf "f_%sf(%s,%s,%s,%s)" f c1 c2 wf1 wf2 | F32 | F12 -> printf "f_%sf(%s,%s,%s,%s)" f c1 c2 wf2 wf1 let print_fermion_current_mom_v1 coeff f c wf1 wf2 p1 p2 p12 fusion = let c = format_coupling coeff c in let c1 = fastener c 1 and c2 = fastener c 2 in match fusion with | F13 -> printf "%s_ff(%s,%s,%s,%s)" f c1 c2 wf1 wf2 | F31 -> printf "%s_ff(-(%s),%s,%s,%s)" f c1 c2 wf1 wf2 | F23 -> printf "f_%sf(%s,%s,%s,%s)" f c1 c2 wf1 wf2 | F32 -> printf "f_%sf(%s,%s,%s,%s)" f c1 c2 wf2 wf1 | F12 -> printf "f_f%s(-(%s),%s,%s,%s)" f c1 c2 wf2 wf1 | F21 -> printf "f_f%s(-(%s),%s,%s,%s)" f c1 c2 wf1 wf2 let print_fermion_current_mom_v1_chiral coeff f c wf1 wf2 p1 p2 p12 fusion = let c = format_coupling coeff c in let c1 = fastener c 1 and c2 = fastener c 2 in match fusion with | F13 -> printf "%s_ff(%s,%s,%s,%s)" f c1 c2 wf1 wf2 | F31 -> printf "%s_ff(-(%s),-(%s),%s,%s)" f c2 c1 wf1 wf2 | F23 -> printf "f_%sf(%s,%s,%s,%s)" f c1 c2 wf1 wf2 | F32 -> printf "f_%sf(%s,%s,%s,%s)" f c1 c2 wf2 wf1 | F12 -> printf "f_f%s(-(%s),-(%s),%s,%s)" f c2 c1 wf2 wf1 | F21 -> printf "f_f%s(-(%s),-(%s),%s,%s)" f c2 c1 wf2 wf1 let print_fermion_current_mom_v2 coeff f c wf1 wf2 p1 p2 p12 fusion = let c = format_coupling coeff c in let c1 = fastener c 1 and c2 = fastener c 2 in match fusion with | F13 -> printf "%s_ff(%s,%s,%s,%s,%s)" f c1 c2 wf1 wf2 p12 | F31 -> printf "%s_ff(-(%s),%s,%s,%s,%s)" f c1 c2 wf1 wf2 p12 | F23 -> printf "f_%sf(%s,%s,%s,%s,%s)" f c1 c2 wf1 wf2 p1 | F32 -> printf "f_%sf(%s,%s,%s,%s,%s)" f c1 c2 wf2 wf1 p2 | F12 -> printf "f_f%s(-(%s),%s,%s,%s,%s)" f c1 c2 wf2 wf1 p2 | F21 -> printf "f_f%s(-(%s),%s,%s,%s,%s)" f c1 c2 wf1 wf2 p1 let print_fermion_current_mom_v2_chiral coeff f c wf1 wf2 p1 p2 p12 fusion = let c = format_coupling coeff c in let c1 = fastener c 1 and c2 = fastener c 2 in match fusion with | F13 -> printf "%s_ff(%s,%s,%s,%s,%s)" f c1 c2 wf1 wf2 p12 | F31 -> printf "%s_ff(-(%s),-(%s),%s,%s,%s)" f c2 c1 wf2 wf1 p12 | F23 -> printf "f_%sf(%s,%s,%s,%s,%s)" f c1 c2 wf1 wf2 p1 | F32 -> printf "f_%sf(%s,%s,%s,%s,%s)" f c1 c2 wf2 wf1 p2 | F12 -> printf "f_f%s(-(%s),-(%s),%s,%s,%s)" f c2 c1 wf1 wf2 p2 | F21 -> printf "f_f%s(-(%s),-(%s),%s,%s,%s)" f c2 c1 wf2 wf1 p1 let print_fermion_current_vector coeff f c wf1 wf2 fusion = let c = format_coupling coeff c in match fusion with | F13 -> printf "%s_ff(%s,%s,%s)" f c wf1 wf2 | F31 -> printf "%s_ff(-%s,%s,%s)" f c wf1 wf2 | F23 -> printf "f_%sf(%s,%s,%s)" f c wf1 wf2 | F32 -> printf "f_%sf(%s,%s,%s)" f c wf2 wf1 | F12 -> printf "f_%sf(-%s,%s,%s)" f c wf2 wf1 | F21 -> printf "f_%sf(-%s,%s,%s)" f c wf1 wf2 let print_fermion_current2_vector coeff f c wf1 wf2 fusion = let c = format_coupling_2 coeff c in let c1 = fastener c 1 and c2 = fastener c 2 in match fusion with | F13 -> printf "%s_ff(%s,%s,%s,%s)" f c1 c2 wf1 wf2 | F31 -> printf "%s_ff(-(%s),%s,%s,%s)" f c1 c2 wf1 wf2 | F23 -> printf "f_%sf(%s,%s,%s,%s)" f c1 c2 wf1 wf2 | F32 -> printf "f_%sf(%s,%s,%s,%s)" f c1 c2 wf2 wf1 | F12 -> printf "f_%sf(-(%s),%s,%s,%s)" f c1 c2 wf2 wf1 | F21 -> printf "f_%sf(-(%s),%s,%s,%s)" f c1 c2 wf1 wf2 let print_fermion_current_chiral coeff f1 f2 c wf1 wf2 fusion = let c = format_coupling coeff c in match fusion with | F13 -> printf "%s_ff(%s,%s,%s)" f1 c wf1 wf2 | F31 -> printf "%s_ff(-%s,%s,%s)" f2 c wf1 wf2 | F23 -> printf "f_%sf(%s,%s,%s)" f1 c wf1 wf2 | F32 -> printf "f_%sf(%s,%s,%s)" f1 c wf2 wf1 | F12 -> printf "f_%sf(-%s,%s,%s)" f2 c wf2 wf1 | F21 -> printf "f_%sf(-%s,%s,%s)" f2 c wf1 wf2 let print_fermion_current2_chiral coeff f c wf1 wf2 fusion = let c = format_coupling_2 coeff c in let c1 = fastener c 1 and c2 = fastener c 2 in match fusion with | F13 -> printf "%s_ff(%s,%s,%s,%s)" f c1 c2 wf1 wf2 | F31 -> printf "%s_ff(-(%s),-(%s),%s,%s)" f c2 c1 wf1 wf2 | F23 -> printf "f_%sf(%s,%s,%s,%s)" f c1 c2 wf1 wf2 | F32 -> printf "f_%sf(%s,%s,%s,%s)" f c1 c2 wf2 wf1 | F12 -> printf "f_%sf(-(%s),-(%s),%s,%s)" f c2 c1 wf2 wf1 | F21 -> printf "f_%sf(-(%s),-(%s),%s,%s)" f c2 c1 wf1 wf2 let print_current = function | coeff, _, VA, _ -> print_fermion_current2_vector coeff "va" | coeff, _, V, _ -> print_fermion_current_vector coeff "v" | coeff, _, A, _ -> print_fermion_current coeff "a" | coeff, _, VL, _ -> print_fermion_current_chiral coeff "vl" "vr" | coeff, _, VR, _ -> print_fermion_current_chiral coeff "vr" "vl" | coeff, _, VLR, _ -> print_fermion_current2_chiral coeff "vlr" | coeff, _, SP, _ -> print_fermion_current2 coeff "sp" | coeff, _, S, _ -> print_fermion_current coeff "s" | coeff, _, P, _ -> print_fermion_current coeff "p" | coeff, _, SL, _ -> print_fermion_current coeff "sl" | coeff, _, SR, _ -> print_fermion_current coeff "sr" | coeff, _, SLR, _ -> print_fermion_current2 coeff "slr" | coeff, _, POT, _ -> print_fermion_current_vector coeff "pot" | _, _, _, _ -> invalid_arg "Targets.Fortran_Majorana_Fermions: Not needed in the models" let print_current_p = function | coeff, Psi, SL, Psi -> print_fermion_current coeff "sl" | coeff, Psi, SR, Psi -> print_fermion_current coeff "sr" | coeff, Psi, SLR, Psi -> print_fermion_current2 coeff "slr" | _, _, _, _ -> invalid_arg "Targets.Fortran_Majorana_Fermions: Not needed in the used models" let print_current_b = function | coeff, Psibar, SL, Psibar -> print_fermion_current coeff "sl" | coeff, Psibar, SR, Psibar -> print_fermion_current coeff "sr" | coeff, Psibar, SLR, Psibar -> print_fermion_current2 coeff "slr" | _, _, _, _ -> invalid_arg "Targets.Fortran_Majorana_Fermions: Not needed in the used models" (* This function is for the vertices with three particles including two fermions but also a momentum, therefore with a dimensionful coupling constant, e.g. the gravitino vertices. One has to dinstinguish between the two kinds of canonical orders in the string of gamma matrices. Of course, the direction of the string of gamma matrices is reversed if one goes from the [Gravbar, _, Psi] to the [Psibar, _, Grav] vertices, and the same is true for the couplings of the gravitino to the Majorana fermions. For more details see the tables in the [coupling] implementation. *) (* We now have to fix the directions of the momenta. For making the compiler happy and because we don't want to make constructions of infinite complexity we list the momentum including vertices without gravitinos here; the pattern matching says that's better. Perhaps we have to find a better name now. For the cases of $MOM$, $MOM5$, $MOML$ and $MOMR$ which arise only in BRST transformations we take the mass as a coupling constant. For $VMOM$ we don't need a mass either. These vertices are like kinetic terms and so need not have a coupling constant. By this we avoid a strange and awful construction with a new variable. But be careful with a generalization if you want to use these vertices for other purposes. *) let format_coupling_mom coeff c = match coeff with | 1 -> c | -1 -> "(-" ^ c ^")" | coeff -> string_of_int coeff ^ "*" ^ c let commute_proj f = match f with | "moml" -> "lmom" | "momr" -> "rmom" | "lmom" -> "moml" | "rmom" -> "momr" | "svl" -> "svr" | "svr" -> "svl" | "sl" -> "sr" | "sr" -> "sl" | "s" -> "s" | "p" -> "p" | _ -> invalid_arg "Targets:Fortran_Majorana_Fermions: wrong case" let print_fermion_current_mom coeff f c wf1 wf2 p1 p2 p12 fusion = let c = format_coupling_mom coeff c in let c1 = fastener c 1 and c2 = fastener c 2 in match fusion with | F13 -> printf "%s_ff(%s,%s,%s,%s,%s)" f c1 c2 wf1 wf2 p12 | F31 -> printf "%s_ff(%s,%s,%s,%s,%s)" f c1 c2 wf1 wf2 p12 | F23 -> printf "f_%sf(%s,%s,%s,%s,%s)" f c1 c2 wf1 wf2 p1 | F32 -> printf "f_%sf(%s,%s,%s,%s,%s)" f c1 c2 wf2 wf1 p2 | F12 -> printf "f_%sf(%s,%s,%s,%s,%s)" f c1 c2 wf2 wf1 p2 | F21 -> printf "f_%sf(%s,%s,%s,%s,%s)" f c1 c2 wf1 wf2 p1 (*i unused value let print_fermion_current_mom_vector coeff f c wf1 wf2 p1 p2 p12 fusion = let c = format_coupling_mom coeff c in let c1 = fastener c 1 and c2 = fastener c 2 in match fusion with | F13 -> printf "%s_ff(%s,%s,%s,%s,%s)" f c1 c2 wf1 wf2 p12 | F31 -> printf "%s_ff(-%s,%s,%s,%s,%s)" f c1 c2 wf1 wf2 p12 | F23 -> printf "f_%sf(%s,%s,%s,%s,%s)" f c1 c2 wf1 wf2 p1 | F32 -> printf "f_%sf(%s,%s,%s,%s,%s)" f c1 c2 wf2 wf1 p2 | F12 -> printf "f_%sf(-%s,%s,%s,%s,%s)" f c1 c2 wf2 wf1 p2 | F21 -> printf "f_%sf(-%s,%s,%s,%s,%s)" f c1 c2 wf1 wf2 p1 i*) let print_fermion_current_mom_sign coeff f c wf1 wf2 p1 p2 p12 fusion = let c = format_coupling_mom coeff c in let c1 = fastener c 1 and c2 = fastener c 2 in match fusion with | F13 -> printf "%s_ff(%s,%s,%s,%s,%s)" f c1 c2 wf1 wf2 p12 | F31 -> printf "%s_ff(%s,%s,%s,%s,-(%s))" f c1 c2 wf1 wf2 p12 | F23 -> printf "f_%sf(%s,%s,%s,%s,%s)" f c1 c2 wf1 wf2 p1 | F32 -> printf "f_%sf(%s,%s,%s,%s,%s)" f c1 c2 wf2 wf1 p2 | F12 -> printf "f_%sf(%s,%s,%s,%s,-(%s))" f c1 c2 wf2 wf1 p2 | F21 -> printf "f_%sf(%s,%s,%s,%s,-(%s))" f c1 c2 wf1 wf2 p1 let print_fermion_current_mom_sign_1 coeff f c wf1 wf2 p1 p2 p12 fusion = let c = format_coupling coeff c in match fusion with | F13 -> printf "%s_ff(%s,%s,%s,%s)" f c wf1 wf2 p12 | F31 -> printf "%s_ff(%s,%s,%s,-(%s))" f c wf1 wf2 p12 | F23 -> printf "f_%sf(%s,%s,%s,%s)" f c wf1 wf2 p1 | F32 -> printf "f_%sf(%s,%s,%s,%s)" f c wf2 wf1 p2 | F12 -> printf "f_%sf(%s,%s,%s,-(%s))" f c wf2 wf1 p2 | F21 -> printf "f_%sf(%s,%s,%s,-(%s))" f c wf1 wf2 p1 let print_fermion_current_mom_chiral coeff f c wf1 wf2 p1 p2 p12 fusion = let c = format_coupling_mom coeff c and cf = commute_proj f in let c1 = fastener c 1 and c2 = fastener c 2 in match fusion with | F13 -> printf "%s_ff(%s,%s,%s,%s,%s)" f c1 c2 wf1 wf2 p12 | F31 -> printf "%s_ff(%s,%s,%s, %s,-(%s))" cf c1 c2 wf1 wf2 p12 | F23 -> printf "f_%sf(%s,%s,%s,%s,%s)" f c1 c2 wf1 wf2 p1 | F32 -> printf "f_%sf(%s,%s,%s,%s,%s)" f c1 c2 wf2 wf1 p2 | F12 -> printf "f_%sf(%s,%s,%s,%s,-(%s))" cf c1 c2 wf2 wf1 p2 | F21 -> printf "f_%sf(%s,%s,%s,%s,-(%s))" cf c1 c2 wf1 wf2 p1 let print_fermion_g_current coeff f c wf1 wf2 p1 p2 p12 fusion = let c = format_coupling coeff c in match fusion with | F13 -> printf "%s_grf(%s,%s,%s,%s)" f c wf1 wf2 p12 | F31 -> printf "%s_fgr(%s,%s,%s,%s)" f c wf1 wf2 p12 | F23 -> printf "gr_%sf(%s,%s,%s,%s)" f c wf1 wf2 p1 | F32 -> printf "gr_%sf(%s,%s,%s,%s)" f c wf2 wf1 p2 | F12 -> printf "f_%sgr(%s,%s,%s,%s)" f c wf2 wf1 p2 | F21 -> printf "f_%sgr(%s,%s,%s,%s)" f c wf1 wf2 p1 let print_fermion_g_2_current coeff f c wf1 wf2 p1 p2 p12 fusion = let c = format_coupling coeff c in match fusion with | F13 -> printf "%s_grf(%s(1),%s(2),%s,%s,%s)" f c c wf1 wf2 p12 | F31 -> printf "%s_fgr(%s(1),%s(2),%s,%s,%s)" f c c wf1 wf2 p12 | F23 -> printf "gr_%sf(%s(1),%s(2),%s,%s,%s)" f c c wf1 wf2 p1 | F32 -> printf "gr_%sf(%s(1),%s(2),%s,%s,%s)" f c c wf2 wf1 p2 | F12 -> printf "f_%sgr(%s(1),%s(2),%s,%s,%s)" f c c wf2 wf1 p2 | F21 -> printf "f_%sgr(%s(1),%s(2),%s,%s,%s)" f c c wf1 wf2 p1 let print_fermion_g_current_rev coeff f c wf1 wf2 p1 p2 p12 fusion = let c = format_coupling coeff c in match fusion with | F13 -> printf "%s_fgr(%s,%s,%s,%s)" f c wf1 wf2 p12 | F31 -> printf "%s_grf(%s,%s,%s,%s)" f c wf1 wf2 p12 | F23 -> printf "f_%sgr(%s,%s,%s,%s)" f c wf1 wf2 p1 | F32 -> printf "f_%sgr(%s,%s,%s,%s)" f c wf2 wf1 p2 | F12 -> printf "gr_%sf(%s,%s,%s,%s)" f c wf2 wf1 p2 | F21 -> printf "gr_%sf(%s,%s,%s,%s)" f c wf1 wf2 p1 let print_fermion_g_2_current_rev coeff f c wf1 wf2 p1 p2 p12 fusion = let c = format_coupling coeff c in match fusion with | F13 -> printf "%s_fgr(%s(1),%s(2),%s,%s,%s)" f c c wf1 wf2 p12 | F31 -> printf "%s_grf(%s(1),%s(2),%s,%s,%s)" f c c wf1 wf2 p12 | F23 -> printf "f_%sgr(%s(1),%s(2),%s,%s,%s)" f c c wf1 wf2 p1 | F32 -> printf "f_%sgr(%s(1),%s(2),%s,%s,%s)" f c c wf2 wf1 p2 | F12 -> printf "gr_%sf(%s(1),%s(2),%s,%s,%s)" f c c wf2 wf1 p2 | F21 -> printf "gr_%sf(%s(1),%s(2),%s,%s,%s)" f c c wf1 wf2 p1 let print_fermion_g_current_vector coeff f c wf1 wf2 _ _ _ fusion = let c = format_coupling coeff c in match fusion with | F13 -> printf "%s_grf(%s,%s,%s)" f c wf1 wf2 | F31 -> printf "%s_fgr(-%s,%s,%s)" f c wf1 wf2 | F23 -> printf "gr_%sf(%s,%s,%s)" f c wf1 wf2 | F32 -> printf "gr_%sf(%s,%s,%s)" f c wf2 wf1 | F12 -> printf "f_%sgr(-%s,%s,%s)" f c wf2 wf1 | F21 -> printf "f_%sgr(-%s,%s,%s)" f c wf1 wf2 let print_fermion_g_current_vector_rev coeff f c wf1 wf2 _ _ _ fusion = let c = format_coupling coeff c in match fusion with | F13 -> printf "%s_fgr(%s,%s,%s)" f c wf1 wf2 | F31 -> printf "%s_grf(-%s,%s,%s)" f c wf1 wf2 | F23 -> printf "f_%sgr(%s,%s,%s)" f c wf1 wf2 | F32 -> printf "f_%sgr(%s,%s,%s)" f c wf2 wf1 | F12 -> printf "gr_%sf(-%s,%s,%s)" f c wf2 wf1 | F21 -> printf "gr_%sf(-%s,%s,%s)" f c wf1 wf2 let print_current_g = function | coeff, _, MOM, _ -> print_fermion_current_mom_sign coeff "mom" | coeff, _, MOM5, _ -> print_fermion_current_mom coeff "mom5" | coeff, _, MOML, _ -> print_fermion_current_mom_chiral coeff "moml" | coeff, _, MOMR, _ -> print_fermion_current_mom_chiral coeff "momr" | coeff, _, LMOM, _ -> print_fermion_current_mom_chiral coeff "lmom" | coeff, _, RMOM, _ -> print_fermion_current_mom_chiral coeff "rmom" | coeff, _, VMOM, _ -> print_fermion_current_mom_sign_1 coeff "vmom" | coeff, Gravbar, S, _ -> print_fermion_g_current coeff "s" | coeff, Gravbar, SL, _ -> print_fermion_g_current coeff "sl" | coeff, Gravbar, SR, _ -> print_fermion_g_current coeff "sr" | coeff, Gravbar, SLR, _ -> print_fermion_g_2_current coeff "slr" | coeff, Gravbar, P, _ -> print_fermion_g_current coeff "p" | coeff, Gravbar, V, _ -> print_fermion_g_current coeff "v" | coeff, Gravbar, VLR, _ -> print_fermion_g_2_current coeff "vlr" | coeff, Gravbar, POT, _ -> print_fermion_g_current_vector coeff "pot" | coeff, _, S, Grav -> print_fermion_g_current_rev coeff "s" | coeff, _, SL, Grav -> print_fermion_g_current_rev coeff "sl" | coeff, _, SR, Grav -> print_fermion_g_current_rev coeff "sr" | coeff, _, SLR, Grav -> print_fermion_g_2_current_rev coeff "slr" | coeff, _, P, Grav -> print_fermion_g_current_rev (-coeff) "p" | coeff, _, V, Grav -> print_fermion_g_current_rev coeff "v" | coeff, _, VLR, Grav -> print_fermion_g_2_current_rev coeff "vlr" | coeff, _, POT, Grav -> print_fermion_g_current_vector_rev coeff "pot" | _, _, _, _ -> invalid_arg "Targets.Fortran_Majorana_Fermions: not used in the models" let print_current_mom = function | coeff, _, TVA, _ -> print_fermion_current_mom_v1 coeff "tva" | coeff, _, TVAM, _ -> print_fermion_current_mom_v2 coeff "tvam" | coeff, _, TLR, _ -> print_fermion_current_mom_v1_chiral coeff "tlr" | coeff, _, TLRM, _ -> print_fermion_current_mom_v2_chiral coeff "tlrm" | _, _, _, _ -> invalid_arg "Targets.Fortran_Majorana_Fermions: Not needed in the models" (* We need support for dimension-5 vertices with two fermions and two bosons, appearing in theories of supergravity and also together with in insertions of the supersymmetric current. There is a canonical order [fermionbar], [boson_1], [boson_2], [fermion], so what one has to do is a mapping from the fusions [F123] etc. to the order of the three wave functions [wf1], [wf2] and [wf3]. *) (* The function [d_p] (for distinct the particle) distinguishes which particle (scalar or vector) must be fused to in the special functions. *) let d_p = function | 1, ("sv"|"pv"|"svl"|"svr"|"slrv") -> "1" | 1, _ -> "" | 2, ("sv"|"pv"|"svl"|"svr"|"slrv") -> "2" | 2, _ -> "" | _, _ -> invalid_arg "Targets.Fortran_Majorana_Fermions: not used" let wf_of_f wf1 wf2 wf3 f = match f with | (F123|F423) -> [wf2; wf3; wf1] | (F213|F243|F143|F142|F413|F412) -> [wf1; wf3; wf2] | (F132|F432) -> [wf3; wf2; wf1] | (F231|F234|F134|F124|F431|F421) -> [wf1; wf2; wf3] | (F312|F342) -> [wf3; wf1; wf2] | (F321|F324|F314|F214|F341|F241) -> [wf2; wf1; wf3] let print_fermion_g4_brs_vector_current coeff f c wf1 wf2 wf3 fusion = let cf = commute_proj f and cp = format_coupling coeff c and cm = if f = "pv" then format_coupling coeff c else format_coupling (-coeff) c and d1 = d_p (1,f) and d2 = d_p (2,f) and f1 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 0) and f2 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 1) and f3 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 2) in match fusion with | (F123|F213|F132|F231|F312|F321) -> printf "f_%sf(%s,%s,%s,%s)" cf cm f1 f2 f3 | (F423|F243|F432|F234|F342|F324) -> printf "f_%sf(%s,%s,%s,%s)" f cp f1 f2 f3 | (F134|F143|F314) -> printf "%s%s_ff(%s,%s,%s,%s)" f d1 cp f1 f2 f3 | (F124|F142|F214) -> printf "%s%s_ff(%s,%s,%s,%s)" f d2 cp f1 f2 f3 | (F413|F431|F341) -> printf "%s%s_ff(%s,%s,%s,%s)" cf d1 cm f1 f2 f3 | (F241|F412|F421) -> printf "%s%s_ff(%s,%s,%s,%s)" cf d2 cm f1 f2 f3 let print_fermion_g4_svlr_current coeff _ c wf1 wf2 wf3 fusion = let c = format_coupling_2 coeff c and f1 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 0) and f2 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 1) and f3 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 2) in let c1 = fastener c 1 and c2 = fastener c 2 in match fusion with | (F123|F213|F132|F231|F312|F321) -> printf "f_svlrf(-(%s),-(%s),%s,%s,%s)" c2 c1 f1 f2 f3 | (F423|F243|F432|F234|F342|F324) -> printf "f_svlrf(%s,%s,%s,%s,%s)" c1 c2 f1 f2 f3 | (F134|F143|F314) -> printf "svlr2_ff(%s,%s,%s,%s,%s)" c1 c2 f1 f2 f3 | (F124|F142|F214) -> printf "svlr1_ff(%s,%s,%s,%s,%s)" c1 c2 f1 f2 f3 | (F413|F431|F341) -> printf "svlr2_ff(-(%s),-(%s),%s,%s,%s)" c2 c1 f1 f2 f3 | (F241|F412|F421) -> printf "svlr1_ff(-(%s),-(%s),%s,%s,%s)" c2 c1 f1 f2 f3 let print_fermion_s2_current coeff f c wf1 wf2 wf3 fusion = let cp = format_coupling coeff c and cm = if f = "p" then format_coupling (-coeff) c else format_coupling coeff c and cf = commute_proj f and f1 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 0) and f2 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 1) and f3 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 2) in match fusion with | (F123|F213|F132|F231|F312|F321) -> printf "%s * f_%sf(%s,%s,%s)" f1 cf cm f2 f3 | (F423|F243|F432|F234|F342|F324) -> printf "%s * f_%sf(%s,%s,%s)" f1 f cp f2 f3 | (F134|F143|F314) -> printf "%s * %s_ff(%s,%s,%s)" f2 f cp f1 f3 | (F124|F142|F214) -> printf "%s * %s_ff(%s,%s,%s)" f2 f cp f1 f3 | (F413|F431|F341) -> printf "%s * %s_ff(%s,%s,%s)" f2 cf cm f1 f3 | (F241|F412|F421) -> printf "%s * %s_ff(%s,%s,%s)" f2 cf cm f1 f3 let print_fermion_s2p_current coeff f c wf1 wf2 wf3 fusion = let c = format_coupling_2 coeff c and f1 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 0) and f2 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 1) and f3 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 2) in let c1 = fastener c 1 and c2 = fastener c 2 in match fusion with | (F123|F213|F132|F231|F312|F321) -> printf "%s * f_%sf(%s,-(%s),%s,%s)" f1 f c1 c2 f2 f3 | (F423|F243|F432|F234|F342|F324) -> printf "%s * f_%sf(%s,%s,%s,%s)" f1 f c1 c2 f2 f3 | (F134|F143|F314) -> printf "%s * %s_ff(%s,%s,%s,%s)" f2 f c1 c2 f1 f3 | (F124|F142|F214) -> printf "%s * %s_ff(%s,%s,%s,%s)" f2 f c1 c2 f1 f3 | (F413|F431|F341) -> printf "%s * %s_ff(%s,-(%s),%s,%s)" f2 f c1 c2 f1 f3 | (F241|F412|F421) -> printf "%s * %s_ff(%s,-(%s),%s,%s)" f2 f c1 c2 f1 f3 let print_fermion_s2lr_current coeff f c wf1 wf2 wf3 fusion = let c = format_coupling_2 coeff c and f1 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 0) and f2 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 1) and f3 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 2) in let c1 = fastener c 1 and c2 = fastener c 2 in match fusion with | (F123|F213|F132|F231|F312|F321) -> printf "%s * f_%sf(%s,%s,%s,%s)" f1 f c2 c1 f2 f3 | (F423|F243|F432|F234|F342|F324) -> printf "%s * f_%sf(%s,%s,%s,%s)" f1 f c1 c2 f2 f3 | (F134|F143|F314) -> printf "%s * %s_ff(%s,%s,%s,%s)" f2 f c1 c2 f1 f3 | (F124|F142|F214) -> printf "%s * %s_ff(%s,%s,%s,%s)" f2 f c1 c2 f1 f3 | (F413|F431|F341) -> printf "%s * %s_ff(%s,%s,%s,%s)" f2 f c2 c1 f1 f3 | (F241|F412|F421) -> printf "%s * %s_ff(%s,%s,%s,%s)" f2 f c2 c1 f1 f3 let print_fermion_g4_current coeff f c wf1 wf2 wf3 fusion = let c = format_coupling coeff c and f1 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 0) and f2 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 1) and f3 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 2) in match fusion with | (F123|F213|F132|F231|F312|F321) -> printf "f_%sgr(-%s,%s,%s,%s)" f c f1 f2 f3 | (F423|F243|F432|F234|F342|F324) -> printf "gr_%sf(%s,%s,%s,%s)" f c f1 f2 f3 | (F134|F143|F314|F124|F142|F214) -> printf "%s_grf(%s,%s,%s,%s)" f c f1 f2 f3 | (F413|F431|F341|F241|F412|F421) -> printf "%s_fgr(-%s,%s,%s,%s)" f c f1 f2 f3 (*i unused value let print_fermion_2_g4_current coeff f c wf1 wf2 wf3 fusion = let f1 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 0) and f2 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 1) and f3 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 2) in let c = format_coupling_2 coeff c in let c1 = fastener c 1 and c2 = fastener c 2 in match fusion with | (F123|F213|F132|F231|F312|F321) -> printf "f_%sgr(-(%s),-(%s),%s,%s,%s)" f c2 c1 f1 f2 f3 | (F423|F243|F432|F234|F342|F324) -> printf "gr_%sf(%s,%s,%s,%s,%s)" f c1 c2 f1 f2 f3 | (F134|F143|F314|F124|F142|F214) -> printf "%s_grf(%s,%s,%s,%s,%s)" f c1 c2 f1 f2 f3 | (F413|F431|F341|F241|F412|F421) -> printf "%s_fgr(-(%s),-(%s),%s,%s,%s)" f c2 c1 f1 f2 f3 i*) let print_fermion_2_g4_current coeff f c wf1 wf2 wf3 fusion = let f1 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 0) and f2 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 1) and f3 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 2) in let c = format_coupling_2 coeff c in let c1 = fastener c 1 and c2 = fastener c 2 in match fusion with | (F123|F213|F132|F231|F312|F321) -> printf "f_%sgr(-(%s),-(%s),%s,%s,%s)" f c2 c1 f1 f2 f3 | (F423|F243|F432|F234|F342|F324) -> printf "gr_%sf(%s,%s,%s,%s,%s)" f c1 c2 f1 f2 f3 | (F134|F143|F314|F124|F142|F214) -> printf "%s_grf(%s,%s,%s,%s,%s)" f c1 c2 f1 f2 f3 | (F413|F431|F341|F241|F412|F421) -> printf "%s_fgr(-(%s),-(%s),%s,%s,%s)" f c2 c1 f1 f2 f3 let print_fermion_g4_current_rev coeff f c wf1 wf2 wf3 fusion = let c = format_coupling coeff c and f1 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 0) and f2 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 1) and f3 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 2) in match fusion with | (F123|F213|F132|F231|F312|F321) -> printf "f_%sgr(%s,%s,%s,%s)" f c f1 f2 f3 | (F423|F243|F432|F234|F342|F324) -> printf "gr_%sf(-%s,%s,%s,%s)" f c f1 f2 f3 | (F134|F143|F314|F124|F142|F214) -> printf "%s_grf(-%s,%s,%s,%s)" f c f1 f2 f3 | (F413|F431|F341|F241|F412|F421) -> printf "%s_fgr(%s,%s,%s,%s)" f c f1 f2 f3 (* Here we have to distinguish which of the two bosons is produced in the fusion of three particles which include both fermions. *) let print_fermion_g4_vector_current coeff f c wf1 wf2 wf3 fusion = let c = format_coupling coeff c and d1 = d_p (1,f) and d2 = d_p (2,f) and f1 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 0) and f2 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 1) and f3 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 2) in match fusion with | (F123|F213|F132|F231|F312|F321) -> printf "f_%sgr(%s,%s,%s,%s)" f c f1 f2 f3 | (F423|F243|F432|F234|F342|F324) -> printf "gr_%sf(%s,%s,%s,%s)" f c f1 f2 f3 | (F134|F143|F314) -> printf "%s%s_grf(%s,%s,%s,%s)" f d1 c f1 f2 f3 | (F124|F142|F214) -> printf "%s%s_grf(%s,%s,%s,%s)" f d2 c f1 f2 f3 | (F413|F431|F341) -> printf "%s%s_fgr(%s,%s,%s,%s)" f d1 c f1 f2 f3 | (F241|F412|F421) -> printf "%s%s_fgr(%s,%s,%s,%s)" f d2 c f1 f2 f3 let print_fermion_2_g4_vector_current coeff f c wf1 wf2 wf3 fusion = let d1 = d_p (1,f) and d2 = d_p (2,f) and f1 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 0) and f2 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 1) and f3 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 2) in let c = format_coupling_2 coeff c in let c1 = fastener c 1 and c2 = fastener c 2 in match fusion with | (F123|F213|F132|F231|F312|F321) -> printf "f_%sgr(%s,%s,%s,%s,%s)" f c1 c2 f1 f2 f3 | (F423|F243|F432|F234|F342|F324) -> printf "gr_%sf(%s,%s,%s,%s,%s)" f c1 c2 f1 f2 f3 | (F134|F143|F314) -> printf "%s%s_grf(%s,%s,%s,%s,%s)" f d1 c1 c2 f1 f2 f3 | (F124|F142|F214) -> printf "%s%s_grf(%s,%s,%s,%s,%s)" f d2 c1 c2 f1 f2 f3 | (F413|F431|F341) -> printf "%s%s_fgr(%s,%s,%s,%s,%s)" f d1 c1 c2 f1 f2 f3 | (F241|F412|F421) -> printf "%s%s_fgr(%s,%s,%s,%s,%s)" f d2 c1 c2 f1 f2 f3 let print_fermion_g4_vector_current_rev coeff f c wf1 wf2 wf3 fusion = let c = format_coupling coeff c and d1 = d_p (1,f) and d2 = d_p (2,f) and f1 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 0) and f2 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 1) and f3 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 2) in match fusion with | (F123|F213|F132|F231|F312|F321) -> printf "gr_%sf(%s,%s,%s,%s)" f c f1 f2 f3 | (F423|F243|F432|F234|F342|F324) -> printf "f_%sgr(%s,%s,%s,%s)" f c f1 f2 f3 | (F134|F143|F314) -> printf "%s%s_fgr(%s,%s,%s,%s)" f d1 c f1 f2 f3 | (F124|F142|F214) -> printf "%s%s_fgr(%s,%s,%s,%s)" f d2 c f1 f2 f3 | (F413|F431|F341) -> printf "%s%s_grf(%s,%s,%s,%s)" f d1 c f1 f2 f3 | (F241|F412|F421) -> printf "%s%s_grf(%s,%s,%s,%s)" f d2 c f1 f2 f3 let print_fermion_2_g4_current_rev coeff f c wf1 wf2 wf3 fusion = let c = format_coupling_2 coeff c in let c1 = fastener c 1 and c2 = fastener c 2 and d1 = d_p (1,f) and d2 = d_p (2,f) in let f1 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 0) and f2 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 1) and f3 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 2) in match fusion with | (F123|F213|F132|F231|F312|F321) -> printf "gr_%sf(%s,%s,%s,%s,%s)" f c1 c2 f1 f2 f3 | (F423|F243|F432|F234|F342|F324) -> printf "f_%sgr(-(%s),-(%s),%s,%s,%s)" f c1 c2 f1 f2 f3 | (F134|F143|F314) -> printf "%s%s_fgr(-(%s),-(%s),%s,%s,%s)" f d1 c1 c2 f1 f2 f3 | (F124|F142|F214) -> printf "%s%s_fgr(-(%s),-(%s),%s,%s,%s)" f d2 c1 c2 f1 f2 f3 | (F413|F431|F341) -> printf "%s%s_grf(%s,%s,%s,%s,%s)" f d1 c1 c2 f1 f2 f3 | (F241|F412|F421) -> printf "%s%s_grf(%s,%s,%s,%s,%s)" f d2 c1 c2 f1 f2 f3 let print_fermion_2_g4_vector_current_rev coeff f c wf1 wf2 wf3 fusion = (* Here we put in the extra minus sign from the coeff. *) let c = format_coupling coeff c in let c1 = fastener c 1 and c2 = fastener c 2 in let d1 = d_p (1,f) and d2 = d_p (2,f) and f1 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 0) and f2 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 1) and f3 = (List.nth (wf_of_f wf1 wf2 wf3 fusion) 2) in match fusion with | (F123|F213|F132|F231|F312|F321) -> printf "gr_%sf(%s,%s,%s,%s,%s)" f c1 c2 f1 f2 f3 | (F423|F243|F432|F234|F342|F324) -> printf "f_%sgr(%s,%s,%s,%s,%s)" f c1 c2 f1 f2 f3 | (F134|F143|F314) -> printf "%s%s_fgr(%s,%s,%s,%s,%s)" f d1 c1 c2 f1 f2 f3 | (F124|F142|F214) -> printf "%s%s_fgr(%s,%s,%s,%s,%s)" f d2 c1 c2 f1 f2 f3 | (F413|F431|F341) -> printf "%s%s_grf(%s,%s,%s,%s,%s)" f d1 c1 c2 f1 f2 f3 | (F241|F412|F421) -> printf "%s%s_grf(%s,%s,%s,%s,%s)" f d2 c1 c2 f1 f2 f3 let print_current_g4 = function | coeff, Gravbar, S2, _ -> print_fermion_g4_current coeff "s2" | coeff, Gravbar, SV, _ -> print_fermion_g4_vector_current coeff "sv" | coeff, Gravbar, SLV, _ -> print_fermion_g4_vector_current coeff "slv" | coeff, Gravbar, SRV, _ -> print_fermion_g4_vector_current coeff "srv" | coeff, Gravbar, SLRV, _ -> print_fermion_2_g4_vector_current coeff "slrv" | coeff, Gravbar, PV, _ -> print_fermion_g4_vector_current coeff "pv" | coeff, Gravbar, V2, _ -> print_fermion_g4_current coeff "v2" | coeff, Gravbar, V2LR, _ -> print_fermion_2_g4_current coeff "v2lr" | _, Gravbar, _, _ -> invalid_arg "print_current_g4: not implemented" | coeff, _, S2, Grav -> print_fermion_g4_current_rev coeff "s2" | coeff, _, SV, Grav -> print_fermion_g4_vector_current_rev (-coeff) "sv" | coeff, _, SLV, Grav -> print_fermion_g4_vector_current_rev (-coeff) "slv" | coeff, _, SRV, Grav -> print_fermion_g4_vector_current_rev (-coeff) "srv" | coeff, _, SLRV, Grav -> print_fermion_2_g4_vector_current_rev coeff "slrv" | coeff, _, PV, Grav -> print_fermion_g4_vector_current_rev coeff "pv" | coeff, _, V2, Grav -> print_fermion_g4_vector_current_rev coeff "v2" | coeff, _, V2LR, Grav -> print_fermion_2_g4_current_rev coeff "v2lr" | _, _, _, Grav -> invalid_arg "print_current_g4: not implemented" | coeff, _, S2, _ -> print_fermion_s2_current coeff "s" | coeff, _, P2, _ -> print_fermion_s2_current coeff "p" | coeff, _, S2P, _ -> print_fermion_s2p_current coeff "sp" | coeff, _, S2L, _ -> print_fermion_s2_current coeff "sl" | coeff, _, S2R, _ -> print_fermion_s2_current coeff "sr" | coeff, _, S2LR, _ -> print_fermion_s2lr_current coeff "slr" | coeff, _, V2, _ -> print_fermion_g4_brs_vector_current coeff "v2" | coeff, _, SV, _ -> print_fermion_g4_brs_vector_current coeff "sv" | coeff, _, PV, _ -> print_fermion_g4_brs_vector_current coeff "pv" | coeff, _, SLV, _ -> print_fermion_g4_brs_vector_current coeff "svl" | coeff, _, SRV, _ -> print_fermion_g4_brs_vector_current coeff "svr" | coeff, _, SLRV, _ -> print_fermion_g4_svlr_current coeff "svlr" | _, _, V2LR, _ -> invalid_arg "Targets.print_current: not available" let reverse_braket _ = false let use_module = "omega95_bispinors" let require_library = ["omega_bispinors_2010_01_A"; "omega_bispinor_cpls_2010_01_A"] end module Fortran_Majorana = Make_Fortran(Fortran_Majorana_Fermions) (* \thocwmodulesubsection{\texttt{FORTRAN\,77}} *) module Fortran77 = Dummy (* \thocwmodulesection{\texttt{C}} *) module C = Dummy (* \thocwmodulesubsection{\texttt{C++}} *) module Cpp = Dummy (* \thocwmodulesubsection{Java} *) module Java = Dummy (* \thocwmodulesection{O'Caml} *) module Ocaml = Dummy (* \thocwmodulesection{\LaTeX} *) module LaTeX = Dummy Index: trunk/omega/src/modellib_Zprime.ml =================================================================== --- trunk/omega/src/modellib_Zprime.ml (revision 8413) +++ trunk/omega/src/modellib_Zprime.ml (revision 8414) @@ -1,628 +1,630 @@ (* modellib_Zprime.ml -- Copyright (C) 1999-2020 by Wolfgang Kilian Thorsten Ohl Juergen Reuter with contributions from Christian Speckner WHIZARD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. WHIZARD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *) (* \thocwmodulesection{SM with additional Z'} *) module type SM_flags = sig val include_anomalous : bool val k_matrix : bool end module SM_no_anomalous : SM_flags = struct let include_anomalous = false let k_matrix = false end module Zprime (Flags : SM_flags) = struct open Coupling let default_width = ref Timelike let use_fudged_width = ref false let options = Options.create [ "constant_width", Arg.Unit (fun () -> default_width := Constant), "use constant width (also in t-channel)"; "fudged_width", Arg.Set use_fudged_width, "use fudge factor for charge particle width"; "custom_width", Arg.String (fun f -> default_width := Custom f), "use custom width"; "cancel_widths", Arg.Unit (fun () -> default_width := Vanishing), - "use vanishing width" ] + "use vanishing width"; + "running_width", Arg.Unit (fun () -> default_width := Running), + "use running width" ] (* We do not introduce the Goldstones for the heavy vectors here. *) type matter_field = L of int | N of int | U of int | D of int type gauge_boson = Ga | Wp | Wm | Z | Gl | ZH type other = Phip | Phim | Phi0 | H type flavor = M of matter_field | G of gauge_boson | O of other let matter_field f = M f let gauge_boson f = G f let other f = O f type field = | Matter of matter_field | Gauge of gauge_boson | Other of other let field = function | M f -> Matter f | G f -> Gauge f | O f -> Other f type gauge = unit let gauge_symbol () = failwith "Models.Zprime.gauge_symbol: internal error" let family n = List.map matter_field [ L n; N n; U n; D n ] let external_flavors () = [ "1st Generation", ThoList.flatmap family [1; -1]; "2nd Generation", ThoList.flatmap family [2; -2]; "3rd Generation", ThoList.flatmap family [3; -3]; "Gauge Bosons", List.map gauge_boson [Ga; Z; Wp; Wm; Gl; ZH]; "Higgs", [O H]; "Goldstone Bosons", List.map other [Phip; Phim; Phi0] ] let flavors () = ThoList.flatmap snd (external_flavors ()) let spinor n = if n >= 0 then Spinor else ConjSpinor let lorentz = function | M f -> begin match f with | L n -> spinor n | N n -> spinor n | U n -> spinor n | D n -> spinor n end | G f -> begin match f with | Ga | Gl -> Vector | Wp | Wm | Z | ZH -> Massive_Vector end | O f -> Scalar let color = function | M (U n) -> Color.SUN (if n > 0 then 3 else -3) | M (D n) -> Color.SUN (if n > 0 then 3 else -3) | G Gl -> Color.AdjSUN 3 | _ -> Color.Singlet let nc () = 3 let prop_spinor n = if n >= 0 then Prop_Spinor else Prop_ConjSpinor let propagator = function | M f -> begin match f with | L n -> prop_spinor n | N n -> prop_spinor n | U n -> prop_spinor n | D n -> prop_spinor n end | G f -> begin match f with | Ga | Gl -> Prop_Feynman | Wp | Wm | Z | ZH -> Prop_Unitarity end | O f -> begin match f with | Phip | Phim | Phi0 -> Only_Insertion | H -> Prop_Scalar end (* Optionally, ask for the fudge factor treatment for the widths of charged particles. Currently, this only applies to $W^\pm$ and top. *) let width f = if !use_fudged_width then match f with | G Wp | G Wm | M (U 3) | M (U (-3)) | _ -> !default_width else !default_width let goldstone = function | G f -> begin match f with | Wp -> Some (O Phip, Coupling.Integer 1) | Wm -> Some (O Phim, Coupling.Integer 1) | Z -> Some (O Phi0, Coupling.Integer 1) | _ -> None end | _ -> None let conjugate = function | M f -> M (begin match f with | L n -> L (-n) | N n -> N (-n) | U n -> U (-n) | D n -> D (-n) end) | G f -> G (begin match f with | Gl -> Gl | Ga -> Ga | Z -> Z | Wp -> Wm | Wm -> Wp | ZH -> ZH end) | O f -> O (begin match f with | Phip -> Phim | Phim -> Phip | Phi0 -> Phi0 | H -> H end) let fermion = function | M f -> begin match f with | L n -> if n > 0 then 1 else -1 | N n -> if n > 0 then 1 else -1 | U n -> if n > 0 then 1 else -1 | D n -> if n > 0 then 1 else -1 end | G f -> begin match f with | Gl | Ga | Z | Wp | Wm | ZH -> 0 end | O _ -> 0 (* Electrical charge, lepton number, baryon number. We could avoid the rationals altogether by multiplying the first and last by 3 \ldots *) module Ch = Charges.QQ let ( // ) = Algebra.Small_Rational.make let generation' = function | 1 -> [ 1//1; 0//1; 0//1] | 2 -> [ 0//1; 1//1; 0//1] | 3 -> [ 0//1; 0//1; 1//1] | -1 -> [-1//1; 0//1; 0//1] | -2 -> [ 0//1; -1//1; 0//1] | -3 -> [ 0//1; 0//1; -1//1] | n -> invalid_arg ("Zprime.generation': " ^ string_of_int n) let generation f = match f with | M (L n | N n | U n | D n) -> generation' n | G _ | O _ -> [0//1; 0//1; 0//1] let charge = function | M f -> begin match f with | L n -> if n > 0 then -1//1 else 1//1 | N n -> 0//1 | U n -> if n > 0 then 2//3 else -2//3 | D n -> if n > 0 then -1//3 else 1//3 end | G f -> begin match f with | Gl | Ga | Z | ZH -> 0//1 | Wp -> 1//1 | Wm -> -1//1 end | O f -> begin match f with | H | Phi0 -> 0//1 | Phip -> 1//1 | Phim -> -1//1 end let lepton = function | M f -> begin match f with | L n | N n -> if n > 0 then 1//1 else -1//1 | U _ | D _ -> 0//1 end | G _ | O _ -> 0//1 let baryon = function | M f -> begin match f with | L _ | N _ -> 0//1 | U n | D n -> if n > 0 then 1//1 else -1//1 end | G _ | O _ -> 0//1 let charges f = [ charge f; lepton f; baryon f] @ generation f type constant = | Unit | Pi | Alpha_QED | Sin2thw | Sinthw | Costhw | E | G_weak | Vev | Q_lepton | Q_up | Q_down | G_CC | G_NC_neutrino | G_NC_lepton | G_NC_up | G_NC_down | G_NC_h_neutrino | G_NC_h_lepton | G_NC_h_up | G_NC_h_down | I_Q_W | I_G_ZWW | I_G_WWW | G_WWWW | G_ZZWW | G_AZWW | G_AAWW | G_HWW | G_HHWW | G_HZZ | G_HHZZ | G_Htt | G_Hbb | G_Hcc | G_Htautau | G_H3 | G_H4 | Gs | I_Gs | G2 | Mass of flavor | Width of flavor (* Two integer counters for the QCD and EW order of the couplings. *) type orders = int * int let orders = function | _ -> (0,0) let input_parameters = [] let derived_parameters = [] let g_over_2_costh = Quot (Neg (Atom G_weak), Prod [Integer 2; Atom Costhw]) let nc_coupling c t3 q = (Real_Array c, [Prod [g_over_2_costh; Diff (t3, Prod [Integer 2; q; Atom Sin2thw])]; Prod [g_over_2_costh; t3]]) let half = Quot (Integer 1, Integer 2) let derived_parameter_arrays = [ nc_coupling G_NC_neutrino half (Integer 0); nc_coupling G_NC_lepton (Neg half) (Integer (-1)); nc_coupling G_NC_up half (Quot (Integer 2, Integer 3)); nc_coupling G_NC_down (Neg half) (Quot (Integer (-1), Integer 3)); nc_coupling G_NC_h_neutrino half (Integer 0); nc_coupling G_NC_h_lepton (Neg half) (Integer (-1)); nc_coupling G_NC_h_up half (Quot (Integer 2, Integer 3)); nc_coupling G_NC_h_down (Neg half) (Quot (Integer (-1), Integer 3)) ] let parameters () = { input = input_parameters; derived = derived_parameters; derived_arrays = derived_parameter_arrays } module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) (* \begin{equation} \mathcal{L}_{\textrm{EM}} = - e \sum_i q_i \bar\psi_i\fmslash{A}\psi_i \end{equation} *) let mgm ((m1, g, m2), fbf, c) = ((M m1, G g, M m2), fbf, c) let mom ((m1, o, m2), fbf, c) = ((M m1, O o, M m2), fbf, c) let electromagnetic_currents n = List.map mgm [ ((L (-n), Ga, L n), FBF (1, Psibar, V, Psi), Q_lepton); ((U (-n), Ga, U n), FBF (1, Psibar, V, Psi), Q_up); ((D (-n), Ga, D n), FBF (1, Psibar, V, Psi), Q_down) ] let color_currents n = List.map mgm [ ((U (-n), Gl, U n), FBF (1, Psibar, V, Psi), Gs); ((D (-n), Gl, D n), FBF (1, Psibar, V, Psi), Gs) ] (* \begin{equation} \mathcal{L}_{\textrm{NC}} = - \frac{g}{2\cos\theta_W} \sum_i \bar\psi_i\fmslash{Z}(g_V^i-g_A^i\gamma_5)\psi_i \end{equation} *) let neutral_currents n = List.map mgm [ ((L (-n), Z, L n), FBF (1, Psibar, VA, Psi), G_NC_lepton); ((N (-n), Z, N n), FBF (1, Psibar, VA, Psi), G_NC_neutrino); ((U (-n), Z, U n), FBF (1, Psibar, VA, Psi), G_NC_up); ((D (-n), Z, D n), FBF (1, Psibar, VA, Psi), G_NC_down) ] (* We want to allow for (almost) completely general couplings but maintain universality (generation independence). Maybe we should also separate the coupling to the top quark since the third generation is somewhat special. *) let neutral_heavy_currents n = List.map mgm [ ((L (-n), ZH, L n), FBF (1, Psibar, VA, Psi), G_NC_h_lepton); ((N (-n), ZH, N n), FBF (1, Psibar, VA, Psi), G_NC_h_neutrino); ((U (-n), ZH, U n), FBF (1, Psibar, VA, Psi), G_NC_h_up); ((D (-n), ZH, D n), FBF (1, Psibar, VA, Psi), G_NC_h_down); ] (* \begin{equation} \mathcal{L}_{\textrm{CC}} = - \frac{g}{2\sqrt2} \sum_i \bar\psi_i (T^+\fmslash{W}^+ + T^-\fmslash{W}^-)(1-\gamma_5)\psi_i \end{equation} *) let charged_currents n = List.map mgm [ ((L (-n), Wm, N n), FBF (1, Psibar, VL, Psi), G_CC); ((N (-n), Wp, L n), FBF (1, Psibar, VL, Psi), G_CC); ((D (-n), Wm, U n), FBF (1, Psibar, VL, Psi), G_CC); ((U (-n), Wp, D n), FBF (1, Psibar, VL, Psi), G_CC) ] let yukawa = [ ((M (U (-3)), O H, M (U 3)), FBF (1, Psibar, S, Psi), G_Htt); ((M (D (-3)), O H, M (D 3)), FBF (1, Psibar, S, Psi), G_Hbb); ((M (U (-2)), O H, M (U 2)), FBF (1, Psibar, S, Psi), G_Hcc); ((M (L (-3)), O H, M (L 3)), FBF (1, Psibar, S, Psi), G_Htautau) ] (* \begin{equation} \mathcal{L}_{\textrm{TGC}} = - e \partial_\mu A_\nu W_+^\mu W_-^\nu + \ldots - e \cot\theta_w \partial_\mu Z_\nu W_+^\mu W_-^\nu + \ldots \end{equation} *) let tgc ((g1, g2, g3), t, c) = ((G g1, G g2, G g3), t, c) let triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW); ((Gl, Gl, Gl), Gauge_Gauge_Gauge 1, I_Gs)] let qgc ((g1, g2, g3, g4), t, c) = ((G g1, G g2, G g3, G g4), t, c) let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] let quartic_gauge = List.map qgc [ (Wm, Wp, Wm, Wp), gauge4, G_WWWW; (Wm, Z, Wp, Z), minus_gauge4, G_ZZWW; (Wm, Z, Wp, Ga), minus_gauge4, G_AZWW; (Wm, Ga, Wp, Ga), minus_gauge4, G_AAWW; (Gl, Gl, Gl, Gl), gauge4, G2 ] let gauge_higgs = [ ((O H, G Wp, G Wm), Scalar_Vector_Vector 1, G_HWW); ((O H, G Z, G Z), Scalar_Vector_Vector 1, G_HZZ) ] let gauge_higgs4 = [ (O H, O H, G Wp, G Wm), Scalar2_Vector2 1, G_HHWW; (O H, O H, G Z, G Z), Scalar2_Vector2 1, G_HHZZ ] let higgs = [ (O H, O H, O H), Scalar_Scalar_Scalar 1, G_H3 ] let higgs4 = [ (O H, O H, O H, O H), Scalar4 1, G_H4 ] let goldstone_vertices = [ ((O Phi0, G Wm, G Wp), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phip, G Ga, G Wm), Scalar_Vector_Vector 1, I_Q_W); ((O Phip, G Z, G Wm), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phim, G Wp, G Ga), Scalar_Vector_Vector 1, I_Q_W); ((O Phim, G Wp, G Z), Scalar_Vector_Vector 1, I_G_ZWW) ] let vertices3 = (ThoList.flatmap electromagnetic_currents [1;2;3] @ ThoList.flatmap color_currents [1;2;3] @ ThoList.flatmap neutral_currents [1;2;3] @ ThoList.flatmap neutral_heavy_currents [1;2;3] @ ThoList.flatmap charged_currents [1;2;3] @ yukawa @ triple_gauge @ gauge_higgs @ higgs @ goldstone_vertices) let vertices4 = quartic_gauge @ gauge_higgs4 @ higgs4 let vertices () = (vertices3, vertices4, []) (* For efficiency, make sure that [F.of_vertices vertices] is evaluated only once. *) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 let flavor_of_string = function | "e-" -> M (L 1) | "e+" -> M (L (-1)) | "mu-" -> M (L 2) | "mu+" -> M (L (-2)) | "tau-" -> M (L 3) | "tau+" -> M (L (-3)) | "nue" -> M (N 1) | "nuebar" -> M (N (-1)) | "numu" -> M (N 2) | "numubar" -> M (N (-2)) | "nutau" -> M (N 3) | "nutaubar" -> M (N (-3)) | "u" -> M (U 1) | "ubar" -> M (U (-1)) | "c" -> M (U 2) | "cbar" -> M (U (-2)) | "t" -> M (U 3) | "tbar" -> M (U (-3)) | "d" -> M (D 1) | "dbar" -> M (D (-1)) | "s" -> M (D 2) | "sbar" -> M (D (-2)) | "b" -> M (D 3) | "bbar" -> M (D (-3)) | "g" | "gl" -> G Gl | "A" -> G Ga | "Z" | "Z0" -> G Z | "ZH" | "ZH0" | "Zh" | "Zh0" -> G ZH | "W+" -> G Wp | "W-" -> G Wm | "H" -> O H | _ -> invalid_arg "Models.Zprime.flavor_of_string" let flavor_to_string = function | M f -> begin match f with | L 1 -> "e-" | L (-1) -> "e+" | L 2 -> "mu-" | L (-2) -> "mu+" | L 3 -> "tau-" | L (-3) -> "tau+" | L _ -> invalid_arg "Models.Zprime.flavor_to_string: invalid lepton" | N 1 -> "nue" | N (-1) -> "nuebar" | N 2 -> "numu" | N (-2) -> "numubar" | N 3 -> "nutau" | N (-3) -> "nutaubar" | N _ -> invalid_arg "Models.Zprime.flavor_to_string: invalid neutrino" | U 1 -> "u" | U (-1) -> "ubar" | U 2 -> "c" | U (-2) -> "cbar" | U 3 -> "t" | U (-3) -> "tbar" | U _ -> invalid_arg "Models.Zprime.flavor_to_string: invalid up type quark" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | D _ -> invalid_arg "Models.Zprime.flavor_to_string: invalid down type quark" end | G f -> begin match f with | Gl -> "g" | Ga -> "A" | Z -> "Z" | Wp -> "W+" | Wm -> "W-" | ZH -> "ZH" end | O f -> begin match f with | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | H -> "H" end let flavor_to_TeX = function | M f -> begin match f with | L 1 -> "e^-" | L (-1) -> "e^+" | L 2 -> "\\mu-" | L (-2) -> "\\mu^+" | L 3 -> "\\tau^-" | L (-3) -> "\\tau^+" | L _ -> invalid_arg "Models.Zprime.flavor_to_TeX: invalid lepton" | N 1 -> "\\nu_e" | N (-1) -> "\\bar{\\nu}_e" | N 2 -> "\\nu_\\mu" | N (-2) -> "\\bar{\\nu}_\\mu" | N 3 -> "\\nu_\\tau" | N (-3) -> "\\bar{\\nu}_\\tau" | N _ -> invalid_arg "Models.Zprime.flavor_to_TeX: invalid neutrino" | U 1 -> "u" | U (-1) -> "\\bar{u}" | U 2 -> "c" | U (-2) -> "\\bar{c}" | U 3 -> "t" | U (-3) -> "\\bar{t}" | U _ -> invalid_arg "Models.Zprime.flavor_to_TeX: invalid up type quark" | D 1 -> "d" | D (-1) -> "\\bar{d}" | D 2 -> "s" | D (-2) -> "\\bar{s}" | D 3 -> "b" | D (-3) -> "\\bar{b}" | D _ -> invalid_arg "Models.Zprime.flavor_to_TeX: invalid down type quark" end | G f -> begin match f with | Gl -> "g" | Ga -> "\\gamma" | Z -> "Z" | Wp -> "W^+" | Wm -> "W^-" | ZH -> "Z_H" end | O f -> begin match f with | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | H -> "H" end let flavor_symbol = function | M f -> begin match f with | L n when n > 0 -> "l" ^ string_of_int n | L n -> "l" ^ string_of_int (abs n) ^ "b" | N n when n > 0 -> "n" ^ string_of_int n | N n -> "n" ^ string_of_int (abs n) ^ "b" | U n when n > 0 -> "u" ^ string_of_int n | U n -> "u" ^ string_of_int (abs n) ^ "b" | D n when n > 0 -> "d" ^ string_of_int n | D n -> "d" ^ string_of_int (abs n) ^ "b" end | G f -> begin match f with | Gl -> "gl" | Ga -> "a" | Z -> "z" | Wp -> "wp" | Wm -> "wm" | ZH -> "zh" end | O f -> begin match f with | Phip -> "pp" | Phim -> "pm" | Phi0 -> "p0" | H -> "h" end (* There are PDG numbers for Z', Z'', W', 32-34, respectively. We just introduce a number 38 for Y0 as a Z'''. As well, there is the number 8 for a t'. *) let pdg = function | M f -> begin match f with | L n when n > 0 -> 9 + 2*n | L n -> - 9 + 2*n | N n when n > 0 -> 10 + 2*n | N n -> - 10 + 2*n | U n when n > 0 -> 2*n | U n -> 2*n | D n when n > 0 -> - 1 + 2*n | D n -> 1 + 2*n end | G f -> begin match f with | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) | ZH -> 32 end | O f -> begin match f with | Phip | Phim -> 27 | Phi0 -> 26 | H -> 25 end let mass_symbol f = "mass(" ^ string_of_int (abs (pdg f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg f)) ^ ")" let constant_symbol = function | Unit -> "unit" | Pi -> "PI" | Alpha_QED -> "alpha" | E -> "e" | G_weak -> "g" | Vev -> "vev" | Sin2thw -> "sin2thw" | Sinthw -> "sinthw" | Costhw -> "costhw" | Q_lepton -> "qlep" | Q_up -> "qup" | Q_down -> "qdwn" | G_NC_lepton -> "gnclep" | G_NC_neutrino -> "gncneu" | G_NC_up -> "gncup" | G_NC_down -> "gncdwn" | G_CC -> "gcc" | G_NC_h_lepton -> "gnchlep" | G_NC_h_neutrino -> "gnchneu" | G_NC_h_up -> "gnchup" | G_NC_h_down -> "gnchdwn" | I_Q_W -> "iqw" | I_G_ZWW -> "igzww" | I_G_WWW -> "igwww" | G_WWWW -> "gw4" | G_ZZWW -> "gzzww" | G_AZWW -> "gazww" | G_AAWW -> "gaaww" | G_HWW -> "ghww" | G_HZZ -> "ghzz" | G_HHWW -> "ghhww" | G_HHZZ -> "ghhzz" | G_Htt -> "ghtt" | G_Hbb -> "ghbb" | G_Htautau -> "ghtautau" | G_Hcc -> "ghcc" | G_H3 -> "gh3" | G_H4 -> "gh4" | Gs -> "gs" | I_Gs -> "igs" | G2 -> "gs**2" | Mass f -> "mass" ^ flavor_symbol f | Width f -> "width" ^ flavor_symbol f end Index: trunk/omega/src/modellib_MSSM.ml =================================================================== --- trunk/omega/src/modellib_MSSM.ml (revision 8413) +++ trunk/omega/src/modellib_MSSM.ml (revision 8414) @@ -1,2646 +1,2648 @@ (* modellib_MSSM.ml -- Copyright (C) 1999-2020 by Wolfgang Kilian Thorsten Ohl Juergen Reuter with contributions from Christian Speckner WHIZARD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. WHIZARD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *) (* modellib_MSSM.ml -- *) (* \thocwmodulesection{Minimal Supersymmetric Standard Model} *) module type MSSM_flags = sig val include_goldstone : bool val include_four : bool val ckm_present : bool val gravitino : bool val higgs_triangle : bool end module MSSM_no_goldstone : MSSM_flags = struct let include_goldstone = false let include_four = true let ckm_present = false let gravitino = false let higgs_triangle = false end module MSSM_goldstone : MSSM_flags = struct let include_goldstone = true let include_four = true let ckm_present = false let gravitino = false let higgs_triangle = false end module MSSM_no_4 : MSSM_flags = struct let include_goldstone = false let include_four = false let ckm_present = false let gravitino = false let higgs_triangle = false end module MSSM_no_4_ckm : MSSM_flags = struct let include_goldstone = false let include_four = false let ckm_present = true let gravitino = false let higgs_triangle = false end module MSSM_Grav : MSSM_flags = struct let include_goldstone = false let include_four = false let ckm_present = false let gravitino = true let higgs_triangle = false end module MSSM_Hgg : MSSM_flags = struct let include_goldstone = false let include_four = false let ckm_present = false let gravitino = false let higgs_triangle = true end module MSSM (Flags : MSSM_flags) = struct open Coupling let default_width = ref Timelike let use_fudged_width = ref false let options = Options.create [ "constant_width", Arg.Unit (fun () -> default_width := Constant), "use constant width (also in t-channel)"; "fudged_width", Arg.Set use_fudged_width, "use fudge factor for charge particle width"; "custom_width", Arg.String (fun f -> default_width := Custom f), "use custom width"; "cancel_widths", Arg.Unit (fun () -> default_width := Vanishing), "use vanishing width"; "cms_width", Arg.Unit (fun () -> default_width := Complex_Mass), - "use complex mass scheme"] + "use complex mass scheme"; + "running_width", Arg.Unit (fun () -> default_width := Running), + "use running width"] type gen = | G of int | GG of gen*gen let rec string_of_gen = function | G n when n > 0 -> string_of_int n | G n -> string_of_int (abs n) ^ "c" | GG (g1,g2) -> string_of_gen g1 ^ "_" ^ string_of_gen g2 (* With this we distinguish the flavour. *) type sff = | SL | SN | SU | SD let string_of_sff = function | SL -> "sl" | SN -> "sn" | SU -> "su" | SD -> "sd" (* With this we distinguish the mass eigenstates. At the moment we have to cheat a little bit for the sneutrinos. Because we are dealing with massless neutrinos there is only one sort of sneutrino. *) type sfm = | M1 | M2 let string_of_sfm = function | M1 -> "1" | M2 -> "2" (* We also introduce special types for the charginos and neutralinos. *) type char = | C1 | C2 | C1c | C2c type neu = | N1 | N2 | N3 | N4 let int_of_char = function | C1 -> 1 | C2 -> 2 | C1c -> -1 | C2c -> -2 let string_of_char = function | C1 -> "1" | C2 -> "2" | C1c -> "-1" | C2c -> "-2" let conj_char = function | C1 -> C1c | C2 -> C2c | C1c -> C1 | C2c -> C2 let string_of_neu = function | N1 -> "1" | N2 -> "2" | N3 -> "3" | N4 -> "4" (* Also we need types to distinguish the Higgs bosons. We follow the conventions of Kuroda, which means \begin{align} \label{eq:higgs3} H_1 &= \begin{pmatrix} \frac{1}{\sqrt{2}} \bigl( v_1 + H^0 \cos\alpha - h^0 \sin\alpha + \ii A^0 \sin\beta - \ii \phi^0 \cos\beta \bigr) \\ H^- \sin\beta - \phi^- \cos\beta \end{pmatrix}, \\ & \notag \\ H_2 & = \begin{pmatrix} H^+ \cos\beta + \phi^+ \sin\beta \\ \frac{1}{\sqrt{2}} \bigl( v_2 + H^0 \sin\alpha + h^0 \cos\alpha + \ii A^0 \cos\beta + \ii \phi^0 \sin\beta \bigr) \end{pmatrix} \label{eq:higgs4} \end{align} This is a different sign convention compared to, e.g., Weinberg's volume iii. We will refer to it as [GS+]. *) type higgs = | H1 (* the light scalar Higgs *) | H2 (* the heavy scalar Higgs *) | H3 (* the pseudoscalar Higgs *) | H4 (* the charged Higgs *) | H5 (* the neutral Goldstone boson *) | H6 (* the charged Goldstone boson *) | DH of higgs*higgs let rec string_of_higgs = function | H1 -> "h1" | H2 -> "h2" | H3 -> "h3" | H4 -> "h4" | H5 -> "p1" | H6 -> "p2" | DH (h1,h2) -> string_of_higgs h1 ^ string_of_higgs h2 type flavor = | L of int | N of int | U of int | D of int | Sup of sfm*int | Sdown of sfm*int | Ga | Wp | Wm | Z | Gl | Slepton of sfm*int | Sneutrino of int | Neutralino of neu | Chargino of char | Gluino | Grino | Phip | Phim | Phi0 | H_Heavy | H_Light | Hp | Hm | A type gauge = unit let gauge_symbol () = failwith "Modellib_MSSM.MSSM.gauge_symbol: internal error" (* At this point we will forget graviton and -tino. *) let lep_family g = [ L g; N g; Slepton (M1,g); Slepton (M2,g); Sneutrino g ] let family g = [ L g; N g; Slepton (M1,g); Slepton (M2,g); Sneutrino g; U g; D g; Sup (M1,g); Sup (M2,g); Sdown (M1,g); Sdown (M2,g)] let external_flavors'' = [ "1st Generation", ThoList.flatmap family [1; -1]; "2nd Generation", ThoList.flatmap family [2; -2]; "3rd Generation", ThoList.flatmap family [3; -3]; "Gauge Bosons", [Ga; Z; Wp; Wm; Gl]; "Charginos", [Chargino C1; Chargino C2; Chargino C1c; Chargino C2c]; "Neutralinos", [Neutralino N1; Neutralino N2; Neutralino N3; Neutralino N4]; "Higgs Bosons", [H_Heavy; H_Light; Hp; Hm; A]; "Gluinos", [Gluino]] let external_flavors' = if Flags.gravitino then external_flavors'' @ ["Gravitino", [Grino]] else external_flavors'' let external_flavors () = if Flags.include_goldstone then external_flavors' @ ["Goldstone Bosons", [Phip; Phim; Phi0]] else external_flavors' let flavors () = ThoList.flatmap snd (external_flavors ()) let spinor n = if n >= 0 then Spinor else if n <= 0 then ConjSpinor else invalid_arg "Modellib_MSSM.MSSM.spinor: internal error" let lorentz = function | L g -> spinor g | N g -> spinor g | U g -> spinor g | D g -> spinor g | Chargino c -> spinor (int_of_char c) | Ga -> Vector (*i | Ga -> Ward_Vector i*) | Gl -> Vector | Wp | Wm | Z -> Massive_Vector | H_Heavy | H_Light | Hp | Hm | A -> Scalar | Phip | Phim | Phi0 -> Scalar | Sup _ | Sdown _ | Slepton _ | Sneutrino _ -> Scalar | Neutralino _ -> Majorana | Gluino -> Majorana | Grino -> Vectorspinor let color = function | U g -> Color.SUN (if g > 0 then 3 else -3) | Sup (m,g) -> Color.SUN (if g > 0 then 3 else -3) | D g -> Color.SUN (if g > 0 then 3 else -3) | Sdown (m,g) -> Color.SUN (if g > 0 then 3 else -3) | Gl | Gluino -> Color.AdjSUN 3 | _ -> Color.Singlet let nc () = 3 let prop_spinor n = if n >= 0 then Prop_Spinor else if n <=0 then Prop_ConjSpinor else invalid_arg "Modellib_MSSM.MSSM.prop_spinor: internal error" let propagator = function | L g -> prop_spinor g | N g -> prop_spinor g | U g -> prop_spinor g | D g -> prop_spinor g | Chargino c -> prop_spinor (int_of_char c) | Ga | Gl -> Prop_Feynman | Wp | Wm | Z -> Prop_Unitarity | H_Heavy | H_Light | Hp | Hm | A -> Prop_Scalar | Phip | Phim | Phi0 -> if Flags.include_goldstone then Prop_Scalar else Only_Insertion | Slepton _ | Sneutrino _ | Sup _ | Sdown _ -> Prop_Scalar | Gluino -> Prop_Majorana | Neutralino _ -> Prop_Majorana | Grino -> Only_Insertion (* Note, that we define the gravitino only as an insertion since when using propagators we are effectively going to a higher order in the gravitational coupling. This would enforce us to also include higher-dimensional vertices with two gravitinos for a consistent power counting in $1/M_{\text{Planck}}$. *) (*i | Grino -> Prop_Vectorspinor i*) (* Optionally, ask for the fudge factor treatment for the widths of charged particles. Currently, this only applies to $W^\pm$ and top. *) let width f = if !use_fudged_width then match f with | Wp | Wm | U 3 | U (-3) -> Fudged | _ -> !default_width else !default_width (* For the Goldstone bosons we adopt the conventions of the Kuroda paper. \begin{subequations} \begin{equation} H_1 \equiv \begin{pmatrix} \left( v_1 + H^0 \cos\alpha - h^0 \sin \alpha + \ii A^0 \sin\beta - \ii \cos\beta \phi^0 \right) / \sqrt{2} \\ H^- \sin\beta - \phi^- \cos\beta \end{pmatrix} \end{equation} \begin{equation} H_2 \equiv \begin{pmatrix} H^+ \cos\beta + \phi^+ \sin\beta \\ \left( v_2 + H^0 \sin\alpha + h^0 \cos\alpha + \ii A^0 \cos\beta + \ii \phi^0 \sin\beta \right) / \sqrt{2} \end{pmatrix} \end{equation} \end{subequations} *) let goldstone = function | Wp -> Some (Phip, Coupling.Integer 1) | Wm -> Some (Phim, Coupling.Integer 1) | Z -> Some (Phi0, Coupling.Integer 1) | _ -> None let conjugate = function | L g -> L (-g) | N g -> N (-g) | U g -> U (-g) | D g -> D (-g) | Sup (m,g) -> Sup (m,-g) | Sdown (m,g) -> Sdown (m,-g) | Slepton (m,g) -> Slepton (m,-g) | Sneutrino g -> Sneutrino (-g) | Gl -> Gl (* | Gl0 -> Gl0 *) | Ga -> Ga | Z -> Z | Wp -> Wm | Wm -> Wp | H_Heavy -> H_Heavy | H_Light -> H_Light | A -> A | Hp -> Hm | Hm -> Hp | Phip -> Phim | Phim -> Phip | Phi0 -> Phi0 | Gluino -> Gluino | Grino -> Grino | Neutralino n -> Neutralino n | Chargino c -> Chargino (conj_char c) let fermion = function | L g -> if g > 0 then 1 else -1 | N g -> if g > 0 then 1 else -1 | U g -> if g > 0 then 1 else -1 | D g -> if g > 0 then 1 else -1 | Gl | Ga | Z | Wp | Wm -> 0 (* | Gl0 -> 0 *) | H_Heavy | H_Light | Hp | Hm | A -> 0 | Phip | Phim | Phi0 -> 0 | Neutralino _ -> 2 | Chargino c -> if (int_of_char c) > 0 then 1 else -1 | Sup _ -> 0 | Sdown _ -> 0 | Slepton _ -> 0 | Sneutrino _ -> 0 | Gluino | Grino -> 2 (* Because the O'Caml compiler only allows 248 constructors we must divide the constants into subgroups of constants, e.g. for the Higgs couplings. In the MSSM there are a lot of angles among the parameters, the Weinberg-angle, the angle describing the Higgs vacuum structure, the mixing angle of the real parts of the Higgs dubletts, the mixing angles of the sfermions. Therefore we are going to define the trigonometric functions of those angles not as constants but as functors of the angels. Sums and differences of angles are only used as arguments for the $\alpha$ and $\beta$ angles, so it makes no sense to define special functions for differences and sums of angles. *) type angle = | Thw | Al | Be | Th_SF of sff*int | Delta | CKM_12 | CKM_13 | CKM_23 let string_of_angle = function | Thw -> "thw" | Al -> "al" | Be -> "be" | Delta -> "d" | CKM_12 -> "ckm12" | CKM_13 -> "ckm13" | CKM_23 -> "ckm23" | Th_SF (f,g) -> "th" ^ string_of_sff f ^ string_of_int g (* We introduce a Boolean type vc as a pseudonym for Vertex Conjugator to distinguish between vertices containing complex mixing matrices like the CKM--matrix or the sfermion or neutralino/chargino--mixing matrices, which have to become complex conjugated. The true--option stands for the conjugated vertex, the false--option for the unconjugated vertex. *) type vc = bool type constant = | Unit | Pi | Alpha_QED | Sin2thw | Sin of angle | Cos of angle | E | G | Vev | Tanb | Tana | Cos2be | Cos2al | Sin2be | Sin2al | Sin4al | Sin4be | Cos4be | Cosapb | Cosamb | Sinapb | Sinamb | Cos2am2b | Sin2am2b | Eidelta | Mu | AU of int | AD of int | AL of int | V_CKM of int*int | M_SF of sff*int*sfm*sfm | M_V of char*char (* left chargino mixing matrix *) | M_U of char*char (* right chargino mixing matrix *) | M_N of neu*neu (* neutralino mixing matrix *) | V_0 of neu*neu | A_0 of neu*neu | V_P of char*char | A_P of char*char | L_CN of char*neu | R_CN of char*neu | L_NC of neu*char | R_NC of neu*char (*i | L_NF of neu*sff*sfm | R_NF of neu*sff*sfm i*) | S_NNH1 of neu*neu | P_NNH1 of neu*neu | S_NNH2 of neu*neu | P_NNH2 of neu*neu | S_NNA of neu*neu | P_NNA of neu*neu | S_NNG of neu*neu | P_NNG of neu*neu | L_CNG of char*neu | R_CNG of char*neu | L_NCH of neu*char | R_NCH of neu*char | Q_lepton | Q_up | Q_down | Q_charg | G_Z | G_CC | G_CCQ of vc*int*int | G_NC_neutrino | G_NC_lepton | G_NC_up | G_NC_down | I_Q_W | I_G_ZWW | G_WWWW | G_ZZWW | G_PZWW | G_PPWW | G_strong | G_SS | I_G_S | G_S_Sqrt | Gs | M of flavor | W of flavor | G_NZN of neu*neu | G_CZC of char*char | G_NNA | G_YUK of int*int | G_YUK_1 of int*int | G_YUK_2 of int*int | G_YUK_3 of int*int | G_YUK_4 of int*int | G_NHC of neu*char | G_CHN of char*neu | G_YUK_C of vc*int*char*sff*sfm | G_YUK_Q of vc*int*int*char*sff*sfm | G_YUK_N of vc*int*neu*sff*sfm | G_YUK_G of vc*int*sff*sfm | G_NGC of neu*char | G_CGN of char*neu | SUM_1 | G_NWC of neu*char | G_CWN of char*neu | G_CH1C of char*char | G_CH2C of char*char | G_CAC of char*char | G_CGC of char*char | G_SWS of vc*int*int*sfm*sfm | G_SLSNW of vc*int*sfm | G_ZSF of sff*int*sfm*sfm | G_CICIH1 of neu*neu | G_CICIH2 of neu*neu | G_CICIA of neu*neu | G_CICIG of neu*neu | G_GH of int | G_GHGo of int | G_GLGLH | G_GLGLHH | G_GLGLA | G_PPH | G_PPHH | G_PPA | G_WWSFSF of sff*int*sfm*sfm | G_WPSLSN of vc*int*sfm | G_H3 of int | G_H4 of int | G_HGo3 of int | G_HGo4 of int | G_GG4 of int | G_H1SFSF of sff*int*sfm*sfm | G_H2SFSF of sff*int*sfm*sfm | G_ASFSF of sff*int*sfm*sfm | G_HSNSL of vc*int*sfm | G_GoSFSF of sff*int*sfm*sfm | G_GoSNSL of vc*int*sfm | G_HSUSD of vc*sfm*sfm*int*int | G_GSUSD of vc*sfm*sfm*int*int | G_WPSUSD of vc*sfm*sfm*int*int | G_WZSUSD of vc*sfm*sfm*int*int | G_WZSLSN of vc*int*sfm | G_GlGlSQSQ | G_PPSFSF of sff | G_ZZSFSF of sff*int*sfm*sfm | G_ZPSFSF of sff*int*sfm*sfm | G_GlZSFSF of sff*int*sfm*sfm | G_GlPSQSQ | G_GlWSUSD of vc*sfm*sfm*int*int | G_GH4 of int | G_GHGo4 of int | G_H1H2SFSF of sff*sfm*sfm*int | G_H1H1SFSF of sff*sfm*sfm*int | G_H2H2SFSF of sff*sfm*sfm*int | G_HHSFSF of sff*sfm*sfm*int | G_AASFSF of sff*sfm*sfm*int | G_HH1SLSN of vc*sfm*int | G_HH2SLSN of vc*sfm*int | G_HASLSN of vc*sfm*int | G_HH1SUSD of vc*sfm*sfm*int*int | G_HH2SUSD of vc*sfm*sfm*int*int | G_HASUSD of vc*sfm*sfm*int*int | G_AG0SFSF of sff*sfm*sfm*int | G_HGSFSF of sff*sfm*sfm*int | G_GGSFSF of sff*sfm*sfm*int | G_G0G0SFSF of sff*sfm*sfm*int | G_HGSNSL of vc*sfm*int | G_H1GSNSL of vc*sfm*int | G_H2GSNSL of vc*sfm*int | G_AGSNSL of vc*sfm*int | G_GGSNSL of vc*sfm*int | G_HGSUSD of vc*sfm*sfm*int*int | G_H1GSUSD of vc*sfm*sfm*int*int | G_H2GSUSD of vc*sfm*sfm*int*int | G_AGSUSD of vc*sfm*sfm*int*int | G_GGSUSD of vc*sfm*sfm*int*int | G_SN4 of int*int | G_SN2SL2_1 of sfm*sfm*int*int | G_SN2SL2_2 of sfm*sfm*int*int | G_SF4 of sff*sff*sfm*sfm*sfm*sfm*int*int | G_SF4_3 of sff*sff*sfm*sfm*sfm*sfm*int*int*int | G_SF4_4 of sff*sff*sfm*sfm*sfm*sfm*int*int*int*int | G_SL4 of sfm*sfm*sfm*sfm*int | G_SL4_2 of sfm*sfm*sfm*sfm*int*int | G_SN2SQ2 of sff*sfm*sfm*int*int | G_SL2SQ2 of sff*sfm*sfm*sfm*sfm*int*int | G_SUSDSNSL of vc*sfm*sfm*sfm*int*int*int | G_SU4 of sfm*sfm*sfm*sfm*int | G_SU4_2 of sfm*sfm*sfm*sfm*int*int | G_SD4 of sfm*sfm*sfm*sfm*int | G_SD4_2 of sfm*sfm*sfm*sfm*int*int | G_SU2SD2 of sfm*sfm*sfm*sfm*int*int*int*int | G_HSF31 of higgs*int*sfm*sfm*sff*sff | G_HSF32 of higgs*int*int*sfm*sfm*sff*sff | G_HSF41 of higgs*int*sfm*sfm*sff*sff | G_HSF42 of higgs*int*int*sfm*sfm*sff*sff | G_Grav | G_Gr_Ch of char | G_Gr_Z_Neu of neu | G_Gr_A_Neu of neu | G_Gr4_Neu of neu | G_Gr4_A_Ch of char | G_Gr4_Z_Ch of char | G_Grav_N | G_Grav_U of int*sfm | G_Grav_D of int*sfm | G_Grav_L of int*sfm | G_Grav_Uc of int*sfm | G_Grav_Dc of int*sfm | G_Grav_Lc of int*sfm | G_GravGl | G_Gr_H_Ch of char | G_Gr_H1_Neu of neu | G_Gr_H2_Neu of neu | G_Gr_H3_Neu of neu | G_Gr4A_Sl of int*sfm | G_Gr4A_Slc of int*sfm | G_Gr4A_Su of int*sfm | G_Gr4A_Suc of int*sfm | G_Gr4A_Sd of int*sfm | G_Gr4A_Sdc of int*sfm | G_Gr4Z_Sn | G_Gr4Z_Snc | G_Gr4Z_Sl of int*sfm | G_Gr4Z_Slc of int*sfm | G_Gr4Z_Su of int*sfm | G_Gr4Z_Suc of int*sfm | G_Gr4Z_Sd of int*sfm | G_Gr4Z_Sdc of int*sfm | G_Gr4W_Sl of int*sfm | G_Gr4W_Slc of int*sfm | G_Gr4W_Su of int*sfm | G_Gr4W_Suc of int*sfm | G_Gr4W_Sd of int*sfm | G_Gr4W_Sdc of int*sfm | G_Gr4W_Sn | G_Gr4W_Snc | G_Gr4Gl_Su of int*sfm | G_Gr4Gl_Suc of int*sfm | G_Gr4Gl_Sd of int*sfm | G_Gr4Gl_Sdc of int*sfm | G_Gr4_Z_H1 of neu | G_Gr4_Z_H2 of neu | G_Gr4_Z_H3 of neu | G_Gr4_W_H of neu | G_Gr4_W_Hc of neu | G_Gr4_H_A of char | G_Gr4_H_Z of char (* Two integer counters for the QCD and EW order of the couplings. *) type orders = int * int let orders = function | _ -> (0,0) let ferm_of_sff = function | SL, g -> (L g) | SN, g -> (N g) | SU, g -> (U g) | SD, g -> (D g) (* \begin{subequations} \begin{align} \alpha_{\text{QED}} &= \frac{1}{137.0359895} \\ \sin^2\theta_w &= 0.23124 \end{align} \end{subequations} Here we must perhaps allow for complex input parameters. So split them into their modulus and their phase. At first, we leave them real; the generalization to complex parameters is obvious. *) module Ch = Charges.QQ let ( // ) = Algebra.Small_Rational.make let generation' = function | 1 -> [ 1//1; 0//1; 0//1] | 2 -> [ 0//1; 1//1; 0//1] | 3 -> [ 0//1; 0//1; 1//1] | -1 -> [-1//1; 0//1; 0//1] | -2 -> [ 0//1; -1//1; 0//1] | -3 -> [ 0//1; 0//1; -1//1] | n -> invalid_arg ("MSSM.generation': " ^ string_of_int n) let generation f = if Flags.ckm_present then [] else match f with | L n | N n | U n | D n | Sup (_,n) | Sdown (_,n) | Slepton (_,n) | Sneutrino n -> generation' n | _ -> [0//1; 0//1; 0//1] let charge = function | L n -> if n > 0 then -1//1 else 1//1 | Slepton (_,n) -> if n > 0 then -1//1 else 1//1 | N n -> 0//1 | Sneutrino n -> 0//1 | U n -> if n > 0 then 2//3 else -2//3 | Sup (_,n) -> if n > 0 then 2//3 else -2//3 | D n -> if n > 0 then -1//3 else 1//3 | Sdown (_,n) -> if n > 0 then -1//3 else 1//3 | Gl | Ga | Z | Neutralino _ | Gluino -> 0//1 | Wp -> 1//1 | Wm -> -1//1 | H_Heavy | H_Light | Phi0 -> 0//1 | Hp | Phip -> 1//1 | Hm | Phim -> -1//1 | Chargino (C1 | C2) -> 1//1 | Chargino (C1c | C2c) -> -1//1 | _ -> 0//1 let lepton = function | L n | N n -> if n > 0 then 1//1 else -1//1 | Slepton (_,n) | Sneutrino n -> if n > 0 then 1//1 else -1//1 | _ -> 0//1 let baryon = function | U n | D n -> if n > 0 then 1//1 else -1//1 | Sup (_,n) | Sdown (_,n) -> if n > 0 then 1//1 else -1//1 | _ -> 0//1 let charges f = [ charge f; lepton f; baryon f] @ generation f let parameters () = { input = []; derived = []; derived_arrays = [] } module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) (* For the couplings there are generally two possibilities concerning the sign of the covariant derivative. \begin{equation} {\rm CD}^\pm = \partial_\mu \pm \ii g T^a A^a_\mu \end{equation} The particle data group defines the signs consistently to be positive. Since the convention for that signs also influence the phase definitions of the gaugino/higgsino fields via the off-diagonal entries in their mass matrices it would be the best to adopt that convention. *) (*** REVISED: Compatible with CD+. ***) let electromagnetic_currents_3 g = [((U (-g), Ga, U g), FBF (1, Psibar, V, Psi), Q_up); ((D (-g), Ga, D g), FBF (1, Psibar, V, Psi), Q_down); ((L (-g), Ga, L g), FBF (1, Psibar, V, Psi), Q_lepton) ] (*** REVISED: Compatible with CD+. ***) let electromagnetic_sfermion_currents g m = [ ((Ga, Slepton (m,-g), Slepton (m,g)), Vector_Scalar_Scalar 1, Q_lepton); ((Ga, Sup (m,-g), Sup (m,g)), Vector_Scalar_Scalar 1, Q_up); ((Ga, Sdown (m,-g), Sdown (m,g)), Vector_Scalar_Scalar 1, Q_down) ] (*** REVISED: Compatible with CD+. ***) let electromagnetic_currents_2 c = let cc = conj_char c in [ ((Chargino cc, Ga, Chargino c), FBF (1, Psibar, V, Psi), Q_charg) ] (*** REVISED: Compatible with CD+. ***) let neutral_currents g = [ ((L (-g), Z, L g), FBF (1, Psibar, VA, Psi), G_NC_lepton); ((N (-g), Z, N g), FBF (1, Psibar, VA, Psi), G_NC_neutrino); ((U (-g), Z, U g), FBF (1, Psibar, VA, Psi), G_NC_up); ((D (-g), Z, D g), FBF (1, Psibar, VA, Psi), G_NC_down) ] (* \begin{equation} \mathcal{L}_{\textrm{CC}} = \mp \frac{g}{2\sqrt2} \sum_i \bar\psi_i \gamma^\mu (1-\gamma_5)(T^+W^+_\mu+T^-W^-_\mu)\psi_i , \end{equation} where the sign corresponds to $\text{CD}_\pm$, respectively. *) (*** REVISED: Compatible with CD+. ***) (* Remark: The definition with the other sign compared to the SM files comes from the fact that $g_{cc} = 1/(2\sqrt{2})$ is used overwhelmingly often in the SUSY Feynman rules, so that JR decided to use a different definiton for [g_cc] in SM and MSSM. *) let charged_currents g = [ ((L (-g), Wm, N g), FBF ((-1), Psibar, VL, Psi), G_CC); ((N (-g), Wp, L g), FBF ((-1), Psibar, VL, Psi), G_CC) ] (* The quark with the inverted generation (the antiparticle) is the outgoing one, the other the incoming. The vertex attached to the outgoing up-quark contains the CKM matrix element {\em not} complex conjugated, while the vertex with the outgoing down-quark has the conjugated CKM matrix element. *) (*** REVISED: Compatible with CD+. ***) let charged_quark_currents g h = [ ((D (-g), Wm, U h), FBF ((-1), Psibar, VL, Psi), G_CCQ (true,g,h)); ((U (-g), Wp, D h), FBF ((-1), Psibar, VL, Psi), G_CCQ (false,h,g))] (*** REVISED: Compatible with CD+. ***) let charged_chargino_currents n c = let cc = conj_char c in [ ((Chargino cc, Wp, Neutralino n), FBF (1, Psibar, VLR, Chi), G_CWN (c,n)); ((Neutralino n, Wm, Chargino c), FBF (1, Chibar, VLR, Psi), G_NWC (n,c)) ] (*** REVISED: Compatible with CD+. ***) let charged_slepton_currents g m = [ ((Wm, Slepton (m,-g), Sneutrino g), Vector_Scalar_Scalar (-1), G_SLSNW (true,g,m)); ((Wp, Slepton (m,g), Sneutrino (-g)), Vector_Scalar_Scalar 1, G_SLSNW (false,g,m)) ] (*** REVISED: Compatible with CD+. ***) let charged_squark_currents' g h m1 m2 = [ ((Wm, Sup (m1,g), Sdown (m2,-h)), Vector_Scalar_Scalar (-1), G_SWS (true,g,h,m1,m2)); ((Wp, Sup (m1,-g), Sdown (m2,h)), Vector_Scalar_Scalar 1, G_SWS (false,g,h,m1,m2)) ] let charged_squark_currents g h = List.flatten (Product.list2 (charged_squark_currents' g h) [M1;M2] [M1;M2]) (*** REVISED: Compatible with CD+. ***) let neutral_sfermion_currents' g m1 m2 = [ ((Z, Slepton (m1,-g), Slepton (m2,g)), Vector_Scalar_Scalar (-1), G_ZSF (SL,g,m1,m2)); ((Z, Sup (m1,-g), Sup (m2,g)), Vector_Scalar_Scalar (-1), G_ZSF (SU,g,m1,m2)); ((Z, Sdown (m1,-g), Sdown (m2,g)), Vector_Scalar_Scalar (-1), G_ZSF (SD,g,m1,m2)) ] let neutral_sfermion_currents g = List.flatten (Product.list2 (neutral_sfermion_currents' g) [M1;M2] [M1;M2]) @ [ ((Z, Sneutrino (-g), Sneutrino g), Vector_Scalar_Scalar (-1), G_ZSF (SN,g,M1,M1)) ] (* The reality of the coupling of the Z-boson to two identical neutralinos makes the vector part of the coupling vanish. So we distinguish them not by the name but by the structure of the couplings. *) (*** REVISED: Compatible with CD+. ***) let neutral_Z_1 (n,m) = [ ((Neutralino n, Z, Neutralino m), FBF (1, Chibar, VA, Chi), (G_NZN (n,m))) ] (*** REVISED: Compatible with CD+. ***) let neutral_Z_2 n = [ ((Neutralino n, Z, Neutralino n), FBF (1, Chibar, Coupling.A, Chi), (G_NZN (n,n)) )] (* For very compressed spectra, radiative decays of the next-to-lightest neutralino become important. The formula can be found Haber/Wyler, 1989. In abuse, we include this loop-induced coupling together in the same model variant with the triangle Higgs couplings. *) let neutral_A = if Flags.higgs_triangle then [ ((Neutralino N2, Ga, Neutralino N1), FBF (1, Chibar, TVAM, Chi), G_NNA) ] else [] (*** REVISED: Compatible with CD+. ***) let charged_Z c1 c2 = let cc1 = conj_char c1 in ((Chargino cc1, Z, Chargino c2), FBF ((-1), Psibar, VA, Psi), G_CZC (c1,c2)) (*** REVISED: Compatible with CD+. ***) let yukawa_v = [ ((Gluino, Gl, Gluino), FBF (1, Chibar, V, Chi), Gs) ] (*** REVISED: Independent of the sign of CD. ***) let yukawa_higgs g = [ ((N (-g), Hp, L g), FBF (1, Psibar, Coupling.SR, Psi), G_YUK (6,g)); ((L (-g), Hm, N g), FBF (1, Psibar, Coupling.SL, Psi), G_YUK (6,g)); ((L (-g), H_Heavy, L g), FBF (1, Psibar, S, Psi), G_YUK (7,g)); ((L (-g), H_Light, L g), FBF (1, Psibar, S, Psi), G_YUK (8,g)); ((L (-g), A, L g), FBF (1, Psibar, P, Psi), G_YUK (9,g)); ((U (-g), H_Heavy, U g), FBF (1, Psibar, S, Psi), G_YUK (10,g)); ((U (-g), H_Light, U g), FBF (1, Psibar, S, Psi), G_YUK (11,g)); ((U (-g), A, U g), FBF (1, Psibar, P, Psi), G_YUK (12,g)); ((D (-g), H_Heavy, D g), FBF (1, Psibar, S, Psi), G_YUK (13,g)); ((D (-g), H_Light, D g), FBF (1, Psibar, S, Psi), G_YUK (14,g)); ((D (-g), A, D g), FBF (1, Psibar, P, Psi), G_YUK (15,g)) ] (*** REVISED: Compatible with CD+ and GS+. ***) let yukawa_goldstone g = [ ((N (-g), Phip, L g), FBF (1, Psibar, Coupling.SR, Psi), G_YUK (19,g)); ((L (-g), Phim, N g), FBF (1, Psibar, Coupling.SL, Psi), G_YUK (19,g)); ((L (-g), Phi0, L g), FBF (1, Psibar, P, Psi), G_YUK (16,g)); ((U (-g), Phi0, U g), FBF (1, Psibar, P, Psi), G_YUK (17,g)); ((D (-g), Phi0, D g), FBF (1, Psibar, P, Psi), G_YUK (18,g)) ] (*** REVISED: Independent of the sign of CD. ***) let yukawa_higgs_quark (g,h) = [ ((U (-g), Hp, D h), FBF (1, Psibar, SLR, Psi), G_YUK_1 (g, h)); ((D (-h), Hm, U g), FBF (1, Psibar, SLR, Psi), G_YUK_2 (g, h)) ] (*** REVISED: Compatible with CD+ and GS+. ***) let yukawa_goldstone_quark g h = [ ((U (-g), Phip, D h), FBF (1, Psibar, SLR, Psi), G_YUK_3 (g, h)); ((D (-h), Phim, U g), FBF (1, Psibar, SLR, Psi), G_YUK_4 (g, h)) ] (*** REVISED: Compatible with CD+. *) let yukawa_higgs_2' (c1,c2) = let cc1 = conj_char c1 in [ ((Chargino cc1, H_Heavy, Chargino c2), FBF (1, Psibar, SLR, Psi), G_CH2C (c1,c2)); ((Chargino cc1, H_Light, Chargino c2), FBF (1, Psibar, SLR, Psi), G_CH1C (c1,c2)); ((Chargino cc1, A, Chargino c2), FBF (1, Psibar, SLR, Psi), G_CAC (c1,c2)) ] let yukawa_higgs_2'' c = let cc = conj_char c in [ ((Chargino cc, H_Heavy, Chargino c), FBF (1, Psibar, S, Psi), G_CH2C (c,c)); ((Chargino cc, H_Light, Chargino c), FBF (1, Psibar, S, Psi), G_CH1C (c,c)); ((Chargino cc, A, Chargino c), FBF (1, Psibar, P, Psi), G_CAC (c,c)) ] let yukawa_higgs_2 = ThoList.flatmap yukawa_higgs_2' [(C1,C2);(C2,C1)] @ ThoList.flatmap yukawa_higgs_2'' [C1;C2] (*** REVISED: Compatible with CD+ and GS+. ***) let yukawa_goldstone_2' (c1,c2) = let cc1 = conj_char c1 in [ ((Chargino cc1, Phi0, Chargino c2), FBF (1, Psibar, SLR, Psi), G_CGC (c1,c2)) ] let yukawa_goldstone_2'' c = let cc = conj_char c in [ ((Chargino cc, Phi0, Chargino c), FBF (1, Psibar, P, Psi), G_CGC (c,c)) ] let yukawa_goldstone_2 = ThoList.flatmap yukawa_goldstone_2' [(C1,C2);(C2,C1)] @ ThoList.flatmap yukawa_goldstone_2'' [C1;C2] (*** REVISED: Compatible with CD+. ***) let higgs_charg_neutr n c = let cc = conj_char c in [ ((Neutralino n, Hm, Chargino c), FBF (-1, Chibar, SLR, Psi), G_NHC (n,c)); ((Chargino cc, Hp, Neutralino n), FBF (-1, Psibar, SLR, Chi), G_CHN (c,n)) ] (*** REVISED: Compatible with CD+ and GS+. ***) let goldstone_charg_neutr n c = let cc = conj_char c in [ ((Neutralino n, Phim, Chargino c), FBF (1, Chibar, SLR, Psi), G_NGC (n,c)); ((Chargino cc, Phip, Neutralino n), FBF (1, Psibar, SLR, Chi), G_CGN (c,n)) ] (*** REVISED: Compatible with CD+. ***) let higgs_neutr' (n,m) = [ ((Neutralino n, H_Heavy, Neutralino m), FBF (1, Chibar, SP, Chi), G_CICIH2 (n,m)); ((Neutralino n, H_Light, Neutralino m), FBF (1, Chibar, SP, Chi), G_CICIH1 (n,m)); ((Neutralino n, A, Neutralino m), FBF (1, Chibar, SP, Chi), G_CICIA (n,m)) ] let higgs_neutr'' n = [ ((Neutralino n, H_Heavy, Neutralino n), FBF (1, Chibar, S, Chi), G_CICIH2 (n,n)); ((Neutralino n, H_Light, Neutralino n), FBF (1, Chibar, S, Chi), G_CICIH1 (n,n)); ((Neutralino n, A, Neutralino n), FBF (1, Chibar, P, Chi), G_CICIA (n,n)) ] let higgs_neutr = ThoList.flatmap higgs_neutr' [(N1,N2);(N1,N3);(N1,N4); (N2,N3);(N2,N4);(N3,N4)] @ ThoList.flatmap higgs_neutr'' [N1;N2;N3;N4] (*** REVISED: Compatible with CD+ and GS+. ***) let goldstone_neutr' (n,m) = [ ((Neutralino n, Phi0, Neutralino m), FBF (1, Chibar, SP, Chi), G_CICIG (n,m)) ] let goldstone_neutr'' n = [ ((Neutralino n, Phi0, Neutralino n), FBF (1, Chibar, P, Chi), G_CICIG (n,n)) ] let goldstone_neutr = ThoList.flatmap goldstone_neutr' [(N1,N2);(N1,N3);(N1,N4); (N2,N3);(N2,N4);(N3,N4)] @ ThoList.flatmap goldstone_neutr'' [N1;N2;N3;N4] (*** REVISED: Compatible with CD+. ***) let yukawa_n_1 n g = [ ((Neutralino n, Slepton (M1,-g), L g), FBF (1, Chibar, Coupling.SL, Psi), G_YUK_N (true,g,n,SL,M1)); ((Neutralino n, Slepton (M2,-g), L g), FBF (1, Chibar, SR, Psi), G_YUK_N (true,g,n,SL,M2)); ((L (-g), Slepton (M1,g), Neutralino n), FBF (1, Psibar, SR, Chi), G_YUK_N (false,g,n,SL,M1)); ((L (-g), Slepton (M2,g), Neutralino n), FBF (1, Psibar, Coupling.SL, Chi), G_YUK_N (false,g,n,SL,M2)); ((Neutralino n, Sup (M1,-g), U g), FBF (1, Chibar, Coupling.SL, Psi), G_YUK_N (true,g,n,SU,M1)); ((Neutralino n, Sup (M2,-g), U g), FBF (1, Chibar, SR, Psi), G_YUK_N (true,g,n,SU,M2)); ((U (-g), Sup (M1,g), Neutralino n), FBF (1, Psibar, SR, Chi), G_YUK_N (false,g,n,SU,M1)); ((U (-g), Sup (M2,g), Neutralino n), FBF (1, Psibar, Coupling.SL, Chi), G_YUK_N (false,g,n,SU,M2)); ((Neutralino n, Sdown (M1,-g), D g), FBF (1, Chibar, Coupling.SL, Psi), G_YUK_N (true,g,n,SD,M1)); ((Neutralino n, Sdown (M2,-g), D g), FBF (1, Chibar, SR, Psi), G_YUK_N (true,g,n,SD,M2)); ((D (-g), Sdown (M1,g), Neutralino n), FBF (1, Psibar, SR, Chi), G_YUK_N (false,g,n,SD,M1)); ((D (-g), Sdown (M2,g), Neutralino n), FBF (1, Psibar, Coupling.SL, Chi), G_YUK_N (false,g,n,SD,M2)) ] let yukawa_n_2 n m = [ ((Neutralino n, Slepton (m,-3), L 3), FBF (1, Chibar, SLR, Psi), G_YUK_N (true,3,n,SL,m)); ((L (-3), Slepton (m,3), Neutralino n), FBF (1, Psibar, SLR, Chi), G_YUK_N (false,3,n,SL,m)); ((Neutralino n, Sup (m,-3), U 3), FBF (1, Chibar, SLR, Psi), G_YUK_N (true,3,n,SU,m)); ((U (-3), Sup (m,3), Neutralino n), FBF (1, Psibar, SLR, Chi), G_YUK_N (false,3,n,SU,m)); ((Neutralino n, Sdown (m,-3), D 3), FBF (1, Chibar, SLR, Psi), G_YUK_N (true,3,n,SD,m)); ((D (-3), Sdown (m,3), Neutralino n), FBF (1, Psibar, SLR, Chi), G_YUK_N (false,3,n,SD,m)) ] let yukawa_n_3 n g = [ ((Neutralino n, Sneutrino (-g), N g), FBF (1, Chibar, Coupling.SL, Psi), G_YUK_N (true,g,n,SN,M1)); ((N (-g), Sneutrino g, Neutralino n), FBF (1, Psibar, SR, Chi), G_YUK_N (false,g,n,SN,M1)) ] let yukawa_n_4 g = [ ((U (-g), Sup (M1,g), Gluino), FBF ((-1), Psibar, SR, Chi), G_S_Sqrt); ((D (-g), Sdown (M1,g), Gluino), FBF ((-1), Psibar, SR, Chi), G_S_Sqrt); ((Gluino, Sup (M1,-g), U g), FBF ((-1), Chibar, Coupling.SL, Psi), G_S_Sqrt); ((Gluino, Sdown (M1,-g), D g), FBF ((-1), Chibar, Coupling.SL, Psi), G_S_Sqrt); ((U (-g), Sup (M2,g), Gluino), FBF (1, Psibar, Coupling.SL, Chi), G_S_Sqrt); ((D (-g), Sdown (M2,g), Gluino), FBF (1, Psibar, Coupling.SL, Chi), G_S_Sqrt); ((Gluino, Sup (M2,-g), U g), FBF (1, Chibar, SR, Psi), G_S_Sqrt); ((Gluino, Sdown (M2,-g), D g), FBF (1, Chibar, SR, Psi), G_S_Sqrt)] let yukawa_n_5 m = [ ((U (-3), Sup (m,3), Gluino), FBF (1, Psibar, SLR, Chi), G_YUK_G (false,3,SU,m)); ((D (-3), Sdown (m,3), Gluino), FBF (1, Psibar, SLR, Chi), G_YUK_G (false,3,SD,m)); ((Gluino, Sup (m,-3), U 3), FBF (1, Chibar, SLR, Psi), G_YUK_G (true,3,SU,m)); ((Gluino, Sdown (m,-3), D 3), FBF (1, Chibar, SLR, Psi), G_YUK_G (true,3,SD,m))] let yukawa_n = List.flatten (Product.list2 yukawa_n_1 [N1;N2;N3;N4] [1;2]) @ List.flatten (Product.list2 yukawa_n_2 [N1;N2;N3;N4] [M1;M2]) @ List.flatten (Product.list2 yukawa_n_3 [N1;N2;N3;N4] [1;2;3]) @ ThoList.flatmap yukawa_n_4 [1;2] @ ThoList.flatmap yukawa_n_5 [M1;M2] (*** REVISED: Compatible with CD+. ***) let yukawa_c_1 c g = let cc = conj_char c in [ ((L (-g), Sneutrino g, Chargino cc), BBB (1, Psibar, Coupling.SR, Psibar), G_YUK_C (true,g,c,SN,M1)); ((Chargino c, Sneutrino (-g), L g), PBP (1, Psi, Coupling.SL, Psi), G_YUK_C (false,g,c,SN,M1)) ] let yukawa_c_2 c = let cc = conj_char c in [ ((L (-3), Sneutrino 3, Chargino cc), BBB (1, Psibar, SLR, Psibar), G_YUK_C (true,3,c,SN,M1)); ((Chargino c, Sneutrino (-3), L 3), PBP (1, Psi, SLR, Psi), G_YUK_C (false,3,c,SN,M1)) ] let yukawa_c_3 c m g = let cc = conj_char c in [ ((N (-g), Slepton (m,g), Chargino c), FBF (1, Psibar, Coupling.SR, Psi), G_YUK_C (true,g,c,SL,m)); ((Chargino cc, Slepton (m,-g), N g), FBF (1, Psibar, Coupling.SL, Psi), G_YUK_C (false,g,c,SL,m)) ] let yukawa_c c = ThoList.flatmap (yukawa_c_1 c) [1;2] @ yukawa_c_2 c @ List.flatten (Product.list2 (yukawa_c_3 c) [M1] [1;2]) @ List.flatten (Product.list2 (yukawa_c_3 c) [M1;M2] [3]) (*** REVISED: Compatible with CD+. ***) let yukawa_cq' c (g,h) m = let cc = conj_char c in [ ((Chargino c, Sup (m,-g), D h), PBP (1, Psi, SLR, Psi), G_YUK_Q (false,g,h,c,SU,m)); ((D (-h), Sup (m,g), Chargino cc), BBB (1, Psibar, SLR, Psibar), G_YUK_Q (true,g,h,c,SU,m)); ((Chargino cc, Sdown (m,-h), U g), FBF (1, Psibar, SLR, Psi), G_YUK_Q (true,g,h,c,SD,m)); ((U (-g), Sdown (m,h), Chargino c), FBF (1, Psibar, SLR, Psi), G_YUK_Q (false,g,h,c,SD,m)) ] let yukawa_cq'' c (g,h) = let cc = conj_char c in [ ((Chargino c, Sup (M1,-g), D h), PBP (1, Psi, Coupling.SL, Psi), G_YUK_Q (false,g,h,c,SU,M1)); ((D (-h), Sup (M1,g), Chargino cc), BBB (1, Psibar, Coupling.SR, Psibar), G_YUK_Q (true,g,h,c,SU,M1)); ((Chargino cc, Sdown (M1,-h), U g), FBF (1, Psibar, Coupling.SL, Psi), G_YUK_Q (true,g,h,c,SD,M1)); ((U (-g), Sdown (M1,h), Chargino c), FBF (1, Psibar, Coupling.SR, Psi), G_YUK_Q (false,g,h,c,SD,M1)) ] let yukawa_cq c = if Flags.ckm_present then List.flatten (Product.list2 (yukawa_cq' c) [(1,3);(2,3);(3,3); (3,2);(3,1)] [M1;M2]) @ ThoList.flatmap (yukawa_cq'' c) [(1,1);(1,2);(2,1);(2,2)] else ThoList.flatmap (yukawa_cq' c (3,3)) [M1;M2] @ ThoList.flatmap (yukawa_cq'' c) [(1,1);(2,2)] (*** REVISED: Compatible with CD+. Remark: Singlet and octet gluon exchange. The coupling is divided by sqrt(2) to account for the correct normalization of the Lie algebra generators. ***) let col_currents g = [ ((D (-g), Gl, D g), FBF ((-1), Psibar, V, Psi), Gs); ((U (-g), Gl, U g), FBF ((-1), Psibar, V, Psi), Gs)] (*** REVISED: Compatible with CD+. Remark: Singlet and octet gluon exchange. The coupling is divided by sqrt(2) to account for the correct normalization of the Lie algebra generators. ***) let col_sfermion_currents g m = [ ((Gl, Sup (m,-g), Sup (m,g)), Vector_Scalar_Scalar (-1), Gs); ((Gl, Sdown (m,-g), Sdown (m,g)), Vector_Scalar_Scalar (-1), Gs)] (* The gravitino coupling is generically $1/(4 M_{Pl.})$ *) (*** Triple vertices containing graivitinos. ***) let triple_gravitino' g = [ ((Grino, Sneutrino (-g), N g), GBG (1, Gravbar, Coupling.SL, Psi), G_Grav_N); ((N (-g), Sneutrino g, Grino), GBG (1, Psibar, Coupling.SL, Grav), G_Grav_N)] let triple_gravitino'' g m = [ ((Grino, Slepton (m, -g), L g), GBG (1, Gravbar, SLR, Psi), G_Grav_L (g,m)); ((L (-g), Slepton (m, g), Grino), GBG (1, Psibar, SLR, Grav), G_Grav_Lc (g,m)); ((Grino, Sup (m, -g), U g), GBG (1, Gravbar, SLR, Psi), G_Grav_U (g,m)); ((U (-g), Sup (m, g), Grino), GBG (1, Psibar, SLR, Grav), G_Grav_Uc (g,m)); ((Grino, Sdown (m, -g), D g), GBG (1, Gravbar, SLR, Psi), G_Grav_D (g,m)); ((D (-g), Sdown (m, g), Grino), GBG (1, Psibar, SLR, Grav), G_Grav_Dc (g,m)) ] let higgs_ch_gravitino c = let cc = conj_char c in [ ((Grino, Hm, Chargino c), GBG (1, Gravbar, SLR, Psi), G_Gr_H_Ch c); ((Chargino cc, Hp, Grino), GBG (1, Psibar, SLR, Grav), G_Gr_H_Ch cc) ] let higgs_neu_gravitino n = [ ((Grino, H_Light, Neutralino n), GBG (1, Gravbar, SLR, Chi), G_Gr_H1_Neu n); ((Grino, H_Heavy, Neutralino n), GBG (1, Gravbar, SLR, Chi), G_Gr_H2_Neu n); ((Grino, A, Neutralino n), GBG (1, Gravbar, SLR, Chi), G_Gr_H3_Neu n) ] let gravitino_gaugino_3 = [ ((Grino, Gl, Gluino), GBG (1, Gravbar, V, Chi), G_Grav); ((Gluino, Gl, Grino), GBG (1, Chibar, V, Grav), G_Grav); ((Chargino C1c, Wp, Grino), GBG (1, Psibar, VLR, Grav), G_Gr_Ch C1); ((Chargino C2c, Wp, Grino), GBG (1, Psibar, VLR, Grav), G_Gr_Ch C2); ((Grino, Wm, Chargino C1), GBG (1, Gravbar, VLR, Psi), G_Gr_Ch C1c); ((Grino, Wm, Chargino C2), GBG (1, Gravbar, VLR, Psi), G_Gr_Ch C2c); ((Grino, Z, Neutralino N1), GBG (1, Gravbar, VLR, Chi), G_Gr_Z_Neu N1); ((Grino, Z, Neutralino N2), GBG (1, Gravbar, VLR, Chi), G_Gr_Z_Neu N2); ((Grino, Z, Neutralino N3), GBG (1, Gravbar, VLR, Chi), G_Gr_Z_Neu N3); ((Grino, Z, Neutralino N4), GBG (1, Gravbar, VLR, Chi), G_Gr_Z_Neu N4); ((Grino, Ga, Neutralino N1), GBG (1, Gravbar, VLR, Chi), G_Gr_A_Neu N1); ((Grino, Ga, Neutralino N2), GBG (1, Gravbar, VLR, Chi), G_Gr_A_Neu N2); ((Grino, Ga, Neutralino N3), GBG (1, Gravbar, VLR, Chi), G_Gr_A_Neu N3); ((Grino, Ga, Neutralino N4), GBG (1, Gravbar, VLR, Chi), G_Gr_A_Neu N4) ] let triple_gravitino = ThoList.flatmap triple_gravitino' [1;2;3] @ List.flatten (Product.list2 triple_gravitino'' [1;2;3] [M1; M2]) @ ThoList.flatmap higgs_ch_gravitino [C1; C2] @ ThoList.flatmap higgs_neu_gravitino [N1; N2; N3; N4] @ gravitino_gaugino_3 (*** REVISED: Compatible with CD+. ***) let triple_gauge = [ ((Ga, Wm, Wp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW); ((Gl, Gl, Gl), Gauge_Gauge_Gauge 1, I_G_S)] (*** REVISED: Independent of the sign of CD. ***) let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let gluon4 = Vector4 [(-1, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] let quartic_gauge = [ (Wm, Wp, Wm, Wp), gauge4, G_WWWW; (Wm, Z, Wp, Z), minus_gauge4, G_ZZWW; (Wm, Z, Wp, Ga), minus_gauge4, G_PZWW; (Wm, Ga, Wp, Ga), minus_gauge4, G_PPWW; (Gl, Gl, Gl, Gl), gauge4, G_SS] (* The [Scalar_Vector_Vector] couplings do not depend on the choice of the sign of the covariant derivative since they are quadratic in the gauge couplings. *) (*** REVISED: Compatible with CD+. ***) (*** Revision: 2005-03-10: first two vertices corrected. ***) let gauge_higgs = [ ((Wm, Hp, A), Vector_Scalar_Scalar 1, G_GH 1); ((Wp, Hm, A), Vector_Scalar_Scalar 1, G_GH 1); ((Z, H_Heavy, A), Vector_Scalar_Scalar 1, G_GH 3); ((Z, H_Light, A), Vector_Scalar_Scalar 1, G_GH 2); ((H_Heavy, Wp, Wm), Scalar_Vector_Vector 1, G_GH 5); ((H_Light, Wp, Wm), Scalar_Vector_Vector 1, G_GH 4); ((Wm, Hp, H_Heavy), Vector_Scalar_Scalar 1, G_GH 7); ((Wp, Hm, H_Heavy), Vector_Scalar_Scalar (-1), G_GH 7); ((Wm, Hp, H_Light), Vector_Scalar_Scalar 1, G_GH 6); ((Wp, Hm, H_Light), Vector_Scalar_Scalar (-1), G_GH 6); ((H_Heavy, Z, Z), Scalar_Vector_Vector 1, G_GH 9); ((H_Light, Z, Z), Scalar_Vector_Vector 1, G_GH 8); ((Z, Hp, Hm), Vector_Scalar_Scalar 1, G_GH 10); ((Ga, Hp, Hm), Vector_Scalar_Scalar 1, G_GH 11) ] @ (if Flags.higgs_triangle then [((H_Light, Gl, Gl), Dim5_Scalar_Gauge2 1, G_GLGLH); ((H_Heavy, Gl, Gl), Dim5_Scalar_Gauge2 1, G_GLGLHH); ((A, Gl, Gl), Dim5_Scalar_Gauge2_Skew 1, G_GLGLA); ((H_Light, Ga, Ga), Dim5_Scalar_Gauge2 1, G_PPH); ((H_Heavy, Ga, Ga), Dim5_Scalar_Gauge2 1, G_PPHH); ((A, Ga, Ga), Dim5_Scalar_Gauge2 1, G_PPA)] else []) (*** REVISED: Compatible with CD+ and GS+. ***) let gauge_higgs_gold = [ ((Wp, Phi0, Phim), Vector_Scalar_Scalar 1, G_GH 1); ((Wm, Phi0, Phip), Vector_Scalar_Scalar 1, G_GH 1); ((Z, H_Heavy, Phi0), Vector_Scalar_Scalar 1, G_GH 2); ((Z, H_Light, Phi0), Vector_Scalar_Scalar (-1), G_GH 3); ((Wp, H_Heavy, Phim), Vector_Scalar_Scalar 1, G_GH 6); ((Wm, H_Heavy, Phip), Vector_Scalar_Scalar (-1), G_GH 6); ((Wp, H_Light, Phim), Vector_Scalar_Scalar (-1), G_GH 7); ((Wm, H_Light, Phip), Vector_Scalar_Scalar 1, G_GH 7); ((Phim, Wp, Ga), Scalar_Vector_Vector 1, G_GHGo 1); ((Phip, Wm, Ga), Scalar_Vector_Vector 1, G_GHGo 1); ((Phim, Wp, Z), Scalar_Vector_Vector 1, G_GHGo 2); ((Phip, Wm, Z), Scalar_Vector_Vector 1, G_GHGo 2); ((Z, Phip, Phim), Vector_Scalar_Scalar 1, G_GH 10); ((Ga, Phip, Phim), Vector_Scalar_Scalar 1, G_GH 11) ] let gauge_higgs4 = [ ((A, A, Z, Z), Scalar2_Vector2 1, G_GH4 1); ((H_Heavy, H_Heavy, Z, Z), Scalar2_Vector2 1, G_GH4 3); ((H_Light, H_Light, Z, Z), Scalar2_Vector2 1, G_GH4 2); ((Hp, Hm, Z, Z), Scalar2_Vector2 1, G_GH4 4); ((Hp, Hm, Ga, Ga), Scalar2_Vector2 1, G_GH4 5); ((Hp, Hm, Ga, Z), Scalar2_Vector2 1, G_GH4 6); ((Hp, H_Heavy, Wm, Z), Scalar2_Vector2 1, G_GH4 8); ((Hm, H_Heavy, Wp, Z), Scalar2_Vector2 1, G_GH4 8); ((Hp, H_Light, Wm, Z), Scalar2_Vector2 1, G_GH4 7); ((Hm, H_Light, Wp, Z), Scalar2_Vector2 1, G_GH4 7); ((Hp, H_Heavy, Wm, Ga), Scalar2_Vector2 1, G_GH4 10); ((Hm, H_Heavy, Wp, Ga), Scalar2_Vector2 1, G_GH4 10); ((Hp, H_Light, Wm, Ga), Scalar2_Vector2 1, G_GH4 9); ((Hm, H_Light, Wp, Ga), Scalar2_Vector2 1, G_GH4 9); ((A, A, Wp, Wm), Scalar2_Vector2 1, G_GH4 11); ((H_Heavy, H_Heavy, Wp, Wm), Scalar2_Vector2 1, G_GH4 13); ((H_Light, H_Light, Wp, Wm), Scalar2_Vector2 1, G_GH4 12); ((Hp, Hm, Wp, Wm), Scalar2_Vector2 1, G_GH4 14); ((Hp, A, Wm, Z), Scalar2_Vector2 1, G_GH4 15); ((Hm, A, Wp, Z), Scalar2_Vector2 (-1), G_GH4 15); ((Hp, A, Wm, Ga), Scalar2_Vector2 1, G_GH4 16); ((Hm, A, Wp, Ga), Scalar2_Vector2 (-1), G_GH4 16) ] let gauge_higgs_gold4 = [ ((Z, Z, Phi0, Phi0), Scalar2_Vector2 1, G_GHGo4 1); ((Z, Z, Phip, Phim), Scalar2_Vector2 1, G_GHGo4 2); ((Ga, Ga, Phip, Phim), Scalar2_Vector2 1, G_GHGo4 3); ((Z, Ga, Phip, Phim), Scalar2_Vector2 1, G_GHGo4 4); ((Wp, Wm, Phip, Phim), Scalar2_Vector2 1, G_GHGo4 5); ((Wp, Wm, Phi0, Phi0), Scalar2_Vector2 1, G_GHGo4 5); ((Wp, Z, Phim, Phi0), Scalar2_Vector2 1, G_GHGo4 6); ((Wm, Z, Phip, Phi0), Scalar2_Vector2 (-1), G_GHGo4 6); ((Wp, Ga, Phim, Phi0), Scalar2_Vector2 1, G_GHGo4 7); ((Wm, Ga, Phip, Phi0), Scalar2_Vector2 (-1), G_GHGo4 7); ((Wp, Z, Phim, H_Heavy), Scalar2_Vector2 1, G_GHGo4 9); ((Wm, Z, Phip, H_Heavy), Scalar2_Vector2 1, G_GHGo4 9); ((Wp, Ga, Phim, H_Heavy), Scalar2_Vector2 1, G_GHGo4 11); ((Wm, Ga, Phip, H_Heavy), Scalar2_Vector2 1, G_GHGo4 11); ((Wp, Z, Phim, H_Light), Scalar2_Vector2 1, G_GHGo4 8); ((Wm, Z, Phip, H_Light), Scalar2_Vector2 1, G_GHGo4 8); ((Wp, Ga, Phim, H_Light), Scalar2_Vector2 1, G_GHGo4 10); ((Wm, Ga, Phip, H_Light), Scalar2_Vector2 1, G_GHGo4 10) ] let gauge_sfermion4' g m1 m2 = [ ((Wp, Wm, Slepton (m1,g), Slepton (m2,-g)), Scalar2_Vector2 1, G_WWSFSF (SL,g,m1,m2)); ((Z, Ga, Slepton (m1,g), Slepton (m2,-g)), Scalar2_Vector2 1, G_ZPSFSF (SL,g,m1,m2)); ((Z, Z, Slepton (m1,g), Slepton (m2,-g)), Scalar2_Vector2 1, G_ZZSFSF (SL,g,m1,m2)); ((Wp, Wm, Sup (m1,g), Sup (m2,-g)), Scalar2_Vector2 1, G_WWSFSF (SU,g,m1,m2)); ((Wp, Wm, Sdown (m1,g), Sdown (m2,-g)), Scalar2_Vector2 1, G_WWSFSF (SD,g,m1,m2)); ((Z, Z, Sup (m1,g), Sup (m2,-g)), Scalar2_Vector2 1, G_ZZSFSF (SU,g,m1,m2)); ((Z, Z, Sdown (m1,g), Sdown (m2,-g)), Scalar2_Vector2 1, G_ZZSFSF (SD,g,m1,m2)); ((Z, Ga, Sup (m1,g), Sup (m2,-g)), Scalar2_Vector2 1, G_ZPSFSF (SU,g,m1,m2)); ((Z, Ga, Sdown (m1,g), Sdown (m2,-g)), Scalar2_Vector2 1, G_ZPSFSF (SD,g,m1,m2)) ] let gauge_sfermion4'' g m = [ ((Wp, Ga, Slepton (m,g), Sneutrino (-g)), Scalar2_Vector2 1, G_WPSLSN (false,g,m)); ((Wm, Ga, Slepton (m,-g), Sneutrino g), Scalar2_Vector2 1, G_WPSLSN (true,g,m)); ((Wp, Z, Slepton (m,g), Sneutrino (-g)), Scalar2_Vector2 1, G_WZSLSN (false,g,m)); ((Wm, Z, Slepton (m,-g), Sneutrino g), Scalar2_Vector2 1, G_WZSLSN (true,g,m)); ((Ga, Ga, Slepton (m,g), Slepton (m,-g)), Scalar2_Vector2 1, G_PPSFSF SL); ((Ga, Ga, Sup (m,g), Sup (m,-g)), Scalar2_Vector2 1, G_PPSFSF SU); ((Ga, Ga, Sdown (m,g), Sdown (m,-g)), Scalar2_Vector2 1, G_PPSFSF SD)] let gauge_sfermion4 g = List.flatten (Product.list2 (gauge_sfermion4' g) [M1;M2] [M1;M2]) @ ThoList.flatmap (gauge_sfermion4'' g) [M1;M2] @ [ ((Wp, Wm, Sneutrino g, Sneutrino (-g)), Scalar2_Vector2 1, G_WWSFSF (SN,g,M1,M1)); ((Z, Z, Sneutrino g, Sneutrino (-g)), Scalar2_Vector2 1, G_ZZSFSF (SN,g,M1,M1)) ] let gauge_squark4'' g h m1 m2 = [ ((Wp, Ga, Sup (m1,-g), Sdown (m2,h)), Scalar2_Vector2 1, G_WPSUSD (false,m1,m2,g,h)); ((Wm, Ga, Sup (m1,g), Sdown (m2,-h)), Scalar2_Vector2 1, G_WPSUSD (true,m1,m2,g,h)); ((Wp, Z, Sup (m1,-g), Sdown (m2,h)), Scalar2_Vector2 1, G_WZSUSD (false,m1,m2,g,h)); ((Wm, Z, Sup (m1,g), Sdown (m2,-h)), Scalar2_Vector2 1, G_WZSUSD (true,m1,m2,g,h)) ] let gauge_squark4' g h = List.flatten (Product.list2 (gauge_squark4'' g h) [M1;M2] [M1;M2]) let gauge_squark4 = if Flags.ckm_present then List.flatten (Product.list2 gauge_squark4' [1;2;3] [1;2;3]) else ThoList.flatmap (fun g -> gauge_squark4' g g) [1;2;3] let gluon_w_squark'' g h m1 m2 = [ ((Gl, Wp, Sup (m1,-g), Sdown (m2,h)), Scalar2_Vector2 1, G_GlWSUSD (false,m1,m2,g,h)); ((Gl, Wm, Sup (m1,g), Sdown (m2,-h)), Scalar2_Vector2 1, G_GlWSUSD (true,m1,m2,g,h)) ] let gluon_w_squark' g h = List.flatten (Product.list2 (gluon_w_squark'' g h) [M1;M2] [M1;M2]) let gluon_w_squark = if Flags.ckm_present then List.flatten (Product.list2 gluon_w_squark' [1;2;3] [1;2;3]) else ThoList.flatmap (fun g -> gluon_w_squark' g g) [1;2;3] let gluon_gauge_squark' g m1 m2 = [ ((Gl, Z, Sup (m1,g), Sup (m2,-g)), Scalar2_Vector2 2, G_GlZSFSF (SU,g,m1,m2)); ((Gl, Z, Sdown (m1,g), Sdown (m2,-g)), Scalar2_Vector2 2, G_GlZSFSF (SD,g,m1,m2)) ] let gluon_gauge_squark'' g m = [ ((Gl, Ga, Sup (m,g), Sup (m,-g)), Scalar2_Vector2 2, G_GlPSQSQ); ((Gl, Ga, Sdown (m,g), Sdown (m,-g)), Scalar2_Vector2 (-1), G_GlPSQSQ) ] let gluon_gauge_squark g = List.flatten (Product.list2 (gluon_gauge_squark' g) [M1;M2] [M1;M2]) @ ThoList.flatmap (gluon_gauge_squark'' g) [M1;M2] let gluon2_squark2 g m = [ ((Gl, Gl, Sup (m,g), Sup (m,-g)), Scalar2_Vector2 1, G_GlGlSQSQ); ((Gl, Gl, Sdown (m,g), Sdown (m,-g)), Scalar2_Vector2 1, G_GlGlSQSQ)] (*** REVISED: Independent of the sign of CD. ***) let higgs = [ ((Hp, Hm, H_Heavy), Scalar_Scalar_Scalar 1, G_H3 1); ((Hp, Hm, H_Light), Scalar_Scalar_Scalar 1, G_H3 2); ((H_Heavy, H_Heavy, H_Light), Scalar_Scalar_Scalar 1, G_H3 3); ((H_Heavy, H_Heavy, H_Heavy), Scalar_Scalar_Scalar 1, G_H3 4); ((H_Light, H_Light, H_Light), Scalar_Scalar_Scalar 1, G_H3 5); ((H_Heavy, H_Light, H_Light), Scalar_Scalar_Scalar 1, G_H3 6); ((H_Heavy, A, A), Scalar_Scalar_Scalar 1, G_H3 7); ((H_Light, A, A), Scalar_Scalar_Scalar 1, G_H3 8) ] (*** REVISED: Compatible with GS+, independent of the sign of CD. ***) let higgs_gold = [ ((H_Heavy, A, Phi0), Scalar_Scalar_Scalar 1, G_HGo3 1); ((H_Light, A, Phi0), Scalar_Scalar_Scalar 1, G_HGo3 2); ((H_Heavy, Hp, Phim), Scalar_Scalar_Scalar 1, G_HGo3 3); ((H_Heavy, Hm, Phip), Scalar_Scalar_Scalar 1, G_HGo3 3); ((H_Light, Hp, Phim), Scalar_Scalar_Scalar 1, G_HGo3 4); ((H_Light, Hm, Phip), Scalar_Scalar_Scalar 1, G_HGo3 4); ((A, Hp, Phim), Scalar_Scalar_Scalar (-1), G_HGo3 5); ((A, Hm, Phip), Scalar_Scalar_Scalar 1, G_HGo3 5); ((H_Heavy, Phi0, Phi0), Scalar_Scalar_Scalar (-1), G_H3 7); ((H_Heavy, Phip, Phim), Scalar_Scalar_Scalar (-1), G_H3 7); ((H_Light, Phi0, Phi0), Scalar_Scalar_Scalar (-1), G_H3 8); ((H_Light, Phip, Phim), Scalar_Scalar_Scalar (-1), G_H3 8) ] (* Here follow purely scalar quartic vertices which are only available for the no-Whizard colored version. *) (*** REVISED: Independent of the sign of CD. ***) let higgs4 = [ ((Hp, Hm, Hp, Hm), Scalar4 1, G_H4 1); ((Hp, Hm, H_Heavy, H_Heavy), Scalar4 1, G_H4 2); ((Hp, Hm, H_Light, H_Light), Scalar4 1, G_H4 3); ((Hp, Hm, H_Heavy, H_Light), Scalar4 1, G_H4 4); ((Hp, Hm, A, A), Scalar4 1, G_H4 5); ((H_Heavy, H_Heavy, H_Heavy, H_Heavy), Scalar4 1, G_H4 6); ((H_Light, H_Light, H_Light, H_Light), Scalar4 1, G_H4 6); ((H_Heavy, H_Heavy, H_Light, H_Light), Scalar4 1, G_H4 7); ((H_Heavy, H_Light, H_Light, H_Light), Scalar4 1, G_H4 8); ((H_Heavy, H_Heavy, H_Heavy, H_Light), Scalar4 (-1), G_H4 8); ((H_Heavy, H_Heavy, A, A), Scalar4 1, G_H4 9); ((H_Light, H_Light, A, A), Scalar4 (-1), G_H4 9); ((H_Heavy, H_Light, A, A), Scalar4 1, G_H4 10); ((A, A, A, A), Scalar4 1, G_H4 11) ] (*** REVISED: Compatible with GS+, independent of the sign of CD. ***) let higgs_gold4 = [ ((H_Heavy, H_Heavy, A, Phi0), Scalar4 1, G_HGo4 1); ((H_Heavy, H_Light, A, Phi0), Scalar4 1, G_HGo4 2); ((H_Light, H_Light, A, Phi0), Scalar4 (-1), G_HGo4 1); ((A, A, A, Phi0), Scalar4 3, G_HGo4 3); ((Hp, Hm, A, Phi0), Scalar4 1, G_HGo4 3); ((H_Heavy, H_Heavy, Hp, Phim), Scalar4 1, G_HGo4 4); ((H_Heavy, H_Heavy, Hm, Phip), Scalar4 1, G_HGo4 4); ((H_Heavy, H_Light, Hp, Phim), Scalar4 1, G_HGo4 5); ((H_Heavy, H_Light, Hm, Phip), Scalar4 1, G_HGo4 5); ((H_Light, H_Light, Hp, Phim), Scalar4 (-1), G_HGo4 4); ((H_Light, H_Light, Hm, Phip), Scalar4 (-1), G_HGo4 4); ((A, A, Hp, Phim), Scalar4 1, G_HGo4 6); ((A, A, Hm, Phip), Scalar4 1, G_HGo4 6); ((H_Heavy, A, Hp, Phim), Scalar4 1, G_HGo4 7); ((H_Heavy, A, Hm, Phip), Scalar4 (-1), G_HGo4 7); ((H_Light, A, Hp, Phim), Scalar4 1, G_HGo4 8); ((H_Light, A, Hm, Phip), Scalar4 (-1), G_HGo4 8); ((Hp, Hm, Hp, Phim), Scalar4 2, G_HGo4 6); ((Hp, Hm, Hm, Phip), Scalar4 2, G_HGo4 6); ((H_Heavy, H_Heavy, Phi0, Phi0), Scalar4 (-1), G_H4 9); ((H_Heavy, H_Light, Phi0, Phi0), Scalar4 (-1), G_H4 10); ((H_Light, H_Light, Phi0, Phi0), Scalar4 1, G_H4 9); ((A, A, Phi0, Phi0), Scalar4 1, G_HGo4 9); ((Hp, Hm, Phi0, Phi0), Scalar4 1, G_HGo4 10); ((H_Heavy, Hp, Phim, Phi0), Scalar4 1, G_HGo4 8); ((H_Heavy, Hm, Phip, Phi0), Scalar4 (-1), G_HGo4 8); ((H_Light, Hp, Phim, Phi0), Scalar4 (-1), G_HGo4 7); ((H_Light, Hm, Phip, Phi0), Scalar4 1, G_HGo4 7); ((A, Hp, Phim, Phi0), Scalar4 1, G_HGo4 11); ((A, Hm, Phip, Phi0), Scalar4 1, G_HGo4 11); ((H_Heavy, H_Heavy, Phip, Phim), Scalar4 1, G_HGo4 12); ((H_Heavy, H_Light, Phip, Phim), Scalar4 1, G_HGo4 13); ((H_Light, H_Light, Phip, Phim), Scalar4 1, G_HGo4 14); ((A, A, Phip, Phim), Scalar4 1, G_HGo4 15); ((Hp, Hm, Phip, Phim), Scalar4 1, G_HGo4 16); ((Hp, Hp, Phim, Phim), Scalar4 1, G_HGo4 17); ((Hm, Hm, Phip, Phip), Scalar4 1, G_HGo4 17); ((Hp, Phim, Phi0, Phi0), Scalar4 (-1), G_HGo4 6); ((Hm, Phip, Phi0, Phi0), Scalar4 (-1), G_HGo4 6); ((A, Phi0, Phi0, Phi0), Scalar4 (-3), G_HGo4 6); ((A, Phi0, Phip, Phim), Scalar4 (-1), G_HGo4 6); ((Hp, Phim, Phip, Phim), Scalar4 (-2), G_HGo4 6); ((Hm, Phip, Phip, Phim), Scalar4 (-2), G_HGo4 6) ] (*** REVISED: Independent of the sign of CD and GS. ***) let goldstone4 = [ ((Phi0, Phi0, Phi0, Phi0), Scalar4 1, G_GG4 1); ((Phip, Phim, Phi0, Phi0), Scalar4 1, G_GG4 2); ((Phip, Phim, Phip, Phim), Scalar4 1, G_GG4 3) ] (* The vertices of the type Higgs - Sfermion - Sfermion are independent of the choice of the CD sign since they are quadratic in the gauge coupling. *) (*** REVISED: Independent of the sign of CD. ***) let higgs_sneutrino' g = [ ((H_Heavy, Sneutrino g, Sneutrino (-g)), Scalar_Scalar_Scalar 1, G_H2SFSF (SN,g,M1,M1)); ((H_Light, Sneutrino g, Sneutrino (-g)), Scalar_Scalar_Scalar 1, G_H1SFSF (SN,g,M1,M1)); ((Hp, Sneutrino (-g), Slepton (M1,g)), Scalar_Scalar_Scalar 1, G_HSNSL (false,g,M1)); ((Hm, Sneutrino g, Slepton (M1,-g)), Scalar_Scalar_Scalar 1, G_HSNSL (true,g,M1)) ] let higgs_sneutrino'' = [ ((Hp, Sneutrino (-3), Slepton (M2,3)), Scalar_Scalar_Scalar 1, G_HSNSL (false,3,M2)); ((Hm, Sneutrino 3, Slepton (M2,-3)), Scalar_Scalar_Scalar 1, G_HSNSL (false,3,M2)) ] let higgs_sneutrino = ThoList.flatmap higgs_sneutrino' [1;2;3] @ higgs_sneutrino'' (* Under the assumption that there is no mixing between the left- and right-handed sfermions for the first two generations there is only a coupling of the form Higgs - sfermion1 - sfermion2 for the third generation. All the others are suppressed by $m_f/M_W$. *) (*** REVISED: Independent of the sign of CD. ***) let higgs_sfermion' g m1 m2 = [ ((H_Heavy, Slepton (m1,g), Slepton (m2,-g)), Scalar_Scalar_Scalar 1, G_H2SFSF (SL,g,m1,m2)); ((H_Light, Slepton (m1,g), Slepton (m2,-g)), Scalar_Scalar_Scalar 1, G_H1SFSF (SL,g,m1,m2)); ((H_Heavy, Sup (m1,g), Sup (m2,-g)), Scalar_Scalar_Scalar 1, G_H2SFSF (SU,g,m1,m2)); ((H_Heavy, Sdown (m1,g), Sdown (m2,-g)), Scalar_Scalar_Scalar 1, G_H2SFSF (SD,g,m1,m2)); ((H_Light, Sup (m1,g), Sup (m2,-g)), Scalar_Scalar_Scalar 1, G_H1SFSF (SU,g,m1,m2)); ((H_Light, Sdown (m1,g), Sdown (m2,-g)), Scalar_Scalar_Scalar 1, G_H1SFSF (SD,g,m1,m2)) ] let higgs_sfermion'' m1 m2 = [ ((A, Slepton (m1,3), Slepton (m2,-3)), Scalar_Scalar_Scalar 1, G_ASFSF (SL,3,m1,m2)); ((A, Sup (m1,3), Sup (m2,-3)), Scalar_Scalar_Scalar 1, G_ASFSF (SU,3,m1,m2)); ((A, Sdown (m1,3), Sdown (m2,-3)), Scalar_Scalar_Scalar 1, G_ASFSF (SD,3,m1,m2)) ] let higgs_sfermion = List.flatten (Product.list2 (higgs_sfermion' 3) [M1;M2] [M1;M2]) @ (higgs_sfermion' 1 M1 M1) @ (higgs_sfermion' 1 M2 M2) @ (higgs_sfermion' 2 M1 M1) @ (higgs_sfermion' 2 M2 M2) @ List.flatten (Product.list2 higgs_sfermion'' [M1;M2] [M1;M2]) (*i let higgs_sfermion g = List.flatten (Product.list2 (higgs_sfermion' g) [M1;M2] [M1;M2]) i*) (*** REVISED: Independent of the sign of CD, compatible with GS+. ***) let goldstone_sfermion' g m1 m2 = [ ((Phi0, Slepton (m1,g), Slepton (m2,-g)), Scalar_Scalar_Scalar 1, G_GoSFSF (SL,g,m1,m2)); ((Phi0, Sup (m1,g), Sup (m2,-g)), Scalar_Scalar_Scalar 1, G_GoSFSF (SU,g,m1,m2)); ((Phi0, Sdown (m1,g), Sdown (m2,-g)), Scalar_Scalar_Scalar 1, G_GoSFSF (SD,g,m1,m2))] let goldstone_sfermion'' g = [ ((Phip, Sneutrino (-g), Slepton (M1,g)), Scalar_Scalar_Scalar 1, G_GoSNSL (false,g,M1)); ((Phim, Sneutrino g, Slepton (M1,-g)), Scalar_Scalar_Scalar 1, G_GoSNSL (true,g,M1)) ] let goldstone_sfermion''' g = [ ((Phip, Sneutrino (-g), Slepton (M2,g)), Scalar_Scalar_Scalar 1, G_GoSNSL (false,g,M2)); ((Phim, Sneutrino g, Slepton (M2,-g)), Scalar_Scalar_Scalar 1, G_GoSNSL (true,g,M2))] let goldstone_sfermion = List.flatten (Product.list2 (goldstone_sfermion' 3) [M1;M2] [M1;M2]) @ ThoList.flatmap goldstone_sfermion'' [1;2;3] @ goldstone_sfermion''' 3 (*** REVISED: Independent of the sign of CD. ***) let higgs_squark' g h m1 m2 = [ ((Hp, Sup (m1,-g), Sdown (m2,h)), Scalar_Scalar_Scalar 1, G_HSUSD (false,m1,m2,g,h)); ((Hm, Sup (m1,g), Sdown (m2,-h)), Scalar_Scalar_Scalar 1, G_HSUSD (true,m1,m2,g,h)) ] let higgs_squark_a g h = higgs_squark' g h M1 M1 let higgs_squark_b (g,h) = List.flatten (Product.list2 (higgs_squark' g h) [M1;M2] [M1;M2]) let higgs_squark = if Flags.ckm_present then List.flatten (Product.list2 higgs_squark_a [1;2] [1;2]) @ ThoList.flatmap higgs_squark_b [(1,3);(2,3);(3,3);(3,1);(3,2)] else higgs_squark_a 1 1 @ higgs_squark_a 2 2 @ higgs_squark_b (3,3) (*** REVISED: Independent of the sign of CD, compatible with GS+. ***) let goldstone_squark' g h m1 m2 = [ ((Phip, Sup (m1,-g), Sdown (m2,h)), Scalar_Scalar_Scalar 1, G_GSUSD (false,m1,m2,g,h)); ((Phim, Sup (m1,g), Sdown (m2,-h)), Scalar_Scalar_Scalar 1, G_GSUSD (true,m1,m2,g,h)) ] let goldstone_squark_a g h = goldstone_squark' g h M1 M1 let goldstone_squark_b (g,h) = List.flatten (Product.list2 (goldstone_squark' g h) [M1;M2] [M1;M2]) let goldstone_squark = List.flatten (Product.list2 goldstone_squark_a [1;2] [1;2]) @ ThoList.flatmap goldstone_squark_b [(1,3);(2,3);(3,3);(3,1);(3,2)] (* BAUSTELLE: For the quartic scalar coupligs we does not allow [whiz_col]. *) let higgs_sneutrino4' g m = [ ((Hp, H_Heavy, Slepton (m,g), Sneutrino (-g)), Scalar4 1, G_HH2SLSN (false,m,g)); ((Hm, H_Heavy, Slepton (m,-g), Sneutrino g), Scalar4 1, G_HH2SLSN (true,m,g)); ((Hp, H_Light, Slepton (m,g), Sneutrino (-g)), Scalar4 1, G_HH1SLSN (false,m,g)); ((Hm, H_Light, Slepton (m,-g), Sneutrino g), Scalar4 1, G_HH1SLSN (true,m,g)); ((Hp, A, Slepton (m,g), Sneutrino (-g)), Scalar4 1, G_HASLSN (false,m,g)); ((Hm, A, Slepton (m,-g), Sneutrino g), Scalar4 1, G_HASLSN (true,m,g)) ] let higgs_sneutrino4 g = ThoList.flatmap (higgs_sneutrino4' g) [M1;M2] @ [ ((H_Heavy, H_Heavy, Sneutrino g, Sneutrino (-g)), Scalar4 1, G_H2H2SFSF (SN,M1,M1,g)); ((H_Heavy, H_Light, Sneutrino g, Sneutrino (-g)), Scalar4 1, G_H1H2SFSF (SN,M1,M1,g)); ((H_Light, H_Light, Sneutrino g, Sneutrino (-g)), Scalar4 1, G_H1H1SFSF (SN,M1,M1,g)); ((Hp, Hm, Sneutrino g, Sneutrino (-g)), Scalar4 1, G_HHSFSF (SN,M1,M1,g)) ] let higgs_sfermion4' g m1 m2 = [ ((H_Heavy, H_Heavy, Slepton (m1,g), Slepton (m2,-g)), Scalar4 1, G_H2H2SFSF (SL,m1,m2,g)); ((H_Heavy, H_Light, Slepton (m1,g), Slepton (m2,-g)), Scalar4 1, G_H1H2SFSF (SL,m1,m2,g)); ((H_Light, H_Light, Slepton (m1,g), Slepton (m2,-g)), Scalar4 1, G_H1H1SFSF (SL,m1,m2,g)); ((A, A, Slepton (m1,g), Slepton (m2,-g)), Scalar4 1, G_AASFSF (SL,m1,m2,g)); ((Hp, Hm, Slepton (m1,g), Slepton (m2,-g)), Scalar4 1, G_HHSFSF (SL,m1,m2,g)); ((H_Heavy, H_Heavy, Sup (m1,g), Sup (m2,-g)), Scalar4 1, G_H2H2SFSF (SU,m1,m2,g)); ((H_Heavy, H_Heavy, Sdown (m1,g), Sdown (m2,-g)), Scalar4 1, G_H2H2SFSF (SD,m1,m2,g)); ((H_Light, H_Light, Sup (m1,g), Sup (m2,-g)), Scalar4 1, G_H1H1SFSF (SU,m1,m2,g)); ((H_Light, H_Light, Sdown (m1,g), Sdown (m2,-g)), Scalar4 1, G_H1H1SFSF (SD,m1,m2,g)); ((H_Light, H_Heavy, Sup (m1,g), Sup (m2,-g)), Scalar4 1, G_H1H2SFSF (SU,m1,m2,g)); ((H_Light, H_Heavy, Sdown (m1,g), Sdown (m2,-g)), Scalar4 1, G_H1H2SFSF (SD,m1,m2,g)); ((Hp, Hm, Sup (m1,g), Sup (m2,-g)), Scalar4 1, G_HHSFSF (SU,m1,m2,g)); ((Hp, Hm, Sdown (m1,g), Sdown (m2,-g)), Scalar4 1, G_HHSFSF (SD,m1,m2,g)); ((A, A, Sup (m1,g), Sup (m2,-g)), Scalar4 1, G_AASFSF (SU,m1,m2,g)); ((A, A, Sdown (m1,g), Sdown (m2,-g)), Scalar4 1, G_AASFSF (SD,m1,m2,g)) ] let higgs_sfermion4 g = List.flatten (Product.list2 (higgs_sfermion4' g) [M1;M2] [M1;M2]) let higgs_squark4' g h m1 m2 = [ ((Hp, H_Light, Sup (m1,-g), Sdown (m2,h)), Scalar4 1, G_HH1SUSD (false,m1,m2,g,h)); ((Hm, H_Light, Sup (m1,g), Sdown (m2,-h)), Scalar4 1, G_HH1SUSD (true,m1,m2,g,h)); ((Hp, H_Heavy, Sup (m1,-g), Sdown (m2,h)), Scalar4 1, G_HH2SUSD (false,m1,m2,g,h)); ((Hm, H_Heavy, Sup (m1,g), Sdown (m2,-h)), Scalar4 1, G_HH2SUSD (true,m1,m2,g,h)); ((Hp, A, Sup (m1,-g), Sdown (m2,h)), Scalar4 1, G_HASUSD (false,m1,m2,g,h)); ((Hm, A, Sup (m1,g), Sdown (m2,-h)), Scalar4 1, G_HASUSD (true,m1,m2,g,h)) ] let higgs_squark4 g h = List.flatten (Product.list2 (higgs_squark4' g h) [M1;M2] [M1;M2]) let higgs_gold_sneutrino' g m = [ ((Hp, Phi0, Sneutrino (-g), Slepton (m,g)), Scalar4 1, G_HGSNSL (false,m,g)); ((Hm, Phi0, Sneutrino g, Slepton (m,-g)), Scalar4 1, G_HGSNSL (true,m,g)); ((H_Heavy, Phip, Sneutrino (-g), Slepton (m,g)), Scalar4 1, G_H2GSNSL (false,m,g)); ((H_Heavy, Phim, Sneutrino g, Slepton (m,-g)), Scalar4 1, G_H2GSNSL (true,m,g)); ((H_Light, Phip, Sneutrino (-g), Slepton (m,g)), Scalar4 1, G_H1GSNSL (false,m,g)); ((H_Light, Phim, Sneutrino g, Slepton (m,-g)), Scalar4 1, G_H1GSNSL (true,m,g)); ((A, Phip, Sneutrino (-g), Slepton (m,g)), Scalar4 1, G_AGSNSL (false,m,g)); ((A, Phim, Sneutrino g, Slepton (m,-g)), Scalar4 1, G_AGSNSL (true,m,g)); ((Phi0, Phip, Sneutrino (-g), Slepton (m,g)), Scalar4 1, G_GGSNSL (false,m,g)); ((Phi0, Phim, Sneutrino g, Slepton (m,-g)), Scalar4 1, G_GGSNSL (true,m,g))] let higgs_gold_sneutrino g = ThoList.flatmap (higgs_gold_sneutrino' g) [M1;M2] @ [ ((A, Phi0, Sneutrino g, Sneutrino (-g)), Scalar4 1, G_AG0SFSF (SN,M1,M1,g)); ((Hp, Phim, Sneutrino g, Sneutrino (-g)), Scalar4 1, G_HGSFSF (SN,M1,M1,g)); ((Hm, Phip, Sneutrino g, Sneutrino (-g)), Scalar4 1, G_HGSFSF (SN,M1,M1,g)); ((Phip, Phim, Sneutrino g, Sneutrino (-g)), Scalar4 1, G_GGSFSF (SN,M1,M1,g)); ((Phi0, Phi0, Sneutrino g, Sneutrino (-g)), Scalar4 1, G_G0G0SFSF (SN,M1,M1,g)) ] let higgs_gold_sfermion' g m1 m2 = [ ((A, Phi0, Slepton (m1,g), Slepton (m2,-g)), Scalar4 1, G_AG0SFSF (SL,m1,m2,g)); ((Hp, Phim, Slepton (m1,g), Slepton (m2,-g)), Scalar4 1, G_HGSFSF (SL,m1,m2,g)); ((Hm, Phip, Slepton (m1,g), Slepton (m2,-g)), Scalar4 1, G_HGSFSF (SL,m1,m2,g)); ((Phip, Phim, Slepton (m1,g), Slepton (m2,-g)), Scalar4 1, G_GGSFSF (SL,m1,m2,g)); ((Phi0, Phi0, Slepton (m1,g), Slepton (m2,-g)), Scalar4 1, G_G0G0SFSF (SL,m1,m2,g)); ((A, Phi0, Sup (m1,g), Sup (m2,-g)), Scalar4 1, G_AG0SFSF (SU,m1,m2,g)); ((A, Phi0, Sdown (m1,g), Sdown (m2,-g)), Scalar4 1, G_AG0SFSF (SD,m1,m2,g)); ((Hp, Phim, Sup (m1,g), Sup (m2,-g)), Scalar4 1, G_HGSFSF (SU,m1,m2,g)); ((Hm, Phip, Sup (m1,g), Sup (m2,-g)), Scalar4 1, G_HGSFSF (SU,m1,m2,g)); ((Hp, Phim, Sdown (m1,g), Sdown (m2,-g)), Scalar4 1, G_HGSFSF (SD,m1,m2,g)); ((Hm, Phip, Sdown (m1,g), Sdown (m2,-g)), Scalar4 1, G_HGSFSF (SD,m1,m2,g)); ((Phip, Phim, Sup (m1,g), Sup (m2,-g)), Scalar4 1, G_GGSFSF (SU,m1,m2,g)); ((Phip, Phim, Sdown (m1,g), Sdown (m2,-g)), Scalar4 1, G_GGSFSF (SD,m1,m2,g)); ((Phi0, Phi0, Sup (m1,g), Sup (m2,-g)), Scalar4 1, G_G0G0SFSF (SU,m1,m2,g)); ((Phi0, Phi0, Sdown (m1,g), Sdown (m2,-g)), Scalar4 1, G_G0G0SFSF (SD,m1,m2,g)) ] let higgs_gold_sfermion g = List.flatten (Product.list2 (higgs_gold_sfermion' g) [M1;M2] [M1;M2]) let higgs_gold_squark' g h m1 m2 = [ ((Hp, Phi0, Sup (m1,-g), Sdown (m2,h)), Scalar4 1, G_HGSUSD (false,m1,m2,g,h)); ((Hm, Phi0, Sup (m1,g), Sdown (m2,-h)), Scalar4 1, G_HGSUSD (true,m1,m2,g,h)); ((H_Heavy, Phip, Sup (m1,-g), Sdown (m2,h)), Scalar4 1, G_H2GSUSD (false,m1,m2,g,h)); ((H_Heavy, Phim, Sup (m1,g), Sdown (m2,-h)), Scalar4 1, G_H2GSUSD (true,m1,m2,g,h)); ((H_Light, Phip, Sup (m1,-g), Sdown (m2,h)), Scalar4 1, G_H1GSUSD (false,m1,m2,g,h)); ((H_Light, Phim, Sup (m1,g), Sdown (m2,-h)), Scalar4 1, G_H1GSUSD (true,m1,m2,g,h)); ((A, Phip, Sup (m1,-g), Sdown (m2,h)), Scalar4 1, G_AGSUSD (false,m1,m2,g,h)); ((A, Phim, Sup (m1,g), Sdown (m2,-h)), Scalar4 1, G_AGSUSD (true,m1,m2,g,h)); ((Phi0, Phip, Sup (m1,-g), Sdown (m2,h)), Scalar4 1, G_GGSUSD (false,m1,m2,g,h)); ((Phi0, Phim, Sup (m1,g), Sdown (m2,-h)), Scalar4 1, G_GGSUSD (true,m1,m2,g,h)) ] let higgs_gold_squark g h = List.flatten (Product.list2 (higgs_gold_squark' g h) [M1;M2] [M1;M2]) let sneutrino4' (g,h) = [ ((Sneutrino g, Sneutrino h, Sneutrino (-g), Sneutrino (-h)), Scalar4 1, G_SN4 (g,h))] let sneutrino4 = ThoList.flatmap sneutrino4' [(1,1);(1,2);(1,3);(2,2);(2,3);(3,3)] let sneu2_slep2_1' g h m1 m2 = ((Sneutrino (-g), Sneutrino g, Slepton (m1,-h), Slepton (m2,h)), Scalar4 1, G_SN2SL2_1 (m1,m2,g,h)) let sneu2_slep2_2' (g,h) m1 m2 = ((Sneutrino g, Sneutrino (-h), Slepton (m1,-g), Slepton (m2,h)), Scalar4 1, G_SN2SL2_2 (m1,m2,g,h)) let sneu2_slep2_1 g h = Product.list2 (sneu2_slep2_1' g h) [M1;M2] [M1;M2] let sneu2_slep2_2 (g,h) = Product.list2 (sneu2_slep2_2' (g,h)) [M1;M2] [M1;M2] (* The 4-slepton-vertices have the following structure: The sleptons come up in pairs of a positive and a negative slepton of the same generation; there is no vertex with e.g. two negative selectrons and two positive smuons, that of course would be a contradiction to the conservation of the separate slepton numbers of each generation which is not implemented in the MSSM. Because there is no CKM-mixing for the sleptons (in case of massless neutrinos) we maximally have two different generations of sleptons in a 4-slepton-vertex. *) let slepton4_1gen' g (m1,m2,m3,m4) = [ ((Slepton (m1,-g), Slepton (m2,g), Slepton (m3,-g), Slepton (m4,g)), Scalar4 1, G_SL4 (m1,m2,m3,m4,g)) ] let slepton4_1gen g = ThoList.flatmap (slepton4_1gen' g) [(M1,M1,M1,M1); (M1,M1,M1,M2); (M1,M1,M2,M1); (M1,M1,M2,M2); (M1,M2,M1,M2); (M1,M2,M2,M1); (M1,M2,M2,M2); (M2,M1,M2,M2); (M2,M2,M2,M2) ] let slepton4_2gen' (g,h) (m1,m2) (m3,m4) = ((Slepton (m1,-g), Slepton (m2,g), Slepton (m3,-h), Slepton (m4,h)), Scalar4 1, G_SL4_2 (m1,m2,m3,m4,g,h)) let slepton4_2gen (g,h) = Product.list2 (slepton4_2gen' (g,h)) [(M1,M1);(M1,M2);(M2,M1);(M2,M2)] [(M1,M1);(M1,M2);(M2,M1);(M2,M2)] let sneu2_squark2' g h m1 m2 = [ ((Sneutrino (-g), Sneutrino g, Sup (m1,-h), Sup (m2,h)), Scalar4 1, G_SN2SQ2 (SU,m1,m2,g,h)); ((Sneutrino (-g), Sneutrino g, Sdown (m1,-h), Sdown (m2,h)), Scalar4 1, G_SN2SQ2 (SD,m1,m2,g,h)) ] let sneu2_squark2 g h = List.flatten (Product.list2 (sneu2_squark2' g h) [M1;M2] [M1;M2]) let slepton2_squark2'' g h m1 m2 m3 m4 = [ ((Slepton (m1,-g), Slepton (m2,g), Sup (m3,-h), Sup (m4,h)), Scalar4 1, G_SL2SQ2 (SU,m1,m2,m3,m4,g,h)); ((Slepton (m1,-g), Slepton (m2,g), Sdown (m3,-h), Sdown (m4,h)), Scalar4 1, G_SL2SQ2 (SD,m1,m2,m3,m4,g,h)) ] let slepton2_squark2' g h m1 m2 = List.flatten (Product.list2 (slepton2_squark2'' g h m1 m2) [M1;M2] [M1;M2]) let slepton2_squark2 g h = List.flatten (Product.list2 (slepton2_squark2' g h) [M1;M2] [M1;M2]) let slep_sneu_squark2'' g1 g2 g3 m1 m2 m3 = [ ((Sup (m1,-g1), Sdown (m2,g2), Slepton (m3,-g3), Sneutrino g3), Scalar4 1, G_SUSDSNSL (false,m1,m2,m3,g1,g2,g3)); ((Sup (m1,g1), Sdown (m2,-g2), Slepton (m3,g3), Sneutrino (-g3)), Scalar4 1, G_SUSDSNSL (true,m1,m2,m3,g1,g2,g3)) ] let slep_sneu_squark2' g1 g2 g3 m1 = List.flatten (Product.list2 (slep_sneu_squark2'' g1 g2 g3 m1) [M1;M2] [M1;M2]) let slep_sneu_squark2 g1 g2 = List.flatten (Product.list2 (slep_sneu_squark2' g1 g2) [1;2;3] [M1;M2]) (* There are three kinds of 4-squark-vertices: Four up-Squarks, four down-squarks or two up- and two down-squarks. *) let sup4_1gen' g (m1,m2,m3,m4) = [ ((Sup (m1,-g), Sup (m2,g), Sup (m3,-g), Sup (m4,g)), Scalar4 1, G_SU4 (m1,m2,m3,m4,g)) ] let sup4_1gen g = ThoList.flatmap (sup4_1gen' g) [(M1,M1,M1,M1); (M1,M1,M1,M2); (M1,M1,M2,M1); (M1,M1,M2,M2); (M1,M2,M1,M2); (M1,M2,M2,M1); (M1,M2,M2,M2); (M2,M1,M2,M2); (M2,M2,M2,M2) ] let sup4_2gen' (g,h) (m1,m2) (m3,m4) = ((Sup (m1,-g), Sup (m2,g), Sup (m3,-h), Sup (m4,h)), Scalar4 1, G_SU4_2 (m1,m2,m3,m4,g,h)) let sup4_2gen (g,h) = Product.list2 (sup4_2gen' (g,h)) [(M1,M1);(M1,M2);(M2,M1);(M2,M2)] [(M1,M1);(M1,M2);(M2,M1);(M2,M2)] let sdown4_1gen' g (m1,m2,m3,m4) = [ ((Sdown (m1,-g), Sdown (m2,g), Sdown (m3,-g), Sdown (m4,g)), Scalar4 1, G_SD4 (m1,m2,m3,m4,g)) ] let sdown4_1gen g = ThoList.flatmap (sdown4_1gen' g) [(M1,M1,M1,M1); (M1,M1,M1,M2); (M1,M1,M2,M1); (M1,M1,M2,M2); (M1,M2,M1,M2); (M1,M2,M2,M1); (M1,M2,M2,M2); (M2,M1,M2,M2); (M2,M2,M2,M2) ] let sdown4_2gen' (g,h) (m1,m2) (m3,m4) = ((Sdown (m1,-g), Sdown (m2,g), Sdown (m3,-h), Sdown (m4,h)), Scalar4 1, G_SD4_2 (m1,m2,m3,m4,g,h)) let sdown4_2gen (g,h) = Product.list2 (sdown4_2gen' (g,h)) [(M1,M1);(M1,M2);(M2,M1);(M2,M2)] [(M1,M1);(M1,M2);(M2,M1);(M2,M2)] let sup2_sdown2_3 g1 g2 g3 g4 m1 m2 m3 m4 = ((Sup (m1,-g1), Sup (m2,g2), Sdown (m3,-g3), Sdown (m4,g4)), Scalar4 1, G_SU2SD2 (m1,m2,m3,m4,g1,g2,g3,g4)) let sup2_sdown2_2 g1 g2 g3 g4 m1 m2 = Product.list2 (sup2_sdown2_3 g1 g2 g3 g4 m1 m2) [M1;M2] [M1;M2] let sup2_sdown2_1 g1 g2 g3 g4 = List.flatten (Product.list2 (sup2_sdown2_2 g1 g2 g3 g4) [M1;M2] [M1;M2]) let sup2_sdown2 g1 g2 = List.flatten (Product.list2 (sup2_sdown2_1 g1 g2) [1;2;3] [1;2;3]) let quartic_grav_gauge g m = [ ((Grino, Slepton (m, -g), Ga, L g), GBBG (1, Gravbar, SLRV, Psi), G_Gr4A_Sl (g,m)); ((L (-g), Slepton (m, g), Ga, Grino), GBBG (1, Psibar, SLRV, Grav), G_Gr4A_Slc (g,m)); ((Grino, Sup (m, -g), Ga, U g), GBBG (1, Gravbar, SLRV, Psi), G_Gr4A_Su (g,m)); ((U (-g), Sup (m, g), Ga, Grino), GBBG (1, Psibar, SLRV, Grav), G_Gr4A_Suc (g,m)); ((Grino, Sdown (m, -g), Ga, D g), GBBG (1, Gravbar, SLRV, Psi), G_Gr4A_Sd (g,m)); ((D (-g), Sdown (m, g), Ga, Grino), GBBG (1, Psibar, SLRV, Grav), G_Gr4A_Sdc (g,m)); ((Grino, Slepton (m, -g), Z, L g), GBBG (1, Gravbar, SLRV, Psi), G_Gr4Z_Sl (g,m)); ((L (-g), Slepton (m, g), Z, Grino), GBBG (1, Psibar, SLRV, Grav), G_Gr4Z_Slc (g,m)); ((Grino, Sup (m, -g), Z, U g), GBBG (1, Gravbar, SLRV, Psi), G_Gr4Z_Su (g,m)); ((U (-g), Sup (m, g), Z, Grino), GBBG (1, Psibar, SLRV, Grav), G_Gr4Z_Suc (g,m)); ((Grino, Sdown (m, -g), Z, D g), GBBG (1, Gravbar, SLRV, Psi), G_Gr4Z_Sd (g,m)); ((D (-g), Sdown (m, g), Z, Grino), GBBG (1, Psibar, SLRV, Grav), G_Gr4Z_Sdc (g,m)); ((Grino, Sup (m, -g), Gl, U g), GBBG (1, Gravbar, SLRV, Psi), G_Gr4Gl_Su (g,m)); ((U (-g), Sup (m, g), Gl, Grino), GBBG (1, Psibar, SLRV, Grav), G_Gr4Gl_Suc (g,m)); ((Grino, Sdown (m, -g), Gl, D g), GBBG (1, Gravbar, SLRV, Psi), G_Gr4Gl_Sd (g,m)); ((D (-g), Sdown (m, g), Gl, Grino), GBBG (1, Psibar, SLRV, Grav), G_Gr4Gl_Sdc (g,m)); ((Grino, Slepton (m, -g), Wm, N g), GBBG (1, Gravbar, SLV, Psi), G_Gr4W_Sl (g,m)); ((N (-g), Slepton (m, g), Wp, Grino), GBBG (1, Psibar, SLV, Grav), G_Gr4Z_Slc (g,m)); ((Grino, Sup (m, -g), Wp, D g), GBBG (1, Gravbar, SLV, Psi), G_Gr4W_Su (g,m)); ((D (-g), Sup (m, g), Wm, Grino), GBBG (1, Psibar, SLV, Grav), G_Gr4W_Suc (g,m)); ((Grino, Sdown (m, -g), Wm, U g), GBBG (1, Gravbar, SLV, Psi), G_Gr4W_Sd (g,m)); ((U (-g), Sdown (m, g), Wp, Grino), GBBG (1, Psibar, SLV, Grav), G_Gr4W_Sdc (g,m)) ] let quartic_grav_sneutrino g = [ ((Grino, Sneutrino (-g), Z, N g), GBBG (1, Gravbar, SLV, Psi), G_Gr4Z_Sn); ((N (-g), Sneutrino g, Z, Grino), GBBG (1, Psibar, SLV, Grav), G_Gr4Z_Snc); ((Grino, Sneutrino (-g), Wp, L g), GBBG (1, Gravbar, SLV, Psi), G_Gr4W_Sn); ((L (-g), Sneutrino g, Wm, Grino), GBBG (1, Psibar, SLV, Grav), G_Gr4W_Snc) ] let quartic_grav_neu n = [ ((Grino, Wp, Wm, Neutralino n), GBBG (1, Gravbar, V2LR, Chi), G_Gr4_Neu n); ((Grino, H_Light, Z, Neutralino n), GBBG (1, Gravbar, SLRV, Chi), G_Gr4_Z_H1 n); ((Grino, H_Heavy, Z, Neutralino n), GBBG (1, Gravbar, SLRV, Chi), G_Gr4_Z_H2 n); ((Grino, A, Z, Neutralino n), GBBG (1, Gravbar, SLRV, Chi), G_Gr4_Z_H3 n); ((Grino, Hm, Wp, Neutralino n), GBBG (1, Gravbar, SLRV, Chi), G_Gr4_W_H n); ((Grino, Hp, Wm, Neutralino n), GBBG (1, Gravbar, SLRV, Chi), G_Gr4_W_Hc n) ] let quartic_grav_char c = let cc = conj_char c in [ ((Grino, Wm, Ga, Chargino c), GBBG (1, Gravbar, V2LR, Psi), G_Gr4_A_Ch c); ((Grino, Wm, Z, Chargino c), GBBG (1, Gravbar, V2LR, Psi), G_Gr4_Z_Ch c); ((Chargino cc, Wp, Ga, Grino), GBBG ((-1), Psibar, V2LR, Grav), G_Gr4_A_Ch cc); ((Chargino cc, Wp, Z, Grino), GBBG ((-1), Psibar, V2LR, Grav), G_Gr4_Z_Ch cc); ((Grino, Hm, Ga, Chargino c), GBBG (1, Gravbar, SLRV, Psi), G_Gr4_H_A c); ((Chargino cc, Hp, Ga, Grino), GBBG (1, Psibar, SLRV, Grav), G_Gr4_H_A cc); ((Grino, Hm, Z, Chargino c), GBBG (1, Gravbar, SLRV, Psi), G_Gr4_H_Z c); ((Chargino cc, Hp, Z, Grino), GBBG (1, Psibar, SLRV, Grav), G_Gr4_H_Z cc)] let quartic_gravitino = [ ((Grino, Gl, Gl, Gluino), GBBG (1, Gravbar, V2, Chi), G_GravGl)] @ ThoList.flatmap quartic_grav_neu [N1; N2; N3; N4] @ ThoList.flatmap quartic_grav_char [C1; C2] @ List.flatten (Product.list2 quartic_grav_gauge [1; 2; 3] [M1; M2]) @ ThoList.flatmap quartic_grav_sneutrino [1; 2; 3] let vertices3'' = if Flags.ckm_present then (ThoList.flatmap electromagnetic_currents_3 [1;2;3] @ ThoList.flatmap electromagnetic_currents_2 [C1;C2] @ List.flatten (Product.list2 electromagnetic_sfermion_currents [1;2;3] [M1;M2]) @ ThoList.flatmap neutral_currents [1;2;3] @ ThoList.flatmap neutral_sfermion_currents [1;2;3] @ ThoList.flatmap charged_currents [1;2;3] @ List.flatten (Product.list2 charged_slepton_currents [1;2;3] [M1;M2]) @ List.flatten (Product.list2 charged_quark_currents [1;2;3] [1;2;3]) @ List.flatten (Product.list2 charged_squark_currents [1;2;3] [1;2;3]) @ ThoList.flatmap yukawa_higgs_quark [(1,3);(2,3);(3,3);(3,1);(3,2)] @ yukawa_higgs 3 @ yukawa_n @ ThoList.flatmap yukawa_c [C1;C2] @ ThoList.flatmap yukawa_cq [C1;C2] @ List.flatten (Product.list2 charged_chargino_currents [N1;N2;N3;N4] [C1;C2]) @ triple_gauge @ ThoList.flatmap neutral_Z_1 [(N1,N2);(N1,N3);(N1,N4);(N2,N3);(N2,N4); (N3,N4)] @ ThoList.flatmap neutral_Z_2 [N1;N2;N3;N4] @ neutral_A @ Product.list2 charged_Z [C1;C2] [C1;C2] @ gauge_higgs @ higgs @ yukawa_higgs_2 @ List.flatten (Product.list2 higgs_charg_neutr [N1;N2;N3;N4] [C1;C2]) @ higgs_neutr @ higgs_sneutrino @ higgs_sfermion @ higgs_squark @ yukawa_v @ ThoList.flatmap col_currents [1;2;3] @ List.flatten (Product.list2 col_sfermion_currents [1;2;3] [M1;M2])) else (ThoList.flatmap electromagnetic_currents_3 [1;2;3] @ ThoList.flatmap electromagnetic_currents_2 [C1;C2] @ List.flatten (Product.list2 electromagnetic_sfermion_currents [1;2;3] [M1;M2]) @ ThoList.flatmap neutral_currents [1;2;3] @ ThoList.flatmap neutral_sfermion_currents [1;2;3] @ ThoList.flatmap charged_currents [1;2;3] @ List.flatten (Product.list2 charged_slepton_currents [1;2;3] [M1;M2]) @ charged_quark_currents 1 1 @ charged_quark_currents 2 2 @ charged_quark_currents 3 3 @ charged_squark_currents 1 1 @ charged_squark_currents 2 2 @ charged_squark_currents 3 3 @ ThoList.flatmap yukawa_higgs_quark [(3,3)] @ yukawa_higgs 3 @ yukawa_n @ ThoList.flatmap yukawa_c [C1;C2] @ ThoList.flatmap yukawa_cq [C1;C2] @ List.flatten (Product.list2 charged_chargino_currents [N1;N2;N3;N4] [C1;C2]) @ triple_gauge @ ThoList.flatmap neutral_Z_1 [(N1,N2);(N1,N3);(N1,N4);(N2,N3);(N2,N4); (N3,N4)] @ ThoList.flatmap neutral_Z_2 [N1;N2;N3;N4] @ neutral_A @ Product.list2 charged_Z [C1;C2] [C1;C2] @ gauge_higgs @ higgs @ yukawa_higgs_2 @ List.flatten (Product.list2 higgs_charg_neutr [N1;N2;N3;N4] [C1;C2]) @ higgs_neutr @ higgs_sneutrino @ higgs_sfermion @ higgs_squark @ yukawa_v @ ThoList.flatmap col_currents [1;2;3] @ List.flatten (Product.list2 col_sfermion_currents [1;2;3] [M1;M2])) let vertices3' = if Flags.gravitino then (vertices3'' @ triple_gravitino) else vertices3'' let vertices3 = if Flags.include_goldstone then (vertices3' @ yukawa_goldstone 3 @ gauge_higgs_gold @ higgs_gold @ yukawa_goldstone_2 @ (if Flags.ckm_present then List.flatten (Product.list2 yukawa_goldstone_quark [1;2;3] [1;2;3]) @ List.flatten (Product.list2 goldstone_charg_neutr [N1;N2;N3;N4] [C1;C2]) else yukawa_goldstone_quark 1 1 @ yukawa_goldstone_quark 2 2 @ yukawa_goldstone_quark 3 3) @ goldstone_neutr @ goldstone_sfermion @ goldstone_squark) else vertices3' let vertices4''' = (quartic_gauge @ higgs4 @ gauge_higgs4 @ ThoList.flatmap gauge_sfermion4 [1;2;3] @ gauge_squark4 @ gluon_w_squark @ List.flatten (Product.list2 gluon2_squark2 [1;2;3] [M1;M2]) @ ThoList.flatmap gluon_gauge_squark [1;2;3]) let vertices4'' = if Flags.gravitino then (vertices4''' @ quartic_gravitino) else vertices4''' let vertices4' = if Flags.include_four then (vertices4'' @ ThoList.flatmap higgs_sfermion4 [1;2;3] @ ThoList.flatmap higgs_sneutrino4 [1;2;3] @ List.flatten (Product.list2 higgs_squark4 [1;2;3] [1;2;3]) @ sneutrino4 @ List.flatten (Product.list2 sneu2_slep2_1 [1;2;3] [1;2;3]) @ ThoList.flatmap sneu2_slep2_2 [(1,2);(1,3);(2,3);(2,1);(3,1);(3,2)] @ ThoList.flatmap slepton4_1gen [1;2;3] @ ThoList.flatmap slepton4_2gen [(1,2);(1,3);(2,3)] @ List.flatten (Product.list2 sneu2_squark2 [1;2;3] [1;2;3]) @ List.flatten (Product.list2 slepton2_squark2 [1;2;3] [1;2;3]) @ List.flatten (Product.list2 slep_sneu_squark2 [1;2;3] [1;2;3]) @ ThoList.flatmap sup4_1gen [1;2;3] @ ThoList.flatmap sup4_2gen [(1,2);(1,3);(2,3)] @ ThoList.flatmap sdown4_1gen [1;2;3] @ ThoList.flatmap sdown4_2gen [(1,2);(1,3);(2,3)] @ List.flatten (Product.list2 sup2_sdown2 [1;2;3] [1;2;3])) else vertices4'' let vertices4 = if Flags.include_goldstone then (vertices4' @ higgs_gold4 @ gauge_higgs_gold4 @ goldstone4 @ ThoList.flatmap higgs_gold_sneutrino [1;2;3] @ ThoList.flatmap higgs_gold_sfermion [1;2;3] @ List.flatten (Product.list2 higgs_gold_squark [1;2;3] [1;2;3])) else vertices4' let vertices () = (vertices3, vertices4, []) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 let flavor_of_string s = match s with | "e-" -> L 1 | "e+" -> L (-1) | "mu-" -> L 2 | "mu+" -> L (-2) | "tau-" -> L 3 | "tau+" -> L (-3) | "nue" -> N 1 | "nuebar" -> N (-1) | "numu" -> N 2 | "numubar" -> N (-2) | "nutau" -> N 3 | "nutaubar" -> N (-3) | "se1-" -> Slepton (M1,1) | "se1+" -> Slepton (M1,-1) | "smu1-" -> Slepton (M1,2) | "smu1+" -> Slepton (M1,-2) | "stau1-" -> Slepton (M1,3) | "stau1+" -> Slepton (M1,-3) | "se2-" -> Slepton (M2,1) | "se2+" -> Slepton (M2,-1) | "smu2-" -> Slepton (M2,2) | "smu2+" -> Slepton (M2,-2) | "stau2-" -> Slepton (M2,3) | "stau2+" -> Slepton (M2,-3) | "snue" -> Sneutrino 1 | "snue*" -> Sneutrino (-1) | "snumu" -> Sneutrino 2 | "snumu*" -> Sneutrino (-2) | "snutau" -> Sneutrino 3 | "snutau*" -> Sneutrino (-3) | "u" -> U 1 | "ubar" -> U (-1) | "c" -> U 2 | "cbar" -> U (-2) | "t" -> U 3 | "tbar" -> U (-3) | "d" -> D 1 | "dbar" -> D (-1) | "s" -> D 2 | "sbar" -> D (-2) | "b" -> D 3 | "bbar" -> D (-3) | "A" -> Ga | "Z" | "Z0" -> Z | "W+" -> Wp | "W-" -> Wm | "gl" | "g" -> Gl | "H" -> H_Heavy | "h" -> H_Light | "A0" -> A | "H+" -> Hp | "H-" -> Hm | "phi0" -> Phi0 | "phi+" -> Phip | "phim" -> Phim | "su1" -> Sup (M1,1) | "su1c" -> Sup (M1,-1) | "sc1" -> Sup (M1,2) | "sc1c" -> Sup (M1,-2) | "st1" -> Sup (M1,3) | "st1c" -> Sup (M1,-3) | "su2" -> Sup (M2,1) | "su2c" -> Sup (M2,-1) | "sc2" -> Sup (M2,2) | "sc2c" -> Sup (M2,-2) | "st2" -> Sup (M2,3) | "st2c" -> Sup (M2,-3) | "sgl" | "sg" -> Gluino | "sd1" -> Sdown (M1,1) | "sd1c" -> Sdown (M1,-1) | "ss1" -> Sdown (M1,2) | "ss1c" -> Sdown (M1,-2) | "sb1" -> Sdown (M1,3) | "sb1c" -> Sdown (M1,-3) | "sd2" -> Sdown (M2,1) | "sd2c" -> Sdown (M2,-1) | "ss2" -> Sdown (M2,2) | "ss2c" -> Sdown (M2,-2) | "sb2" -> Sdown (M2,3) | "sb2c" -> Sdown (M2,-3) | "neu1" -> Neutralino N1 | "neu2" -> Neutralino N2 | "neu3" -> Neutralino N3 | "neu4" -> Neutralino N4 | "ch1+" -> Chargino C1 | "ch2+" -> Chargino C2 | "ch1-" -> Chargino C1c | "ch2-" -> Chargino C2c | "GR" -> Grino | _ -> invalid_arg "Modellib_MSSM.MSSM.flavor_of_string" let flavor_to_string = function | L 1 -> "e-" | L (-1) -> "e+" | L 2 -> "mu-" | L (-2) -> "mu+" | L 3 -> "tau-" | L (-3) -> "tau+" | N 1 -> "nue" | N (-1) -> "nuebar" | N 2 -> "numu" | N (-2) -> "numubar" | N 3 -> "nutau" | N (-3) -> "nutaubar" | U 1 -> "u" | U (-1) -> "ubar" | U 2 -> "c" | U (-2) -> "cbar" | U 3 -> "t" | U (-3) -> "tbar" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | L _ -> invalid_arg "Modellib_MSSM.MSSM.flavor_to_string: invalid lepton" | N _ -> invalid_arg "Modellib_MSSM.MSSM.flavor_to_string: invalid neutrino" | U _ -> invalid_arg "Modellib_MSSM.MSSM.flavor_to_string: invalid up type quark" | D _ -> invalid_arg "Modellib_MSSM.MSSM.flavor_to_string: invalid down type quark" | Gl -> "gl" | Gluino -> "sgl" | Ga -> "A" | Z -> "Z" | Wp -> "W+" | Wm -> "W-" | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | H_Heavy -> "H" | H_Light -> "h" | A -> "A0" | Hp -> "H+" | Hm -> "H-" | Slepton (M1,1) -> "se1-" | Slepton (M1,-1) -> "se1+" | Slepton (M1,2) -> "smu1-" | Slepton (M1,-2) -> "smu1+" | Slepton (M1,3) -> "stau1-" | Slepton (M1,-3) -> "stau1+" | Slepton (M2,1) -> "se2-" | Slepton (M2,-1) -> "se2+" | Slepton (M2,2) -> "smu2-" | Slepton (M2,-2) -> "smu2+" | Slepton (M2,3) -> "stau2-" | Slepton (M2,-3) -> "stau2+" | Sneutrino 1 -> "snue" | Sneutrino (-1) -> "snue*" | Sneutrino 2 -> "snumu" | Sneutrino (-2) -> "snumu*" | Sneutrino 3 -> "snutau" | Sneutrino (-3) -> "snutau*" | Sup (M1,1) -> "su1" | Sup (M1,-1) -> "su1c" | Sup (M1,2) -> "sc1" | Sup (M1,-2) -> "sc1c" | Sup (M1,3) -> "st1" | Sup (M1,-3) -> "st1c" | Sup (M2,1) -> "su2" | Sup (M2,-1) -> "su2c" | Sup (M2,2) -> "sc2" | Sup (M2,-2) -> "sc2c" | Sup (M2,3) -> "st2" | Sup (M2,-3) -> "st2c" | Sdown (M1,1) -> "sd1" | Sdown (M1,-1) -> "sd1c" | Sdown (M1,2) -> "ss1" | Sdown (M1,-2) -> "ss1c" | Sdown (M1,3) -> "sb1" | Sdown (M1,-3) -> "sb1c" | Sdown (M2,1) -> "sd2" | Sdown (M2,-1) -> "sd2c" | Sdown (M2,2) -> "ss2" | Sdown (M2,-2) -> "ss2c" | Sdown (M2,3) -> "sb2" | Sdown (M2,-3) -> "sb2c" | Neutralino N1 -> "neu1" | Neutralino N2 -> "neu2" | Neutralino N3 -> "neu3" | Neutralino N4 -> "neu4" | Slepton _ -> invalid_arg "Modellib_MSSM.MSSM.flavor_to_string: invalid slepton" | Sneutrino _ -> invalid_arg "Modellib_MSSM.MSSM.flavor_to_string: invalid sneutrino" | Sup _ -> invalid_arg "Modellib_MSSM.MSSM.flavor_to_string: invalid up type squark" | Sdown _ -> invalid_arg "Modellib_MSSM.MSSM.flavor_to_string: invalid down type squark" | Chargino C1 -> "ch1+" | Chargino C1c -> "ch1-" | Chargino C2 -> "ch2+" | Chargino C2c -> "ch2-" | Grino -> "GR" let flavor_symbol = function | L g when g > 0 -> "l" ^ string_of_int g | L g -> "l" ^ string_of_int (abs g) ^ "b" | N g when g > 0 -> "n" ^ string_of_int g | N g -> "n" ^ string_of_int (abs g) ^ "b" | U g when g > 0 -> "u" ^ string_of_int g | U g -> "u" ^ string_of_int (abs g) ^ "b" | D g when g > 0 -> "d" ^ string_of_int g | D g -> "d" ^ string_of_int (abs g) ^ "b" | Gl -> "gl" | Ga -> "a" | Z -> "z" | Wp -> "wp" | Wm -> "wm" | Slepton (M1,g) when g > 0 -> "sl1" ^ string_of_int g | Slepton (M1,g) -> "sl1c" ^ string_of_int (abs g) | Slepton (M2,g) when g > 0 -> "sl2" ^ string_of_int g | Slepton (M2,g) -> "sl2c" ^ string_of_int (abs g) | Sneutrino g when g > 0 -> "sn" ^ string_of_int g | Sneutrino g -> "snc" ^ string_of_int (abs g) | Sup (M1,g) when g > 0 -> "su1" ^ string_of_int g | Sup (M1,g) -> "su1c" ^ string_of_int (abs g) | Sup (M2,g) when g > 0 -> "su2" ^ string_of_int g | Sup (M2,g) -> "su2c" ^ string_of_int (abs g) | Sdown (M1,g) when g > 0 -> "sd1" ^ string_of_int g | Sdown (M1,g) -> "sd1c" ^ string_of_int (abs g) | Sdown (M2,g) when g > 0 -> "sd2" ^ string_of_int g | Sdown (M2,g) -> "sd2c" ^ string_of_int (abs g) | Neutralino n -> "neu" ^ (string_of_neu n) | Chargino c when (int_of_char c) > 0 -> "cp" ^ string_of_char c | Chargino c -> "cm" ^ string_of_int (abs (int_of_char c)) | Gluino -> "sgl" | Phip -> "pp" | Phim -> "pm" | Phi0 -> "p0" | H_Heavy -> "h0h" | H_Light -> "h0l" | A -> "a0" | Hp -> "hp" | Hm -> "hm" | Grino -> "gv" let flavor_to_TeX = function | L 1 -> "e^-" | L (-1) -> "e^+" | L 2 -> "\\mu^-" | L (-2) -> "\\mu^+" | L 3 -> "\\tau^-" | L (-3) -> "\\tau^+" | N 1 -> "\\nu_e" | N (-1) -> "\\bar{\\nu}_e" | N 2 -> "\\nu_\\mu" | N (-2) -> "\\bar{\\nu}_\\mu" | N 3 -> "\\nu_\\tau" | N (-3) -> "\\bar{\\nu}_\\tau" | U 1 -> "u" | U (-1) -> "\\bar{u}" | U 2 -> "c" | U (-2) -> "\\bar{c}" | U 3 -> "t" | U (-3) -> "\\bar{t}" | D 1 -> "d" | D (-1) -> "\\bar{d}" | D 2 -> "s" | D (-2) -> "\\bar{s}" | D 3 -> "b" | D (-3) -> "\\bar{b}" | L _ -> invalid_arg "Modellib_MSSM.MSSM.flavor_to_TeX: invalid lepton" | N _ -> invalid_arg "Modellib_MSSM.MSSM.flavor_to_TeX: invalid neutrino" | U _ -> invalid_arg "Modellib_MSSM.MSSM.flavor_to_TeX: invalid up type quark" | D _ -> invalid_arg "Modellib_MSSM.MSSM.flavor_to_TeX: invalid down type quark" | Gl -> "g" | Gluino -> "\\widetilde{g}" | Ga -> "\\gamma" | Z -> "Z" | Wp -> "W^+" | Wm -> "W^-" | Phip -> "\\phi^+" | Phim -> "\\phi^-" | Phi0 -> "\\phi^0" | H_Heavy -> "H^0" | H_Light -> "h^0" | A -> "A^0" | Hp -> "H^+" | Hm -> "H^-" | Slepton (M1,1) -> "\\widetilde{e}_1^-" | Slepton (M1,-1) -> "\\widetilde{e}_1^+" | Slepton (M1,2) -> "\\widetilde{\\mu}_1^-" | Slepton (M1,-2) -> "\\widetilde{\\mu}_1^+" | Slepton (M1,3) -> "\\widetilde{\\tau}_1^-" | Slepton (M1,-3) -> "\\widetilde{\\tau}_1^+" | Slepton (M2,1) -> "\\widetilde{e}_2^-" | Slepton (M2,-1) -> "\\widetilde{e}_2^+" | Slepton (M2,2) -> "\\widetilde{\\mu}_2^-" | Slepton (M2,-2) -> "\\widetilde{\\mu}_2^+" | Slepton (M2,3) -> "\\widetilde{\\tau}_2^-" | Slepton (M2,-3) -> "\\widetilde{\\tau}_2^+" | Sneutrino 1 -> "\\widetilde{\\nu}_e" | Sneutrino (-1) -> "\\widetilde{\\nu}_e^*" | Sneutrino 2 -> "\\widetilde{\\nu}_\\mu" | Sneutrino (-2) -> "\\widetilde{\\nu}_\\mu^*" | Sneutrino 3 -> "\\widetilde{\\nu}_\\tau" | Sneutrino (-3) -> "\\widetilde{\\nu}_\\tau^*" | Sup (M1,1) -> "\\widetilde{u}_1" | Sup (M1,-1) -> "\\widetilde{u}_1^*" | Sup (M1,2) -> "\\widetilde{c}_1" | Sup (M1,-2) -> "\\widetilde{c}_1^*" | Sup (M1,3) -> "\\widetilde{t}_1" | Sup (M1,-3) -> "\\widetilde{t}_1^*" | Sup (M2,1) -> "\\widetilde{u}_2" | Sup (M2,-1) -> "\\widetilde{u}_2^*" | Sup (M2,2) -> "\\widetilde{c}_2" | Sup (M2,-2) -> "\\widetilde{c}_2^*" | Sup (M2,3) -> "\\widetilde{t}_2" | Sup (M2,-3) -> "\\widetilde{t}_2^*" | Sdown (M1,1) -> "\\widetilde{d}_1" | Sdown (M1,-1) -> "\\widetilde{d}_1^*" | Sdown (M1,2) -> "\\widetilde{s}_1" | Sdown (M1,-2) -> "\\widetilde{s}_1^*" | Sdown (M1,3) -> "\\widetilde{b}_1" | Sdown (M1,-3) -> "\\widetilde{b}_1^*" | Sdown (M2,1) -> "\\widetilde{d}_2" | Sdown (M2,-1) -> "\\widetilde{d}_2^*" | Sdown (M2,2) -> "\\widetilde{s}_2" | Sdown (M2,-2) -> "\\widetilde{s}_2^*" | Sdown (M2,3) -> "\\widetilde{b}_2" | Sdown (M2,-3) -> "\\widetilde{b}_2^*" | Neutralino N1 -> "\\widetilde{\\chi}^0_1" | Neutralino N2 -> "\\widetilde{\\chi}^0_2" | Neutralino N3 -> "\\widetilde{\\chi}^0_3" | Neutralino N4 -> "\\widetilde{\\chi}^0_4" | Slepton _ -> invalid_arg "Modellib_MSSM.MSSM.flavor_to_TeX: invalid slepton" | Sneutrino _ -> invalid_arg "Modellib_MSSM.MSSM.flavor_to_TeX: invalid sneutrino" | Sup _ -> invalid_arg "Modellib_MSSM.MSSM.flavor_to_TeX: invalid up type squark" | Sdown _ -> invalid_arg "Modellib_MSSM.MSSM.flavor_to_TeX: invalid down type squark" | Chargino C1 -> "\\widetilde{\\chi}_1^+" | Chargino C1c -> "\\widetilde{\\chi}_1^-" | Chargino C2 -> "\\widetilde{\\chi}_2^+" | Chargino C2c -> "\\widetilde{\\chi}_2^-" | Grino -> "\\widetilde{G}" let pdg = function | L g when g > 0 -> 9 + 2*g | L g -> - 9 + 2*g | N g when g > 0 -> 10 + 2*g | N g -> - 10 + 2*g | U g when g > 0 -> 2*g | U g -> 2*g | D g when g > 0 -> - 1 + 2*g | D g -> 1 + 2*g | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) | H_Light -> 25 | H_Heavy -> 35 | A -> 36 | Hp -> 37 | Hm -> (-37) | Phip | Phim -> 27 | Phi0 -> 26 | Slepton (M1,g) when g > 0 -> 1000009 + 2*g | Slepton (M1,g) -> - 1000009 + 2*g | Slepton (M2,g) when g > 0 -> 2000009 + 2*g | Slepton (M2,g) -> - 2000009 + 2*g | Sneutrino g when g > 0 -> 1000010 + 2*g | Sneutrino g -> - 1000010 + 2*g | Sup (M1,g) when g > 0 -> 1000000 + 2*g | Sup (M1,g) -> - 1000000 + 2*g | Sup (M2,g) when g > 0 -> 2000000 + 2*g | Sup (M2,g) -> - 2000000 + 2*g | Sdown (M1,g) when g > 0 -> 999999 + 2*g | Sdown (M1,g) -> - 999999 + 2*g | Sdown (M2,g) when g > 0 -> 1999999 + 2*g | Sdown (M2,g) -> - 1999999 + 2*g | Gluino -> 1000021 | Grino -> 1000039 | Chargino C1 -> 1000024 | Chargino C1c -> (-1000024) | Chargino C2 -> 1000037 | Chargino C2c -> (-1000037) | Neutralino N1 -> 1000022 | Neutralino N2 -> 1000023 | Neutralino N3 -> 1000025 | Neutralino N4 -> 1000035 (* We must take care of the pdg numbers for the two different kinds of sfermions in the MSSM. The particle data group in its Monte Carlo particle numbering scheme takes only into account mixtures of the third generation squarks and the stau. For the other sfermions we will use the number of the lefthanded field for the lighter mixed state and the one for the righthanded for the heavier. Below are the official pdg numbers from the Particle Data Group. In order not to produce arrays with some million entries in the Fortran code for the masses and the widths we introduce our private pdg numbering scheme which only extends not too far beyond 42. Our private scheme then has the following pdf numbers (for the sparticles the subscripts $L/R$ and $1/2$ are taken synonymously): \begin{center} \renewcommand{\arraystretch}{1.2} \begin{tabular}{|r|l|l|}\hline $d$ & down-quark & 1 \\\hline $u$ & up-quark & 2 \\\hline $s$ & strange-quark & 3 \\\hline $c$ & charm-quark & 4 \\\hline $b$ & bottom-quark & 5 \\\hline $t$ & top-quark & 6 \\\hline\hline $e^-$ & electron & 11 \\\hline $\nu_e$ & electron-neutrino & 12 \\\hline $\mu^-$ & muon & 13 \\\hline $\nu_\mu$ & muon-neutrino & 14 \\\hline $\tau^-$ & tau & 15 \\\hline $\nu_\tau$ & tau-neutrino & 16 \\\hline\hline $g$ & gluon & (9) 21 \\\hline $\gamma$ & photon & 22 \\\hline $Z^0$ & Z-boson & 23 \\\hline $W^+$ & W-boson & 24 \\\hline\hline $h^0$ & light Higgs boson & 25 \\\hline $H^0$ & heavy Higgs boson & 35 \\\hline $A^0$ & pseudoscalar Higgs & 36 \\\hline $H^+$ & charged Higgs & 37 \\\hline\hline $\widetilde{\psi}_\mu$ & gravitino & 39 \\\hline\hline $\widetilde{d}_L$ & down-squark 1 & 41 \\\hline $\widetilde{u}_L$ & up-squark 1 & 42 \\\hline $\widetilde{s}_L$ & strange-squark 1 & 43 \\\hline $\widetilde{c}_L$ & charm-squark 1 & 44 \\\hline $\widetilde{b}_L$ & bottom-squark 1 & 45 \\\hline $\widetilde{t}_L$ & top-squark 1 & 46 \\\hline $\widetilde{d}_R$ & down-squark 2 & 47 \\\hline $\widetilde{u}_R$ & up-squark 2 & 48 \\\hline $\widetilde{s}_R$ & strange-squark 2 & 49 \\\hline $\widetilde{c}_R$ & charm-squark 2 & 50 \\\hline $\widetilde{b}_R$ & bottom-squark 2 & 51 \\\hline $\widetilde{t}_R$ & top-squark 2 & 52 \\\hline\hline $\widetilde{e}_L$ & selectron 1 & 53 \\\hline $\widetilde{\nu}_{e,L}$ & electron-sneutrino & 54 \\\hline $\widetilde{\mu}_L$ & smuon 1 & 55 \\\hline $\widetilde{\nu}_{\mu,L}$ & muon-sneutrino & 56 \\\hline $\widetilde{\tau}_L$ & stau 1 & 57 \\\hline $\widetilde{\nu}_{\tau,L}$ & tau-sneutrino & 58 \\\hline $\widetilde{e}_R$ & selectron 2 & 59 \\\hline $\widetilde{\mu}_R$ & smuon 2 & 61 \\\hline $\widetilde{\tau}_R$ & stau 2 & 63 \\\hline\hline $\widetilde{g}$ & gluino & 64 \\\hline $\widetilde{\chi}^0_1$ & neutralino 1 & 65 \\\hline $\widetilde{\chi}^0_2$ & neutralino 2 & 66 \\\hline $\widetilde{\chi}^0_3$ & neutralino 3 & 67 \\\hline $\widetilde{\chi}^0_4$ & neutralino 4 & 68 \\\hline $\widetilde{\chi}^+_1$ & chargino 1 & 69 \\\hline $\widetilde{\chi}^+_2$ & chargino 2 & 70 \\\hline\hline \end{tabular} \end{center} *) let pdg_mw = function | L g when g > 0 -> 9 + 2*g | L g -> - 9 + 2*g | N g when g > 0 -> 10 + 2*g | N g -> - 10 + 2*g | U g when g > 0 -> 2*g | U g -> 2*g | D g when g > 0 -> - 1 + 2*g | D g -> 1 + 2*g | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) | H_Light -> 25 | H_Heavy -> 35 | A -> 36 | Hp -> 37 | Hm -> (-37) | Phip | Phim -> 27 | Phi0 -> 26 | Sup (M1,g) when g > 0 -> 40 + 2*g | Sup (M1,g) -> - 40 + 2*g | Sup (M2,g) when g > 0 -> 46 + 2*g | Sup (M2,g) -> - 46 + 2*g | Sdown (M1,g) when g > 0 -> 39 + 2*g | Sdown (M1,g) -> - 39 + 2*g | Sdown (M2,g) when g > 0 -> 45 + 2*g | Sdown (M2,g) -> - 45 + 2*g | Slepton (M1,g) when g > 0 -> 51 + 2*g | Slepton (M1,g) -> - 51 + 2*g | Slepton (M2,g) when g > 0 -> 57 + 2*g | Slepton (M2,g) -> - 57 + 2*g | Sneutrino g when g > 0 -> 52 + 2*g | Sneutrino g -> - 52 + 2*g | Grino -> 39 | Gluino -> 64 | Chargino C1 -> 69 | Chargino C1c -> (-69) | Chargino C2 -> 70 | Chargino C2c -> (-70) | Neutralino N1 -> 65 | Neutralino N2 -> 66 | Neutralino N3 -> 67 | Neutralino N4 -> 68 let mass_symbol f = "mass(" ^ string_of_int (abs (pdg_mw f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg_mw f)) ^ ")" let conj_symbol = function | false, str -> str | true, str -> str ^ "_c" let constant_symbol = function | Unit -> "unit" | Pi -> "PI" | Alpha_QED -> "alpha" | E -> "e" | G -> "g" | Vev -> "vev" | Sin2thw -> "sin2thw" | Eidelta -> "eidelta" | Mu -> "mu" | G_Z -> "gz" | Sin a -> "sin" ^ string_of_angle a | Cos a -> "cos" ^ string_of_angle a | Sin2am2b -> "sin2am2b" | Cos2am2b -> "cos2am2b" | Sinamb -> "sinamb" | Sinapb -> "sinapb" | Cosamb -> "cosamb" | Cosapb -> "cosapb" | Cos4be -> "cos4be" | Sin4be -> "sin4be" | Sin4al -> "sin4al" | Sin2al -> "sin2al" | Cos2al -> "cos2al" | Sin2be -> "sin2be" | Cos2be -> "cos2be" | Tana -> "tana" | Tanb -> "tanb" | Q_lepton -> "qlep" | Q_up -> "qup" | Q_down -> "qdwn" | Q_charg -> "qchar" | V_CKM (g1,g2) -> "vckm_" ^ string_of_int g1 ^ string_of_int g2 | M_SF (f,g,m1,m2) -> "mix_" ^ string_of_sff f ^ string_of_int g ^ string_of_sfm m1 ^ string_of_sfm m2 | AL g -> "al_" ^ string_of_int g | AD g -> "ad_" ^ string_of_int g | AU g -> "au_" ^ string_of_int g | A_0 (n1,n2) -> "a0_" ^ string_of_neu n1 ^ string_of_neu n2 | A_P (c1,c2) -> "ap_" ^ string_of_char c1 ^ string_of_char c2 | V_0 (n1,n2) -> "v0_" ^ string_of_neu n1 ^ string_of_neu n2 | V_P (c1,c2) -> "vp_" ^ string_of_char c1 ^ string_of_char c2 | M_N (n1,n2) -> "mn_" ^ string_of_neu n1 ^ string_of_neu n2 | M_U (c1,c2) -> "mu_" ^ string_of_char c1 ^ string_of_char c2 | M_V (c1,c2) -> "mv_" ^ string_of_char c1 ^ string_of_char c2 | L_NC (n,c) -> "lnc_" ^ string_of_neu n ^ string_of_char c | R_NC (n,c) -> "rnc_" ^ string_of_neu n ^ string_of_char c | L_CN (c,n) -> "lcn_" ^ string_of_char c ^ string_of_neu n | R_CN (c,n) -> "rcn_" ^ string_of_char c ^ string_of_neu n | L_NCH (n,c) -> "lnch_" ^ string_of_neu n ^ string_of_char c | R_NCH (n,c) -> "rnch_" ^ string_of_neu n ^ string_of_char c | L_CNG (c,n) -> "lcng_" ^ string_of_char c ^ string_of_neu n | R_CNG (c,n) -> "rcng_" ^ string_of_char c ^ string_of_neu n | S_NNA (n1,n2) -> "snna_" ^ string_of_neu n1 ^ string_of_neu n2 | P_NNA (n1,n2) -> "pnna_" ^ string_of_neu n1 ^ string_of_neu n2 | S_NNG (n1,n2) -> "snng_" ^ string_of_neu n1 ^ string_of_neu n2 | P_NNG (n1,n2) -> "pnng_" ^ string_of_neu n1 ^ string_of_neu n2 | S_NNH1 (n1,n2) -> "snnh1_" ^ string_of_neu n1 ^ string_of_neu n2 | P_NNH1 (n1,n2) -> "pnnh1_" ^ string_of_neu n1 ^ string_of_neu n2 | S_NNH2 (n1,n2) -> "snnh2_" ^ string_of_neu n1 ^ string_of_neu n2 | P_NNH2 (n1,n2) -> "pnnh2_" ^ string_of_neu n1 ^ string_of_neu n2 | G_NC_lepton -> "gnclep" | G_NC_neutrino -> "gncneu" | G_NC_up -> "gncup" | G_NC_down -> "gncdwn" | G_CC -> "gcc" | G_CCQ (vc,g1,g2) -> conj_symbol (vc, "gccq_" ^ string_of_int g1 ^ "_" ^ string_of_int g2) | I_Q_W -> "iqw" | I_G_ZWW -> "igzww" | G_WWWW -> "gw4" | G_ZZWW -> "gzzww" | G_PZWW -> "gpzww" | G_PPWW -> "gppww" | G_GH 1 -> "ghaw" | G_GH 2 -> "gh1az" | G_GH 3 -> "gh2az" | G_GH 4 -> "gh1ww" | G_GH 5 -> "gh2ww" | G_GH 6 -> "ghh1w" | G_GH 7 -> "ghh2w" | G_GH 8 -> "gh1zz" | G_GH 9 -> "gh2zz" | G_GH 10 -> "ghhz" | G_GH 11 -> "ghhp" | G_GH _ -> failwith "this G_GH coupling is not available" | G_GLGLH -> "gglglh" | G_GLGLHH -> "gglglhh" | G_GLGLA -> "gglgla" | G_PPH -> "gpph" | G_PPHH -> "gpphh" | G_PPA -> "gppa" | G_GHGo n -> "g_hgh(" ^ string_of_int n ^ ")" | G_GH4 1 -> "gaazz" | G_GH4 2 -> "gh1h1zz" | G_GH4 3 -> "gh2h2zz" | G_GH4 4 -> "ghphmzz" | G_GH4 5 -> "ghphmpp" | G_GH4 6 -> "ghphmpz" | G_GH4 7 -> "ghh1wz" | G_GH4 8 -> "ghh2wz" | G_GH4 9 -> "ghh1wp" | G_GH4 10 -> "ghh2wp" | G_GH4 11 -> "gaaww" | G_GH4 12 -> "gh1h1ww" | G_GH4 13 -> "gh2h2ww" | G_GH4 14 -> "ghhww" | G_GH4 15 -> "ghawz" | G_GH4 16 -> "ghawp" | G_GH4 _ -> failwith "this G_GH4 coupling is not available" | G_CICIH1 (n1,n2) -> "gcicih1_" ^ string_of_neu n1 ^ "_" ^ string_of_neu n2 | G_CICIH2 (n1,n2) -> "gcicih2_" ^ string_of_neu n1 ^ "_" ^ string_of_neu n2 | G_CICIA (n1,n2) -> "gcicia_" ^ string_of_neu n1 ^ "_" ^ string_of_neu n2 | G_CICIG (n1,n2) -> "gcicig_" ^ string_of_neu n1 ^ "_" ^ string_of_neu n2 | G_H3 n -> "gh3_" ^ string_of_int n | G_H4 n -> "gh4_" ^ string_of_int n | G_HGo3 n -> "ghg3_" ^ string_of_int n | G_HGo4 n -> "ghg4_" ^ string_of_int n | G_GG4 n -> "ggg4_" ^ string_of_int n | G_strong -> "gs" | G_SS -> "gs**2" | Gs -> "gs" | I_G_S -> "igs" | G_S_Sqrt -> "gssq" | G_NWC (n,c) -> "gnwc_" ^ string_of_neu n ^ "_" ^ string_of_char c | G_CWN (c,n) -> "gcwn_" ^ string_of_char c ^ "_" ^ string_of_neu n | G_CH1C (c1,c2) -> "gch1c_" ^ string_of_char c1 ^ "_" ^ string_of_char c2 | G_CH2C (c1,c2) -> "gch2c_" ^ string_of_char c1 ^ "_" ^ string_of_char c2 | G_CAC (c1,c2) -> "gcac_" ^ string_of_char c1 ^ "_" ^ string_of_char c2 | G_CGC (c1,c2) -> "gcgc_" ^ string_of_char c1 ^ "_" ^ string_of_char c2 | G_YUK (i,g) -> "g_yuk" ^ string_of_int i ^ "_" ^ string_of_int g | G_NZN (n1,n2) -> "gnzn_" ^ string_of_neu n1 ^ "_" ^ string_of_neu n2 | G_NNA -> "gnna" | G_CZC (c1,c2) -> "gczc_" ^ string_of_char c1 ^ "_" ^ string_of_char c2 | G_YUK_1 (n,m) -> "g_yuk1_" ^ string_of_int n ^ "_" ^ string_of_int m | G_YUK_2 (n,m) -> "g_yuk2_" ^ string_of_int n ^ "_" ^ string_of_int m | G_YUK_3 (n,m) -> "g_yuk3_" ^ string_of_int n ^ "_" ^ string_of_int m | G_YUK_4 (n,m) -> "g_yuk4_" ^ string_of_int n ^ "_" ^ string_of_int m | G_YUK_C (vc,g,c,sf,m) -> conj_symbol (vc, "g_yuk_ch" ^ string_of_char c ^ "_" ^ string_of_sff sf ^ string_of_sfm m ^ "_" ^ string_of_int g ) | G_YUK_N (vc,g,n,sf,m) -> conj_symbol (vc, "g_yuk_n" ^ string_of_neu n ^ "_" ^ string_of_sff sf ^ string_of_sfm m ^ "_" ^ string_of_int g ) | G_YUK_G (vc,g,sf,m) -> conj_symbol (vc, "g_yuk_g" ^ string_of_sff sf ^ string_of_sfm m ^ "_" ^ string_of_int g) | G_YUK_Q (vc,g1,g2,c,sf,m) -> conj_symbol (vc, "g_yuk_ch" ^ string_of_char c ^ "_" ^ string_of_sff sf ^ string_of_sfm m ^ "_" ^ string_of_int g1 ^ "_" ^ string_of_int g2) | G_NHC (n,c) -> "g_nhc_" ^ string_of_neu n ^ "_" ^ string_of_char c | G_CHN (c,n) -> "g_chn_" ^ string_of_neu n ^ "_" ^ string_of_char c | G_NGC (n,c) -> "g_ngc_" ^ string_of_neu n ^ string_of_char c | G_CGN (c,n) -> "g_cgn_" ^ string_of_char c ^ string_of_neu n | SUM_1 -> "sum1" | G_SLSNW (vc,g,m) -> conj_symbol (vc, "gsl" ^ string_of_sfm m ^ "_" ^ string_of_int g ^ "snw") | G_ZSF (f,g,m1,m2) -> "g" ^ string_of_sff f ^ string_of_sfm m1 ^ "z" ^ string_of_sff f ^ string_of_sfm m2 ^ "_" ^ string_of_int g | G_WWSFSF (f,g,m1,m2) -> "gww" ^ string_of_sff f ^ string_of_sfm m1 ^ string_of_sff f ^ string_of_sfm m2 ^ "_" ^ string_of_int g | G_WPSLSN (vc,g,m) -> conj_symbol (vc, "gpwsl" ^ string_of_sfm m ^ "sn_" ^ string_of_int g) | G_WZSLSN (vc,g,m) -> conj_symbol (vc, "gwzsl" ^ string_of_sfm m ^ "sn_" ^ string_of_int g) | G_H1SFSF (f,g,m1,m2) -> "gh1" ^ string_of_sff f ^ string_of_sfm m1 ^ string_of_sff f ^ string_of_sfm m2 ^ "_" ^ string_of_int g | G_H2SFSF (f,g,m1,m2) -> "gh2" ^ string_of_sff f ^ string_of_sfm m1 ^ string_of_sff f ^ string_of_sfm m2 ^ "_" ^ string_of_int g | G_ASFSF (f,g,m1,m2) -> "ga" ^ string_of_sff f ^ string_of_sfm m1 ^ string_of_sff f ^ string_of_sfm m2 ^ "_" ^ string_of_int g | G_HSNSL (vc,g,m) -> conj_symbol (vc, "ghsnsl" ^ string_of_sfm m ^ "_" ^ string_of_int g) | G_GoSFSF (f,g,m1,m2) -> "ggo" ^ string_of_sff f ^ string_of_sfm m1 ^ string_of_sff f ^ string_of_sfm m2 ^ "_" ^ string_of_int g | G_GoSNSL (vc,g,m) -> conj_symbol (vc, "ggosnsl" ^ string_of_sfm m ^ "_" ^ string_of_int g) | G_HSUSD (vc,m1,m2,g1,g2) -> conj_symbol (vc, "ghsu" ^ string_of_sfm m1 ^ "sd" ^ string_of_sfm m2 ^ "_" ^ string_of_int g1 ^ "_" ^ string_of_int g2) | G_GSUSD (vc,m1,m2,g1,g2) -> conj_symbol (vc, "ggsu" ^ string_of_sfm m1 ^ "sd" ^ string_of_sfm m2 ^ "_" ^ string_of_int g1 ^ "_" ^ string_of_int g2) | G_WPSUSD (vc,m1,m2,n,m) -> conj_symbol (vc, "gpwpsu" ^ string_of_sfm m1 ^ "sd" ^ string_of_sfm m2 ^ "_" ^ string_of_int n ^ "_" ^ string_of_int m) | G_WZSUSD (vc,m1,m2,n,m) -> conj_symbol (vc, "gzwpsu" ^ string_of_sfm m1 ^ "sd" ^ string_of_sfm m2 ^ "_" ^ string_of_int n ^ "_" ^ string_of_int m) | G_SWS (vc,g1,g2,m1,m2) -> conj_symbol (vc, "gs" ^ string_of_sfm m1 ^ "ws" ^ string_of_sfm m2 ^ "_" ^ string_of_int g1 ^ "_" ^ string_of_int g2) | G_GlGlSQSQ -> "gglglsqsq" | G_PPSFSF f -> "gpp" ^ string_of_sff f ^ string_of_sff f | G_ZZSFSF (f,g,m1,m2) -> "gzz" ^ string_of_sff f ^ string_of_sfm m1 ^ string_of_sff f ^ string_of_sfm m2 ^ "_" ^ string_of_int g | G_ZPSFSF (f,g,m1,m2) -> "gzp" ^ string_of_sff f ^ string_of_sfm m1 ^ string_of_sff f ^ string_of_sfm m2 ^ "_" ^ string_of_int g | G_GlPSQSQ -> "gglpsqsq" | G_GlZSFSF (f,g,m1,m2) -> "ggl" ^ string_of_sff f ^ string_of_sfm m1 ^ string_of_sff f ^ string_of_sfm m2 ^ "_" ^ string_of_int g | G_GlWSUSD (vc,m1,m2,g1,g2) -> conj_symbol (vc, "gglwsu" ^ string_of_sfm m1 ^ "sd" ^ string_of_sfm m2 ^ "_" ^ string_of_int g1 ^ "_" ^ string_of_int g2) | G_GHGo4 1 -> "gzzg0g0" | G_GHGo4 2 -> "gzzgpgm" | G_GHGo4 3 -> "gppgpgm" | G_GHGo4 4 -> "gzpgpgm" | G_GHGo4 5 -> "gwwgpgm" | G_GHGo4 6 -> "gwwg0g0" | G_GHGo4 7 -> "gwzg0g" | G_GHGo4 8 -> "gwzg0g" | G_GHGo4 9 -> "gwzh1g" | G_GHGo4 10 -> "gwzh2g" | G_GHGo4 11 -> "gwph1g" | G_GHGo4 12 -> "gwph2g" | G_GHGo4 _ -> failwith "Coupling G_GHGo4 is not available" | G_HSF31 (h,g,m1,m2,f1,f2) -> "g_" ^ string_of_higgs h ^ string_of_int g ^ string_of_sfm m1 ^ string_of_sfm m2 ^ string_of_sff f1 ^ string_of_sff f2 | G_HSF32 (h,g1,g2,m1,m2,f1,f2) -> "g_" ^ string_of_higgs h ^ string_of_int g1 ^ "_" ^ string_of_int g2 ^ string_of_sfm m1 ^ string_of_sfm m2 ^ string_of_sff f1 ^ string_of_sff f2 | G_HSF41 (h,g,m1,m2,f1,f2) -> "g_" ^ string_of_higgs h ^ string_of_int g ^ string_of_sfm m1 ^ string_of_sfm m2 ^ string_of_sff f1 ^ string_of_sff f2 | G_HSF42 (h,g1,g2,m1,m2,f1,f2) -> "g_" ^ string_of_higgs h ^ string_of_int g1 ^ "_" ^ string_of_int g2 ^ string_of_sfm m1 ^ string_of_sfm m2 ^ string_of_sff f1 ^ string_of_sff f2 | G_H1H1SFSF (f,m1,m2,n) -> "gh1h1" ^ string_of_sff f ^ string_of_sfm m1 ^ string_of_sff f ^ string_of_sfm m2 ^ "_" ^ string_of_int n | G_H1H2SFSF (f,m1,m2,n) -> "gh1h2" ^ string_of_sff f ^ string_of_sfm m1 ^ string_of_sff f ^ string_of_sfm m2 ^ "_" ^ string_of_int n | G_H2H2SFSF (f,m1,m2,n) -> "gh2h2" ^ string_of_sff f ^ string_of_sfm m1 ^ string_of_sff f ^ string_of_sfm m2 ^ "_" ^ string_of_int n | G_HHSFSF (f,m1,m2,n) -> "ghh" ^ string_of_sff f ^ string_of_sfm m1 ^ string_of_sff f ^ string_of_sfm m2 ^ "_" ^ string_of_int n | G_AASFSF (f,m1,m2,n) -> "gaa" ^ string_of_sff f ^ string_of_sfm m1 ^ string_of_sff f ^ string_of_sfm m2 ^ "_" ^ string_of_int n | G_HH1SUSD (vc,m1,m2,g1,g2) -> conj_symbol (vc, "ghh1su" ^ string_of_sfm m1 ^ "sd" ^ string_of_sfm m2 ^ "_" ^ string_of_int g1 ^ "_" ^ string_of_int g2) | G_HH2SUSD (vc,m1,m2,g1,g2) -> conj_symbol (vc, "ghh2su" ^ string_of_sfm m1 ^ "sd" ^ string_of_sfm m2 ^ "_" ^ string_of_int g1 ^ "_" ^ string_of_int g2) | G_HASUSD (vc,m1,m2,g1,g2) -> conj_symbol (vc, "ghasu" ^ string_of_sfm m1 ^ "sd" ^ string_of_sfm m2 ^ "_" ^ string_of_int g1 ^ "_" ^ string_of_int g2 ^ "_c") | G_HH1SLSN (vc,m,g) -> conj_symbol (vc, "ghh1sl" ^ string_of_sfm m ^ "sn_" ^ string_of_int g) | G_HH2SLSN (vc,m,g) -> conj_symbol (vc, "ghh2sl" ^ string_of_sfm m ^ "sn_" ^ string_of_int g) | G_HASLSN (vc,m,g) -> conj_symbol (vc, "ghasl" ^ string_of_sfm m ^ "sn_" ^ string_of_int g) | G_AG0SFSF (f,m1,m2,n) -> "gag0" ^ string_of_sff f ^ string_of_sfm m1 ^ string_of_sff f ^ string_of_sfm m2 ^ "_" ^ string_of_int n | G_HGSFSF (f,m1,m2,n) -> "ghg" ^ string_of_sff f ^ string_of_sfm m1 ^ string_of_sff f ^ string_of_sfm m1 ^ "_" ^ string_of_int n | G_GGSFSF (f,m1,m2,n) -> "ggg" ^ string_of_sff f ^ string_of_sfm m1 ^ string_of_sff f ^ string_of_sfm m2 ^ "_" ^ string_of_int n | G_G0G0SFSF (f,m1,m2,n) -> "gg0g0" ^ string_of_sff f ^ string_of_sfm m1 ^ string_of_sff f ^ string_of_sfm m2 ^ "_" ^ string_of_int n | G_HGSNSL (vc,m,n) -> conj_symbol (vc, "ghgsnsl" ^ string_of_sfm m ^ "_" ^ string_of_int n) | G_H1GSNSL (vc,m,n) -> conj_symbol (vc, "gh1gsnsl" ^ string_of_sfm m ^ "_" ^ string_of_int n) | G_H2GSNSL (vc,m,n) -> conj_symbol (vc, "gh2gsnsl" ^ string_of_sfm m ^ "_" ^ string_of_int n) | G_AGSNSL (vc,m,n) -> conj_symbol (vc, "gagsnsl" ^ string_of_sfm m ^ "_" ^ string_of_int n) | G_GGSNSL (vc,m,n) -> conj_symbol (vc, "gggsnsl" ^ string_of_sfm m ^ "_" ^ string_of_int n) | G_HGSUSD (vc,m1,m2,g1,g2) -> conj_symbol (vc, "gghpsu" ^ string_of_sfm m1 ^ "sd" ^ string_of_sfm m2 ^ "_" ^ string_of_int g1 ^ "_" ^ string_of_int g2) | G_H1GSUSD (vc,m1,m2,g1,g2) -> conj_symbol (vc, "gh1gpsu" ^ string_of_sfm m1 ^ "sd" ^ string_of_sfm m2 ^ "_" ^ string_of_int g1 ^ "_" ^ string_of_int g2) | G_H2GSUSD (vc,m1,m2,g1,g2) -> conj_symbol (vc, "gh2gpsu" ^ string_of_sfm m1 ^ "sd" ^ string_of_sfm m2 ^ "_" ^ string_of_int g1 ^ "_" ^ string_of_int g2) | G_AGSUSD (vc,m1,m2,g1,g2) -> conj_symbol (vc, "gagpsu" ^ string_of_sfm m1 ^ "sd" ^ string_of_sfm m2 ^ "_" ^ string_of_int g1 ^ "_" ^ string_of_int g2) | G_GGSUSD (vc,m1,m2,g1,g2) -> conj_symbol (vc, "gggpsu" ^ string_of_sfm m1 ^ "sd" ^ string_of_sfm m2 ^ "_" ^ string_of_int g1 ^ "_" ^ string_of_int g2) | G_SN4 (g1,g2) -> "gsn4_" ^ string_of_int g1 ^ "_" ^ string_of_int g2 | G_SN2SL2_1 (m1,m2,g1,g2) -> "gsl_" ^ string_of_int g1 ^ "_sl_" ^ string_of_int g1 ^ "_sl" ^ string_of_sfm m1 ^ "_" ^ string_of_int g2 ^ "_sl" ^ string_of_sfm m2 ^ "_" ^ string_of_int g2 | G_SN2SL2_2 (m1,m2,g1,g2) -> "gsl_" ^ string_of_int g1 ^ "_sl_" ^ string_of_int g2 ^ "_sl" ^ string_of_sfm m1 ^ "_" ^ string_of_int g1 ^ "_sl" ^ string_of_sfm m2 ^ "_" ^ string_of_int g2 ^ "_mix" | G_SF4 (f1,f2,m1,m2,m3,m4,g1,g2) -> "gsf" ^ string_of_sff f1 ^ string_of_sff f2 ^ string_of_sfm m1 ^ string_of_sfm m2 ^ string_of_sfm m3 ^ string_of_sfm m4 ^ string_of_int g1 ^ string_of_int g2 | G_SF4_3 (f1,f2,m1,m2,m3,m4,g1,g2,g3) -> "gsf" ^ string_of_sff f1 ^ string_of_sff f2 ^ string_of_sfm m1 ^ string_of_sfm m2 ^ string_of_sfm m3 ^ string_of_sfm m4 ^ string_of_int g1 ^ string_of_int g2 ^ "_" ^ string_of_int g3 | G_SF4_4 (f1,f2,m1,m2,m3,m4,g1,g2,g3,g4) -> "gsf" ^ string_of_sff f1 ^ string_of_sff f2 ^ string_of_sfm m1 ^ string_of_sfm m2 ^ string_of_sfm m3 ^ string_of_sfm m4 ^ string_of_int g1 ^ "_" ^ string_of_int g2 ^ string_of_int g3 ^ "_" ^ string_of_int g4 | G_SL4 (m1,m2,m3,m4,g) -> "gsl" ^ string_of_sfm m1 ^ "_" ^ "sl" ^ string_of_sfm m2 ^ "_" ^ "sl" ^ string_of_sfm m3 ^ "_" ^ "sl" ^ string_of_sfm m4 ^ "_" ^ string_of_int g | G_SL4_2 (m1,m2,m3,m4,g1,g2) -> "gsl" ^ string_of_sfm m1 ^ "_" ^ "sl" ^ string_of_sfm m2 ^ "_" ^ "sl" ^ string_of_sfm m3 ^ "_" ^ "sl" ^ string_of_sfm m4 ^ "_" ^ string_of_int g1 ^ "_" ^ string_of_int g2 | G_SN2SQ2 (f,m1,m2,g1,g2) -> "gsn_" ^ string_of_int g1 ^ "_sn_" ^ string_of_int g1 ^ "_" ^ string_of_sff f ^ string_of_sfm m1 ^ "_" ^ string_of_int g2 ^ "_" ^ string_of_sff f ^ string_of_sfm m2 ^ "_" ^ string_of_int g2 | G_SL2SQ2 (f,m1,m2,m3,m4,g1,g2) -> "gsl" ^ string_of_sfm m1 ^ "_" ^ string_of_int g1 ^ "_sl" ^ string_of_sfm m2 ^ "_" ^ string_of_int g1 ^ "_" ^ string_of_sff f ^ string_of_sfm m3 ^ "_" ^ string_of_int g2 ^ "_" ^ string_of_sff f ^ string_of_sfm m4 ^ "_" ^ string_of_int g2 | G_SUSDSNSL (vc,m1,m2,m3,g1,g2,g3) -> conj_symbol (vc, "gsl" ^ string_of_sfm m3 ^ "_" ^ string_of_int g3 ^ "_sn_" ^ string_of_int g3 ^ "_su" ^ string_of_sfm m1 ^ "_" ^ string_of_int g1 ^ "_sd" ^ string_of_sfm m2 ^ "_" ^ string_of_int g2) | G_SU4 (m1,m2,m3,m4,g) -> "gsu" ^ string_of_sfm m1 ^ "_" ^ "_su" ^ string_of_sfm m2 ^ "_" ^ "_su" ^ string_of_sfm m3 ^ "_" ^ "_su" ^ string_of_sfm m4 ^ "_" ^ string_of_int g | G_SU4_2 (m1,m2,m3,m4,g1,g2) -> "gsu" ^ string_of_sfm m1 ^ "_" ^ "_su" ^ string_of_sfm m2 ^ "_" ^ "_su" ^ string_of_sfm m3 ^ "_" ^ "_su" ^ string_of_sfm m4 ^ "_" ^ string_of_int g1 ^ "_" ^ string_of_int g2 | G_SD4 (m1,m2,m3,m4,g) -> "gsd" ^ string_of_sfm m1 ^ "_" ^ "_sd" ^ string_of_sfm m2 ^ "_" ^ "_sd" ^ string_of_sfm m3 ^ "_" ^ "_sd" ^ string_of_sfm m4 ^ "_" ^ string_of_int g | G_SD4_2 (m1,m2,m3,m4,g1,g2) -> "gsd" ^ string_of_sfm m1 ^ "_" ^ "_sd" ^ string_of_sfm m2 ^ "_" ^ "_sd" ^ string_of_sfm m3 ^ "_" ^ "_sd" ^ string_of_sfm m4 ^ "_" ^ string_of_int g1 ^ "_" ^ string_of_int g2 | G_SU2SD2 (m1,m2,m3,m4,g1,g2,g3,g4) -> "gsu" ^ string_of_sfm m1 ^ "_" ^ string_of_int g1 ^ "_su" ^ string_of_sfm m2 ^ "_" ^ string_of_int g2 ^ "_sd" ^ string_of_sfm m3 ^ "_" ^ string_of_int g3 ^ "_sd" ^ string_of_sfm m4 ^ "_" ^ string_of_int g4 | M f -> "mass" ^ flavor_symbol f | W f -> "width" ^ flavor_symbol f | G_Grav -> "ggrav" | G_Gr_Ch C1 -> "ggrch1" | G_Gr_Ch C2 -> "ggrch2" | G_Gr_Ch C1c -> "ggrch1c" | G_Gr_Ch C2c -> "ggrch2c" | G_Gr_Z_Neu n -> "ggrzneu" ^ string_of_neu n | G_Gr_A_Neu n -> "ggraneu" ^ string_of_neu n | G_Gr4_Neu n -> "ggr4neu" ^ string_of_neu n | G_Gr4_A_Ch C1 -> "ggr4ach1" | G_Gr4_A_Ch C2 -> "ggr4ach2" | G_Gr4_A_Ch C1c -> "ggr4ach1c" | G_Gr4_A_Ch C2c -> "ggr4ach2c" | G_Gr4_Z_Ch C1 -> "ggr4zch1" | G_Gr4_Z_Ch C2 -> "ggr4zch2" | G_Gr4_Z_Ch C1c -> "ggr4zch1c" | G_Gr4_Z_Ch C2c -> "ggr4zch2c" | G_Grav_N -> "ggravn" | G_GravGl -> "gs * ggrav" | G_Grav_L (g,m) -> "ggravl" ^ string_of_int g ^ string_of_sfm m | G_Grav_Lc (g,m) -> "ggravl" ^ string_of_int g ^ string_of_sfm m ^ "c" | G_Grav_U (g,m) -> "ggravu" ^ string_of_int g ^ string_of_sfm m | G_Grav_Uc (g,m) -> "ggravu" ^ string_of_int g ^ string_of_sfm m ^ "c" | G_Grav_D (g,m) -> "ggravd" ^ string_of_int g ^ string_of_sfm m | G_Grav_Dc (g,m) -> "ggravd" ^ string_of_int g ^ string_of_sfm m ^ "c" | G_Gr_H_Ch C1 -> "ggrhch1" | G_Gr_H_Ch C2 -> "ggrhch2" | G_Gr_H_Ch C1c -> "ggrhch1c" | G_Gr_H_Ch C2c -> "ggrhch2c" | G_Gr_H1_Neu n -> "ggrh1neu" ^ string_of_neu n | G_Gr_H2_Neu n -> "ggrh2neu" ^ string_of_neu n | G_Gr_H3_Neu n -> "ggrh3neu" ^ string_of_neu n | G_Gr4A_Sl (g,m) -> "ggr4asl" ^ string_of_int g ^ string_of_sfm m | G_Gr4A_Slc (g,m) -> "ggr4asl" ^ string_of_int g ^ string_of_sfm m ^ "c" | G_Gr4A_Su (g,m) -> "ggr4asu" ^ string_of_int g ^ string_of_sfm m | G_Gr4A_Suc (g,m) -> "ggr4asu" ^ string_of_int g ^ string_of_sfm m ^ "c" | G_Gr4A_Sd (g,m) -> "ggr4asd" ^ string_of_int g ^ string_of_sfm m | G_Gr4A_Sdc (g,m) -> "ggr4asd" ^ string_of_int g ^ string_of_sfm m ^ "c" | G_Gr4Z_Sn -> "ggr4zsn" | G_Gr4Z_Snc -> "ggr4zsnc" | G_Gr4Z_Sl (g,m) -> "ggr4zsl" ^ string_of_int g ^ string_of_sfm m | G_Gr4Z_Slc (g,m) -> "ggr4zsl" ^ string_of_int g ^ string_of_sfm m ^ "c" | G_Gr4Z_Su (g,m) -> "ggr4zsu" ^ string_of_int g ^ string_of_sfm m | G_Gr4Z_Suc (g,m) -> "ggr4zsu" ^ string_of_int g ^ string_of_sfm m ^ "c" | G_Gr4Z_Sd (g,m) -> "ggr4zsd" ^ string_of_int g ^ string_of_sfm m | G_Gr4Z_Sdc (g,m) -> "ggr4zsd" ^ string_of_int g ^ string_of_sfm m ^ "c" | G_Gr4W_Sl (g,m) -> "ggr4wsl" ^ string_of_int g ^ string_of_sfm m | G_Gr4W_Slc (g,m) -> "ggr4wsl" ^ string_of_int g ^ string_of_sfm m ^ "c" | G_Gr4W_Su (g,m) -> "ggr4wsu" ^ string_of_int g ^ string_of_sfm m | G_Gr4W_Suc (g,m) -> "ggr4wsu" ^ string_of_int g ^ string_of_sfm m ^ "c" | G_Gr4W_Sd (g,m) -> "ggr4wsd" ^ string_of_int g ^ string_of_sfm m | G_Gr4W_Sdc (g,m) -> "ggr4wsd" ^ string_of_int g ^ string_of_sfm m ^ "c" | G_Gr4Gl_Su (g,m) -> "ggr4glsu" ^ string_of_int g ^ string_of_sfm m | G_Gr4Gl_Suc (g,m) -> "ggr4glsu" ^ string_of_int g ^ string_of_sfm m ^ "c" | G_Gr4Gl_Sd (g,m) -> "ggr4glsd" ^ string_of_int g ^ string_of_sfm m | G_Gr4Gl_Sdc (g,m) -> "ggr4glsd" ^ string_of_int g ^ string_of_sfm m ^ "c" | G_Gr4_Z_H1 n -> "ggr4zh1_" ^ string_of_neu n | G_Gr4_Z_H2 n -> "ggr4zh2_" ^ string_of_neu n | G_Gr4_Z_H3 n -> "ggr4zh3_" ^ string_of_neu n | G_Gr4_W_H n -> "ggr4wh_" ^ string_of_neu n | G_Gr4_W_Hc n -> "ggr4whc_" ^ string_of_neu n | G_Gr4_H_A C1 -> "ggr4ha1" | G_Gr4_H_A C2 -> "ggr4ha2" | G_Gr4_H_A C1c -> "ggr4ha1c" | G_Gr4_H_A C2c -> "ggr4ha2c" | G_Gr4_H_Z C1 -> "ggr4hz1" | G_Gr4_H_Z C2 -> "ggr4hz2" | G_Gr4_H_Z C1c -> "ggr4hz1c" | G_Gr4_H_Z C2c -> "ggr4hz2c" | G_Gr4W_Sn -> "ggr4wsn" | G_Gr4W_Snc -> "ggr4wsnc" end (*i * Local Variables: * mode:caml * indent-tabs-mode:nil * page-delimiter:"^(\\* .*\n" * End: i*) Index: trunk/omega/src/modellib_WZW.ml =================================================================== --- trunk/omega/src/modellib_WZW.ml (revision 8413) +++ trunk/omega/src/modellib_WZW.ml (revision 8414) @@ -1,628 +1,630 @@ (* modellib_WZW.ml -- Copyright (C) 1999-2020 by Wolfgang Kilian Thorsten Ohl Juergen Reuter with contributions from Christian Speckner WHIZARD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. WHIZARD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *) (* \thocwmodulesection{SM with WZW-type pseudoscalars} *) module type SM_flags = sig val include_anomalous : bool val k_matrix : bool end module SM_no_anomalous : SM_flags = struct let include_anomalous = false let k_matrix = false end module WZW (Flags : SM_flags) = struct open Coupling let default_width = ref Timelike let use_fudged_width = ref false let options = Options.create [ "constant_width", Arg.Unit (fun () -> default_width := Constant), "use constant width (also in t-channel)"; "fudged_width", Arg.Set use_fudged_width, "use fudge factor for charge particle width"; "custom_width", Arg.String (fun f -> default_width := Custom f), "use custom width"; "cancel_widths", Arg.Unit (fun () -> default_width := Vanishing), "use vanishing width"; "cms_width", Arg.Unit (fun () -> default_width := Complex_Mass), - "use complex mass scheme"] + "use complex mass scheme"; + "running_width", Arg.Unit (fun () -> default_width := Running), + "use running width"] (* We do not introduce the Goldstones for the heavy vectors here. *) type matter_field = L of int | N of int | U of int | D of int type gauge_boson = Ga | Wp | Wm | Z | Gl type other = Phip | Phim | Phi0 | H | Psi0 | Eta type flavor = M of matter_field | G of gauge_boson | O of other let matter_field f = M f let gauge_boson f = G f let other f = O f type field = | Matter of matter_field | Gauge of gauge_boson | Other of other let field = function | M f -> Matter f | G f -> Gauge f | O f -> Other f type gauge = unit let gauge_symbol () = failwith "Models.WZW.gauge_symbol: internal error" let family n = List.map matter_field [ L n; N n; U n; D n ] let external_flavors () = [ "1st Generation", ThoList.flatmap family [1; -1]; "2nd Generation", ThoList.flatmap family [2; -2]; "3rd Generation", ThoList.flatmap family [3; -3]; "Gauge Bosons", List.map gauge_boson [Ga; Z; Wp; Wm; Gl]; "Higgs", [O H; O Psi0; O Eta]; "Goldstone Bosons", List.map other [Phip; Phim; Phi0] ] let flavors () = ThoList.flatmap snd (external_flavors ()) let spinor n = if n >= 0 then Spinor else ConjSpinor let lorentz = function | M f -> begin match f with | L n -> spinor n | N n -> spinor n | U n -> spinor n | D n -> spinor n end | G f -> begin match f with | Ga | Gl -> Vector | Wp | Wm | Z -> Massive_Vector end | O f -> Scalar let color = function | M (U n) -> Color.SUN (if n > 0 then 3 else -3) | M (D n) -> Color.SUN (if n > 0 then 3 else -3) | G Gl -> Color.AdjSUN 3 | _ -> Color.Singlet let nc () = 3 let prop_spinor n = if n >= 0 then Prop_Spinor else Prop_ConjSpinor let propagator = function | M f -> begin match f with | L n -> prop_spinor n | N n -> prop_spinor n | U n -> prop_spinor n | D n -> prop_spinor n end | G f -> begin match f with | Ga | Gl -> Prop_Feynman | Wp | Wm | Z -> Prop_Unitarity end | O f -> begin match f with | Phip | Phim | Phi0 -> Only_Insertion | H | Psi0 | Eta -> Prop_Scalar end (* Optionally, ask for the fudge factor treatment for the widths of charged particles. Currently, this only applies to $W^\pm$ and top. *) let width f = if !use_fudged_width then match f with | G Wp | G Wm | M (U 3) | M (U (-3)) | _ -> !default_width else !default_width let goldstone = function | G f -> begin match f with | Wp -> Some (O Phip, Coupling.Integer 1) | Wm -> Some (O Phim, Coupling.Integer 1) | Z -> Some (O Phi0, Coupling.Integer 1) | _ -> None end | _ -> None let conjugate = function | M f -> M (begin match f with | L n -> L (-n) | N n -> N (-n) | U n -> U (-n) | D n -> D (-n) end) | G f -> G (begin match f with | Gl -> Gl | Ga -> Ga | Z -> Z | Wp -> Wm | Wm -> Wp end) | O f -> O (begin match f with | Phip -> Phim | Phim -> Phip | Phi0 -> Phi0 | H -> H | Psi0 -> Psi0 | Eta -> Eta end) let fermion = function | M f -> begin match f with | L n -> if n > 0 then 1 else -1 | N n -> if n > 0 then 1 else -1 | U n -> if n > 0 then 1 else -1 | D n -> if n > 0 then 1 else -1 end | G f -> begin match f with | Gl | Ga | Z | Wp | Wm -> 0 end | O _ -> 0 (* Electrical charge, lepton number, baryon number. We could avoid the rationals altogether by multiplying the first and last by 3 \ldots *) module Ch = Charges.QQ let ( // ) = Algebra.Small_Rational.make let generation' = function | 1 -> [ 1//1; 0//1; 0//1] | 2 -> [ 0//1; 1//1; 0//1] | 3 -> [ 0//1; 0//1; 1//1] | -1 -> [-1//1; 0//1; 0//1] | -2 -> [ 0//1; -1//1; 0//1] | -3 -> [ 0//1; 0//1; -1//1] | n -> invalid_arg ("WZW.generation': " ^ string_of_int n) let generation f = match f with | M (L n | N n | U n | D n) -> generation' n | G _ | O _ -> [0//1; 0//1; 0//1] let charge = function | M f -> begin match f with | L n -> if n > 0 then -1//1 else 1//1 | N n -> 0//1 | U n -> if n > 0 then 2//3 else -2//3 | D n -> if n > 0 then -1//3 else 1//3 end | G f -> begin match f with | Gl | Ga | Z -> 0//1 | Wp -> 1//1 | Wm -> -1//1 end | O f -> begin match f with | H | Phi0 | Psi0 | Eta -> 0//1 | Phip -> 1//1 | Phim -> -1//1 end let lepton = function | M f -> begin match f with | L n | N n -> if n > 0 then 1//1 else -1//1 | U _ | D _ -> 0//1 end | G _ | O _ -> 0//1 let baryon = function | M f -> begin match f with | L _ | N _ -> 0//1 | U n | D n -> if n > 0 then 1//1 else -1//1 end | G _ | O _ -> 0//1 let charges f = [ charge f; lepton f; baryon f] @ generation f type constant = | Unit | Pi | Alpha_QED | Sin2thw | Sinthw | Costhw | E | G_weak | Vev | Q_lepton | Q_up | Q_down | G_CC | G_NC_neutrino | G_NC_lepton | G_NC_up | G_NC_down | G_NC_h_neutrino | G_NC_h_lepton | G_NC_h_up | G_NC_h_down | I_Q_W | I_G_ZWW | I_G_WWW | G_WWWW | G_ZZWW | G_AZWW | G_AAWW | G_HWW | G_HHWW | G_HZZ | G_HHZZ | G_EtaGG | G_EtaWW | G_PsiWW | G_PsiZZ | G_PsiAA | G_PsiAZ | G_PsiGG | G_EtaZZ | G_EtaAZ | G_EtaAA | G_Htt | G_Hbb | G_Hcc | G_Htautau | G_H3 | G_H4 | Gs | I_Gs | G2 | Mass of flavor | Width of flavor (* Two integer counters for the QCD and EW order of the couplings. *) type orders = int * int let orders = function | _ -> (0,0) let input_parameters = [] let derived_parameters = [] let g_over_2_costh = Quot (Neg (Atom G_weak), Prod [Integer 2; Atom Costhw]) let nc_coupling c t3 q = (Real_Array c, [Prod [g_over_2_costh; Diff (t3, Prod [Integer 2; q; Atom Sin2thw])]; Prod [g_over_2_costh; t3]]) let half = Quot (Integer 1, Integer 2) let derived_parameter_arrays = [ nc_coupling G_NC_neutrino half (Integer 0); nc_coupling G_NC_lepton (Neg half) (Integer (-1)); nc_coupling G_NC_up half (Quot (Integer 2, Integer 3)); nc_coupling G_NC_down (Neg half) (Quot (Integer (-1), Integer 3)); nc_coupling G_NC_h_neutrino half (Integer 0); nc_coupling G_NC_h_lepton (Neg half) (Integer (-1)); nc_coupling G_NC_h_up half (Quot (Integer 2, Integer 3)); nc_coupling G_NC_h_down (Neg half) (Quot (Integer (-1), Integer 3)) ] let parameters () = { input = input_parameters; derived = derived_parameters; derived_arrays = derived_parameter_arrays } module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) (* \begin{equation} \mathcal{L}_{\textrm{EM}} = - e \sum_i q_i \bar\psi_i\fmslash{A}\psi_i \end{equation} *) let mgm ((m1, g, m2), fbf, c) = ((M m1, G g, M m2), fbf, c) let mom ((m1, o, m2), fbf, c) = ((M m1, O o, M m2), fbf, c) let electromagnetic_currents n = List.map mgm [ ((L (-n), Ga, L n), FBF (1, Psibar, V, Psi), Q_lepton); ((U (-n), Ga, U n), FBF (1, Psibar, V, Psi), Q_up); ((D (-n), Ga, D n), FBF (1, Psibar, V, Psi), Q_down) ] let color_currents n = List.map mgm [ ((U (-n), Gl, U n), FBF (1, Psibar, V, Psi), Gs); ((D (-n), Gl, D n), FBF (1, Psibar, V, Psi), Gs) ] (* \begin{equation} \mathcal{L}_{\textrm{NC}} = - \frac{g}{2\cos\theta_W} \sum_i \bar\psi_i\fmslash{Z}(g_V^i-g_A^i\gamma_5)\psi_i \end{equation} *) let neutral_currents n = List.map mgm [ ((L (-n), Z, L n), FBF (1, Psibar, VA, Psi), G_NC_lepton); ((N (-n), Z, N n), FBF (1, Psibar, VA, Psi), G_NC_neutrino); ((U (-n), Z, U n), FBF (1, Psibar, VA, Psi), G_NC_up); ((D (-n), Z, D n), FBF (1, Psibar, VA, Psi), G_NC_down) ] (* \begin{equation} \mathcal{L}_{\textrm{CC}} = - \frac{g}{2\sqrt2} \sum_i \bar\psi_i (T^+\fmslash{W}^+ + T^-\fmslash{W}^-)(1-\gamma_5)\psi_i \end{equation} *) let charged_currents n = List.map mgm [ ((L (-n), Wm, N n), FBF (1, Psibar, VL, Psi), G_CC); ((N (-n), Wp, L n), FBF (1, Psibar, VL, Psi), G_CC); ((D (-n), Wm, U n), FBF (1, Psibar, VL, Psi), G_CC); ((U (-n), Wp, D n), FBF (1, Psibar, VL, Psi), G_CC) ] let yukawa = [ ((M (U (-3)), O H, M (U 3)), FBF (1, Psibar, S, Psi), G_Htt); ((M (D (-3)), O H, M (D 3)), FBF (1, Psibar, S, Psi), G_Hbb); ((M (U (-2)), O H, M (U 2)), FBF (1, Psibar, S, Psi), G_Hcc); ((M (L (-3)), O H, M (L 3)), FBF (1, Psibar, S, Psi), G_Htautau) ] (* \begin{equation} \mathcal{L}_{\textrm{TGC}} = - e \partial_\mu A_\nu W_+^\mu W_-^\nu + \ldots - e \cot\theta_w \partial_\mu Z_\nu W_+^\mu W_-^\nu + \ldots \end{equation} *) let tgc ((g1, g2, g3), t, c) = ((G g1, G g2, G g3), t, c) let triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW); ((Gl, Gl, Gl), Gauge_Gauge_Gauge 1, I_Gs)] let qgc ((g1, g2, g3, g4), t, c) = ((G g1, G g2, G g3, G g4), t, c) let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] let quartic_gauge = List.map qgc [ (Wm, Wp, Wm, Wp), gauge4, G_WWWW; (Wm, Z, Wp, Z), minus_gauge4, G_ZZWW; (Wm, Z, Wp, Ga), minus_gauge4, G_AZWW; (Wm, Ga, Wp, Ga), minus_gauge4, G_AAWW; (Gl, Gl, Gl, Gl), gauge4, G2 ] let gauge_higgs = [ ((O H, G Wp, G Wm), Scalar_Vector_Vector 1, G_HWW); ((O H, G Z, G Z), Scalar_Vector_Vector 1, G_HZZ); ((O Psi0, G Wp, G Wm), Dim5_Scalar_Gauge2_Skew 1, G_PsiWW); ((O Psi0, G Z, G Z), Dim5_Scalar_Gauge2_Skew 1, G_PsiZZ); ((O Psi0, G Ga, G Ga), Dim5_Scalar_Gauge2_Skew 1, G_PsiAA); ((O Psi0, G Z, G Ga), Dim5_Scalar_Gauge2_Skew 1, G_PsiAZ); ((O Psi0, G Gl, G Gl), Dim5_Scalar_Gauge2_Skew 1, G_PsiGG); ((O Eta, G Gl, G Gl), Dim5_Scalar_Gauge2_Skew 1, G_EtaGG); ((O Eta, G Wp, G Wm), Dim5_Scalar_Gauge2_Skew 1, G_EtaWW); ((O Eta, G Z, G Z), Dim5_Scalar_Gauge2_Skew 1, G_EtaZZ); ((O Eta, G Z, G Ga), Dim5_Scalar_Gauge2_Skew 1, G_EtaAZ); ((O Eta, G Ga, G Ga), Dim5_Scalar_Gauge2_Skew 1, G_EtaAA)] let gauge_higgs4 = [ (O H, O H, G Wp, G Wm), Scalar2_Vector2 1, G_HHWW; (O H, O H, G Z, G Z), Scalar2_Vector2 1, G_HHZZ ] let higgs = [ (O H, O H, O H), Scalar_Scalar_Scalar 1, G_H3 ] let higgs4 = [ (O H, O H, O H, O H), Scalar4 1, G_H4 ] let goldstone_vertices = [ ((O Phi0, G Wm, G Wp), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phip, G Ga, G Wm), Scalar_Vector_Vector 1, I_Q_W); ((O Phip, G Z, G Wm), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phim, G Wp, G Ga), Scalar_Vector_Vector 1, I_Q_W); ((O Phim, G Wp, G Z), Scalar_Vector_Vector 1, I_G_ZWW) ] let vertices3 = (ThoList.flatmap electromagnetic_currents [1;2;3] @ ThoList.flatmap color_currents [1;2;3] @ ThoList.flatmap neutral_currents [1;2;3] @ ThoList.flatmap charged_currents [1;2;3] @ yukawa @ triple_gauge @ gauge_higgs @ higgs @ goldstone_vertices) let vertices4 = quartic_gauge @ gauge_higgs4 @ higgs4 let vertices () = (vertices3, vertices4, []) (* For efficiency, make sure that [F.of_vertices vertices] is evaluated only once. *) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 let flavor_of_string = function | "e-" -> M (L 1) | "e+" -> M (L (-1)) | "mu-" -> M (L 2) | "mu+" -> M (L (-2)) | "tau-" -> M (L 3) | "tau+" -> M (L (-3)) | "nue" -> M (N 1) | "nuebar" -> M (N (-1)) | "numu" -> M (N 2) | "numubar" -> M (N (-2)) | "nutau" -> M (N 3) | "nutaubar" -> M (N (-3)) | "u" -> M (U 1) | "ubar" -> M (U (-1)) | "c" -> M (U 2) | "cbar" -> M (U (-2)) | "t" -> M (U 3) | "tbar" -> M (U (-3)) | "d" -> M (D 1) | "dbar" -> M (D (-1)) | "s" -> M (D 2) | "sbar" -> M (D (-2)) | "b" -> M (D 3) | "bbar" -> M (D (-3)) | "g" | "gl" -> G Gl | "A" -> G Ga | "Z" | "Z0" -> G Z | "W+" -> G Wp | "W-" -> G Wm | "Psi" -> O Psi0 | "Eta" -> O Eta | "H" -> O H | _ -> invalid_arg "Models.WZW.flavor_of_string" let flavor_to_string = function | M f -> begin match f with | L 1 -> "e-" | L (-1) -> "e+" | L 2 -> "mu-" | L (-2) -> "mu+" | L 3 -> "tau-" | L (-3) -> "tau+" | L _ -> invalid_arg "Models.WZW.flavor_to_string: invalid lepton" | N 1 -> "nue" | N (-1) -> "nuebar" | N 2 -> "numu" | N (-2) -> "numubar" | N 3 -> "nutau" | N (-3) -> "nutaubar" | N _ -> invalid_arg "Models.WZW.flavor_to_string: invalid neutrino" | U 1 -> "u" | U (-1) -> "ubar" | U 2 -> "c" | U (-2) -> "cbar" | U 3 -> "t" | U (-3) -> "tbar" | U _ -> invalid_arg "Models.WZW.flavor_to_string: invalid up type quark" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | D _ -> invalid_arg "Models.WZW.flavor_to_string: invalid down type quark" end | G f -> begin match f with | Gl -> "g" | Ga -> "A" | Z -> "Z" | Wp -> "W+" | Wm -> "W-" end | O f -> begin match f with | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | H -> "H" | Psi0 -> "psi" | Eta -> "eta" end let flavor_to_TeX = function | M f -> begin match f with | L 1 -> "e^-" | L (-1) -> "e^+" | L 2 -> "\\mu-" | L (-2) -> "\\mu^+" | L 3 -> "\\tau^-" | L (-3) -> "\\tau^+" | L _ -> invalid_arg "Models.WZW.flavor_to_TeX: invalid lepton" | N 1 -> "\\nu_e" | N (-1) -> "\\bar{\\nu}_e" | N 2 -> "\\nu_\\mu" | N (-2) -> "\\bar{\\nu}_\\mu" | N 3 -> "\\nu_\\tau" | N (-3) -> "\\bar{\\nu}_\\tau" | N _ -> invalid_arg "Models.WZW.flavor_to_TeX: invalid neutrino" | U 1 -> "u" | U (-1) -> "\\bar{u}" | U 2 -> "c" | U (-2) -> "\\bar{c}" | U 3 -> "t" | U (-3) -> "\\bar{t}" | U _ -> invalid_arg "Models.WZW.flavor_to_TeX: invalid up type quark" | D 1 -> "d" | D (-1) -> "\\bar{d}" | D 2 -> "s" | D (-2) -> "\\bar{s}" | D 3 -> "b" | D (-3) -> "\\bar{b}" | D _ -> invalid_arg "Models.WZW.flavor_to_TeX: invalid down type quark" end | G f -> begin match f with | Gl -> "g" | Ga -> "\\gamma" | Z -> "Z" | Wp -> "W^+" | Wm -> "W^-" end | O f -> begin match f with | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | H -> "H" | Psi0 -> "\\Psi" | Eta -> "\\eta" end let flavor_symbol = function | M f -> begin match f with | L n when n > 0 -> "l" ^ string_of_int n | L n -> "l" ^ string_of_int (abs n) ^ "b" | N n when n > 0 -> "n" ^ string_of_int n | N n -> "n" ^ string_of_int (abs n) ^ "b" | U n when n > 0 -> "u" ^ string_of_int n | U n -> "u" ^ string_of_int (abs n) ^ "b" | D n when n > 0 -> "d" ^ string_of_int n | D n -> "d" ^ string_of_int (abs n) ^ "b" end | G f -> begin match f with | Gl -> "gl" | Ga -> "a" | Z -> "z" | Wp -> "wp" | Wm -> "wm" end | O f -> begin match f with | Phip -> "pp" | Phim -> "pm" | Phi0 -> "p0" | H -> "h" | Psi0 -> "psi" | Eta -> "eta" end (* There are PDG numbers for Z', Z'', W', 32-34, respectively. We just introduce a number 38 for Y0 as a Z'''. As well, there is the number 8 for a t'. *) let pdg = function | M f -> begin match f with | L n when n > 0 -> 9 + 2*n | L n -> - 9 + 2*n | N n when n > 0 -> 10 + 2*n | N n -> - 10 + 2*n | U n when n > 0 -> 2*n | U n -> 2*n | D n when n > 0 -> - 1 + 2*n | D n -> 1 + 2*n end | G f -> begin match f with | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) end | O f -> begin match f with | Phip | Phim -> 27 | Phi0 -> 26 | H -> 25 | Psi0 -> 28 | Eta -> 29 end let mass_symbol f = "mass(" ^ string_of_int (abs (pdg f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg f)) ^ ")" let constant_symbol = function | Unit -> "unit" | Pi -> "PI" | Alpha_QED -> "alpha" | E -> "e" | G_weak -> "g" | Vev -> "vev" | Sin2thw -> "sin2thw" | Sinthw -> "sinthw" | Costhw -> "costhw" | Q_lepton -> "qlep" | Q_up -> "qup" | Q_down -> "qdwn" | G_NC_lepton -> "gnclep" | G_NC_neutrino -> "gncneu" | G_NC_up -> "gncup" | G_NC_down -> "gncdwn" | G_CC -> "gcc" | G_NC_h_lepton -> "gnchlep" | G_NC_h_neutrino -> "gnchneu" | G_NC_h_up -> "gnchup" | G_NC_h_down -> "gnchdwn" | I_Q_W -> "iqw" | I_G_ZWW -> "igzww" | I_G_WWW -> "igwww" | G_WWWW -> "gw4" | G_ZZWW -> "gzzww" | G_AZWW -> "gazww" | G_AAWW -> "gaaww" | G_HWW -> "ghww" | G_HZZ -> "ghzz" | G_HHWW -> "ghhww" | G_HHZZ -> "ghhzz" | G_PsiWW -> "gpsiww" | G_PsiZZ -> "gpsizz" | G_PsiAA -> "gpsiaa" | G_PsiAZ -> "gpsiaz" | G_PsiGG -> "gpsigg" | G_EtaGG -> "getagg" | G_EtaZZ -> "getazz" | G_EtaAA -> "getaaa" | G_EtaAZ -> "getaaz" | G_EtaWW -> "getaww" | G_Htt -> "ghtt" | G_Hbb -> "ghbb" | G_Htautau -> "ghtautau" | G_Hcc -> "ghcc" | G_H3 -> "gh3" | G_H4 -> "gh4" | Gs -> "gs" | I_Gs -> "igs" | G2 -> "gs**2" | Mass f -> "mass" ^ flavor_symbol f | Width f -> "width" ^ flavor_symbol f end Index: trunk/omega/src/modellib_NMSSM.ml =================================================================== --- trunk/omega/src/modellib_NMSSM.ml (revision 8413) +++ trunk/omega/src/modellib_NMSSM.ml (revision 8414) @@ -1,1591 +1,1593 @@ (* modellib_NMSSM.ml -- Copyright (C) 1999-2020 by Wolfgang Kilian Thorsten Ohl Juergen Reuter with contributions from Christian Speckner Felix Braam (this file only) WHIZARD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. WHIZARD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *) (* \thocwmodulesection{Next-to-Minimal Supersymmetric Standard Model} *) (* This is based on the NMSSM implementation by Felix Braam. Note that for the Higgs sector vertices the conventions of the Franke/Fraas paper have been used. *) module type NMSSM_flags = sig val ckm_present : bool val higgs_triangle : bool end module NMSSM : NMSSM_flags = struct let ckm_present = false let higgs_triangle = false end module NMSSM_CKM : NMSSM_flags = struct let ckm_present = true let higgs_triangle = false end module NMSSM_Hgg : NMSSM_flags = struct let ckm_present = false let higgs_triangle = true end module NMSSM_func (Flags : NMSSM_flags) = struct open Coupling let default_width = ref Timelike let use_fudged_width = ref false let options = Options.create [ "constant_width", Arg.Unit (fun () -> default_width := Constant), "use constant width (also in t-channel)"; "fudged_width", Arg.Set use_fudged_width, "use fudge factor for charge particle width"; "custom_width", Arg.String (fun f -> default_width := Custom f), "use custom width"; "cancel_widths", Arg.Unit (fun () -> default_width := Vanishing), - "use vanishing width"] + "use vanishing width"; + "running_width", Arg.Unit (fun () -> default_width := Running), + "use running width"] (* Yields a list of tuples consistig of the off-diag combinations of the elements in "set". *) let choose2 set = List.map (function [x;y] -> (x,y) | _ -> failwith "choose2") (Combinatorics.choose 2 set) (* [pairs] appends the diagonal combinations to [choose2]. *) let rec diag = function | [] -> [] | x1 :: rest -> (x1, x1) :: diag rest let pairs l = choose2 l @ diag l let rec cloop set i j k = if i > ((List.length set)-1) then [] else if j > i then cloop set (succ i) (j-i-1) (j-i-1) else if k > j then cloop set i (succ j) (k-j-1) else (List.nth set i, List.nth set j, List.nth set k) :: cloop set i j (succ k) let triples set = cloop set 0 0 0 let rec two_and_one' l1 z n = if n < 0 then [] else ((fst (List.nth (pairs l1) n)),(snd (List.nth (pairs l1) n)), z):: two_and_one' l1 z (pred n) let two_and_one l1 l2 = let f z = two_and_one' l1 z ((List.length (pairs l1))-1) in List.flatten ( List.map f l2 ) type gen = | G of int | GG of gen*gen let rec string_of_gen = function | G n when n > 0 -> string_of_int n | G n -> string_of_int (abs n) ^ "c" | GG (g1,g2) -> string_of_gen g1 ^ "_" ^ string_of_gen g2 (* With this we distinguish the flavour. *) type sff = | SL | SN | SU | SD let string_of_sff = function | SL -> "sl" | SN -> "sn" | SU -> "su" | SD -> "sd" (* With this we distinguish the mass eigenstates. At the moment we have to cheat a little bit for the sneutrinos. Because we are dealing with massless neutrinos there is only one sort of sneutrino. *) type sfm = | M1 | M2 let string_of_sfm = function | M1 -> "1" | M2 -> "2" (* We also introduce special types for the charginos and neutralinos. *) type char = | C1 | C2 | C1c | C2c type neu = | N1 | N2 | N3 | N4 | N5 let int_of_char = function | C1 -> 1 | C2 -> 2 | C1c -> -1 | C2c -> -2 let string_of_char = function | C1 -> "1" | C2 -> "2" | C1c -> "-1" | C2c -> "-2" let conj_char = function | C1 -> C1c | C2 -> C2c | C1c -> C1 | C2c -> C2 let string_of_neu = function | N1 -> "1" | N2 -> "2" | N3 -> "3" | N4 -> "4" | N5 -> "5" (* For the Higgs bosons, we follow the conventions of Franke/Fraas. *) type shiggs = | S1 | S2 | S3 type phiggs = | P1 | P2 let string_of_shiggs = function | S1 -> "1" | S2 -> "2" | S3 -> "3" let string_of_phiggs = function | P1 -> "1" | P2 -> "2" type flavor = | L of int | N of int | U of int | D of int | Sup of sfm*int | Sdown of sfm*int | Ga | Wp | Wm | Z | Gl | Slepton of sfm*int | Sneutrino of int | Neutralino of neu | Chargino of char | Gluino | SHiggs of shiggs | Hp | Hm | PHiggs of phiggs let string_of_fermion_type = function | L _ -> "l" | U _ -> "u" | D _ -> "d" | N _ -> "n" | _ -> failwith "Modellib_NMSSM.NMSSM.string_of_fermion_type: invalid fermion type" let string_of_fermion_gen = function | L g | U g | D g | N g -> string_of_int (abs (g)) | _ -> failwith "Modellib_NMSSM.NMSSM.string_of_fermion_gen: invalid fermion type" type gauge = unit let gauge_symbol () = failwith "Modellib_NMSSM.NMSSM.gauge_symbol: internal error" (* At this point we will forget graviton and -ino. *) let family g = [ L g; N g; Slepton (M1,g); Slepton (M2,g); Sneutrino g; U g; D g; Sup (M1,g); Sup (M2,g); Sdown (M1,g); Sdown (M2,g)] let external_flavors () = [ "1st Generation matter", ThoList.flatmap family [1; -1]; "2nd Generation matter", ThoList.flatmap family [2; -2]; "3rd Generation matter", ThoList.flatmap family [3; -3]; "Gauge Bosons", [Ga; Z; Wp; Wm; Gl]; "Charginos", [Chargino C1; Chargino C2; Chargino C1c; Chargino C2c]; "Neutralinos", [Neutralino N1; Neutralino N2; Neutralino N3; Neutralino N4; Neutralino N5]; "Higgs Bosons", [SHiggs S1; SHiggs S2; SHiggs S3; Hp; Hm; PHiggs P1; PHiggs P2]; "Gluino", [Gluino]] let flavors () = ThoList.flatmap snd (external_flavors ()) let spinor n m = if n >= 0 && m >= 0 then Spinor else if n <= 0 && m <=0 then ConjSpinor else invalid_arg "Modellib_NMSSM.NMSSM.spinor: internal error" let lorentz = function | L g -> spinor g 0 | N g -> spinor g 0 | U g -> spinor g 0 | D g -> spinor g 0 | Chargino c -> spinor (int_of_char c) 0 | Ga | Gl -> Vector | Wp | Wm | Z -> Massive_Vector | SHiggs _ | PHiggs _ | Hp | Hm | Sup _ | Sdown _ | Slepton _ | Sneutrino _ -> Scalar | Neutralino _ | Gluino -> Majorana let color = function | U g -> Color.SUN (if g > 0 then 3 else -3) | Sup (m,g) -> Color.SUN (if g > 0 then 3 else -3) | D g -> Color.SUN (if g > 0 then 3 else -3) | Sdown (m,g) -> Color.SUN (if g > 0 then 3 else -3) | Gl | Gluino -> Color.AdjSUN 3 | _ -> Color.Singlet let nc () = 3 let prop_spinor n m = if n >= 0 && m >=0 then Prop_Spinor else if n <=0 && m <=0 then Prop_ConjSpinor else invalid_arg "Modellib_NMSSM.NMSSM.prop_spinor: internal error" let propagator = function | L g -> prop_spinor g 0 | N g -> prop_spinor g 0 | U g -> prop_spinor g 0 | D g -> prop_spinor g 0 | Chargino c -> prop_spinor (int_of_char c) 0 | Ga | Gl -> Prop_Feynman | Wp | Wm | Z -> Prop_Unitarity | SHiggs _ | PHiggs _ -> Prop_Scalar | Hp | Hm -> Prop_Scalar | Sup _ | Sdown _ | Slepton _ | Sneutrino _ -> Prop_Scalar | Gluino -> Prop_Majorana | Neutralino _ -> Prop_Majorana (* Optionally, ask for the fudge factor treatment for the widths of charged particles. Currently, this only applies to $W^\pm$ and top. *) let width f = if !use_fudged_width then match f with | Wp | Wm | U 3 | U (-3) -> Fudged | _ -> !default_width else !default_width let goldstone _ = None let conjugate = function | L g -> L (-g) | N g -> N (-g) | U g -> U (-g) | D g -> D (-g) | Sup (m,g) -> Sup (m,-g) | Sdown (m,g) -> Sdown (m,-g) | Slepton (m,g) -> Slepton (m,-g) | Sneutrino g -> Sneutrino (-g) | Gl -> Gl | Ga -> Ga | Z -> Z | Wp -> Wm | Wm -> Wp | SHiggs s -> SHiggs s | PHiggs p -> PHiggs p | Hp -> Hm | Hm -> Hp | Gluino -> Gluino | Neutralino n -> Neutralino n | Chargino c -> Chargino (conj_char c) let fermion = function | L g -> if g > 0 then 1 else -1 | N g -> if g > 0 then 1 else -1 | U g -> if g > 0 then 1 else -1 | D g -> if g > 0 then 1 else -1 | Gl | Ga | Z | Wp | Wm -> 0 | SHiggs _ | Hp | Hm | PHiggs _ -> 0 | Neutralino _ -> 2 | Chargino c -> if (int_of_char c) > 0 then 1 else -1 | Sup _ -> 0 | Sdown _ -> 0 | Slepton _ -> 0 | Sneutrino _ -> 0 | Gluino -> 2 module Ch = Charges.QQ let ( // ) = Algebra.Small_Rational.make let generation' = function | 1 -> [ 1//1; 0//1; 0//1] | 2 -> [ 0//1; 1//1; 0//1] | 3 -> [ 0//1; 0//1; 1//1] | -1 -> [-1//1; 0//1; 0//1] | -2 -> [ 0//1; -1//1; 0//1] | -3 -> [ 0//1; 0//1; -1//1] | n -> invalid_arg ("NMSSM.generation': " ^ string_of_int n) let generation f = if Flags.ckm_present then [] else match f with | L n | N n | U n | D n | Sup (_,n) | Sdown (_,n) | Slepton (_,n) | Sneutrino n -> generation' n | _ -> [0//1; 0//1; 0//1] let charge = function | L n -> if n > 0 then -1//1 else 1//1 | Slepton (_,n) -> if n > 0 then -1//1 else 1//1 | N n -> 0//1 | Sneutrino n -> 0//1 | U n -> if n > 0 then 2//3 else -2//3 | Sup (_,n) -> if n > 0 then 2//3 else -2//3 | D n -> if n > 0 then -1//3 else 1//3 | Sdown (_,n) -> if n > 0 then -1//3 else 1//3 | Gl | Ga | Z | Neutralino _ | Gluino -> 0//1 | Wp -> 1//1 | Wm -> -1//1 | SHiggs _ | PHiggs _ -> 0//1 | Hp -> 1//1 | Hm -> -1//1 | Chargino (C1 | C2) -> 1//1 | Chargino (C1c | C2c) -> -1//1 let lepton = function | L n | N n -> if n > 0 then 1//1 else -1//1 | Slepton (_,n) | Sneutrino n -> if n > 0 then 1//1 else -1//1 | _ -> 0//1 let baryon = function | U n | D n -> if n > 0 then 1//1 else -1//1 | Sup (_,n) | Sdown (_,n) -> if n > 0 then 1//1 else -1//1 | _ -> 0//1 let charges f = [ charge f; lepton f; baryon f] @ generation f (* We introduce a Boolean type vc as a pseudonym for Vertex Conjugator to distinguish between vertices containing complex mixing matrices like the CKM--matrix or the sfermion or neutralino/chargino--mixing matrices, which have to become complex conjugated. The true--option stands for the conjugated vertex, the false--option for the unconjugated vertex. *) type vc = bool type constant = | E | G | Mu (*lambda**) | Lambda | Q_lepton | Q_up | Q_down | Q_charg | G_Z | G_CC | G_CCQ of vc*int*int | G_NC_neutrino | G_NC_lepton | G_NC_up | G_NC_down | I_Q_W | I_G_ZWW | G_WWWW | G_ZZWW | G_PZWW | G_PPWW | G_SS | I_G_S | Gs | G_NZN of neu*neu | G_CZC of char*char | G_YUK_FFS of flavor*flavor*shiggs | G_YUK_FFP of flavor*flavor*phiggs | G_YUK_LCN of int | G_YUK_UCD of int*int | G_YUK_DCU of int*int | G_NHC of vc*neu*char | G_YUK_C of vc*flavor*char*sff*sfm | G_YUK_Q of vc*int*flavor*char*sff*sfm | G_YUK_N of vc*flavor*neu*sff*sfm | G_YUK_G of vc*flavor*sff*sfm | G_NWC of neu*char | G_CWN of char*neu | G_CSC of char*char*shiggs | G_CPC of char*char*phiggs | G_WSQ of vc*int*int*sfm*sfm | G_SLSNW of vc*int*sfm | G_ZSF of sff*int*sfm*sfm | G_CICIS of neu*neu*shiggs | G_CICIP of neu*neu*phiggs | G_GH_WPC of phiggs | G_GH_WSC of shiggs | G_GH_ZSP of shiggs*phiggs | G_GH_WWS of shiggs | G_GH_ZZS of shiggs | G_GH_ZCC | G_GH_GaCC | G_GH4_ZZPP of phiggs*phiggs | G_GH4_ZZSS of shiggs*shiggs | G_GH4_ZZCC | G_GH4_GaGaCC | G_GH4_ZGaCC | G_GH4_WWCC | G_GH4_WWPP of phiggs*phiggs | G_GH4_WWSS of shiggs*shiggs | G_GH4_ZWSC of shiggs | G_GH4_GaWSC of shiggs | G_GH4_ZWPC of phiggs | G_GH4_GaWPC of phiggs | G_WWSFSF of sff*int*sfm*sfm | G_WPSLSN of vc*int*sfm | G_H3_SCC of shiggs | G_H3_SSS of shiggs*shiggs*shiggs | G_H3_SPP of shiggs*phiggs*phiggs | G_SFSFS of shiggs*sff*int*sfm*sfm | G_SFSFP of phiggs*sff*int*sfm*sfm | G_HSNSL of vc*int*sfm | G_HSUSD of vc*sfm*sfm*int*int | G_WPSUSD of vc*sfm*sfm*int*int | G_WZSUSD of vc*sfm*sfm*int*int | G_WZSLSN of vc*int*sfm | G_GlGlSQSQ | G_PPSFSF of sff | G_ZZSFSF of sff*int*sfm*sfm | G_ZPSFSF of sff*int*sfm*sfm | G_GlZSFSF of sff*int*sfm*sfm | G_GlPSQSQ | G_GlWSUSD of vc*sfm*sfm*int*int | G_GLUGLUA0 of phiggs | G_GLUGLUH0 of shiggs (* Two integer counters for the QCD and EW order of the couplings. *) type orders = int * int let orders = function | _ -> (0,0) (* \begin{subequations} \begin{align} \alpha_{\text{QED}} &= \frac{1}{137.0359895} \\ \sin^2\theta_w &= 0.23124 \end{align} \end{subequations} Here we must perhaps allow for complex input parameters. So split them into their modulus and their phase. At first, we leave them real; the generalization to complex parameters is obvious. *) let parameters () = { input = []; derived = []; derived_arrays = [] } module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) (* For the couplings there are generally two possibilities concerning the sign of the covariant derivative. \begin{equation} {\rm CD}^\pm = \partial_\mu \pm \ii g T^a A^a_\mu \end{equation} The particle data group defines the signs consistently to be positive. Since the convention for that signs also influence the phase definitions of the gaugino/higgsino fields via the off-diagonal entries in their mass matrices it would be the best to adopt that convention. *) (*** REVISED: Compatible with CD+. FB ***) let electromagnetic_currents_3 g = [ ((L (-g), Ga, L g), FBF (1, Psibar, V, Psi), Q_lepton); ((U (-g), Ga, U g), FBF (1, Psibar, V, Psi), Q_up); ((D (-g), Ga, D g), FBF (1, Psibar, V, Psi), Q_down)] (*** REVISED: Compatible with CD+. FB***) let electromagnetic_sfermion_currents g m = [ ((Ga, Slepton (m,-g), Slepton (m,g)), Vector_Scalar_Scalar 1, Q_lepton); ((Ga, Sup (m,-g), Sup (m,g)), Vector_Scalar_Scalar 1, Q_up); ((Ga, Sdown (m,-g), Sdown (m,g)), Vector_Scalar_Scalar 1, Q_down)] (*** REVISED: Compatible with CD+. FB***) let electromagnetic_currents_2 c = let cc = conj_char c in [ ((Chargino cc, Ga, Chargino c), FBF (1, Psibar, V, Psi), Q_charg) ] (*** REVISED: Compatible with CD+. FB***) let neutral_currents g = [ ((L (-g), Z, L g), FBF (1, Psibar, VA, Psi), G_NC_lepton); ((N (-g), Z, N g), FBF (1, Psibar, VA, Psi), G_NC_neutrino); ((U (-g), Z, U g), FBF (1, Psibar, VA, Psi), G_NC_up); ((D (-g), Z, D g), FBF (1, Psibar, VA, Psi), G_NC_down)] (* \begin{equation} \mathcal{L}_{\textrm{CC}} = \mp \frac{g}{2\sqrt2} \sum_i \bar\psi_i \gamma^\mu (1-\gamma_5)(T^+W^+_\mu+T^-W^-_\mu)\psi_i , \end{equation} where the sign corresponds to $\text{CD}_\pm$, respectively. *) (*** REVISED: Compatible with CD+. ***) (* Remark: The definition with the other sign compared to the SM files comes from the fact that $g_{cc} = 1/(2\sqrt{2})$ is used overwhelmingly often in the SUSY Feynman rules, so that JR decided to use a different definiton for [g_cc] in SM and MSSM. *) (** FB **) let charged_currents g = [ ((L (-g), Wm, N g), FBF ((-1), Psibar, VL, Psi), G_CC); ((N (-g), Wp, L g), FBF ((-1), Psibar, VL, Psi), G_CC) ] (* The quark with the inverted generation (the antiparticle) is the outgoing one, the other the incoming. The vertex attached to the outgoing up-quark contains the CKM matrix element {\em not} complex conjugated, while the vertex with the outgoing down-quark has the conjugated CKM matrix element. *) (*** REVISED: Compatible with CD+. FB ***) let charged_quark_currents g h = [ ((D (-g), Wm, U h), FBF ((-1), Psibar, VL, Psi), G_CCQ (true,g,h)); ((U (-g), Wp, D h), FBF ((-1), Psibar, VL, Psi), G_CCQ (false,h,g))] (*** REVISED: Compatible with CD+.FB ***) let charged_chargino_currents n c = let cc = conj_char c in [ ((Chargino cc, Wp, Neutralino n), FBF (1, Psibar, VLR, Chi), G_CWN (c,n)); ((Neutralino n, Wm, Chargino c), FBF (1, Chibar, VLR, Psi), G_NWC (n,c)) ] (*** REVISED: Compatible with CD+. FB***) let charged_slepton_currents g m = [ ((Wm, Slepton (m,-g), Sneutrino g), Vector_Scalar_Scalar (-1), G_SLSNW (true,g,m)); ((Wp, Slepton (m,g), Sneutrino (-g)), Vector_Scalar_Scalar 1, G_SLSNW (false,g,m)) ] (*** REVISED: Compatible with CD+. FB***) let charged_squark_currents' g h m1 m2 = [ ((Wm, Sup (m1,g), Sdown (m2,-h)), Vector_Scalar_Scalar (-1), G_WSQ (true,g,h,m1,m2)); ((Wp, Sup (m1,-g), Sdown (m2,h)), Vector_Scalar_Scalar 1, G_WSQ (false,g,h,m1,m2)) ] let charged_squark_currents g h = List.flatten (Product.list2 (charged_squark_currents' g h) [M1;M2] [M1;M2] ) (*** REVISED: Compatible with CD+. FB ***) let neutral_sfermion_currents' g m1 m2 = [ ((Z, Slepton (m1,-g), Slepton (m2,g)), Vector_Scalar_Scalar (-1), G_ZSF (SL,g,m1,m2)); ((Z, Sup (m1,-g), Sup (m2,g)), Vector_Scalar_Scalar (-1), G_ZSF(SU,g,m1,m2)); ((Z, Sdown (m1,-g), Sdown (m2,g)), Vector_Scalar_Scalar (-1), G_ZSF (SD,g,m1,m2))] let neutral_sfermion_currents g = List.flatten (Product.list2 (neutral_sfermion_currents' g) [M1;M2] [M1;M2]) @ [ ((Z, Sneutrino (-g), Sneutrino g), Vector_Scalar_Scalar (-1), G_ZSF (SN,g,M1,M1)) ] (*** REVISED: Compatible with CD+. FB***) let neutral_Z (n,m) = [ ((Neutralino n, Z, Neutralino m), FBF (1, Chibar, VLR, Chi), (G_NZN (n,m))) ] (*** REVISED: Compatible with CD+. FB***) let charged_Z c1 c2 = let cc1 = conj_char c1 in ((Chargino cc1, Z, Chargino c2), FBF ((-1), Psibar, VA , Psi), G_CZC (c1,c2)) (*** REVISED: Compatible with CD+. Remark: This is pure octet. FB***) let yukawa_v = [ (Gluino, Gl, Gluino), FBF (1, Chibar, V, Chi), Gs] (*** REVISED: Independent of the sign of CD. ***) (*** REVISED: Felix Braam: Compact version using new COMBOS + FF-Couplings *) let yukawa_higgs_FFS f s = [((conjugate f, SHiggs s, f ), FBF (1, Psibar, S, Psi), G_YUK_FFS (conjugate f, f, s))] let yukawa_higgs_FFP f p = [((conjugate f, PHiggs p, f), FBF (1, Psibar, P, Psi), G_YUK_FFP (conjugate f ,f , p))] let yukawa_higgs_NLC g = [ ((N (-g), Hp, L g), FBF (1, Psibar, Coupling.SR, Psi), G_YUK_LCN g); ((L (-g), Hm, N g), FBF (1, Psibar, Coupling.SL, Psi), G_YUK_LCN g)] let yukawa_higgs g = yukawa_higgs_NLC g @ List.flatten ( Product.list2 yukawa_higgs_FFS [L g; U g; D g] [S1; S2; S3]) @ List.flatten ( Product.list2 yukawa_higgs_FFP [L g; U g; D g] [P1; P2]) (*** REVISED: Independent of the sign of CD. FB***) let yukawa_higgs_quark (g,h) = [ ((U (-g), Hp, D h), FBF (1, Psibar, SLR, Psi), G_YUK_UCD (g, h)); ((D (-h), Hm, U g), FBF (1, Psibar, SLR, Psi), G_YUK_DCU (g, h)) ] (*** REVISED: Compatible with CD+. ***) (*** REVISED: Felix Braam: Compact version using new COMBOS*) let yukawa_shiggs_2 c1 c2 s = let cc1 = conj_char c1 in ((Chargino cc1, SHiggs s, Chargino c2), FBF (1, Psibar, SLR, Psi), G_CSC (c1,c2,s)) let yukawa_phiggs_2 c1 c2 p = let cc1 = conj_char c1 in ((Chargino cc1, PHiggs p, Chargino c2), FBF (1, Psibar, SLR, Psi), G_CPC (c1,c2,p)) let yukawa_higgs_2 = Product.list3 yukawa_shiggs_2 [C1;C2] [C1;C2] [S1;S2;S3] @ Product.list3 yukawa_phiggs_2 [C1;C2] [C1;C2] [P1;P2] (*** REVISED: Compatible with CD+.FB ***) let higgs_charg_neutr n c = let cc = conj_char c in [ ((Neutralino n, Hm, Chargino c), FBF (-1, Chibar, SLR, Psi), G_NHC (false,n,c)); ((Chargino cc, Hp, Neutralino n), FBF (-1, Psibar, SLR, Chi), G_NHC (true,n,c)) ] (*** REVISED: Compatible with CD+. ***) (*** REVISED: Felix Braam: Compact version using new COMBOS*) let shiggs_neutr (n,m,s) = ((Neutralino n, SHiggs s, Neutralino m), FBF (1, Chibar, SLR, Chi), G_CICIS (n,m,s)) let phiggs_neutr (n,m,p) = ((Neutralino n, PHiggs p, Neutralino m), FBF (1, Chibar, SLR, Chi), G_CICIP (n,m,p)) let higgs_neutr = List.map shiggs_neutr (two_and_one [N1;N2;N3;N4;N5] [S1;S2;S3]) @ List.map phiggs_neutr (two_and_one [N1;N2;N3;N4;N5] [P1;P2]) (*** REVISED: Compatible with CD+. FB***) let yukawa_n_2 n m g = [ ((Neutralino n, Slepton (m,-g), L g), FBF (1, Chibar, SLR, Psi), G_YUK_N (true,L g,n,SL,m)); ((L (-g), Slepton (m,g), Neutralino n), FBF (1, Psibar, SLR, Chi), G_YUK_N (false,L g,n,SL,m)); ((Neutralino n, Sup (m,-g), U g), FBF (1, Chibar, SLR, Psi), G_YUK_N (true,U g,n,SU,m)); ((U (-g), Sup (m,g), Neutralino n), FBF (1, Psibar, SLR, Chi), G_YUK_N (false,U g,n,SU,m)); ((Neutralino n, Sdown (m,-g), D g), FBF (1, Chibar, SLR, Psi), G_YUK_N (true,D g,n,SD,m)); ((D (-g), Sdown (m,g), Neutralino n), FBF (1, Psibar, SLR, Chi), G_YUK_N (false,D g,n,SD,m)) ] let yukawa_n_3 n g = [ ((Neutralino n, Sneutrino (-g), N g), FBF (1, Chibar, SLR, Psi), G_YUK_N (true,N g,n,SN,M1)); ((N (-g), Sneutrino g, Neutralino n), FBF (1, Psibar, SLR, Chi), G_YUK_N (false,N g, n,SN,M1)) ] let yukawa_n_5 g m = [ ((U (-g), Sup (m,g), Gluino), FBF (1, Psibar, SLR, Chi), G_YUK_G (false,U g,SU,m)); ((D (-g), Sdown (m,g), Gluino), FBF (1, Psibar, SLR, Chi), G_YUK_G (false,D g,SD,m)); ((Gluino, Sup (m,-g), U g), FBF (1, Chibar, SLR, Psi), G_YUK_G (true,U g,SU,m)); ((Gluino, Sdown (m,-g), D g), FBF (1, Chibar, SLR, Psi), G_YUK_G (true,D g,SD,m))] let yukawa_n = List.flatten (Product.list3 yukawa_n_2 [N1;N2;N3;N4;N5] [M1;M2] [1;2;3]) @ List.flatten (Product.list2 yukawa_n_3 [N1;N2;N3;N4;N5] [1;2;3]) @ List.flatten (Product.list2 yukawa_n_5 [1;2;3] [M1;M2]) (*** REVISED: Compatible with CD+.FB ***) let yukawa_c_2 c g = let cc = conj_char c in [ ((L (-g), Sneutrino g, Chargino cc), BBB (1, Psibar, SLR, Psibar), G_YUK_C (true,L g,c,SN,M1)); ((Chargino c, Sneutrino (-g), L g), PBP (1, Psi, SLR, Psi), G_YUK_C (false,L g,c,SN,M1)) ] let yukawa_c_3 c m g = let cc = conj_char c in [ ((N (-g), Slepton (m,g), Chargino c), FBF (1, Psibar, SLR, Psi), G_YUK_C (true,N g,c,SL,m)); ((Chargino cc, Slepton (m,-g), N g), FBF (1, Psibar, SLR, Psi), G_YUK_C (false,N g,c,SL,m)) ] let yukawa_c c = ThoList.flatmap (yukawa_c_2 c) [1;2;3] @ List.flatten (Product.list2 (yukawa_c_3 c) [M1;M2] [1;2;3]) (*** REVISED: Compatible with CD+. FB***) let yukawa_cq' c (g,h) m = let cc = conj_char c in [ ((Chargino c, Sup (m,-g), D h), PBP (1, Psi, SLR, Psi), G_YUK_Q (false,g,D h,c,SU,m)); ((D (-h), Sup (m,g), Chargino cc), BBB (1, Psibar, SLR, Psibar), G_YUK_Q (true,g,D h,c,SU,m)); ((Chargino cc, Sdown (m,-g), U h), FBF (1, Psibar, SLR, Psi), G_YUK_Q (true,g,U h,c,SD,m)); ((U (-h), Sdown (m,g), Chargino c), FBF (1, Psibar, SLR, Psi), G_YUK_Q (false,g,U h,c,SD,m)) ] let yukawa_cq c = if Flags.ckm_present then List.flatten (Product.list2 (yukawa_cq' c) [(1,1);(1,2);(2,1);(2,2);(1,3);(2,3);(3,3);(3,2);(3,1)] [M1;M2]) else List.flatten (Product.list2 (yukawa_cq' c) [(1,1);(2,2);(3,3)] [M1;M2]) (*** REVISED: Compatible with CD+. Remark: Singlet and octet gluon exchange. The coupling is divided by sqrt(2) to account for the correct normalization of the Lie algebra generators. **FB*) let col_currents g = [ ((D (-g), Gl, D g), FBF ((-1), Psibar, V, Psi), Gs); ((U (-g), Gl, U g), FBF ((-1), Psibar, V, Psi), Gs)] (*** REVISED: Compatible with CD+. Remark: Singlet and octet gluon exchange. The coupling is divided by sqrt(2) to account for the correct normalization of the Lie algebra generators. **FB*) let chg = function | M1 -> M2 | M2 -> M1 let col_sfermion_currents g m = [ ((Gl, Sup (m,-g), Sup (m,g)), Vector_Scalar_Scalar (-1), Gs); ((Gl, Sdown (m,-g), Sdown (m,g)), Vector_Scalar_Scalar (-1), Gs)] (*** REVISED: Compatible with CD+. **FB*) let triple_gauge = [ ((Ga, Wm, Wp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW); ((Gl, Gl, Gl), Gauge_Gauge_Gauge 1, I_G_S)] (*** REVISED: Independent of the sign of CD. **FB*) let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] let quartic_gauge = [ (Wm, Wp, Wm, Wp), gauge4, G_WWWW; (Wm, Z, Wp, Z), minus_gauge4, G_ZZWW; (Wm, Z, Wp, Ga), minus_gauge4, G_PZWW; (Wm, Ga, Wp, Ga), minus_gauge4, G_PPWW; (Gl, Gl, Gl, Gl), gauge4, G_SS] (* The [Scalar_Vector_Vector] couplings do not depend on the choice of the sign of the covariant derivative since they are quadratic in the gauge couplings. *) (** Effective Higgs-Gluon-Gluon coupling. **) let gauge_higgs_GlGlS s= ((SHiggs s, Gl, Gl), Dim5_Scalar_Gauge2 1, G_GLUGLUH0 s) let gauge_higgs_GlGlP p= ((PHiggs p, Gl, Gl), Dim5_Scalar_Gauge2_Skew 1, G_GLUGLUA0 p) (*** REVISED: Compatible with CD+. FB***) (*** Revision: 2005-03-10: first two vertices corrected. ***) (*** REVISED: Compact version using new COMBOS*) (*** REVISED: Couplings adjusted to FF-convention*) let gauge_higgs_WPC p= [ ((Wm, Hp, PHiggs p), Vector_Scalar_Scalar 1, G_GH_WPC p); ((Wp, Hm, PHiggs p), Vector_Scalar_Scalar 1, G_GH_WPC p)] let gauge_higgs_WSC s= [((Wm, Hp, SHiggs s),Vector_Scalar_Scalar 1, G_GH_WSC s); ((Wp, Hm, SHiggs s),Vector_Scalar_Scalar (-1), G_GH_WSC s)] let gauge_higgs_ZSP s p = [((Z, SHiggs s, PHiggs p),Vector_Scalar_Scalar 1, G_GH_ZSP (s,p))] let gauge_higgs_WWS s= ((SHiggs s, Wp, Wm),Scalar_Vector_Vector 1, G_GH_WWS s) let gauge_higgs_ZZS s= ((SHiggs s, Z, Z), Scalar_Vector_Vector 1, G_GH_ZZS s) let gauge_higgs_ZCC = ((Z, Hp, Hm),Vector_Scalar_Scalar 1, G_GH_ZCC ) let gauge_higgs_GaCC = ((Ga, Hp, Hm),Vector_Scalar_Scalar 1, G_GH_GaCC ) let gauge_higgs = ThoList.flatmap gauge_higgs_WPC [P1;P2] @ ThoList.flatmap gauge_higgs_WSC [S1;S2;S3] @ List.flatten (Product.list2 gauge_higgs_ZSP [S1;S2;S3] [P1;P2]) @ List.map gauge_higgs_WWS [S1;S2;S3] @ List.map gauge_higgs_ZZS [S1;S2;S3] @ [gauge_higgs_ZCC] @ [gauge_higgs_GaCC] @ (if Flags.higgs_triangle then List.map gauge_higgs_GlGlS [S1;S2;S3] @ List.map gauge_higgs_GlGlP [P1;P2] else []) (*** REVISED: Compact version using new COMBOS*) (*** REVISED: Couplings adjusted to FF-convention*) let gauge_higgs4_ZZPP (p1,p2) = ((PHiggs p1, PHiggs p2, Z, Z), Scalar2_Vector2 1, G_GH4_ZZPP (p1,p2)) let gauge_higgs4_ZZSS (s1,s2) = ((SHiggs s1, SHiggs s2 , Z, Z), Scalar2_Vector2 1, G_GH4_ZZSS (s1,s2)) let gauge_higgs4_ZZCC = ((Hp, Hm, Z, Z), Scalar2_Vector2 1, G_GH4_ZZCC) let gauge_higgs4_GaGaCC = ((Hp, Hm, Ga, Ga), Scalar2_Vector2 1, G_GH4_GaGaCC) let gauge_higgs4_ZGaCC = ((Hp, Hm, Ga, Z), Scalar2_Vector2 1, G_GH4_ZGaCC ) let gauge_higgs4_WWCC = ((Hp, Hm, Wp, Wm), Scalar2_Vector2 1, G_GH4_WWCC ) let gauge_higgs4_WWPP (p1,p2) = ((PHiggs p1, PHiggs p2, Wp, Wm), Scalar2_Vector2 1, G_GH4_WWPP (p1,p2)) let gauge_higgs4_WWSS (s1,s2) = ((SHiggs s1, SHiggs s2, Wp, Wm), Scalar2_Vector2 1, G_GH4_WWSS (s1,s2)) let gauge_higgs4_ZWSC s = [ ((Hp, SHiggs s, Wm, Z), Scalar2_Vector2 1, G_GH4_ZWSC s); ((Hm, SHiggs s, Wp, Z), Scalar2_Vector2 1, G_GH4_ZWSC s)] let gauge_higgs4_GaWSC s = [ ((Hp, SHiggs s, Wm, Ga), Scalar2_Vector2 1, G_GH4_GaWSC s); ((Hm, SHiggs s, Wp, Ga), Scalar2_Vector2 1, G_GH4_GaWSC s) ] let gauge_higgs4_ZWPC p = [ ((Hp, PHiggs p, Wm, Z), Scalar2_Vector2 1, G_GH4_ZWPC p); ((Hm, PHiggs p, Wp, Z), Scalar2_Vector2 (-1), G_GH4_ZWPC p)] let gauge_higgs4_GaWPC p = [ ((Hp, PHiggs p, Wm, Ga), Scalar2_Vector2 1, G_GH4_GaWPC p); ((Hm, PHiggs p, Wp, Ga), Scalar2_Vector2 (-1), G_GH4_GaWPC p) ] let gauge_higgs4 = List.map gauge_higgs4_ZZPP (pairs [P1;P2]) @ List.map gauge_higgs4_ZZSS (pairs [S1;S2;S3]) @ [gauge_higgs4_ZZCC] @ [gauge_higgs4_GaGaCC] @ [gauge_higgs4_ZGaCC] @ [gauge_higgs4_WWCC] @ List.map gauge_higgs4_WWPP (pairs [P1;P2]) @ List.map gauge_higgs4_WWSS (pairs [S1;S2;S3]) @ ThoList.flatmap gauge_higgs4_ZWSC [S1;S2;S3] @ ThoList.flatmap gauge_higgs4_GaWSC [S1;S2;S3] @ ThoList.flatmap gauge_higgs4_ZWPC [P1;P2] @ ThoList.flatmap gauge_higgs4_GaWPC [P1;P2] (**********************************************FB****) let gauge_sfermion4' g m1 m2 = [ ((Wp, Wm, Slepton (m1,g), Slepton (m2,-g)), Scalar2_Vector2 1, G_WWSFSF (SL,g,m1,m2)); ((Z, Ga, Slepton (m1,g), Slepton (m2,-g)), Scalar2_Vector2 1, G_ZPSFSF (SL,g,m1,m2)); ((Z, Z, Slepton (m1,g), Slepton (m2,-g)), Scalar2_Vector2 1, G_ZZSFSF(SL,g,m1,m2)); ((Wp, Wm, Sup (m1,g), Sup (m2,-g)), Scalar2_Vector2 1, G_WWSFSF (SU,g,m1,m2)); ((Wp, Wm, Sdown (m1,g), Sdown (m2,-g)), Scalar2_Vector2 1, G_WWSFSF(SD,g,m1,m2)); ((Z, Z, Sup (m1,g), Sup (m2,-g)), Scalar2_Vector2 1, G_ZZSFSF (SU,g,m1,m2)); ((Z, Z, Sdown (m1,g), Sdown (m2,-g)), Scalar2_Vector2 1, G_ZZSFSF (SD,g,m1,m2)); ((Z, Ga, Sup (m1,g), Sup (m2,-g)), Scalar2_Vector2 1, G_ZPSFSF (SU,g,m1,m2)); ((Z, Ga, Sdown (m1,g), Sdown (m2,-g)), Scalar2_Vector2 1, G_ZPSFSF (SD,g,m1,m2)) ] let gauge_sfermion4'' g m = [ ((Wp, Ga, Slepton (m,g), Sneutrino (-g)), Scalar2_Vector2 1, G_WPSLSN (false,g,m)); ((Wm, Ga, Slepton (m,-g), Sneutrino g), Scalar2_Vector2 1, G_WPSLSN (true,g,m)); ((Wp, Z, Slepton (m,g), Sneutrino (-g)), Scalar2_Vector2 1, G_WZSLSN(false,g,m)); ((Wm, Z, Slepton (m,-g), Sneutrino g), Scalar2_Vector2 1, G_WZSLSN (true,g,m)); ((Ga, Ga, Slepton (m,g), Slepton (m,-g)), Scalar2_Vector2 1, G_PPSFSF SL); ((Ga, Ga, Sup (m,g), Sup (m,-g)), Scalar2_Vector2 1, G_PPSFSF SU); ((Ga, Ga, Sdown (m,g), Sdown (m,-g)), Scalar2_Vector2 1, G_PPSFSF SD)] let gauge_sfermion4 g = List.flatten (Product.list2 (gauge_sfermion4' g) [M1;M2] [M1;M2]) @ ThoList.flatmap (gauge_sfermion4'' g) [M1;M2] @ [ ((Wp, Wm, Sneutrino g, Sneutrino (-g)), Scalar2_Vector2 1, G_WWSFSF (SN,g,M1,M1)); ((Z, Z, Sneutrino g, Sneutrino (-g)), Scalar2_Vector2 1, G_ZZSFSF (SN,g,M1,M1)) ] (*** Added by Felix Braam. ***) let gauge_squark4'' g h m1 m2 = [ ((Wp, Ga, Sup (m1,-g), Sdown (m2,h)), Scalar2_Vector2 1, G_WPSUSD (false,m1,m2,g,h)); ((Wm, Ga, Sup (m1,g), Sdown (m2,-h)), Scalar2_Vector2 1, G_WPSUSD (true,m1,m2,g,h)); ((Wp, Z, Sup (m1,-g), Sdown (m2,h)), Scalar2_Vector2 1, G_WZSUSD (false,m1,m2,g,h)); ((Wm, Z, Sup (m1,g), Sdown (m2,-h)), Scalar2_Vector2 1, G_WZSUSD (true,m1,m2,g,h)) ] let gauge_squark4' g h = List.flatten (Product.list2 (gauge_squark4'' g h) [M1;M2] [M1;M2]) let gauge_squark4 = if Flags.ckm_present then List.flatten (Product.list2 gauge_squark4' [1;2;3] [1;2;3]) else ThoList.flatmap (fun g -> gauge_squark4' g g) [1;2;3] (**********************************FB*********************) let gluon_w_squark'' g h m1 m2 = [ ((Gl, Wp, Sup (m1,-g), Sdown (m2,h)), Scalar2_Vector2 1, G_GlWSUSD (false,m1,m2,g,h)); ((Gl, Wm, Sup (m1,g), Sdown (m2,-h)), Scalar2_Vector2 1, G_GlWSUSD (true,m1,m2,g,h)) ] let gluon_w_squark' g h = List.flatten (Product.list2 (gluon_w_squark'' g h) [M1;M2] [M1;M2]) let gluon_w_squark = if Flags.ckm_present then List.flatten (Product.list2 gluon_w_squark' [1;2;3] [1;2;3]) else ThoList.flatmap (fun g -> gluon_w_squark' g g) [1;2;3] (***********************************FB********************) let gluon_gauge_squark' g m1 m2 = [ ((Gl, Z, Sup (m1,g), Sup (m2,-g)), Scalar2_Vector2 2, G_GlZSFSF (SU,g,m1,m2)); ((Gl, Z, Sdown (m1,g), Sdown (m2,-g)), Scalar2_Vector2 2, G_GlZSFSF (SD,g,m1,m2)) ] let gluon_gauge_squark'' g m = [ ((Gl, Ga, Sup (m,g), Sup (m,-g)), Scalar2_Vector2 2, G_GlPSQSQ); ((Gl, Ga, Sdown (m,g), Sdown (m,-g)), Scalar2_Vector2 (-1), G_GlPSQSQ) ] let gluon_gauge_squark g = List.flatten (Product.list2 (gluon_gauge_squark' g) [M1;M2] [M1;M2]) @ ThoList.flatmap (gluon_gauge_squark'' g) [M1;M2] (*************************************FB******************) let gluon2_squark2' g m = [ ((Gl, Gl, Sup (m,g), Sup (m,-g)), Scalar2_Vector2 2, G_GlGlSQSQ); ((Gl, Gl, Sdown (m,g), Sdown (m,-g)), Scalar2_Vector2 2, G_GlGlSQSQ) ] let gluon2_squark2 g = ThoList.flatmap (gluon2_squark2' g) [M1;M2] (*** REVISED: Independent of the sign of CD. *FB**) (*** REVISED: Compact version using new COMBOS*) (*** REVISED: Couplings adjusted to FF-convention*) let higgs_SCC s = ((Hp, Hm, SHiggs s), Scalar_Scalar_Scalar 1, G_H3_SCC s ) let higgs_SSS (s1,s2,s3)= ((SHiggs s1, SHiggs s2, SHiggs s3), Scalar_Scalar_Scalar 1, G_H3_SSS (s1,s2,s3)) let higgs_SPP (p1,p2,s) = ((SHiggs s, PHiggs p1, PHiggs p2), Scalar_Scalar_Scalar 1, G_H3_SPP (s,p1,p2)) let higgs = List.map higgs_SCC [S1;S2;S3]@ List.map higgs_SSS (triples [S1;S2;S3])@ List.map higgs_SPP (two_and_one [P1;P2] [S1;S2;S3]) let higgs4 = [] (* The vertices of the type Higgs - Sfermion - Sfermion are independent of the choice of the CD sign since they are quadratic in the gauge coupling. *) (*** REVISED: Independent of the sign of CD. ***) let higgs_sneutrino' s g = ((SHiggs s, Sneutrino g, Sneutrino (-g)), Scalar_Scalar_Scalar 1, G_SFSFS (s,SN,g,M1,M1)) let higgs_sneutrino'' g m = [((Hp, Sneutrino (-g), Slepton (m,g)), Scalar_Scalar_Scalar 1, G_HSNSL (false,g,m)); ((Hm, Sneutrino g, Slepton (m,-g)), Scalar_Scalar_Scalar 1, G_HSNSL (true,g,m))] let higgs_sneutrino = Product.list2 higgs_sneutrino' [S1;S2;S3] [1;2;3] @ List.flatten ( Product.list2 higgs_sneutrino'' [1;2;3] [M1;M2] ) (* Under the assumption that there is no mixing between the left- and right-handed sfermions for the first two generations there is only a coupling of the form Higgs - sfermion1 - sfermion2 for the third generation. All the others are suppressed by $m_f/M_W$. *) (*** REVISED: Independent of the sign of CD. ***) let higgs_sfermion_S s g m1 m2 = [ ((SHiggs s, Slepton (m1,g), Slepton (m2,-g)), Scalar_Scalar_Scalar 1, G_SFSFS (s,SL,g,m1,m2)); ((SHiggs s, Sup (m1,g), Sup (m2,-g)), Scalar_Scalar_Scalar 1, G_SFSFS (s,SU,g,m1,m2)); ((SHiggs s, Sdown (m1,g), Sdown (m2,-g)), Scalar_Scalar_Scalar 1, G_SFSFS (s,SD,g,m1,m2))] let higgs_sfermion' g m1 m2 = (higgs_sfermion_S S1 g m1 m2) @ (higgs_sfermion_S S2 g m1 m2) @ (higgs_sfermion_S S3 g m1 m2) let higgs_sfermion_P p g m1 m2 = [ ((PHiggs p, Slepton (m1,g), Slepton (m2,-g)), Scalar_Scalar_Scalar 1, G_SFSFP (p,SL,g,m1,m2)); ((PHiggs p, Sup (m1,g), Sup (m2,-g)), Scalar_Scalar_Scalar 1, G_SFSFP (p,SU,g,m1,m2)); ((PHiggs p, Sdown (m1,g), Sdown (m2,-g)), Scalar_Scalar_Scalar 1, G_SFSFP (p,SD,g,m1,m2)) ] let higgs_sfermion'' g m1 m2 = (higgs_sfermion_P P1 g m1 m2) @ (higgs_sfermion_P P2 g m1 m2) let higgs_sfermion = List.flatten (Product.list3 higgs_sfermion' [1;2;3] [M1;M2] [M1;M2]) @ List.flatten (Product.list3 higgs_sfermion'' [1;2;3] [M1;M2] [M1;M2]) (*** REVISED: Independent of the sign of CD. ***) let higgs_squark' g h m1 m2 = [ ((Hp, Sup (m1,-g), Sdown (m2,h)), Scalar_Scalar_Scalar 1, G_HSUSD (false,m1,m2,g,h)); ((Hm, Sup (m1,g), Sdown (m2,-h)), Scalar_Scalar_Scalar 1, G_HSUSD (true,m1,m2,g,h)) ] let higgs_squark_a g h = higgs_squark' g h M1 M1 let higgs_squark_b (g,h) = List.flatten (Product.list2 (higgs_squark' g h) [M1;M2] [M1;M2]) let higgs_squark = if Flags.ckm_present then List.flatten (Product.list2 higgs_squark_a [1;2] [1;2]) @ ThoList.flatmap higgs_squark_b [(1,3);(2,3);(3,3);(3,1);(3,2)] else higgs_squark_a 1 1 @ higgs_squark_a 2 2 @ higgs_squark_b (3,3) let vertices3 = (ThoList.flatmap electromagnetic_currents_3 [1;2;3] @ ThoList.flatmap electromagnetic_currents_2 [C1;C2] @ List.flatten (Product.list2 electromagnetic_sfermion_currents [1;2;3] [M1;M2]) @ ThoList.flatmap neutral_currents [1;2;3] @ ThoList.flatmap neutral_sfermion_currents [1;2;3] @ ThoList.flatmap charged_currents [1;2;3] @ List.flatten (Product.list2 charged_slepton_currents [1;2;3] [M1;M2]) @ (if Flags.ckm_present then List.flatten (Product.list2 charged_quark_currents [1;2;3] [1;2;3]) @ List.flatten (Product.list2 charged_squark_currents [1;2;3] [1;2;3]) @ ThoList.flatmap yukawa_higgs_quark [(1,3);(2,3);(3,3);(3,1);(3,2)] else charged_quark_currents 1 1 @ charged_quark_currents 2 2 @ charged_quark_currents 3 3 @ charged_squark_currents 1 1 @ charged_squark_currents 2 2 @ charged_squark_currents 3 3 @ ThoList.flatmap yukawa_higgs_quark [(3,3)]) @ (*i ThoList.flatmap yukawa_higgs [1;2;3] @ i*) yukawa_higgs 3 @ yukawa_n @ ThoList.flatmap yukawa_c [C1;C2] @ ThoList.flatmap yukawa_cq [C1;C2] @ List.flatten (Product.list2 charged_chargino_currents [N1;N2;N3;N4;N5] [C1;C2]) @ triple_gauge @ ThoList.flatmap neutral_Z (pairs [N1;N2;N3;N4;N5]) @ Product.list2 charged_Z [C1;C2] [C1;C2] @ gauge_higgs @ higgs @ yukawa_higgs_2 @ (*i List.flatten (Product.list2 yukawa_higgs_quark [1;2;3] [1;2;3]) @ i*) List.flatten (Product.list2 higgs_charg_neutr [N1;N2;N3;N4;N5] [C1;C2]) @ higgs_neutr @ higgs_sneutrino @ higgs_sfermion @ higgs_squark @ yukawa_v @ ThoList.flatmap col_currents [1;2;3] @ List.flatten (Product.list2 col_sfermion_currents [1;2;3] [M1;M2])) let vertices4 = (quartic_gauge @ higgs4 @ gauge_higgs4 @ ThoList.flatmap gauge_sfermion4 [1;2;3] @ gauge_squark4 @ gluon_w_squark @ ThoList.flatmap gluon2_squark2 [1;2;3] @ ThoList.flatmap gluon_gauge_squark [1;2;3]) let vertices () = (vertices3, vertices4, []) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 (* SLHA2-Nomenclature for neutral Higgses *) let flavor_of_string s = match s with | "e-" -> L 1 | "e+" -> L (-1) | "mu-" -> L 2 | "mu+" -> L (-2) | "tau-" -> L 3 | "tau+" -> L (-3) | "nue" -> N 1 | "nuebar" -> N (-1) | "numu" -> N 2 | "numubar" -> N (-2) | "nutau" -> N 3 | "nutaubar" -> N (-3) | "se1-" -> Slepton (M1,1) | "se1+" -> Slepton (M1,-1) | "smu1-" -> Slepton (M1,2) | "smu1+" -> Slepton (M1,-2) | "stau1-" -> Slepton (M1,3) | "stau1+" -> Slepton (M1,-3) | "se2-" -> Slepton (M2,1) | "se2+" -> Slepton (M2,-1) | "smu2-" -> Slepton (M2,2) | "smu2+" -> Slepton (M2,-2) | "stau2-" -> Slepton (M2,3) | "stau2+" -> Slepton (M2,-3) | "snue" -> Sneutrino 1 | "snue*" -> Sneutrino (-1) | "snumu" -> Sneutrino 2 | "snumu*" -> Sneutrino (-2) | "snutau" -> Sneutrino 3 | "snutau*" -> Sneutrino (-3) | "u" -> U 1 | "ubar" -> U (-1) | "c" -> U 2 | "cbar" -> U (-2) | "t" -> U 3 | "tbar" -> U (-3) | "d" -> D 1 | "dbar" -> D (-1) | "s" -> D 2 | "sbar" -> D (-2) | "b" -> D 3 | "bbar" -> D (-3) | "A" -> Ga | "Z" | "Z0" -> Z | "W+" -> Wp | "W-" -> Wm | "gl" | "g" -> Gl | "h01" -> SHiggs S1 | "h02" -> SHiggs S2 | "h03" -> SHiggs S3 | "A01" -> PHiggs P1 | "A02" -> PHiggs P2 | "H+" -> Hp | "H-" -> Hm | "su1" -> Sup (M1,1) | "su1c" -> Sup (M1,-1) | "sc1" -> Sup (M1,2) | "sc1c" -> Sup (M1,-2) | "st1" -> Sup (M1,3) | "st1c" -> Sup (M1,-3) | "su2" -> Sup (M2,1) | "su2c" -> Sup (M2,-1) | "sc2" -> Sup (M2,2) | "sc2c" -> Sup (M2,-2) | "st2" -> Sup (M2,3) | "st2c" -> Sup (M2,-3) | "sgl" | "sg" -> Gluino | "sd1" -> Sdown (M1,1) | "sd1c" -> Sdown (M1,-1) | "ss1" -> Sdown (M1,2) | "ss1c" -> Sdown (M1,-2) | "sb1" -> Sdown (M1,3) | "sb1c" -> Sdown (M1,-3) | "sd2" -> Sdown (M2,1) | "sd2c" -> Sdown (M2,-1) | "ss2" -> Sdown (M2,2) | "ss2c" -> Sdown (M2,-2) | "sb2" -> Sdown (M2,3) | "sb2c" -> Sdown (M2,-3) | "neu1" -> Neutralino N1 | "neu2" -> Neutralino N2 | "neu3" -> Neutralino N3 | "neu4" -> Neutralino N4 | "neu5" -> Neutralino N5 | "ch1+" -> Chargino C1 | "ch2+" -> Chargino C2 | "ch1-" -> Chargino C1c | "ch2-" -> Chargino C2c | s -> invalid_arg ("Fatal error: %s Modellib_NMSSM.NMSSM.flavor_of_string:" ^ s) let flavor_to_string = function | L 1 -> "e-" | L (-1) -> "e+" | L 2 -> "mu-" | L (-2) -> "mu+" | L 3 -> "tau-" | L (-3) -> "tau+" | N 1 -> "nue" | N (-1) -> "nuebar" | N 2 -> "numu" | N (-2) -> "numubar" | N 3 -> "nutau" | N (-3) -> "nutaubar" | U 1 -> "u" | U (-1) -> "ubar" | U 2 -> "c" | U (-2) -> "cbar" | U 3 -> "t" | U (-3) -> "tbar" | U _ -> invalid_arg "Modellib_NMSSM.NMSSM.flavor_to_string: invalid up type quark" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | D _ -> invalid_arg "Modellib_NMSSM.NMSSM.flavor_to_string: invalid down type quark" | Gl -> "gl" | Gluino -> "sgl" | Ga -> "A" | Z -> "Z" | Wp -> "W+" | Wm -> "W-" | SHiggs S1 -> "h01" | SHiggs S2 -> "h02" | SHiggs S3 -> "h03" | PHiggs P1 -> "A01" | PHiggs P2 -> "A02" | Hp -> "H+" | Hm -> "H-" | Slepton (M1,1) -> "se1-" | Slepton (M1,-1) -> "se1+" | Slepton (M1,2) -> "smu1-" | Slepton (M1,-2) -> "smu1+" | Slepton (M1,3) -> "stau1-" | Slepton (M1,-3) -> "stau1+" | Slepton (M2,1) -> "se2-" | Slepton (M2,-1) -> "se2+" | Slepton (M2,2) -> "smu2-" | Slepton (M2,-2) -> "smu2+" | Slepton (M2,3) -> "stau2-" | Slepton (M2,-3) -> "stau2+" | Sneutrino 1 -> "snue" | Sneutrino (-1) -> "snue*" | Sneutrino 2 -> "snumu" | Sneutrino (-2) -> "snumu*" | Sneutrino 3 -> "snutau" | Sneutrino (-3) -> "snutau*" | Sup (M1,1) -> "su1" | Sup (M1,-1) -> "su1c" | Sup (M1,2) -> "sc1" | Sup (M1,-2) -> "sc1c" | Sup (M1,3) -> "st1" | Sup (M1,-3) -> "st1c" | Sup (M2,1) -> "su2" | Sup (M2,-1) -> "su2c" | Sup (M2,2) -> "sc2" | Sup (M2,-2) -> "sc2c" | Sup (M2,3) -> "st2" | Sup (M2,-3) -> "st2c" | Sdown (M1,1) -> "sd1" | Sdown (M1,-1) -> "sd1c" | Sdown (M1,2) -> "ss1" | Sdown (M1,-2) -> "ss1c" | Sdown (M1,3) -> "sb1" | Sdown (M1,-3) -> "sb1c" | Sdown (M2,1) -> "sd2" | Sdown (M2,-1) -> "sd2c" | Sdown (M2,2) -> "ss2" | Sdown (M2,-2) -> "ss2c" | Sdown (M2,3) -> "sb2" | Sdown (M2,-3) -> "sb2c" | Neutralino N1 -> "neu1" | Neutralino N2 -> "neu2" | Neutralino N3 -> "neu3" | Neutralino N4 -> "neu4" | Neutralino N5 -> "neu5" | Chargino C1 -> "ch1+" | Chargino C1c -> "ch1-" | Chargino C2 -> "ch2+" | Chargino C2c -> "ch2-" | _ -> invalid_arg "Modellib_NMSSM.NMSSM.flavor_to_string" let flavor_to_TeX = function | L 1 -> "e^-" | L (-1) -> "e^+" | L 2 -> "\\mu^-" | L (-2) -> "\\mu^+" | L 3 -> "\\tau^-" | L (-3) -> "\\tau^+" | N 1 -> "\\nu_e" | N (-1) -> "\\bar{\\nu}_e" | N 2 -> "\\nu_\\mu" | N (-2) -> "\\bar{\\nu}_\\mu" | N 3 -> "\\nu_\\tau" | N (-3) -> "\\bar{\\nu}_\\tau" | U 1 -> "u" | U (-1) -> "\\bar{u}" | U 2 -> "c" | U (-2) -> "\\bar{c}" | U 3 -> "t" | U (-3) -> "\\bar{t}" | D 1 -> "d" | D (-1) -> "\\bar{d}" | D 2 -> "s" | D (-2) -> "\\bar{s}" | D 3 -> "b" | D (-3) -> "\\bar{b}" | L _ -> invalid_arg "Modellib_NMSSM.NMSSM.flavor_to_TeX: invalid lepton" | N _ -> invalid_arg "Modellib_NMSSM.NMSSM.flavor_to_TeX: invalid neutrino" | U _ -> invalid_arg "Modellib_NMSSM.NMSSM.flavor_to_TeX: invalid up type quark" | D _ -> invalid_arg "Modellib_NMSSM.NMSSM.flavor_to_TeX: invalid down type quark" | Gl -> "g" | Gluino -> "\\widetilde{g}" | Ga -> "\\gamma" | Z -> "Z" | Wp -> "W^+" | Wm -> "W^-" | SHiggs S1 -> "S_1" | SHiggs S2 -> "S_2" | SHiggs S3 -> "S_3" | PHiggs P1 -> "P_1" | PHiggs P2 -> "P_2" | Hp -> "H^+" | Hm -> "H^-" | Slepton (M1,1) -> "\\widetilde{e}_1^-" | Slepton (M1,-1) -> "\\widetilde{e}_1^+" | Slepton (M1,2) -> "\\widetilde{\\mu}_1^-" | Slepton (M1,-2) -> "\\widetilde{\\mu}_1^+" | Slepton (M1,3) -> "\\widetilde{\\tau}_1^-" | Slepton (M1,-3) -> "\\widetilde{\\tau}_1^+" | Slepton (M2,1) -> "\\widetilde{e}_2^-" | Slepton (M2,-1) -> "\\widetilde{e}_2^+" | Slepton (M2,2) -> "\\widetilde{\\mu}_2^-" | Slepton (M2,-2) -> "\\widetilde{\\mu}_2^+" | Slepton (M2,3) -> "\\widetilde{\\tau}_2^-" | Slepton (M2,-3) -> "\\widetilde{\\tau}_2^+" | Sneutrino 1 -> "\\widetilde{\\nu}_e" | Sneutrino (-1) -> "\\widetilde{\\nu}_e^*" | Sneutrino 2 -> "\\widetilde{\\nu}_\\mu" | Sneutrino (-2) -> "\\widetilde{\\nu}_\\mu^*" | Sneutrino 3 -> "\\widetilde{\\nu}_\\tau" | Sneutrino (-3) -> "\\widetilde{\\nu}_\\tau^*" | Sup (M1,1) -> "\\widetilde{u}_1" | Sup (M1,-1) -> "\\widetilde{u}_1^*" | Sup (M1,2) -> "\\widetilde{c}_1" | Sup (M1,-2) -> "\\widetilde{c}_1^*" | Sup (M1,3) -> "\\widetilde{t}_1" | Sup (M1,-3) -> "\\widetilde{t}_1^*" | Sup (M2,1) -> "\\widetilde{u}_2" | Sup (M2,-1) -> "\\widetilde{u}_2^*" | Sup (M2,2) -> "\\widetilde{c}_2" | Sup (M2,-2) -> "\\widetilde{c}_2^*" | Sup (M2,3) -> "\\widetilde{t}_2" | Sup (M2,-3) -> "\\widetilde{t}_2^*" | Sdown (M1,1) -> "\\widetilde{d}_1" | Sdown (M1,-1) -> "\\widetilde{d}_1^*" | Sdown (M1,2) -> "\\widetilde{s}_1" | Sdown (M1,-2) -> "\\widetilde{s}_1^*" | Sdown (M1,3) -> "\\widetilde{b}_1" | Sdown (M1,-3) -> "\\widetilde{b}_1^*" | Sdown (M2,1) -> "\\widetilde{d}_2" | Sdown (M2,-1) -> "\\widetilde{d}_2^*" | Sdown (M2,2) -> "\\widetilde{s}_2" | Sdown (M2,-2) -> "\\widetilde{s}_2^*" | Sdown (M2,3) -> "\\widetilde{b}_2" | Sdown (M2,-3) -> "\\widetilde{b}_2^*" | Neutralino N1 -> "\\widetilde{\\chi}^0_1" | Neutralino N2 -> "\\widetilde{\\chi}^0_2" | Neutralino N3 -> "\\widetilde{\\chi}^0_3" | Neutralino N4 -> "\\widetilde{\\chi}^0_4" | Neutralino N5 -> "\\widetilde{\\chi}^0_5" | Slepton _ -> invalid_arg "Modellib_NMSSM.NMSSM.flavor_to_TeX: invalid slepton" | Sneutrino _ -> invalid_arg "Modellib_NMSSM.NMSSM.flavor_to_TeX: invalid sneutrino" | Sup _ -> invalid_arg "Modellib_NMSSM.NMSSM.flavor_to_TeX: invalid up type squark" | Sdown _ -> invalid_arg "Modellib_NMSSM.NMSSM.flavor_to_TeX: invalid down type squark" | Chargino C1 -> "\\widetilde{\\chi}_1^+" | Chargino C1c -> "\\widetilde{\\chi}_1^-" | Chargino C2 -> "\\widetilde{\\chi}_2^+" | Chargino C2c -> "\\widetilde{\\chi}_2^-" let flavor_symbol = function | L g when g > 0 -> "l" ^ string_of_int g | L g -> "l" ^ string_of_int (abs g) ^ "b" | N g when g > 0 -> "n" ^ string_of_int g | N g -> "n" ^ string_of_int (abs g) ^ "b" | U g when g > 0 -> "u" ^ string_of_int g | U g -> "u" ^ string_of_int (abs g) ^ "b" | D g when g > 0 -> "d" ^ string_of_int g | D g -> "d" ^ string_of_int (abs g) ^ "b" | Gl -> "gl" | Ga -> "a" | Z -> "z" | Wp -> "wp" | Wm -> "wm" | Slepton (M1,g) when g > 0 -> "sl1" ^ string_of_int g | Slepton (M1,g) -> "sl1c" ^ string_of_int (abs g) | Slepton (M2,g) when g > 0 -> "sl2" ^ string_of_int g | Slepton (M2,g) -> "sl2c" ^ string_of_int (abs g) | Sneutrino g when g > 0 -> "sn" ^ string_of_int g | Sneutrino g -> "snc" ^ string_of_int (abs g) | Sup (M1,g) when g > 0 -> "su1" ^ string_of_int g | Sup (M1,g) -> "su1c" ^ string_of_int (abs g) | Sup (M2,g) when g > 0 -> "su2" ^ string_of_int g | Sup (M2,g) -> "su2c" ^ string_of_int (abs g) | Sdown (M1,g) when g > 0 -> "sd1" ^ string_of_int g | Sdown (M1,g) -> "sd1c" ^ string_of_int (abs g) | Sdown (M2,g) when g > 0 -> "sd2" ^ string_of_int g | Sdown (M2,g) -> "sd2c" ^ string_of_int (abs g) | Neutralino n -> "neu" ^ (string_of_neu n) | Chargino c when (int_of_char c) > 0 -> "cp" ^ string_of_char c | Chargino c -> "cm" ^ string_of_int (abs (int_of_char c)) | Gluino -> "sgl" | SHiggs s -> "h0" ^ (string_of_shiggs s) | PHiggs p -> "A0" ^ (string_of_phiggs p) | Hp -> "hp" | Hm -> "hm" let pdg = function | L g when g > 0 -> 9 + 2*g | L g -> - 9 + 2*g | N g when g > 0 -> 10 + 2*g | N g -> - 10 + 2*g | U g when g > 0 -> 2*g | U g -> 2*g | D g when g > 0 -> - 1 + 2*g | D g -> 1 + 2*g | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) | SHiggs S1 -> 25 | SHiggs S2 -> 35 | SHiggs S3 -> 45 | PHiggs P1 -> 36 | PHiggs P2 -> 46 | Hp -> 37 | Hm -> (-37) | Slepton (M1,g) when g > 0 -> 1000009 + 2*g | Slepton (M1,g) -> - 1000009 + 2*g | Slepton (M2,g) when g > 0 -> 2000009 + 2*g | Slepton (M2,g) -> - 2000009 + 2*g | Sneutrino g when g > 0 -> 1000010 + 2*g | Sneutrino g -> - 1000010 + 2*g | Sup (M1,g) when g > 0 -> 1000000 + 2*g | Sup (M1,g) -> - 1000000 + 2*g | Sup (M2,g) when g > 0 -> 2000000 + 2*g | Sup (M2,g) -> - 2000000 + 2*g | Sdown (M1,g) when g > 0 -> 999999 + 2*g | Sdown (M1,g) -> - 999999 + 2*g | Sdown (M2,g) when g > 0 -> 1999999 + 2*g | Sdown (M2,g) -> - 1999999 + 2*g | Gluino -> 1000021 | Chargino C1 -> 1000024 | Chargino C1c -> (-1000024) | Chargino C2 -> 1000037 | Chargino C2c -> (-1000037) | Neutralino N1 -> 1000022 | Neutralino N2 -> 1000023 | Neutralino N3 -> 1000025 | Neutralino N4 -> 1000035 | Neutralino N5 -> 1000045 (* We must take care of the pdg numbers for the two different kinds of sfermions in the MSSM. The particle data group in its Monte Carlo particle numbering scheme takes only into account mixtures of the third generation squarks and the stau. For the other sfermions we will use the number of the lefthanded field for the lighter mixed state and the one for the righthanded for the heavier. Below are the official pdg numbers from the Particle Data Group. In order not to produce arrays with some million entries in the Fortran code for the masses and the widths we introduce our private pdg numbering scheme which only extends not too far beyond 42. Our private scheme then has the following pdf numbers (for the sparticles the subscripts $L/R$ and $1/2$ are taken synonymously): \begin{center} \renewcommand{\arraystretch}{1.2} \begin{tabular}{|r|l|l|}\hline $d$ & down-quark & 1 \\\hline $u$ & up-quark & 2 \\\hline $s$ & strange-quark & 3 \\\hline $c$ & charm-quark & 4 \\\hline $b$ & bottom-quark & 5 \\\hline $t$ & top-quark & 6 \\\hline\hline $e^-$ & electron & 11 \\\hline $\nu_e$ & electron-neutrino & 12 \\\hline $\mu^-$ & muon & 13 \\\hline $\nu_\mu$ & muon-neutrino & 14 \\\hline $\tau^-$ & tau & 15 \\\hline $\nu_\tau$ & tau-neutrino & 16 \\\hline\hline $g$ & gluon & (9) 21 \\\hline $\gamma$ & photon & 22 \\\hline $Z^0$ & Z-boson & 23 \\\hline $W^+$ & W-boson & 24 \\\hline\hline $h^0$ & light Higgs boson & 25 \\\hline $H^0$ & heavy Higgs boson & 35 \\\hline $A^0$ & pseudoscalar Higgs & 36 \\\hline $H^+$ & charged Higgs & 37 \\\hline\hline $\tilde{d}_L$ & down-squark 1 & 41 \\\hline $\tilde{u}_L$ & up-squark 1 & 42 \\\hline $\tilde{s}_L$ & strange-squark 1 & 43 \\\hline $\tilde{c}_L$ & charm-squark 1 & 44 \\\hline $\tilde{b}_L$ & bottom-squark 1 & 45 \\\hline $\tilde{t}_L$ & top-squark 1 & 46 \\\hline $\tilde{d}_R$ & down-squark 2 & 47 \\\hline $\tilde{u}_R$ & up-squark 2 & 48 \\\hline $\tilde{s}_R$ & strange-squark 2 & 49 \\\hline $\tilde{c}_R$ & charm-squark 2 & 50 \\\hline $\tilde{b}_R$ & bottom-squark 2 & 51 \\\hline $\tilde{t}_R$ & top-squark 2 & 52 \\\hline\hline $\tilde{e}_L$ & selectron 1 & 53 \\\hline $\tilde{\nu}_{e,L}$ & electron-sneutrino & 54 \\\hline $\tilde{\mu}_L$ & smuon 1 & 55 \\\hline $\tilde{\nu}_{\mu,L}$ & muon-sneutrino & 56 \\\hline $\tilde{\tau}_L$ & stau 1 & 57 \\\hline $\tilde{\nu}_{\tau,L}$ & tau-sneutrino & 58 \\\hline $\tilde{e}_R$ & selectron 2 & 59 \\\hline $\tilde{\mu}_R$ & smuon 2 & 61 \\\hline $\tilde{\tau}_R$ & stau 2 & 63 \\\hline\hline $\tilde{g}$ & gluino & 64 \\\hline $\tilde{\chi}^0_1$ & neutralino 1 & 65 \\\hline $\tilde{\chi}^0_2$ & neutralino 2 & 66 \\\hline $\tilde{\chi}^0_3$ & neutralino 3 & 67 \\\hline $\tilde{\chi}^0_4$ & neutralino 4 & 68 \\\hline $\tilde{\chi}^0_5$ & neutralino 5 & 69 \\\hline $\tilde{\chi4}^+_1$ & chargino 1 & 70 \\\hline $\tilde{\chi}^+_2$ & chargino 2 & 71 \\\hline\hline $a$ & pseudoscalar & 72 \\\hline $s$ & scalar singlet & 73 \\\hline $\tilde{G}$ & gravitino & -- \\\hline\hline \end{tabular} \end{center} *) let pdg_mw = function | L g when g > 0 -> 9 + 2*g | L g -> - 9 + 2*g | N g when g > 0 -> 10 + 2*g | N g -> - 10 + 2*g | U g when g > 0 -> 2*g | U g -> 2*g | D g when g > 0 -> - 1 + 2*g | D g -> 1 + 2*g | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) | SHiggs S1 -> 25 | SHiggs S2 -> 35 | PHiggs P1 -> 36 | Hp -> 37 | Hm -> (-37) | Sup (M1,g) when g > 0 -> 40 + 2*g | Sup (M1,g) -> - 40 + 2*g | Sup (M2,g) when g > 0 -> 46 + 2*g | Sup (M2,g) -> - 46 + 2*g | Sdown (M1,g) when g > 0 -> 39 + 2*g | Sdown (M1,g) -> - 39 + 2*g | Sdown (M2,g) when g > 0 -> 45 + 2*g | Sdown (M2,g) -> - 45 + 2*g | Slepton (M1,g) when g > 0 -> 51 + 2*g | Slepton (M1,g) -> - 51 + 2*g | Slepton (M2,g) when g > 0 -> 57 + 2*g | Slepton (M2,g) -> - 57 + 2*g | Sneutrino g when g > 0 -> 52 + 2*g | Sneutrino g -> - 52 + 2*g | Gluino -> 64 | Chargino C1 -> 70 | Chargino C1c -> (-70) | Chargino C2 -> 71 | Chargino C2c -> (-71) | Neutralino N1 -> 65 | Neutralino N2 -> 66 | Neutralino N3 -> 67 | Neutralino N4 -> 68 | Neutralino N5 -> 69 | PHiggs P2 -> 72 | SHiggs S3 -> 73 let mass_symbol f = "mass(" ^ string_of_int (abs (pdg_mw f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg_mw f)) ^ ")" let conj_symbol = function | false, str -> str | true, str -> str ^ "_c" let constant_symbol = function | E -> "e" | G -> "g" | Mu -> "mu" | Lambda -> "lambda" | G_Z -> "gz" | Q_lepton -> "qlep" | Q_up -> "qup" | Q_down -> "qdwn" | Q_charg -> "qchar" | G_NC_lepton -> "gnclep" | G_NC_neutrino -> "gncneu" | G_NC_up -> "gncup" | G_NC_down -> "gncdwn" | G_CC -> "gcc" | G_CCQ (vc,g1,g2) -> conj_symbol (vc, "g_ccq" ) ^ "(" ^ string_of_int g1 ^ "," ^ string_of_int g2 ^ ")" | I_Q_W -> "iqw" | I_G_ZWW -> "igzww" | G_WWWW -> "gw4" | G_ZZWW -> "gzzww" | G_PZWW -> "gpzww" | G_PPWW -> "gppww" | G_GH4_ZZPP (p1,p2) -> "g_ZZA0A0(" ^ string_of_phiggs p1 ^ "," ^ string_of_phiggs p2 ^ ")" | G_GH4_ZZSS (s1,s2) -> "g_ZZh0h0(" ^ string_of_shiggs s1 ^ "," ^ string_of_shiggs s2 ^ ")" | G_GH4_ZZCC -> "g_zzhphm" | G_GH4_GaGaCC -> "g_AAhphm" | G_GH4_ZGaCC -> "g_zAhphm" | G_GH4_WWCC -> "g_wwhphm" | G_GH4_WWPP (p1,p2) -> "g_WWA0A0(" ^ string_of_phiggs p1 ^ "," ^ string_of_phiggs p2 ^ ")" | G_GH4_WWSS (s1,s2) -> "g_WWh0h0(" ^ string_of_shiggs s1 ^ "," ^ string_of_shiggs s2 ^ ")" | G_GH4_ZWSC s -> "g_ZWhph0(" ^ string_of_shiggs s ^")" | G_GH4_GaWSC s -> "g_AWhph0(" ^ string_of_shiggs s ^")" | G_GH4_ZWPC p -> "g_ZWhpA0(" ^ string_of_phiggs p ^")" | G_GH4_GaWPC p -> "g_AWhpA0(" ^ string_of_phiggs p ^")" | G_CICIS (n1,n2,s) -> "g_neuneuh0(" ^ string_of_neu n1 ^ "," ^ string_of_neu n2 ^ "," ^ string_of_shiggs s ^ ")" | G_CICIP (n1,n2,p) -> "g_neuneuA0(" ^ string_of_neu n1 ^ "," ^ string_of_neu n2 ^ "," ^ string_of_phiggs p ^ ")" | G_H3_SCC s -> "g_h0hphm(" ^ string_of_shiggs s ^ ")" | G_H3_SPP (s,p1,p2) -> "g_h0A0A0(" ^ string_of_shiggs s ^ "," ^ string_of_phiggs p1 ^ "," ^ string_of_phiggs p2 ^ ")" | G_H3_SSS (s1,s2,s3) -> "g_h0h0h0(" ^ string_of_shiggs s1 ^ "," ^ string_of_shiggs s2 ^ "," ^ string_of_shiggs s3 ^ ")" | G_CSC (c1,c2,s) -> "g_chchh0(" ^ string_of_char c1 ^ "," ^ string_of_char c2 ^ "," ^ string_of_shiggs s ^")" | G_CPC (c1,c2,p) -> "g_chchA0(" ^ string_of_char c1 ^ "," ^ string_of_char c2 ^ "," ^ string_of_phiggs p ^")" | G_YUK_FFS (f1,f2,s) -> "g_yuk_h0_" ^ string_of_fermion_type f1 ^ string_of_fermion_type f2 ^ "(" ^ string_of_shiggs s ^ "," ^ string_of_fermion_gen f1 ^ ")" | G_YUK_FFP (f1,f2,p) -> "g_yuk_A0_" ^ string_of_fermion_type f1 ^ string_of_fermion_type f2 ^ "(" ^ string_of_phiggs p ^ "," ^ string_of_fermion_gen f1 ^ ")" | G_YUK_LCN g -> "g_yuk_hp_ln(" ^ string_of_int g ^ ")" | G_NWC (n,c) -> "g_nwc(" ^ string_of_char c ^ "," ^ string_of_neu n ^ ")" | G_CWN (c,n) -> "g_cwn(" ^ string_of_char c ^ "," ^ string_of_neu n ^ ")" | G_SLSNW (vc,g,m) -> conj_symbol (vc, "g_wslsn") ^ "(" ^ string_of_int g ^ "," ^ string_of_sfm m ^ ")" | G_NZN (n1,n2) -> "g_zneuneu(" ^ string_of_neu n1 ^ "," ^ string_of_neu n2 ^ ")" | G_CZC (c1,c2) -> "g_zchch(" ^ string_of_char c1 ^ "," ^ string_of_char c2 ^ ")" | Gs -> "gs" | G_YUK_UCD (n,m) -> "g_yuk_hp_ud(" ^ string_of_int n ^ "," ^ string_of_int m ^ ")" | G_YUK_DCU (n,m) -> "g_yuk_hm_du(" ^ string_of_int n ^ "," ^ string_of_int m ^ ")" | G_YUK_N (vc,f,n,sf,m) -> conj_symbol (vc, "g_yuk_neu_" ^ string_of_fermion_type f ^ string_of_sff sf) ^ "(" ^ string_of_fermion_gen f ^ "," ^ string_of_neu n ^ "," ^ string_of_sfm m ^ ")" | G_YUK_G (vc,f,sf,m) -> conj_symbol (vc, "g_yuk_gluino_" ^ string_of_fermion_type f ^ string_of_sff sf) ^ "(" ^ string_of_fermion_gen f ^ "," ^ string_of_sfm m ^ ")" | G_YUK_C (vc,f,c,sf,m) -> conj_symbol (vc, "g_yuk_char_" ^ string_of_fermion_type f ^ string_of_sff sf) ^ "(" ^ string_of_fermion_gen f ^ "," ^ string_of_char c ^ "," ^ string_of_sfm m ^ ")" | G_YUK_Q (vc,g1,f,c,sf,m) -> conj_symbol (vc, "g_yuk_char_" ^ string_of_fermion_type f ^ string_of_sff sf) ^ "(" ^ string_of_int g1 ^ "," ^ string_of_fermion_gen f ^ "," ^ string_of_char c ^ "," ^ string_of_sfm m ^ ")" | G_WPSUSD (vc,m1,m2,g1,g2) -> conj_symbol (vc, "g_wA_susd") ^ "(" ^ string_of_int g1 ^ "," ^ string_of_int g2 ^ "," ^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ ")" | G_WZSUSD (vc,m1,m2,g1,g2) -> conj_symbol (vc, "g_wz_susd") ^ "(" ^ string_of_int g1 ^ "," ^ string_of_int g2 ^ "," ^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ ")" | G_GH_ZSP (s,p) -> "g_zh0a0(" ^ string_of_shiggs s ^ "," ^ string_of_phiggs p ^ ")" | G_GH_WSC s -> "g_Whph0(" ^ string_of_shiggs s ^ ")" | G_GH_WPC p -> "g_WhpA0(" ^ string_of_phiggs p ^ ")" | G_GH_ZZS s -> "g_ZZh0(" ^ string_of_shiggs s ^ ")" | G_GH_WWS s -> "g_WWh0(" ^ string_of_shiggs s ^ ")" | G_GLUGLUH0 s -> "g_glugluh0(" ^ string_of_shiggs s ^ ")" | G_GLUGLUA0 p -> "g_gluglua0(" ^ string_of_phiggs p ^ ")" | G_GH_ZCC -> "g_Zhmhp" | G_GH_GaCC -> "g_Ahmhp" | G_ZSF (f,g,m1,m2) -> "g_z" ^ string_of_sff f ^ string_of_sff f ^ "(" ^ string_of_int g ^ "," ^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ ")" | G_HSNSL (vc,g,m) -> conj_symbol (vc, "g_hp_sl" ^ string_of_sfm m ^ "sn1") ^ "(" ^ string_of_int g ^ ")" | G_GlGlSQSQ -> "g_gg_sqsq" | G_PPSFSF f -> "g_AA_" ^ string_of_sff f ^ string_of_sff f | G_ZZSFSF (f,g,m1,m2) -> "g_zz_" ^ string_of_sff f ^ string_of_sff f ^ "(" ^ string_of_int g ^","^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ ")" | G_ZPSFSF (f,g,m1,m2) -> "g_zA_" ^ string_of_sff f ^ string_of_sff f ^ "(" ^ string_of_int g ^","^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ ")" | G_GlPSQSQ -> "g_gA_sqsq" | G_GlZSFSF (f,g,m1,m2) -> "g_gz_" ^ string_of_sff f ^ string_of_sff f ^ "(" ^ string_of_int g ^ "," ^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ ")" | G_GlWSUSD (vc,m1,m2,g1,g2) -> conj_symbol (vc, "g_gw_susd") ^ "(" ^ string_of_int g1 ^ "," ^ string_of_int g2 ^ "," ^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ ")" | G_SS -> "gs**2" | I_G_S -> "igs" | G_NHC (vc,n,c) -> conj_symbol(vc,"g_neuhmchar") ^ "(" ^ string_of_neu n ^ "," ^ string_of_char c ^")" | G_WWSFSF (f,g,m1,m2) -> "g_ww_" ^ string_of_sff f ^ string_of_sff f ^"(" ^ string_of_int g ^ "," ^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ ")" | G_WPSLSN (vc,g,m) -> conj_symbol (vc, "g_wA_slsn") ^ "(" ^ string_of_int g ^ "," ^ string_of_sfm m ^ ")" | G_WZSLSN (vc,g,m) -> conj_symbol (vc, "g_wz_slsn") ^"("^ string_of_int g ^ "," ^ string_of_sfm m ^ ")" | G_SFSFS (s,f,g,m1,m2) -> "g_h0_"^ string_of_sff f ^ string_of_sfm m1 ^ string_of_sff f ^ string_of_sfm m2 ^ "(" ^ string_of_shiggs s ^ "," ^ string_of_int g ^ ")" | G_SFSFP (p,f,g,m1,m2) -> "g_A0_"^ string_of_sff f ^ string_of_sfm m1 ^ string_of_sff f ^ string_of_sfm m2 ^ "(" ^ string_of_phiggs p ^ "," ^ string_of_int g ^ ")" | G_HSUSD (vc,m1,m2,g1,g2) -> conj_symbol (vc, "g_hp_su" ^ string_of_sfm m1 ^ "sd" ^ string_of_sfm m2 )^ "(" ^ string_of_int g1 ^ "," ^ string_of_int g2 ^")" | G_WSQ (vc,g1,g2,m1,m2) -> conj_symbol (vc, "g_wsusd") ^ "(" ^ string_of_int g1 ^ "," ^ string_of_int g2 ^ "," ^ string_of_sfm m1 ^ "," ^ string_of_sfm m2 ^ ")" end Index: trunk/omega/src/modellib_NoH.ml =================================================================== --- trunk/omega/src/modellib_NoH.ml (revision 8413) +++ trunk/omega/src/modellib_NoH.ml (revision 8414) @@ -1,2920 +1,2922 @@ (* modellib_NoH.ml -- Copyright (C) 1999-2020 by Wolfgang Kilian Thorsten Ohl Juergen Reuter with contributions from Christian Speckner Marco Sekulla Fabian Bach (only parts of this file) WHIZARD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. WHIZARD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *) (* \thocwmodulesection{Minimal Higgsless Model (Unitarity Gauge)} *) module type NoH_flags = sig val triple_anom : bool val quartic_anom : bool val k_matrix : bool val ckm_present : bool val top_anom : bool val top_anom_4f : bool end module NoH_k_matrix : NoH_flags = struct let triple_anom = false let quartic_anom = false let k_matrix = true let ckm_present = false let top_anom = false let top_anom_4f = false end (* \thocwmodulesection{Minimal Higgsless Model including unitarization} *) module NoH (Flags : NoH_flags) = struct open Coupling let default_width = ref Timelike let use_fudged_width = ref false let options = Options.create [ "constant_width", Arg.Unit (fun () -> default_width := Constant), "use constant width (also in t-channel)"; "fudged_width", Arg.Set use_fudged_width, "use fudge factor for charge particle width"; "custom_width", Arg.String (fun f -> default_width := Custom f), "use custom width"; "cancel_widths", Arg.Unit (fun () -> default_width := Vanishing), "use vanishing width"; "cms_width", Arg.Unit (fun () -> default_width := Complex_Mass), - "use complex mass scheme"] + "use complex mass scheme"; + "running_width", Arg.Unit (fun () -> default_width := Running), + "use running width"] type f_aux_top = TTGG | TBWA | TBWZ | TTWW | BBWW | (*i top auxiliary field "flavors" *) QGUG | QBUB | QW | DL | DR | QUQD1L | QUQD1R | QUQD8L | QUQD8R type matter_field = L of int | N of int | U of int | D of int type gauge_boson = Ga | Wp | Wm | Z | Gl type other = Phip | Phim | Phi0 | Aux_top of int*int*int*bool*f_aux_top (*i lorentz*color*charge*top-side*flavor *) type flavor = M of matter_field | G of gauge_boson | O of other let matter_field f = M f let gauge_boson f = G f let other f = O f type field = | Matter of matter_field | Gauge of gauge_boson | Other of other let field = function | M f -> Matter f | G f -> Gauge f | O f -> Other f type gauge = unit let gauge_symbol () = failwith "Modellib.NoH.gauge_symbol: internal error" let family n = List.map matter_field [ L n; N n; U n; D n ] let rec aux_top_flavors (f,l,co,ch) = List.append ( List.map other [ Aux_top(l,co,ch/2,true,f); Aux_top(l,co,ch/2,false,f) ] ) ( if ch > 1 then List.append ( List.map other [ Aux_top(l,co,-ch/2,true,f); Aux_top(l,co,-ch/2,false,f) ] ) ( aux_top_flavors (f,l,co,(ch-2)) ) else [] ) let external_flavors () = [ "1st Generation", ThoList.flatmap family [1; -1]; "2nd Generation", ThoList.flatmap family [2; -2]; "3rd Generation", ThoList.flatmap family [3; -3]; "Gauge Bosons", List.map gauge_boson [Ga; Z; Wp; Wm; Gl]; "Goldstone Bosons", List.map other [Phip; Phim; Phi0] ] let flavors () = List.append ( ThoList.flatmap snd (external_flavors ()) ) ( ThoList.flatmap aux_top_flavors [ (TTGG,2,1,1); (TBWA,2,0,2); (TBWZ,2,0,2); (TTWW,2,0,1); (BBWW,2,0,1); (QGUG,1,1,1); (QBUB,1,0,1); (QW,1,0,3); (DL,0,0,3); (DR,0,0,3); (QUQD1L,0,0,3); (QUQD1R,0,0,3); (QUQD8L,0,1,3); (QUQD8R,0,1,3) ] ) let spinor n = if n >= 0 then Spinor else ConjSpinor let lorentz_aux = function | 2 -> Tensor_1 | 1 -> Vector | 0 -> Scalar | _ -> invalid_arg ("NoH.lorentz_aux: wrong value") let lorentz = function | M f -> begin match f with | L n -> spinor n | N n -> spinor n | U n -> spinor n | D n -> spinor n end | G f -> begin match f with | Ga | Gl -> Vector | Wp | Wm | Z -> Massive_Vector end | O f -> begin match f with | Aux_top (l,_,_,_,_) -> lorentz_aux l | _ -> Scalar end let color = function | M (U n) -> Color.SUN (if n > 0 then 3 else -3) | M (D n) -> Color.SUN (if n > 0 then 3 else -3) | G Gl -> Color.AdjSUN 3 | O (Aux_top (_,co,_,_,_)) -> if co == 0 then Color.Singlet else Color.AdjSUN 3 | _ -> Color.Singlet let nc () = 3 let prop_spinor n = if n >= 0 then Prop_Spinor else Prop_ConjSpinor let prop_aux = function | 2 -> Aux_Tensor_1 | 1 -> Aux_Vector | 0 -> Aux_Scalar | _ -> invalid_arg ("NoH.prop_aux: wrong value") let propagator = function | M f -> begin match f with | L n -> prop_spinor n | N n -> prop_spinor n | U n -> prop_spinor n | D n -> prop_spinor n end | G f -> begin match f with | Ga | Gl -> Prop_Feynman | Wp | Wm | Z -> Prop_Unitarity end | O f -> begin match f with | Phip | Phim | Phi0 -> Only_Insertion | Aux_top (l,_,_,_,_) -> prop_aux l end (* Optionally, ask for the fudge factor treatment for the widths of charged particles. Currently, this only applies to $W^\pm$ and top. *) let width f = if !use_fudged_width then match f with | G Wp | G Wm | M (U 3) | M (U (-3)) -> Fudged | _ -> !default_width else !default_width let goldstone = function | G f -> begin match f with | Wp -> Some (O Phip, Coupling.Integer 1) | Wm -> Some (O Phim, Coupling.Integer 1) | Z -> Some (O Phi0, Coupling.Integer 1) | _ -> None end | _ -> None let conjugate = function | M f -> M (begin match f with | L n -> L (-n) | N n -> N (-n) | U n -> U (-n) | D n -> D (-n) end) | G f -> G (begin match f with | Gl -> Gl | Ga -> Ga | Z -> Z | Wp -> Wm | Wm -> Wp end) | O f -> O (begin match f with | Phip -> Phim | Phim -> Phip | Phi0 -> Phi0 | Aux_top (l,co,ch,n,f) -> Aux_top (l,co,(-ch),(not n),f) end) let fermion = function | M f -> begin match f with | L n -> if n > 0 then 1 else -1 | N n -> if n > 0 then 1 else -1 | U n -> if n > 0 then 1 else -1 | D n -> if n > 0 then 1 else -1 end | G f -> begin match f with | Gl | Ga | Z | Wp | Wm -> 0 end | O _ -> 0 (* Electrical charge, lepton number, baryon number. We could avoid the rationals altogether by multiplying the first and last by 3 \ldots *) module Ch = Charges.QQ let ( // ) = Algebra.Small_Rational.make let generation' = function | 1 -> [ 1//1; 0//1; 0//1] | 2 -> [ 0//1; 1//1; 0//1] | 3 -> [ 0//1; 0//1; 1//1] | -1 -> [-1//1; 0//1; 0//1] | -2 -> [ 0//1; -1//1; 0//1] | -3 -> [ 0//1; 0//1; -1//1] | n -> invalid_arg ("NoH.generation': " ^ string_of_int n) let generation f = if Flags.ckm_present then [] else match f with | M (L n | N n | U n | D n) -> generation' n | G _ | O _ -> [0//1; 0//1; 0//1] let charge = function | M f -> begin match f with | L n -> if n > 0 then -1//1 else 1//1 | N n -> 0//1 | U n -> if n > 0 then 2//3 else -2//3 | D n -> if n > 0 then -1//3 else 1//3 end | G f -> begin match f with | Gl | Ga | Z -> 0//1 | Wp -> 1//1 | Wm -> -1//1 end | O f -> begin match f with | Phi0 -> 0//1 | Phip -> 1//1 | Phim -> -1//1 | Aux_top (_,_,ch,_,_) -> ch//1 end let lepton = function | M f -> begin match f with | L n | N n -> if n > 0 then 1//1 else -1//1 | U _ | D _ -> 0//1 end | G _ | O _ -> 0//1 let baryon = function | M f -> begin match f with | L _ | N _ -> 0//1 | U n | D n -> if n > 0 then 1//1 else -1//1 end | G _ | O _ -> 0//1 let charges f = [ charge f; lepton f; baryon f] @ generation f type constant = | Unit | Half | Pi | Alpha_QED | Sin2thw | Sinthw | Costhw | E | G_weak | I_G_weak | Vev | Q_lepton | Q_up | Q_down | G_CC | G_CCQ of int*int | G_NC_neutrino | G_NC_lepton | G_NC_up | G_NC_down | G_TVA_ttA | G_TVA_bbA | G_VLR_ttZ | G_TVA_ttZ | G_TVA_bbZ | G_VLR_btW | G_VLR_tbW | G_TLR_btW | G_TRL_tbW | G_TLR_btWZ | G_TRL_tbWZ | G_TLR_btWA | G_TRL_tbWA | G_TVA_ttWW | G_TVA_bbWW | G_TVA_ttG | G_TVA_ttGG | G_VLR_qGuG | G_VLR_qBuB | G_VLR_qBuB_u | G_VLR_qBuB_d | G_VLR_qBuB_e | G_VL_qBuB_n | G_VL_qW | G_VL_qW_u | G_VL_qW_d | G_SL_DttR | G_SR_DttR | G_SL_DttL | G_SLR_DbtR | G_SL_DbtL | C_quqd1R_bt | C_quqd1R_tb | C_quqd1L_bt | C_quqd1L_tb | C_quqd8R_bt | C_quqd8R_tb | C_quqd8L_bt | C_quqd8L_tb | I_Q_W | I_G_ZWW | G_WWWW | G_ZZWW | G_AZWW | G_AAWW | I_G1_AWW | I_G1_ZWW | I_G1_plus_kappa_plus_G4_AWW | I_G1_plus_kappa_plus_G4_ZWW | I_G1_plus_kappa_minus_G4_AWW | I_G1_plus_kappa_minus_G4_ZWW | I_G1_minus_kappa_plus_G4_AWW | I_G1_minus_kappa_plus_G4_ZWW | I_G1_minus_kappa_minus_G4_AWW | I_G1_minus_kappa_minus_G4_ZWW | I_lambda_AWW | I_lambda_ZWW | G5_AWW | G5_ZWW | I_kappa5_AWW | I_kappa5_ZWW | I_lambda5_AWW | I_lambda5_ZWW | Alpha_WWWW0 | Alpha_ZZWW1 | Alpha_WWWW2 | Alpha_ZZWW0 | Alpha_ZZZZ | D_Alpha_ZZWW0_S | D_Alpha_ZZWW0_T | D_Alpha_ZZWW1_S | D_Alpha_ZZWW1_T | D_Alpha_ZZWW1_U | D_Alpha_WWWW0_S | D_Alpha_WWWW0_T | D_Alpha_WWWW0_U | D_Alpha_WWWW2_S | D_Alpha_WWWW2_T | D_Alpha_ZZZZ_S | D_Alpha_ZZZZ_T | Gs | I_Gs | G2 | Mass of flavor | Width of flavor | K_Matrix_Coeff of int | K_Matrix_Pole of int (* Two integer counters for the QCD and EW order of the couplings. *) type orders = int * int let orders = function | Q_lepton | Q_up | Q_down | G_NC_lepton | G_NC_neutrino | G_NC_up | G_NC_down | G_CC | G_CCQ _ | I_Q_W | I_G_ZWW | I_G1_AWW | I_G1_ZWW | I_G_weak | Half | Unit | I_G1_plus_kappa_plus_G4_AWW | I_G1_plus_kappa_plus_G4_ZWW | I_G1_minus_kappa_plus_G4_AWW | I_G1_minus_kappa_plus_G4_ZWW | I_G1_plus_kappa_minus_G4_AWW | I_G1_plus_kappa_minus_G4_ZWW | I_G1_minus_kappa_minus_G4_AWW | I_G1_minus_kappa_minus_G4_ZWW | I_kappa5_AWW | I_kappa5_ZWW | G5_AWW | G5_ZWW | I_lambda_AWW | I_lambda_ZWW | I_lambda5_AWW | I_lambda5_ZWW | G_TVA_ttA | G_TVA_bbA | G_VLR_ttZ | G_TVA_ttZ | G_TVA_bbZ | G_VLR_btW | G_VLR_tbW | G_TLR_btW | G_TRL_tbW | G_TLR_btWA | G_TRL_tbWA | G_TLR_btWZ | G_TRL_tbWZ | G_VLR_qBuB | G_VLR_qBuB_u | G_VLR_qBuB_d | G_VLR_qBuB_e | G_VL_qBuB_n | G_VL_qW | G_VL_qW_u | G_VL_qW_d | G_SL_DttR | G_SR_DttR | G_SL_DttL | G_SLR_DbtR | G_SL_DbtL | G_TVA_ttWW | G_TVA_bbWW -> (0,1) | G_WWWW | G_ZZWW | G_AZWW | G_AAWW | Alpha_WWWW0 | Alpha_WWWW2 | Alpha_ZZWW0 | Alpha_ZZWW1 | Alpha_ZZZZ | D_Alpha_WWWW0_S | D_Alpha_WWWW0_T | D_Alpha_WWWW0_U | D_Alpha_WWWW2_S | D_Alpha_WWWW2_T | D_Alpha_ZZWW0_S | D_Alpha_ZZWW0_T | D_Alpha_ZZWW1_S | D_Alpha_ZZWW1_T | D_Alpha_ZZWW1_U | D_Alpha_ZZZZ_S | D_Alpha_ZZZZ_T -> (0,2) | Gs | I_Gs | G_TVA_ttG | G_TVA_ttGG | G_VLR_qGuG | C_quqd1R_bt | C_quqd1R_tb | C_quqd1L_bt | C_quqd1L_tb | C_quqd8R_bt | C_quqd8R_tb | C_quqd8L_bt | C_quqd8L_tb -> (1,0) | G2 -> (2,0) (* These constants are not used, hence initialized to zero. *) | Sinthw | Sin2thw | Costhw | Pi | Alpha_QED | G_weak | K_Matrix_Coeff _ | K_Matrix_Pole _ | Mass _ | Width _ | Vev | E -> (0,0) (* \begin{dubious} The current abstract syntax for parameter dependencies is admittedly tedious. Later, there will be a parser for a convenient concrete syntax as a part of a concrete syntax for models. But as these examples show, it should include simple functions. \end{dubious} *) (* \begin{subequations} \begin{align} \alpha_{\text{QED}} &= \frac{1}{137.0359895} \\ \sin^2\theta_w &= 0.23124 \end{align} \end{subequations} *) let input_parameters = [ Alpha_QED, 1. /. 137.0359895; Sin2thw, 0.23124; Mass (G Z), 91.187; Mass (M (N 1)), 0.0; Mass (M (L 1)), 0.51099907e-3; Mass (M (N 2)), 0.0; Mass (M (L 2)), 0.105658389; Mass (M (N 3)), 0.0; Mass (M (L 3)), 1.77705; Mass (M (U 1)), 5.0e-3; Mass (M (D 1)), 3.0e-3; Mass (M (U 2)), 1.2; Mass (M (D 2)), 0.1; Mass (M (U 3)), 174.0; Mass (M (D 3)), 4.2 ] (* \begin{subequations} \begin{align} e &= \sqrt{4\pi\alpha} \\ \sin\theta_w &= \sqrt{\sin^2\theta_w} \\ \cos\theta_w &= \sqrt{1-\sin^2\theta_w} \\ g &= \frac{e}{\sin\theta_w} \\ m_W &= \cos\theta_w m_Z \\ v &= \frac{2m_W}{g} \\ g_{CC} = -\frac{g}{2\sqrt2} &= -\frac{e}{2\sqrt2\sin\theta_w} \\ Q_{\text{lepton}} = -q_{\text{lepton}}e &= e \\ Q_{\text{up}} = -q_{\text{up}}e &= -\frac{2}{3}e \\ Q_{\text{down}} = -q_{\text{down}}e &= \frac{1}{3}e \\ \ii q_We = \ii g_{\gamma WW} &= \ii e \\ \ii g_{ZWW} &= \ii g \cos\theta_w \\ \ii g_{WWW} &= \ii g \end{align} \end{subequations} *) let derived_parameters = [ Real E, Sqrt (Prod [Integer 4; Atom Pi; Atom Alpha_QED]); Real Sinthw, Sqrt (Atom Sin2thw); Real Costhw, Sqrt (Diff (Integer 1, Atom Sin2thw)); Real G_weak, Quot (Atom E, Atom Sinthw); Real (Mass (G Wp)), Prod [Atom Costhw; Atom (Mass (G Z))]; Real Vev, Quot (Prod [Integer 2; Atom (Mass (G Wp))], Atom G_weak); Real Q_lepton, Atom E; Real Q_up, Prod [Quot (Integer (-2), Integer 3); Atom E]; Real Q_down, Prod [Quot (Integer 1, Integer 3); Atom E]; Real G_CC, Neg (Quot (Atom G_weak, Prod [Integer 2; Sqrt (Integer 2)])); Complex I_Q_W, Prod [I; Atom E]; Complex I_G_weak, Prod [I; Atom G_weak]; Complex I_G_ZWW, Prod [I; Atom G_weak; Atom Costhw] ] (* \begin{equation} - \frac{g}{2\cos\theta_w} \end{equation} *) let g_over_2_costh = Quot (Neg (Atom G_weak), Prod [Integer 2; Atom Costhw]) (* \begin{subequations} \begin{align} - \frac{g}{2\cos\theta_w} g_V &= - \frac{g}{2\cos\theta_w} (T_3 - 2 q \sin^2\theta_w) \\ - \frac{g}{2\cos\theta_w} g_A &= - \frac{g}{2\cos\theta_w} T_3 \end{align} \end{subequations} *) let nc_coupling c t3 q = (Real_Array c, [Prod [g_over_2_costh; Diff (t3, Prod [Integer 2; q; Atom Sin2thw])]; Prod [g_over_2_costh; t3]]) let half = Quot (Integer 1, Integer 2) let derived_parameter_arrays = [ nc_coupling G_NC_neutrino half (Integer 0); nc_coupling G_NC_lepton (Neg half) (Integer (-1)); nc_coupling G_NC_up half (Quot (Integer 2, Integer 3)); nc_coupling G_NC_down (Neg half) (Quot (Integer (-1), Integer 3)) ] let parameters () = { input = input_parameters; derived = derived_parameters; derived_arrays = derived_parameter_arrays } module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) (* \begin{equation} \mathcal{L}_{\textrm{EM}} = - e \sum_i q_i \bar\psi_i\fmslash{A}\psi_i \end{equation} *) let mgm ((m1, g, m2), fbf, c) = ((M m1, G g, M m2), fbf, c) let mom ((m1, o, m2), fbf, c) = ((M m1, O o, M m2), fbf, c) let electromagnetic_currents n = List.map mgm [ ((L (-n), Ga, L n), FBF (1, Psibar, V, Psi), Q_lepton); ((U (-n), Ga, U n), FBF (1, Psibar, V, Psi), Q_up); ((D (-n), Ga, D n), FBF (1, Psibar, V, Psi), Q_down) ] let color_currents n = List.map mgm [ ((U (-n), Gl, U n), FBF ((-1), Psibar, V, Psi), Gs); ((D (-n), Gl, D n), FBF ((-1), Psibar, V, Psi), Gs) ] (* \begin{equation} \mathcal{L}_{\textrm{NC}} = - \frac{g}{2\cos\theta_W} \sum_i \bar\psi_i\fmslash{Z}(g_V^i-g_A^i\gamma_5)\psi_i \end{equation} *) let neutral_currents n = List.map mgm [ ((L (-n), Z, L n), FBF (1, Psibar, VA, Psi), G_NC_lepton); ((N (-n), Z, N n), FBF (1, Psibar, VA, Psi), G_NC_neutrino); ((U (-n), Z, U n), FBF (1, Psibar, VA, Psi), G_NC_up); ((D (-n), Z, D n), FBF (1, Psibar, VA, Psi), G_NC_down) ] (* \begin{equation} \mathcal{L}_{\textrm{CC}} = - \frac{g}{2\sqrt2} \sum_i \bar\psi_i (T^+\fmslash{W}^+ + T^-\fmslash{W}^-)(1-\gamma_5)\psi_i \end{equation} *) let charged_currents' n = List.map mgm [ ((L (-n), Wm, N n), FBF (1, Psibar, VL, Psi), G_CC); ((N (-n), Wp, L n), FBF (1, Psibar, VL, Psi), G_CC) ] let charged_currents'' n = List.map mgm [ ((D (-n), Wm, U n), FBF (1, Psibar, VL, Psi), G_CC); ((U (-n), Wp, D n), FBF (1, Psibar, VL, Psi), G_CC) ] let charged_currents_triv = ThoList.flatmap charged_currents' [1;2;3] @ ThoList.flatmap charged_currents'' [1;2;3] let charged_currents_ckm = let charged_currents_2 n1 n2 = List.map mgm [ ((D (-n1), Wm, U n2), FBF (1, Psibar, VL, Psi), G_CCQ (n2,n1)); ((U (-n1), Wp, D n2), FBF (1, Psibar, VL, Psi), G_CCQ (n1,n2)) ] in ThoList.flatmap charged_currents' [1;2;3] @ List.flatten (Product.list2 charged_currents_2 [1;2;3] [1;2;3]) (* \begin{equation} \mathcal{L}_{\textrm{TGC}} = - e \partial_\mu A_\nu W_+^\mu W_-^\nu + \ldots - e \cot\theta_w \partial_\mu Z_\nu W_+^\mu W_-^\nu + \ldots \end{equation} *) let tgc ((g1, g2, g3), t, c) = ((G g1, G g2, G g3), t, c) let standard_triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW); ((Gl, Gl, Gl), Gauge_Gauge_Gauge 1, I_Gs)] (* \begin{multline} \mathcal{L}_{\textrm{TGC}}(g_1,\kappa) = g_1 \mathcal{L}_T(V,W^+,W^-) \\ + \frac{\kappa+g_1}{2} \Bigl(\mathcal{L}_T(W^-,V,W^+) - \mathcal{L}_T(W^+,V,W^-)\Bigr)\\ + \frac{\kappa-g_1}{2} \Bigl(\mathcal{L}_L(W^-,V,W^+) - \mathcal{L}_T(W^+,V,W^-)\Bigr) \end{multline} *) (* \begin{dubious} The whole thing in the LEP2 workshop notation: \begin{multline} \ii\mathcal{L}_{\textrm{TGC},V} / g_{WWV} = \\ g_1^V V^\mu (W^-_{\mu\nu}W^{+,\nu}-W^+_{\mu\nu}W^{-,\nu}) + \kappa_V W^+_\mu W^-_\nu V^{\mu\nu} + \frac{\lambda_V}{m_W^2} V_{\mu\nu} W^-_{\rho\mu} W^{+,\hphantom{\nu}\rho}_{\hphantom{+,}\nu} \\ + \ii g_5^V \epsilon_{\mu\nu\rho\sigma} \left( (\partial^\rho W^{-,\mu}) W^{+,\nu} - W^{-,\mu}(\partial^\rho W^{+,\nu}) \right) V^\sigma \\ + \ii g_4^V W^-_\mu W^+_\nu (\partial^\mu V^\nu + \partial^\nu V^\mu) - \frac{\tilde\kappa_V}{2} W^-_\mu W^+_\nu \epsilon^{\mu\nu\rho\sigma} V_{\rho\sigma} - \frac{\tilde\lambda_V}{2m_W^2} W^-_{\rho\mu} W^{+,\mu}_{\hphantom{+,\mu}\nu} \epsilon^{\nu\rho\alpha\beta} V_{\alpha\beta} \end{multline} using the conventions of Itzykson and Zuber with $\epsilon^{0123} = +1$. \end{dubious} *) (* \begin{dubious} This is equivalent to the notation of Hagiwara et al.~\cite{HPZH87}, if we remember that they have opposite signs for~$g_{WWV}$: \begin{multline} \mathcal{L}_{WWV} / (-g_{WWV}) = \\ \ii g_1^V \left( W^\dagger_{\mu\nu} W^\mu - W^\dagger_\mu W^\mu_{\hphantom{\mu}\nu} \right) V^\nu + \ii \kappa_V W^\dagger_\mu W_\nu V^{\mu\nu} + \ii \frac{\lambda_V}{m_W^2} W^\dagger_{\lambda\mu} W^\mu_{\hphantom{\mu}\nu} V^{\nu\lambda} \\ - g_4^V W^\dagger_\mu W_\nu \left(\partial^\mu V^\nu + \partial^\nu V^\mu \right) + g_5^V \epsilon^{\mu\nu\lambda\sigma} \left( W^\dagger_\mu \stackrel{\leftrightarrow}{\partial_\lambda} W_\nu \right) V_\sigma\\ + \ii \tilde\kappa_V W^\dagger_\mu W_\nu \tilde{V}^{\mu\nu} + \ii\frac{\tilde\lambda_V}{m_W^2} W^\dagger_{\lambda\mu} W^\mu_{\hphantom{\mu}\nu} \tilde{V}^{\nu\lambda} \end{multline} Here $V^\mu$ stands for either the photon or the~$Z$ field, $W^\mu$ is the $W^-$ field, $W_{\mu\nu} = \partial_\mu W_\nu - \partial_\nu W_\mu$, $V_{\mu\nu} = \partial_\mu V_\nu - \partial_\nu V_\mu$, and $\tilde{V}_{\mu\nu} = \frac{1}{2} \epsilon_{\mu\nu\lambda\sigma} V^{\lambda\sigma}$. \end{dubious} *) let anomalous_triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Dim4_Vector_Vector_Vector_T (-1), I_G1_AWW); ((Z, Wm, Wp), Dim4_Vector_Vector_Vector_T (-1), I_G1_ZWW); ((Wm, Ga, Wp), Dim4_Vector_Vector_Vector_T 1, I_G1_plus_kappa_minus_G4_AWW); ((Wm, Z, Wp), Dim4_Vector_Vector_Vector_T 1, I_G1_plus_kappa_minus_G4_ZWW); ((Wp, Ga, Wm), Dim4_Vector_Vector_Vector_T (-1), I_G1_plus_kappa_plus_G4_AWW); ((Wp, Z, Wm), Dim4_Vector_Vector_Vector_T (-1), I_G1_plus_kappa_plus_G4_ZWW); ((Wm, Ga, Wp), Dim4_Vector_Vector_Vector_L (-1), I_G1_minus_kappa_plus_G4_AWW); ((Wm, Z, Wp), Dim4_Vector_Vector_Vector_L (-1), I_G1_minus_kappa_plus_G4_ZWW); ((Wp, Ga, Wm), Dim4_Vector_Vector_Vector_L 1, I_G1_minus_kappa_minus_G4_AWW); ((Wp, Z, Wm), Dim4_Vector_Vector_Vector_L 1, I_G1_minus_kappa_minus_G4_ZWW); ((Ga, Wm, Wp), Dim4_Vector_Vector_Vector_L5 (-1), I_kappa5_AWW); ((Z, Wm, Wp), Dim4_Vector_Vector_Vector_L5 (-1), I_kappa5_ZWW); ((Ga, Wm, Wp), Dim4_Vector_Vector_Vector_T5 (-1), G5_AWW); ((Z, Wm, Wp), Dim4_Vector_Vector_Vector_T5 (-1), G5_ZWW); ((Ga, Wp, Wm), Dim6_Gauge_Gauge_Gauge (-1), I_lambda_AWW); ((Z, Wp, Wm), Dim6_Gauge_Gauge_Gauge (-1), I_lambda_ZWW); ((Ga, Wp, Wm), Dim6_Gauge_Gauge_Gauge_5 (-1), I_lambda5_AWW); ((Z, Wp, Wm), Dim6_Gauge_Gauge_Gauge_5 (-1), I_lambda5_ZWW) ] let triple_gauge = if Flags.triple_anom then anomalous_triple_gauge else standard_triple_gauge (* \begin{equation} \mathcal{L}_{\textrm{QGC}} = - g^2 W_{+,\mu} W_{-,\nu} W_+^\mu W_-^\nu + \ldots \end{equation} *) (* Actually, quartic gauge couplings are a little bit more straightforward using auxiliary fields. Here we have to impose the antisymmetry manually: \begin{subequations} \begin{multline} (W^{+,\mu}_1 W^{-,\nu}_2 - W^{+,\nu}_1 W^{-,\mu}_2) (W^+_{3,\mu} W^-_{4,\nu} - W^+_{3,\nu} W^-_{4,\mu}) \\ = 2(W^+_1W^+_3)(W^-_2W^-_4) - 2(W^+_1W^-_4)(W^-_2W^+_3) \end{multline} also ($V$ can be $A$ or $Z$) \begin{multline} (W^{+,\mu}_1 V^\nu_2 - W^{+,\nu}_1 V^\mu_2) (W^-_{3,\mu} V_{4,\nu} - W^-_{3,\nu} V_{4,\mu}) \\ = 2(W^+_1W^-_3)(V_2V_4) - 2(W^+_1V_4)(V_2W^-_3) \end{multline} \end{subequations} *) (* \begin{subequations} \begin{multline} W^{+,\mu} W^{-,\nu} W^+_\mu W^-_\nu \end{multline} \end{subequations} *) let qgc ((g1, g2, g3, g4), t, c) = ((G g1, G g2, G g3, G g4), t, c) let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] let standard_quartic_gauge = List.map qgc [ (Wm, Wp, Wm, Wp), gauge4, G_WWWW; (Wm, Z, Wp, Z), minus_gauge4, G_ZZWW; (Wm, Z, Wp, Ga), minus_gauge4, G_AZWW; (Wm, Ga, Wp, Ga), minus_gauge4, G_AAWW; (Gl, Gl, Gl, Gl), gauge4, G2 ] (* \begin{subequations} \begin{align} \mathcal{L}_4 &= \alpha_4 \left( \frac{g^4}{2}\left( (W^+_\mu W^{-,\mu})^2 + W^+_\mu W^{+,\mu} W^-_\mu W^{-,\mu} \right)\right.\notag \\ &\qquad\qquad\qquad \left. + \frac{g^4}{\cos^2\theta_w} W^+_\mu Z^\mu W^-_\nu Z^\nu + \frac{g^4}{4\cos^4\theta_w} (Z_\mu Z^\mu)^2 \right) \\ \mathcal{L}_5 &= \alpha_5 \left( g^4 (W^+_\mu W^{-,\mu})^2 + \frac{g^4}{\cos^2\theta_w} W^+_\mu W^{-,\mu} Z_\nu Z^\nu + \frac{g^4}{4\cos^4\theta_w} (Z_\mu Z^\mu)^2 \right) \end{align} \end{subequations} or \begin{multline} \mathcal{L}_4 + \mathcal{L}_5 = (\alpha_4+2\alpha_5) g^4 \frac{1}{2} (W^+_\mu W^{-,\mu})^2 \\ + 2\alpha_4 g^4 \frac{1}{4} W^+_\mu W^{+,\mu} W^-_\mu W^{-,\mu} + \alpha_4 \frac{g^4}{\cos^2\theta_w} W^+_\mu Z^\mu W^-_\nu Z^\nu \\ + 2\alpha_5 \frac{g^4}{\cos^2\theta_w} \frac{1}{2} W^+_\mu W^{-,\mu} Z_\nu Z^\nu + (2\alpha_4 + 2\alpha_5) \frac{g^4}{\cos^4\theta_w} \frac{1}{8} (Z_\mu Z^\mu)^2 \end{multline} and therefore \begin{subequations} \begin{align} \alpha_{(WW)_0} &= (\alpha_4+2\alpha_5) g^4 \\ \alpha_{(WW)_2} &= 2\alpha_4 g^4 \\ \alpha_{(WZ)_0} &= 2\alpha_5 \frac{g^4}{\cos^2\theta_w} \\ \alpha_{(WZ)_1} &= \alpha_4 \frac{g^4}{\cos^2\theta_w} \\ \alpha_{ZZ} &= (2\alpha_4 + 2\alpha_5) \frac{g^4}{\cos^4\theta_w} \end{align} \end{subequations} *) let anomalous_quartic_gauge = if Flags.quartic_anom then List.map qgc [ ((Wm, Wm, Wp, Wp), Vector4 [(1, C_13_42); (1, C_14_23)], Alpha_WWWW0); ((Wm, Wm, Wp, Wp), Vector4 [1, C_12_34], Alpha_WWWW2); ((Wm, Wp, Z, Z), Vector4 [1, C_12_34], Alpha_ZZWW0); ((Wm, Wp, Z, Z), Vector4 [(1, C_13_42); (1, C_14_23)], Alpha_ZZWW1); ((Z, Z, Z, Z), Vector4 [(1, C_12_34); (1, C_13_42); (1, C_14_23)], Alpha_ZZZZ) ] else [] (* In any diagonal channel~$\chi$, the scattering amplitude~$a_\chi(s)$ is unitary iff\footnote{% Trivial proof: \begin{equation} -1 = \textrm{Im}\left(\frac{1}{a_\chi(s)}\right) = \frac{\textrm{Im}(a_\chi^*(s))}{ |a_\chi(s)|^2 } = - \frac{\textrm{Im}(a_\chi(s))}{ |a_\chi(s)|^2 } \end{equation} i.\,e.~$\textrm{Im}(a_\chi(s)) = |a_\chi(s)|^2$.} \begin{equation} \textrm{Im}\left(\frac{1}{a_\chi(s)}\right) = -1 \end{equation} For a real perturbative scattering amplitude~$r_\chi(s)$ this can be enforced easily--and arbitrarily--by \begin{equation} \frac{1}{a_\chi(s)} = \frac{1}{r_\chi(s)} - \mathrm{i} \end{equation} *) let k_matrix_quartic_gauge = if Flags.k_matrix then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_WWWW0_S); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_jr (0, [(1, C_14_23)]), D_Alpha_WWWW0_T); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_jr (0, [(1, C_13_42)]), D_Alpha_WWWW0_U); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_WWWW0_S); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_jr (0, [(1, C_14_23)]), D_Alpha_WWWW0_T); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_jr (0, [(1, C_13_42)]), D_Alpha_WWWW0_U); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_WWWW2_S); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_jr (0, [(1, C_13_42); (1, C_14_23)]), D_Alpha_WWWW2_T); ((Wm, Wp, Z, Z), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_ZZWW0_S); ((Wm, Wp, Z, Z), Vector4_K_Matrix_jr (0, [(1, C_13_42); (1, C_14_23)]), D_Alpha_ZZWW0_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_ZZWW1_S); ((Wm, Z, Wp, Z), Vector4_K_Matrix_jr (0, [(1, C_13_42)]), D_Alpha_ZZWW1_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_jr (0, [(1, C_14_23)]), D_Alpha_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_jr (1, [(1, C_12_34)]), D_Alpha_ZZWW1_S); ((Wp, Z, Z, Wm), Vector4_K_Matrix_jr (1, [(1, C_13_42)]), D_Alpha_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_jr (1, [(1, C_14_23)]), D_Alpha_ZZWW1_T); ((Z, Wp, Wm, Z), Vector4_K_Matrix_jr (2, [(1, C_12_34)]), D_Alpha_ZZWW1_S); ((Z, Wp, Wm, Z), Vector4_K_Matrix_jr (2, [(1, C_13_42)]), D_Alpha_ZZWW1_U); ((Z, Wp, Wm, Z), Vector4_K_Matrix_jr (2, [(1, C_14_23)]), D_Alpha_ZZWW1_T); ((Z, Z, Z, Z), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_jr (0, [(1, C_13_42); (1, C_14_23)]), D_Alpha_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_jr (3, [(1, C_14_23)]), D_Alpha_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_jr (3, [(1, C_13_42); (1, C_12_34)]), D_Alpha_ZZZZ_T)] else [] (*i Thorsten's original implementation of the K matrix, which we keep since it still might be usefull for the future. let k_matrix_quartic_gauge = if Flags.k_matrix then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 0, K_Matrix_Pole 0]), Alpha_WWWW0); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 2, K_Matrix_Pole 2]), Alpha_WWWW2); ((Wm, Wp, Z, Z), Vector4_K_Matrix_tho (0, [(K_Matrix_Coeff 0, K_Matrix_Pole 0); (K_Matrix_Coeff 2, K_Matrix_Pole 2)]), Alpha_ZZWW0); ((Wm, Z, Wp, Z), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 1, K_Matrix_Pole 1]), Alpha_ZZWW1); ((Z, Z, Z, Z), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 0, K_Matrix_Pole 0]), Alpha_ZZZZ) ] else [] i*) let quartic_gauge = standard_quartic_gauge @ anomalous_quartic_gauge @ k_matrix_quartic_gauge (* WK's couplings (apparently, he still intends to divide by $\Lambda^2_{\text{EWSB}}=16\pi^2v_{\mathrm{F}}^2$): \begin{subequations} \begin{align} \mathcal{L}^{\tau}_4 &= \left\lbrack (\partial_{\mu}H)(\partial^{\mu}H) + \frac{g^2v_{\mathrm{F}}^2}{4} V_{\mu} V^{\mu} \right\rbrack^2 \\ \mathcal{L}^{\tau}_5 &= \left\lbrack (\partial_{\mu}H)(\partial_{\nu}H) + \frac{g^2v_{\mathrm{F}}^2}{4} V_{\mu} V_{\nu} \right\rbrack^2 \end{align} \end{subequations} with \begin{equation} V_{\mu} V_{\nu} = \frac{1}{2} \left( W^+_{\mu} W^-_{\nu} + W^+_{\nu} W^-_{\mu} \right) + \frac{1}{2\cos^2\theta_{w}} Z_{\mu} Z_{\nu} \end{equation} (note the symmetrization!), i.\,e. \begin{subequations} \begin{align} \mathcal{L}_4 &= \alpha_4 \frac{g^4v_{\mathrm{F}}^4}{16} (V_{\mu} V_{\nu})^2 \\ \mathcal{L}_5 &= \alpha_5 \frac{g^4v_{\mathrm{F}}^4}{16} (V_{\mu} V^{\mu})^2 \end{align} \end{subequations} *) let goldstone_vertices = [ ((O Phi0, G Wm, G Wp), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phip, G Ga, G Wm), Scalar_Vector_Vector 1, I_Q_W); ((O Phip, G Z, G Wm), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phim, G Wp, G Ga), Scalar_Vector_Vector 1, I_Q_W); ((O Phim, G Wp, G Z), Scalar_Vector_Vector 1, I_G_ZWW) ] (* Anomalous trilinear interactions $f_i f_j V$ : \begin{equation} \Delta\mathcal{L}_{tt\gamma} = - e \frac{\upsilon}{\Lambda^2} \bar{t} i\sigma^{\mu\nu} k_\nu (d_V(k^2) + i d_A(k^2) \gamma_5) t A_\mu \end{equation} *) let anomalous_ttA = if Flags.top_anom then [ ((M (U (-3)), G Ga, M (U 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_ttA) ] else [] (* \begin{equation} \Delta\mathcal{L}_{bb\gamma} = - e \frac{\upsilon}{\Lambda^2} \bar{b} i\sigma^{\mu\nu} k_\nu (d_V(k^2) + i d_A(k^2) \gamma_5) b A_\mu \end{equation} *) let anomalous_bbA = if Flags.top_anom then [ ((M (D (-3)), G Ga, M (D 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_bbA) ] else [] (* \begin{equation} \Delta\mathcal{L}_{ttg} = - g_s \frac{\upsilon}{\Lambda^2} \bar{t}\lambda^a i\sigma^{\mu\nu}k_\nu (d_V(k^2)+id_A(k^2)\gamma_5)tG^a_\mu \end{equation} *) let anomalous_ttG = if Flags.top_anom then [ ((M (U (-3)), G Gl, M (U 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_ttG) ] else [] (* \begin{equation} \Delta\mathcal{L}_{ttZ} = - \frac{g}{2 c_W} \frac{\upsilon^2}{\Lambda^2}\left\lbrack \bar{t} \fmslash{Z} (X_L(k^2) P_L + X_R(k^2) P_R) t + \bar{t}\frac{i\sigma^{\mu\nu}k_\nu}{m_Z} (d_V(k^2)+id_A(k^2)\gamma_5)tZ_\mu\right\rbrack \end{equation} *) let anomalous_ttZ = if Flags.top_anom then [ ((M (U (-3)), G Z, M (U 3)), FBF (1, Psibar, VLRM, Psi), G_VLR_ttZ); ((M (U (-3)), G Z, M (U 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_ttZ) ] else [] (* \begin{equation} \Delta\mathcal{L}_{bbZ} = - \frac{g}{2 c_W} \frac{\upsilon^2}{\Lambda^2} \bar{b}\frac{i\sigma^{\mu\nu}k_\nu}{m_Z} (d_V(k^2)+id_A(k^2)\gamma_5)bZ_\mu \end{equation} *) let anomalous_bbZ = if Flags.top_anom then [ ((M (D (-3)), G Z, M (D 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_bbZ) ] else [] (* \begin{equation} \Delta\mathcal{L}_{tbW} = - \frac{g}{\sqrt{2}} \frac{\upsilon^2}{\Lambda^2}\left\lbrack \bar{b}\fmslash{W}^-(V_L(k^2) P_L+V_R(k^2) P_R) t + \bar{b}\frac{i\sigma^{\mu\nu}k_\nu}{m_W} (g_L(k^2)P_L+g_R(k^2)P_R)tW^-_\mu\right\rbrack + \textnormal{H.c.} \end{equation} *) let anomalous_tbW = if Flags.top_anom then [ ((M (D (-3)), G Wm, M (U 3)), FBF (1, Psibar, VLRM, Psi), G_VLR_btW); ((M (U (-3)), G Wp, M (D 3)), FBF (1, Psibar, VLRM, Psi), G_VLR_tbW); ((M (D (-3)), G Wm, M (U 3)), FBF (1, Psibar, TLRM, Psi), G_TLR_btW); ((M (U (-3)), G Wp, M (D 3)), FBF (1, Psibar, TRLM, Psi), G_TRL_tbW) ] else [] (* quartic fermion-gauge interactions $f_i f_j V_1 V_2$ emerging from gauge-invariant effective operators: \begin{equation} \Delta\mathcal{L}_{ttgg} = - \frac{g_s^2}{2} f_{abc} \frac{\upsilon}{\Lambda^2} \bar{t} \lambda^a \sigma^{\mu\nu} (d_V(k^2)+id_A(k^2)\gamma_5)t G^b_\mu G^c_\nu \end{equation} *) let anomalous_ttGG = if Flags.top_anom then [ ((M (U (-3)), O (Aux_top (2,1,0,true,TTGG)), M (U 3)), FBF (1, Psibar, TVA, Psi), G_TVA_ttGG); ((O (Aux_top (2,1,0,false,TTGG)), G Gl, G Gl), Aux_Gauge_Gauge 1, I_Gs) ] else [] (* \begin{equation} \Delta\mathcal{L}_{tbWA} = - i\sin\theta_w \frac{g^2}{2\sqrt{2}} \frac{\upsilon^2}{\Lambda^2}\left\lbrack \bar{b}\frac{\sigma^{\mu\nu}}{m_W} (g_L(k^2)P_L+g_R(k^2)P_R)t A_\mu W^-_\nu \right\rbrack + \textnormal{H.c.} \end{equation} *) let anomalous_tbWA = if Flags.top_anom then [ ((M (D (-3)), O (Aux_top (2,0,-1,true,TBWA)), M (U 3)), FBF (1, Psibar, TLR, Psi), G_TLR_btWA); ((O (Aux_top (2,0,1,false,TBWA)), G Ga, G Wm), Aux_Gauge_Gauge 1, I_G_weak); ((M (U (-3)), O (Aux_top (2,0,1,true,TBWA)), M (D 3)), FBF (1, Psibar, TRL, Psi), G_TRL_tbWA); ((O (Aux_top (2,0,-1,false,TBWA)), G Wp, G Ga), Aux_Gauge_Gauge 1, I_G_weak) ] else [] (* \begin{equation} \Delta\mathcal{L}_{tbWZ} = - i\cos\theta_w \frac{g^2}{2\sqrt{2}} \frac{\upsilon^2}{\Lambda^2}\left\lbrack \bar{b}\frac{\sigma^{\mu\nu}}{m_W} (g_L(k^2)P_L+g_R(k^2)P_R)t Z_\mu W^-_\nu \right\rbrack + \textnormal{H.c.} \end{equation} *) let anomalous_tbWZ = if Flags.top_anom then [ ((M (D (-3)), O (Aux_top (2,0,-1,true,TBWZ)), M (U 3)), FBF (1, Psibar, TLR, Psi), G_TLR_btWZ); ((O (Aux_top (2,0,1,false,TBWZ)), G Z, G Wm), Aux_Gauge_Gauge 1, I_G_weak); ((M (U (-3)), O (Aux_top (2,0,1,true,TBWZ)), M (D 3)), FBF (1, Psibar, TRL, Psi), G_TRL_tbWZ); ((O (Aux_top (2,0,-1,false,TBWZ)), G Wp, G Z), Aux_Gauge_Gauge 1, I_G_weak) ] else [] (* \begin{equation} \Delta\mathcal{L}_{ttWW} = - i \frac{g^2}{2} \frac{\upsilon^2}{\Lambda^2} \bar{t} \frac{\sigma^{\mu\nu}}{m_W} (d_V(k^2)+id_A(k^2)\gamma_5)t W^-_\mu W^+_\nu \end{equation} *) let anomalous_ttWW = if Flags.top_anom then [ ((M (U (-3)), O (Aux_top (2,0,0,true,TTWW)), M (U 3)), FBF (1, Psibar, TVA, Psi), G_TVA_ttWW); ((O (Aux_top (2,0,0,false,TTWW)), G Wm, G Wp), Aux_Gauge_Gauge 1, I_G_weak) ] else [] (* \begin{equation} \Delta\mathcal{L}_{bbWW} = - i \frac{g^2}{2} \frac{\upsilon^2}{\Lambda^2} \bar{b} \frac{\sigma^{\mu\nu}}{m_W} (d_V(k^2)+id_A(k^2)\gamma_5)b W^-_\mu W^+_\nu \end{equation} *) let anomalous_bbWW = if Flags.top_anom then [ ((M (D (-3)), O (Aux_top (2,0,0,true,BBWW)), M (D 3)), FBF (1, Psibar, TVA, Psi), G_TVA_bbWW); ((O (Aux_top (2,0,0,false,BBWW)), G Wm, G Wp), Aux_Gauge_Gauge 1, I_G_weak) ] else [] (* 4-fermion contact terms emerging from operator rewriting: *) let anomalous_top_qGuG_tt = [ ((M (U (-3)), O (Aux_top (1,1,0,true,QGUG)), M (U 3)), FBF (1, Psibar, VLR, Psi), G_VLR_qGuG) ] let anomalous_top_qGuG_ff n = List.map mom [ ((U (-n), Aux_top (1,1,0,false,QGUG), U n), FBF (1, Psibar, V, Psi), Unit); ((D (-n), Aux_top (1,1,0,false,QGUG), D n), FBF (1, Psibar, V, Psi), Unit) ] let anomalous_top_qGuG = if Flags.top_anom_4f then anomalous_top_qGuG_tt @ ThoList.flatmap anomalous_top_qGuG_ff [1;2;3] else [] let anomalous_top_qBuB_tt = [ ((M (U (-3)), O (Aux_top (1,0,0,true,QBUB)), M (U 3)), FBF (1, Psibar, VLR, Psi), G_VLR_qBuB) ] let anomalous_top_qBuB_ff n = List.map mom [ ((U (-n), Aux_top (1,0,0,false,QBUB), U n), FBF (1, Psibar, VLR, Psi), G_VLR_qBuB_u); ((D (-n), Aux_top (1,0,0,false,QBUB), D n), FBF (1, Psibar, VLR, Psi), G_VLR_qBuB_d); ((L (-n), Aux_top (1,0,0,false,QBUB), L n), FBF (1, Psibar, VLR, Psi), G_VLR_qBuB_e); ((N (-n), Aux_top (1,0,0,false,QBUB), N n), FBF (1, Psibar, VL, Psi), G_VL_qBuB_n) ] let anomalous_top_qBuB = if Flags.top_anom_4f then anomalous_top_qBuB_tt @ ThoList.flatmap anomalous_top_qBuB_ff [1;2;3] else [] let anomalous_top_qW_tq = [ ((M (U (-3)), O (Aux_top (1,0,0,true,QW)), M (U 3)), FBF (1, Psibar, VL, Psi), G_VL_qW); ((M (D (-3)), O (Aux_top (1,0,-1,true,QW)), M (U 3)), FBF (1, Psibar, VL, Psi), G_VL_qW); ((M (U (-3)), O (Aux_top (1,0,1,true,QW)), M (D 3)), FBF (1, Psibar, VL, Psi), G_VL_qW) ] let anomalous_top_qW_ff n = List.map mom [ ((U (-n), Aux_top (1,0,0,false,QW), U n), FBF (1, Psibar, VL, Psi), G_VL_qW_u); ((D (-n), Aux_top (1,0,0,false,QW), D n), FBF (1, Psibar, VL, Psi), G_VL_qW_d); ((N (-n), Aux_top (1,0,0,false,QW), N n), FBF (1, Psibar, VL, Psi), G_VL_qW_u); ((L (-n), Aux_top (1,0,0,false,QW), L n), FBF (1, Psibar, VL, Psi), G_VL_qW_d); ((D (-n), Aux_top (1,0,-1,false,QW), U n), FBF (1, Psibar, VL, Psi), Half); ((U (-n), Aux_top (1,0,1,false,QW), D n), FBF (1, Psibar, VL, Psi), Half); ((L (-n), Aux_top (1,0,-1,false,QW), N n), FBF (1, Psibar, VL, Psi), Half); ((N (-n), Aux_top (1,0,1,false,QW), L n), FBF (1, Psibar, VL, Psi), Half) ] let anomalous_top_qW = if Flags.top_anom_4f then anomalous_top_qW_tq @ ThoList.flatmap anomalous_top_qW_ff [1;2;3] else [] let anomalous_top_DuDd = if Flags.top_anom_4f then [ ((M (U (-3)), O (Aux_top (0,0,0,true,DR)), M (U 3)), FBF (1, Psibar, SR, Psi), Half); ((M (U (-3)), O (Aux_top (0,0,0,false,DR)), M (U 3)), FBF (1, Psibar, SL, Psi), G_SL_DttR); ((M (D (-3)), O (Aux_top (0,0,0,false,DR)), M (D 3)), FBF (1, Psibar, SR, Psi), G_SR_DttR); ((M (U (-3)), O (Aux_top (0,0,0,true,DL)), M (U 3)), FBF (1, Psibar, SL, Psi), Half); ((M (D (-3)), O (Aux_top (0,0,0,false,DL)), M (D 3)), FBF (1, Psibar, SL, Psi), G_SL_DttL); ((M (D (-3)), O (Aux_top (0,0,-1,true,DR)), M (U 3)), FBF (1, Psibar, SR, Psi), Half); ((M (U (-3)), O (Aux_top (0,0,1,false,DR)), M (D 3)), FBF (1, Psibar, SLR, Psi), G_SLR_DbtR); ((M (D (-3)), O (Aux_top (0,0,-1,true,DL)), M (U 3)), FBF (1, Psibar, SL, Psi), Half); ((M (U (-3)), O (Aux_top (0,0,1,false,DL)), M (D 3)), FBF (1, Psibar, SL, Psi), G_SL_DbtL) ] else [] let anomalous_top_quqd1_tq = [ ((M (D (-3)), O (Aux_top (0,0,-1,true,QUQD1R)), M (U 3)), FBF (1, Psibar, SR, Psi), C_quqd1R_bt); ((M (U (-3)), O (Aux_top (0,0, 1,true,QUQD1R)), M (D 3)), FBF (1, Psibar, SL, Psi), C_quqd1R_tb); ((M (D (-3)), O (Aux_top (0,0,-1,true,QUQD1L)), M (U 3)), FBF (1, Psibar, SL, Psi), C_quqd1L_bt); ((M (U (-3)), O (Aux_top (0,0, 1,true,QUQD1L)), M (D 3)), FBF (1, Psibar, SR, Psi), C_quqd1L_tb) ] let anomalous_top_quqd1_ff n = List.map mom [ ((U (-n), Aux_top (0,0, 1,false,QUQD1R), D n), FBF (1, Psibar, SR, Psi), Half); ((D (-n), Aux_top (0,0,-1,false,QUQD1R), U n), FBF (1, Psibar, SL, Psi), Half); ((U (-n), Aux_top (0,0, 1,false,QUQD1L), D n), FBF (1, Psibar, SL, Psi), Half); ((D (-n), Aux_top (0,0,-1,false,QUQD1L), U n), FBF (1, Psibar, SR, Psi), Half) ] let anomalous_top_quqd1 = if Flags.top_anom_4f then anomalous_top_quqd1_tq @ ThoList.flatmap anomalous_top_quqd1_ff [1;2;3] else [] let anomalous_top_quqd8_tq = [ ((M (D (-3)), O (Aux_top (0,1,-1,true,QUQD8R)), M (U 3)), FBF (1, Psibar, SR, Psi), C_quqd8R_bt); ((M (U (-3)), O (Aux_top (0,1, 1,true,QUQD8R)), M (D 3)), FBF (1, Psibar, SL, Psi), C_quqd8R_tb); ((M (D (-3)), O (Aux_top (0,1,-1,true,QUQD8L)), M (U 3)), FBF (1, Psibar, SL, Psi), C_quqd8L_bt); ((M (U (-3)), O (Aux_top (0,1, 1,true,QUQD8L)), M (D 3)), FBF (1, Psibar, SR, Psi), C_quqd8L_tb) ] let anomalous_top_quqd8_ff n = List.map mom [ ((U (-n), Aux_top (0,1, 1,false,QUQD8R), D n), FBF (1, Psibar, SR, Psi), Half); ((D (-n), Aux_top (0,1,-1,false,QUQD8R), U n), FBF (1, Psibar, SL, Psi), Half); ((U (-n), Aux_top (0,1, 1,false,QUQD8L), D n), FBF (1, Psibar, SL, Psi), Half); ((D (-n), Aux_top (0,1,-1,false,QUQD8L), U n), FBF (1, Psibar, SR, Psi), Half) ] let anomalous_top_quqd8 = if Flags.top_anom_4f then anomalous_top_quqd8_tq @ ThoList.flatmap anomalous_top_quqd8_ff [1;2;3] else [] let vertices3 = (ThoList.flatmap electromagnetic_currents [1;2;3] @ ThoList.flatmap color_currents [1;2;3] @ ThoList.flatmap neutral_currents [1;2;3] @ (if Flags.ckm_present then charged_currents_ckm else charged_currents_triv) @ triple_gauge @ goldstone_vertices @ anomalous_ttA @ anomalous_bbA @ anomalous_ttZ @ anomalous_bbZ @ anomalous_tbW @ anomalous_tbWA @ anomalous_tbWZ @ anomalous_ttWW @ anomalous_bbWW @ anomalous_ttG @ anomalous_ttGG @ anomalous_top_qGuG @ anomalous_top_qBuB @ anomalous_top_qW @ anomalous_top_DuDd @ anomalous_top_quqd1 @ anomalous_top_quqd8) let vertices4 = quartic_gauge let vertices () = (vertices3, vertices4, []) (* For efficiency, make sure that [F.of_vertices vertices] is evaluated only once. *) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 let flavor_of_string = function | "e-" -> M (L 1) | "e+" -> M (L (-1)) | "mu-" -> M (L 2) | "mu+" -> M (L (-2)) | "tau-" -> M (L 3) | "tau+" -> M (L (-3)) | "nue" -> M (N 1) | "nuebar" -> M (N (-1)) | "numu" -> M (N 2) | "numubar" -> M (N (-2)) | "nutau" -> M (N 3) | "nutaubar" -> M (N (-3)) | "u" -> M (U 1) | "ubar" -> M (U (-1)) | "c" -> M (U 2) | "cbar" -> M (U (-2)) | "t" -> M (U 3) | "tbar" -> M (U (-3)) | "d" -> M (D 1) | "dbar" -> M (D (-1)) | "s" -> M (D 2) | "sbar" -> M (D (-2)) | "b" -> M (D 3) | "bbar" -> M (D (-3)) | "g" | "gl" -> G Gl | "A" -> G Ga | "Z" | "Z0" -> G Z | "W+" -> G Wp | "W-" -> G Wm | "Aux_t_ttGG0" -> O (Aux_top (2,1, 0,true,TTGG)) | "Aux_ttGG0" -> O (Aux_top (2,1, 0,false,TTGG)) | "Aux_t_tbWA+" -> O (Aux_top (2,0, 1,true,TBWA)) | "Aux_tbWA+" -> O (Aux_top (2,0, 1,false,TBWA)) | "Aux_t_tbWA-" -> O (Aux_top (2,0,-1,true,TBWA)) | "Aux_tbWA-" -> O (Aux_top (2,0,-1,false,TBWA)) | "Aux_t_tbWZ+" -> O (Aux_top (2,0, 1,true,TBWZ)) | "Aux_tbWZ+" -> O (Aux_top (2,0, 1,false,TBWZ)) | "Aux_t_tbWZ-" -> O (Aux_top (2,0,-1,true,TBWZ)) | "Aux_tbWZ-" -> O (Aux_top (2,0,-1,false,TBWZ)) | "Aux_t_ttWW0" -> O (Aux_top (2,0, 0,true,TTWW)) | "Aux_ttWW0" -> O (Aux_top (2,0, 0,false,TTWW)) | "Aux_t_bbWW0" -> O (Aux_top (2,0, 0,true,BBWW)) | "Aux_bbWW0" -> O (Aux_top (2,0, 0,false,BBWW)) | "Aux_t_qGuG0" -> O (Aux_top (1,1, 0,true,QGUG)) | "Aux_qGuG0" -> O (Aux_top (1,1, 0,false,QGUG)) | "Aux_t_qBuB0" -> O (Aux_top (1,0, 0,true,QBUB)) | "Aux_qBuB0" -> O (Aux_top (1,0, 0,false,QBUB)) | "Aux_t_qW0" -> O (Aux_top (1,0, 0,true,QW)) | "Aux_qW0" -> O (Aux_top (1,0, 0,false,QW)) | "Aux_t_qW+" -> O (Aux_top (1,0, 1,true,QW)) | "Aux_qW+" -> O (Aux_top (1,0, 1,false,QW)) | "Aux_t_qW-" -> O (Aux_top (1,0,-1,true,QW)) | "Aux_qW-" -> O (Aux_top (1,0,-1,false,QW)) | "Aux_t_dL0" -> O (Aux_top (0,0, 0,true,DL)) | "Aux_dL0" -> O (Aux_top (0,0, 0,false,DL)) | "Aux_t_dL+" -> O (Aux_top (0,0, 1,true,DL)) | "Aux_dL+" -> O (Aux_top (0,0, 1,false,DL)) | "Aux_t_dL-" -> O (Aux_top (0,0,-1,true,DL)) | "Aux_dL-" -> O (Aux_top (0,0,-1,false,DL)) | "Aux_t_dR0" -> O (Aux_top (0,0, 0,true,DR)) | "Aux_dR0" -> O (Aux_top (0,0, 0,false,DR)) | "Aux_t_dR+" -> O (Aux_top (0,0, 1,true,DR)) | "Aux_dR+" -> O (Aux_top (0,0, 1,false,DR)) | "Aux_t_dR-" -> O (Aux_top (0,0,-1,true,DR)) | "Aux_dR-" -> O (Aux_top (0,0,-1,false,DR)) | "Aux_t_quqd1L+" -> O (Aux_top (0,0, 1,true,QUQD1L)) | "Aux_quqd1L+" -> O (Aux_top (0,0, 1,false,QUQD1L)) | "Aux_t_quqd1L-" -> O (Aux_top (0,0,-1,true,QUQD1L)) | "Aux_quqd1L-" -> O (Aux_top (0,0,-1,false,QUQD1L)) | "Aux_t_quqd1R+" -> O (Aux_top (0,0, 1,true,QUQD1R)) | "Aux_quqd1R+" -> O (Aux_top (0,0, 1,false,QUQD1R)) | "Aux_t_quqd1R-" -> O (Aux_top (0,0,-1,true,QUQD1R)) | "Aux_quqd1R-" -> O (Aux_top (0,0,-1,false,QUQD1R)) | "Aux_t_quqd8L+" -> O (Aux_top (0,1, 1,true,QUQD8L)) | "Aux_quqd8L+" -> O (Aux_top (0,1, 1,false,QUQD8L)) | "Aux_t_quqd8L-" -> O (Aux_top (0,1,-1,true,QUQD8L)) | "Aux_quqd8L-" -> O (Aux_top (0,1,-1,false,QUQD8L)) | "Aux_t_quqd8R+" -> O (Aux_top (0,1, 1,true,QUQD8R)) | "Aux_quqd8R+" -> O (Aux_top (0,1, 1,false,QUQD8R)) | "Aux_t_quqd8R-" -> O (Aux_top (0,1,-1,true,QUQD8R)) | "Aux_quqd8R-" -> O (Aux_top (0,1,-1,false,QUQD8R)) | _ -> invalid_arg "Modellib.NoH.flavor_of_string" let flavor_to_string = function | M f -> begin match f with | L 1 -> "e-" | L (-1) -> "e+" | L 2 -> "mu-" | L (-2) -> "mu+" | L 3 -> "tau-" | L (-3) -> "tau+" | L _ -> invalid_arg "Modellib.NoH.flavor_to_string: invalid lepton" | N 1 -> "nue" | N (-1) -> "nuebar" | N 2 -> "numu" | N (-2) -> "numubar" | N 3 -> "nutau" | N (-3) -> "nutaubar" | N _ -> invalid_arg "Modellib.NoH.flavor_to_string: invalid neutrino" | U 1 -> "u" | U (-1) -> "ubar" | U 2 -> "c" | U (-2) -> "cbar" | U 3 -> "t" | U (-3) -> "tbar" | U _ -> invalid_arg "Modellib.NoH.flavor_to_string: invalid up type quark" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | D _ -> invalid_arg "Modellib.NoH.flavor_to_string: invalid down type quark" end | G f -> begin match f with | Gl -> "gl" | Ga -> "A" | Z -> "Z" | Wp -> "W+" | Wm -> "W-" end | O f -> begin match f with | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | Aux_top (_,_,ch,n,v) -> "Aux_" ^ (if n then "t_" else "") ^ ( begin match v with | TTGG -> "ttGG" | TBWA -> "tbWA" | TBWZ -> "tbWZ" | TTWW -> "ttWW" | BBWW -> "bbWW" | QGUG -> "qGuG" | QBUB -> "qBuB" | QW -> "qW" | DL -> "dL" | DR -> "dR" | QUQD1L -> "quqd1L" | QUQD1R -> "quqd1R" | QUQD8L -> "quqd8L" | QUQD8R -> "quqd8R" end ) ^ ( if ch > 0 then "+" else if ch < 0 then "-" else "0" ) end let flavor_to_TeX = function | M f -> begin match f with | L 1 -> "e^-" | L (-1) -> "e^+" | L 2 -> "\\mu^-" | L (-2) -> "\\mu^+" | L 3 -> "\\tau^-" | L (-3) -> "\\tau^+" | L _ -> invalid_arg "Modellib.NoH.flavor_to_TeX: invalid lepton" | N 1 -> "\\nu_e" | N (-1) -> "\\bar{\\nu}_e" | N 2 -> "\\nu_\\mu" | N (-2) -> "\\bar{\\nu}_\\mu" | N 3 -> "\\nu_\\tau" | N (-3) -> "\\bar{\\nu}_\\tau" | N _ -> invalid_arg "Modellib.NoH.flavor_to_TeX: invalid neutrino" | U 1 -> "u" | U (-1) -> "\\bar{u}" | U 2 -> "c" | U (-2) -> "\\bar{c}" | U 3 -> "t" | U (-3) -> "\\bar{t}" | U _ -> invalid_arg "Modellib.NoH.flavor_to_TeX: invalid up type quark" | D 1 -> "d" | D (-1) -> "\\bar{d}" | D 2 -> "s" | D (-2) -> "\\bar{s}" | D 3 -> "b" | D (-3) -> "\\bar{b}" | D _ -> invalid_arg "Modellib.NoH.flavor_to_TeX: invalid down type quark" end | G f -> begin match f with | Gl -> "g" | Ga -> "\\gamma" | Z -> "Z" | Wp -> "W^+" | Wm -> "W^-" end | O f -> begin match f with | Phip -> "\\phi^+" | Phim -> "\\phi^-" | Phi0 -> "\\phi^0" | Aux_top (_,_,ch,n,v) -> "\\textnormal{Aux_" ^ (if n then "t_" else "") ^ ( begin match v with | TTGG -> "ttGG" | TBWA -> "tbWA" | TBWZ -> "tbWZ" | TTWW -> "ttWW" | BBWW -> "bbWW" | QGUG -> "qGuG" | QBUB -> "qBuB" | QW -> "qW" | DL -> "dL" | DR -> "dR" | QUQD1L -> "quqd1L" | QUQD1R -> "quqd1R" | QUQD8L -> "quqd8L" | QUQD8R -> "quqd8R" end ) ^ ( if ch > 0 then "^+" else if ch < 0 then "^-" else "^0" ) ^ "}" end let flavor_symbol = function | M f -> begin match f with | L n when n > 0 -> "l" ^ string_of_int n | L n -> "l" ^ string_of_int (abs n) ^ "b" | N n when n > 0 -> "n" ^ string_of_int n | N n -> "n" ^ string_of_int (abs n) ^ "b" | U n when n > 0 -> "u" ^ string_of_int n | U n -> "u" ^ string_of_int (abs n) ^ "b" | D n when n > 0 -> "d" ^ string_of_int n | D n -> "d" ^ string_of_int (abs n) ^ "b" end | G f -> begin match f with | Gl -> "gl" | Ga -> "a" | Z -> "z" | Wp -> "wp" | Wm -> "wm" end | O f -> begin match f with | Phip -> "pp" | Phim -> "pm" | Phi0 -> "p0" | Aux_top (_,_,ch,n,v) -> "aux_" ^ (if n then "t_" else "") ^ ( begin match v with | TTGG -> "ttgg" | TBWA -> "tbwa" | TBWZ -> "tbwz" | TTWW -> "ttww" | BBWW -> "bbww" | QGUG -> "qgug" | QBUB -> "qbub" | QW -> "qw" | DL -> "dl" | DR -> "dr" | QUQD1L -> "quqd1l" | QUQD1R -> "quqd1r" | QUQD8L -> "quqd8l" | QUQD8R -> "quqd8r" end ) ^ "_" ^ ( if ch > 0 then "p" else if ch < 0 then "m" else "0" ) end let pdg = function | M f -> begin match f with | L n when n > 0 -> 9 + 2*n | L n -> - 9 + 2*n | N n when n > 0 -> 10 + 2*n | N n -> - 10 + 2*n | U n when n > 0 -> 2*n | U n -> 2*n | D n when n > 0 -> - 1 + 2*n | D n -> 1 + 2*n end | G f -> begin match f with | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) end | O f -> begin match f with | Phip | Phim -> 27 | Phi0 -> 26 | Aux_top (_,_,ch,t,f) -> let n = begin match f with | QW -> 0 | QUQD1R -> 1 | QUQD1L -> 2 | QUQD8R -> 3 | QUQD8L -> 4 | _ -> 5 end in (602 + 3*n - ch) * ( if t then (1) else (-1) ) end let mass_symbol f = "mass(" ^ string_of_int (abs (pdg f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg f)) ^ ")" let constant_symbol = function | Unit -> "unit" | Half -> "half" | Pi -> "PI" | Alpha_QED -> "alpha" | E -> "e" | G_weak -> "g" | Vev -> "vev" | I_G_weak -> "ig" | Sin2thw -> "sin2thw" | Sinthw -> "sinthw" | Costhw -> "costhw" | Q_lepton -> "qlep" | Q_up -> "qup" | Q_down -> "qdwn" | G_NC_lepton -> "gnclep" | G_NC_neutrino -> "gncneu" | G_NC_up -> "gncup" | G_NC_down -> "gncdwn" | G_TVA_ttA -> "gtva_tta" | G_TVA_bbA -> "gtva_bba" | G_VLR_ttZ -> "gvlr_ttz" | G_TVA_ttZ -> "gtva_ttz" | G_TVA_bbZ -> "gtva_bbz" | G_VLR_btW -> "gvlr_btw" | G_VLR_tbW -> "gvlr_tbw" | G_TLR_btW -> "gtlr_btw" | G_TRL_tbW -> "gtrl_tbw" | G_TLR_btWA -> "gtlr_btwa" | G_TRL_tbWA -> "gtrl_tbwa" | G_TLR_btWZ -> "gtlr_btwz" | G_TRL_tbWZ -> "gtrl_tbwz" | G_TVA_ttWW -> "gtva_ttww" | G_TVA_bbWW -> "gtva_bbww" | G_TVA_ttG -> "gtva_ttg" | G_TVA_ttGG -> "gtva_ttgg" | G_VLR_qGuG -> "gvlr_qgug" | G_VLR_qBuB -> "gvlr_qbub" | G_VLR_qBuB_u -> "gvlr_qbub_u" | G_VLR_qBuB_d -> "gvlr_qbub_d" | G_VLR_qBuB_e -> "gvlr_qbub_e" | G_VL_qBuB_n -> "gvl_qbub_n" | G_VL_qW -> "gvl_qw" | G_VL_qW_u -> "gvl_qw_u" | G_VL_qW_d -> "gvl_qw_d" | G_SL_DttR -> "gsl_dttr" | G_SR_DttR -> "gsr_dttr" | G_SL_DttL -> "gsl_dttl" | G_SLR_DbtR -> "gslr_dbtr" | G_SL_DbtL -> "gsl_dbtl" | C_quqd1R_bt -> "c_quqd1_1" | C_quqd1R_tb -> "conjg(c_quqd1_1)" | C_quqd1L_bt -> "conjg(c_quqd1_2)" | C_quqd1L_tb -> "c_quqd1_2" | C_quqd8R_bt -> "c_quqd8_1" | C_quqd8R_tb -> "conjg(c_quqd8_1)" | C_quqd8L_bt -> "conjg(c_quqd8_2)" | C_quqd8L_tb -> "c_quqd8_2" | G_CC -> "gcc" | G_CCQ (n1,n2) -> "gccq" ^ string_of_int n1 ^ string_of_int n2 | I_Q_W -> "iqw" | I_G_ZWW -> "igzww" | G_WWWW -> "gw4" | G_ZZWW -> "gzzww" | G_AZWW -> "gazww" | G_AAWW -> "gaaww" | I_G1_AWW -> "ig1a" | I_G1_ZWW -> "ig1z" | I_G1_plus_kappa_plus_G4_AWW -> "ig1pkpg4a" | I_G1_plus_kappa_plus_G4_ZWW -> "ig1pkpg4z" | I_G1_plus_kappa_minus_G4_AWW -> "ig1pkmg4a" | I_G1_plus_kappa_minus_G4_ZWW -> "ig1pkmg4z" | I_G1_minus_kappa_plus_G4_AWW -> "ig1mkpg4a" | I_G1_minus_kappa_plus_G4_ZWW -> "ig1mkpg4z" | I_G1_minus_kappa_minus_G4_AWW -> "ig1mkmg4a" | I_G1_minus_kappa_minus_G4_ZWW -> "ig1mkmg4z" | I_lambda_AWW -> "ila" | I_lambda_ZWW -> "ilz" | G5_AWW -> "rg5a" | G5_ZWW -> "rg5z" | I_kappa5_AWW -> "ik5a" | I_kappa5_ZWW -> "ik5z" | I_lambda5_AWW -> "il5a" | I_lambda5_ZWW -> "il5z" | Alpha_WWWW0 -> "alww0" | Alpha_WWWW2 -> "alww2" | Alpha_ZZWW0 -> "alzw0" | Alpha_ZZWW1 -> "alzw1" | Alpha_ZZZZ -> "alzz" | D_Alpha_ZZWW0_S -> "dalzz0_s(gkm,mkm," | D_Alpha_ZZWW0_T -> "dalzz0_t(gkm,mkm," | D_Alpha_ZZWW1_S -> "dalzz1_s(gkm,mkm," | D_Alpha_ZZWW1_T -> "dalzz1_t(gkm,mkm," | D_Alpha_ZZWW1_U -> "dalzz1_u(gkm,mkm," | D_Alpha_WWWW0_S -> "dalww0_s(gkm,mkm," | D_Alpha_WWWW0_T -> "dalww0_t(gkm,mkm," | D_Alpha_WWWW0_U -> "dalww0_u(gkm,mkm," | D_Alpha_WWWW2_S -> "dalww2_s(gkm,mkm," | D_Alpha_WWWW2_T -> "dalww2_t(gkm,mkm," | D_Alpha_ZZZZ_S -> "dalz4_s(gkm,mkm," | D_Alpha_ZZZZ_T -> "dalz4_t(gkm,mkm," | Gs -> "gs" | I_Gs -> "igs" | G2 -> "gs**2" | Mass f -> "mass" ^ flavor_symbol f | Width f -> "width" ^ flavor_symbol f | K_Matrix_Coeff i -> "kc" ^ string_of_int i | K_Matrix_Pole i -> "kp" ^ string_of_int i end (* \thocwmodulesection{Minimal Higgsless Model including additional Resonances} *) module AltH (Flags : NoH_flags) = struct open Coupling let default_width = ref Timelike let use_fudged_width = ref false let options = Options.create [ "constant_width", Arg.Unit (fun () -> default_width := Constant), "use constant width (also in t-channel)"; "fudged_width", Arg.Set use_fudged_width, "use fudge factor for charge particle width"; "custom_width", Arg.String (fun f -> default_width := Custom f), "use custom width"; "cancel_widths", Arg.Unit (fun () -> default_width := Vanishing), "use vanishing width"; "cms_width", Arg.Unit (fun () -> default_width := Complex_Mass), "use complex mass scheme"] type f_aux_top = TTGG | TBWA | TBWZ | TTWW | BBWW | (*i top auxiliary field "flavors" *) QGUG | QBUB | QW | DL | DR type matter_field = L of int | N of int | U of int | D of int type gauge_boson = Ga | Wp | Wm | Z | Gl type other = Phip | Phim | Phi0 | Rsigma | Rphin | Rphip | Rphim | Rphipp | Rphimm | Rf | Rtn | Rtp | Rtm | Rtpp | Rtmm | Aux_top of int*int*int*bool*f_aux_top (*i lorentz*color*charge*top-side*flavor *) type flavor = M of matter_field | G of gauge_boson | O of other let matter_field f = M f let gauge_boson f = G f let other f = O f type field = | Matter of matter_field | Gauge of gauge_boson | Other of other let field = function | M f -> Matter f | G f -> Gauge f | O f -> Other f type gauge = unit let gauge_symbol () = failwith "Modellib_NoH.AltH.gauge_symbol: internal error" let family n = List.map matter_field [ L n; N n; U n; D n ] let rec aux_top_flavors (f,l,co,ch) = List.append ( List.map other [ Aux_top(l,co,ch/2,true,f); Aux_top(l,co,ch/2,false,f) ] ) ( if ch > 1 then List.append ( List.map other [ Aux_top(l,co,-ch/2,true,f); Aux_top(l,co,-ch/2,false,f) ] ) ( aux_top_flavors (f,l,co,(ch-2)) ) else [] ) let external_flavors () = [ "1st Generation", ThoList.flatmap family [1; -1]; "2nd Generation", ThoList.flatmap family [2; -2]; "3rd Generation", ThoList.flatmap family [3; -3]; "Gauge Bosons", List.map gauge_boson [Ga; Z; Wp; Wm; Gl]; "Scalar Resonances", List.map other [Rsigma; Rphin; Rphip; Rphim; Rphipp; Rphimm]; "Tensor Resonances", List.map other [Rf; Rtn; Rtp; Rtm; Rtpp; Rtmm]; "Goldstone Bosons", List.map other [Phip; Phim; Phi0] ] let flavors () = List.append ( ThoList.flatmap snd (external_flavors ()) ) ( ThoList.flatmap aux_top_flavors [ (TTGG,2,1,1); (TBWA,2,0,2); (TBWZ,2,0,2); (TTWW,2,0,1); (BBWW,2,0,1); (QGUG,1,1,1); (QBUB,1,0,1); (QW,1,0,3); (DL,0,0,3); (DR,0,0,3) ] ) let spinor n = if n >= 0 then Spinor else ConjSpinor let lorentz_aux = function | 2 -> Tensor_1 | 1 -> Vector | 0 -> Scalar | _ -> invalid_arg ("SM.lorentz_aux: wrong value") let lorentz = function | M f -> begin match f with | L n -> spinor n | N n -> spinor n | U n -> spinor n | D n -> spinor n end | G f -> begin match f with | Ga | Gl -> Vector | Wp | Wm | Z -> Massive_Vector end | O f -> begin match f with | Aux_top (l,_,_,_,_) -> lorentz_aux l | Rf | Rtn | Rtp | Rtm | Rtpp | Rtmm -> Tensor_2 | _ -> Scalar end let color = function | M (U n) -> Color.SUN (if n > 0 then 3 else -3) | M (D n) -> Color.SUN (if n > 0 then 3 else -3) | G Gl -> Color.AdjSUN 3 | O (Aux_top (_,co,_,_,_)) -> if co == 0 then Color.Singlet else Color.AdjSUN 3 | _ -> Color.Singlet let nc () = 3 let prop_spinor n = if n >= 0 then Prop_Spinor else Prop_ConjSpinor let prop_aux = function | 2 -> Aux_Tensor_1 | 1 -> Aux_Vector | 0 -> Aux_Scalar | _ -> invalid_arg ("SM.prop_aux: wrong value") let propagator = function | M f -> begin match f with | L n -> prop_spinor n | N n -> prop_spinor n | U n -> prop_spinor n | D n -> prop_spinor n end | G f -> begin match f with | Ga | Gl -> Prop_Feynman | Wp | Wm | Z -> Prop_Unitarity end | O f -> begin match f with | Phip | Phim | Phi0 -> Only_Insertion | Rsigma -> Prop_Scalar | Rphin | Rphip | Rphim | Rphipp | Rphimm -> Prop_Scalar | Rf -> Prop_Tensor_2 | Rtn | Rtp | Rtm | Rtpp | Rtmm -> Prop_Tensor_2 | Aux_top (l,_,_,_,_) -> prop_aux l end (* Optionally, ask for the fudge factor treatment for the widths of charged particles. Currently, this only applies to $W^\pm$ and top. *) let width f = if !use_fudged_width then match f with | G Wp | G Wm | M (U 3) | M (U (-3)) -> Fudged | _ -> !default_width else !default_width let goldstone = function | G f -> begin match f with | Wp -> Some (O Phip, Coupling.Integer 1) | Wm -> Some (O Phim, Coupling.Integer 1) | Z -> Some (O Phi0, Coupling.Integer 1) | _ -> None end | _ -> None let conjugate = function | M f -> M (begin match f with | L n -> L (-n) | N n -> N (-n) | U n -> U (-n) | D n -> D (-n) end) | G f -> G (begin match f with | Gl -> Gl | Ga -> Ga | Z -> Z | Wp -> Wm | Wm -> Wp end) | O f -> O (begin match f with | Phip -> Phim | Phim -> Phip | Phi0 -> Phi0 | Rsigma -> Rsigma | Rphin -> Rphin | Rphip -> Rphim | Rphim -> Rphip | Rphipp -> Rphimm | Rphimm -> Rphipp | Rf -> Rf | Rtn -> Rtn | Rtp -> Rtm | Rtm -> Rtp | Rtpp -> Rtmm | Rtmm -> Rtpp | Aux_top (l,co,ch,n,f) -> Aux_top (l,co,(-ch),(not n),f) end) let fermion = function | M f -> begin match f with | L n -> if n > 0 then 1 else -1 | N n -> if n > 0 then 1 else -1 | U n -> if n > 0 then 1 else -1 | D n -> if n > 0 then 1 else -1 end | G f -> begin match f with | Gl | Ga | Z | Wp | Wm -> 0 end | O _ -> 0 (* Electrical charge, lepton number, baryon number. We could avoid the rationals altogether by multiplying the first and last by 3 \ldots *) module Ch = Charges.QQ let ( // ) = Algebra.Small_Rational.make let generation' = function | 1 -> [ 1//1; 0//1; 0//1] | 2 -> [ 0//1; 1//1; 0//1] | 3 -> [ 0//1; 0//1; 1//1] | -1 -> [-1//1; 0//1; 0//1] | -2 -> [ 0//1; -1//1; 0//1] | -3 -> [ 0//1; 0//1; -1//1] | n -> invalid_arg ("SM.generation': " ^ string_of_int n) let generation f = if Flags.ckm_present then [] else match f with | M (L n | N n | U n | D n) -> generation' n | G _ | O _ -> [0//1; 0//1; 0//1] let charge = function | M f -> begin match f with | L n -> if n > 0 then -1//1 else 1//1 | N n -> 0//1 | U n -> if n > 0 then 2//3 else -2//3 | D n -> if n > 0 then -1//3 else 1//3 end | G f -> begin match f with | Gl | Ga | Z -> 0//1 | Wp -> 1//1 | Wm -> -1//1 end | O f -> begin match f with | Rsigma | Phi0 | Rphin | Rf | Rtn -> 0//1 | Phip | Rphip | Rtp -> 1//1 | Phim | Rphim | Rtm -> -1//1 | Rphipp | Rtpp -> 2//1 | Rphimm | Rtmm -> -2//1 | Aux_top (_,_,ch,_,_) -> ch//1 end let lepton = function | M f -> begin match f with | L n | N n -> if n > 0 then 1//1 else -1//1 | U _ | D _ -> 0//1 end | G _ | O _ -> 0//1 let baryon = function | M f -> begin match f with | L _ | N _ -> 0//1 | U n | D n -> if n > 0 then 1//1 else -1//1 end | G _ | O _ -> 0//1 let charges f = [ charge f; lepton f; baryon f] @ generation f type constant = | Unit | Half | Pi | Alpha_QED | Sin2thw | Sinthw | Costhw | E | G_weak | I_G_weak | Vev | Q_lepton | Q_up | Q_down | G_CC | G_CCQ of int*int | G_NC_neutrino | G_NC_lepton | G_NC_up | G_NC_down | G_TVA_ttA | G_TVA_bbA | G_VLR_ttZ | G_TVA_ttZ | G_TVA_bbZ | G_VLR_btW | G_VLR_tbW | G_TLR_btW | G_TRL_tbW | G_TLR_btWZ | G_TRL_tbWZ | G_TLR_btWA | G_TRL_tbWA | G_TVA_ttWW | G_TVA_bbWW | G_TVA_ttG | G_TVA_ttGG | G_VLR_qGuG | G_VLR_qBuB | G_VLR_qBuB_u | G_VLR_qBuB_d | G_VLR_qBuB_e | G_VL_qBuB_n | G_VL_qW | G_VL_qW_u | G_VL_qW_d | G_SL_DttR | G_SR_DttR | G_SL_DttL | G_SLR_DbtR | G_SL_DbtL | I_Q_W | I_G_ZWW | G_WWWW | G_ZZWW | G_AZWW | G_AAWW | I_G1_AWW | I_G1_ZWW | I_G1_plus_kappa_plus_G4_AWW | I_G1_plus_kappa_plus_G4_ZWW | I_G1_plus_kappa_minus_G4_AWW | I_G1_plus_kappa_minus_G4_ZWW | I_G1_minus_kappa_plus_G4_AWW | I_G1_minus_kappa_plus_G4_ZWW | I_G1_minus_kappa_minus_G4_AWW | I_G1_minus_kappa_minus_G4_ZWW | I_lambda_AWW | I_lambda_ZWW | G5_AWW | G5_ZWW | I_kappa5_AWW | I_kappa5_ZWW | I_lambda5_AWW | I_lambda5_ZWW | Alpha_WWWW0 | Alpha_ZZWW1 | Alpha_WWWW2 | Alpha_ZZWW0 | Alpha_ZZZZ | D_Alpha_ZZWW0_S | D_Alpha_ZZWW0_T | D_Alpha_ZZWW1_S | D_Alpha_ZZWW1_T | D_Alpha_ZZWW1_U | D_Alpha_WWWW0_S | D_Alpha_WWWW0_T | D_Alpha_WWWW0_U | D_Alpha_WWWW2_S | D_Alpha_WWWW2_T | D_Alpha_ZZZZ_S | D_Alpha_ZZZZ_T | G_SWW | G_SWW_T | G_SSWW | G_SZZ | G_SZZ_T | G_SSZZ | G_PNWW | G_PNZZ | G_PWZ | G_PWW | G_FWW | G_FZZ | G_FWW_T | G_FZZ_T | G_TNWW | G_TNZZ | G_TWZ | G_TWW | Gs | I_Gs | G2 | Mass of flavor | Width of flavor | K_Matrix_Coeff of int | K_Matrix_Pole of int (* \begin{dubious} The current abstract syntax for parameter dependencies is admittedly tedious. Later, there will be a parser for a convenient concrete syntax as a part of a concrete syntax for models. But as these examples show, it should include simple functions. \end{dubious} *) type orders = int * int let orders = function | _ -> (0,0) (* \begin{subequations} \begin{align} \alpha_{\text{QED}} &= \frac{1}{137.0359895} \\ \sin^2\theta_w &= 0.23124 \end{align} \end{subequations} *) let input_parameters = [ Alpha_QED, 1. /. 137.0359895; Sin2thw, 0.23124; Mass (G Z), 91.187; Mass (M (N 1)), 0.0; Mass (M (L 1)), 0.51099907e-3; Mass (M (N 2)), 0.0; Mass (M (L 2)), 0.105658389; Mass (M (N 3)), 0.0; Mass (M (L 3)), 1.77705; Mass (M (U 1)), 5.0e-3; Mass (M (D 1)), 3.0e-3; Mass (M (U 2)), 1.2; Mass (M (D 2)), 0.1; Mass (M (U 3)), 174.0; Mass (M (D 3)), 4.2 ] (* \begin{subequations} \begin{align} e &= \sqrt{4\pi\alpha} \\ \sin\theta_w &= \sqrt{\sin^2\theta_w} \\ \cos\theta_w &= \sqrt{1-\sin^2\theta_w} \\ g &= \frac{e}{\sin\theta_w} \\ m_W &= \cos\theta_w m_Z \\ v &= \frac{2m_W}{g} \\ g_{CC} = -\frac{g}{2\sqrt2} &= -\frac{e}{2\sqrt2\sin\theta_w} \\ Q_{\text{lepton}} = -q_{\text{lepton}}e &= e \\ Q_{\text{up}} = -q_{\text{up}}e &= -\frac{2}{3}e \\ Q_{\text{down}} = -q_{\text{down}}e &= \frac{1}{3}e \\ \ii q_We = \ii g_{\gamma WW} &= \ii e \\ \ii g_{ZWW} &= \ii g \cos\theta_w \\ \ii g_{WWW} &= \ii g \end{align} \end{subequations} *) let derived_parameters = [ Real E, Sqrt (Prod [Integer 4; Atom Pi; Atom Alpha_QED]); Real Sinthw, Sqrt (Atom Sin2thw); Real Costhw, Sqrt (Diff (Integer 1, Atom Sin2thw)); Real G_weak, Quot (Atom E, Atom Sinthw); Real (Mass (G Wp)), Prod [Atom Costhw; Atom (Mass (G Z))]; Real Vev, Quot (Prod [Integer 2; Atom (Mass (G Wp))], Atom G_weak); Real Q_lepton, Atom E; Real Q_up, Prod [Quot (Integer (-2), Integer 3); Atom E]; Real Q_down, Prod [Quot (Integer 1, Integer 3); Atom E]; Real G_CC, Neg (Quot (Atom G_weak, Prod [Integer 2; Sqrt (Integer 2)])); Complex I_Q_W, Prod [I; Atom E]; Complex I_G_weak, Prod [I; Atom G_weak]; Complex I_G_ZWW, Prod [I; Atom G_weak; Atom Costhw] ] (* \begin{equation} - \frac{g}{2\cos\theta_w} \end{equation} *) let g_over_2_costh = Quot (Neg (Atom G_weak), Prod [Integer 2; Atom Costhw]) (* \begin{subequations} \begin{align} - \frac{g}{2\cos\theta_w} g_V &= - \frac{g}{2\cos\theta_w} (T_3 - 2 q \sin^2\theta_w) \\ - \frac{g}{2\cos\theta_w} g_A &= - \frac{g}{2\cos\theta_w} T_3 \end{align} \end{subequations} *) let nc_coupling c t3 q = (Real_Array c, [Prod [g_over_2_costh; Diff (t3, Prod [Integer 2; q; Atom Sin2thw])]; Prod [g_over_2_costh; t3]]) let half = Quot (Integer 1, Integer 2) let derived_parameter_arrays = [ nc_coupling G_NC_neutrino half (Integer 0); nc_coupling G_NC_lepton (Neg half) (Integer (-1)); nc_coupling G_NC_up half (Quot (Integer 2, Integer 3)); nc_coupling G_NC_down (Neg half) (Quot (Integer (-1), Integer 3)) ] let parameters () = { input = input_parameters; derived = derived_parameters; derived_arrays = derived_parameter_arrays } module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) (* \begin{equation} \mathcal{L}_{\textrm{EM}} = - e \sum_i q_i \bar\psi_i\fmslash{A}\psi_i \end{equation} *) let mgm ((m1, g, m2), fbf, c) = ((M m1, G g, M m2), fbf, c) let mom ((m1, o, m2), fbf, c) = ((M m1, O o, M m2), fbf, c) let electromagnetic_currents n = List.map mgm [ ((L (-n), Ga, L n), FBF (1, Psibar, V, Psi), Q_lepton); ((U (-n), Ga, U n), FBF (1, Psibar, V, Psi), Q_up); ((D (-n), Ga, D n), FBF (1, Psibar, V, Psi), Q_down) ] let color_currents n = List.map mgm [ ((U (-n), Gl, U n), FBF ((-1), Psibar, V, Psi), Gs); ((D (-n), Gl, D n), FBF ((-1), Psibar, V, Psi), Gs) ] (* \begin{equation} \mathcal{L}_{\textrm{NC}} = - \frac{g}{2\cos\theta_W} \sum_i \bar\psi_i\fmslash{Z}(g_V^i-g_A^i\gamma_5)\psi_i \end{equation} *) let neutral_currents n = List.map mgm [ ((L (-n), Z, L n), FBF (1, Psibar, VA, Psi), G_NC_lepton); ((N (-n), Z, N n), FBF (1, Psibar, VA, Psi), G_NC_neutrino); ((U (-n), Z, U n), FBF (1, Psibar, VA, Psi), G_NC_up); ((D (-n), Z, D n), FBF (1, Psibar, VA, Psi), G_NC_down) ] (* \begin{equation} \mathcal{L}_{\textrm{CC}} = - \frac{g}{2\sqrt2} \sum_i \bar\psi_i (T^+\fmslash{W}^+ + T^-\fmslash{W}^-)(1-\gamma_5)\psi_i \end{equation} *) let charged_currents' n = List.map mgm [ ((L (-n), Wm, N n), FBF (1, Psibar, VL, Psi), G_CC); ((N (-n), Wp, L n), FBF (1, Psibar, VL, Psi), G_CC) ] let charged_currents'' n = List.map mgm [ ((D (-n), Wm, U n), FBF (1, Psibar, VL, Psi), G_CC); ((U (-n), Wp, D n), FBF (1, Psibar, VL, Psi), G_CC) ] let charged_currents_triv = ThoList.flatmap charged_currents' [1;2;3] @ ThoList.flatmap charged_currents'' [1;2;3] let charged_currents_ckm = let charged_currents_2 n1 n2 = List.map mgm [ ((D (-n1), Wm, U n2), FBF (1, Psibar, VL, Psi), G_CCQ (n2,n1)); ((U (-n1), Wp, D n2), FBF (1, Psibar, VL, Psi), G_CCQ (n1,n2)) ] in ThoList.flatmap charged_currents' [1;2;3] @ List.flatten (Product.list2 charged_currents_2 [1;2;3] [1;2;3]) (* \begin{equation} \mathcal{L}_{\textrm{TGC}} = - e \partial_\mu A_\nu W_+^\mu W_-^\nu + \ldots - e \cot\theta_w \partial_\mu Z_\nu W_+^\mu W_-^\nu + \ldots \end{equation} *) let tgc ((g1, g2, g3), t, c) = ((G g1, G g2, G g3), t, c) let standard_triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW); ((Gl, Gl, Gl), Gauge_Gauge_Gauge 1, I_Gs)] (* \begin{multline} \mathcal{L}_{\textrm{TGC}}(g_1,\kappa) = g_1 \mathcal{L}_T(V,W^+,W^-) \\ + \frac{\kappa+g_1}{2} \Bigl(\mathcal{L}_T(W^-,V,W^+) - \mathcal{L}_T(W^+,V,W^-)\Bigr)\\ + \frac{\kappa-g_1}{2} \Bigl(\mathcal{L}_L(W^-,V,W^+) - \mathcal{L}_T(W^+,V,W^-)\Bigr) \end{multline} *) (* \begin{dubious} The whole thing in the LEP2 workshop notation: \begin{multline} \ii\mathcal{L}_{\textrm{TGC},V} / g_{WWV} = \\ g_1^V V^\mu (W^-_{\mu\nu}W^{+,\nu}-W^+_{\mu\nu}W^{-,\nu}) + \kappa_V W^+_\mu W^-_\nu V^{\mu\nu} + \frac{\lambda_V}{m_W^2} V_{\mu\nu} W^-_{\rho\mu} W^{+,\hphantom{\nu}\rho}_{\hphantom{+,}\nu} \\ + \ii g_5^V \epsilon_{\mu\nu\rho\sigma} \left( (\partial^\rho W^{-,\mu}) W^{+,\nu} - W^{-,\mu}(\partial^\rho W^{+,\nu}) \right) V^\sigma \\ + \ii g_4^V W^-_\mu W^+_\nu (\partial^\mu V^\nu + \partial^\nu V^\mu) - \frac{\tilde\kappa_V}{2} W^-_\mu W^+_\nu \epsilon^{\mu\nu\rho\sigma} V_{\rho\sigma} - \frac{\tilde\lambda_V}{2m_W^2} W^-_{\rho\mu} W^{+,\mu}_{\hphantom{+,\mu}\nu} \epsilon^{\nu\rho\alpha\beta} V_{\alpha\beta} \end{multline} using the conventions of Itzykson and Zuber with $\epsilon^{0123} = +1$. \end{dubious} *) (* \begin{dubious} This is equivalent to the notation of Hagiwara et al.~\cite{HPZH87}, if we remember that they have opposite signs for~$g_{WWV}$: \begin{multline} \mathcal{L}_{WWV} / (-g_{WWV}) = \\ \ii g_1^V \left( W^\dagger_{\mu\nu} W^\mu - W^\dagger_\mu W^\mu_{\hphantom{\mu}\nu} \right) V^\nu + \ii \kappa_V W^\dagger_\mu W_\nu V^{\mu\nu} + \ii \frac{\lambda_V}{m_W^2} W^\dagger_{\lambda\mu} W^\mu_{\hphantom{\mu}\nu} V^{\nu\lambda} \\ - g_4^V W^\dagger_\mu W_\nu \left(\partial^\mu V^\nu + \partial^\nu V^\mu \right) + g_5^V \epsilon^{\mu\nu\lambda\sigma} \left( W^\dagger_\mu \stackrel{\leftrightarrow}{\partial_\lambda} W_\nu \right) V_\sigma\\ + \ii \tilde\kappa_V W^\dagger_\mu W_\nu \tilde{V}^{\mu\nu} + \ii\frac{\tilde\lambda_V}{m_W^2} W^\dagger_{\lambda\mu} W^\mu_{\hphantom{\mu}\nu} \tilde{V}^{\nu\lambda} \end{multline} Here $V^\mu$ stands for either the photon or the~$Z$ field, $W^\mu$ is the $W^-$ field, $W_{\mu\nu} = \partial_\mu W_\nu - \partial_\nu W_\mu$, $V_{\mu\nu} = \partial_\mu V_\nu - \partial_\nu V_\mu$, and $\tilde{V}_{\mu\nu} = \frac{1}{2} \epsilon_{\mu\nu\lambda\sigma} V^{\lambda\sigma}$. \end{dubious} *) let anomalous_triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Dim4_Vector_Vector_Vector_T (-1), I_G1_AWW); ((Z, Wm, Wp), Dim4_Vector_Vector_Vector_T (-1), I_G1_ZWW); ((Wm, Ga, Wp), Dim4_Vector_Vector_Vector_T 1, I_G1_plus_kappa_minus_G4_AWW); ((Wm, Z, Wp), Dim4_Vector_Vector_Vector_T 1, I_G1_plus_kappa_minus_G4_ZWW); ((Wp, Ga, Wm), Dim4_Vector_Vector_Vector_T (-1), I_G1_plus_kappa_plus_G4_AWW); ((Wp, Z, Wm), Dim4_Vector_Vector_Vector_T (-1), I_G1_plus_kappa_plus_G4_ZWW); ((Wm, Ga, Wp), Dim4_Vector_Vector_Vector_L (-1), I_G1_minus_kappa_plus_G4_AWW); ((Wm, Z, Wp), Dim4_Vector_Vector_Vector_L (-1), I_G1_minus_kappa_plus_G4_ZWW); ((Wp, Ga, Wm), Dim4_Vector_Vector_Vector_L 1, I_G1_minus_kappa_minus_G4_AWW); ((Wp, Z, Wm), Dim4_Vector_Vector_Vector_L 1, I_G1_minus_kappa_minus_G4_ZWW); ((Ga, Wm, Wp), Dim4_Vector_Vector_Vector_L5 (-1), I_kappa5_AWW); ((Z, Wm, Wp), Dim4_Vector_Vector_Vector_L5 (-1), I_kappa5_ZWW); ((Ga, Wm, Wp), Dim4_Vector_Vector_Vector_T5 (-1), G5_AWW); ((Z, Wm, Wp), Dim4_Vector_Vector_Vector_T5 (-1), G5_ZWW); ((Ga, Wp, Wm), Dim6_Gauge_Gauge_Gauge (-1), I_lambda_AWW); ((Z, Wp, Wm), Dim6_Gauge_Gauge_Gauge (-1), I_lambda_ZWW); ((Ga, Wp, Wm), Dim6_Gauge_Gauge_Gauge_5 (-1), I_lambda5_AWW); ((Z, Wp, Wm), Dim6_Gauge_Gauge_Gauge_5 (-1), I_lambda5_ZWW) ] let triple_gauge = if Flags.triple_anom then anomalous_triple_gauge else standard_triple_gauge (* \begin{equation} \mathcal{L}_{\textrm{QGC}} = - g^2 W_{+,\mu} W_{-,\nu} W_+^\mu W_-^\nu + \ldots \end{equation} *) (* Actually, quartic gauge couplings are a little bit more straightforward using auxiliary fields. Here we have to impose the antisymmetry manually: \begin{subequations} \begin{multline} (W^{+,\mu}_1 W^{-,\nu}_2 - W^{+,\nu}_1 W^{-,\mu}_2) (W^+_{3,\mu} W^-_{4,\nu} - W^+_{3,\nu} W^-_{4,\mu}) \\ = 2(W^+_1W^+_3)(W^-_2W^-_4) - 2(W^+_1W^-_4)(W^-_2W^+_3) \end{multline} also ($V$ can be $A$ or $Z$) \begin{multline} (W^{+,\mu}_1 V^\nu_2 - W^{+,\nu}_1 V^\mu_2) (W^-_{3,\mu} V_{4,\nu} - W^-_{3,\nu} V_{4,\mu}) \\ = 2(W^+_1W^-_3)(V_2V_4) - 2(W^+_1V_4)(V_2W^-_3) \end{multline} \end{subequations} *) (* \begin{subequations} \begin{multline} W^{+,\mu} W^{-,\nu} W^+_\mu W^-_\nu \end{multline} \end{subequations} *) let qgc ((g1, g2, g3, g4), t, c) = ((G g1, G g2, G g3, G g4), t, c) let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] let standard_quartic_gauge = List.map qgc [ (Wm, Wp, Wm, Wp), gauge4, G_WWWW; (Wm, Z, Wp, Z), minus_gauge4, G_ZZWW; (Wm, Z, Wp, Ga), minus_gauge4, G_AZWW; (Wm, Ga, Wp, Ga), minus_gauge4, G_AAWW; (Gl, Gl, Gl, Gl), gauge4, G2 ] (* \begin{subequations} \begin{align} \mathcal{L}_4 &= \alpha_4 \left( \frac{g^4}{2}\left( (W^+_\mu W^{-,\mu})^2 + W^+_\mu W^{+,\mu} W^-_\mu W^{-,\mu} \right)\right.\notag \\ &\qquad\qquad\qquad \left. + \frac{g^4}{\cos^2\theta_w} W^+_\mu Z^\mu W^-_\nu Z^\nu + \frac{g^4}{4\cos^4\theta_w} (Z_\mu Z^\mu)^2 \right) \\ \mathcal{L}_5 &= \alpha_5 \left( g^4 (W^+_\mu W^{-,\mu})^2 + \frac{g^4}{\cos^2\theta_w} W^+_\mu W^{-,\mu} Z_\nu Z^\nu + \frac{g^4}{4\cos^4\theta_w} (Z_\mu Z^\mu)^2 \right) \end{align} \end{subequations} or \begin{multline} \mathcal{L}_4 + \mathcal{L}_5 = (\alpha_4+2\alpha_5) g^4 \frac{1}{2} (W^+_\mu W^{-,\mu})^2 \\ + 2\alpha_4 g^4 \frac{1}{4} W^+_\mu W^{+,\mu} W^-_\mu W^{-,\mu} + \alpha_4 \frac{g^4}{\cos^2\theta_w} W^+_\mu Z^\mu W^-_\nu Z^\nu \\ + 2\alpha_5 \frac{g^4}{\cos^2\theta_w} \frac{1}{2} W^+_\mu W^{-,\mu} Z_\nu Z^\nu + (2\alpha_4 + 2\alpha_5) \frac{g^4}{\cos^4\theta_w} \frac{1}{8} (Z_\mu Z^\mu)^2 \end{multline} and therefore \begin{subequations} \begin{align} \alpha_{(WW)_0} &= (\alpha_4+2\alpha_5) g^4 \\ \alpha_{(WW)_2} &= 2\alpha_4 g^4 \\ \alpha_{(WZ)_0} &= 2\alpha_5 \frac{g^4}{\cos^2\theta_w} \\ \alpha_{(WZ)_1} &= \alpha_4 \frac{g^4}{\cos^2\theta_w} \\ \alpha_{ZZ} &= (2\alpha_4 + 2\alpha_5) \frac{g^4}{\cos^4\theta_w} \end{align} \end{subequations} *) let anomalous_quartic_gauge = if Flags.quartic_anom then List.map qgc [ ((Wm, Wm, Wp, Wp), Vector4 [(1, C_13_42); (1, C_14_23)], Alpha_WWWW0); ((Wm, Wm, Wp, Wp), Vector4 [1, C_12_34], Alpha_WWWW2); ((Wm, Wp, Z, Z), Vector4 [1, C_12_34], Alpha_ZZWW0); ((Wm, Wp, Z, Z), Vector4 [(1, C_13_42); (1, C_14_23)], Alpha_ZZWW1); ((Z, Z, Z, Z), Vector4 [(1, C_12_34); (1, C_13_42); (1, C_14_23)], Alpha_ZZZZ) ] else [] (* In any diagonal channel~$\chi$, the scattering amplitude~$a_\chi(s)$ is unitary iff\footnote{% Trivial proof: \begin{equation} -1 = \textrm{Im}\left(\frac{1}{a_\chi(s)}\right) = \frac{\textrm{Im}(a_\chi^*(s))}{ |a_\chi(s)|^2 } = - \frac{\textrm{Im}(a_\chi(s))}{ |a_\chi(s)|^2 } \end{equation} i.\,e.~$\textrm{Im}(a_\chi(s)) = |a_\chi(s)|^2$.} \begin{equation} \textrm{Im}\left(\frac{1}{a_\chi(s)}\right) = -1 \end{equation} For a real perturbative scattering amplitude~$r_\chi(s)$ this can be enforced easily--and arbitrarily--by \begin{equation} \frac{1}{a_\chi(s)} = \frac{1}{r_\chi(s)} - \mathrm{i} \end{equation} *) let k_matrix_quartic_gauge = if Flags.k_matrix then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_WWWW0_S); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_jr (0, [(1, C_14_23)]), D_Alpha_WWWW0_T); ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_jr (0, [(1, C_13_42)]), D_Alpha_WWWW0_U); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_WWWW0_S); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_jr (0, [(1, C_14_23)]), D_Alpha_WWWW0_T); ((Wp, Wm, Wp, Wm), Vector4_K_Matrix_jr (0, [(1, C_13_42)]), D_Alpha_WWWW0_U); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_WWWW2_S); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_jr (0, [(1, C_13_42); (1, C_14_23)]), D_Alpha_WWWW2_T); ((Wm, Wp, Z, Z), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_ZZWW0_S); ((Wm, Wp, Z, Z), Vector4_K_Matrix_jr (0, [(1, C_13_42); (1, C_14_23)]), D_Alpha_ZZWW0_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_ZZWW1_S); ((Wm, Z, Wp, Z), Vector4_K_Matrix_jr (0, [(1, C_13_42)]), D_Alpha_ZZWW1_T); ((Wm, Z, Wp, Z), Vector4_K_Matrix_jr (0, [(1, C_14_23)]), D_Alpha_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_jr (1, [(1, C_12_34)]), D_Alpha_ZZWW1_S); ((Wp, Z, Z, Wm), Vector4_K_Matrix_jr (1, [(1, C_13_42)]), D_Alpha_ZZWW1_U); ((Wp, Z, Z, Wm), Vector4_K_Matrix_jr (1, [(1, C_14_23)]), D_Alpha_ZZWW1_T); ((Z, Wp, Wm, Z), Vector4_K_Matrix_jr (2, [(1, C_12_34)]), D_Alpha_ZZWW1_S); ((Z, Wp, Wm, Z), Vector4_K_Matrix_jr (2, [(1, C_13_42)]), D_Alpha_ZZWW1_U); ((Z, Wp, Wm, Z), Vector4_K_Matrix_jr (2, [(1, C_14_23)]), D_Alpha_ZZWW1_T); ((Z, Z, Z, Z), Vector4_K_Matrix_jr (0, [(1, C_12_34)]), D_Alpha_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_jr (0, [(1, C_13_42); (1, C_14_23)]), D_Alpha_ZZZZ_T); ((Z, Z, Z, Z), Vector4_K_Matrix_jr (3, [(1, C_14_23)]), D_Alpha_ZZZZ_S); ((Z, Z, Z, Z), Vector4_K_Matrix_jr (3, [(1, C_13_42); (1, C_12_34)]), D_Alpha_ZZZZ_T)] else [] (*i Thorsten's original implementation of the K matrix, which we keep since it still might be usefull for the future. let k_matrix_quartic_gauge = if Flags.k_matrix then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 0, K_Matrix_Pole 0]), Alpha_WWWW0); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 2, K_Matrix_Pole 2]), Alpha_WWWW2); ((Wm, Wp, Z, Z), Vector4_K_Matrix_tho (0, [(K_Matrix_Coeff 0, K_Matrix_Pole 0); (K_Matrix_Coeff 2, K_Matrix_Pole 2)]), Alpha_ZZWW0); ((Wm, Z, Wp, Z), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 1, K_Matrix_Pole 1]), Alpha_ZZWW1); ((Z, Z, Z, Z), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 0, K_Matrix_Pole 0]), Alpha_ZZZZ) ] else [] i*) let quartic_gauge = standard_quartic_gauge @ anomalous_quartic_gauge @ k_matrix_quartic_gauge (* WK's couplings (apparently, he still intends to divide by $\Lambda^2_{\text{EWSB}}=16\pi^2v_{\mathrm{F}}^2$): with \begin{equation} V_{\mu} V_{\nu} = \frac{1}{2} \left( W^+_{\mu} W^-_{\nu} + W^+_{\nu} W^-_{\mu} \right) + \frac{1}{2\cos^2\theta_{w}} Z_{\mu} Z_{\nu} \end{equation} (note the symmetrization!), i.\,e. \begin{subequations} \begin{align} \mathcal{L}_4 &= \alpha_4 \frac{g^4v_{\mathrm{F}}^4}{16} (V_{\mu} V_{\nu})^2 \\ \mathcal{L}_5 &= \alpha_5 \frac{g^4v_{\mathrm{F}}^4}{16} (V_{\mu} V^{\mu})^2 \end{align} \end{subequations} *) let goldstone_vertices = [ ((O Phi0, G Wm, G Wp), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phip, G Ga, G Wm), Scalar_Vector_Vector 1, I_Q_W); ((O Phip, G Z, G Wm), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phim, G Wp, G Ga), Scalar_Vector_Vector 1, I_Q_W); ((O Phim, G Wp, G Z), Scalar_Vector_Vector 1, I_G_ZWW) ] (* New Resonances *) (* \begin{dubious} There is an extra minus in the Lagrangian to have the same sign as HWW or HZZ vertex. Effectivly this doesn't matter for VBS, because $(-1)^2=1$. This is only for completeness. \end{dubious} \begin{subequations} \begin{align} \mathbf{V}_\mu &= -\mathrm{i} g\mathbf{W}_\mu+\mathrm{i} g^\prime\mathbf{B}_\mu \\ \mathbf{W}_\mu &= W_\mu^a\frac{\tau^a}{2} \\ \mathbf{B}_\mu &= W_\mu^a\frac{\tau^3}{2} \\ \tau^{++}&= \tau^+ \otimes \tau^+ \\ \tau^+ &= \frac{1}{2} \left (\tau^+ \otimes \tau^3 + \tau^3+\tau^+ \right ) \\ \tau^0 &= \frac{1}{\sqrt{6}} \left (\tau^3\otimes\tau^3 -\tau^+ \otimes \tau^- - \tau^-+\tau^+ \right ) \\ \tau^- &= \frac{1}{2} \left (\tau^- \otimes \tau^3 + \tau^3+\tau^- \right ) \\ \tau^{--}&= \tau^- \otimes \tau^- \end{align} \end{subequations} *) (* Scalar Isoscalar \begin{equation} \mathcal{L}_{\sigma}= -\frac{g_\sigma v}{2} \text{tr} \left\lbrack \mathbf{V}_\mu \mathbf{V}^\mu \right\rbrack \sigma \end{equation} *) let rsigma3 = [ ((O Rsigma, G Wp, G Wm), Scalar_Vector_Vector 1, G_SWW); ((O Rsigma, G Z, G Z), Scalar_Vector_Vector 1, G_SZZ) ] let rsigma3t = [ ((O Rsigma, G Wp, G Wm), Scalar_Vector_Vector_t 1, G_SWW_T); ((O Rsigma, G Z, G Z), Scalar_Vector_Vector_t 1, G_SZZ_T) ] let rsigma4 = [ (O Rsigma, O Rsigma, G Wp, G Wm), Scalar2_Vector2 1, G_SSWW; (O Rsigma, O Rsigma, G Z, G Z), Scalar2_Vector2 1, G_SSZZ ] (* Scalar Isotensor \begin{subequations} \begin{align} \mathcal{L}_{\phi}&= \frac{g_\phi v}{4} \text{Tr} \left \lbrack \left ( \mathbf{V}_\mu \otimes \mathbf{V}^\mu - \frac{\tau^{aa}}{6} \text{Tr} \left \lbrack \mathbf{V}_\mu \mathbf{V}^\mu \right \rbrack\right ) {\mathbf{\phi}} \right \rbrack\\ \phi&=\sqrt{2} \left (\phi^{++}\tau^{++}+\phi^+\tau^++\phi^0\tau^0+\phi^-\tau^- + \phi^{--}\tau^{--} \right ) \end{align} \end{subequations} *) let rphi3 = [ ((O Rphin, G Wp, G Wm), Scalar_Vector_Vector 1, G_PNWW); ((O Rphin, G Z, G Z), Scalar_Vector_Vector 1, G_PNZZ) ; ((O Rphip, G Z, G Wm), Scalar_Vector_Vector 1, G_PWZ) ; ((O Rphipp, G Wm, G Wm), Scalar_Vector_Vector 1, G_PWW) ; ((O Rphim, G Wp, G Z), Scalar_Vector_Vector 1, G_PWZ) ; ((O Rphimm, G Wp, G Wp), Scalar_Vector_Vector 1, G_PWW) ] (* Tensor IsoScalar *) let rf3 = [ ((O Rf, G Wp, G Wm), Tensor_2_Vector_Vector_1 1, G_FWW); ((O Rf, G Z, G Z), Tensor_2_Vector_Vector_1 1, G_FZZ) ] let rf3t = [ ((O Rf, G Wp, G Wm), Tensor_2_Vector_Vector_t 1, G_FWW_T); ((O Rf, G Z, G Z), Tensor_2_Vector_Vector_t 1, G_FZZ_T) ] (* Tensor Isotensor \begin{subequations} \begin{align} \mathcal{L}_{t} \end{align} \end{subequations} *) let rt3 = [ ((O Rtn, G Wp, G Wm), Tensor_2_Vector_Vector_1 1, G_TNWW); ((O Rtn, G Z, G Z), Tensor_2_Vector_Vector_1 1, G_TNZZ) ; ((O Rtp, G Z, G Wm), Tensor_2_Vector_Vector_1 1, G_TWZ) ; ((O Rtpp, G Wm, G Wm), Tensor_2_Vector_Vector_1 1, G_TWW) ; ((O Rtm, G Wp, G Z), Tensor_2_Vector_Vector_1 1, G_TWZ) ; ((O Rtmm, G Wp, G Wp), Tensor_2_Vector_Vector_1 1, G_TWW) ] (* Anomalous trilinear interactions $f_i f_j V$ : \begin{equation} \Delta\mathcal{L}_{tt\gamma} = - e \frac{\upsilon}{\Lambda^2} \bar{t} i\sigma^{\mu\nu} k_\nu (d_V(k^2) + i d_A(k^2) \gamma_5) t A_\mu \end{equation} *) let anomalous_ttA = if Flags.top_anom then [ ((M (U (-3)), G Ga, M (U 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_ttA) ] else [] (* \begin{equation} \Delta\mathcal{L}_{bb\gamma} = - e \frac{\upsilon}{\Lambda^2} \bar{b} i\sigma^{\mu\nu} k_\nu (d_V(k^2) + i d_A(k^2) \gamma_5) b A_\mu \end{equation} *) let anomalous_bbA = if Flags.top_anom then [ ((M (D (-3)), G Ga, M (D 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_bbA) ] else [] (* \begin{equation} \Delta\mathcal{L}_{ttg} = - g_s \frac{\upsilon}{\Lambda^2} \bar{t}\lambda^a i\sigma^{\mu\nu}k_\nu (d_V(k^2)+id_A(k^2)\gamma_5)tG^a_\mu \end{equation} *) let anomalous_ttG = if Flags.top_anom then [ ((M (U (-3)), G Gl, M (U 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_ttG) ] else [] (* \begin{equation} \Delta\mathcal{L}_{ttZ} = - \frac{g}{2 c_W} \frac{\upsilon^2}{\Lambda^2}\left\lbrack \bar{t} \fmslash{Z} (X_L(k^2) P_L + X_R(k^2) P_R) t + \bar{t}\frac{i\sigma^{\mu\nu}k_\nu}{m_Z} (d_V(k^2)+id_A(k^2)\gamma_5)tZ_\mu\right\rbrack \end{equation} *) let anomalous_ttZ = if Flags.top_anom then [ ((M (U (-3)), G Z, M (U 3)), FBF (1, Psibar, VLRM, Psi), G_VLR_ttZ); ((M (U (-3)), G Z, M (U 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_ttZ) ] else [] (* \begin{equation} \Delta\mathcal{L}_{bbZ} = - \frac{g}{2 c_W} \frac{\upsilon^2}{\Lambda^2} \bar{b}\frac{i\sigma^{\mu\nu}k_\nu}{m_Z} (d_V(k^2)+id_A(k^2)\gamma_5)bZ_\mu \end{equation} *) let anomalous_bbZ = if Flags.top_anom then [ ((M (D (-3)), G Z, M (D 3)), FBF (1, Psibar, TVAM, Psi), G_TVA_bbZ) ] else [] (* \begin{equation} \Delta\mathcal{L}_{tbW} = - \frac{g}{\sqrt{2}} \frac{\upsilon^2}{\Lambda^2}\left\lbrack \bar{b}\fmslash{W}^-(V_L(k^2) P_L+V_R(k^2) P_R) t + \bar{b}\frac{i\sigma^{\mu\nu}k_\nu}{m_W} (g_L(k^2)P_L+g_R(k^2)P_R)tW^-_\mu\right\rbrack + \textnormal{H.c.} \end{equation} *) let anomalous_tbW = if Flags.top_anom then [ ((M (D (-3)), G Wm, M (U 3)), FBF (1, Psibar, VLRM, Psi), G_VLR_btW); ((M (U (-3)), G Wp, M (D 3)), FBF (1, Psibar, VLRM, Psi), G_VLR_tbW); ((M (D (-3)), G Wm, M (U 3)), FBF (1, Psibar, TLRM, Psi), G_TLR_btW); ((M (U (-3)), G Wp, M (D 3)), FBF (1, Psibar, TRLM, Psi), G_TRL_tbW) ] else [] (* quartic fermion-gauge interactions $f_i f_j V_1 V_2$ emerging from gauge-invariant effective operators: \begin{equation} \Delta\mathcal{L}_{ttgg} = - \frac{g_s^2}{2} f_{abc} \frac{\upsilon}{\Lambda^2} \bar{t} \lambda^a \sigma^{\mu\nu} (d_V(k^2)+id_A(k^2)\gamma_5)t G^b_\mu G^c_\nu \end{equation} *) let anomalous_ttGG = if Flags.top_anom then [ ((M (U (-3)), O (Aux_top (2,1,0,true,TTGG)), M (U 3)), FBF (1, Psibar, TVA, Psi), G_TVA_ttGG); ((O (Aux_top (2,1,0,false,TTGG)), G Gl, G Gl), Aux_Gauge_Gauge 1, I_Gs) ] else [] (* \begin{equation} \Delta\mathcal{L}_{tbWA} = - i\sin\theta_w \frac{g^2}{2\sqrt{2}} \frac{\upsilon^2}{\Lambda^2}\left\lbrack \bar{b}\frac{\sigma^{\mu\nu}}{m_W} (g_L(k^2)P_L+g_R(k^2)P_R)t A_\mu W^-_\nu \right\rbrack + \textnormal{H.c.} \end{equation} *) let anomalous_tbWA = if Flags.top_anom then [ ((M (D (-3)), O (Aux_top (2,0,-1,true,TBWA)), M (U 3)), FBF (1, Psibar, TLR, Psi), G_TLR_btWA); ((O (Aux_top (2,0,1,false,TBWA)), G Ga, G Wm), Aux_Gauge_Gauge 1, I_G_weak); ((M (U (-3)), O (Aux_top (2,0,1,true,TBWA)), M (D 3)), FBF (1, Psibar, TRL, Psi), G_TRL_tbWA); ((O (Aux_top (2,0,-1,false,TBWA)), G Wp, G Ga), Aux_Gauge_Gauge 1, I_G_weak) ] else [] (* \begin{equation} \Delta\mathcal{L}_{tbWZ} = - i\cos\theta_w \frac{g^2}{2\sqrt{2}} \frac{\upsilon^2}{\Lambda^2}\left\lbrack \bar{b}\frac{\sigma^{\mu\nu}}{m_W} (g_L(k^2)P_L+g_R(k^2)P_R)t Z_\mu W^-_\nu \right\rbrack + \textnormal{H.c.} \end{equation} *) let anomalous_tbWZ = if Flags.top_anom then [ ((M (D (-3)), O (Aux_top (2,0,-1,true,TBWZ)), M (U 3)), FBF (1, Psibar, TLR, Psi), G_TLR_btWZ); ((O (Aux_top (2,0,1,false,TBWZ)), G Z, G Wm), Aux_Gauge_Gauge 1, I_G_weak); ((M (U (-3)), O (Aux_top (2,0,1,true,TBWZ)), M (D 3)), FBF (1, Psibar, TRL, Psi), G_TRL_tbWZ); ((O (Aux_top (2,0,-1,false,TBWZ)), G Wp, G Z), Aux_Gauge_Gauge 1, I_G_weak) ] else [] (* \begin{equation} \Delta\mathcal{L}_{ttWW} = - i \frac{g^2}{2} \frac{\upsilon^2}{\Lambda^2} \bar{t} \frac{\sigma^{\mu\nu}}{m_W} (d_V(k^2)+id_A(k^2)\gamma_5)t W^-_\mu W^+_\nu \end{equation} *) let anomalous_ttWW = if Flags.top_anom then [ ((M (U (-3)), O (Aux_top (2,0,0,true,TTWW)), M (U 3)), FBF (1, Psibar, TVA, Psi), G_TVA_ttWW); ((O (Aux_top (2,0,0,false,TTWW)), G Wm, G Wp), Aux_Gauge_Gauge 1, I_G_weak) ] else [] (* \begin{equation} \Delta\mathcal{L}_{bbWW} = - i \frac{g^2}{2} \frac{\upsilon^2}{\Lambda^2} \bar{b} \frac{\sigma^{\mu\nu}}{m_W} (d_V(k^2)+id_A(k^2)\gamma_5)b W^-_\mu W^+_\nu \end{equation} *) let anomalous_bbWW = if Flags.top_anom then [ ((M (D (-3)), O (Aux_top (2,0,0,true,BBWW)), M (D 3)), FBF (1, Psibar, TVA, Psi), G_TVA_bbWW); ((O (Aux_top (2,0,0,false,BBWW)), G Wm, G Wp), Aux_Gauge_Gauge 1, I_G_weak) ] else [] (* 4-fermion contact terms emerging from operator rewriting: *) let anomalous_top_qGuG_tt = [ ((M (U (-3)), O (Aux_top (1,1,0,true,QGUG)), M (U 3)), FBF (1, Psibar, VLR, Psi), G_VLR_qGuG) ] let anomalous_top_qGuG_ff n = List.map mom [ ((U (-n), Aux_top (1,1,0,false,QGUG), U n), FBF (1, Psibar, V, Psi), Unit); ((D (-n), Aux_top (1,1,0,false,QGUG), D n), FBF (1, Psibar, V, Psi), Unit) ] let anomalous_top_qGuG = if Flags.top_anom_4f then anomalous_top_qGuG_tt @ ThoList.flatmap anomalous_top_qGuG_ff [1;2;3] else [] let anomalous_top_qBuB_tt = [ ((M (U (-3)), O (Aux_top (1,0,0,true,QBUB)), M (U 3)), FBF (1, Psibar, VLR, Psi), G_VLR_qBuB) ] let anomalous_top_qBuB_ff n = List.map mom [ ((U (-n), Aux_top (1,0,0,false,QBUB), U n), FBF (1, Psibar, VLR, Psi), G_VLR_qBuB_u); ((D (-n), Aux_top (1,0,0,false,QBUB), D n), FBF (1, Psibar, VLR, Psi), G_VLR_qBuB_d); ((L (-n), Aux_top (1,0,0,false,QBUB), L n), FBF (1, Psibar, VLR, Psi), G_VLR_qBuB_e); ((N (-n), Aux_top (1,0,0,false,QBUB), N n), FBF (1, Psibar, VL, Psi), G_VL_qBuB_n) ] let anomalous_top_qBuB = if Flags.top_anom_4f then anomalous_top_qBuB_tt @ ThoList.flatmap anomalous_top_qBuB_ff [1;2;3] else [] let anomalous_top_qW_tq = [ ((M (U (-3)), O (Aux_top (1,0,0,true,QW)), M (U 3)), FBF (1, Psibar, VL, Psi), G_VL_qW); ((M (D (-3)), O (Aux_top (1,0,-1,true,QW)), M (U 3)), FBF (1, Psibar, VL, Psi), G_VL_qW); ((M (U (-3)), O (Aux_top (1,0,1,true,QW)), M (D 3)), FBF (1, Psibar, VL, Psi), G_VL_qW) ] let anomalous_top_qW_ff n = List.map mom [ ((U (-n), Aux_top (1,0,0,false,QW), U n), FBF (1, Psibar, VL, Psi), G_VL_qW_u); ((D (-n), Aux_top (1,0,0,false,QW), D n), FBF (1, Psibar, VL, Psi), G_VL_qW_d); ((N (-n), Aux_top (1,0,0,false,QW), N n), FBF (1, Psibar, VL, Psi), G_VL_qW_u); ((L (-n), Aux_top (1,0,0,false,QW), L n), FBF (1, Psibar, VL, Psi), G_VL_qW_d); ((D (-n), Aux_top (1,0,-1,false,QW), U n), FBF (1, Psibar, VL, Psi), Half); ((U (-n), Aux_top (1,0,1,false,QW), D n), FBF (1, Psibar, VL, Psi), Half); ((L (-n), Aux_top (1,0,-1,false,QW), N n), FBF (1, Psibar, VL, Psi), Half); ((N (-n), Aux_top (1,0,1,false,QW), L n), FBF (1, Psibar, VL, Psi), Half) ] let anomalous_top_qW = if Flags.top_anom_4f then anomalous_top_qW_tq @ ThoList.flatmap anomalous_top_qW_ff [1;2;3] else [] let anomalous_top_DuDd = if Flags.top_anom_4f then [ ((M (U (-3)), O (Aux_top (0,0,0,true,DR)), M (U 3)), FBF (1, Psibar, SR, Psi), Half); ((M (U (-3)), O (Aux_top (0,0,0,false,DR)), M (U 3)), FBF (1, Psibar, SL, Psi), G_SL_DttR); ((M (D (-3)), O (Aux_top (0,0,0,false,DR)), M (D 3)), FBF (1, Psibar, SR, Psi), G_SR_DttR); ((M (U (-3)), O (Aux_top (0,0,0,true,DL)), M (U 3)), FBF (1, Psibar, SL, Psi), Half); ((M (D (-3)), O (Aux_top (0,0,0,false,DL)), M (D 3)), FBF (1, Psibar, SL, Psi), G_SL_DttL); ((M (D (-3)), O (Aux_top (0,0,-1,true,DR)), M (U 3)), FBF (1, Psibar, SR, Psi), Half); ((M (U (-3)), O (Aux_top (0,0,1,false,DR)), M (D 3)), FBF (1, Psibar, SLR, Psi), G_SLR_DbtR); ((M (D (-3)), O (Aux_top (0,0,-1,true,DL)), M (U 3)), FBF (1, Psibar, SL, Psi), Half); ((M (U (-3)), O (Aux_top (0,0,1,false,DL)), M (D 3)), FBF (1, Psibar, SL, Psi), G_SL_DbtL) ] else [] let vertices3 = (ThoList.flatmap electromagnetic_currents [1;2;3] @ ThoList.flatmap color_currents [1;2;3] @ ThoList.flatmap neutral_currents [1;2;3] @ (if Flags.ckm_present then charged_currents_ckm else charged_currents_triv) @ triple_gauge @ goldstone_vertices @ rsigma3 @ rsigma3t @ rphi3 @ rf3 @ rf3t @ rt3 @ anomalous_ttA @ anomalous_bbA @ anomalous_ttZ @ anomalous_bbZ @ anomalous_tbW @ anomalous_tbWA @ anomalous_tbWZ @ anomalous_ttWW @ anomalous_bbWW @ anomalous_ttG @ anomalous_ttGG @ anomalous_top_qGuG @ anomalous_top_qBuB @ anomalous_top_qW @ anomalous_top_DuDd) let vertices4 = quartic_gauge @ rsigma4 let vertices () = (vertices3, vertices4, []) (* For efficiency, make sure that [F.of_vertices vertices] is evaluated only once. *) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 let flavor_of_string = function | "e-" -> M (L 1) | "e+" -> M (L (-1)) | "mu-" -> M (L 2) | "mu+" -> M (L (-2)) | "tau-" -> M (L 3) | "tau+" -> M (L (-3)) | "nue" -> M (N 1) | "nuebar" -> M (N (-1)) | "numu" -> M (N 2) | "numubar" -> M (N (-2)) | "nutau" -> M (N 3) | "nutaubar" -> M (N (-3)) | "u" -> M (U 1) | "ubar" -> M (U (-1)) | "c" -> M (U 2) | "cbar" -> M (U (-2)) | "t" -> M (U 3) | "tbar" -> M (U (-3)) | "d" -> M (D 1) | "dbar" -> M (D (-1)) | "s" -> M (D 2) | "sbar" -> M (D (-2)) | "b" -> M (D 3) | "bbar" -> M (D (-3)) | "g" | "gl" -> G Gl | "A" -> G Ga | "Z" | "Z0" -> G Z | "W+" -> G Wp | "W-" -> G Wm | "Rsigma" -> O Rsigma | "Rphi0" -> O Rphin | "Rphi+" -> O Rphip | "Rphi-" -> O Rphim | "Rphi++" -> O Rphip | "Rphi--" -> O Rphimm | "Rf" -> O Rf | "Rt0" -> O Rtn | "Rt+" -> O Rtp | "Rt-" -> O Rtm | "Rt++" -> O Rtp | "Rt--" -> O Rtmm | "Aux_t_ttGG0" -> O (Aux_top (2,1, 0,true,TTGG)) | "Aux_ttGG0" -> O (Aux_top (2,1, 0,false,TTGG)) | "Aux_t_tbWA+" -> O (Aux_top (2,0, 1,true,TBWA)) | "Aux_tbWA+" -> O (Aux_top (2,0, 1,false,TBWA)) | "Aux_t_tbWA-" -> O (Aux_top (2,0,-1,true,TBWA)) | "Aux_tbWA-" -> O (Aux_top (2,0,-1,false,TBWA)) | "Aux_t_tbWZ+" -> O (Aux_top (2,0, 1,true,TBWZ)) | "Aux_tbWZ+" -> O (Aux_top (2,0, 1,false,TBWZ)) | "Aux_t_tbWZ-" -> O (Aux_top (2,0,-1,true,TBWZ)) | "Aux_tbWZ-" -> O (Aux_top (2,0,-1,false,TBWZ)) | "Aux_t_ttWW0" -> O (Aux_top (2,0, 0,true,TTWW)) | "Aux_ttWW0" -> O (Aux_top (2,0, 0,false,TTWW)) | "Aux_t_bbWW0" -> O (Aux_top (2,0, 0,true,BBWW)) | "Aux_bbWW0" -> O (Aux_top (2,0, 0,false,BBWW)) | "Aux_t_qGuG0" -> O (Aux_top (1,1, 0,true,QGUG)) | "Aux_qGuG0" -> O (Aux_top (1,1, 0,false,QGUG)) | "Aux_t_qBuB0" -> O (Aux_top (1,0, 0,true,QBUB)) | "Aux_qBuB0" -> O (Aux_top (1,0, 0,false,QBUB)) | "Aux_t_qW0" -> O (Aux_top (1,0, 0,true,QW)) | "Aux_qW0" -> O (Aux_top (1,0, 0,false,QW)) | "Aux_t_qW+" -> O (Aux_top (1,0, 1,true,QW)) | "Aux_qW+" -> O (Aux_top (1,0, 1,false,QW)) | "Aux_t_qW-" -> O (Aux_top (1,0,-1,true,QW)) | "Aux_qW-" -> O (Aux_top (1,0,-1,false,QW)) | "Aux_t_dL0" -> O (Aux_top (0,0, 0,true,DL)) | "Aux_dL0" -> O (Aux_top (0,0, 0,false,DL)) | "Aux_t_dL+" -> O (Aux_top (0,0, 1,true,DL)) | "Aux_dL+" -> O (Aux_top (0,0, 1,false,DL)) | "Aux_t_dL-" -> O (Aux_top (0,0,-1,true,DL)) | "Aux_dL-" -> O (Aux_top (0,0,-1,false,DL)) | "Aux_t_dR0" -> O (Aux_top (0,0, 0,true,DR)) | "Aux_dR0" -> O (Aux_top (0,0, 0,false,DR)) | "Aux_t_dR+" -> O (Aux_top (0,0, 1,true,DR)) | "Aux_dR+" -> O (Aux_top (0,0, 1,false,DR)) | "Aux_t_dR-" -> O (Aux_top (0,0,-1,true,DR)) | "Aux_dR-" -> O (Aux_top (0,0,-1,false,DR)) | _ -> invalid_arg "Modellib_NoH.AltH.flavor_of_string" let flavor_to_string = function | M f -> begin match f with | L 1 -> "e-" | L (-1) -> "e+" | L 2 -> "mu-" | L (-2) -> "mu+" | L 3 -> "tau-" | L (-3) -> "tau+" | L _ -> invalid_arg "Modellib_NoH.AltH.flavor_to_string: invalid lepton" | N 1 -> "nue" | N (-1) -> "nuebar" | N 2 -> "numu" | N (-2) -> "numubar" | N 3 -> "nutau" | N (-3) -> "nutaubar" | N _ -> invalid_arg "Modellib_NoH.AltH.flavor_to_string: invalid neutrino" | U 1 -> "u" | U (-1) -> "ubar" | U 2 -> "c" | U (-2) -> "cbar" | U 3 -> "t" | U (-3) -> "tbar" | U _ -> invalid_arg "Modellib_NoH.AltH.flavor_to_string: invalid up type quark" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | D _ -> invalid_arg "Modellib_NoH.AltH.flavor_to_string: invalid down type quark" end | G f -> begin match f with | Gl -> "gl" | Ga -> "A" | Z -> "Z" | Wp -> "W+" | Wm -> "W-" end | O f -> begin match f with | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | Rsigma -> "Rsigma" | Rphin -> "Rphin" | Rphip -> "Rphi+" | Rphim -> "Rphi-" | Rphipp -> "Rphi++" | Rphimm -> "Rphi--" | Rf -> "Rf" | Rtn -> "Rtn" | Rtp -> "Rt+" | Rtm -> "Rt-" | Rtpp -> "Rt++" | Rtmm -> "Rt--" | Aux_top (_,_,ch,n,v) -> "Aux_" ^ (if n then "t_" else "") ^ ( begin match v with | TTGG -> "ttGG" | TBWA -> "tbWA" | TBWZ -> "tbWZ" | TTWW -> "ttWW" | BBWW -> "bbWW" | QGUG -> "qGuG" | QBUB -> "qBuB" | QW -> "qW" | DL -> "dL" | DR -> "dR" end ) ^ ( if ch > 0 then "+" else if ch < 0 then "-" else "0" ) end let flavor_to_TeX = function | M f -> begin match f with | L 1 -> "e^-" | L (-1) -> "e^+" | L 2 -> "\\mu^-" | L (-2) -> "\\mu^+" | L 3 -> "\\tau^-" | L (-3) -> "\\tau^+" | L _ -> invalid_arg "Modellib_NoH.AltH.flavor_to_TeX: invalid lepton" | N 1 -> "\\nu_e" | N (-1) -> "\\bar{\\nu}_e" | N 2 -> "\\nu_\\mu" | N (-2) -> "\\bar{\\nu}_\\mu" | N 3 -> "\\nu_\\tau" | N (-3) -> "\\bar{\\nu}_\\tau" | N _ -> invalid_arg "Modellib_NoH.AltH.flavor_to_TeX: invalid neutrino" | U 1 -> "u" | U (-1) -> "\\bar{u}" | U 2 -> "c" | U (-2) -> "\\bar{c}" | U 3 -> "t" | U (-3) -> "\\bar{t}" | U _ -> invalid_arg "Modellib_NoH.AltH.flavor_to_TeX: invalid up type quark" | D 1 -> "d" | D (-1) -> "\\bar{d}" | D 2 -> "s" | D (-2) -> "\\bar{s}" | D 3 -> "b" | D (-3) -> "\\bar{b}" | D _ -> invalid_arg "Modellib_NoH.AltH.flavor_to_TeX: invalid down type quark" end | G f -> begin match f with | Gl -> "g" | Ga -> "\\gamma" | Z -> "Z" | Wp -> "W^+" | Wm -> "W^-" end | O f -> begin match f with | Phip -> "\\phi^+" | Phim -> "\\phi^-" | Phi0 -> "\\phi^0" | Rsigma -> "\\sigma" | Rphip -> "\\phi^+" | Rphim -> "\\phi^-" | Rphin -> "\\phi^0" | Rphipp -> "\\phi^{++}" | Rphimm -> "\\phi^{--}" | Rf -> "f" | Rtp -> "t^+" | Rtm -> "t^-" | Rtn -> "t^0" | Rtpp -> "t^{++}" | Rtmm -> "t^{--}" | Aux_top (_,_,ch,n,v) -> "\\textnormal{Aux_" ^ (if n then "t_" else "") ^ ( begin match v with | TTGG -> "ttGG" | TBWA -> "tbWA" | TBWZ -> "tbWZ" | TTWW -> "ttWW" | BBWW -> "bbWW" | QGUG -> "qGuG" | QBUB -> "qBuB" | QW -> "qW" | DL -> "dL" | DR -> "dR" end ) ^ ( if ch > 0 then "^+" else if ch < 0 then "^-" else "^0" ) ^ "}" end let flavor_symbol = function | M f -> begin match f with | L n when n > 0 -> "l" ^ string_of_int n | L n -> "l" ^ string_of_int (abs n) ^ "b" | N n when n > 0 -> "n" ^ string_of_int n | N n -> "n" ^ string_of_int (abs n) ^ "b" | U n when n > 0 -> "u" ^ string_of_int n | U n -> "u" ^ string_of_int (abs n) ^ "b" | D n when n > 0 -> "d" ^ string_of_int n | D n -> "d" ^ string_of_int (abs n) ^ "b" end | G f -> begin match f with | Gl -> "gl" | Ga -> "a" | Z -> "z" | Wp -> "wp" | Wm -> "wm" end | O f -> begin match f with | Phip -> "pp" | Phim -> "pm" | Phi0 -> "p0" | Rsigma -> "rsi" | Rphip -> "rpp" | Rphim -> "rpm" | Rphin -> "rpn" | Rphipp -> "rppp" | Rphimm -> "rpmm" | Rf -> "rf" | Rtp -> "rtp" | Rtm -> "rtm" | Rtn -> "rtn" | Rtpp -> "rtpp" | Rtmm -> "rtmm" | Aux_top (_,_,ch,n,v) -> "aux_" ^ (if n then "t_" else "") ^ ( begin match v with | TTGG -> "ttgg" | TBWA -> "tbwa" | TBWZ -> "tbwz" | TTWW -> "ttww" | BBWW -> "bbww" | QGUG -> "qgug" | QBUB -> "qbub" | QW -> "qw" | DL -> "dl" | DR -> "dr" end ) ^ "_" ^ ( if ch > 0 then "p" else if ch < 0 then "m" else "0" ) end (* Introducing new Resonances from 45, there are no PDG values *) let pdg = function | M f -> begin match f with | L n when n > 0 -> 9 + 2*n | L n -> - 9 + 2*n | N n when n > 0 -> 10 + 2*n | N n -> - 10 + 2*n | U n when n > 0 -> 2*n | U n -> 2*n | D n when n > 0 -> - 1 + 2*n | D n -> 1 + 2*n end | G f -> begin match f with | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) end | O f -> begin match f with | Phip | Phim -> 27 | Phi0 -> 26 | Rsigma -> 45 | Rphin -> 46 | Rphip | Rphim -> 47 | Rphipp | Rphimm -> 48 | Rf -> 52 | Rtn -> 53 | Rtp | Rtm -> 54 | Rtpp | Rtmm -> 55 | Aux_top (_,_,_,_,_) -> 81 end let mass_symbol f = "mass(" ^ string_of_int (abs (pdg f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg f)) ^ ")" let constant_symbol = function | Unit -> "unit" | Half -> "half" | Pi -> "PI" | Alpha_QED -> "alpha" | E -> "e" | G_weak -> "g" | Vev -> "vev" | I_G_weak -> "ig" | Sin2thw -> "sin2thw" | Sinthw -> "sinthw" | Costhw -> "costhw" | Q_lepton -> "qlep" | Q_up -> "qup" | Q_down -> "qdwn" | G_NC_lepton -> "gnclep" | G_NC_neutrino -> "gncneu" | G_NC_up -> "gncup" | G_NC_down -> "gncdwn" | G_TVA_ttA -> "gtva_tta" | G_TVA_bbA -> "gtva_bba" | G_VLR_ttZ -> "gvlr_ttz" | G_TVA_ttZ -> "gtva_ttz" | G_TVA_bbZ -> "gtva_bbz" | G_VLR_btW -> "gvlr_btw" | G_VLR_tbW -> "gvlr_tbw" | G_TLR_btW -> "gtlr_btw" | G_TRL_tbW -> "gtrl_tbw" | G_TLR_btWA -> "gtlr_btwa" | G_TRL_tbWA -> "gtrl_tbwa" | G_TLR_btWZ -> "gtlr_btwz" | G_TRL_tbWZ -> "gtrl_tbwz" | G_TVA_ttWW -> "gtva_ttww" | G_TVA_bbWW -> "gtva_bbww" | G_TVA_ttG -> "gtva_ttg" | G_TVA_ttGG -> "gtva_ttgg" | G_VLR_qGuG -> "gvlr_qgug" | G_VLR_qBuB -> "gvlr_qbub" | G_VLR_qBuB_u -> "gvlr_qbub_u" | G_VLR_qBuB_d -> "gvlr_qbub_d" | G_VLR_qBuB_e -> "gvlr_qbub_e" | G_VL_qBuB_n -> "gvl_qbub_n" | G_VL_qW -> "gvl_qw" | G_VL_qW_u -> "gvl_qw_u" | G_VL_qW_d -> "gvl_qw_d" | G_SL_DttR -> "gsl_dttr" | G_SR_DttR -> "gsr_dttr" | G_SL_DttL -> "gsl_dttl" | G_SLR_DbtR -> "gslr_dbtr" | G_SL_DbtL -> "gsl_dbtl" | G_CC -> "gcc" | G_CCQ (n1,n2) -> "gccq" ^ string_of_int n1 ^ string_of_int n2 | I_Q_W -> "iqw" | I_G_ZWW -> "igzww" | G_WWWW -> "gw4" | G_ZZWW -> "gzzww" | G_AZWW -> "gazww" | G_AAWW -> "gaaww" | I_G1_AWW -> "ig1a" | I_G1_ZWW -> "ig1z" | I_G1_plus_kappa_plus_G4_AWW -> "ig1pkpg4a" | I_G1_plus_kappa_plus_G4_ZWW -> "ig1pkpg4z" | I_G1_plus_kappa_minus_G4_AWW -> "ig1pkmg4a" | I_G1_plus_kappa_minus_G4_ZWW -> "ig1pkmg4z" | I_G1_minus_kappa_plus_G4_AWW -> "ig1mkpg4a" | I_G1_minus_kappa_plus_G4_ZWW -> "ig1mkpg4z" | I_G1_minus_kappa_minus_G4_AWW -> "ig1mkmg4a" | I_G1_minus_kappa_minus_G4_ZWW -> "ig1mkmg4z" | I_lambda_AWW -> "ila" | I_lambda_ZWW -> "ilz" | G5_AWW -> "rg5a" | G5_ZWW -> "rg5z" | I_kappa5_AWW -> "ik5a" | I_kappa5_ZWW -> "ik5z" | I_lambda5_AWW -> "il5a" | I_lambda5_ZWW -> "il5z" | Alpha_WWWW0 -> "alww0" | Alpha_WWWW2 -> "alww2" | Alpha_ZZWW0 -> "alzw0" | Alpha_ZZWW1 -> "alzw1" | Alpha_ZZZZ -> "alzz" | D_Alpha_ZZWW0_S -> "dalzz0_s(gkm,mkm," | D_Alpha_ZZWW0_T -> "dalzz0_t(gkm,mkm," | D_Alpha_ZZWW1_S -> "dalzz1_s(gkm,mkm," | D_Alpha_ZZWW1_T -> "dalzz1_t(gkm,mkm," | D_Alpha_ZZWW1_U -> "dalzz1_u(gkm,mkm," | D_Alpha_WWWW0_S -> "dalww0_s(gkm,mkm," | D_Alpha_WWWW0_T -> "dalww0_t(gkm,mkm," | D_Alpha_WWWW0_U -> "dalww0_u(gkm,mkm," | D_Alpha_WWWW2_S -> "dalww2_s(gkm,mkm," | D_Alpha_WWWW2_T -> "dalww2_t(gkm,mkm," | D_Alpha_ZZZZ_S -> "dalz4_s(gkm,mkm," | D_Alpha_ZZZZ_T -> "dalz4_t(gkm,mkm," | G_SWW -> "gsww" | G_SZZ -> "gszz" | G_SWW_T -> "gswwt" | G_SZZ_T -> "gszzt" | G_PNWW -> "gpnww" | G_PNZZ -> "gpnzz" | G_PWZ -> "gpwz" | G_PWW -> "gpww" | G_FWW -> "gfww" | G_FZZ -> "gfzz" | G_FWW_T -> "gfwwt" | G_FZZ_T -> "gfzzt" | G_TNWW -> "gtnww" | G_TNZZ -> "gtnzz" | G_TWZ -> "gtwz" | G_TWW -> "gtww" | G_SSWW -> "gssww" | G_SSZZ -> "gsszz" | Gs -> "gs" | I_Gs -> "igs" | G2 -> "gs**2" | Mass f -> "mass" ^ flavor_symbol f | Width f -> "width" ^ flavor_symbol f | K_Matrix_Coeff i -> "kc" ^ string_of_int i | K_Matrix_Pole i -> "kp" ^ string_of_int i end Index: trunk/omega/src/omegalib.nw =================================================================== --- trunk/omega/src/omegalib.nw (revision 8413) +++ trunk/omega/src/omegalib.nw (revision 8414) @@ -1,14097 +1,14119 @@ % -*- ess-noweb-default-code-mode: f90-mode; noweb-default-code-mode: f90-mode; -*- % omegalib.nw -- % % Copyright (C) 1999-2020 by % Wolfgang Kilian % Thorsten Ohl % Juergen Reuter % with contributions from % Fabian Bach % Bijan Chokoufe Nejad % Marco Sekulla % Christian Speckner % % WHIZARD is free software; you can redistribute it and/or modify it % under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2, or (at your option) % any later version. % % WHIZARD is distributed in the hope that it will be useful, but % WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @ \section{Trivia} <<[[omega_spinors.f90]]>>= <> module omega_spinors use kinds use constants implicit none private public :: operator (*), operator (+), operator (-) public :: abs <<[[intrinsic :: abs]]>> type, public :: conjspinor ! private (omegalib needs access, but DON'T TOUCH IT!) complex(kind=default), dimension(4) :: a end type conjspinor type, public :: spinor ! private (omegalib needs access, but DON'T TOUCH IT!) complex(kind=default), dimension(4) :: a end type spinor <> integer, parameter, public :: omega_spinors_2010_01_A = 0 contains <> end module omega_spinors @ <<[[intrinsic :: abs]] (if working)>>= intrinsic :: abs @ <<[[intrinsic :: conjg]] (if working)>>= intrinsic :: conjg @ well, the Intel Fortran Compiler chokes on these with an internal error: <<[[intrinsic :: abs]]>>= @ <<[[intrinsic :: conjg]]>>= @ To reenable the pure functions that have been removed for OpenMP, one should set this chunk to [[pure &]] <<[[pure]] unless OpenMP>>= @ \subsection{Inner Product} <>= interface operator (*) module procedure conjspinor_spinor end interface private :: conjspinor_spinor @ \begin{equation} \bar\psi\psi' \end{equation} NB: [[dot_product]] conjugates its first argument, we can either cancel this or inline [[dot_product]]: <>= pure function conjspinor_spinor (psibar, psi) result (psibarpsi) complex(kind=default) :: psibarpsi type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi psibarpsi = psibar%a(1)*psi%a(1) + psibar%a(2)*psi%a(2) & + psibar%a(3)*psi%a(3) + psibar%a(4)*psi%a(4) end function conjspinor_spinor @ \subsection{Spinor Vector Space} \subsubsection{Scalar Multiplication} <>= interface operator (*) module procedure integer_spinor, spinor_integer, & real_spinor, double_spinor, & complex_spinor, dcomplex_spinor, & spinor_real, spinor_double, & spinor_complex, spinor_dcomplex end interface private :: integer_spinor, spinor_integer, real_spinor, & double_spinor, complex_spinor, dcomplex_spinor, & spinor_real, spinor_double, spinor_complex, spinor_dcomplex @ <>= pure function integer_spinor (x, y) result (xy) integer, intent(in) :: x type(spinor), intent(in) :: y type(spinor) :: xy xy%a = x * y%a end function integer_spinor @ <>= pure function real_spinor (x, y) result (xy) real(kind=single), intent(in) :: x type(spinor), intent(in) :: y type(spinor) :: xy xy%a = x * y%a end function real_spinor pure function double_spinor (x, y) result (xy) real(kind=default), intent(in) :: x type(spinor), intent(in) :: y type(spinor) :: xy xy%a = x * y%a end function double_spinor pure function complex_spinor (x, y) result (xy) complex(kind=single), intent(in) :: x type(spinor), intent(in) :: y type(spinor) :: xy xy%a = x * y%a end function complex_spinor pure function dcomplex_spinor (x, y) result (xy) complex(kind=default), intent(in) :: x type(spinor), intent(in) :: y type(spinor) :: xy xy%a = x * y%a end function dcomplex_spinor pure function spinor_integer (y, x) result (xy) integer, intent(in) :: x type(spinor), intent(in) :: y type(spinor) :: xy xy%a = x * y%a end function spinor_integer pure function spinor_real (y, x) result (xy) real(kind=single), intent(in) :: x type(spinor), intent(in) :: y type(spinor) :: xy xy%a = x * y%a end function spinor_real pure function spinor_double (y, x) result (xy) real(kind=default), intent(in) :: x type(spinor), intent(in) :: y type(spinor) :: xy xy%a = x * y%a end function spinor_double pure function spinor_complex (y, x) result (xy) complex(kind=single), intent(in) :: x type(spinor), intent(in) :: y type(spinor) :: xy xy%a = x * y%a end function spinor_complex pure function spinor_dcomplex (y, x) result (xy) complex(kind=default), intent(in) :: x type(spinor), intent(in) :: y type(spinor) :: xy xy%a = x * y%a end function spinor_dcomplex @ <>= interface operator (*) module procedure integer_conjspinor, conjspinor_integer, & real_conjspinor, double_conjspinor, & complex_conjspinor, dcomplex_conjspinor, & conjspinor_real, conjspinor_double, & conjspinor_complex, conjspinor_dcomplex end interface private :: integer_conjspinor, conjspinor_integer, real_conjspinor, & double_conjspinor, complex_conjspinor, dcomplex_conjspinor, & conjspinor_real, conjspinor_double, conjspinor_complex, & conjspinor_dcomplex @ <>= pure function integer_conjspinor (x, y) result (xy) integer, intent(in) :: x type(conjspinor), intent(in) :: y type(conjspinor) :: xy xy%a = x * y%a end function integer_conjspinor pure function real_conjspinor (x, y) result (xy) real(kind=single), intent(in) :: x type(conjspinor), intent(in) :: y type(conjspinor) :: xy xy%a = x * y%a end function real_conjspinor pure function double_conjspinor (x, y) result (xy) real(kind=default), intent(in) :: x type(conjspinor), intent(in) :: y type(conjspinor) :: xy xy%a = x * y%a end function double_conjspinor pure function complex_conjspinor (x, y) result (xy) complex(kind=single), intent(in) :: x type(conjspinor), intent(in) :: y type(conjspinor) :: xy xy%a = x * y%a end function complex_conjspinor pure function dcomplex_conjspinor (x, y) result (xy) complex(kind=default), intent(in) :: x type(conjspinor), intent(in) :: y type(conjspinor) :: xy xy%a = x * y%a end function dcomplex_conjspinor pure function conjspinor_integer (y, x) result (xy) integer, intent(in) :: x type(conjspinor), intent(in) :: y type(conjspinor) :: xy xy%a = x * y%a end function conjspinor_integer pure function conjspinor_real (y, x) result (xy) real(kind=single), intent(in) :: x type(conjspinor), intent(in) :: y type(conjspinor) :: xy xy%a = x * y%a end function conjspinor_real pure function conjspinor_double (y, x) result (xy) real(kind=default), intent(in) :: x type(conjspinor), intent(in) :: y type(conjspinor) :: xy xy%a = x * y%a end function conjspinor_double pure function conjspinor_complex (y, x) result (xy) complex(kind=single), intent(in) :: x type(conjspinor), intent(in) :: y type(conjspinor) :: xy xy%a = x * y%a end function conjspinor_complex pure function conjspinor_dcomplex (y, x) result (xy) complex(kind=default), intent(in) :: x type(conjspinor), intent(in) :: y type(conjspinor) :: xy xy%a = x * y%a end function conjspinor_dcomplex @ \subsubsection{Unary Plus and Minus} <>= interface operator (+) module procedure plus_spinor, plus_conjspinor end interface private :: plus_spinor, plus_conjspinor interface operator (-) module procedure neg_spinor, neg_conjspinor end interface private :: neg_spinor, neg_conjspinor @ <>= pure function plus_spinor (x) result (plus_x) type(spinor), intent(in) :: x type(spinor) :: plus_x plus_x%a = x%a end function plus_spinor pure function neg_spinor (x) result (neg_x) type(spinor), intent(in) :: x type(spinor) :: neg_x neg_x%a = - x%a end function neg_spinor @ <>= pure function plus_conjspinor (x) result (plus_x) type(conjspinor), intent(in) :: x type(conjspinor) :: plus_x plus_x%a = x%a end function plus_conjspinor pure function neg_conjspinor (x) result (neg_x) type(conjspinor), intent(in) :: x type(conjspinor) :: neg_x neg_x%a = - x%a end function neg_conjspinor @ \subsubsection{Addition and Subtraction} <>= interface operator (+) module procedure add_spinor, add_conjspinor end interface private :: add_spinor, add_conjspinor interface operator (-) module procedure sub_spinor, sub_conjspinor end interface private :: sub_spinor, sub_conjspinor @ <>= pure function add_spinor (x, y) result (xy) type(spinor), intent(in) :: x, y type(spinor) :: xy xy%a = x%a + y%a end function add_spinor pure function sub_spinor (x, y) result (xy) type(spinor), intent(in) :: x, y type(spinor) :: xy xy%a = x%a - y%a end function sub_spinor @ <>= pure function add_conjspinor (x, y) result (xy) type(conjspinor), intent(in) :: x, y type(conjspinor) :: xy xy%a = x%a + y%a end function add_conjspinor pure function sub_conjspinor (x, y) result (xy) type(conjspinor), intent(in) :: x, y type(conjspinor) :: xy xy%a = x%a - y%a end function sub_conjspinor @ \subsection{Norm} <>= interface abs module procedure abs_spinor, abs_conjspinor end interface private :: abs_spinor, abs_conjspinor @ <>= pure function abs_spinor (psi) result (x) type(spinor), intent(in) :: psi real(kind=default) :: x x = sqrt (real (dot_product (psi%a, psi%a))) end function abs_spinor @ <>= pure function abs_conjspinor (psibar) result (x) real(kind=default) :: x type(conjspinor), intent(in) :: psibar x = sqrt (real (dot_product (psibar%a, psibar%a))) end function abs_conjspinor @ \section{Spinors Revisited} <<[[omega_bispinors.f90]]>>= <> module omega_bispinors use kinds use constants implicit none private public :: operator (*), operator (+), operator (-) public :: abs type, public :: bispinor ! private (omegalib needs access, but DON'T TOUCH IT!) complex(kind=default), dimension(4) :: a end type bispinor <> integer, parameter, public :: omega_bispinors_2010_01_A = 0 contains <> end module omega_bispinors @ <>= interface operator (*) module procedure spinor_product end interface private :: spinor_product @ \begin{equation} \bar\psi\psi' \end{equation} NB: [[dot_product]] conjugates its first argument, we have to cancel this. <>= pure function spinor_product (psil, psir) result (psilpsir) complex(kind=default) :: psilpsir type(bispinor), intent(in) :: psil, psir type(bispinor) :: psidum psidum%a(1) = psir%a(2) psidum%a(2) = - psir%a(1) psidum%a(3) = - psir%a(4) psidum%a(4) = psir%a(3) psilpsir = dot_product (conjg (psil%a), psidum%a) end function spinor_product @ \subsection{Spinor Vector Space} \subsubsection{Scalar Multiplication} <>= interface operator (*) module procedure integer_bispinor, bispinor_integer, & real_bispinor, double_bispinor, & complex_bispinor, dcomplex_bispinor, & bispinor_real, bispinor_double, & bispinor_complex, bispinor_dcomplex end interface private :: integer_bispinor, bispinor_integer, real_bispinor, & double_bispinor, complex_bispinor, dcomplex_bispinor, & bispinor_real, bispinor_double, bispinor_complex, bispinor_dcomplex @ <>= pure function integer_bispinor (x, y) result (xy) type(bispinor) :: xy integer, intent(in) :: x type(bispinor), intent(in) :: y xy%a = x * y%a end function integer_bispinor @ <>= pure function real_bispinor (x, y) result (xy) type(bispinor) :: xy real(kind=single), intent(in) :: x type(bispinor), intent(in) :: y xy%a = x * y%a end function real_bispinor @ <>= pure function double_bispinor (x, y) result (xy) type(bispinor) :: xy real(kind=default), intent(in) :: x type(bispinor), intent(in) :: y xy%a = x * y%a end function double_bispinor @ <>= pure function complex_bispinor (x, y) result (xy) type(bispinor) :: xy complex(kind=single), intent(in) :: x type(bispinor), intent(in) :: y xy%a = x * y%a end function complex_bispinor @ <>= pure function dcomplex_bispinor (x, y) result (xy) type(bispinor) :: xy complex(kind=default), intent(in) :: x type(bispinor), intent(in) :: y xy%a = x * y%a end function dcomplex_bispinor @ <>= pure function bispinor_integer (y, x) result (xy) type(bispinor) :: xy integer, intent(in) :: x type(bispinor), intent(in) :: y xy%a = x * y%a end function bispinor_integer @ <>= pure function bispinor_real (y, x) result (xy) type(bispinor) :: xy real(kind=single), intent(in) :: x type(bispinor), intent(in) :: y xy%a = x * y%a end function bispinor_real @ <>= pure function bispinor_double (y, x) result (xy) type(bispinor) :: xy real(kind=default), intent(in) :: x type(bispinor), intent(in) :: y xy%a = x * y%a end function bispinor_double @ <>= pure function bispinor_complex (y, x) result (xy) type(bispinor) :: xy complex(kind=single), intent(in) :: x type(bispinor), intent(in) :: y xy%a = x * y%a end function bispinor_complex @ <>= pure function bispinor_dcomplex (y, x) result (xy) type(bispinor) :: xy complex(kind=default), intent(in) :: x type(bispinor), intent(in) :: y xy%a = x * y%a end function bispinor_dcomplex @ \subsubsection{Unary Plus and Minus} <>= interface operator (+) module procedure plus_bispinor end interface private :: plus_bispinor interface operator (-) module procedure neg_bispinor end interface private :: neg_bispinor @ <>= pure function plus_bispinor (x) result (plus_x) type(bispinor) :: plus_x type(bispinor), intent(in) :: x plus_x%a = x%a end function plus_bispinor @ <>= pure function neg_bispinor (x) result (neg_x) type(bispinor) :: neg_x type(bispinor), intent(in) :: x neg_x%a = - x%a end function neg_bispinor @ \subsubsection{Addition and Subtraction} <>= interface operator (+) module procedure add_bispinor end interface private :: add_bispinor interface operator (-) module procedure sub_bispinor end interface private :: sub_bispinor @ <>= pure function add_bispinor (x, y) result (xy) type(bispinor) :: xy type(bispinor), intent(in) :: x, y xy%a = x%a + y%a end function add_bispinor @ <>= pure function sub_bispinor (x, y) result (xy) type(bispinor) :: xy type(bispinor), intent(in) :: x, y xy%a = x%a - y%a end function sub_bispinor @ \subsection{Norm} <>= interface abs module procedure abs_bispinor end interface private :: abs_bispinor @ <>= pure function abs_bispinor (psi) result (x) real(kind=default) :: x type(bispinor), intent(in) :: psi x = sqrt (real (dot_product (psi%a, psi%a))) end function abs_bispinor @ \section{Vectorspinors} <<[[omega_vectorspinors.f90]]>>= <> module omega_vectorspinors use kinds use constants use omega_bispinors use omega_vectors implicit none private public :: operator (*), operator (+), operator (-) public :: abs type, public :: vectorspinor ! private (omegalib needs access, but DON'T TOUCH IT!) type(bispinor), dimension(4) :: psi end type vectorspinor <> integer, parameter, public :: omega_vectorspinors_2010_01_A = 0 contains <> end module omega_vectorspinors @ <>= interface operator (*) module procedure vspinor_product end interface private :: vspinor_product @ \begin{equation} \bar\psi^\mu\psi'_\mu \end{equation} <>= pure function vspinor_product (psil, psir) result (psilpsir) complex(kind=default) :: psilpsir type(vectorspinor), intent(in) :: psil, psir psilpsir = psil%psi(1) * psir%psi(1) & - psil%psi(2) * psir%psi(2) & - psil%psi(3) * psir%psi(3) & - psil%psi(4) * psir%psi(4) end function vspinor_product @ \subsection{Vectorspinor Vector Space} \subsubsection{Scalar Multiplication} <>= interface operator (*) module procedure integer_vectorspinor, vectorspinor_integer, & real_vectorspinor, double_vectorspinor, & complex_vectorspinor, dcomplex_vectorspinor, & vectorspinor_real, vectorspinor_double, & vectorspinor_complex, vectorspinor_dcomplex, & momentum_vectorspinor, vectorspinor_momentum end interface private :: integer_vectorspinor, vectorspinor_integer, real_vectorspinor, & double_vectorspinor, complex_vectorspinor, dcomplex_vectorspinor, & vectorspinor_real, vectorspinor_double, vectorspinor_complex, & vectorspinor_dcomplex @ <>= pure function integer_vectorspinor (x, y) result (xy) type(vectorspinor) :: xy integer, intent(in) :: x type(vectorspinor), intent(in) :: y integer :: k do k = 1,4 xy%psi(k) = x * y%psi(k) end do end function integer_vectorspinor @ <>= pure function real_vectorspinor (x, y) result (xy) type(vectorspinor) :: xy real(kind=single), intent(in) :: x type(vectorspinor), intent(in) :: y integer :: k do k = 1,4 xy%psi(k) = x * y%psi(k) end do end function real_vectorspinor @ <>= pure function double_vectorspinor (x, y) result (xy) type(vectorspinor) :: xy real(kind=default), intent(in) :: x type(vectorspinor), intent(in) :: y integer :: k do k = 1,4 xy%psi(k) = x * y%psi(k) end do end function double_vectorspinor @ <>= pure function complex_vectorspinor (x, y) result (xy) type(vectorspinor) :: xy complex(kind=single), intent(in) :: x type(vectorspinor), intent(in) :: y integer :: k do k = 1,4 xy%psi(k) = x * y%psi(k) end do end function complex_vectorspinor @ <>= pure function dcomplex_vectorspinor (x, y) result (xy) type(vectorspinor) :: xy complex(kind=default), intent(in) :: x type(vectorspinor), intent(in) :: y integer :: k do k = 1,4 xy%psi(k) = x * y%psi(k) end do end function dcomplex_vectorspinor @ <>= pure function vectorspinor_integer (y, x) result (xy) type(vectorspinor) :: xy integer, intent(in) :: x type(vectorspinor), intent(in) :: y integer :: k do k = 1,4 xy%psi(k) = y%psi(k) * x end do end function vectorspinor_integer @ <>= pure function vectorspinor_real (y, x) result (xy) type(vectorspinor) :: xy real(kind=single), intent(in) :: x type(vectorspinor), intent(in) :: y integer :: k do k = 1,4 xy%psi(k) = y%psi(k) * x end do end function vectorspinor_real @ <>= pure function vectorspinor_double (y, x) result (xy) type(vectorspinor) :: xy real(kind=default), intent(in) :: x type(vectorspinor), intent(in) :: y integer :: k do k = 1,4 xy%psi(k) = y%psi(k) * x end do end function vectorspinor_double @ <>= pure function vectorspinor_complex (y, x) result (xy) type(vectorspinor) :: xy complex(kind=single), intent(in) :: x type(vectorspinor), intent(in) :: y integer :: k do k = 1,4 xy%psi(k) = y%psi(k) * x end do end function vectorspinor_complex @ <>= pure function vectorspinor_dcomplex (y, x) result (xy) type(vectorspinor) :: xy complex(kind=default), intent(in) :: x type(vectorspinor), intent(in) :: y integer :: k do k = 1,4 xy%psi(k) = y%psi(k) * x end do end function vectorspinor_dcomplex @ <>= pure function momentum_vectorspinor (y, x) result (xy) type(bispinor) :: xy type(momentum), intent(in) :: y type(vectorspinor), intent(in) :: x integer :: k do k = 1,4 xy%a(k) = y%t * x%psi(1)%a(k) - y%x(1) * x%psi(2)%a(k) - & y%x(2) * x%psi(3)%a(k) - y%x(3) * x%psi(4)%a(k) end do end function momentum_vectorspinor @ <>= pure function vectorspinor_momentum (y, x) result (xy) type(bispinor) :: xy type(momentum), intent(in) :: x type(vectorspinor), intent(in) :: y integer :: k do k = 1,4 xy%a(k) = x%t * y%psi(1)%a(k) - x%x(1) * y%psi(2)%a(k) - & x%x(2) * y%psi(3)%a(k) - x%x(3) * y%psi(4)%a(k) end do end function vectorspinor_momentum @ \subsubsection{Unary Plus and Minus} <>= interface operator (+) module procedure plus_vectorspinor end interface private :: plus_vectorspinor interface operator (-) module procedure neg_vectorspinor end interface private :: neg_vectorspinor @ <>= pure function plus_vectorspinor (x) result (plus_x) type(vectorspinor) :: plus_x type(vectorspinor), intent(in) :: x integer :: k do k = 1,4 plus_x%psi(k) = + x%psi(k) end do end function plus_vectorspinor @ <>= pure function neg_vectorspinor (x) result (neg_x) type(vectorspinor) :: neg_x type(vectorspinor), intent(in) :: x integer :: k do k = 1,4 neg_x%psi(k) = - x%psi(k) end do end function neg_vectorspinor @ \subsubsection{Addition and Subtraction} <>= interface operator (+) module procedure add_vectorspinor end interface private :: add_vectorspinor interface operator (-) module procedure sub_vectorspinor end interface private :: sub_vectorspinor @ <>= pure function add_vectorspinor (x, y) result (xy) type(vectorspinor) :: xy type(vectorspinor), intent(in) :: x, y integer :: k do k = 1,4 xy%psi(k) = x%psi(k) + y%psi(k) end do end function add_vectorspinor @ <>= pure function sub_vectorspinor (x, y) result (xy) type(vectorspinor) :: xy type(vectorspinor), intent(in) :: x, y integer :: k do k = 1,4 xy%psi(k) = x%psi(k) - y%psi(k) end do end function sub_vectorspinor @ \subsection{Norm} <>= interface abs module procedure abs_vectorspinor end interface private :: abs_vectorspinor @ <>= pure function abs_vectorspinor (psi) result (x) real(kind=default) :: x type(vectorspinor), intent(in) :: psi x = sqrt (real (dot_product (psi%psi(1)%a, psi%psi(1)%a) & - dot_product (psi%psi(2)%a, psi%psi(2)%a) & - dot_product (psi%psi(3)%a, psi%psi(3)%a) & - dot_product (psi%psi(4)%a, psi%psi(4)%a))) end function abs_vectorspinor @ \section{Vectors and Tensors} Condensed representation of antisymmetric rank-2 tensors: \begin{equation} \begin{pmatrix} T^{00} & T^{01} & T^{02} & T^{03} \\ T^{10} & T^{11} & T^{12} & T^{13} \\ T^{20} & T^{21} & T^{22} & T^{23} \\ T^{30} & T^{31} & T^{32} & T^{33} \end{pmatrix} = \begin{pmatrix} 0 & T_e^1 & T_e^2 & T_e^3 \\ -T_e^1 & 0 & T_b^3 & -T_b^2 \\ -T_e^2 & -T_b^3 & 0 & T_b^1 \\ -T_e^3 & T_b^2 & -T_b^1 & 0 \end{pmatrix} \end{equation} <<[[omega_vectors.f90]]>>= <> module omega_vectors use kinds use constants implicit none private public :: assignment (=), operator(==) public :: operator (*), operator (+), operator (-), operator (.wedge.) public :: abs, conjg public :: random_momentum <<[[intrinsic :: abs]]>> <<[[intrinsic :: conjg]]>> type, public :: momentum ! private (omegalib needs access, but DON'T TOUCH IT!) real(kind=default) :: t real(kind=default), dimension(3) :: x end type momentum type, public :: vector ! private (omegalib needs access, but DON'T TOUCH IT!) complex(kind=default) :: t complex(kind=default), dimension(3) :: x end type vector type, public :: tensor2odd ! private (omegalib needs access, but DON'T TOUCH IT!) complex(kind=default), dimension(3) :: e complex(kind=default), dimension(3) :: b end type tensor2odd <> integer, parameter, public :: omega_vectors_2010_01_A = 0 contains <> end module omega_vectors @ \subsection{Constructors} <>= interface assignment (=) module procedure momentum_of_array, vector_of_momentum, & vector_of_array, vector_of_double_array, & array_of_momentum, array_of_vector end interface private :: momentum_of_array, vector_of_momentum, vector_of_array, & vector_of_double_array, array_of_momentum, array_of_vector @ <>= pure subroutine momentum_of_array (m, p) type(momentum), intent(out) :: m real(kind=default), dimension(0:), intent(in) :: p m%t = p(0) m%x = p(1:3) end subroutine momentum_of_array pure subroutine array_of_momentum (p, v) real(kind=default), dimension(0:), intent(out) :: p type(momentum), intent(in) :: v p(0) = v%t p(1:3) = v%x end subroutine array_of_momentum @ <>= pure subroutine vector_of_array (v, p) type(vector), intent(out) :: v complex(kind=default), dimension(0:), intent(in) :: p v%t = p(0) v%x = p(1:3) end subroutine vector_of_array pure subroutine vector_of_double_array (v, p) type(vector), intent(out) :: v real(kind=default), dimension(0:), intent(in) :: p v%t = p(0) v%x = p(1:3) end subroutine vector_of_double_array pure subroutine array_of_vector (p, v) complex(kind=default), dimension(0:), intent(out) :: p type(vector), intent(in) :: v p(0) = v%t p(1:3) = v%x end subroutine array_of_vector @ <>= pure subroutine vector_of_momentum (v, p) type(vector), intent(out) :: v type(momentum), intent(in) :: p v%t = p%t v%x = p%x end subroutine vector_of_momentum @ <>= interface operator(==) module procedure momentum_eq end interface @ <>= elemental function momentum_eq (lhs, rhs) result (yorn) logical :: yorn type(momentum), intent(in) :: lhs type(momentum), intent(in) :: rhs yorn = all (abs(lhs%x - rhs%x) < eps0) .and. abs(lhs%t - rhs%t) < eps0 end function momentum_eq @ \subsection{Inner Products} <>= interface operator (*) module procedure momentum_momentum, vector_vector, & vector_momentum, momentum_vector, tensor2odd_tensor2odd end interface private :: momentum_momentum, vector_vector, vector_momentum, & momentum_vector, tensor2odd_tensor2odd @ <>= pure function momentum_momentum (x, y) result (xy) type(momentum), intent(in) :: x type(momentum), intent(in) :: y real(kind=default) :: xy xy = x%t*y%t - x%x(1)*y%x(1) - x%x(2)*y%x(2) - x%x(3)*y%x(3) end function momentum_momentum pure function momentum_vector (x, y) result (xy) type(momentum), intent(in) :: x type(vector), intent(in) :: y complex(kind=default) :: xy xy = x%t*y%t - x%x(1)*y%x(1) - x%x(2)*y%x(2) - x%x(3)*y%x(3) end function momentum_vector pure function vector_momentum (x, y) result (xy) type(vector), intent(in) :: x type(momentum), intent(in) :: y complex(kind=default) :: xy xy = x%t*y%t - x%x(1)*y%x(1) - x%x(2)*y%x(2) - x%x(3)*y%x(3) end function vector_momentum pure function vector_vector (x, y) result (xy) type(vector), intent(in) :: x type(vector), intent(in) :: y complex(kind=default) :: xy xy = x%t*y%t - x%x(1)*y%x(1) - x%x(2)*y%x(2) - x%x(3)*y%x(3) end function vector_vector @ Just like classical electrodynamics: \begin{equation} \frac{1}{2} T_{\mu\nu} U^{\mu\nu} = \frac{1}{2} \left( - T^{0i} U^{0i} - T^{i0} U^{i0} + T^{ij} U^{ij} \right) = T_b^k U_b^k - T_e^k U_e^k \end{equation} <>= pure function tensor2odd_tensor2odd (x, y) result (xy) type(tensor2odd), intent(in) :: x type(tensor2odd), intent(in) :: y complex(kind=default) :: xy xy = x%b(1)*y%b(1) + x%b(2)*y%b(2) + x%b(3)*y%b(3) & - x%e(1)*y%e(1) - x%e(2)*y%e(2) - x%e(3)*y%e(3) end function tensor2odd_tensor2odd @ \subsection{Not Entirely Inner Products} <>= interface operator (*) module procedure momentum_tensor2odd, tensor2odd_momentum, & vector_tensor2odd, tensor2odd_vector end interface private :: momentum_tensor2odd, tensor2odd_momentum, vector_tensor2odd, & tensor2odd_vector @ \begin{subequations} \begin{align} y^\nu = x_\mu T^{\mu\nu}: & y^0 = - x^i T^{i0} = x^i T^{0i} \\ & y^1 = x^0 T^{01} - x^2 T^{21} - x^3 T^{31} \\ & y^2 = x^0 T^{02} - x^1 T^{12} - x^3 T^{32} \\ & y^3 = x^0 T^{03} - x^1 T^{13} - x^2 T^{23} \end{align} \end{subequations} <>= pure function vector_tensor2odd (x, t2) result (xt2) type(vector), intent(in) :: x type(tensor2odd), intent(in) :: t2 type(vector) :: xt2 xt2%t = x%x(1)*t2%e(1) + x%x(2)*t2%e(2) + x%x(3)*t2%e(3) xt2%x(1) = x%t*t2%e(1) + x%x(2)*t2%b(3) - x%x(3)*t2%b(2) xt2%x(2) = x%t*t2%e(2) + x%x(3)*t2%b(1) - x%x(1)*t2%b(3) xt2%x(3) = x%t*t2%e(3) + x%x(1)*t2%b(2) - x%x(2)*t2%b(1) end function vector_tensor2odd pure function momentum_tensor2odd (x, t2) result (xt2) type(momentum), intent(in) :: x type(tensor2odd), intent(in) :: t2 type(vector) :: xt2 xt2%t = x%x(1)*t2%e(1) + x%x(2)*t2%e(2) + x%x(3)*t2%e(3) xt2%x(1) = x%t*t2%e(1) + x%x(2)*t2%b(3) - x%x(3)*t2%b(2) xt2%x(2) = x%t*t2%e(2) + x%x(3)*t2%b(1) - x%x(1)*t2%b(3) xt2%x(3) = x%t*t2%e(3) + x%x(1)*t2%b(2) - x%x(2)*t2%b(1) end function momentum_tensor2odd @ \begin{subequations} \begin{align} y^\mu = T^{\mu\nu} x_\nu : & y^0 = - T^{0i} x^i \\ & y^1 = T^{10} x^0 - T^{12} x^2 - T^{13} x^3 \\ & y^2 = T^{20} x^0 - T^{21} x^1 - T^{23} x^3 \\ & y^3 = T^{30} x^0 - T^{31} x^1 - T^{32} x^2 \end{align} \end{subequations} <>= pure function tensor2odd_vector (t2, x) result (t2x) type(tensor2odd), intent(in) :: t2 type(vector), intent(in) :: x type(vector) :: t2x t2x%t = - t2%e(1)*x%x(1) - t2%e(2)*x%x(2) - t2%e(3)*x%x(3) t2x%x(1) = - t2%e(1)*x%t + t2%b(2)*x%x(3) - t2%b(3)*x%x(2) t2x%x(2) = - t2%e(2)*x%t + t2%b(3)*x%x(1) - t2%b(1)*x%x(3) t2x%x(3) = - t2%e(3)*x%t + t2%b(1)*x%x(2) - t2%b(2)*x%x(1) end function tensor2odd_vector pure function tensor2odd_momentum (t2, x) result (t2x) type(tensor2odd), intent(in) :: t2 type(momentum), intent(in) :: x type(vector) :: t2x t2x%t = - t2%e(1)*x%x(1) - t2%e(2)*x%x(2) - t2%e(3)*x%x(3) t2x%x(1) = - t2%e(1)*x%t + t2%b(2)*x%x(3) - t2%b(3)*x%x(2) t2x%x(2) = - t2%e(2)*x%t + t2%b(3)*x%x(1) - t2%b(1)*x%x(3) t2x%x(3) = - t2%e(3)*x%t + t2%b(1)*x%x(2) - t2%b(2)*x%x(1) end function tensor2odd_momentum @ \subsection{Outer Products} <>= interface operator (.wedge.) module procedure momentum_wedge_momentum, & momentum_wedge_vector, vector_wedge_momentum, vector_wedge_vector end interface private :: momentum_wedge_momentum, momentum_wedge_vector, & vector_wedge_momentum, vector_wedge_vector @ <>= pure function momentum_wedge_momentum (x, y) result (t2) type(momentum), intent(in) :: x type(momentum), intent(in) :: y type(tensor2odd) :: t2 t2%e = x%t * y%x - x%x * y%t t2%b(1) = x%x(2) * y%x(3) - x%x(3) * y%x(2) t2%b(2) = x%x(3) * y%x(1) - x%x(1) * y%x(3) t2%b(3) = x%x(1) * y%x(2) - x%x(2) * y%x(1) end function momentum_wedge_momentum pure function momentum_wedge_vector (x, y) result (t2) type(momentum), intent(in) :: x type(vector), intent(in) :: y type(tensor2odd) :: t2 t2%e = x%t * y%x - x%x * y%t t2%b(1) = x%x(2) * y%x(3) - x%x(3) * y%x(2) t2%b(2) = x%x(3) * y%x(1) - x%x(1) * y%x(3) t2%b(3) = x%x(1) * y%x(2) - x%x(2) * y%x(1) end function momentum_wedge_vector pure function vector_wedge_momentum (x, y) result (t2) type(vector), intent(in) :: x type(momentum), intent(in) :: y type(tensor2odd) :: t2 t2%e = x%t * y%x - x%x * y%t t2%b(1) = x%x(2) * y%x(3) - x%x(3) * y%x(2) t2%b(2) = x%x(3) * y%x(1) - x%x(1) * y%x(3) t2%b(3) = x%x(1) * y%x(2) - x%x(2) * y%x(1) end function vector_wedge_momentum pure function vector_wedge_vector (x, y) result (t2) type(vector), intent(in) :: x type(vector), intent(in) :: y type(tensor2odd) :: t2 t2%e = x%t * y%x - x%x * y%t t2%b(1) = x%x(2) * y%x(3) - x%x(3) * y%x(2) t2%b(2) = x%x(3) * y%x(1) - x%x(1) * y%x(3) t2%b(3) = x%x(1) * y%x(2) - x%x(2) * y%x(1) end function vector_wedge_vector @ \subsection{Vector Space} \subsubsection{Scalar Multiplication} <>= interface operator (*) module procedure integer_momentum, real_momentum, double_momentum, & complex_momentum, dcomplex_momentum, & integer_vector, real_vector, double_vector, & complex_vector, dcomplex_vector, & integer_tensor2odd, real_tensor2odd, double_tensor2odd, & complex_tensor2odd, dcomplex_tensor2odd, & momentum_integer, momentum_real, momentum_double, & momentum_complex, momentum_dcomplex, & vector_integer, vector_real, vector_double, & vector_complex, vector_dcomplex, & tensor2odd_integer, tensor2odd_real, tensor2odd_double, & tensor2odd_complex, tensor2odd_dcomplex end interface private :: integer_momentum, real_momentum, double_momentum, & complex_momentum, dcomplex_momentum, integer_vector, real_vector, & double_vector, complex_vector, dcomplex_vector, & integer_tensor2odd, real_tensor2odd, double_tensor2odd, & complex_tensor2odd, dcomplex_tensor2odd, momentum_integer, & momentum_real, momentum_double, momentum_complex, & momentum_dcomplex, vector_integer, vector_real, vector_double, & vector_complex, vector_dcomplex, tensor2odd_integer, & tensor2odd_real, tensor2odd_double, tensor2odd_complex, & tensor2odd_dcomplex @ <>= pure function integer_momentum (x, y) result (xy) integer, intent(in) :: x type(momentum), intent(in) :: y type(momentum) :: xy xy%t = x * y%t xy%x = x * y%x end function integer_momentum pure function real_momentum (x, y) result (xy) real(kind=single), intent(in) :: x type(momentum), intent(in) :: y type(momentum) :: xy xy%t = x * y%t xy%x = x * y%x end function real_momentum pure function double_momentum (x, y) result (xy) real(kind=default), intent(in) :: x type(momentum), intent(in) :: y type(momentum) :: xy xy%t = x * y%t xy%x = x * y%x end function double_momentum pure function complex_momentum (x, y) result (xy) complex(kind=single), intent(in) :: x type(momentum), intent(in) :: y type(vector) :: xy xy%t = x * y%t xy%x = x * y%x end function complex_momentum pure function dcomplex_momentum (x, y) result (xy) complex(kind=default), intent(in) :: x type(momentum), intent(in) :: y type(vector) :: xy xy%t = x * y%t xy%x = x * y%x end function dcomplex_momentum @ <>= pure function integer_vector (x, y) result (xy) integer, intent(in) :: x type(vector), intent(in) :: y type(vector) :: xy xy%t = x * y%t xy%x = x * y%x end function integer_vector pure function real_vector (x, y) result (xy) real(kind=single), intent(in) :: x type(vector), intent(in) :: y type(vector) :: xy xy%t = x * y%t xy%x = x * y%x end function real_vector pure function double_vector (x, y) result (xy) real(kind=default), intent(in) :: x type(vector), intent(in) :: y type(vector) :: xy xy%t = x * y%t xy%x = x * y%x end function double_vector pure function complex_vector (x, y) result (xy) complex(kind=single), intent(in) :: x type(vector), intent(in) :: y type(vector) :: xy xy%t = x * y%t xy%x = x * y%x end function complex_vector pure function dcomplex_vector (x, y) result (xy) complex(kind=default), intent(in) :: x type(vector), intent(in) :: y type(vector) :: xy xy%t = x * y%t xy%x = x * y%x end function dcomplex_vector @ <>= pure function integer_tensor2odd (x, t2) result (xt2) integer, intent(in) :: x type(tensor2odd), intent(in) :: t2 type(tensor2odd) :: xt2 xt2%e = x * t2%e xt2%b = x * t2%b end function integer_tensor2odd pure function real_tensor2odd (x, t2) result (xt2) real(kind=single), intent(in) :: x type(tensor2odd), intent(in) :: t2 type(tensor2odd) :: xt2 xt2%e = x * t2%e xt2%b = x * t2%b end function real_tensor2odd pure function double_tensor2odd (x, t2) result (xt2) real(kind=default), intent(in) :: x type(tensor2odd), intent(in) :: t2 type(tensor2odd) :: xt2 xt2%e = x * t2%e xt2%b = x * t2%b end function double_tensor2odd pure function complex_tensor2odd (x, t2) result (xt2) complex(kind=single), intent(in) :: x type(tensor2odd), intent(in) :: t2 type(tensor2odd) :: xt2 xt2%e = x * t2%e xt2%b = x * t2%b end function complex_tensor2odd pure function dcomplex_tensor2odd (x, t2) result (xt2) complex(kind=default), intent(in) :: x type(tensor2odd), intent(in) :: t2 type(tensor2odd) :: xt2 xt2%e = x * t2%e xt2%b = x * t2%b end function dcomplex_tensor2odd @ <>= pure function momentum_integer (y, x) result (xy) integer, intent(in) :: x type(momentum), intent(in) :: y type(momentum) :: xy xy%t = x * y%t xy%x = x * y%x end function momentum_integer pure function momentum_real (y, x) result (xy) real(kind=single), intent(in) :: x type(momentum), intent(in) :: y type(momentum) :: xy xy%t = x * y%t xy%x = x * y%x end function momentum_real pure function momentum_double (y, x) result (xy) real(kind=default), intent(in) :: x type(momentum), intent(in) :: y type(momentum) :: xy xy%t = x * y%t xy%x = x * y%x end function momentum_double pure function momentum_complex (y, x) result (xy) complex(kind=single), intent(in) :: x type(momentum), intent(in) :: y type(vector) :: xy xy%t = x * y%t xy%x = x * y%x end function momentum_complex pure function momentum_dcomplex (y, x) result (xy) complex(kind=default), intent(in) :: x type(momentum), intent(in) :: y type(vector) :: xy xy%t = x * y%t xy%x = x * y%x end function momentum_dcomplex @ <>= pure function vector_integer (y, x) result (xy) integer, intent(in) :: x type(vector), intent(in) :: y type(vector) :: xy xy%t = x * y%t xy%x = x * y%x end function vector_integer pure function vector_real (y, x) result (xy) real(kind=single), intent(in) :: x type(vector), intent(in) :: y type(vector) :: xy xy%t = x * y%t xy%x = x * y%x end function vector_real pure function vector_double (y, x) result (xy) real(kind=default), intent(in) :: x type(vector), intent(in) :: y type(vector) :: xy xy%t = x * y%t xy%x = x * y%x end function vector_double pure function vector_complex (y, x) result (xy) complex(kind=single), intent(in) :: x type(vector), intent(in) :: y type(vector) :: xy xy%t = x * y%t xy%x = x * y%x end function vector_complex pure function vector_dcomplex (y, x) result (xy) complex(kind=default), intent(in) :: x type(vector), intent(in) :: y type(vector) :: xy xy%t = x * y%t xy%x = x * y%x end function vector_dcomplex @ <>= pure function tensor2odd_integer (t2, x) result (t2x) type(tensor2odd), intent(in) :: t2 integer, intent(in) :: x type(tensor2odd) :: t2x t2x%e = x * t2%e t2x%b = x * t2%b end function tensor2odd_integer pure function tensor2odd_real (t2, x) result (t2x) type(tensor2odd), intent(in) :: t2 real(kind=single), intent(in) :: x type(tensor2odd) :: t2x t2x%e = x * t2%e t2x%b = x * t2%b end function tensor2odd_real pure function tensor2odd_double (t2, x) result (t2x) type(tensor2odd), intent(in) :: t2 real(kind=default), intent(in) :: x type(tensor2odd) :: t2x t2x%e = x * t2%e t2x%b = x * t2%b end function tensor2odd_double pure function tensor2odd_complex (t2, x) result (t2x) type(tensor2odd), intent(in) :: t2 complex(kind=single), intent(in) :: x type(tensor2odd) :: t2x t2x%e = x * t2%e t2x%b = x * t2%b end function tensor2odd_complex pure function tensor2odd_dcomplex (t2, x) result (t2x) type(tensor2odd), intent(in) :: t2 complex(kind=default), intent(in) :: x type(tensor2odd) :: t2x t2x%e = x * t2%e t2x%b = x * t2%b end function tensor2odd_dcomplex @ \subsubsection{Unary Plus and Minus} <>= interface operator (+) module procedure plus_momentum, plus_vector, plus_tensor2odd end interface private :: plus_momentum, plus_vector, plus_tensor2odd interface operator (-) module procedure neg_momentum, neg_vector, neg_tensor2odd end interface private :: neg_momentum, neg_vector, neg_tensor2odd @ <>= pure function plus_momentum (x) result (plus_x) type(momentum), intent(in) :: x type(momentum) :: plus_x plus_x = x end function plus_momentum pure function neg_momentum (x) result (neg_x) type(momentum), intent(in) :: x type(momentum) :: neg_x neg_x%t = - x%t neg_x%x = - x%x end function neg_momentum @ <>= pure function plus_vector (x) result (plus_x) type(vector), intent(in) :: x type(vector) :: plus_x plus_x = x end function plus_vector pure function neg_vector (x) result (neg_x) type(vector), intent(in) :: x type(vector) :: neg_x neg_x%t = - x%t neg_x%x = - x%x end function neg_vector @ <>= pure function plus_tensor2odd (x) result (plus_x) type(tensor2odd), intent(in) :: x type(tensor2odd) :: plus_x plus_x = x end function plus_tensor2odd pure function neg_tensor2odd (x) result (neg_x) type(tensor2odd), intent(in) :: x type(tensor2odd) :: neg_x neg_x%e = - x%e neg_x%b = - x%b end function neg_tensor2odd @ \subsubsection{Addition and Subtraction} <>= interface operator (+) module procedure add_momentum, add_vector, & add_vector_momentum, add_momentum_vector, add_tensor2odd end interface private :: add_momentum, add_vector, add_vector_momentum, & add_momentum_vector, add_tensor2odd interface operator (-) module procedure sub_momentum, sub_vector, & sub_vector_momentum, sub_momentum_vector, sub_tensor2odd end interface private :: sub_momentum, sub_vector, sub_vector_momentum, & sub_momentum_vector, sub_tensor2odd @ <>= pure function add_momentum (x, y) result (xy) type(momentum), intent(in) :: x, y type(momentum) :: xy xy%t = x%t + y%t xy%x = x%x + y%x end function add_momentum pure function add_vector (x, y) result (xy) type(vector), intent(in) :: x, y type(vector) :: xy xy%t = x%t + y%t xy%x = x%x + y%x end function add_vector pure function add_momentum_vector (x, y) result (xy) type(momentum), intent(in) :: x type(vector), intent(in) :: y type(vector) :: xy xy%t = x%t + y%t xy%x = x%x + y%x end function add_momentum_vector pure function add_vector_momentum (x, y) result (xy) type(vector), intent(in) :: x type(momentum), intent(in) :: y type(vector) :: xy xy%t = x%t + y%t xy%x = x%x + y%x end function add_vector_momentum pure function add_tensor2odd (x, y) result (xy) type(tensor2odd), intent(in) :: x, y type(tensor2odd) :: xy xy%e = x%e + y%e xy%b = x%b + y%b end function add_tensor2odd @ <>= pure function sub_momentum (x, y) result (xy) type(momentum), intent(in) :: x, y type(momentum) :: xy xy%t = x%t - y%t xy%x = x%x - y%x end function sub_momentum pure function sub_vector (x, y) result (xy) type(vector), intent(in) :: x, y type(vector) :: xy xy%t = x%t - y%t xy%x = x%x - y%x end function sub_vector pure function sub_momentum_vector (x, y) result (xy) type(momentum), intent(in) :: x type(vector), intent(in) :: y type(vector) :: xy xy%t = x%t - y%t xy%x = x%x - y%x end function sub_momentum_vector pure function sub_vector_momentum (x, y) result (xy) type(vector), intent(in) :: x type(momentum), intent(in) :: y type(vector) :: xy xy%t = x%t - y%t xy%x = x%x - y%x end function sub_vector_momentum pure function sub_tensor2odd (x, y) result (xy) type(tensor2odd), intent(in) :: x, y type(tensor2odd) :: xy xy%e = x%e - y%e xy%b = x%b - y%b end function sub_tensor2odd @ \subsection{Norm} \emph{Not} the covariant length! <>= interface abs module procedure abs_momentum, abs_vector, abs_tensor2odd end interface private :: abs_momentum, abs_vector, abs_tensor2odd @ <>= pure function abs_momentum (x) result (absx) type(momentum), intent(in) :: x real(kind=default) :: absx absx = sqrt (real (x%t*x%t + dot_product (x%x, x%x))) end function abs_momentum pure function abs_vector (x) result (absx) type(vector), intent(in) :: x real(kind=default) :: absx absx = sqrt (real (conjg(x%t)*x%t + dot_product (x%x, x%x))) end function abs_vector pure function abs_tensor2odd (x) result (absx) type(tensor2odd), intent(in) :: x real(kind=default) :: absx absx = sqrt (real (dot_product (x%e, x%e) + dot_product (x%b, x%b))) end function abs_tensor2odd @ \subsection{Conjugation} <>= interface conjg module procedure conjg_momentum, conjg_vector, conjg_tensor2odd end interface private :: conjg_momentum, conjg_vector, conjg_tensor2odd @ <>= pure function conjg_momentum (x) result (conjg_x) type(momentum), intent(in) :: x type(momentum) :: conjg_x conjg_x = x end function conjg_momentum pure function conjg_vector (x) result (conjg_x) type(vector), intent(in) :: x type(vector) :: conjg_x conjg_x%t = conjg (x%t) conjg_x%x = conjg (x%x) end function conjg_vector pure function conjg_tensor2odd (t2) result (conjg_t2) type(tensor2odd), intent(in) :: t2 type(tensor2odd) :: conjg_t2 conjg_t2%e = conjg (t2%e) conjg_t2%b = conjg (t2%b) end function conjg_tensor2odd @ \subsection{$\epsilon$-Tensors} \begin{equation} \epsilon_{0123} = 1 = - \epsilon^{0123} \end{equation} in particular \begin{equation} \epsilon(p_1,p_2,p_3,p_4) = \epsilon_{\mu_1\mu_2\mu_3\mu_4} p_1^{\mu_1}p_2^{\mu_2}p_3^{\mu_3}p_4^{\mu_4} = p_1^0 p_2^1 p_3^2 p_4^3 \pm \ldots \end{equation} <>= interface pseudo_scalar module procedure pseudo_scalar_momentum, pseudo_scalar_vector, & pseudo_scalar_vec_mom end interface public :: pseudo_scalar private :: pseudo_scalar_momentum, pseudo_scalar_vector @ <>= pure function pseudo_scalar_momentum (p1, p2, p3, p4) result (eps1234) type(momentum), intent(in) :: p1, p2, p3, p4 real(kind=default) :: eps1234 eps1234 = & p1%t * p2%x(1) * (p3%x(2) * p4%x(3) - p3%x(3) * p4%x(2)) & + p1%t * p2%x(2) * (p3%x(3) * p4%x(1) - p3%x(1) * p4%x(3)) & + p1%t * p2%x(3) * (p3%x(1) * p4%x(2) - p3%x(2) * p4%x(1)) & - p1%x(1) * p2%x(2) * (p3%x(3) * p4%t - p3%t * p4%x(3)) & - p1%x(1) * p2%x(3) * (p3%t * p4%x(2) - p3%x(2) * p4%t ) & - p1%x(1) * p2%t * (p3%x(2) * p4%x(3) - p3%x(3) * p4%x(2)) & + p1%x(2) * p2%x(3) * (p3%t * p4%x(1) - p3%x(1) * p4%t ) & + p1%x(2) * p2%t * (p3%x(1) * p4%x(3) - p3%x(3) * p4%x(1)) & + p1%x(2) * p2%x(1) * (p3%x(3) * p4%t - p3%t * p4%x(3)) & - p1%x(3) * p2%t * (p3%x(1) * p4%x(2) - p3%x(2) * p4%x(1)) & - p1%x(3) * p2%x(1) * (p3%x(2) * p4%t - p3%t * p4%x(2)) & - p1%x(3) * p2%x(2) * (p3%t * p4%x(1) - p3%x(1) * p4%t ) end function pseudo_scalar_momentum @ <>= pure function pseudo_scalar_vector (p1, p2, p3, p4) result (eps1234) type(vector), intent(in) :: p1, p2, p3, p4 complex(kind=default) :: eps1234 eps1234 = & p1%t * p2%x(1) * (p3%x(2) * p4%x(3) - p3%x(3) * p4%x(2)) & + p1%t * p2%x(2) * (p3%x(3) * p4%x(1) - p3%x(1) * p4%x(3)) & + p1%t * p2%x(3) * (p3%x(1) * p4%x(2) - p3%x(2) * p4%x(1)) & - p1%x(1) * p2%x(2) * (p3%x(3) * p4%t - p3%t * p4%x(3)) & - p1%x(1) * p2%x(3) * (p3%t * p4%x(2) - p3%x(2) * p4%t ) & - p1%x(1) * p2%t * (p3%x(2) * p4%x(3) - p3%x(3) * p4%x(2)) & + p1%x(2) * p2%x(3) * (p3%t * p4%x(1) - p3%x(1) * p4%t ) & + p1%x(2) * p2%t * (p3%x(1) * p4%x(3) - p3%x(3) * p4%x(1)) & + p1%x(2) * p2%x(1) * (p3%x(3) * p4%t - p3%t * p4%x(3)) & - p1%x(3) * p2%t * (p3%x(1) * p4%x(2) - p3%x(2) * p4%x(1)) & - p1%x(3) * p2%x(1) * (p3%x(2) * p4%t - p3%t * p4%x(2)) & - p1%x(3) * p2%x(2) * (p3%t * p4%x(1) - p3%x(1) * p4%t ) end function pseudo_scalar_vector @ <>= pure function pseudo_scalar_vec_mom (p1, v1, p2, v2) result (eps1234) type(momentum), intent(in) :: p1, p2 type(vector), intent(in) :: v1, v2 complex(kind=default) :: eps1234 eps1234 = & p1%t * v1%x(1) * (p2%x(2) * v2%x(3) - p2%x(3) * v2%x(2)) & + p1%t * v1%x(2) * (p2%x(3) * v2%x(1) - p2%x(1) * v2%x(3)) & + p1%t * v1%x(3) * (p2%x(1) * v2%x(2) - p2%x(2) * v2%x(1)) & - p1%x(1) * v1%x(2) * (p2%x(3) * v2%t - p2%t * v2%x(3)) & - p1%x(1) * v1%x(3) * (p2%t * v2%x(2) - p2%x(2) * v2%t ) & - p1%x(1) * v1%t * (p2%x(2) * v2%x(3) - p2%x(3) * v2%x(2)) & + p1%x(2) * v1%x(3) * (p2%t * v2%x(1) - p2%x(1) * v2%t ) & + p1%x(2) * v1%t * (p2%x(1) * v2%x(3) - p2%x(3) * v2%x(1)) & + p1%x(2) * v1%x(1) * (p2%x(3) * v2%t - p2%t * v2%x(3)) & - p1%x(3) * v1%t * (p2%x(1) * v2%x(2) - p2%x(2) * v2%x(1)) & - p1%x(3) * v1%x(1) * (p2%x(2) * v2%t - p2%t * v2%x(2)) & - p1%x(3) * v1%x(2) * (p2%t * v2%x(1) - p2%x(1) * v2%t ) end function pseudo_scalar_vec_mom @ \begin{equation} \epsilon_\mu(p_1,p_2,p_3) = \epsilon_{\mu\mu_1\mu_2\mu_3} p_1^{\mu_1}p_2^{\mu_2}p_3^{\mu_3} \end{equation} i.\,e. \begin{subequations} \begin{align} \epsilon_0(p_1,p_2,p_3) &= p_1^1 p_2^2 p_3^3 \pm \ldots \\ \epsilon_1(p_1,p_2,p_3) &= p_1^2 p_2^3 p_3^0 \pm \ldots \\ \epsilon_2(p_1,p_2,p_3) &= - p_1^3 p_2^0 p_3^1 \pm \ldots \\ \epsilon_3(p_1,p_2,p_3) &= p_1^0 p_2^1 p_3^2 \pm \ldots \end{align} \end{subequations} <>= interface pseudo_vector module procedure pseudo_vector_momentum, pseudo_vector_vector, & pseudo_vector_vec_mom end interface public :: pseudo_vector private :: pseudo_vector_momentum, pseudo_vector_vector @ <>= pure function pseudo_vector_momentum (p1, p2, p3) result (eps123) type(momentum), intent(in) :: p1, p2, p3 type(momentum) :: eps123 eps123%t = & + p1%x(1) * (p2%x(2) * p3%x(3) - p2%x(3) * p3%x(2)) & + p1%x(2) * (p2%x(3) * p3%x(1) - p2%x(1) * p3%x(3)) & + p1%x(3) * (p2%x(1) * p3%x(2) - p2%x(2) * p3%x(1)) eps123%x(1) = & + p1%x(2) * (p2%x(3) * p3%t - p2%t * p3%x(3)) & + p1%x(3) * (p2%t * p3%x(2) - p2%x(2) * p3%t ) & + p1%t * (p2%x(2) * p3%x(3) - p2%x(3) * p3%x(2)) eps123%x(2) = & - p1%x(3) * (p2%t * p3%x(1) - p2%x(1) * p3%t ) & - p1%t * (p2%x(1) * p3%x(3) - p2%x(3) * p3%x(1)) & - p1%x(1) * (p2%x(3) * p3%t - p2%t * p3%x(3)) eps123%x(3) = & + p1%t * (p2%x(1) * p3%x(2) - p2%x(2) * p3%x(1)) & + p1%x(1) * (p2%x(2) * p3%t - p2%t * p3%x(2)) & + p1%x(2) * (p2%t * p3%x(1) - p2%x(1) * p3%t ) end function pseudo_vector_momentum @ <>= pure function pseudo_vector_vector (p1, p2, p3) result (eps123) type(vector), intent(in) :: p1, p2, p3 type(vector) :: eps123 eps123%t = & + p1%x(1) * (p2%x(2) * p3%x(3) - p2%x(3) * p3%x(2)) & + p1%x(2) * (p2%x(3) * p3%x(1) - p2%x(1) * p3%x(3)) & + p1%x(3) * (p2%x(1) * p3%x(2) - p2%x(2) * p3%x(1)) eps123%x(1) = & + p1%x(2) * (p2%x(3) * p3%t - p2%t * p3%x(3)) & + p1%x(3) * (p2%t * p3%x(2) - p2%x(2) * p3%t ) & + p1%t * (p2%x(2) * p3%x(3) - p2%x(3) * p3%x(2)) eps123%x(2) = & - p1%x(3) * (p2%t * p3%x(1) - p2%x(1) * p3%t ) & - p1%t * (p2%x(1) * p3%x(3) - p2%x(3) * p3%x(1)) & - p1%x(1) * (p2%x(3) * p3%t - p2%t * p3%x(3)) eps123%x(3) = & + p1%t * (p2%x(1) * p3%x(2) - p2%x(2) * p3%x(1)) & + p1%x(1) * (p2%x(2) * p3%t - p2%t * p3%x(2)) & + p1%x(2) * (p2%t * p3%x(1) - p2%x(1) * p3%t ) end function pseudo_vector_vector @ <>= pure function pseudo_vector_vec_mom (p1, p2, v) result (eps123) type(momentum), intent(in) :: p1, p2 type(vector), intent(in) :: v type(vector) :: eps123 eps123%t = & + p1%x(1) * (p2%x(2) * v%x(3) - p2%x(3) * v%x(2)) & + p1%x(2) * (p2%x(3) * v%x(1) - p2%x(1) * v%x(3)) & + p1%x(3) * (p2%x(1) * v%x(2) - p2%x(2) * v%x(1)) eps123%x(1) = & + p1%x(2) * (p2%x(3) * v%t - p2%t * v%x(3)) & + p1%x(3) * (p2%t * v%x(2) - p2%x(2) * v%t ) & + p1%t * (p2%x(2) * v%x(3) - p2%x(3) * v%x(2)) eps123%x(2) = & - p1%x(3) * (p2%t * v%x(1) - p2%x(1) * v%t ) & - p1%t * (p2%x(1) * v%x(3) - p2%x(3) * v%x(1)) & - p1%x(1) * (p2%x(3) * v%t - p2%t * v%x(3)) eps123%x(3) = & + p1%t * (p2%x(1) * v%x(2) - p2%x(2) * v%x(1)) & + p1%x(1) * (p2%x(2) * v%t - p2%t * v%x(2)) & + p1%x(2) * (p2%t * v%x(1) - p2%x(1) * v%t ) end function pseudo_vector_vec_mom @ \subsection{Utilities} <>= @ <>= subroutine random_momentum (p, pabs, m) type(momentum), intent(out) :: p real(kind=default), intent(in) :: pabs, m real(kind=default), dimension(2) :: r real(kind=default) :: phi, cos_th call random_number (r) phi = 2*PI * r(1) cos_th = 2 * r(2) - 1 p%t = sqrt (pabs**2 + m**2) p%x = pabs * (/ cos_th * cos(phi), cos_th * sin(phi), sqrt (1 - cos_th**2) /) end subroutine random_momentum @ \section{Polarization vectors} <<[[omega_polarizations.f90]]>>= <> module omega_polarizations use kinds use constants use omega_vectors implicit none private <> integer, parameter, public :: omega_polarizations_2010_01_A = 0 contains <> end module omega_polarizations @ Here we use a phase convention for the polarization vectors compatible with the angular momentum coupling to spin 3/2 and spin 2. \begin{subequations} \begin{align} \epsilon^\mu_1(k) &= \frac{1}{|\vec k|\sqrt{k_x^2+k_y^2}} \left(0; k_z k_x, k_y k_z, - k_x^2 - k_y^2\right) \\ \epsilon^\mu_2(k) &= \frac{1}{\sqrt{k_x^2+k_y^2}} \left(0; -k_y, k_x, 0\right) \\ \epsilon^\mu_3(k) &= \frac{k_0}{m|\vec k|} \left({\vec k}^2/k_0; k_x, k_y, k_z\right) \end{align} \end{subequations} and \begin{subequations} \begin{align} \epsilon^\mu_\pm(k) &= \frac{1}{\sqrt{2}} (\epsilon^\mu_1(k) \pm \ii\epsilon^\mu_2(k) ) \\ \epsilon^\mu_0(k) &= \epsilon^\mu_3(k) \end{align} \end{subequations} i.\,e. \begin{subequations} \begin{align} \epsilon^\mu_+(k) &= \frac{1}{\sqrt{2}\sqrt{k_x^2+k_y^2}} \left(0; \frac{k_zk_x}{|\vec k|} - \ii k_y, \frac{k_yk_z}{|\vec k|} + \ii k_x, - \frac{k_x^2+k_y^2}{|\vec k|}\right) \\ \epsilon^\mu_-(k) &= \frac{1}{\sqrt{2}\sqrt{k_x^2+k_y^2}} \left(0; \frac{k_zk_x}{|\vec k|} + \ii k_y, \frac{k_yk_z}{|\vec k|} - \ii k_x, -\frac{k_x^2+k_y^2}{|\vec k|}\right) \\ \epsilon^\mu_0(k) &= \frac{k_0}{m|\vec k|} \left({\vec k}^2/k_0; k_x, k_y, k_z\right) \end{align} \end{subequations} Determining the mass from the momenta is a numerically haphazardous for light particles. Therefore, we accept some redundancy and pass the mass explicitely. <>= public :: eps @ <>= pure function eps (m, k, s) result (e) type(vector) :: e real(kind=default), intent(in) :: m type(momentum), intent(in) :: k integer, intent(in) :: s real(kind=default) :: kt, kabs, kabs2, sqrt2 sqrt2 = sqrt (2.0_default) kabs2 = dot_product (k%x, k%x) e%t = 0 e%x = 0 if (kabs2 > 0) then kabs = sqrt (kabs2) select case (s) case (1) kt = sqrt (k%x(1)**2 + k%x(2)**2) if (abs(kt) <= epsilon(kt) * kabs) then if (k%x(3) > 0) then e%x(1) = cmplx ( 1, 0, kind=default) / sqrt2 e%x(2) = cmplx ( 0, 1, kind=default) / sqrt2 else e%x(1) = cmplx ( - 1, 0, kind=default) / sqrt2 e%x(2) = cmplx ( 0, 1, kind=default) / sqrt2 end if else e%x(1) = cmplx ( k%x(3)*k%x(1)/kabs, & - k%x(2), kind=default) / kt / sqrt2 e%x(2) = cmplx ( k%x(2)*k%x(3)/kabs, & k%x(1), kind=default) / kt / sqrt2 e%x(3) = - kt / kabs / sqrt2 end if case (-1) kt = sqrt (k%x(1)**2 + k%x(2)**2) if (abs(kt) <= epsilon(kt) * kabs) then if (k%x(3) > 0) then e%x(1) = cmplx ( 1, 0, kind=default) / sqrt2 e%x(2) = cmplx ( 0, - 1, kind=default) / sqrt2 else e%x(1) = cmplx ( -1, 0, kind=default) / sqrt2 e%x(2) = cmplx ( 0, - 1, kind=default) / sqrt2 end if else e%x(1) = cmplx ( k%x(3)*k%x(1)/kabs, & k%x(2), kind=default) / kt / sqrt2 e%x(2) = cmplx ( k%x(2)*k%x(3)/kabs, & - k%x(1), kind=default) / kt / sqrt2 e%x(3) = - kt / kabs / sqrt2 end if case (0) if (m > 0) then e%t = kabs / m e%x = k%t / (m*kabs) * k%x end if case (3) e = (0,1) * k case (4) if (m > 0) then e = (1 / m) * k else e = (1 / k%t) * k end if end select else !!! for particles in their rest frame defined to be !!! polarized along the 3-direction select case (s) case (1) e%x(1) = cmplx ( 1, 0, kind=default) / sqrt2 e%x(2) = cmplx ( 0, 1, kind=default) / sqrt2 case (-1) e%x(1) = cmplx ( 1, 0, kind=default) / sqrt2 e%x(2) = cmplx ( 0, - 1, kind=default) / sqrt2 case (0) if (m > 0) then e%x(3) = 1 end if case (4) if (m > 0) then e = (1 / m) * k else e = (1 / k%t) * k end if end select end if end function eps @ \section{Polarization vectors revisited} <<[[omega_polarizations_madgraph.f90]]>>= <> module omega_polarizations_madgraph use kinds use constants use omega_vectors implicit none private <> integer, parameter, public :: omega_pols_madgraph_2010_01_A = 0 contains <> end module omega_polarizations_madgraph @ This set of polarization vectors is compatible with HELAS~\cite{HELAS}: \begin{subequations} \begin{align} \epsilon^\mu_1(k) &= \frac{1}{|\vec k|\sqrt{k_x^2+k_y^2}} \left(0; k_z k_x, k_y k_z, - k_x^2 - k_y^2\right) \\ \epsilon^\mu_2(k) &= \frac{1}{\sqrt{k_x^2+k_y^2}} \left(0; -k_y, k_x, 0\right) \\ \epsilon^\mu_3(k) &= \frac{k_0}{m|\vec k|} \left({\vec k}^2/k_0; k_x, k_y, k_z\right) \end{align} \end{subequations} and \begin{subequations} \begin{align} \epsilon^\mu_\pm(k) &= \frac{1}{\sqrt{2}} (\mp \epsilon^\mu_1(k) - \ii\epsilon^\mu_2(k) ) \\ \epsilon^\mu_0(k) &= \epsilon^\mu_3(k) \end{align} \end{subequations} i.\,e. \begin{subequations} \begin{align} \epsilon^\mu_+(k) &= \frac{1}{\sqrt{2}\sqrt{k_x^2+k_y^2}} \left(0; -\frac{k_zk_x}{|\vec k|} + \ii k_y, -\frac{k_yk_z}{|\vec k|} - \ii k_x, \frac{k_x^2+k_y^2}{|\vec k|}\right) \\ \epsilon^\mu_-(k) &= \frac{1}{\sqrt{2}\sqrt{k_x^2+k_y^2}} \left(0; \frac{k_zk_x}{|\vec k|} + \ii k_y, \frac{k_yk_z}{|\vec k|} - \ii k_x, -\frac{k_x^2+k_y^2}{|\vec k|}\right) \\ \epsilon^\mu_0(k) &= \frac{k_0}{m|\vec k|} \left({\vec k}^2/k_0; k_x, k_y, k_z\right) \end{align} \end{subequations} Fortunately, for comparing with squared matrix generated by Madgraph we can also use the modified version, since the difference is only a phase and does \emph{not} mix helicity states. @ Determining the mass from the momenta is a numerically haphazardous for light particles. Therefore, we accept some redundancy and pass the mass explicitely. <>= public :: eps @ <>= pure function eps (m, k, s) result (e) type(vector) :: e real(kind=default), intent(in) :: m type(momentum), intent(in) :: k integer, intent(in) :: s real(kind=default) :: kt, kabs, kabs2, sqrt2 sqrt2 = sqrt (2.0_default) kabs2 = dot_product (k%x, k%x) e%t = 0 e%x = 0 if (kabs2 > 0) then kabs = sqrt (kabs2) select case (s) case (1) kt = sqrt (k%x(1)**2 + k%x(2)**2) if (abs(kt) <= epsilon(kt) * kabs) then if (k%x(3) > 0) then e%x(1) = cmplx ( - 1, 0, kind=default) / sqrt2 e%x(2) = cmplx ( 0, - 1, kind=default) / sqrt2 else e%x(1) = cmplx ( 1, 0, kind=default) / sqrt2 e%x(2) = cmplx ( 0, - 1, kind=default) / sqrt2 end if else e%x(1) = cmplx ( - k%x(3)*k%x(1)/kabs, & k%x(2), kind=default) / kt / sqrt2 e%x(2) = cmplx ( - k%x(2)*k%x(3)/kabs, & - k%x(1), kind=default) / kt / sqrt2 e%x(3) = kt / kabs / sqrt2 end if case (-1) kt = sqrt (k%x(1)**2 + k%x(2)**2) if (abs(kt) <= epsilon(kt) * kabs) then if (k%x(3) > 0) then e%x(1) = cmplx ( 1, 0, kind=default) / sqrt2 e%x(2) = cmplx ( 0, - 1, kind=default) / sqrt2 else e%x(1) = cmplx ( -1, 0, kind=default) / sqrt2 e%x(2) = cmplx ( 0, - 1, kind=default) / sqrt2 end if else e%x(1) = cmplx ( k%x(3)*k%x(1)/kabs, & k%x(2), kind=default) / kt / sqrt2 e%x(2) = cmplx ( k%x(2)*k%x(3)/kabs, & - k%x(1), kind=default) / kt / sqrt2 e%x(3) = - kt / kabs / sqrt2 end if case (0) if (m > 0) then e%t = kabs / m e%x = k%t / (m*kabs) * k%x end if case (3) e = (0,1) * k case (4) if (m > 0) then e = (1 / m) * k else e = (1 / k%t) * k end if end select else !!! for particles in their rest frame defined to be !!! polarized along the 3-direction select case (s) case (1) e%x(1) = cmplx ( - 1, 0, kind=default) / sqrt2 e%x(2) = cmplx ( 0, - 1, kind=default) / sqrt2 case (-1) e%x(1) = cmplx ( 1, 0, kind=default) / sqrt2 e%x(2) = cmplx ( 0, - 1, kind=default) / sqrt2 case (0) if (m > 0) then e%x(3) = 1 end if case (4) if (m > 0) then e = (1 / m) * k else e = (1 / k%t) * k end if end select end if end function eps @ \section{Symmetric Tensors} Spin-2 polarization tensors are symmetric, transversal and traceless \begin{subequations} \begin{align} \epsilon^{\mu\nu}_{m}(k) &= \epsilon^{\nu\mu}_{m}(k) \\ k_\mu \epsilon^{\mu\nu}_{m}(k) &= k_\nu \epsilon^{\mu\nu}_{m}(k) = 0 \\ \epsilon^{\mu}_{m,\mu}(k) &= 0 \end{align} \end{subequations} with $m=1,2,3,4,5$. Our current representation is redundant and does \emph{not} enforce symmetry or tracelessness. <<[[omega_tensors.f90]]>>= <> module omega_tensors use kinds use constants use omega_vectors implicit none private public :: operator (*), operator (+), operator (-), & operator (.tprod.) public :: abs, conjg <<[[intrinsic :: abs]]>> <<[[intrinsic :: conjg]]>> type, public :: tensor ! private (omegalib needs access, but DON'T TOUCH IT!) complex(kind=default), dimension(0:3,0:3) :: t end type tensor <> integer, parameter, public :: omega_tensors_2010_01_A = 0 contains <> end module omega_tensors @ \subsection{Vector Space} \subsubsection{Scalar Multliplication} <>= interface operator (*) module procedure integer_tensor, real_tensor, double_tensor, & complex_tensor, dcomplex_tensor end interface private :: integer_tensor, real_tensor, double_tensor private :: complex_tensor, dcomplex_tensor @ <>= pure function integer_tensor (x, y) result (xy) integer, intent(in) :: x type(tensor), intent(in) :: y type(tensor) :: xy xy%t = x * y%t end function integer_tensor pure function real_tensor (x, y) result (xy) real(kind=single), intent(in) :: x type(tensor), intent(in) :: y type(tensor) :: xy xy%t = x * y%t end function real_tensor pure function double_tensor (x, y) result (xy) real(kind=default), intent(in) :: x type(tensor), intent(in) :: y type(tensor) :: xy xy%t = x * y%t end function double_tensor pure function complex_tensor (x, y) result (xy) complex(kind=single), intent(in) :: x type(tensor), intent(in) :: y type(tensor) :: xy xy%t = x * y%t end function complex_tensor pure function dcomplex_tensor (x, y) result (xy) complex(kind=default), intent(in) :: x type(tensor), intent(in) :: y type(tensor) :: xy xy%t = x * y%t end function dcomplex_tensor @ \subsubsection{Addition and Subtraction} <>= interface operator (+) module procedure plus_tensor end interface private :: plus_tensor interface operator (-) module procedure neg_tensor end interface private :: neg_tensor @ <>= pure function plus_tensor (t1) result (t2) type(tensor), intent(in) :: t1 type(tensor) :: t2 t2 = t1 end function plus_tensor pure function neg_tensor (t1) result (t2) type(tensor), intent(in) :: t1 type(tensor) :: t2 t2%t = - t1%t end function neg_tensor @ <>= interface operator (+) module procedure add_tensor end interface private :: add_tensor interface operator (-) module procedure sub_tensor end interface private :: sub_tensor @ <>= pure function add_tensor (x, y) result (xy) type(tensor), intent(in) :: x, y type(tensor) :: xy xy%t = x%t + y%t end function add_tensor pure function sub_tensor (x, y) result (xy) type(tensor), intent(in) :: x, y type(tensor) :: xy xy%t = x%t - y%t end function sub_tensor @ <>= interface operator (.tprod.) module procedure out_prod_vv, out_prod_vm, & out_prod_mv, out_prod_mm end interface private :: out_prod_vv, out_prod_vm, & out_prod_mv, out_prod_mm @ <>= pure function out_prod_vv (v, w) result (t) type(tensor) :: t type(vector), intent(in) :: v, w integer :: i, j t%t(0,0) = v%t * w%t t%t(0,1:3) = v%t * w%x t%t(1:3,0) = v%x * w%t do i = 1, 3 do j = 1, 3 t%t(i,j) = v%x(i) * w%x(j) end do end do end function out_prod_vv @ <>= pure function out_prod_vm (v, m) result (t) type(tensor) :: t type(vector), intent(in) :: v type(momentum), intent(in) :: m integer :: i, j t%t(0,0) = v%t * m%t t%t(0,1:3) = v%t * m%x t%t(1:3,0) = v%x * m%t do i = 1, 3 do j = 1, 3 t%t(i,j) = v%x(i) * m%x(j) end do end do end function out_prod_vm @ <>= pure function out_prod_mv (m, v) result (t) type(tensor) :: t type(vector), intent(in) :: v type(momentum), intent(in) :: m integer :: i, j t%t(0,0) = m%t * v%t t%t(0,1:3) = m%t * v%x t%t(1:3,0) = m%x * v%t do i = 1, 3 do j = 1, 3 t%t(i,j) = m%x(i) * v%x(j) end do end do end function out_prod_mv @ <>= pure function out_prod_mm (m, n) result (t) type(tensor) :: t type(momentum), intent(in) :: m, n integer :: i, j t%t(0,0) = m%t * n%t t%t(0,1:3) = m%t * n%x t%t(1:3,0) = m%x * n%t do i = 1, 3 do j = 1, 3 t%t(i,j) = m%x(i) * n%x(j) end do end do end function out_prod_mm @ <>= interface abs module procedure abs_tensor end interface private :: abs_tensor @ <>= pure function abs_tensor (t) result (abs_t) type(tensor), intent(in) :: t real(kind=default) :: abs_t abs_t = sqrt (sum ((abs (t%t))**2)) end function abs_tensor @ <>= interface conjg module procedure conjg_tensor end interface private :: conjg_tensor @ <>= pure function conjg_tensor (t) result (conjg_t) type(tensor), intent(in) :: t type(tensor) :: conjg_t conjg_t%t = conjg (t%t) end function conjg_tensor @ <>= interface operator (*) module procedure tensor_tensor, vector_tensor, tensor_vector, & momentum_tensor, tensor_momentum end interface private :: tensor_tensor, vector_tensor, tensor_vector, & momentum_tensor, tensor_momentum @ <>= pure function tensor_tensor (t1, t2) result (t1t2) type(tensor), intent(in) :: t1 type(tensor), intent(in) :: t2 complex(kind=default) :: t1t2 integer :: i1, i2 t1t2 = t1%t(0,0)*t2%t(0,0) & - dot_product (conjg (t1%t(0,1:)), t2%t(0,1:)) & - dot_product (conjg (t1%t(1:,0)), t2%t(1:,0)) do i1 = 1, 3 do i2 = 1, 3 t1t2 = t1t2 + t1%t(i1,i2)*t2%t(i1,i2) end do end do end function tensor_tensor @ <>= pure function tensor_vector (t, v) result (tv) type(tensor), intent(in) :: t type(vector), intent(in) :: v type(vector) :: tv tv%t = t%t(0,0) * v%t - dot_product (conjg (t%t(0,1:)), v%x) tv%x(1) = t%t(0,1) * v%t - dot_product (conjg (t%t(1,1:)), v%x) tv%x(2) = t%t(0,2) * v%t - dot_product (conjg (t%t(2,1:)), v%x) tv%x(3) = t%t(0,3) * v%t - dot_product (conjg (t%t(3,1:)), v%x) end function tensor_vector @ <>= pure function vector_tensor (v, t) result (vt) type(vector), intent(in) :: v type(tensor), intent(in) :: t type(vector) :: vt vt%t = v%t * t%t(0,0) - dot_product (conjg (v%x), t%t(1:,0)) vt%x(1) = v%t * t%t(0,1) - dot_product (conjg (v%x), t%t(1:,1)) vt%x(2) = v%t * t%t(0,2) - dot_product (conjg (v%x), t%t(1:,2)) vt%x(3) = v%t * t%t(0,3) - dot_product (conjg (v%x), t%t(1:,3)) end function vector_tensor @ <>= pure function tensor_momentum (t, p) result (tp) type(tensor), intent(in) :: t type(momentum), intent(in) :: p type(vector) :: tp tp%t = t%t(0,0) * p%t - dot_product (conjg (t%t(0,1:)), p%x) tp%x(1) = t%t(0,1) * p%t - dot_product (conjg (t%t(1,1:)), p%x) tp%x(2) = t%t(0,2) * p%t - dot_product (conjg (t%t(2,1:)), p%x) tp%x(3) = t%t(0,3) * p%t - dot_product (conjg (t%t(3,1:)), p%x) end function tensor_momentum @ <>= pure function momentum_tensor (p, t) result (pt) type(momentum), intent(in) :: p type(tensor), intent(in) :: t type(vector) :: pt pt%t = p%t * t%t(0,0) - dot_product (p%x, t%t(1:,0)) pt%x(1) = p%t * t%t(0,1) - dot_product (p%x, t%t(1:,1)) pt%x(2) = p%t * t%t(0,2) - dot_product (p%x, t%t(1:,2)) pt%x(3) = p%t * t%t(0,3) - dot_product (p%x, t%t(1:,3)) end function momentum_tensor @ \section{Symmetric Polarization Tensors} \begin{subequations} \begin{align} \epsilon^{\mu\nu}_{+2}(k) &= \epsilon^{\mu}_{+}(k)\epsilon^{\nu}_{+}(k) \\ \epsilon^{\mu\nu}_{+1}(k) &= \frac{1}{\sqrt{2}} \left( \epsilon^{\mu}_{+}(k)\epsilon^{\nu}_{0}(k) + \epsilon^{\mu}_{0}(k)\epsilon^{\nu}_{+}(k) \right) \\ \epsilon^{\mu\nu}_{0}(k) &= \frac{1}{\sqrt{6}} \left( \epsilon^{\mu}_{+}(k)\epsilon^{\nu}_{-}(k) + \epsilon^{\mu}_{-}(k)\epsilon^{\nu}_{+}(k) - 2 \epsilon^{\mu}_{0}(k)\epsilon^{\nu}_{0}(k) \right) \\ \epsilon^{\mu\nu}_{-1}(k) &= \frac{1}{\sqrt{2}} \left( \epsilon^{\mu}_{-}(k)\epsilon^{\nu}_{0}(k) + \epsilon^{\mu}_{0}(k)\epsilon^{\nu}_{-}(k) \right) \\ \epsilon^{\mu\nu}_{-2}(k) &= \epsilon^{\mu}_{-}(k)\epsilon^{\nu}_{-}(k) \end{align} \end{subequations} Note that~$\epsilon^{\mu}_{\pm2,\mu}(k) = \epsilon^{\mu}_{\pm}(k)\epsilon_{\pm,\mu}(k) \propto \epsilon^{\mu}_{\pm}(k)\epsilon_{\mp,\mu}^{*}(k) = 0$ and that the sign in $\epsilon^{\mu\nu}_{0}(k)$ insures its tracelessness\footnote{ On the other hand, with the shift operator $L_{-}\ket{+}=\ee^{\ii\phi}\ket{0}$ and $L_{-}\ket{0}=\ee^{\ii\chi}\ket{-}$, we find \begin{equation*} L_{-}^{2}\ket{++} = 2\ee^{2\ii\phi}\ket{00} + \ee^{\ii(\phi+\chi)}(\ket{+-}+\ket{-+}) \end{equation*} i.\,e.~$\chi-\phi=\pi$, if we want to identify $\epsilon^{\mu}_{-,0,+}$ with $\ket{-,0,+}$.}. <<[[omega_tensor_polarizations.f90]]>>= <> module omega_tensor_polarizations use kinds use constants use omega_vectors use omega_tensors use omega_polarizations implicit none private <> integer, parameter, public :: omega_tensor_pols_2010_01_A = 0 contains <> end module omega_tensor_polarizations @ <>= public :: eps2 @ <>= pure function eps2 (m, k, s) result (t) type(tensor) :: t real(kind=default), intent(in) :: m type(momentum), intent(in) :: k integer, intent(in) :: s type(vector) :: ep, em, e0 t%t = 0 select case (s) case (2) ep = eps (m, k, 1) t = ep.tprod.ep case (1) ep = eps (m, k, 1) e0 = eps (m, k, 0) t = (1 / sqrt (2.0_default)) & * ((ep.tprod.e0) + (e0.tprod.ep)) case (0) ep = eps (m, k, 1) e0 = eps (m, k, 0) em = eps (m, k, -1) t = (1 / sqrt (6.0_default)) & * ((ep.tprod.em) + (em.tprod.ep) - 2*(e0.tprod.e0)) case (-1) e0 = eps (m, k, 0) em = eps (m, k, -1) t = (1 / sqrt (2.0_default)) & * ((em.tprod.e0) + (e0.tprod.em)) case (-2) em = eps (m, k, -1) t = em.tprod.em end select end function eps2 @ \section{Couplings} <<[[omega_couplings.f90]]>>= <> module omega_couplings use kinds use constants use omega_vectors use omega_tensors implicit none private <> <> integer, parameter, public :: omega_couplings_2010_01_A = 0 contains <> <> end module omega_couplings @ <>= public :: wd_tl @ <>= +public :: wd_run +@ +<>= public :: gauss @ \begin{equation} \Theta(p^2)\Gamma \end{equation} <>= pure function wd_tl (p, w) result (width) real(kind=default) :: width type(momentum), intent(in) :: p real(kind=default), intent(in) :: w if (p*p > 0) then width = w else width = 0 end if end function wd_tl @ +\begin{equation} + \frac{p^2}{m^2} \Gamma +\end{equation} +<>= +pure function wd_run (p, m, w) result (width) + real(kind=default) :: width + type(momentum), intent(in) :: p + real(kind=default), intent(in) :: m + real(kind=default), intent(in) :: w + if (p*p > 0) then + width = w * (p*p) / m**2 + else + width = 0 + end if +end function wd_run +@ <>= pure function gauss (x, mu, w) result (gg) real(kind=default) :: gg real(kind=default), intent(in) :: x, mu, w if (w > 0) then gg = exp(-(x - mu**2)**2/4.0_default/mu**2/w**2) * & sqrt(sqrt(PI/2)) / w / mu else gg = 1.0_default end if end function gauss @ <>= public :: pr_phi, pr_unitarity, pr_feynman, pr_gauge, pr_rxi public :: pr_vector_pure public :: pj_phi, pj_unitarity public :: pg_phi, pg_unitarity @ \begin{equation} \frac{\ii}{p^2-m^2+\ii m\Gamma}\phi \end{equation} <>= pure function pr_phi (p, m, w, phi) result (pphi) complex(kind=default) :: pphi type(momentum), intent(in) :: p real(kind=default), intent(in) :: m, w complex(kind=default), intent(in) :: phi pphi = (1 / cmplx (p*p - m**2, m*w, kind=default)) * phi end function pr_phi @ \begin{equation} \sqrt{\frac{\pi}{M\Gamma}} \phi \end{equation} <>= pure function pj_phi (m, w, phi) result (pphi) complex(kind=default) :: pphi real(kind=default), intent(in) :: m, w complex(kind=default), intent(in) :: phi pphi = (0, -1) * sqrt (PI / m / w) * phi end function pj_phi @ <>= pure function pg_phi (p, m, w, phi) result (pphi) complex(kind=default) :: pphi type(momentum), intent(in) :: p real(kind=default), intent(in) :: m, w complex(kind=default), intent(in) :: phi pphi = ((0, 1) * gauss (p*p, m, w)) * phi end function pg_phi @ \begin{equation} \frac{\ii}{p^2-m^2+\ii m\Gamma} \left( -g_{\mu\nu} + \frac{p_\mu p_\nu}{m^2} \right) \epsilon^\nu(p) \end{equation} NB: the explicit cast to [[vector]] is required here, because a specific [[complex_momentum]] procedure for [[operator (*)]] would introduce ambiguities. NB: we used to use the constructor [[vector (p%t, p%x)]] instead of the temporary variable, but the Intel Fortran Compiler choked on it. <>= pure function pr_unitarity (p, m, w, cms, e) result (pe) type(vector) :: pe type(momentum), intent(in) :: p real(kind=default), intent(in) :: m, w type(vector), intent(in) :: e logical, intent(in) :: cms type(vector) :: pv complex(kind=default) :: c_mass2 pv = p if (cms) then c_mass2 = cmplx (m**2, -m*w, kind=default) else c_mass2 = m**2 end if pe = - (1 / cmplx (p*p - m**2, m*w, kind=default)) & * (e - (p*e / c_mass2) * pv) end function pr_unitarity @ \begin{equation} \sqrt{\frac{\pi}{M\Gamma}} \left( -g_{\mu\nu} + \frac{p_\mu p_\nu}{m^2} \right) \epsilon^\nu(p) \end{equation} <>= pure function pj_unitarity (p, m, w, e) result (pe) type(vector) :: pe type(momentum), intent(in) :: p real(kind=default), intent(in) :: m, w type(vector), intent(in) :: e type(vector) :: pv pv = p pe = (0, 1) * sqrt (PI / m / w) * (e - (p*e / m**2) * pv) end function pj_unitarity @ <>= pure function pg_unitarity (p, m, w, e) result (pe) type(vector) :: pe type(momentum), intent(in) :: p real(kind=default), intent(in) :: m, w type(vector), intent(in) :: e type(vector) :: pv pv = p pe = - gauss (p*p, m, w) & * (e - (p*e / m**2) * pv) end function pg_unitarity @ \begin{equation} \frac{-i}{p^2} \epsilon^\nu(p) \end{equation} <>= pure function pr_feynman (p, e) result (pe) type(vector) :: pe type(momentum), intent(in) :: p type(vector), intent(in) :: e pe = - (1 / (p*p)) * e end function pr_feynman @ \begin{equation} \frac{\ii}{p^2} \left( -g_{\mu\nu} + (1-\xi)\frac{p_\mu p_\nu}{p^2} \right) \epsilon^\nu(p) \end{equation} <>= pure function pr_gauge (p, xi, e) result (pe) type(vector) :: pe type(momentum), intent(in) :: p real(kind=default), intent(in) :: xi type(vector), intent(in) :: e real(kind=default) :: p2 type(vector) :: pv p2 = p*p pv = p pe = - (1 / p2) * (e - ((1 - xi) * (p*e) / p2) * pv) end function pr_gauge @ \begin{equation} \frac{\ii}{p^2-m^2+\ii m\Gamma} \left( -g_{\mu\nu} + (1-\xi)\frac{p_\mu p_\nu}{p^2-\xi m^2} \right) \epsilon^\nu(p) \end{equation} <>= pure function pr_rxi (p, m, w, xi, e) result (pe) type(vector) :: pe type(momentum), intent(in) :: p real(kind=default), intent(in) :: m, w, xi type(vector), intent(in) :: e real(kind=default) :: p2 type(vector) :: pv p2 = p*p pv = p pe = - (1 / cmplx (p2 - m**2, m*w, kind=default)) & * (e - ((1 - xi) * (p*e) / (p2 - xi * m**2)) * pv) end function pr_rxi @ \begin{equation} \frac{\ii}{p^2-m^2+\ii m\Gamma} \left( -g_{\mu\nu} \right) \epsilon^\nu(p) \end{equation} <>= pure function pr_vector_pure (p, m, w, e) result (pe) type(vector) :: pe type(momentum), intent(in) :: p real(kind=default), intent(in) :: m, w type(vector), intent(in) :: e real(kind=default) :: p2 type(vector) :: pv p2 = p*p pv = p pe = - (1 / cmplx (p2 - m**2, m*w, kind=default)) * e end function pr_vector_pure @ <>= public :: pr_tensor, pr_tensor_pure @ \begin{subequations} \begin{equation} \frac{\ii P^{\mu\nu,\rho\sigma}(p,m)}{p^2-m^2+\ii m\Gamma} T_{\rho\sigma} \end{equation} with \begin{multline} P^{\mu\nu,\rho\sigma}(p,m) = \frac{1}{2} \left(g^{\mu\rho}-\frac{p^{\mu}p^{\nu}}{m^2}\right) \left(g^{\nu\sigma}-\frac{p^{\nu}p^{\sigma}}{m^2}\right) + \frac{1}{2} \left(g^{\mu\sigma}-\frac{p^{\mu}p^{\sigma}}{m^2}\right) \left(g^{\nu\rho}-\frac{p^{\nu}p^{\rho}}{m^2}\right) \\ - \frac{1}{3} \left(g^{\mu\nu}-\frac{p^{\mu}p^{\nu}}{m^2}\right) \left(g^{\rho\sigma}-\frac{p^{\rho}p^{\sigma}}{m^2}\right) \end{multline} \end{subequations} Be careful with raising and lowering of indices: \begin{subequations} \begin{align} g^{\mu\nu}-\frac{k^{\mu}k^{\nu}}{m^2} &= \begin{pmatrix} 1 - k^0k^0 / m^2 & - k^0 \vec k / m^2 \\ - \vec k k^0 / m^2 & - \mathbf{1} - \vec k \otimes \vec k / m^2 \end{pmatrix} \\ g^{\mu}_{\hphantom{\mu}\nu}-\frac{k^{\mu}k_{\nu}}{m^2} &= \begin{pmatrix} 1 - k^0k^0 / m^2 & k^0 \vec k / m^2 \\ - \vec k k^0 / m^2 & \mathbf{1} + \vec k \otimes \vec k / m^2 \end{pmatrix} \end{align} \end{subequations} <>= pure function pr_tensor (p, m, w, t) result (pt) type(tensor) :: pt type(momentum), intent(in) :: p real(kind=default), intent(in) :: m, w type(tensor), intent(in) :: t complex(kind=default) :: p_dd_t real(kind=default), dimension(0:3,0:3) :: p_uu, p_ud, p_du, p_dd integer :: i, j p_uu(0,0) = 1 - p%t * p%t / m**2 p_uu(0,1:3) = - p%t * p%x / m**2 p_uu(1:3,0) = p_uu(0,1:3) do i = 1, 3 do j = 1, 3 p_uu(i,j) = - p%x(i) * p%x(j) / m**2 end do end do do i = 1, 3 p_uu(i,i) = - 1 + p_uu(i,i) end do p_ud(:,0) = p_uu(:,0) p_ud(:,1:3) = - p_uu(:,1:3) p_du = transpose (p_ud) p_dd(:,0) = p_du(:,0) p_dd(:,1:3) = - p_du(:,1:3) p_dd_t = 0 do i = 0, 3 do j = 0, 3 p_dd_t = p_dd_t + p_dd(i,j) * t%t(i,j) end do end do pt%t = matmul (p_ud, matmul (0.5_default * (t%t + transpose (t%t)), p_du)) & - (p_dd_t / 3.0_default) * p_uu pt%t = pt%t / cmplx (p*p - m**2, m*w, kind=default) end function pr_tensor @ \begin{subequations} \begin{equation} \frac{\ii P_p^{\mu\nu,\rho\sigma}}{p^2-m^2+\ii m\Gamma} T_{\rho\sigma} \end{equation} with \begin{multline} P_p^{\mu\nu,\rho\sigma} = \frac{1}{2} g^{\mu\rho} g^{\nu\sigma} + \frac{1}{2} g^{\mu\sigma} g^{\nu\rho} - \frac{1}{2} g^{\mu\nu}g^{\rho\sigma} \end{multline} \end{subequations} <>= pure function pr_tensor_pure (p, m, w, t) result (pt) type(tensor) :: pt type(momentum), intent(in) :: p real(kind=default), intent(in) :: m, w type(tensor), intent(in) :: t complex(kind=default) :: p_dd_t real(kind=default), dimension(0:3,0:3) :: g_uu integer :: i, j g_uu(0,0) = 1 g_uu(0,1:3) = 0 g_uu(1:3,0) = g_uu(0,1:3) do i = 1, 3 do j = 1, 3 g_uu(i,j) = 0 end do end do do i = 1, 3 g_uu(i,i) = - 1 end do p_dd_t = t%t(0,0) - t%t(1,1) - t%t(2,2) - t%t(3,3) pt%t = 0.5_default * ((t%t + transpose (t%t)) & - p_dd_t * g_uu ) pt%t = pt%t / cmplx (p*p - m**2, m*w, kind=default) end function pr_tensor_pure @ \subsection{Triple Gauge Couplings} <>= public :: g_gg @ According to~(\ref{eq:fuse-gauge}) \begin{multline} A^{a,\mu}(k_1+k_2) = - \ii g \bigl( (k_1^{\mu}-k_2^{\mu})A^{a_1}(k_1) \cdot A^{a_2}(k_2) \\ + (2k_2+k_1)\cdot A^{a_1}(k_1)A^{a_2,\mu}(k_2) - A^{a_1,\mu}(k_1)A^{a_2}(k_2)\cdot(2k_1+k_2) \bigr) \end{multline} <>= pure function g_gg (g, a1, k1, a2, k2) result (a) complex(kind=default), intent(in) :: g type(vector), intent(in) :: a1, a2 type(momentum), intent(in) :: k1, k2 type(vector) :: a a = (0, -1) * g * ((k1 - k2) * (a1 * a2) & + ((2*k2 + k1) * a1) * a2 - a1 * ((2*k1 + k2) * a2)) end function g_gg @ \subsection{Quadruple Gauge Couplings} <>= public :: x_gg, g_gx @ \begin{equation} T^{a,\mu\nu}(k_1+k_2) = g \bigl( A^{a_1,\mu}(k_1) A^{a_2,\nu}(k_2) - A^{a_1,\nu}(k_1) A^{a_2,\mu}(k_2) \bigr) \end{equation} <>= pure function x_gg (g, a1, a2) result (x) complex(kind=default), intent(in) :: g type(vector), intent(in) :: a1, a2 type(tensor2odd) :: x x = g * (a1 .wedge. a2) end function x_gg @ \begin{equation} A^{a,\mu}(k_1+k_2) = g A^{a_1}_\nu(k_1) T^{a_2,\nu\mu}(k_2) \end{equation} <>= pure function g_gx (g, a1, x) result (a) complex(kind=default), intent(in) :: g type(vector), intent(in) :: a1 type(tensor2odd), intent(in) :: x type(vector) :: a a = g * (a1 * x) end function g_gx @ \subsection{Scalar Current} <>= public :: v_ss, s_vs @ \begin{equation} V^\mu(k_1+k_2) = g(k_1^\mu - k_2^\mu)\phi_1(k_1)\phi_2(k_2) \end{equation} <>= pure function v_ss (g, phi1, k1, phi2, k2) result (v) complex(kind=default), intent(in) :: g, phi1, phi2 type(momentum), intent(in) :: k1, k2 type(vector) :: v v = (k1 - k2) * (g * phi1 * phi2) end function v_ss @ \begin{equation} \phi(k_1+k_2) = g(k_1^\mu + 2k_2^\mu)V_\mu(k_1)\phi(k_2) \end{equation} <>= pure function s_vs (g, v1, k1, phi2, k2) result (phi) complex(kind=default), intent(in) :: g, phi2 type(vector), intent(in) :: v1 type(momentum), intent(in) :: k1, k2 complex(kind=default) :: phi phi = g * ((k1 + 2*k2) * v1) * phi2 end function s_vs @ \subsection{Transversal Scalar-Vector Coupling} <>= public :: s_vv_t, v_sv_t @ \begin{equation} phi(k_1+k_2) = g((V_1(k_1) V_2(k_2))(k_1 k_2) - (V_1(k_1) k_2)(V_2(k_2) k_1)) \end{equation} <>= pure function s_vv_t (g, v1, k1, v2, k2) result (phi) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 complex(kind=default) :: phi phi = g * ((v1*v2) * (k1*k2) - (v1*k2) * (v2*k1)) end function s_vv_t @ \begin{equation} V_1^\mu(k_\phi+k_V) = g phi(((k_\phi+k_V)k_V)V_2^\mu- (k_\phi+k_V)V_2)k_V^\mu ) \end{equation} <>= pure function v_sv_t (g, phi, kphi,v, kv) result (vout) complex(kind=default), intent(in) :: g, phi type(vector), intent(in) :: v type(momentum), intent(in) :: kv, kphi type(momentum) :: kout type(vector) :: vout kout = - (kv + kphi) vout = g * phi * ((kout*kv) * v - (v * kout) * kv) end function v_sv_t @ \subsection{Transversal TensorScalar-Vector Coupling} <>= public :: tphi_vv, tphi_vv_cf, v_tphiv, v_tphiv_cf @ \begin{equation} phi(k_1 + k_2) = g (V_1(k_1) (k_1 +k_2)) * ( V_2(k_2) (k_1 + k_2)) \end{equation} <>= pure function tphi_vv (g, v1, k1, v2, k2) result (phi) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 complex(kind=default) :: phi type(momentum) :: k k = - (k1 + k2) phi = 2 * g * (v1*k) * (v2*k) end function tphi_vv @ \begin{equation} phi(k_1+k_2) = g((V_1(k_1) V_2(k_2))(k_1 + k_2)^2) \end{equation} <>= pure function tphi_vv_cf (g, v1, k1, v2, k2) result (phi) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 complex(kind=default) :: phi type(momentum) :: k k = - (k1 + k2) phi = - g/2 * (v1*v2) * (k*k) end function tphi_vv_cf @ \begin{equation} V_1^\mu(k_\phi+k_V) = g phi ((k_\phi+k_V)V_2) (k_\phi+k_V)^\mu \end{equation} <>= pure function v_tphiv (g, phi, kphi,v, kv) result (vout) complex(kind=default), intent(in) :: g, phi type(vector), intent(in) :: v type(momentum), intent(in) :: kv, kphi type(momentum) :: kout type(vector) :: vout kout = - (kv + kphi) vout = 2 * g * phi * ((v * kout) * kout) end function v_tphiv @ \begin{equation} V_1^\mu(k_\phi+k_V) = g phi((k_\phi+k_V)(k_\phi+k_V))V_2^\mu \end{equation} <>= pure function v_tphiv_cf (g, phi, kphi,v, kv) result (vout) complex(kind=default), intent(in) :: g, phi type(vector), intent(in) :: v type(momentum), intent(in) :: kv, kphi type(momentum) :: kout type(vector) :: vout kout = - (kv + kphi) vout = -g/2 * phi * (kout*kout) * v end function v_tphiv_cf @ \subsection{Triple Vector Couplings} <>= public :: tkv_vv, lkv_vv, tv_kvv, lv_kvv, kg_kgkg public :: t5kv_vv, l5kv_vv, t5v_kvv, l5v_kvv, kg5_kgkg, kg_kg5kg public :: dv_vv, v_dvv, dv_vv_cf, v_dvv_cf @ \begin{equation} V^\mu(k_1+k_2) = \ii g(k_1-k_2)^\mu V_1^\nu(k_1)V_{2,\nu}(k_2) \end{equation} <>= pure function tkv_vv (g, v1, k1, v2, k2) result (v) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(vector) :: v v = (k1 - k2) * ((0, 1) * g * (v1*v2)) end function tkv_vv @ \begin{equation} V^\mu(k_1+k_2) = \ii g \epsilon^{\mu\nu\rho\sigma} (k_1-k_2)_{\nu} V_{1,\rho}(k_1)V_{2,\sigma}(k_2) \end{equation} <>= pure function t5kv_vv (g, v1, k1, v2, k2) result (v) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(vector) :: v type(vector) :: k k = k1 - k2 v = (0, 1) * g * pseudo_vector (k, v1, v2) end function t5kv_vv @ \begin{equation} V^\mu(k_1+k_2) = \ii g(k_1+k_2)^\mu V_1^\nu(k_1)V_{2,\nu}(k_2) \end{equation} <>= pure function lkv_vv (g, v1, k1, v2, k2) result (v) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(vector) :: v v = (k1 + k2) * ((0, 1) * g * (v1*v2)) end function lkv_vv @ \begin{equation} V^\mu(k_1+k_2) = \ii g \epsilon^{\mu\nu\rho\sigma} (k_1+k_2)_{\nu} V_{1,\rho}(k_1)V_{2,\sigma}(k_2) \end{equation} <>= pure function l5kv_vv (g, v1, k1, v2, k2) result (v) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(vector) :: v type(vector) :: k k = k1 + k2 v = (0, 1) * g * pseudo_vector (k, v1, v2) end function l5kv_vv @ \begin{equation} V^\mu(k_1+k_2) = \ii g (k_2-k)^\nu V_{1,\nu}(k_1)V_2^\mu(k_2) = \ii g (2k_2+k_1)^\nu V_{1,\nu}(k_1)V_2^\mu(k_2) \end{equation} using $k=-k_1-k_2$ <>= pure function tv_kvv (g, v1, k1, v2, k2) result (v) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(vector) :: v v = v2 * ((0, 1) * g * ((2*k2 + k1)*v1)) end function tv_kvv @ \begin{equation} V^\mu(k_1+k_2) = \ii g \epsilon^{\mu\nu\rho\sigma} (2k_2+k_1)_{\nu} V_{1,\rho}(k_1)V_{2,\sigma}(k_2) \end{equation} <>= pure function t5v_kvv (g, v1, k1, v2, k2) result (v) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(vector) :: v type(vector) :: k k = k1 + 2*k2 v = (0, 1) * g * pseudo_vector (k, v1, v2) end function t5v_kvv @ \begin{equation} V^\mu(k_1+k_2) = - \ii g k_1^\nu V_{1,\nu}(k_1)V_2^\mu(k_2) \end{equation} using $k=-k_1-k_2$ <>= pure function lv_kvv (g, v1, k1, v2) result (v) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1 type(vector) :: v v = v2 * ((0, -1) * g * (k1*v1)) end function lv_kvv @ \begin{equation} V^\mu(k_1+k_2) = - \ii g \epsilon^{\mu\nu\rho\sigma} k_{1,\nu} V_{1,\rho}(k_1)V_{2,\sigma}(k_2) \end{equation} <>= pure function l5v_kvv (g, v1, k1, v2) result (v) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1 type(vector) :: v type(vector) :: k k = k1 v = (0, -1) * g * pseudo_vector (k, v1, v2) end function l5v_kvv @ \begin{equation} A^\mu(k_1+k_2) = \ii g k^\nu \Bigl( F_{1,\nu}^{\hphantom{1,\nu}\rho}(k_1)F_{2,\rho\mu}(k_2) - F_{1,\mu}^{\hphantom{1,\mu}\rho}(k_1)F_{2,\rho\nu}(k_2) \Bigr) \end{equation} with $k=-k_1-k_2$, i.\,e. \begin{multline} A^\mu(k_1+k_2) = -\ii g \Bigl( [(kk_2)(k_1A_2) - (k_1k_2)(kA_2)] A_1^\mu \\ + [(k_1k_2)(kA_1) - (kk_1)(k_2A_1)] A_2^\mu \\ + [(k_2A_1)(kA_2) - (kk_2)(A_1A_2)] k_1^\mu \\ + [(kk_1)(A_1A_2) - (kA_1)(k_1A_2)] k_2^\mu \Bigr) \end{multline} <>= pure function kg_kgkg (g, a1, k1, a2, k2) result (a) complex(kind=default), intent(in) :: g type(vector), intent(in) :: a1, a2 type(momentum), intent(in) :: k1, k2 type(vector) :: a real(kind=default) :: k1k1, k2k2, k1k2, kk1, kk2 complex(kind=default) :: a1a2, k2a1, ka1, k1a2, ka2 k1k1 = k1 * k1 k1k2 = k1 * k2 k2k2 = k2 * k2 kk1 = k1k1 + k1k2 kk2 = k1k2 + k2k2 k2a1 = k2 * a1 ka1 = k2a1 + k1 * a1 k1a2 = k1 * a2 ka2 = k1a2 + k2 * a2 a1a2 = a1 * a2 a = (0, -1) * g * ( (kk2 * k1a2 - k1k2 * ka2 ) * a1 & + (k1k2 * ka1 - kk1 * k2a1) * a2 & + (ka2 * k2a1 - kk2 * a1a2) * k1 & + (kk1 * a1a2 - ka1 * k1a2) * k2 ) end function kg_kgkg @ \begin{equation} A^\mu(k_1+k_2) = \ii g \epsilon^{\mu\nu\rho\sigma} k_{\nu} F_{1,\rho}^{\hphantom{1,\rho}\lambda}(k_1)F_{2,\lambda\sigma}(k_2) \end{equation} with $k=-k_1-k_2$, i.\,e. \begin{multline} A^\mu(k_1+k_2) = -2\ii g \epsilon^{\mu\nu\rho\sigma} k_{\nu} \Bigl( (k_2A_1) k_{1,\rho} A_{2,\sigma} + (k_1A_2) A_{1,\rho} k_{2,\sigma} \\ - (A_1A_2) k_{1,\rho} k_{2,\sigma} - (k_1k_2) A_{1,\rho} A_{2,\sigma} \Bigr) \end{multline} <>= pure function kg5_kgkg (g, a1, k1, a2, k2) result (a) complex(kind=default), intent(in) :: g type(vector), intent(in) :: a1, a2 type(momentum), intent(in) :: k1, k2 type(vector) :: a type(vector) :: kv, k1v, k2v kv = - k1 - k2 k1v = k1 k2v = k2 a = (0, -2) * g * ( (k2*A1) * pseudo_vector (kv, k1v, a2 ) & + (k1*A2) * pseudo_vector (kv, A1 , k2v) & - (A1*A2) * pseudo_vector (kv, k1v, k2v) & - (k1*k2) * pseudo_vector (kv, a1 , a2 ) ) end function kg5_kgkg @ \begin{equation} A^\mu(k_1+k_2) = \ii g k_{\nu} \Bigl( \epsilon^{\mu\rho\lambda\sigma} F_{1,\hphantom{\nu}\rho}^{\hphantom{1,}\nu} - \epsilon^{\nu\rho\lambda\sigma} F_{1,\hphantom{\mu}\rho}^{\hphantom{1,}\mu} \Bigr) \frac{1}{2} F_{1,\lambda\sigma} \end{equation} with $k=-k_1-k_2$, i.\,e. \begin{multline} A^\mu(k_1+k_2) = -\ii g \Bigl( \epsilon^{\mu\rho\lambda\sigma} (kk_2) A_{2,\rho} - \epsilon^{\mu\rho\lambda\sigma} (kA_2) k_{2,\rho} - k_2^\mu \epsilon^{\nu\rho\lambda\sigma} k_nu A_{2,\rho} + A_2^\mu \epsilon^{\nu\rho\lambda\sigma} k_nu k_{2,\rho} \Bigr) k_{1,\lambda} A_{1,\sigma} \end{multline} \begin{dubious} This is not the most efficienct way of doing it: $\epsilon^{\mu\nu\rho\sigma}F_{1,\rho\sigma}$ should be cached! \end{dubious} <>= pure function kg_kg5kg (g, a1, k1, a2, k2) result (a) complex(kind=default), intent(in) :: g type(vector), intent(in) :: a1, a2 type(momentum), intent(in) :: k1, k2 type(vector) :: a type(vector) :: kv, k1v, k2v kv = - k1 - k2 k1v = k1 k2v = k2 a = (0, -1) * g * ( (kv*k2v) * pseudo_vector (a2 , k1v, a1) & - (kv*a2 ) * pseudo_vector (k2v, k1v, a1) & - k2v * pseudo_scalar (kv, a2, k1v, a1) & + a2 * pseudo_scalar (kv, k2v, k1v, a1) ) end function kg_kg5kg @ \begin{equation} V^\mu(k_1+k_2) = - g ((k_1+k_2) V_{1}) V_{2}^\mu + ((k_1+k_2) V_{2}) V_{1}^\mu \end{equation} <>= pure function dv_vv (g, v1, k1, v2, k2) result (v) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(vector) :: v type(vector) :: k k = -(k1 + k2) v = g * ((k * v1) * v2 + (k * v2) * v1) end function dv_vv @ \begin{equation} V^\mu(k_1+k_2) = \frac{g}{2} ( V_{1} (k_{1}) V_{2} (k_{2}) ) (k_{1}+k_{2})^\mu \end{equation} <>= pure function dv_vv_cf (g, v1, k1, v2, k2) result (v) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(vector) :: v type(vector) :: k k = -(k1 + k2) v = - g/2 * (v1 * v2) * k end function dv_vv_cf @ \begin{equation} V_{1}^\mu = g * ( k V_{2}) V (k) + ( V V_{2}) k \end{equation} <>= pure function v_dvv (g, v, k, v2) result (v1) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v, v2 type(momentum), intent(in) :: k type(vector) :: v1 v1 = g * ((v * v2) * k + (k * v2) * v) end function v_dvv @ \begin{equation} V_{1}^\mu = -\frac{g}{2} ( V (k) k ) V_{2}^\mu \end{equation} <>= pure function v_dvv_cf (g, v, k, v2) result (v1) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v, v2 type(momentum), intent(in) :: k type(vector) :: v1 v1 = - g/2 * (v * k) * v2 end function v_dvv_cf @ \section{Tensorvector - Scalar coupling } <>= public :: dv_phi2,phi_dvphi, dv_phi2_cf, phi_dvphi_cf @ \begin{equation} V^\mu (k_1 + k_2 ) = g* ((k_1 k_2 + k_2 k_2) k_1^\mu + (k_1 k_2 + k_1 k_1) k_2^\mu ) * phi_1 (k_1) phi_2 (k_2) \end{equation} <>= pure function dv_phi2 (g, phi1, k1, phi2, k2) result (v) complex(kind=default), intent(in) :: g, phi1, phi2 type(momentum), intent(in) :: k1, k2 type(vector) :: v v = g * phi1 * phi2 * ( & (k1 * k2 + k2 * k2 ) * k1 + & (k1 * k2 + k1 * k1 ) * k2 ) end function dv_phi2 @ \begin{equation} V^\mu (k_1 + k_2 ) = - \frac{g}{2} * (k_1 k_2) * (k_1 + k_2 )^\mu * phi_1 (k_1) phi_2 (k_2) \end{equation} <>= pure function dv_phi2_cf (g, phi1, k1, phi2, k2) result (v) complex(kind=default), intent(in) :: g, phi1, phi2 type(momentum), intent(in) :: k1, k2 type(vector) :: v v = - g/2 * phi1 * phi2 * (k1 * k2) * (k1 + k2) end function dv_phi2_cf @ \begin{equation} phi_1 (k_1) = g * ((k_1 k_2 + k_2 k_2) (k_1 * V(-k_1 - k_2) ) + (k_1 k_2 + k_1 k_1) (k_2 * V(-k_1 - k_2) ) ) * phi_2 (k_2) \end{equation} <>= pure function phi_dvphi (g, v, k, phi2, k2) result (phi1) complex(kind=default), intent(in) :: g, phi2 type(vector), intent(in) :: v type(momentum), intent(in) :: k, k2 complex(kind=default) :: phi1 type(momentum) :: k1 k1 = - (k + k2) phi1 = g * phi2 * ( & (k1 * k2 + k2 * k2 ) * ( k1 * V ) + & (k1 * k2 + k1 * k1 ) * ( k2 * V ) ) end function phi_dvphi @ \begin{equation} phi_1 (k_1 ) = - \frac{g}{2} * (k_1 k_2) * ((k_1 + k_2 ) V(- k_1 - k_2)) \end{equation} <>= pure function phi_dvphi_cf (g, v, k, phi2, k2) result (phi1) complex(kind=default), intent(in) :: g, phi2 type(vector), intent(in) :: v type(momentum), intent(in) :: k, k2 complex(kind=default) :: phi1 type(momentum) :: k1 k1 = -(k + k2) phi1 = - g/2 * phi2 * (k1 * k2) * ((k1 + k2) * v) end function phi_dvphi_cf @ \section{Scalar-Vector Dim-5 Couplings} <>= public :: phi_vv, v_phiv, phi_u_vv, v_u_phiv @ <>= pure function phi_vv (g, k1, k2, v1, v2) result (phi) complex(kind=default), intent(in) :: g type(momentum), intent(in) :: k1, k2 type(vector), intent(in) :: v1, v2 complex(kind=default) :: phi phi = g * pseudo_scalar (k1, v1, k2, v2) end function phi_vv @ <>= pure function v_phiv (g, phi, k1, k2, v) result (w) complex(kind=default), intent(in) :: g, phi type(vector), intent(in) :: v type(momentum), intent(in) :: k1, k2 type(vector) :: w w = g * phi * pseudo_vector (k1, k2, v) end function v_phiv @ <>= pure function phi_u_vv (g, k1, k2, v1, v2) result (phi) complex(kind=default), intent(in) :: g type(momentum), intent(in) :: k1, k2 type(vector), intent(in) :: v1, v2 complex(kind=default) :: phi phi = g * ((k1*v2)*((-(k1+k2))*v1) + & (k2*v1)*((-(k1+k2))*v2) + & (((k1+k2)*(k1+k2)) * (v1*v2))) end function phi_u_vv @ <>= pure function v_u_phiv (g, phi, k1, k2, v) result (w) complex(kind=default), intent(in) :: g, phi type(vector), intent(in) :: v type(momentum), intent(in) :: k1, k2 type(vector) :: w w = g * phi * ((k1*v)*k2 + & ((-(k1+k2))*v)*k1 + & ((k1*k1)*v)) end function v_u_phiv @ \section{Dim-6 Anoumalous Couplings with Higgs} <>= public :: s_vv_6D, v_sv_6D, s_vv_6DP, v_sv_6DP, a_hz_D, h_az_D, z_ah_D, & a_hz_DP, h_az_DP, z_ah_DP, h_hh_6 <>= pure function s_vv_6D (g, v1, k1, v2, k2) result (phi) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 complex(kind=default) :: phi phi = g * (-(k1 * v1) * (k1 * v2) - (k2 * v1) * (k2 * v2) & + ((k1 * k1) + (k2 * k2)) * (v1 * v2)) end function s_vv_6D <>= pure function v_sv_6D (g, phi, kphi, v, kv) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: phi type(vector), intent(in) :: v type(momentum), intent(in) :: kphi, kv type(vector) :: vout vout = g * ( - phi * (kv * v) * kv - phi * ((kphi + kv) * v) * (kphi + kv) & + phi * (kv * kv) * v + phi * ((kphi + kv)*(kphi + kv)) * v) end function v_sv_6D <>= pure function s_vv_6DP (g, v1, k1, v2, k2) result (phi) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 complex(kind=default) :: phi phi = g * ( (-(k1+k2)*v1) * (k1*v2) - ((k1+k2)*v2) * (k2*v1) + & ((k1+k2)*(k1+k2))*(v1*v2) ) end function s_vv_6DP <>= pure function v_sv_6DP (g, phi, kphi, v, kv) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: phi type(vector), intent(in) :: v type(momentum), intent(in) :: kphi, kv type(vector) :: vout vout = g * phi * ((-(kphi + kv)*v) * kphi + (kphi * v) * kv + & (kphi*kphi) * v ) end function v_sv_6DP <>= pure function a_hz_D (g, h1, k1, v2, k2) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1 type(vector), intent(in) :: v2 type(momentum), intent(in) :: k1, k2 type(vector) :: vout vout = g * h1 * (((k1 + k2) * v2) * (k1 + k2) + & ((k1 + k2) * (k1 + k2)) * v2) end function a_hz_D <>= pure function h_az_D (g, v1, k1, v2, k2) result (hout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 complex(kind=default) :: hout hout = g * ((k1 * v1) * (k1 * v2) + (k1 * k1) * (v1 * v2)) end function h_az_D <>= pure function z_ah_D (g, v1, k1, h2, k2) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h2 type(vector), intent(in) :: v1 type(momentum), intent(in) :: k1, k2 type(vector) :: vout vout = g * h2 * ((k1 * v1) * k1 + ((k1 * k1)) *v1) end function z_ah_D <>= pure function a_hz_DP (g, h1, k1, v2, k2) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1 type(vector), intent(in) :: v2 type(momentum), intent(in) :: k1, k2 type(vector) :: vout vout = g * ((- h1 * (k1 + k2) * v2) * (k1) & + h1 * ((k1 + k2) * (k1)) *v2) end function a_hz_DP <>= pure function h_az_DP (g, v1, k1, v2, k2) result (hout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 complex(kind=default) :: hout hout = g * (- (k1 * v2) * ((k1 + k2) * v1) + (k1 * (k1 + k2)) * (v1 * v2)) end function h_az_DP <>= pure function z_ah_DP (g, v1, k1, h2, k2) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h2 type(vector), intent(in) :: v1 type(momentum), intent(in) :: k1, k2 type(vector) :: vout vout = g * h2* ((k2 * v1) * k1 - (k1 * k2) * v1) end function z_ah_DP <>= pure function h_hh_6 (g, h1, k1, h2, k2) result (hout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1, h2 type(momentum), intent(in) :: k1, k2 complex(kind=default) :: hout hout = g * ((k1* k1) + (k2 * k2) + (k1* k2)) * h1 * h2 end function h_hh_6 @ \section{Dim-6 Anoumalous Couplings without Higgs} <>= public :: g_gg_13, g_gg_23, g_gg_6, kg_kgkg_i <>= pure function g_gg_23 (g, v1, k1, v2, k2) result (vout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(vector) :: vout vout = g * (v1 * (-2*(k1*v2)) + v2 * (2*k2 * v1) + (k1 - k2) * (v1*v2)) end function g_gg_23 <>= pure function g_gg_13 (g, v1, k1, v2, k2) result (vout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(vector) :: vout vout = g * (v1 * (2*(k1 + k2)*v2) - v2 * ((k1 + 2*k2) * v1) + 2*k2 * (v1 * v2)) end function g_gg_13 <>= pure function g_gg_6 (g, v1, k1, v2, k2) result (vout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(vector) :: vout vout = g * & ( k1 * ((-(k1 + k2) * v2) * (k2 * v1) + ((k1 + k2) * k2) * (v1 * v2)) & + k2 * (((k1 + k2) * v1) * (k1 * v2) - ((k1 + k2) * k1) * (v1 * v2)) & + v1 * (-((k1 + k2) * k2) * (k1 * v2) + (k1 * k2) * ((k1 + k2) * v2)) & + v2 * (((k1 + k2) * k1) * (k2 * v1) - (k1 * k2) * ((k1 + k2) * v1))) end function g_gg_6 <>= pure function kg_kgkg_i (g, a1, k1, a2, k2) result (a) complex(kind=default), intent(in) :: g type(vector), intent(in) :: a1, a2 type(momentum), intent(in) :: k1, k2 type(vector) :: a real(kind=default) :: k1k1, k2k2, k1k2, kk1, kk2 complex(kind=default) :: a1a2, k2a1, ka1, k1a2, ka2 k1k1 = k1 * k1 k1k2 = k1 * k2 k2k2 = k2 * k2 kk1 = k1k1 + k1k2 kk2 = k1k2 + k2k2 k2a1 = k2 * a1 ka1 = k2a1 + k1 * a1 k1a2 = k1 * a2 ka2 = k1a2 + k2 * a2 a1a2 = a1 * a2 a = (-1) * g * ( (kk2 * k1a2 - k1k2 * ka2 ) * a1 & + (k1k2 * ka1 - kk1 * k2a1) * a2 & + (ka2 * k2a1 - kk2 * a1a2) * k1 & + (kk1 * a1a2 - ka1 * k1a2) * k2 ) end function kg_kgkg_i @ \section{Dim-6 Anoumalous Couplings with AWW} <>= public ::a_ww_DP, w_aw_DP, a_ww_DW <>= pure function a_ww_DP (g, v1, k1, v2, k2) result (vout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(vector) :: vout vout = g * ( - ((k1 + k2) * v2) * v1 + ((k1 + k2) * v1) * v2) end function a_ww_DP <>= pure function w_aw_DP (g, v1, k1, v2, k2) result (vout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(vector) :: vout vout = g * ((k1 * v2) * v1 - (v1 * v2) * k1) end function w_aw_DP <>= pure function a_ww_DW (g, v1, k1, v2, k2) result (vout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(vector) :: vout vout = g * (v1 * (- (4*k1 + 2*k2) * v2) & + v2 * ( (2*k1 + 4*k2) * v1) & + (k1 - k2) * (2*v1*v2)) end function a_ww_DW <>= public :: w_wz_DPW, z_ww_DPW, w_wz_DW, z_ww_DW, w_wz_D, z_ww_D <>= pure function w_wz_DPW (g, v1, k1, v2, k2) result (vout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(vector) :: vout vout = g * (v1 * (-(k1+k2)*v2 - k1*v2) + v2 * ((k1+k2)*v1) + k1 * (v1*v2)) end function w_wz_DPW <>= pure function z_ww_DPW (g, v1, k1, v2, k2) result (vout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(vector) :: vout vout = g * (k1*(v1*v2) - k2*(v1*v2) - v1*(k1*v2) + v2*(k2*v1)) end function z_ww_DPW <>= pure function w_wz_DW (g, v1, k1, v2, k2) result (vout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(vector) :: vout vout = g * (v2 * (v1 * k2) - k2 * (v1 * v2)) end function w_wz_DW <>= pure function z_ww_DW (g, v1, k1, v2, k2) result (vout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(vector) :: vout vout = g * (v1 * ((-1)*(k1+k2) * v2) + v2 * ((k1+k2) * v1)) end function z_ww_DW <>= pure function w_wz_D (g, v1, k1, v2, k2) result (vout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(vector) :: vout vout = g * (v2 * (k2*v1) - k2 * (v1*v2)) end function w_wz_D <>= pure function z_ww_D (g, v1, k1, v2, k2) result (vout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(vector) :: vout vout = g * (v1 * (- (k1 + k2) * v2) + v2 * ((k1 + k2) * v1)) end function z_ww_D @ \section{Dim-6 Quartic Couplings} <>= public :: hhhh_p2, a_hww_DPB, h_aww_DPB, w_ahw_DPB, a_hww_DPW, h_aww_DPW, & w_ahw_DPW, a_hww_DW, h_aww_DW, w3_ahw_DW, w4_ahw_DW <>= pure function hhhh_p2 (g, h1, k1, h2, k2, h3, k3) result (hout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1, h2, h3 type(momentum), intent(in) :: k1, k2, k3 complex(kind=default) :: hout hout = g * h1*h2*h3* (k1*k1 + k2*k2 +k3*k3 + k1*k3 + k1*k2 + k2*k3) end function hhhh_p2 <>= pure function a_hww_DPB (g, h1, k1, v2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1 type(vector), intent(in) :: v2, v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h1 * (v3*((k1+k2+k3)*v2) - v2*((k1+k2+k3)*v3)) end function a_hww_DPB <>= pure function h_aww_DPB (g, v1, k1, v2, k2, v3, k3) result (hout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2, v3 type(momentum), intent(in) :: k1, k2, k3 complex(kind=default) :: hout hout = g * ((k1 * v3) * (v1 * v2) - (k1 * v2) * (v1 * v3)) end function h_aww_DPB <>= pure function w_ahw_DPB (g, v1, k1, h2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h2 type(vector), intent(in) :: v1, v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h2 * (v1 * (k1 * v3) - k1 * (v1 * v3)) end function w_ahw_DPB <>= pure function a_hww_DPW (g, h1, k1, v2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1 type(vector), intent(in) :: v2, v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h1 * (v3 * ((2*k1+k2+k3)*v2) - v2 * ((2*k1+k2+k3)*v3)) end function a_hww_DPW <>= pure function h_aww_DPW (g, v1, k1, v2, k2, v3, k3) result (hout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2, v3 type(momentum), intent(in) :: k1, k2, k3 complex(kind=default) :: hout hout = g * ((-(2*k1+k2+k3)*v2)*(v1*v3)+((2*k1+k2+k3)*v3)*(v1*v2)) end function h_aww_DPW <>= pure function w_ahw_DPW (g, v1, k1, h2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h2 type(vector), intent(in) :: v1, v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h2 * ((k2 - k1) * (v1 * v3) + v1 * ((k1 - k2) * v3)) end function w_ahw_DPW <>= pure function a_hww_DW (g, h1, k1, v2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1 type(vector), intent(in) :: v2, v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h1 * ( v2 * (-(3*k1 + 4*k2 + 4*k3) * v3) & + v3 * ((3*k1 + 2*k2 + 4*k3) * v2) & + (k2 - k3) *2*(v2 * v3)) end function a_hww_DW <>= pure function h_aww_DW (g, v1, k1, v2, k2, v3, k3) result (hout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2, v3 type(momentum), intent(in) :: k1, k2, k3 complex(kind=default) :: hout hout = g * ((v1*v2) * ((3*k1 - k2 - k3)*v3) & + (v1*v3) * ((-3*k1 - k2 + k3)*v2) & + (v2*v3) * (2*(k2-k3)*v1)) end function h_aww_DW <>= pure function w3_ahw_DW (g, v1, k1, h2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h2 type(vector), intent(in) :: v1, v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h2 * (v1 * ((4*k1 + k2) * v3) & +v3 * (-2*(k1 + k2 + 2*k3) * v1) & +(-2*k1 + k2 + 2*k3) * (v1*v3)) end function w3_ahw_DW <>= pure function w4_ahw_DW (g, v1, k1, h2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h2 type(vector), intent(in) :: v1, v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h2 * (v1 * (-(4*k1 + k2 + 2*k3) * v3) & + v3 * (2*(k1 + k2 + 2*k3) * v1) & +(4*k1 + k2) * (v1*v3)) end function w4_ahw_DW <>= public ::a_aww_DW, w_aaw_DW, a_aww_W, w_aaw_W <>= pure function a_aww_DW (g, v1, k1, v2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2, v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * (2*v1*(v2*v3) - v2*(v1*v3) - v3*(v1*v2)) end function a_aww_DW pure function w_aaw_DW (g, v1, k1, v2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2, v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * (2*v3*(v1*v2) - v2*(v1*v3) - v1*(v2*v3)) end function w_aaw_DW pure function a_aww_W (g, v1, k1, v2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2, v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * (v1*((-(k2+k3)*v2)*(k2*v3) + (-(k2+k3)*v3)*(k3*v2)) & +v2*((-((k2-k3)*v1)*(k1+k2+k3)*v3) - (k1*v3)*(k2*v1) & + ((k1+k2+k3)*v1)*(k2*v3)) & +v3*(((k2-k3)*v1)*((k1+k2+k3)*v2) - (k1*v2)*(k3*v1) & + ((k1+k2+k3)*v1)*(k3*v2)) & +(v1*v2)*(((2*k1+k2+k3)*v3)*k2 - (k2*v3)*k1 -(k1*v3)*k3) & +(v1*v3)*(((2*k1+k2+k3)*v2)*k3 - (k3*v2)*k1 - (k1*v2)*k3) & +(v2*v3)*((-(k1+k2+k3)*v1)*(k2+k3) + ((k2+k3)*v1)*k1) & +(-(k1+k2+k3)*k3 +k1*k2)*((v1*v3)*v2 - (v2*v3)*v1) & +(-(k1+k2+k3)*k2 + k1*k3)*((v1*v2)*v3 - (v2*v3)*v1)) end function a_aww_W pure function w_aaw_W (g, v1, k1, v2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2, v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * (v1*((k1*v3)*(-(k1+k2+2*k3)*v2) + (k2*v3)*((k1+k2+k3)*v2) & + (k1*v2)*((k1+k2+k3)*v3)) & + v2*(((k1-k2)*v3)*((k1+k2+k3)*v1) - (k2*v3)*(k3*v1) & + (k2*v1)*((k1+k2+k3)*v3)) & + v3*((k1*v2)*(-(k1+k2)*v1) + (k2*v1)*(-(k1+k2)*v2)) & + (v1*v2)*((k1+k2)*(-(k1+k2+k3)*v3) + k3*((k1+k2)*v3))& + (v1*v3)*(-k2*(k3*v2) - k3*(k1*v2) + k1*((k1+k2+2*k3)*v2)) & + (v2*v3)*(-k1*(k3*v1) - k3*(k2*v1) + k2*((k1+k2+2*k3)*v1)) & + (-k2*(k1+k2+k3) + k1*k3)*(v1*(v2*v3) - v3*(v1*v2)) & + (-k1*(k1+k2+k3) + k2*k3)*(v2*(v1*v3) - v3*(v1*v2)) ) end function w_aaw_W <>= public :: h_hww_D, w_hhw_D, h_hww_DP, w_hhw_DP, h_hvv_PB, v_hhv_PB <>= pure function h_hww_D (g, h1, k1, v2, k2, v3, k3) result (hout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1 type(vector), intent(in) :: v2, v3 type(momentum), intent(in) :: k1, k2, k3 complex(kind=default) :: hout hout = g * h1 * ((v2*v3)*((k2*k2)+(k3*k3)) - (k2*v2)*(k2*v3) & - (k3*v2)*(k3*v3)) end function h_hww_D <>= pure function w_hhw_D (g, h1, k1, h2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1, h2 type(vector), intent(in) :: v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h1 * h2 * (v3 * ((k1+k2+k3)*(k1+k2+k3)+(k3*k3)) & - (k1+k2+k3) * ((k1+k2+k3)*v3) - k3 * (k3*v3)) end function w_hhw_D <>= pure function h_hww_DP (g, h1, k1, v2, k2, v3, k3) result (hout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1 type(vector), intent(in) :: v2, v3 type(momentum), intent(in) :: k1, k2, k3 complex(kind=default) :: hout hout = g * h1 * (-((k2+k3)*v2)*(k2*v3) - & ((k2+k3)*v3)*(k3*v2)+ (v2*v3)*((k2+k3)*(k2+k3))) end function h_hww_DP <>= pure function w_hhw_DP (g, h1, k1, h2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1, h2 type(vector), intent(in) :: v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h1 * h2 * (k3*((k1+k2)*v3) + (k1+k2)*(-(k1+k2+k3)*v3) & + v3*((k1+k2)*(k1+k2))) end function w_hhw_DP <>= pure function h_hvv_PB (g, h1, k1, v2, k2, v3, k3) result (hout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1 type(vector), intent(in) :: v2, v3 type(momentum), intent(in) :: k1, k2, k3 complex(kind=default) :: hout hout = g * h1 * ((k2*v3)*(k3*v2) - (k2*k3)*(v2*v3)) end function h_hvv_PB <>= pure function v_hhv_PB (g, h1, k1, h2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1, h2 type(vector), intent(in) :: v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h1 * h2 * ((-(k1+k2+k3)*v3)*k3 + ((k1+k2+k3)*k3)*v3) end function v_hhv_PB <>= public :: a_hhz_D, h_ahz_D, z_ahh_D, a_hhz_DP, h_ahz_DP, z_ahh_DP, & a_hhz_PB, h_ahz_PB, z_ahh_PB <>= pure function a_hhz_D (g, h1, k1, h2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1, h2 type(vector), intent(in) :: v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h1 * h2 * ((k1+k2+k3) * ((k1+k2+k3)*v3) & - v3 * ((k1+k2+k3)*(k1+k2+k3))) end function a_hhz_D <>= pure function h_ahz_D (g, v1, k1, h2, k2, v3, k3) result (hout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h2 type(vector), intent(in) :: v1, v3 type(momentum), intent(in) :: k1, k2, k3 complex(kind=default) :: hout hout = g * h2 * ((k1*v1)*(k1*v3) - (k1*k1)*(v1*v3)) end function h_ahz_D <>= pure function z_ahh_D (g, v1, k1, h2, k2, h3, k3) result (vout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1 complex(kind=default), intent(in) :: h2, h3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h2 * h3 * ((k1*v1)*k1 - (k1*k1)*v1) end function z_ahh_D <>= pure function a_hhz_DP (g, h1, k1, h2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1, h2 type(vector), intent(in) :: v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h1 * h2 * ((-(k1+k2+k3)*v3)*(k1+k2) + ((k1+k2+k3)*(k1+k2))*v3) end function a_hhz_DP <>= pure function h_ahz_DP (g, v1, k1, h2, k2, v3, k3) result (hout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h2 type(vector), intent(in) :: v1, v3 type(momentum), intent(in) :: k1, k2, k3 complex(kind=default) :: hout hout = g * h2 * ( (k1*v3)*(-(k1+k3)*v1) + (k1*(k1+k3))*(v1*v3) ) end function h_ahz_DP <>= pure function z_ahh_DP (g, v1, k1, h2, k2, h3, k3) result (vout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1 complex(kind=default), intent(in) :: h2, h3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h2 * h3 * (k1*((k2+k3)*v1) - v1*(k1*(k2+k3))) end function z_ahh_DP <>= pure function a_hhz_PB (g, h1, k1, h2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1, h2 type(vector), intent(in) :: v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h1 * h2 * (k3*((k1+k2+k3)*v3) - v3*((k1+k2+k3)*k3)) end function a_hhz_PB <>= pure function h_ahz_PB (g, v1, k1, h2, k2, v3, k3) result (hout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h2 type(vector), intent(in) :: v1, v3 type(momentum), intent(in) :: k1, k2, k3 complex(kind=default) :: hout hout = g * h2 * ((-k1*v3)*(k3*v1) + (k1*k3)*(v1*v3)) end function h_ahz_PB <>= pure function z_ahh_PB (g, v1, k1, h2, k2, h3, k3) result (vout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1 complex(kind=default), intent(in) :: h2, h3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h2 * h3 * (k1*((k1+k2+k3)*v1) - v1*(k1*(k1+k2+k3))) end function z_ahh_PB <>= public :: h_wwz_DW, w_hwz_DW, z_hww_DW, h_wwz_DPB, w_hwz_DPB, z_hww_DPB public :: h_wwz_DDPW, w_hwz_DDPW, z_hww_DDPW, h_wwz_DPW, w_hwz_DPW, z_hww_DPW <>= pure function h_wwz_DW (g, v1, k1, v2, k2, v3, k3) result (hout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2, v3 type(momentum), intent(in) :: k1, k2, k3 complex(kind=default) :: hout hout = g * (((k1-k2)*v3)*(v1*v2)-((2*k1+k2)*v2)*(v1*v3) + & ((k1+2*k2)*v1)*(v2*v3)) end function h_wwz_DW <>= pure function w_hwz_DW (g, h1, k1, v2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1 type(vector), intent(in) :: v2, v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h1 * ( v2*(-(k1+2*k2+k3)*v3) + v3*((2*k1+k2+2*k3)*v2) - & (k1 - k2 + k3)*(v2*v3)) end function w_hwz_DW <>= pure function z_hww_DW (g, h1, k1, v2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1 type(vector), intent(in) :: v2, v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h1 * ((k2-k3)*(v2*v3) - v2*((2*k2+k3)*v3) + v3*((k2+2*k3)*v2)) end function z_hww_DW <>= pure function h_wwz_DPB (g, v1, k1, v2, k2, v3, k3) result (hout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2, v3 type(momentum), intent(in) :: k1, k2, k3 complex(kind=default) :: hout hout = g * ((k3*v1)*(v2*v3) - (k3*v2)*(v1*v3)) end function h_wwz_DPB <>= pure function w_hwz_DPB (g, h1, k1, v2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1 type(vector), intent(in) :: v2, v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h1 * (k3*(v2*v3) - v3*(k3*v2)) end function w_hwz_DPB <>= pure function z_hww_DPB (g, h1, k1, v2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1 type(vector), intent(in) :: v2, v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h1 * (((k1+k2+k3)*v3)*v2 - ((k1+k2+k3)*v2)*v3) end function z_hww_DPB <>= pure function h_wwz_DDPW (g, v1, k1, v2, k2, v3, k3) result (hout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2, v3 type(momentum), intent(in) :: k1, k2, k3 complex(kind=default) :: hout hout = g * (((k1-k2)*v3)*(v1*v2)-((k1-k3)*v2)*(v1*v3)+((k2-k3)*v1)*(v2*v3)) end function h_wwz_DDPW <>= pure function w_hwz_DDPW (g, h1, k1, v2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1 type(vector), intent(in) :: v2, v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h1 * ((-(k1+2*k2+k3)*v3)*v2 + ((k1+k2+2*k3)*v2)*v3 + & (v2*v3)*(k2-k3)) end function w_hwz_DDPW <>= pure function z_hww_DDPW (g, h1, k1, v2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1 type(vector), intent(in) :: v2, v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h1 * ((v2*v3)*(k2-k3) - ((k1+2*k2+k3)*v3) *v2 + & ((k1+k2+2*k3)*v2)*v3 ) end function z_hww_DDPW <>= pure function h_wwz_DPW (g, v1, k1, v2, k2, v3, k3) result (hout) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2, v3 type(momentum), intent(in) :: k1, k2, k3 complex(kind=default) :: hout hout = g * (((k1-k2)*v3)*(v1*v2) + (-(2*k1+k2+k3)*v2)*(v1*v3) + & ((k1+2*k2+k3)*v1)*(v2*v3)) end function h_wwz_DPW <>= pure function w_hwz_DPW (g, h1, k1, v2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1 type(vector), intent(in) :: v2, v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h1 * ((-(k1+2*k2+k3)*v3)*v2 + ((2*k1+k2+k3)*v2)*v3 + & (v2*v3)*(k2-k1)) end function w_hwz_DPW <>= pure function z_hww_DPW (g, h1, k1, v2, k2, v3, k3) result (vout) complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: h1 type(vector), intent(in) :: v2, v3 type(momentum), intent(in) :: k1, k2, k3 type(vector) :: vout vout = g * h1 * ((v2*v3)*(k2-k3) + ((k1-k2)*v3)*v2 + ((k3-k1)*v2)*v3) end function z_hww_DPW @ \section{Scalar3 Dim-5 Couplings} <>= public :: phi_dim5s2 @ \begin{equation} \phi_1(k_1) = g (k_2 \cdot k_3) \phi_2 (k_2) \phi_3 (k_3) \end{equation} <>= pure function phi_dim5s2 (g, phi2, k2, phi3, k3) result (phi1) complex(kind=default), intent(in) :: g, phi2, phi3 type(momentum), intent(in) :: k2, k3 complex(kind=default) :: phi1 phi1 = g * phi2 * phi3 * (k2 * k3) end function phi_dim5s2 @ \section{Tensorscalar-Scalar Couplings} <>= public :: tphi_ss, tphi_ss_cf, s_tphis, s_tphis_cf @ \begin{equation} \phi(k_1 + k_2) = 2 g ((k_1 \cdot k_2) + (k_1 \cdot k_1)) ((k_1 \cdot k_2) + (k_2 \cdot k_2)) \phi_1 (k_1) \phi_2 (k_2) \end{equation} <>= pure function tphi_ss (g, phi1, k1, phi2, k2) result (phi) complex(kind=default), intent(in) :: g, phi1, phi2 type(momentum), intent(in) :: k1, k2 complex(kind=default) :: phi phi = 2 * g * phi1 * phi2 * & ((k1 * k2)+ (k1 * k1)) * & ((k1 * k2)+ (k2 * k2)) end function tphi_ss @ \begin{equation} \phi(k_1 + k_2) = - g/2 (k_1 \cdot k_2) ((k_1 + k_2) \cdot (k_1 + k_2)) \phi_1 (k_1) \phi_2 (k_2) \end{equation} <>= pure function tphi_ss_cf (g, phi1, k1, phi2, k2) result (phi) complex(kind=default), intent(in) :: g, phi1, phi2 type(momentum), intent(in) :: k1, k2 complex(kind=default) :: phi phi = - g/2 * phi1 * phi2 * & (k1 * k2) * & ((k1 + k2) * (k1 + k2)) end function tphi_ss_cf @ \begin{equation} \phi_1(k_1) = 2 g ((k_1 \cdot k_2) + (k_1 \cdot k_1)) ((k_1 \cdot k_2) + (k_2 \cdot k_2)) \phi(k_2-k_1) \phi_2 (k_2) \end{equation} <>= pure function s_tphis (g, phi, k, phi2, k2) result (phi1) complex(kind=default), intent(in) :: g, phi, phi2 type(momentum), intent(in) :: k, k2 complex(kind=default) :: phi1 type(momentum) :: k1 k1 = - ( k + k2) phi1 = 2 * g * phi * phi2 * & ((k1 * k2)+ (k1 * k1)) * & ((k1 * k2)+ (k2 * k2)) end function s_tphis @ \begin{equation} \phi_1(k_1) = - g/2 (k_1 \cdot k_2) ((k_1 + k_2) \cdot (k_1 + k_2)) \phi (k_2 -k_1) \phi_2 (k_2) \end{equation} <>= pure function s_tphis_cf (g, phi, k, phi2, k2) result (phi1) complex(kind=default), intent(in) :: g, phi, phi2 type(momentum), intent(in) :: k, k2 complex(kind=default) :: phi1 type(momentum) :: k1 k1 = - ( k + k2) phi1 = - g/2 * phi * phi2 * & (k1 * k2) * & ((k1 + k2) * (k1 + k2)) end function s_tphis_cf @ \section{Scalar2-Vector2 Dim-8 Couplings} <>= public :: phi_phi2v_1, v_phi2v_1, phi_phi2v_2, v_phi2v_2 @ \begin{equation} \phi_2(k_2) = g \left (\left ( k_1 \cdot V_1 \right ) \left ( k_2 \cdot V_2 \right ) + \left ( k_1 \cdot V_1 \right )\left ( k_1 \cdot V_2 \right ) \right ) \phi_1 (k_1) \end{equation} <>= pure function phi_phi2v_1 (g, phi1, k1, v1, k_v1, v2, k_v2) result (phi2) complex(kind=default), intent(in) :: g, phi1 type(momentum), intent(in) :: k1, k_v1, k_v2 type(momentum) :: k2 type(vector), intent(in) :: v1, v2 complex(kind=default) :: phi2 k2 = - k1 - k_v1 - k_v2 phi2 = g * phi1 * & ( (k1 * v1) * (k2 * v2) + (k1 * v2) * (k2 * v1) ) end function phi_phi2v_1 @ \begin{equation} V_2^\mu =g \left ( k_1^\mu \left ( k_2 \cdot V_1 \right ) + k_2^\mu \left ( k_1 \cdot V_1 \right ) \right ) \phi_1 (k_1) \phi_2 (k_2) \end{equation} <>= pure function v_phi2v_1 (g, phi1, k1, phi2, k2, v1) result (v2) complex(kind=default), intent(in) :: g, phi1, phi2 type(momentum), intent(in) :: k1, k2 type(vector), intent(in) :: v1 type(vector) :: v2 v2 = g * phi1 * phi2 * & ( k1 * (k2 * v1) + k2 * (k1 * v1) ) end function v_phi2v_1 @ \begin{equation} \phi_2(k_2) = g \left ( k_1 \cdot k_2 \right ) \left ( V_1\cdot V_2 \right) \phi_1 (k_1) \end{equation} <>= pure function phi_phi2v_2 (g, phi1, k1, v1,k_v1, v2, k_v2) result (phi2) complex(kind=default), intent(in) :: g, phi1 type(momentum), intent(in) :: k1, k_v1, k_v2 type(vector), intent(in) :: v1, v2 type(momentum) :: k2 complex(kind=default) :: phi2 k2 = - k1 - k_v1 - k_v2 phi2 = g * phi1 * (k1 * k2) * (v1 * v2) end function phi_phi2v_2 @ \begin{equation} V_2^\mu = g V_1^\mu \left ( k_1 \cdot k_2 \right ) \phi_1 \phi_2 \end{equation} <>= pure function v_phi2v_2 (g, phi1, k1, phi2, k2, v1) result (v2) complex(kind=default), intent(in) :: g, phi1, phi2 type(momentum), intent(in) :: k1, k2 type(vector), intent(in) :: v1 type(vector) :: v2 v2 = g * phi1 * phi2 * & ( k1 * k2 ) * v1 end function v_phi2v_2 @ \section{Scalar4 Dim-8 Couplings} <>= public :: s_dim8s3 @ \begin{equation} \phi(k_1) = g \left [ \left ( k_1 \cdot k_2 \right ) \left ( k_3 \cdot k_4 \right )+ \left ( k_1 \cdot k_3 \right ) \left ( k_2 \cdot k_4 \right ) + \left ( k_1 \cdot k_4 \right )\left ( k_2 \cdot k_3 \right ) \right ] \phi_2 (k_2) \phi_3 (k_3) \phi_4 (k_4) \end{equation} <>= pure function s_dim8s3 (g, phi2, k2, phi3, k3, phi4, k4) result (phi1) complex(kind=default), intent(in) :: g, phi2, phi3, phi4 type(momentum), intent(in) :: k2, k3, k4 type(momentum) :: k1 complex(kind=default) :: phi1 k1 = - k2 - k3 - k4 phi1 = g * ( (k1 * k2) * (k3 * k4) + (k1 * k3) * (k2 * k4) & + (k1 * k4) * (k2 * k3) ) * phi2 * phi3 * phi4 end function s_dim8s3 @ \section{Mixed Scalar2-Vector2 Dim-8 Couplings} <>= public :: phi_phi2v_m_0, v_phi2v_m_0, phi_phi2v_m_1, v_phi2v_m_1, phi_phi2v_m_7, v_phi2v_m_7 @ \begin{equation} \phi_2(k_2) = g \left (\left ( V_1 \cdot k_{V_2} \right ) \left ( V_2 \cdot k_{V_1} \right ) \left ( k_1 \cdot k_2 \right ) - (\left ( V_1 \cdot V_2 \right ) \left ( k_{V_1} \cdot k_{V_2} \right ) \left ( k_1 \cdot k_2 \right ) \right ) \phi_1 (k_1) \end{equation} <>= pure function phi_phi2v_m_0 (g, phi1, k1, v1, k_v1, v2, k_v2) result (phi2) complex(kind=default), intent(in) :: g, phi1 type(momentum), intent(in) :: k1, k_v1, k_v2 type(momentum) :: k2 type(vector), intent(in) :: v1, v2 complex(kind=default) :: phi2 k2 = - k1 - k_v1 - k_v2 phi2 = g * phi1 * & ( (v1 * k_v2) * (v2 * k_v1) * (k1 * k2) & - (v1 * v2) * (k_v1 * k_v2) * (k1 * k2) ) end function phi_phi2v_m_0 @ \begin{equation} V_2^\mu =g \left ( k_{V_1}^\mu \left ( V_1 \cdot k_{V_2} \right ) \left ( k_1 \cdot k_2 \right ) - V_1^\mu \left ( k_{V_1} \cdot k_{V_2} \right ) \left ( k_1 \cdot k_2 \right ) \right ) \phi_1 (k_1) \phi_2 (k_2)) \end{equation} <>= pure function v_phi2v_m_0 (g, phi1, k1, phi2, k2, v1, k_v1) result (v2) complex(kind=default), intent(in) :: g, phi1, phi2 type(momentum), intent(in) :: k1, k2, k_v1 type(vector), intent(in) :: v1 type(momentum) :: k_v2 type(vector) :: v2 k_v2 = - k_v1 - k1 - k2 v2 = g * phi1 * phi2 * & ( k_v1 * (v1 * k_v2) * (k1 * k2) & - v1 * (k_v2 * k_v1) * (k1 * k2) ) end function v_phi2v_m_0 @ \begin{equation} \phi_2(k_2) = g \left (\left ( V_1 \cdot V_2 \right ) \left ( k_1 \cdot k_{V_2} \right ) \left ( k_2 \cdot k_{V_1} \right ) + (\left ( V_1 \cdot V_2 \right ) \left ( k_1 \cdot k_{V_1} \right ) \left ( k_2 \cdot k_{V_2} \right ) \\ + (\left ( V_1 \cdot k_2 \right ) \left ( V_2 \cdot k_1 \right ) \left ( k_{V_1} \cdot k_{V_2} \right ) + (\left ( V_1 \cdot k_1 \right ) \left ( V_2 \cdot k_2 \right ) \left ( k_{V_1} \cdot k_{V_2} \right ) \\ - (\left ( V_1 \cdot k_{V_2} \right ) \left ( V_2 \cdot k_2 \right ) \left ( k_1 \cdot k_{V_1} \right ) - (\left ( V_1 \cdot k_2 \right ) \left ( V_2 \cdot k_{V_1} \right ) \left ( k_1 \cdot k_{V_2} \right ) \\ - (\left ( V_1 \cdot k_{V_2} \right ) \left ( V_2 \cdot k_1 \right ) \left ( k_2 \cdot k_{V_1} \right ) - (\left ( V_1 \cdot k_1 \right ) \left ( V_2 \cdot k_{V_1} \right ) \left ( k_2 \cdot k_{V_2} \right ) \right ) \phi_1 (k_1) \end{equation} <>= pure function phi_phi2v_m_1 (g, phi1, k1, v1, k_v1, v2, k_v2) result (phi2) complex(kind=default), intent(in) :: g, phi1 type(momentum), intent(in) :: k1, k_v1, k_v2 type(momentum) :: k2 type(vector), intent(in) :: v1, v2 complex(kind=default) :: phi2 k2 = - k1 - k_v1 - k_v2 phi2 = g * phi1 * & ( (v1 * v2) * (k1 * k_v2) * (k2 * k_v1) & + (v1 * v2) * (k1 * k_v1) * (k2 * k_v2) & + (v1 * k2) * (v2 * k1) * (k_v1 * k_v2) & + (v1 * k1) * (v2 * k2) * (k_v1 * k_v2) & - (v1 * k_v2) * (v2 * k2) * (k1 * k_v1) & - (v1 * k2) * (v2 * k_v1) * (k1 * k_v2) & - (v1 * k_v2) * (v2 * k1) * (k2 * k_v1) & - (v1 * k1) * (v2 * k_v1) * (k2 * k_v2) ) end function phi_phi2v_m_1 @ \begin{equation} V_2^\mu =g \left ( k_1^\mu \left ( V_1 \cdot k_2 \right ) \left ( k_{V_1} \cdot k_{V_2} \right ) \\ + k_2^\mu \left ( V_1 \cdot k_1 \right ) \left ( k_{V_1} \cdot k_{V_2} \right ) \\ + V_1^\mu \left ( k_{V_1} \cdot k_1 \right ) \left ( k_{V_2} \cdot k_2 \right ) \\ + V_1^\mu \left ( k_{V_1} \cdot k_2 \right ) \left ( k_{V_2} \cdot k_1 \right ) \\ - k_1^\mu \left ( V_1 \cdot k_{V_2} \right ) \left ( k_{V_1} \cdot k_2 \right ) \\ - k_2^\mu \left ( V_1 \cdot k_{V_2} \right ) \left ( k_{V_1} \cdot k_1 \right ) \\ - k_{V_1}^\mu \left ( V_1 \cdot k_1 \right ) \left ( k_{V_2} \cdot k_2 \right ) \\ - k_{V_1}^\mu \left ( V_1 \cdot k_2 \right ) \left ( k_{V_2} \cdot k_1 \right ) \right ) \\ \phi_1 (k_1) \phi_2 (k_2) \end{equation} <>= pure function v_phi2v_m_1 (g, phi1, k1, phi2, k2, v1, k_v1) result (v2) complex(kind=default), intent(in) :: g, phi1, phi2 type(momentum), intent(in) :: k1, k2, k_v1 type(vector), intent(in) :: v1 type(momentum) :: k_v2 type(vector) :: v2 k_v2 = - k_v1 - k1 - k2 v2 = g * phi1 * phi2 * & ( k1 * (v1 * k2) * (k_v1 * k_v2) & + k2 * (v1 * k1) * (k_v1 * k_v2) & + v1 * (k_v1 * k1) * (k_v2 * k2) & + v1 * (k_v1 * k2) * (k_v2 * k1) & - k1 * (v1 * k_v2) * (k_v1 * k2) & - k2 * (v1 * k_v2) * (k_v1 * k1) & - k_v1 * (v1 * k1) * (k_v2 * k2) & - k_v1 * (v1 * k2) * (k_v2 * k1) ) end function v_phi2v_m_1 @ \begin{equation} \phi_2(k_2) = g \left (\left ( V_1 \cdot k_{V_2} \right ) \left ( k_1 \cdot V_2 \right ) \left ( k_2 \cdot k_{V_1} \right ) + (\left ( V_1 \cdot k_{V_2} \right ) \left ( k_1 \cdot k_{V_1} \right ) \left ( k_2 \cdot k_{V_2} \right ) \\ + (\left ( V_1 \cdot k_1 \right ) \left ( V_2 \cdot k_{V_1} \right ) \left ( k_2 \cdot k_{V_2} \right ) + (\left ( V_1 \cdot k_2 \right ) \left ( V_2 \cdot k_{V_1} \right ) \left ( k_1 \cdot k_{V_2} \right ) \\ - (\left ( V_1 \cdot V_2 \right ) \left ( k_1 \cdot k_{V_2} \right ) \left ( k_2 \cdot k_{V_1} \right ) - (\left ( V_1 \cdot V_2 \right ) \left ( k_1 \cdot k_{V_1} \right ) \left ( k_2 \cdot k_{V_2} \right ) \\ - (\left ( V_1 \cdot k_2 \right ) \left ( V_2 \cdot k_1 \right ) \left ( k_{V_1} \cdot k_{V_2} \right ) - (\left ( V_1 \cdot k_1 \right ) \left ( V_2 \cdot k_2 \right ) \left ( k_{V_1} \cdot k_{V_2} \right ) \right ) \phi_1 (k_1) \end{equation} <>= pure function phi_phi2v_m_7 (g, phi1, k1, v1, k_v1, v2, k_v2) result (phi2) complex(kind=default), intent(in) :: g, phi1 type(momentum), intent(in) :: k1, k_v1, k_v2 type(momentum) :: k2 type(vector), intent(in) :: v1, v2 complex(kind=default) :: phi2 k2 = - k1 - k_v1 - k_v2 phi2 = g * phi1 * & ( (v1 * k_v2) * (k1 * v2) * (k2 * k_v1) & + (v1 * k_v2) * (k1 * k_v1) * (k2 * v2) & + (v1 * k1) * (v2 * k_v1) * (k2 * k_v2) & + (v1 * k2) * (v2 * k_v1) * (k1 * k_v2) & - (v1 * v2) * (k1 * k_v2) * (k2 * k_v1) & - (v1 * v2) * (k1 * k_v1) * (k2 * k_v2) & - (v1 * k2) * (v2 * k1) * (k_v1 * k_v2) & - (v1 * k1) * (v2 * k2) * (k_v1 * k_v2) ) end function phi_phi2v_m_7 @ \begin{equation} V_2^\mu =g \left ( k_1^\mu \left ( V_1 \cdot k_{V_2} \right ) \left ( k_2 \cdot k_{V_1} \right ) \\ + k_2^\mu \left ( V_1 \cdot k_{V_2} \right ) \left ( k_1 \cdot k_{V_1} \right ) \\ + k_{V_1}^\mu \left ( V_1 \cdot k_1 \right ) \left ( k_2 \cdot k_{V_2} \right ) \\ + k_{V_1}^\mu \left ( V_1 \cdot k_2 \right ) \left ( k_1 \cdot k_{V_2} \right ) \\ - k_1^\mu \left ( V_1 \cdot k_2 \right ) \left ( k_{V_1} \cdot k_{V_2} \right ) \\ - k_2^\mu \left ( V_1 \cdot k_1 \right ) \left ( k_{V_1} \cdot k_{V_2} \right ) \\ - k_{V_1}^\mu \left ( k_1 \cdot k_{V_2} \right ) \left ( k_2 \cdot k_{V_1} \right ) \\ - k_{V_1}^\mu \left ( k_1 \cdot k_{V_1} \right ) \left ( k_2 \cdot k_{V_2} \right ) \right ) \\ \phi_1 (k_1) \phi_2 (k_2) \end{equation} <>= pure function v_phi2v_m_7 (g, phi1, k1, phi2, k2, v1, k_v1) result (v2) complex(kind=default), intent(in) :: g, phi1, phi2 type(momentum), intent(in) :: k1, k2, k_v1 type(vector), intent(in) :: v1 type(momentum) :: k_v2 type(vector) :: v2 k_v2 = - k_v1 - k1 - k2 v2 = g * phi1 * phi2 * & ( k1 * (v1 * k_v2) * (k2 * k_v1) & + k2 * (v1 * k_v2) * (k1 * k_v1) & + k_v1 * (v1 * k1) * (k2 * k_v2) & + k_v1 * (v1 * k2) * (k1 * k_v2) & - k1 * (v1 * k2) * (k_v1 * k_v2) & - k2 * (v1 * k1) * (k_v1 * k_v2) & - v1 * (k1 * k_v2) * (k2 * k_v1) & - v1 * (k1 * k_v1) * (k2 * k_v2) ) end function v_phi2v_m_7 @ \section{Transversal Gauge4 Dim-8 Couplings} <>= public :: g_dim8g3_t_0, g_dim8g3_t_1, g_dim8g3_t_2 @ \begin{equation} V_1^\mu = g \left [ k_2^\mu \left ( k_1 \cdot V_2 \right ) - V_2^\mu \left ( k_1 \cdot k_2 \right ) \right ] \left [ \left ( k_3 \cdot V_4 \right) \left ( k_4 \cdot V_3 \right ) - \left (V_3 \cdot V_4 \right ) \left ( k_3 \cdot k_4 \right ) \right ] \end{equation} <>= pure function g_dim8g3_t_0 (g, v2, k2, v3, k3, v4, k4) result (v1) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v2, v3, v4 type(momentum), intent(in) :: k2, k3, k4 type(vector) :: v1 type(momentum) :: k1 k1 = - k2 - k3 - k4 v1 = g * (k2 * (k1 * v2) - v2 * (k1 * k2)) & * ((k3 * v4) * (k4 * v3) - (v3 * v4) * (k3 * k4)) end function g_dim8g3_t_0 @ \begin{equation} V_1^\mu = g \left [ k_2^\mu \left ( k_1 \cdot V_2 \right ) - V_2^\mu \left ( k_1 \cdot k_2 \right ) \right ] \left [ \left ( k_3 \cdot V_4 \right) \left ( k_4 \cdot V_3 \right ) - \left (V_3 \cdot V_4 \right ) \left ( k_3 \cdot k_4 \right ) \right ] \end{equation} <>= pure function g_dim8g3_t_1 (g, v2, k2, v3, k3, v4, k4) result (v1) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v2, v3, v4 type(momentum), intent(in) :: k2, k3, k4 type(vector) :: v1 type(momentum) :: k1 k1 = - k2 - k3 - k4 v1 = g * (v3 * (v2 * k4) * (k1 * k3) * (k2 * v4) & + v4 * (v2 * k3) * (k1 * k4) * (k2 * v3) & + k3 * (v2 * v4) * (k1 * v3) * (k2 * k4) & + k4 * (v2 * v3) * (k1 * v4) * (k2 * k3) & - v3 * (v2 * v4) * (k1 * k3) * (k2 * k4) & - v4 * (v2 * v3) * (k1 * k4) * (k2 * k3) & - k3 * (v2 * k4) * (k1 * v3) * (k2 * v4) & - k4 * (v2 * k3) * (k1 * v4) * (k2 * v3)) end function g_dim8g3_t_1 @ \begin{equation} V_1^\mu = g \left [ k_2^\mu \left (V_2 \cdot k_3\right ) \left (V_3 \cdot k_4\right ) \left (V_4 \cdot k_1\right ) \\ + k_3^\mu \left (V_2 \cdot k_1\right ) \left (V_3 \cdot k_4\right ) \left (V_4 \cdot k_2\right ) \\ + k_2^\mu \left (V_2 \cdot k_4\right ) \left (V_3 \cdot k_1\right ) \left (V_4 \cdot k_3\right ) \\ + k_4^\mu \left (V_2 \cdot k_1\right ) \left (V_3 \cdot k_2\right ) \left (V_4 \cdot k_3\right ) \\ + k_4^\mu \left (V_2 \cdot k_3\right ) \left (V_3 \cdot V_4\right ) \left (k_1 \cdot k_2\right ) \\ + k_3^\mu \left (V_2 \cdot k_4\right ) \left (V_3 \cdot V_4\right ) \left (k_1 \cdot k_2\right ) \\ - k_3^\mu \left (V_2 \cdot V_4\right ) \left (V_3 \cdot k_4\right ) \left (k_1 \cdot k_2\right ) \\ - V_4^\mu \left (V_2 \cdot k_3\right ) \left (V_3 \cdot k_4\right ) \left (k_1 \cdot k_2\right ) \\ - k_4^\mu \left (V_2 \cdot V_3\right ) \left (V_4 \cdot k_3\right ) \left (k_1 \cdot k_2\right ) \\ - V_3^\mu \left (V_2 \cdot k_4\right ) \left (V_4 \cdot k_3\right ) \left (k_1 \cdot k_2\right ) \\ - k_2^\mu \left (V_2 \cdot k_4\right ) \left (V_3 \cdot V_4\right ) \left (k_1 \cdot k_3\right ) \\ + k_2^\mu \left (V_2 \cdot V_4\right ) \left (V_3 \cdot k_4\right ) \left (k_1 \cdot k_3\right ) \\ - V_2^\mu \left (V_3 \cdot k_4\right ) \left (V_4 \cdot k_2\right ) \left (k_1 \cdot k_3\right ) \\ - k_2^\mu \left (V_2 \cdot k_3\right ) \left (V_3 \cdot V_4\right ) \left (k_1 \cdot k_4\right ) \\ + k_2^\mu \left (V_2 \cdot V_3\right ) \left (V_4 \cdot k_3\right ) \left (k_1 \cdot k_4\right ) \\ - V_2^\mu \left (V_3 \cdot k_2\right ) \left (V_4 \cdot k_3\right ) \left (k_1 \cdot k_4\right ) \\ - k_4^\mu \left (V_2 \cdot k_1\right ) \left (V_3 \cdot V_4\right ) \left (k_2 \cdot k_3\right ) \\ + V_4^\mu \left (V_2 \cdot k_1\right ) \left (V_3 \cdot k_4\right ) \left (k_2 \cdot k_3\right ) \\ - V_2^\mu \left (V_3 \cdot k_4\right ) \left (V_4 \cdot k_1\right ) \left (k_2 \cdot k_3\right ) \\ + V_2^\mu \left (V_3 \cdot V_4\right ) \left (k_1 \cdot k_4\right ) \left (k_2 \cdot k_3\right ) \\ - k_3^\mu \left (V_2 \cdot k_1\right ) \left (V_3 \cdot V_4\right ) \left (k_2 \cdot k_4\right ) \\ + V_3^\mu \left (V_2 \cdot k_1\right ) \left (V_4 \cdot k_3\right ) \left (k_2 \cdot k_4\right ) \\ - V_2^\mu \left (V_3 \cdot k_1\right ) \left (V_4 \cdot k_3\right ) \left (k_2 \cdot k_4\right ) \\ + V_2^\mu \left (V_3 \cdot V_4\right ) \left (k_1 \cdot k_3\right ) \left (k_2 \cdot k_4\right ) \\ - k_2^\mu \left (V_2 \cdot V_4\right ) \left (V_3 \cdot k_1\right ) \left (k_3 \cdot k_4\right ) \\ - V_4^\mu \left (V_2 \cdot k_1\right ) \left (V_3 \cdot k_2\right ) \left (k_3 \cdot k_4\right ) \\ - k_2^\mu \left (V_2 \cdot V_3\right ) \left (V_4 \cdot k_1\right ) \left (k_3 \cdot k_4\right ) \\ + V_2^\mu \left (V_3 \cdot k_2\right ) \left (V_4 \cdot k_1\right ) \left (k_3 \cdot k_4\right ) \\ - V_3^\mu \left (V_2 \cdot k_1\right ) \left (V_4 \cdot k_2\right ) \left (k_3 \cdot k_4\right ) \\ + V_2^\mu \left (V_3 \cdot k_1\right ) \left (V_4 \cdot k_2\right ) \left (k_3 \cdot k_4\right ) \\ + V_4^\mu \left (V_2 \cdot V_3\right ) \left (k_1 \cdot k_2\right ) \left (k_3 \cdot k_4\right ) \\ + V_3^\mu \left (V_2 \cdot V_4\right ) \left (k_1 \cdot k_2\right ) \left (k_3 \cdot k_4\right ) \right ] \end{equation} <>= pure function g_dim8g3_t_2 (g, v2, k2, v3, k3, v4, k4) result (v1) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v2, v3, v4 type(momentum), intent(in) :: k2, k3, k4 type(vector) :: v1 type(momentum) :: k1 k1 = - k2 - k3 - k4 v1 = g * (k2 * (v2 * k3) * (v3 * k4) * (v4 * k1) & + k3 * (v2 * k1) * (v3 * k4) * (v4 * k2) & + k2 * (v2 * k4) * (v3 * k1) * (v4 * k3) & + k4 * (v2 * k1) * (v3 * k2) * (v4 * k3) & + k4 * (v2 * k3) * (v3 * v4) * (k1 * k2) & + k3 * (v2 * k4) * (v3 * v4) * (k1 * k2) & - k3 * (v2 * v4) * (v3 * k4) * (k1 * k2) & - v4 * (v2 * k3) * (v3 * k4) * (k1 * k2) & - k4 * (v2 * v3) * (v4 * k3) * (k1 * k2) & - v3 * (v2 * k4) * (v4 * k3) * (k1 * k2) & - k2 * (v2 * k4) * (v3 * v4) * (k1 * k3) & + k2 * (v2 * v4) * (v3 * k4) * (k1 * k3) & - v2 * (v3 * k4) * (v4 * k2) * (k1 * k3) & - k2 * (v2 * k3) * (v3 * v4) * (k1 * k4) & + k2 * (v2 * v3) * (v4 * k3) * (k1 * k4) & - v2 * (v3 * k2) * (v4 * k3) * (k1 * k4) & - k4 * (v2 * k1) * (v3 * v4) * (k2 * k3) & + v4 * (v2 * k1) * (v3 * k4) * (k2 * k3) & - v2 * (v3 * k4) * (v4 * k1) * (k2 * k3) & + v2 * (v3 * v4) * (k1 * k4) * (k2 * k3) & - k3 * (v2 * k1) * (v3 * v4) * (k2 * k4) & + v3 * (v2 * k1) * (v4 * k3) * (k2 * k4) & - v2 * (v3 * k1) * (v4 * k3) * (k2 * k4) & + v2 * (v3 * v4) * (k1 * k3) * (k2 * k4) & - k2 * (v2 * v4) * (v3 * k1) * (k3 * k4) & - v4 * (v2 * k1) * (v3 * k2) * (k3 * k4) & - k2 * (v2 * v3) * (v4 * k1) * (k3 * k4) & + v2 * (v3 * k2) * (v4 * k1) * (k3 * k4) & - v3 * (v2 * k1) * (v4 * k2) * (k3 * k4) & + v2 * (v3 * k1) * (v4 * k2) * (k3 * k4) & + v4 * (v2 * v3) * (k1 * k2) * (k3 * k4) & + v3 * (v2 * v4) * (k1 * k2) * (k3 * k4)) end function g_dim8g3_t_2 @ \section{Mixed Gauge4 Dim-8 Couplings} <>= public :: g_dim8g3_m_0, g_dim8g3_m_1, g_dim8g3_m_7 @ \begin{equation} V_1^\mu = g_1 \left [ V_2^\mu \left (V_3 \cdot V_4\right ) \left (k_1 \cdot k_2\right ) \\ - k_2^\mu \left (V_2 \cdot k_1\right ) \left (V_3 \cdot V_4\right ) \\ \right ] \\ + g_2 \left [ V_2^\mu \left (V_3 \cdot V_4\right ) \left (k_3 \cdot k_4\right ) \\ - V_2^\mu \left (V_3 \cdot k_4\right ) \left (V_4 \cdot k_3\right ) \\ \right ] \end{equation} <>= pure function g_dim8g3_m_0 (g1, g2, v2, k2, v3, k3, v4, k4) result (v1) complex(kind=default), intent(in) :: g1, g2 type(vector), intent(in) :: v2, v3, v4 type(momentum), intent(in) :: k2, k3, k4 type(vector) :: v1 type(momentum) :: k1 k1 = - k2 - k3 - k4 v1 = g1 * (v2 * (v3 * v4) * (k1 * k2) & - k2 * (v2 * k1) * (v3 * v4)) & + g2 * (v2 * (v3 * v4) * (k3 * k4) & - v2 * (v3 * k4) * (v4 * k3)) end function g_dim8g3_m_0 @ \begin{equation} V_1^\mu = g_1 \left [ k_2^\mu \left (V_2 \cdot V_4\right ) \left (V_3 \cdot k_1\right ) \\ + V_4^\mu \left (V_2 \cdot k_1\right ) \left (V_3 \cdot k_2\right ) \\ + k_2^\mu \left (V_2 \cdot V_3\right ) \left (V_4 \cdot k_1\right ) \\ + V_3^\mu \left (V_2 \cdot k_1\right ) \left (V_4 \cdot k_2\right ) \\ - V_2^\mu \left (V_3 \cdot k_2\right ) \left (V_4 \cdot k_1\right ) \\ - V_2^\mu \left (V_3 \cdot k_1\right ) \left (V_4 \cdot k_2\right ) \\ - V_4^\mu \left (V_2 \cdot V_3\right ) \left (k_1 \cdot k_2\right ) \\ - V_3^\mu \left (V_2 \cdot V_4\right ) \left (k_1 \cdot k_2\right ) \\ \right ] \\ + g_2 \left [ k_3^\mu \left (V_2 \cdot V_4\right ) \left (V_3 \cdot k_4\right ) \\ - k_4^\mu \left (V_2 \cdot k_3\right ) \left (V_3 \cdot V_4\right ) \\ - k_3^\mu \left (V_2 \cdot k_4\right ) \left (V_3 \cdot V_4\right ) \\ + V_4^\mu \left (V_2 \cdot k_3\right ) \left (V_3 \cdot k_4\right ) \\ + k_4^\mu \left (V_2 \cdot V_3\right ) \left (V_4 \cdot k_3\right ) \\ + V_3^\mu \left (V_2 \cdot k_4\right ) \left (V_4 \cdot k_3\right ) \\ - V_4^\mu \left (V_2 \cdot V_3\right ) \left (k_3 \cdot k_4\right ) \\ - V_3^\mu \left (V_2 \cdot V_4\right ) \left (k_3 \cdot k_4\right ) \\ \right ] \end{equation} <>= pure function g_dim8g3_m_1 (g1, g2, v2, k2, v3, k3, v4, k4) result (v1) complex(kind=default), intent(in) :: g1, g2 type(vector), intent(in) :: v2, v3, v4 type(momentum), intent(in) :: k2, k3, k4 type(vector) :: v1 type(momentum) :: k1 k1 = - k2 - k3 - k4 v1 = g1 * (k2 * (v2 * v4) * (v3 * k1) & + v4 * (v2 * k1) * (v3 * k2) & + k2 * (v2 * v3) * (v4 * k1) & + v3 * (v2 * k1) * (v4 * k2) & - v2 * (v3 * k2) * (v4 * k1) & - v2 * (v3 * k1) * (v4 * k2) & - v4 * (v2 * v3) * (k1 * k2) & - v3 * (v2 * v4) * (k1 * k2)) & + g2 * (k3 * (v2 * v4) * (v3 * k4) & - k4 * (v2 * k3) * (v3 * v4) & - k3 * (v2 * k4) * (v3 * v4) & + v4 * (v2 * k3) * (v3 * k4) & + k4 * (v2 * v3) * (v4 * k3) & + v3 * (v2 * k4) * (v4 * k3) & - v4 * (v2 * v3) * (k3 * k4) & - v3 * (v2 * v4) * (k3 * k4)) end function g_dim8g3_m_1 @ \begin{equation} V_1^\mu = g_1 \left [ V_2^\mu \left (V_3 \cdot k_2\right ) \left (V_4 \cdot k_1\right ) \\ + V_2^\mu \left (V_4 \cdot k_1\right ) \left (V_4 \cdot k_2\right ) \\ + V_4^\mu \left (V_2 \cdot V_3\right ) \left (k_1 \cdot k_2\right ) \\ + V_3^\mu \left (V_2 \cdot V_4\right ) \left (k_1 \cdot k_2\right ) \\ - k_2^\mu \left (V_2 \cdot V_4\right ) \left (V_3 \cdot k_1\right ) \\ - V_4^\mu \left (V_2 \cdot k_1\right ) \left (V_3 \cdot k_2\right ) \\ - k_2^\mu \left (V_2 \cdot V_3\right ) \left (V_4 \cdot k_1\right ) \\ - V_3^\mu \left (V_2 \cdot k_1\right ) \left (V_4 \cdot k_2\right ) \\ \right ] \\ + g_2 \left [ k_3^\mu \left (V_2 \cdot k_1\right ) \left (V_3 \cdot V_4\right ) \\ + k_4^\mu \left (V_2 \cdot k_1\right ) \left (V_3 \cdot V_4\right ) \\ + k_2^\mu \left (V_2 \cdot k_3\right ) \left (V_3 \cdot V_4\right ) \\ + k_2^\mu \left (V_2 \cdot k_4\right ) \left (V_3 \cdot V_4\right ) \\ + V_4^\mu \left (V_2 \cdot k_4\right ) \left (V_3 \cdot k_1\right ) \\ + k_4^\mu \left (V_2 \cdot V_4\right ) \left (V_3 \cdot k_2\right ) \\ + V_3^\mu \left (V_2 \cdot k_3\right ) \left (V_4 \cdot k_1\right ) \\ + V_2^\mu \left (V_3 \cdot k_4\right ) \left (V_4 \cdot k_1\right ) \\ + V_3^\mu \left (V_2 \cdot V_3\right ) \left (V_4 \cdot k_2\right ) \\ + V_2^\mu \left (V_3 \cdot k_4\right ) \left (V_4 \cdot k_2\right ) \\ + V_2^\mu \left (V_3 \cdot k_1\right ) \left (V_4 \cdot k_3\right ) \\ + V_2^\mu \left (V_3 \cdot k_2\right ) \left (V_4 \cdot k_3\right ) \\ + V_4^\mu \left (V_2 \cdot V_3\right ) \left (k_1 \cdot k_3\right ) \\ + V_3^\mu \left (V_2 \cdot V_4\right ) \left (k_1 \cdot k_4\right ) \\ + V_3^\mu \left (V_2 \cdot V_4\right ) \left (k_2 \cdot k_3\right ) \\ + V_4^\mu \left (V_2 \cdot V_3\right ) \left (k_2 \cdot k_4\right ) \\ - k_4^\mu \left (V_2 \cdot V_4\right ) \left (V_3 \cdot k_1\right ) \\ - V_4^\mu \left (V_2 \cdot k_3\right ) \left (V_3 \cdot k_1\right ) \\ - k_3^\mu \left (V_2 \cdot V_4\right ) \left (V_3 \cdot k_2\right ) \\ - V_4^\mu \left (V_2 \cdot k_4\right ) \left (V_3 \cdot k_2\right ) \\ - k_2^\mu \left (V_2 \cdot V_4\right ) \left (V_3 \cdot k_4\right ) \\ - V_4^\mu \left (V_2 \cdot k_1\right ) \left (V_3 \cdot k_4\right ) \\ - k_3^\mu \left (V_2 \cdot V_3\right ) \left (V_4 \cdot k_1\right ) \\ - V_3^\mu \left (V_2 \cdot k_4\right ) \left (V_4 \cdot k_1\right ) \\ - k_4^\mu \left (V_2 \cdot V_3\right ) \left (V_4 \cdot k_2\right ) \\ - V_3^\mu \left (V_2 \cdot k_3\right ) \left (V_4 \cdot k_2\right ) \\ - k_2^\mu \left (V_2 \cdot V_3\right ) \left (V_4 \cdot k_3\right ) \\ - V_3^\mu \left (V_2 \cdot k_1\right ) \left (V_4 \cdot k_3\right ) \\ - V_2^\mu \left (V_3 \cdot V_4\right ) \left (k_1 \cdot k_3\right ) \\ - V_2^\mu \left (V_3 \cdot V_4\right ) \left (k_1 \cdot k_4\right ) \\ - V_2^\mu \left (V_3 \cdot V_4\right ) \left (k_2 \cdot k_3\right ) \\ - V_2^\mu \left (V_3 \cdot V_4\right ) \left (k_2 \cdot k_4\right ) \\ \right ] + g_3 \left [ k_4^\mu \left (V_2 \cdot k_3\right ) \left (V_3 \cdot V_4\right ) \\ + k_3^\mu \left (V_2 \cdot k_4\right ) \left (V_3 \cdot V_4\right ) \\ + V_4^\mu \left (V_2 \cdot V_3\right ) \left (k_3 \cdot k_4\right ) \\ + V_3^\mu \left (V_2 \cdot V_4\right ) \left (k_3 \cdot k_4\right ) \\ - k_3^\mu \left (V_2 \cdot V_4\right ) \left (V_3 \cdot k_4\right ) \\ - V_4^\mu \left (V_2 \cdot k_3\right ) \left (V_3 \cdot k_4\right ) \\ - k_4^\mu \left (V_2 \cdot V_3\right ) \left (V_4 \cdot k_3\right ) \\ - V_3^\mu \left (V_2 \cdot k_4\right ) \left (V_4 \cdot k_3\right ) \\ \right ] \end{equation} <>= pure function g_dim8g3_m_7 (g1, g2, g3, v2, k2, v3, k3, v4, k4) result (v1) complex(kind=default), intent(in) :: g1, g2, g3 type(vector), intent(in) :: v2, v3, v4 type(momentum), intent(in) :: k2, k3, k4 type(vector) :: v1 type(momentum) :: k1 k1 = - k2 - k3 - k4 v1 = g1 * (v2 * (v3 * k2) * (v4 * k1) & + v2 * (v3 * k1) * (v4 * k2) & + v4 * (v2 * v3) * (k1 * k2) & + v3 * (v2 * v4) * (k1 * k2) & - k2 * (v2 * v4) * (v3 * k1) & - v4 * (v2 * k1) * (v3 * k2) & - k2 * (v2 * v3) * (v4 * k1) & - v3 * (v2 * k1) * (v4 * k2)) & + g2 * (k3 * (v2 * k1) * (v3 * v4) & + k4 * (v2 * k1) * (v3 * v4) & + k2 * (v2 * k3) * (v3 * v4) & + k2 * (v2 * k4) * (v3 * v4) & + v4 * (v2 * k4) * (v3 * k1) & + k4 * (v2 * v4) * (v3 * k2) & + v3 * (v2 * k3) * (v4 * k1) & + v2 * (v3 * k4) * (v4 * k1) & + k3 * (v2 * v3) * (v4 * k2) & + v2 * (v3 * k4) * (v4 * k2) & + v2 * (v3 * k1) * (v4 * k3) & + v2 * (v3 * k2) * (v4 * k3) & + v4 * (v2 * v3) * (k1 * k3) & + v3 * (v2 * v4) * (k1 * k4) & + v3 * (v2 * v4) * (k2 * k3) & + v4 * (v2 * v3) * (k2 * k4) & - k4 * (v2 * v4) * (v3 * k1) & - v4 * (v2 * k3) * (v3 * k1) & - k3 * (v2 * v4) * (v3 * k2) & - v4 * (v2 * k4) * (v3 * k2) & - k2 * (v2 * v4) * (v3 * k4) & - v4 * (v2 * k1) * (v3 * k4) & - k3 * (v2 * v3) * (v4 * k1) & - v3 * (v2 * k4) * (v4 * k1) & - k4 * (v2 * v3) * (v4 * k2) & - v3 * (v2 * k3) * (v4 * k2) & - k2 * (v2 * v3) * (v4 * k3) & - v3 * (v2 * k1) * (v4 * k3) & - v2 * (v3 * v4) * (k1 * k3) & - v2 * (v3 * v4) * (k1 * k4) & - v2 * (v3 * v4) * (k2 * k3) & - v2 * (v3 * v4) * (k2 * k4)) & + g3 * (k4 * (v2 * k3) * (v3 * v4) & + k3 * (v2 * k4) * (v3 * v4) & + v4 * (v2 * v3) * (k3 * k4) & + v3 * (v2 * v4) * (k3 * k4) & - k3 * (v2 * v4) * (v3 * k4) & - v4 * (v2 * k3) * (v3 * k4) & - k4 * (v2 * v3) * (v4 * k3) & - v3 * (v2 * k4) * (v4 * k3)) end function g_dim8g3_m_7 @ \section{Graviton Couplings} <>= public :: s_gravs, v_gravv, grav_ss, grav_vv @ <>= pure function s_gravs (g, m, k1, k2, t, s) result (phi) complex(kind=default), intent(in) :: g, s real(kind=default), intent(in) :: m type(momentum), intent(in) :: k1, k2 type(tensor), intent(in) :: t complex(kind=default) :: phi, t_tr t_tr = t%t(0,0) - t%t(1,1) - t%t(2,2) - t%t(3,3) phi = g * s * (((t*k1)*k2) + ((t*k2)*k1) & - g * (m**2 + (k1*k2))*t_tr)/2.0_default end function s_gravs @ <>= pure function grav_ss (g, m, k1, k2, s1, s2) result (t) complex(kind=default), intent(in) :: g, s1, s2 real(kind=default), intent(in) :: m type(momentum), intent(in) :: k1, k2 type(tensor) :: t_metric, t t_metric%t = 0 t_metric%t(0,0) = 1.0_default t_metric%t(1,1) = - 1.0_default t_metric%t(2,2) = - 1.0_default t_metric%t(3,3) = - 1.0_default t = g*s1*s2/2.0_default * (-(m**2 + (k1*k2)) * t_metric & + (k1.tprod.k2) + (k2.tprod.k1)) end function grav_ss @ <>= pure function v_gravv (g, m, k1, k2, t, v) result (vec) complex(kind=default), intent(in) :: g real(kind=default), intent(in) :: m type(momentum), intent(in) :: k1, k2 type(vector), intent(in) :: v type(tensor), intent(in) :: t complex(kind=default) :: t_tr real(kind=default) :: xi type(vector) :: vec xi = 1.0_default t_tr = t%t(0,0) - t%t(1,1) - t%t(2,2) - t%t(3,3) vec = (-g)/ 2.0_default * (((k1*k2) + m**2) * & (t*v + v*t - t_tr * v) + t_tr * (k1*v) * k2 & - (k1*v) * ((k2*t) + (t*k2)) & - ((k1*(t*v)) + (v*(t*k1))) * k2 & + ((k1*(t*k2)) + (k2*(t*k1))) * v) !!! Unitarity gauge: xi -> Infinity !!! + (1.0_default/xi) * (t_tr * ((k1*v)*k2) + & !!! (k2*v)*k2 + (k2*v)*k1 - (k1*(t*v))*k1 + & !!! (k2*v)*(k2*t) - (v*(t*k1))*k1 - (k2*v)*(t*k2))) end function v_gravv @ <>= pure function grav_vv (g, m, k1, k2, v1, v2) result (t) complex(kind=default), intent(in) :: g type(momentum), intent(in) :: k1, k2 real(kind=default), intent(in) :: m real(kind=default) :: xi type(vector), intent (in) :: v1, v2 type(tensor) :: t_metric, t xi = 0.00001_default t_metric%t = 0 t_metric%t(0,0) = 1.0_default t_metric%t(1,1) = - 1.0_default t_metric%t(2,2) = - 1.0_default t_metric%t(3,3) = - 1.0_default t = (-g)/2.0_default * ( & ((k1*k2) + m**2) * ( & (v1.tprod.v2) + (v2.tprod.v1) - (v1*v2) * t_metric) & + (v1*k2)*(v2*k1)*t_metric & - (k2*v1)*((v2.tprod.k1) + (k1.tprod.v2)) & - (k1*v2)*((v1.tprod.k2) + (k2.tprod.v1)) & + (v1*v2)*((k1.tprod.k2) + (k2.tprod.k1))) !!! Unitarity gauge: xi -> Infinity !!! + (1.0_default/xi) * ( & !!! ((k1*v1)*(k1*v2) + (k2*v1)*(k2*v2) + (k1*v1)*(k2*v2))* & !!! t_metric) - (k1*v1) * ((k1.tprod.v2) + (v2.tprod.k1)) & !!! - (k2*v2) * ((k2.tprod.v1) + (v1.tprod.k2))) end function grav_vv @ \section{Tensor Couplings} <>= public :: t2_vv, v_t2v, t2_vv_cf, v_t2v_cf, & t2_vv_1, v_t2v_1, t2_vv_t, v_t2v_t, & t2_phi2, phi_t2phi, t2_phi2_cf, phi_t2phi_cf @ \begin{equation} T_{\mu\nu} = g * V_{1 \,\mu} V_{2\,\nu} + V_{1\,\nu} V_{2\,\mu} \end{equation} <>= pure function t2_vv (g, v1, v2) result (t) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(tensor) :: t type(tensor) :: tmp tmp = v1.tprod.v2 t%t = g * (tmp%t + transpose (tmp%t)) end function t2_vv @ \begin{equation} V_{1\,\mu} = g * T_{\mu \nu} V_{2}^{\nu}+ T_{\nu \mu} V_{2}^{\nu} \end{equation} <>= pure function v_t2v (g, t, v) result (tv) complex(kind=default), intent(in) :: g type(tensor), intent(in) :: t type(vector), intent(in) :: v type(vector) :: tv type(tensor) :: tmp tmp%t = t%t + transpose (t%t) tv = g * (tmp * v) end function v_t2v @ \begin{equation} T_{\mu\nu} =- \frac{g}{2} V_1^\rho V_{2 \,\rho} \end{equation} <>= pure function t2_vv_cf (g, v1, v2) result (t) complex(kind=default), intent(in) :: g complex(kind=default) :: tmp_s type(vector), intent(in) :: v1, v2 type(tensor) :: t_metric, t t_metric%t = 0 t_metric%t(0,0) = 1.0_default t_metric%t(1,1) = - 1.0_default t_metric%t(2,2) = - 1.0_default t_metric%t(3,3) = - 1.0_default tmp_s = v1 * v2 t%t = - (g /2.0_default) * tmp_s * t_metric%t end function t2_vv_cf @ \begin{equation} V_{1\,\mu} = -\frac{g}{2} T^{\nu}_{ \nu} V_{2}^{\mu} \end{equation} <>= pure function v_t2v_cf (g, t, v) result (tv) complex(kind=default), intent(in) :: g type(tensor), intent(in) :: t type(vector), intent(in) :: v type(vector) :: tv, tmp_tv tmp_tv = ( t%t(0,0)-t%t(1,1)-t%t(2,2)-t%t(3,3) ) * v tv = - ( g /2.0_default) * tmp_tv end function v_t2v_cf @ \begin{equation} T_{\mu\nu} = g * \left ( k_{1 \,\mu} k_{2\,\nu} + k_{1\,\nu} k_{2\,\mu} \right ) \phi_1 \left ( k_1 \right ) \phi_1 \left ( k_2 \right ) \end{equation} <>= pure function t2_phi2 (g, phi1, k1, phi2, k2) result (t) complex(kind=default), intent(in) :: g, phi1, phi2 type(momentum), intent(in) :: k1, k2 type(tensor) :: t type(tensor) :: tmp tmp = k1.tprod.k2 t%t = g * (tmp%t + transpose (tmp%t)) * phi1 * phi2 end function t2_phi2 @ \begin{equation} \phi_{1} (k_1) =g * \left ( T_{\mu \nu} k_{1}^{\mu}k_{2}^{\nu} + T_{\nu \mu} k_{2}^{\mu}k_{1}^{\nu} \right ) \phi_2 \left (k_2 \right ) \end{equation} <>= pure function phi_t2phi (g, t, kt, phi2, k2) result (phi1) complex(kind=default), intent(in) :: g, phi2 type(tensor), intent(in) :: t type(momentum), intent(in) :: kt, k2 type(momentum) :: k1 complex(kind=default) :: phi1 type(tensor) :: tmp k1 = -kt - k2 tmp%t = t%t + transpose (t%t) phi1 = g * ( (tmp * k2) * k1) * phi2 end function phi_t2phi @ \begin{equation} T_{\mu\nu} =- \frac{g}{2} k_1^\rho k_{2 \,\rho} \phi_1 \left ( k_1 \right ) \phi_2 \left ( k_2 \right ) \end{equation} <>= pure function t2_phi2_cf (g, phi1, k1, phi2, k2) result (t) complex(kind=default), intent(in) :: g, phi1, phi2 complex(kind=default) :: tmp_s type(momentum), intent(in) :: k1, k2 type(tensor) :: t_metric, t t_metric%t = 0 t_metric%t(0,0) = 1.0_default t_metric%t(1,1) = - 1.0_default t_metric%t(2,2) = - 1.0_default t_metric%t(3,3) = - 1.0_default tmp_s = (k1 * k2) * phi1 * phi2 t%t = - (g /2.0_default) * tmp_s * t_metric%t end function t2_phi2_cf @ \begin{equation} \phi_1 (k_1) = - \frac{g}{2} T^{\nu}_{ \nu} \left (k_1 \cdot k_2 \right ) \phi_2 (k_2) \end{equation} <>= pure function phi_t2phi_cf (g, t, kt, phi2, k2) result (phi1) complex(kind=default), intent(in) :: g, phi2 type(tensor), intent(in) :: t type(momentum), intent(in) :: kt, k2 type(momentum) :: k1 complex(kind=default) :: tmp_ts, phi1 k1 = - kt - k2 tmp_ts = ( t%t(0,0)-t%t(1,1)-t%t(2,2)-t%t(3,3) ) phi1 = - ( g /2.0_default) * tmp_ts * (k1 * k2) * phi2 end function phi_t2phi_cf @ <>= pure function t2_vv_1 (g, v1, v2) result (t) complex(kind=default), intent(in) :: g complex(kind=default) :: tmp_s type(vector), intent(in) :: v1, v2 type(tensor) :: tmp type(tensor) :: t_metric, t t_metric%t = 0 t_metric%t(0,0) = 1.0_default t_metric%t(1,1) = - 1.0_default t_metric%t(2,2) = - 1.0_default t_metric%t(3,3) = - 1.0_default tmp = v1.tprod.v2 tmp_s = v1 * v2 t%t = g * (tmp%t + transpose (tmp%t) - tmp_s * t_metric%t ) end function t2_vv_1 @ <>= pure function v_t2v_1 (g, t, v) result (tv) complex(kind=default), intent(in) :: g type(tensor), intent(in) :: t type(vector), intent(in) :: v type(vector) :: tv, tmp_tv type(tensor) :: tmp tmp_tv = ( t%t(0,0)-t%t(1,1)-t%t(2,2)-t%t(3,3) ) * v tmp%t = t%t + transpose (t%t) tv = g * (tmp * v - tmp_tv) end function v_t2v_1 @ <>= pure function t2_vv_t (g, v1, k1, v2, k2) result (t) complex(kind=default), intent(in) :: g complex(kind=default) :: tmp_s type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(tensor) :: tmp, tmp_v1k2, tmp_v2k1, tmp_k1k2, tmp2 type(tensor) :: t_metric, t t_metric%t = 0 t_metric%t(0,0) = 1.0_default t_metric%t(1,1) = - 1.0_default t_metric%t(2,2) = - 1.0_default t_metric%t(3,3) = - 1.0_default tmp = v1.tprod.v2 tmp_s = v1 * v2 tmp_v1k2 = (v2 * k1) * (v1.tprod.k2) tmp_v2k1 = (v1 * k2) * (v2.tprod.k1) tmp_k1k2 = tmp_s * (k1.tprod.k2) tmp2%t = tmp_v1k2%t + tmp_v2k1%t - tmp_k1k2%t t%t = g * ( (k1*k2) * (tmp%t + transpose (tmp%t) - tmp_s * t_metric%t ) & + ((v1 * k2) * (v2 * k1)) * t_metric%t & - tmp2%t - transpose(tmp2%t)) end function t2_vv_t @ <>= pure function v_t2v_t (g, t, kt, v, kv) result (tv) complex(kind=default), intent(in) :: g type(tensor), intent(in) :: t type(vector), intent(in) :: v type(momentum), intent(in) :: kt, kv type(momentum) :: kout type(vector) :: tv, tmp_tv type(tensor) :: tmp kout = - (kt + kv) tmp_tv = ( t%t(0,0)-t%t(1,1)-t%t(2,2)-t%t(3,3) ) * v tmp%t = t%t + transpose (t%t) tv = g * ( (tmp * v - tmp_tv) * (kv * kout )& + ( t%t(0,0)-t%t(1,1)-t%t(2,2)-t%t(3,3) ) * (kout * v ) * kv & - (kout * v) * ( tmp * kv) & - (v* (t * kout) + kout * (t * v)) * kv & + (kout* (t * kv) + kv * (t * kout)) * v) end function v_t2v_t @ <>= public :: t2_vv_d5_1, v_t2v_d5_1 @ <>= pure function t2_vv_d5_1 (g, v1, k1, v2, k2) result (t) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(tensor) :: t t = (g * (v1 * v2)) * (k1-k2).tprod.(k1-k2) end function t2_vv_d5_1 @ <>= pure function v_t2v_d5_1 (g, t1, k1, v2, k2) result (tv) complex(kind=default), intent(in) :: g type(tensor), intent(in) :: t1 type(vector), intent(in) :: v2 type(momentum), intent(in) :: k1, k2 type(vector) :: tv tv = (g * ((k1+2*k2).tprod.(k1+2*k2) * t1)) * v2 end function v_t2v_d5_1 @ <>= public :: t2_vv_d5_2, v_t2v_d5_2 @ <>= pure function t2_vv_d5_2 (g, v1, k1, v2, k2) result (t) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(tensor) :: t t = (g * (k2 * v1)) * (k2-k1).tprod.v2 t%t = t%t + transpose (t%t) end function t2_vv_d5_2 @ <>= pure function v_t2v_d5_2 (g, t1, k1, v2, k2) result (tv) complex(kind=default), intent(in) :: g type(tensor), intent(in) :: t1 type(vector), intent(in) :: v2 type(momentum), intent(in) :: k1, k2 type(vector) :: tv type(tensor) :: tmp type(momentum) :: k1_k2, k1_2k2 k1_k2 = k1 + k2 k1_2k2 = k1_k2 + k2 tmp%t = t1%t + transpose (t1%t) tv = (g * (k1_k2 * v2)) * (k1_2k2 * tmp) end function v_t2v_d5_2 @ <>= public :: t2_vv_d7, v_t2v_d7 @ <>= pure function t2_vv_d7 (g, v1, k1, v2, k2) result (t) complex(kind=default), intent(in) :: g type(vector), intent(in) :: v1, v2 type(momentum), intent(in) :: k1, k2 type(tensor) :: t t = (g * (k2 * v1) * (k1 * v2)) * (k1-k2).tprod.(k1-k2) end function t2_vv_d7 @ <>= pure function v_t2v_d7 (g, t1, k1, v2, k2) result (tv) complex(kind=default), intent(in) :: g type(tensor), intent(in) :: t1 type(vector), intent(in) :: v2 type(momentum), intent(in) :: k1, k2 type(vector) :: tv type(vector) :: k1_k2, k1_2k2 k1_k2 = k1 + k2 k1_2k2 = k1_k2 + k2 tv = (- g * (k1_k2 * v2) * (k1_2k2.tprod.k1_2k2 * t1)) * k2 end function v_t2v_d7 @ \section{Spinor Couplings} <<[[omega_spinor_couplings.f90]]>>= <> module omega_spinor_couplings use kinds use constants use omega_spinors use omega_vectors use omega_tensors use omega_couplings implicit none private <> <> <> <> integer, parameter, public :: omega_spinor_cpls_2010_01_A = 0 contains <> <> <> <> end module omega_spinor_couplings @ See table~\ref{tab:fermionic-currents} for the names of Fortran functions. We could have used long names instead, but this would increase the chance of running past continuation line limits without adding much to the legibility. @ \subsection{Fermionic Vector and Axial Couplings} There's more than one chiral representation. This one is compatible with HELAS~\cite{HELAS}. \begin{equation} \gamma^0 = \begin{pmatrix} 0 & \mathbf{1} \\ \mathbf{1} & 0 \end{pmatrix},\; \gamma^i = \begin{pmatrix} 0 & \sigma^i \\ -\sigma^i & 0 \end{pmatrix},\; \gamma_5 = i\gamma^0\gamma^1\gamma^2\gamma^3 = \begin{pmatrix} -\mathbf{1} & 0 \\ 0 & \mathbf{1} \end{pmatrix} \end{equation} Therefore \begin{subequations} \begin{align} g_S + g_P\gamma_5 &= \begin{pmatrix} g_S - g_P & 0 & 0 & 0 \\ 0 & g_S - g_P & 0 & 0 \\ 0 & 0 & g_S + g_P & 0 \\ 0 & 0 & 0 & g_S + g_P \end{pmatrix} \\ g_V\gamma^0 - g_A\gamma^0\gamma_5 &= \begin{pmatrix} 0 & 0 & g_V - g_A & 0 \\ 0 & 0 & 0 & g_V - g_A \\ g_V + g_A & 0 & 0 & 0 \\ 0 & g_V + g_A & 0 & 0 \end{pmatrix} \\ g_V\gamma^1 - g_A\gamma^1\gamma_5 &= \begin{pmatrix} 0 & 0 & 0 & g_V - g_A \\ 0 & 0 & g_V - g_A & 0 \\ 0 & - g_V - g_A & 0 & 0 \\ - g_V - g_A & 0 & 0 & 0 \end{pmatrix} \\ g_V\gamma^2 - g_A\gamma^2\gamma_5 &= \begin{pmatrix} 0 & 0 & 0 & -\ii(g_V - g_A) \\ 0 & 0 & \ii(g_V - g_A) & 0 \\ 0 & \ii(g_V + g_A) & 0 & 0 \\ -\ii(g_V + g_A) & 0 & 0 & 0 \end{pmatrix} \\ g_V\gamma^3 - g_A\gamma^3\gamma_5 &= \begin{pmatrix} 0 & 0 & g_V - g_A & 0 \\ 0 & 0 & 0 & - g_V + g_A \\ - g_V - g_A & 0 & 0 & 0 \\ 0 & g_V + g_A & 0 & 0 \end{pmatrix} \end{align} \end{subequations} \begin{table} \begin{center} \begin{tabular}{>{$}l<{$}|>{$}l<{$}} \bar\psi(g_V\gamma^\mu - g_A\gamma^\mu\gamma_5)\psi & \text{\texttt{va\_ff}}(g_V,g_A,\bar\psi,\psi) \\ g_V\bar\psi\gamma^\mu\psi & \text{\texttt{v\_ff}}(g_V,\bar\psi,\psi) \\ g_A\bar\psi\gamma_5\gamma^\mu\psi & \text{\texttt{a\_ff}}(g_A,\bar\psi,\psi) \\ g_L\bar\psi\gamma^\mu(1-\gamma_5)\psi & \text{\texttt{vl\_ff}}(g_L,\bar\psi,\psi) \\ g_R\bar\psi\gamma^\mu(1+\gamma_5)\psi & \text{\texttt{vr\_ff}}(g_R,\bar\psi,\psi) \\\hline \fmslash{V}(g_V - g_A\gamma_5)\psi & \text{\texttt{f\_vaf}}(g_V,g_A,V,\psi) \\ g_V\fmslash{V}\psi & \text{\texttt{f\_vf}}(g_V,V,\psi) \\ g_A\gamma_5\fmslash{V}\psi & \text{\texttt{f\_af}}(g_A,V,\psi) \\ g_L\fmslash{V}(1-\gamma_5)\psi & \text{\texttt{f\_vlf}}(g_L,V,\psi) \\ g_R\fmslash{V}(1+\gamma_5)\psi & \text{\texttt{f\_vrf}}(g_R,V,\psi) \\\hline \bar\psi\fmslash{V}(g_V - g_A\gamma_5) & \text{\texttt{f\_fva}}(g_V,g_A,\bar\psi,V) \\ g_V\bar\psi\fmslash{V} & \text{\texttt{f\_fv}}(g_V,\bar\psi,V) \\ g_A\bar\psi\gamma_5\fmslash{V} & \text{\texttt{f\_fa}}(g_A,\bar\psi,V) \\ g_L\bar\psi\fmslash{V}(1-\gamma_5) & \text{\texttt{f\_fvl}}(g_L,\bar\psi,V) \\ g_R\bar\psi\fmslash{V}(1+\gamma_5) & \text{\texttt{f\_fvr}}(g_R,\bar\psi,V) \end{tabular} \end{center} \caption{\label{tab:fermionic-currents} Mnemonically abbreviated names of Fortran functions implementing fermionic vector and axial currents.} \end{table} \begin{table} \begin{center} \begin{tabular}{>{$}l<{$}|>{$}l<{$}} \bar\psi(g_S + g_P\gamma_5)\psi & \text{\texttt{sp\_ff}}(g_S,g_P,\bar\psi,\psi) \\ g_S\bar\psi\psi & \text{\texttt{s\_ff}}(g_S,\bar\psi,\psi) \\ g_P\bar\psi\gamma_5\psi & \text{\texttt{p\_ff}}(g_P,\bar\psi,\psi) \\ g_L\bar\psi(1-\gamma_5)\psi & \text{\texttt{sl\_ff}}(g_L,\bar\psi,\psi) \\ g_R\bar\psi(1+\gamma_5)\psi & \text{\texttt{sr\_ff}}(g_R,\bar\psi,\psi) \\\hline \phi(g_S + g_P\gamma_5)\psi & \text{\texttt{f\_spf}}(g_S,g_P,\phi,\psi) \\ g_S\phi\psi & \text{\texttt{f\_sf}}(g_S,\phi,\psi) \\ g_P\phi\gamma_5\psi & \text{\texttt{f\_pf}}(g_P,\phi,\psi) \\ g_L\phi(1-\gamma_5)\psi & \text{\texttt{f\_slf}}(g_L,\phi,\psi) \\ g_R\phi(1+\gamma_5)\psi & \text{\texttt{f\_srf}}(g_R,\phi,\psi) \\\hline \bar\psi\phi(g_S + g_P\gamma_5) & \text{\texttt{f\_fsp}}(g_S,g_P,\bar\psi,\phi) \\ g_S\bar\psi\phi & \text{\texttt{f\_fs}}(g_S,\bar\psi,\phi) \\ g_P\bar\psi\phi\gamma_5 & \text{\texttt{f\_fp}}(g_P,\bar\psi,\phi) \\ g_L\bar\psi\phi(1-\gamma_5) & \text{\texttt{f\_fsl}}(g_L,\bar\psi,\phi) \\ g_R\bar\psi\phi(1+\gamma_5) & \text{\texttt{f\_fsr}}(g_R,\bar\psi,\phi) \end{tabular} \end{center} \caption{\label{tab:fermionic-scalar currents} Mnemonically abbreviated names of Fortran functions implementing fermionic scalar and pseudo scalar ``currents''.} \end{table} <>= public :: va_ff, v_ff, a_ff, vl_ff, vr_ff, vlr_ff, grav_ff, va2_ff, & tva_ff, tlr_ff, trl_ff, tvam_ff, tlrm_ff, trlm_ff, va3_ff @ <>= pure function va_ff (gv, ga, psibar, psi) result (j) type(vector) :: j complex(kind=default), intent(in) :: gv, ga type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi complex(kind=default) :: gl, gr complex(kind=default) :: g13, g14, g23, g24, g31, g32, g41, g42 gl = gv + ga gr = gv - ga g13 = psibar%a(1)*psi%a(3) g14 = psibar%a(1)*psi%a(4) g23 = psibar%a(2)*psi%a(3) g24 = psibar%a(2)*psi%a(4) g31 = psibar%a(3)*psi%a(1) g32 = psibar%a(3)*psi%a(2) g41 = psibar%a(4)*psi%a(1) g42 = psibar%a(4)*psi%a(2) j%t = gr * ( g13 + g24) + gl * ( g31 + g42) j%x(1) = gr * ( g14 + g23) - gl * ( g32 + g41) j%x(2) = (gr * ( - g14 + g23) + gl * ( g32 - g41)) * (0, 1) j%x(3) = gr * ( g13 - g24) + gl * ( - g31 + g42) end function va_ff @ <>= pure function va2_ff (gva, psibar, psi) result (j) type(vector) :: j complex(kind=default), intent(in), dimension(2) :: gva type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi complex(kind=default) :: gl, gr complex(kind=default) :: g13, g14, g23, g24, g31, g32, g41, g42 gl = gva(1) + gva(2) gr = gva(1) - gva(2) g13 = psibar%a(1)*psi%a(3) g14 = psibar%a(1)*psi%a(4) g23 = psibar%a(2)*psi%a(3) g24 = psibar%a(2)*psi%a(4) g31 = psibar%a(3)*psi%a(1) g32 = psibar%a(3)*psi%a(2) g41 = psibar%a(4)*psi%a(1) g42 = psibar%a(4)*psi%a(2) j%t = gr * ( g13 + g24) + gl * ( g31 + g42) j%x(1) = gr * ( g14 + g23) - gl * ( g32 + g41) j%x(2) = (gr * ( - g14 + g23) + gl * ( g32 - g41)) * (0, 1) j%x(3) = gr * ( g13 - g24) + gl * ( - g31 + g42) end function va2_ff @ <>= pure function va3_ff (gv, ga, psibar, psi) result (j) type(vector) :: j complex(kind=default), intent(in) :: gv, ga type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi j = va_ff (gv, ga, psibar, psi) j%t = 0.0_default end function va3_ff @ <>= pure function tva_ff (gv, ga, psibar, psi) result (t) type(tensor2odd) :: t complex(kind=default), intent(in) :: gv, ga type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi complex(kind=default) :: gl, gr complex(kind=default) :: g12, g21, g1m2, g34, g43, g3m4 gr = gv + ga gl = gv - ga g12 = psibar%a(1)*psi%a(2) g21 = psibar%a(2)*psi%a(1) g1m2 = psibar%a(1)*psi%a(1) - psibar%a(2)*psi%a(2) g34 = psibar%a(3)*psi%a(4) g43 = psibar%a(4)*psi%a(3) g3m4 = psibar%a(3)*psi%a(3) - psibar%a(4)*psi%a(4) t%e(1) = (gl * ( - g12 - g21) + gr * ( g34 + g43)) * (0, 1) t%e(2) = gl * ( - g12 + g21) + gr * ( g34 - g43) t%e(3) = (gl * ( - g1m2 ) + gr * ( g3m4 )) * (0, 1) t%b(1) = gl * ( g12 + g21) + gr * ( g34 + g43) t%b(2) = (gl * ( - g12 + g21) + gr * ( - g34 + g43)) * (0, 1) t%b(3) = gl * ( g1m2 ) + gr * ( g3m4 ) end function tva_ff @ <>= pure function tlr_ff (gl, gr, psibar, psi) result (t) type(tensor2odd) :: t complex(kind=default), intent(in) :: gl, gr type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi t = tva_ff (gr+gl, gr-gl, psibar, psi) end function tlr_ff @ <>= pure function trl_ff (gr, gl, psibar, psi) result (t) type(tensor2odd) :: t complex(kind=default), intent(in) :: gl, gr type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi t = tva_ff (gr+gl, gr-gl, psibar, psi) end function trl_ff @ <>= pure function tvam_ff (gv, ga, psibar, psi, p) result (j) type(vector) :: j complex(kind=default), intent(in) :: gv, ga type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi type(momentum), intent(in) :: p j = (tva_ff(gv, ga, psibar, psi) * p) * (0,1) end function tvam_ff @ <>= pure function tlrm_ff (gl, gr, psibar, psi, p) result (j) type(vector) :: j complex(kind=default), intent(in) :: gl, gr type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi type(momentum), intent(in) :: p j = tvam_ff (gr+gl, gr-gl, psibar, psi, p) end function tlrm_ff @ <>= pure function trlm_ff (gr, gl, psibar, psi, p) result (j) type(vector) :: j complex(kind=default), intent(in) :: gl, gr type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi type(momentum), intent(in) :: p j = tvam_ff (gr+gl, gr-gl, psibar, psi, p) end function trlm_ff @ Special cases that avoid some multiplications <>= pure function v_ff (gv, psibar, psi) result (j) type(vector) :: j complex(kind=default), intent(in) :: gv type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi complex(kind=default) :: g13, g14, g23, g24, g31, g32, g41, g42 g13 = psibar%a(1)*psi%a(3) g14 = psibar%a(1)*psi%a(4) g23 = psibar%a(2)*psi%a(3) g24 = psibar%a(2)*psi%a(4) g31 = psibar%a(3)*psi%a(1) g32 = psibar%a(3)*psi%a(2) g41 = psibar%a(4)*psi%a(1) g42 = psibar%a(4)*psi%a(2) j%t = gv * ( g13 + g24 + g31 + g42) j%x(1) = gv * ( g14 + g23 - g32 - g41) j%x(2) = gv * ( - g14 + g23 + g32 - g41) * (0, 1) j%x(3) = gv * ( g13 - g24 - g31 + g42) end function v_ff @ <>= pure function a_ff (ga, psibar, psi) result (j) type(vector) :: j complex(kind=default), intent(in) :: ga type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi complex(kind=default) :: g13, g14, g23, g24, g31, g32, g41, g42 g13 = psibar%a(1)*psi%a(3) g14 = psibar%a(1)*psi%a(4) g23 = psibar%a(2)*psi%a(3) g24 = psibar%a(2)*psi%a(4) g31 = psibar%a(3)*psi%a(1) g32 = psibar%a(3)*psi%a(2) g41 = psibar%a(4)*psi%a(1) g42 = psibar%a(4)*psi%a(2) j%t = ga * ( - g13 - g24 + g31 + g42) j%x(1) = - ga * ( g14 + g23 + g32 + g41) j%x(2) = ga * ( g14 - g23 + g32 - g41) * (0, 1) j%x(3) = ga * ( - g13 + g24 - g31 + g42) end function a_ff @ <>= pure function vl_ff (gl, psibar, psi) result (j) type(vector) :: j complex(kind=default), intent(in) :: gl type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi complex(kind=default) :: gl2 complex(kind=default) :: g31, g32, g41, g42 gl2 = 2 * gl g31 = psibar%a(3)*psi%a(1) g32 = psibar%a(3)*psi%a(2) g41 = psibar%a(4)*psi%a(1) g42 = psibar%a(4)*psi%a(2) j%t = gl2 * ( g31 + g42) j%x(1) = - gl2 * ( g32 + g41) j%x(2) = gl2 * ( g32 - g41) * (0, 1) j%x(3) = gl2 * ( - g31 + g42) end function vl_ff @ <>= pure function vr_ff (gr, psibar, psi) result (j) type(vector) :: j complex(kind=default), intent(in) :: gr type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi complex(kind=default) :: gr2 complex(kind=default) :: g13, g14, g23, g24 gr2 = 2 * gr g13 = psibar%a(1)*psi%a(3) g14 = psibar%a(1)*psi%a(4) g23 = psibar%a(2)*psi%a(3) g24 = psibar%a(2)*psi%a(4) j%t = gr2 * ( g13 + g24) j%x(1) = gr2 * ( g14 + g23) j%x(2) = gr2 * ( - g14 + g23) * (0, 1) j%x(3) = gr2 * ( g13 - g24) end function vr_ff @ <>= pure function grav_ff (g, m, kb, k, psibar, psi) result (j) type(tensor) :: j complex(kind=default), intent(in) :: g real(kind=default), intent(in) :: m type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi type(momentum), intent(in) :: kb, k complex(kind=default) :: g2, g8, c_dum type(vector) :: v_dum type(tensor) :: t_metric t_metric%t = 0 t_metric%t(0,0) = 1.0_default t_metric%t(1,1) = - 1.0_default t_metric%t(2,2) = - 1.0_default t_metric%t(3,3) = - 1.0_default g2 = g/2.0_default g8 = g/8.0_default v_dum = v_ff(g8, psibar, psi) c_dum = (- m) * s_ff (g2, psibar, psi) - (kb+k)*v_dum j = c_dum*t_metric - (((kb+k).tprod.v_dum) + & (v_dum.tprod.(kb+k))) end function grav_ff @ \begin{equation} g_L\gamma_\mu(1-\gamma_5) + g_R\gamma_\mu(1+\gamma_5) = (g_L+g_R)\gamma_\mu - (g_L-g_R)\gamma_\mu\gamma_5 = g_V\gamma_\mu - g_A\gamma_\mu\gamma_5 \end{equation} \ldots{} give the compiler the benefit of the doubt that it will optimize the function all. If not, we could inline it \ldots <>= pure function vlr_ff (gl, gr, psibar, psi) result (j) type(vector) :: j complex(kind=default), intent(in) :: gl, gr type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi j = va_ff (gl+gr, gl-gr, psibar, psi) end function vlr_ff @ and \begin{equation} \fmslash{v} - \fmslash{a}\gamma_5 = \begin{pmatrix} 0 & 0 & v_- - a_- & - v^* + a^* \\ 0 & 0 & - v + a & v_+ - a_+ \\ v_+ + a_+ & v^* + a^* & 0 & 0 \\ v + a & v_- + a_- & 0 & 0 \end{pmatrix} \end{equation} with $v_\pm=v_0\pm v_3$, $a_\pm=a_0\pm a_3$, $v=v_1+\ii v_2$, $v^*=v_1-\ii v_2$, $a=a_1+\ii a_2$, and $a^*=a_1-\ii a_2$. But note that~$\cdot^*$ is \emph{not} complex conjugation for complex~$v_\mu$ or~$a_\mu$. <>= public :: f_vaf, f_vf, f_af, f_vlf, f_vrf, f_vlrf, f_va2f, & f_tvaf, f_tlrf, f_trlf, f_tvamf, f_tlrmf, f_trlmf, f_va3f @ <>= pure function f_vaf (gv, ga, v, psi) result (vpsi) type(spinor) :: vpsi complex(kind=default), intent(in) :: gv, ga type(vector), intent(in) :: v type(spinor), intent(in) :: psi complex(kind=default) :: gl, gr complex(kind=default) :: vp, vm, v12, v12s gl = gv + ga gr = gv - ga vp = v%t + v%x(3) vm = v%t - v%x(3) v12 = v%x(1) + (0,1)*v%x(2) v12s = v%x(1) - (0,1)*v%x(2) vpsi%a(1) = gr * ( vm * psi%a(3) - v12s * psi%a(4)) vpsi%a(2) = gr * ( - v12 * psi%a(3) + vp * psi%a(4)) vpsi%a(3) = gl * ( vp * psi%a(1) + v12s * psi%a(2)) vpsi%a(4) = gl * ( v12 * psi%a(1) + vm * psi%a(2)) end function f_vaf @ <>= pure function f_va2f (gva, v, psi) result (vpsi) type(spinor) :: vpsi complex(kind=default), intent(in), dimension(2) :: gva type(vector), intent(in) :: v type(spinor), intent(in) :: psi complex(kind=default) :: gl, gr complex(kind=default) :: vp, vm, v12, v12s gl = gva(1) + gva(2) gr = gva(1) - gva(2) vp = v%t + v%x(3) vm = v%t - v%x(3) v12 = v%x(1) + (0,1)*v%x(2) v12s = v%x(1) - (0,1)*v%x(2) vpsi%a(1) = gr * ( vm * psi%a(3) - v12s * psi%a(4)) vpsi%a(2) = gr * ( - v12 * psi%a(3) + vp * psi%a(4)) vpsi%a(3) = gl * ( vp * psi%a(1) + v12s * psi%a(2)) vpsi%a(4) = gl * ( v12 * psi%a(1) + vm * psi%a(2)) end function f_va2f @ <>= pure function f_va3f (gv, ga, v, psi) result (vpsi) type(spinor) :: vpsi complex(kind=default), intent(in) :: gv, ga type(vector), intent(in) :: v type(spinor), intent(in) :: psi complex(kind=default) :: gl, gr complex(kind=default) :: vp, vm, v12, v12s gl = gv + ga gr = gv - ga vp = v%x(3) !+ v%t vm = - v%x(3) !+ v%t v12 = v%x(1) + (0,1)*v%x(2) v12s = v%x(1) - (0,1)*v%x(2) vpsi%a(1) = gr * ( vm * psi%a(3) - v12s * psi%a(4)) vpsi%a(2) = gr * ( - v12 * psi%a(3) + vp * psi%a(4)) vpsi%a(3) = gl * ( vp * psi%a(1) + v12s * psi%a(2)) vpsi%a(4) = gl * ( v12 * psi%a(1) + vm * psi%a(2)) end function f_va3f @ <>= pure function f_tvaf (gv, ga, t, psi) result (tpsi) type(spinor) :: tpsi complex(kind=default), intent(in) :: gv, ga type(tensor2odd), intent(in) :: t type(spinor), intent(in) :: psi complex(kind=default) :: gl, gr complex(kind=default) :: e21, e21s, b12, b12s, be3, be3s gr = gv + ga gl = gv - ga e21 = t%e(2) + t%e(1)*(0,1) e21s = t%e(2) - t%e(1)*(0,1) b12 = t%b(1) + t%b(2)*(0,1) b12s = t%b(1) - t%b(2)*(0,1) be3 = t%b(3) + t%e(3)*(0,1) be3s = t%b(3) - t%e(3)*(0,1) tpsi%a(1) = 2*gl * ( psi%a(1) * be3 + psi%a(2) * ( e21 +b12s)) tpsi%a(2) = 2*gl * ( - psi%a(2) * be3 + psi%a(1) * (-e21s+b12 )) tpsi%a(3) = 2*gr * ( psi%a(3) * be3s + psi%a(4) * (-e21 +b12s)) tpsi%a(4) = 2*gr * ( - psi%a(4) * be3s + psi%a(3) * ( e21s+b12 )) end function f_tvaf @ <>= pure function f_tlrf (gl, gr, t, psi) result (tpsi) type(spinor) :: tpsi complex(kind=default), intent(in) :: gl, gr type(tensor2odd), intent(in) :: t type(spinor), intent(in) :: psi tpsi = f_tvaf (gr+gl, gr-gl, t, psi) end function f_tlrf @ <>= pure function f_trlf (gr, gl, t, psi) result (tpsi) type(spinor) :: tpsi complex(kind=default), intent(in) :: gl, gr type(tensor2odd), intent(in) :: t type(spinor), intent(in) :: psi tpsi = f_tvaf (gr+gl, gr-gl, t, psi) end function f_trlf @ <>= pure function f_tvamf (gv, ga, v, psi, k) result (vpsi) type(spinor) :: vpsi complex(kind=default), intent(in) :: gv, ga type(vector), intent(in) :: v type(spinor), intent(in) :: psi type(momentum), intent(in) :: k type(tensor2odd) :: t t = (v.wedge.k) * (0, 0.5) vpsi = f_tvaf(gv, ga, t, psi) end function f_tvamf @ <>= pure function f_tlrmf (gl, gr, v, psi, k) result (vpsi) type(spinor) :: vpsi complex(kind=default), intent(in) :: gl, gr type(vector), intent(in) :: v type(spinor), intent(in) :: psi type(momentum), intent(in) :: k vpsi = f_tvamf (gr+gl, gr-gl, v, psi, k) end function f_tlrmf @ <>= pure function f_trlmf (gr, gl, v, psi, k) result (vpsi) type(spinor) :: vpsi complex(kind=default), intent(in) :: gl, gr type(vector), intent(in) :: v type(spinor), intent(in) :: psi type(momentum), intent(in) :: k vpsi = f_tvamf (gr+gl, gr-gl, v, psi, k) end function f_trlmf @ <>= pure function f_vf (gv, v, psi) result (vpsi) type(spinor) :: vpsi complex(kind=default), intent(in) :: gv type(vector), intent(in) :: v type(spinor), intent(in) :: psi complex(kind=default) :: vp, vm, v12, v12s vp = v%t + v%x(3) vm = v%t - v%x(3) v12 = v%x(1) + (0,1)*v%x(2) v12s = v%x(1) - (0,1)*v%x(2) vpsi%a(1) = gv * ( vm * psi%a(3) - v12s * psi%a(4)) vpsi%a(2) = gv * ( - v12 * psi%a(3) + vp * psi%a(4)) vpsi%a(3) = gv * ( vp * psi%a(1) + v12s * psi%a(2)) vpsi%a(4) = gv * ( v12 * psi%a(1) + vm * psi%a(2)) end function f_vf @ <>= pure function f_af (ga, v, psi) result (vpsi) type(spinor) :: vpsi complex(kind=default), intent(in) :: ga type(vector), intent(in) :: v type(spinor), intent(in) :: psi complex(kind=default) :: vp, vm, v12, v12s vp = v%t + v%x(3) vm = v%t - v%x(3) v12 = v%x(1) + (0,1)*v%x(2) v12s = v%x(1) - (0,1)*v%x(2) vpsi%a(1) = ga * ( - vm * psi%a(3) + v12s * psi%a(4)) vpsi%a(2) = ga * ( v12 * psi%a(3) - vp * psi%a(4)) vpsi%a(3) = ga * ( vp * psi%a(1) + v12s * psi%a(2)) vpsi%a(4) = ga * ( v12 * psi%a(1) + vm * psi%a(2)) end function f_af @ <>= pure function f_vlf (gl, v, psi) result (vpsi) type(spinor) :: vpsi complex(kind=default), intent(in) :: gl type(vector), intent(in) :: v type(spinor), intent(in) :: psi complex(kind=default) :: gl2 complex(kind=default) :: vp, vm, v12, v12s gl2 = 2 * gl vp = v%t + v%x(3) vm = v%t - v%x(3) v12 = v%x(1) + (0,1)*v%x(2) v12s = v%x(1) - (0,1)*v%x(2) vpsi%a(1) = 0 vpsi%a(2) = 0 vpsi%a(3) = gl2 * ( vp * psi%a(1) + v12s * psi%a(2)) vpsi%a(4) = gl2 * ( v12 * psi%a(1) + vm * psi%a(2)) end function f_vlf @ <>= pure function f_vrf (gr, v, psi) result (vpsi) type(spinor) :: vpsi complex(kind=default), intent(in) :: gr type(vector), intent(in) :: v type(spinor), intent(in) :: psi complex(kind=default) :: gr2 complex(kind=default) :: vp, vm, v12, v12s gr2 = 2 * gr vp = v%t + v%x(3) vm = v%t - v%x(3) v12 = v%x(1) + (0,1)*v%x(2) v12s = v%x(1) - (0,1)*v%x(2) vpsi%a(1) = gr2 * ( vm * psi%a(3) - v12s * psi%a(4)) vpsi%a(2) = gr2 * ( - v12 * psi%a(3) + vp * psi%a(4)) vpsi%a(3) = 0 vpsi%a(4) = 0 end function f_vrf @ <>= pure function f_vlrf (gl, gr, v, psi) result (vpsi) type(spinor) :: vpsi complex(kind=default), intent(in) :: gl, gr type(vector), intent(in) :: v type(spinor), intent(in) :: psi vpsi = f_vaf (gl+gr, gl-gr, v, psi) end function f_vlrf @ <>= public :: f_fva, f_fv, f_fa, f_fvl, f_fvr, f_fvlr, f_fva2, & f_ftva, f_ftlr, f_ftrl, f_ftvam, f_ftlrm, f_ftrlm, f_fva3 @ <>= pure function f_fva (gv, ga, psibar, v) result (psibarv) type(conjspinor) :: psibarv complex(kind=default), intent(in) :: gv, ga type(conjspinor), intent(in) :: psibar type(vector), intent(in) :: v complex(kind=default) :: gl, gr complex(kind=default) :: vp, vm, v12, v12s gl = gv + ga gr = gv - ga vp = v%t + v%x(3) vm = v%t - v%x(3) v12 = v%x(1) + (0,1)*v%x(2) v12s = v%x(1) - (0,1)*v%x(2) psibarv%a(1) = gl * ( psibar%a(3) * vp + psibar%a(4) * v12) psibarv%a(2) = gl * ( psibar%a(3) * v12s + psibar%a(4) * vm ) psibarv%a(3) = gr * ( psibar%a(1) * vm - psibar%a(2) * v12) psibarv%a(4) = gr * ( - psibar%a(1) * v12s + psibar%a(2) * vp ) end function f_fva @ <>= pure function f_fva2 (gva, psibar, v) result (psibarv) type(conjspinor) :: psibarv complex(kind=default), intent(in), dimension(2) :: gva type(conjspinor), intent(in) :: psibar type(vector), intent(in) :: v complex(kind=default) :: gl, gr complex(kind=default) :: vp, vm, v12, v12s gl = gva(1) + gva(2) gr = gva(1) - gva(2) vp = v%t + v%x(3) vm = v%t - v%x(3) v12 = v%x(1) + (0,1)*v%x(2) v12s = v%x(1) - (0,1)*v%x(2) psibarv%a(1) = gl * ( psibar%a(3) * vp + psibar%a(4) * v12) psibarv%a(2) = gl * ( psibar%a(3) * v12s + psibar%a(4) * vm ) psibarv%a(3) = gr * ( psibar%a(1) * vm - psibar%a(2) * v12) psibarv%a(4) = gr * ( - psibar%a(1) * v12s + psibar%a(2) * vp ) end function f_fva2 @ <>= pure function f_fva3 (gv, ga, psibar, v) result (psibarv) type(conjspinor) :: psibarv complex(kind=default), intent(in) :: gv, ga type(conjspinor), intent(in) :: psibar type(vector), intent(in) :: v complex(kind=default) :: gl, gr complex(kind=default) :: vp, vm, v12, v12s gl = gv + ga gr = gv - ga vp = v%x(3) !+ v%t vm = - v%x(3) !+ v%t v12 = v%x(1) + (0,1)*v%x(2) v12s = v%x(1) - (0,1)*v%x(2) psibarv%a(1) = gl * ( psibar%a(3) * vp + psibar%a(4) * v12) psibarv%a(2) = gl * ( psibar%a(3) * v12s + psibar%a(4) * vm ) psibarv%a(3) = gr * ( psibar%a(1) * vm - psibar%a(2) * v12) psibarv%a(4) = gr * ( - psibar%a(1) * v12s + psibar%a(2) * vp ) end function f_fva3 @ <>= pure function f_ftva (gv, ga, psibar, t) result (psibart) type(conjspinor) :: psibart complex(kind=default), intent(in) :: gv, ga type(conjspinor), intent(in) :: psibar type(tensor2odd), intent(in) :: t complex(kind=default) :: gl, gr complex(kind=default) :: e21, e21s, b12, b12s, be3, be3s gr = gv + ga gl = gv - ga e21 = t%e(2) + t%e(1)*(0,1) e21s = t%e(2) - t%e(1)*(0,1) b12 = t%b(1) + t%b(2)*(0,1) b12s = t%b(1) - t%b(2)*(0,1) be3 = t%b(3) + t%e(3)*(0,1) be3s = t%b(3) - t%e(3)*(0,1) psibart%a(1) = 2*gl * ( psibar%a(1) * be3 + psibar%a(2) * (-e21s+b12 )) psibart%a(2) = 2*gl * ( - psibar%a(2) * be3 + psibar%a(1) * ( e21 +b12s)) psibart%a(3) = 2*gr * ( psibar%a(3) * be3s + psibar%a(4) * ( e21s+b12 )) psibart%a(4) = 2*gr * ( - psibar%a(4) * be3s + psibar%a(3) * (-e21 +b12s)) end function f_ftva @ <>= pure function f_ftlr (gl, gr, psibar, t) result (psibart) type(conjspinor) :: psibart complex(kind=default), intent(in) :: gl, gr type(conjspinor), intent(in) :: psibar type(tensor2odd), intent(in) :: t psibart = f_ftva (gr+gl, gr-gl, psibar, t) end function f_ftlr @ <>= pure function f_ftrl (gr, gl, psibar, t) result (psibart) type(conjspinor) :: psibart complex(kind=default), intent(in) :: gl, gr type(conjspinor), intent(in) :: psibar type(tensor2odd), intent(in) :: t psibart = f_ftva (gr+gl, gr-gl, psibar, t) end function f_ftrl @ <>= pure function f_ftvam (gv, ga, psibar, v, k) result (psibarv) type(conjspinor) :: psibarv complex(kind=default), intent(in) :: gv, ga type(conjspinor), intent(in) :: psibar type(vector), intent(in) :: v type(momentum), intent(in) :: k type(tensor2odd) :: t t = (v.wedge.k) * (0, 0.5) psibarv = f_ftva(gv, ga, psibar, t) end function f_ftvam @ <>= pure function f_ftlrm (gl, gr, psibar, v, k) result (psibarv) type(conjspinor) :: psibarv complex(kind=default), intent(in) :: gl, gr type(conjspinor), intent(in) :: psibar type(vector), intent(in) :: v type(momentum), intent(in) :: k psibarv = f_ftvam (gr+gl, gr-gl, psibar, v, k) end function f_ftlrm @ <>= pure function f_ftrlm (gr, gl, psibar, v, k) result (psibarv) type(conjspinor) :: psibarv complex(kind=default), intent(in) :: gl, gr type(conjspinor), intent(in) :: psibar type(vector), intent(in) :: v type(momentum), intent(in) :: k psibarv = f_ftvam (gr+gl, gr-gl, psibar, v, k) end function f_ftrlm @ <>= pure function f_fv (gv, psibar, v) result (psibarv) type(conjspinor) :: psibarv complex(kind=default), intent(in) :: gv type(conjspinor), intent(in) :: psibar type(vector), intent(in) :: v complex(kind=default) :: vp, vm, v12, v12s vp = v%t + v%x(3) vm = v%t - v%x(3) v12 = v%x(1) + (0,1)*v%x(2) v12s = v%x(1) - (0,1)*v%x(2) psibarv%a(1) = gv * ( psibar%a(3) * vp + psibar%a(4) * v12) psibarv%a(2) = gv * ( psibar%a(3) * v12s + psibar%a(4) * vm ) psibarv%a(3) = gv * ( psibar%a(1) * vm - psibar%a(2) * v12) psibarv%a(4) = gv * ( - psibar%a(1) * v12s + psibar%a(2) * vp ) end function f_fv @ <>= pure function f_fa (ga, psibar, v) result (psibarv) type(conjspinor) :: psibarv complex(kind=default), intent(in) :: ga type(vector), intent(in) :: v type(conjspinor), intent(in) :: psibar complex(kind=default) :: vp, vm, v12, v12s vp = v%t + v%x(3) vm = v%t - v%x(3) v12 = v%x(1) + (0,1)*v%x(2) v12s = v%x(1) - (0,1)*v%x(2) psibarv%a(1) = ga * ( psibar%a(3) * vp + psibar%a(4) * v12) psibarv%a(2) = ga * ( psibar%a(3) * v12s + psibar%a(4) * vm ) psibarv%a(3) = ga * ( - psibar%a(1) * vm + psibar%a(2) * v12) psibarv%a(4) = ga * ( psibar%a(1) * v12s - psibar%a(2) * vp ) end function f_fa @ <>= pure function f_fvl (gl, psibar, v) result (psibarv) type(conjspinor) :: psibarv complex(kind=default), intent(in) :: gl type(conjspinor), intent(in) :: psibar type(vector), intent(in) :: v complex(kind=default) :: gl2 complex(kind=default) :: vp, vm, v12, v12s gl2 = 2 * gl vp = v%t + v%x(3) vm = v%t - v%x(3) v12 = v%x(1) + (0,1)*v%x(2) v12s = v%x(1) - (0,1)*v%x(2) psibarv%a(1) = gl2 * ( psibar%a(3) * vp + psibar%a(4) * v12) psibarv%a(2) = gl2 * ( psibar%a(3) * v12s + psibar%a(4) * vm ) psibarv%a(3) = 0 psibarv%a(4) = 0 end function f_fvl @ <>= pure function f_fvr (gr, psibar, v) result (psibarv) type(conjspinor) :: psibarv complex(kind=default), intent(in) :: gr type(conjspinor), intent(in) :: psibar type(vector), intent(in) :: v complex(kind=default) :: gr2 complex(kind=default) :: vp, vm, v12, v12s gr2 = 2 * gr vp = v%t + v%x(3) vm = v%t - v%x(3) v12 = v%x(1) + (0,1)*v%x(2) v12s = v%x(1) - (0,1)*v%x(2) psibarv%a(1) = 0 psibarv%a(2) = 0 psibarv%a(3) = gr2 * ( psibar%a(1) * vm - psibar%a(2) * v12) psibarv%a(4) = gr2 * ( - psibar%a(1) * v12s + psibar%a(2) * vp ) end function f_fvr @ <>= pure function f_fvlr (gl, gr, psibar, v) result (psibarv) type(conjspinor) :: psibarv complex(kind=default), intent(in) :: gl, gr type(conjspinor), intent(in) :: psibar type(vector), intent(in) :: v psibarv = f_fva (gl+gr, gl-gr, psibar, v) end function f_fvlr @ \subsection{Fermionic Scalar and Pseudo Scalar Couplings} <>= public :: sp_ff, s_ff, p_ff, sl_ff, sr_ff, slr_ff @ <>= pure function sp_ff (gs, gp, psibar, psi) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gs, gp type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi j = (gs - gp) * (psibar%a(1)*psi%a(1) + psibar%a(2)*psi%a(2)) & + (gs + gp) * (psibar%a(3)*psi%a(3) + psibar%a(4)*psi%a(4)) end function sp_ff @ <>= pure function s_ff (gs, psibar, psi) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gs type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi j = gs * (psibar * psi) end function s_ff @ <>= pure function p_ff (gp, psibar, psi) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gp type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi j = gp * ( psibar%a(3)*psi%a(3) + psibar%a(4)*psi%a(4) & - psibar%a(1)*psi%a(1) - psibar%a(2)*psi%a(2)) end function p_ff @ <>= pure function sl_ff (gl, psibar, psi) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gl type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi j = 2 * gl * (psibar%a(1)*psi%a(1) + psibar%a(2)*psi%a(2)) end function sl_ff @ <>= pure function sr_ff (gr, psibar, psi) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gr type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi j = 2 * gr * (psibar%a(3)*psi%a(3) + psibar%a(4)*psi%a(4)) end function sr_ff @ \begin{equation} g_L(1-\gamma_5) + g_R(1+\gamma_5) = (g_R+g_L) + (g_R-g_L)\gamma_5 = g_S + g_P\gamma_5 \end{equation} <>= pure function slr_ff (gl, gr, psibar, psi) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gl, gr type(conjspinor), intent(in) :: psibar type(spinor), intent(in) :: psi j = sp_ff (gr+gl, gr-gl, psibar, psi) end function slr_ff @ <>= public :: f_spf, f_sf, f_pf, f_slf, f_srf, f_slrf @ <>= pure function f_spf (gs, gp, phi, psi) result (phipsi) type(spinor) :: phipsi complex(kind=default), intent(in) :: gs, gp complex(kind=default), intent(in) :: phi type(spinor), intent(in) :: psi phipsi%a(1:2) = ((gs - gp) * phi) * psi%a(1:2) phipsi%a(3:4) = ((gs + gp) * phi) * psi%a(3:4) end function f_spf @ <>= pure function f_sf (gs, phi, psi) result (phipsi) type(spinor) :: phipsi complex(kind=default), intent(in) :: gs complex(kind=default), intent(in) :: phi type(spinor), intent(in) :: psi phipsi%a = (gs * phi) * psi%a end function f_sf @ <>= pure function f_pf (gp, phi, psi) result (phipsi) type(spinor) :: phipsi complex(kind=default), intent(in) :: gp complex(kind=default), intent(in) :: phi type(spinor), intent(in) :: psi phipsi%a(1:2) = (- gp * phi) * psi%a(1:2) phipsi%a(3:4) = ( gp * phi) * psi%a(3:4) end function f_pf @ <>= pure function f_slf (gl, phi, psi) result (phipsi) type(spinor) :: phipsi complex(kind=default), intent(in) :: gl complex(kind=default), intent(in) :: phi type(spinor), intent(in) :: psi phipsi%a(1:2) = (2 * gl * phi) * psi%a(1:2) phipsi%a(3:4) = 0 end function f_slf @ <>= pure function f_srf (gr, phi, psi) result (phipsi) type(spinor) :: phipsi complex(kind=default), intent(in) :: gr complex(kind=default), intent(in) :: phi type(spinor), intent(in) :: psi phipsi%a(1:2) = 0 phipsi%a(3:4) = (2 * gr * phi) * psi%a(3:4) end function f_srf @ <>= pure function f_slrf (gl, gr, phi, psi) result (phipsi) type(spinor) :: phipsi complex(kind=default), intent(in) :: gl, gr complex(kind=default), intent(in) :: phi type(spinor), intent(in) :: psi phipsi = f_spf (gr+gl, gr-gl, phi, psi) end function f_slrf @ <>= public :: f_fsp, f_fs, f_fp, f_fsl, f_fsr, f_fslr @ <>= pure function f_fsp (gs, gp, psibar, phi) result (psibarphi) type(conjspinor) :: psibarphi complex(kind=default), intent(in) :: gs, gp type(conjspinor), intent(in) :: psibar complex(kind=default), intent(in) :: phi psibarphi%a(1:2) = ((gs - gp) * phi) * psibar%a(1:2) psibarphi%a(3:4) = ((gs + gp) * phi) * psibar%a(3:4) end function f_fsp @ <>= pure function f_fs (gs, psibar, phi) result (psibarphi) type(conjspinor) :: psibarphi complex(kind=default), intent(in) :: gs type(conjspinor), intent(in) :: psibar complex(kind=default), intent(in) :: phi psibarphi%a = (gs * phi) * psibar%a end function f_fs @ <>= pure function f_fp (gp, psibar, phi) result (psibarphi) type(conjspinor) :: psibarphi complex(kind=default), intent(in) :: gp type(conjspinor), intent(in) :: psibar complex(kind=default), intent(in) :: phi psibarphi%a(1:2) = (- gp * phi) * psibar%a(1:2) psibarphi%a(3:4) = ( gp * phi) * psibar%a(3:4) end function f_fp @ <>= pure function f_fsl (gl, psibar, phi) result (psibarphi) type(conjspinor) :: psibarphi complex(kind=default), intent(in) :: gl type(conjspinor), intent(in) :: psibar complex(kind=default), intent(in) :: phi psibarphi%a(1:2) = (2 * gl * phi) * psibar%a(1:2) psibarphi%a(3:4) = 0 end function f_fsl @ <>= pure function f_fsr (gr, psibar, phi) result (psibarphi) type(conjspinor) :: psibarphi complex(kind=default), intent(in) :: gr type(conjspinor), intent(in) :: psibar complex(kind=default), intent(in) :: phi psibarphi%a(1:2) = 0 psibarphi%a(3:4) = (2 * gr * phi) * psibar%a(3:4) end function f_fsr @ <>= pure function f_fslr (gl, gr, psibar, phi) result (psibarphi) type(conjspinor) :: psibarphi complex(kind=default), intent(in) :: gl, gr type(conjspinor), intent(in) :: psibar complex(kind=default), intent(in) :: phi psibarphi = f_fsp (gr+gl, gr-gl, psibar, phi) end function f_fslr <>= public :: f_gravf, f_fgrav @ <>= pure function f_gravf (g, m, kb, k, t, psi) result (tpsi) type(spinor) :: tpsi complex(kind=default), intent(in) :: g real(kind=default), intent(in) :: m type(spinor), intent(in) :: psi type(tensor), intent(in) :: t type(momentum), intent(in) :: kb, k complex(kind=default) :: g2, g8, t_tr type(vector) :: kkb kkb = k + kb g2 = g / 2.0_default g8 = g / 8.0_default t_tr = t%t(0,0) - t%t(1,1) - t%t(2,2) - t%t(3,3) tpsi = (- f_sf (g2, cmplx (m,0.0, kind=default), psi) & - f_vf ((g8*m), kkb, psi)) * t_tr - & f_vf (g8,(t*kkb + kkb*t),psi) end function f_gravf @ <>= pure function f_fgrav (g, m, kb, k, psibar, t) result (psibart) type(conjspinor) :: psibart complex(kind=default), intent(in) :: g real(kind=default), intent(in) :: m type(conjspinor), intent(in) :: psibar type(tensor), intent(in) :: t type(momentum), intent(in) :: kb, k type(vector) :: kkb complex(kind=default) :: g2, g8, t_tr kkb = k + kb g2 = g / 2.0_default g8 = g / 8.0_default t_tr = t%t(0,0) - t%t(1,1) - t%t(2,2) - t%t(3,3) psibart = (- f_fs (g2, psibar, cmplx (m, 0.0, kind=default)) & - f_fv ((g8 * m), psibar, kkb)) * t_tr - & f_fv (g8,psibar,(t*kkb + kkb*t)) end function f_fgrav @ \subsection{On Shell Wave Functions} <>= public :: u, ubar, v, vbar private :: chi_plus, chi_minus @ \begin{subequations} \begin{align} \chi_+(\vec p) &= \frac{1}{\sqrt{2|\vec p|(|\vec p|+p_3)}} \begin{pmatrix} |\vec p|+p_3 \\ p_1 + \ii p_2 \end{pmatrix} \\ \chi_-(\vec p) &= \frac{1}{\sqrt{2|\vec p|(|\vec p|+p_3)}} \begin{pmatrix} - p_1 + \ii p_2 \\ |\vec p|+p_3 \end{pmatrix} \end{align} \end{subequations} <>= pure function chi_plus (p) result (chi) complex(kind=default), dimension(2) :: chi type(momentum), intent(in) :: p real(kind=default) :: pabs pabs = sqrt (dot_product (p%x, p%x)) if (pabs + p%x(3) <= 1000 * epsilon (pabs) * pabs) then chi = (/ cmplx ( 0.0, 0.0, kind=default), & cmplx ( 1.0, 0.0, kind=default) /) else chi = 1 / sqrt (2*pabs*(pabs + p%x(3))) & * (/ cmplx (pabs + p%x(3), kind=default), & cmplx (p%x(1), p%x(2), kind=default) /) end if end function chi_plus @ <>= pure function chi_minus (p) result (chi) complex(kind=default), dimension(2) :: chi type(momentum), intent(in) :: p real(kind=default) :: pabs pabs = sqrt (dot_product (p%x, p%x)) if (pabs + p%x(3) <= 1000 * epsilon (pabs) * pabs) then chi = (/ cmplx (-1.0, 0.0, kind=default), & cmplx ( 0.0, 0.0, kind=default) /) else chi = 1 / sqrt (2*pabs*(pabs + p%x(3))) & * (/ cmplx (-p%x(1), p%x(2), kind=default), & cmplx (pabs + p%x(3), kind=default) /) end if end function chi_minus @ \begin{equation} u_\pm(p,|m|) = \begin{pmatrix} \sqrt{p_0\mp|\vec p|} \cdot \chi_\pm(\vec p) \\ \sqrt{p_0\pm|\vec p|} \cdot \chi_\pm(\vec p) \end{pmatrix}\qquad u_\pm(p,-|m|) = \begin{pmatrix} - i \sqrt{p_0\mp|\vec p|} \cdot \chi_\pm(\vec p) \\ + i \sqrt{p_0\pm|\vec p|} \cdot \chi_\pm(\vec p) \end{pmatrix} \end{equation} Determining the mass from the momenta is a numerically haphazardous for light particles. Therefore, we accept some redundancy and pass the mass explicitely. Even if the mass is not used in the chiral representation, we do so for symmetry with polarization vectors and to be prepared for other representations. <>= pure function u (mass, p, s) result (psi) type(spinor) :: psi real(kind=default), intent(in) :: mass type(momentum), intent(in) :: p integer, intent(in) :: s complex(kind=default), dimension(2) :: chi real(kind=default) :: pabs, delta, m m = abs(mass) pabs = sqrt (dot_product (p%x, p%x)) if (m < epsilon (m) * pabs) then delta = 0 else delta = sqrt (max (p%t - pabs, 0._default)) end if select case (s) case (1) chi = chi_plus (p) psi%a(1:2) = delta * chi psi%a(3:4) = sqrt (p%t + pabs) * chi case (-1) chi = chi_minus (p) psi%a(1:2) = sqrt (p%t + pabs) * chi psi%a(3:4) = delta * chi case default pabs = m ! make the compiler happy and use m psi%a = 0 end select if (mass < 0) then psi%a(1:2) = - imago * psi%a(1:2) psi%a(3:4) = + imago * psi%a(3:4) end if end function u @ <>= pure function ubar (m, p, s) result (psibar) type(conjspinor) :: psibar real(kind=default), intent(in) :: m type(momentum), intent(in) :: p integer, intent(in) :: s type(spinor) :: psi psi = u (m, p, s) psibar%a(1:2) = conjg (psi%a(3:4)) psibar%a(3:4) = conjg (psi%a(1:2)) end function ubar @ \begin{equation} v_\pm(p) = \begin{pmatrix} \mp\sqrt{p_0\pm|\vec p|} \cdot \chi_\mp(\vec p) \\ \pm\sqrt{p_0\mp|\vec p|} \cdot \chi_\mp(\vec p) \end{pmatrix} \end{equation} <>= pure function v (mass, p, s) result (psi) type(spinor) :: psi real(kind=default), intent(in) :: mass type(momentum), intent(in) :: p integer, intent(in) :: s complex(kind=default), dimension(2) :: chi real(kind=default) :: pabs, delta, m m = abs(mass) pabs = sqrt (dot_product (p%x, p%x)) if (m < epsilon (m) * pabs) then delta = 0 else delta = sqrt (max (p%t - pabs, 0._default)) end if select case (s) case (1) chi = chi_minus (p) psi%a(1:2) = - sqrt (p%t + pabs) * chi psi%a(3:4) = delta * chi case (-1) chi = chi_plus (p) psi%a(1:2) = delta * chi psi%a(3:4) = - sqrt (p%t + pabs) * chi case default pabs = m ! make the compiler happy and use m psi%a = 0 end select if (mass < 0) then psi%a(1:2) = - imago * psi%a(1:2) psi%a(3:4) = + imago * psi%a(3:4) end if end function v @ <>= pure function vbar (m, p, s) result (psibar) type(conjspinor) :: psibar real(kind=default), intent(in) :: m type(momentum), intent(in) :: p integer, intent(in) :: s type(spinor) :: psi psi = v (m, p, s) psibar%a(1:2) = conjg (psi%a(3:4)) psibar%a(3:4) = conjg (psi%a(1:2)) end function vbar @ \subsection{Off Shell Wave Functions} I've just taken this over from Christian Schwinn's version. <>= public :: brs_u, brs_ubar, brs_v, brs_vbar @ The off-shell wave functions needed for gauge checking are obtained from the LSZ-formulas: \begin{subequations} \begin{align} \Braket{\text{Out}|d^\dagger|\text{In}}&=i\int d^4x \bar v e^{-ikx}(i\fmslash\partial-m)\Braket{\text{Out}|\psi|\text{In}}\\ \Braket{\text{Out}|b|\text{In}}&=-i\int d^4x \bar u e^{ikx}(i\fmslash\partial-m)\Braket{\text{Out}|\psi|\text{In}}\\ \Braket{\text{Out}|d|\text{In}}&= i\int d^4x \Braket{\text{Out}|\bar \psi| \text{In}}(-i\fmslash{\overleftarrow\partial}-m)v e^{ikx}\\ \Braket{\text{Out}|b^\dagger|\text{In}}&= -i\int d^4x \Braket{\text{Out}|\bar \psi| \text{In}}(-i\fmslash{\overleftarrow\partial}-m)u e^{-ikx} \end{align} \end{subequations} Since the relative sign between fermions and antifermions is ignored for on-shell amplitudes we must also ignore it here, so all wavefunctions must have a $(-i)$ factor. In momentum space we have: \begin{equation} brs u(p)=(-i) (\fmslash p-m)u(p) \end{equation} <>= pure function brs_u (m, p, s) result (dpsi) type(spinor) :: dpsi,psi real(kind=default), intent(in) :: m type(momentum), intent(in) :: p integer, intent(in) :: s type (vector)::vp complex(kind=default), parameter :: one = (1, 0) vp=p psi=u(m,p,s) dpsi=cmplx(0.0,-1.0)*(f_vf(one,vp,psi)-m*psi) end function brs_u @ \begin{equation} brs v(p)=i (\fmslash p+m)v(p) \end{equation} <>= pure function brs_v (m, p, s) result (dpsi) type(spinor) :: dpsi, psi real(kind=default), intent(in) :: m type(momentum), intent(in) :: p integer, intent(in) :: s type (vector)::vp complex(kind=default), parameter :: one = (1, 0) vp=p psi=v(m,p,s) dpsi=cmplx(0.0,1.0)*(f_vf(one,vp,psi)+m*psi) end function brs_v @ \begin{equation} brs \bar{u}(p)=(-i)\bar u(p)(\fmslash p-m) \end{equation} <>= pure function brs_ubar (m, p, s)result (dpsibar) type(conjspinor) :: dpsibar, psibar real(kind=default), intent(in) :: m type(momentum), intent(in) :: p integer, intent(in) :: s type (vector)::vp complex(kind=default), parameter :: one = (1, 0) vp=p psibar=ubar(m,p,s) dpsibar=cmplx(0.0,-1.0)*(f_fv(one,psibar,vp)-m*psibar) end function brs_ubar @ \begin{equation} brs \bar{v}(p)=(i)\bar v(p)(\fmslash p+m) \end{equation} <>= pure function brs_vbar (m, p, s) result (dpsibar) type(conjspinor) :: dpsibar,psibar real(kind=default), intent(in) :: m type(momentum), intent(in) :: p integer, intent(in) :: s type(vector)::vp complex(kind=default), parameter :: one = (1, 0) vp=p psibar=vbar(m,p,s) dpsibar=cmplx(0.0,1.0)*(f_fv(one,psibar,vp)+m*psibar) end function brs_vbar @ NB: The remarks on momentum flow in the propagators don't apply here since the incoming momenta are flipped for the wave functions. @ \subsection{Propagators} NB: the common factor of~$\ii$ is extracted: <>= public :: pr_psi, pr_psibar public :: pj_psi, pj_psibar public :: pg_psi, pg_psibar @ \begin{equation} \frac{i(-\fmslash{p}+m)}{p^2-m^2+\ii m\Gamma}\psi \end{equation} NB: the sign of the momentum comes about because all momenta are treated as \emph{outgoing} and the particle charge flow is therefore opposite to the momentum. <>= pure function pr_psi (p, m, w, cms, psi) result (ppsi) type(spinor) :: ppsi type(momentum), intent(in) :: p real(kind=default), intent(in) :: m, w type(spinor), intent(in) :: psi logical, intent(in) :: cms type(vector) :: vp complex(kind=default), parameter :: one = (1, 0) complex(kind=default) :: num_mass vp = p if (cms) then num_mass = sqrt(cmplx(m**2, -m*w, kind=default)) else num_mass = cmplx (m, 0, kind=default) end if ppsi = (1 / cmplx (p*p - m**2, m*w, kind=default)) & * (- f_vf (one, vp, psi) + num_mass * psi) end function pr_psi @ \begin{equation} \sqrt{\frac{\pi}{M\Gamma}} (-\fmslash{p}+m)\psi \end{equation} <>= pure function pj_psi (p, m, w, psi) result (ppsi) type(spinor) :: ppsi type(momentum), intent(in) :: p real(kind=default), intent(in) :: m, w type(spinor), intent(in) :: psi type(vector) :: vp complex(kind=default), parameter :: one = (1, 0) vp = p ppsi = (0, -1) * sqrt (PI / m / w) * (- f_vf (one, vp, psi) + m * psi) end function pj_psi @ <>= pure function pg_psi (p, m, w, psi) result (ppsi) type(spinor) :: ppsi type(momentum), intent(in) :: p real(kind=default), intent(in) :: m, w type(spinor), intent(in) :: psi type(vector) :: vp complex(kind=default), parameter :: one = (1, 0) vp = p ppsi = gauss(p*p, m, w) * (- f_vf (one, vp, psi) + m * psi) end function pg_psi @ \begin{equation} \bar\psi \frac{i(\fmslash{p}+m)}{p^2-m^2+\ii m\Gamma} \end{equation} NB: the sign of the momentum comes about because all momenta are treated as \emph{outgoing} and the antiparticle charge flow is therefore parallel to the momentum. <>= pure function pr_psibar (p, m, w, cms, psibar) result (ppsibar) type(conjspinor) :: ppsibar type(momentum), intent(in) :: p real(kind=default), intent(in) :: m, w type(conjspinor), intent(in) :: psibar logical, intent(in) :: cms type(vector) :: vp complex(kind=default), parameter :: one = (1, 0) complex(kind=default) :: num_mass vp = p if (cms) then num_mass = sqrt(cmplx(m**2, -m*w, kind=default)) else num_mass = cmplx (m, 0, kind=default) end if ppsibar = (1 / cmplx (p*p - m**2, m*w, kind=default)) & * (f_fv (one, psibar, vp) + num_mass * psibar) end function pr_psibar @ \begin{equation} \sqrt{\frac{\pi}{M\Gamma}} \bar\psi (\fmslash{p}+m) \end{equation} NB: the sign of the momentum comes about because all momenta are treated as \emph{outgoing} and the antiparticle charge flow is therefore parallel to the momentum. <>= pure function pj_psibar (p, m, w, psibar) result (ppsibar) type(conjspinor) :: ppsibar type(momentum), intent(in) :: p real(kind=default), intent(in) :: m, w type(conjspinor), intent(in) :: psibar type(vector) :: vp complex(kind=default), parameter :: one = (1, 0) vp = p ppsibar = (0, -1) * sqrt (PI / m / w) * (f_fv (one, psibar, vp) + m * psibar) end function pj_psibar @ <>= pure function pg_psibar (p, m, w, psibar) result (ppsibar) type(conjspinor) :: ppsibar type(momentum), intent(in) :: p real(kind=default), intent(in) :: m, w type(conjspinor), intent(in) :: psibar type(vector) :: vp complex(kind=default), parameter :: one = (1, 0) vp = p ppsibar = gauss (p*p, m, w) * (f_fv (one, psibar, vp) + m * psibar) end function pg_psibar @ \begin{equation} \frac{i(-\fmslash{p}+m)}{p^2-m^2+\ii m\Gamma} \sum_n \psi_n\otimes\bar\psi_n \end{equation} NB: the temporary variables [[psi(1:4)]] are not nice, but the compilers should be able to optimize the unnecessary copies away. In any case, even if the copies are performed, they are (probably) negligible compared to the floating point multiplications anyway \ldots <<(Not used yet) Declaration of operations for spinors>>= type, public :: spinordyad ! private (omegalib needs access, but DON'T TOUCH IT!) complex(kind=default), dimension(4,4) :: a end type spinordyad @ <<(Not used yet) Implementation of spinor propagators>>= pure function pr_dyadleft (p, m, w, psipsibar) result (psipsibarp) type(spinordyad) :: psipsibarp type(momentum), intent(in) :: p real(kind=default), intent(in) :: m, w type(spinordyad), intent(in) :: psipsibar integer :: i type(vector) :: vp type(spinor), dimension(4) :: psi complex(kind=default) :: pole complex(kind=default), parameter :: one = (1, 0) vp = p pole = 1 / cmplx (p*p - m**2, m*w, kind=default) do i = 1, 4 psi(i)%a = psipsibar%a(:,i) psi(i) = pole * (- f_vf (one, vp, psi(i)) + m * psi(i)) psipsibarp%a(:,i) = psi(i)%a end do end function pr_dyadleft @ \begin{equation} \sum_n \psi_n\otimes\bar\psi_n \frac{i(\fmslash{p}+m)}{p^2-m^2+\ii m\Gamma} \end{equation} <<(Not used yet) Implementation of spinor propagators>>= pure function pr_dyadright (p, m, w, psipsibar) result (psipsibarp) type(spinordyad) :: psipsibarp type(momentum), intent(in) :: p real(kind=default), intent(in) :: m, w type(spinordyad), intent(in) :: psipsibar integer :: i type(vector) :: vp type(conjspinor), dimension(4) :: psibar complex(kind=default) :: pole complex(kind=default), parameter :: one = (1, 0) vp = p pole = 1 / cmplx (p*p - m**2, m*w, kind=default) do i = 1, 4 psibar(i)%a = psipsibar%a(i,:) psibar(i) = pole * (f_fv (one, psibar(i), vp) + m * psibar(i)) psipsibarp%a(i,:) = psibar(i)%a end do end function pr_dyadright @ \section{Spinor Couplings Revisited} <<[[omega_bispinor_couplings.f90]]>>= <> module omega_bispinor_couplings use kinds use constants use omega_bispinors use omega_vectorspinors use omega_vectors use omega_couplings implicit none private <> <> <> <> integer, parameter, public :: omega_bispinor_cpls_2010_01_A = 0 contains <> <> <> <> end module omega_bispinor_couplings @ See table~\ref{tab:fermionic-currents} for the names of Fortran functions. We could have used long names instead, but this would increase the chance of running past continuation line limits without adding much to the legibility. @ \subsection{Fermionic Vector and Axial Couplings} There's more than one chiral representation. This one is compatible with HELAS~\cite{HELAS}. \begin{subequations} \begin{align} & \gamma^0 = \begin{pmatrix} 0 & \mathbf{1} \\ \mathbf{1} & 0 \end{pmatrix},\; \gamma^i = \begin{pmatrix} 0 & \sigma^i \\ -\sigma^i & 0 \end{pmatrix},\; \gamma_5 = i\gamma^0\gamma^1\gamma^2\gamma^3 = \begin{pmatrix} -\mathbf{1} & 0 \\ 0 & \mathbf{1} \end{pmatrix}, \\ & C = \begin{pmatrix} \epsilon & 0 \\ 0 & - \epsilon \end{pmatrix} \; , \qquad \epsilon = \begin{pmatrix} 0 & 1 \\ -1 & 0 \end{pmatrix} . \end{align} \end{subequations} Therefore \begin{subequations} \begin{align} g_S + g_P\gamma_5 &= \begin{pmatrix} g_S - g_P & 0 & 0 & 0 \\ 0 & g_S - g_P & 0 & 0 \\ 0 & 0 & g_S + g_P & 0 \\ 0 & 0 & 0 & g_S + g_P \end{pmatrix} \\ g_V\gamma^0 - g_A\gamma^0\gamma_5 &= \begin{pmatrix} 0 & 0 & g_V - g_A & 0 \\ 0 & 0 & 0 & g_V - g_A \\ g_V + g_A & 0 & 0 & 0 \\ 0 & g_V + g_A & 0 & 0 \end{pmatrix} \\ g_V\gamma^1 - g_A\gamma^1\gamma_5 &= \begin{pmatrix} 0 & 0 & 0 & g_V - g_A \\ 0 & 0 & g_V - g_A & 0 \\ 0 & - g_V - g_A & 0 & 0 \\ - g_V - g_A & 0 & 0 & 0 \end{pmatrix} \\ g_V\gamma^2 - g_A\gamma^2\gamma_5 &= \begin{pmatrix} 0 & 0 & 0 & -\ii(g_V - g_A) \\ 0 & 0 & \ii(g_V - g_A) & 0 \\ 0 & \ii(g_V + g_A) & 0 & 0 \\ -\ii(g_V + g_A) & 0 & 0 & 0 \end{pmatrix} \\ g_V\gamma^3 - g_A\gamma^3\gamma_5 &= \begin{pmatrix} 0 & 0 & g_V - g_A & 0 \\ 0 & 0 & 0 & - g_V + g_A \\ - g_V - g_A & 0 & 0 & 0 \\ 0 & g_V + g_A & 0 & 0 \end{pmatrix} \end{align} \end{subequations} and \begin{subequations} \begin{align} C(g_S + g_P\gamma_5) &= \begin{pmatrix} 0 & g_S - g_P & 0 & 0 \\ - g_S + g_P & 0 & 0 & 0 \\ 0 & 0 & 0 & - g_S - g_P \\ 0 & 0 & g_S + g_P & 0 \end{pmatrix} \\ C(g_V\gamma^0 - g_A\gamma^0\gamma_5) &= \begin{pmatrix} 0 & 0 & 0 & g_V - g_A \\ 0 & 0 & - g_V + g_A & 0 \\ 0 & - g_V - g_A & 0 & 0 \\ g_V + g_A & 0 & 0 & 0 \end{pmatrix} \\ C(g_V\gamma^1 - g_A\gamma^1\gamma_5) &= \begin{pmatrix} 0 & 0 & g_V - g_A & 0 \\ 0 & 0 & 0 & - g_V + g_A \\ g_V + g_A & 0 & 0 & 0 \\ 0 & - g_V - g_A & 0 & 0 \end{pmatrix} \\ C(g_V\gamma^2 - g_A\gamma^2\gamma_5) &= \begin{pmatrix} 0 & 0 & \ii(g_V - g_A) & 0 \\ 0 & 0 & 0 & \ii(g_V - g_A) \\ \ii(g_V + g_A) & 0 & 0 & 0 \\ 0 & \ii(g_V + g_A) & 0 & 0 \end{pmatrix} \\ C(g_V\gamma^3 - g_A\gamma^3\gamma_5) &= \begin{pmatrix} 0 & 0 & 0 & - g_V + g_A \\ 0 & 0 & - g_V + g_A & 0 \\ 0 & - g_V - g_A & 0 & 0 \\ - g_V - g_A & 0 & 0 & 0 \end{pmatrix} \end{align} \end{subequations} <>= public :: va_ff, v_ff, a_ff, vl_ff, vr_ff, vlr_ff, va2_ff, tva_ff, tvam_ff, & tlr_ff, tlrm_ff @ <>= pure function va_ff (gv, ga, psil, psir) result (j) type(vector) :: j complex(kind=default), intent(in) :: gv, ga type(bispinor), intent(in) :: psil, psir complex(kind=default) :: gl, gr complex(kind=default) :: g13, g14, g23, g24, g31, g32, g41, g42 gl = gv + ga gr = gv - ga g13 = psil%a(1)*psir%a(3) g14 = psil%a(1)*psir%a(4) g23 = psil%a(2)*psir%a(3) g24 = psil%a(2)*psir%a(4) g31 = psil%a(3)*psir%a(1) g32 = psil%a(3)*psir%a(2) g41 = psil%a(4)*psir%a(1) g42 = psil%a(4)*psir%a(2) j%t = gr * ( g14 - g23) + gl * ( - g32 + g41) j%x(1) = gr * ( g13 - g24) + gl * ( g31 - g42) j%x(2) = (gr * ( g13 + g24) + gl * ( g31 + g42)) * (0, 1) j%x(3) = gr * ( - g14 - g23) + gl * ( - g32 - g41) end function va_ff @ <>= pure function va2_ff (gva, psil, psir) result (j) type(vector) :: j complex(kind=default), intent(in), dimension(2) :: gva type(bispinor), intent(in) :: psil, psir complex(kind=default) :: gl, gr complex(kind=default) :: g13, g14, g23, g24, g31, g32, g41, g42 gl = gva(1) + gva(2) gr = gva(1) - gva(2) g13 = psil%a(1)*psir%a(3) g14 = psil%a(1)*psir%a(4) g23 = psil%a(2)*psir%a(3) g24 = psil%a(2)*psir%a(4) g31 = psil%a(3)*psir%a(1) g32 = psil%a(3)*psir%a(2) g41 = psil%a(4)*psir%a(1) g42 = psil%a(4)*psir%a(2) j%t = gr * ( g14 - g23) + gl * ( - g32 + g41) j%x(1) = gr * ( g13 - g24) + gl * ( g31 - g42) j%x(2) = (gr * ( g13 + g24) + gl * ( g31 + g42)) * (0, 1) j%x(3) = gr * ( - g14 - g23) + gl * ( - g32 - g41) end function va2_ff @ <>= pure function v_ff (gv, psil, psir) result (j) type(vector) :: j complex(kind=default), intent(in) :: gv type(bispinor), intent(in) :: psil, psir complex(kind=default) :: g13, g14, g23, g24, g31, g32, g41, g42 g13 = psil%a(1)*psir%a(3) g14 = psil%a(1)*psir%a(4) g23 = psil%a(2)*psir%a(3) g24 = psil%a(2)*psir%a(4) g31 = psil%a(3)*psir%a(1) g32 = psil%a(3)*psir%a(2) g41 = psil%a(4)*psir%a(1) g42 = psil%a(4)*psir%a(2) j%t = gv * ( g14 - g23 - g32 + g41) j%x(1) = gv * ( g13 - g24 + g31 - g42) j%x(2) = gv * ( g13 + g24 + g31 + g42) * (0, 1) j%x(3) = gv * ( - g14 - g23 - g32 - g41) end function v_ff @ <>= pure function a_ff (ga, psil, psir) result (j) type(vector) :: j complex(kind=default), intent(in) :: ga type(bispinor), intent(in) :: psil, psir complex(kind=default) :: g13, g14, g23, g24, g31, g32, g41, g42 g13 = psil%a(1)*psir%a(3) g14 = psil%a(1)*psir%a(4) g23 = psil%a(2)*psir%a(3) g24 = psil%a(2)*psir%a(4) g31 = psil%a(3)*psir%a(1) g32 = psil%a(3)*psir%a(2) g41 = psil%a(4)*psir%a(1) g42 = psil%a(4)*psir%a(2) j%t = -ga * ( g14 - g23 + g32 - g41) j%x(1) = -ga * ( g13 - g24 - g31 + g42) j%x(2) = -ga * ( g13 + g24 - g31 - g42) * (0, 1) j%x(3) = -ga * ( - g14 - g23 + g32 + g41) end function a_ff @ <>= pure function vl_ff (gl, psil, psir) result (j) type(vector) :: j complex(kind=default), intent(in) :: gl type(bispinor), intent(in) :: psil, psir complex(kind=default) :: gl2 complex(kind=default) :: g31, g32, g41, g42 gl2 = 2 * gl g31 = psil%a(3)*psir%a(1) g32 = psil%a(3)*psir%a(2) g41 = psil%a(4)*psir%a(1) g42 = psil%a(4)*psir%a(2) j%t = gl2 * ( - g32 + g41) j%x(1) = gl2 * ( g31 - g42) j%x(2) = gl2 * ( g31 + g42) * (0, 1) j%x(3) = gl2 * ( - g32 - g41) end function vl_ff @ <>= pure function vr_ff (gr, psil, psir) result (j) type(vector) :: j complex(kind=default), intent(in) :: gr type(bispinor), intent(in) :: psil, psir complex(kind=default) :: gr2 complex(kind=default) :: g13, g14, g23, g24 gr2 = 2 * gr g13 = psil%a(1)*psir%a(3) g14 = psil%a(1)*psir%a(4) g23 = psil%a(2)*psir%a(3) g24 = psil%a(2)*psir%a(4) j%t = gr2 * ( g14 - g23) j%x(1) = gr2 * ( g13 - g24) j%x(2) = gr2 * ( g13 + g24) * (0, 1) j%x(3) = gr2 * ( - g14 - g23) end function vr_ff @ <>= pure function vlr_ff (gl, gr, psibar, psi) result (j) type(vector) :: j complex(kind=default), intent(in) :: gl, gr type(bispinor), intent(in) :: psibar type(bispinor), intent(in) :: psi j = va_ff (gl+gr, gl-gr, psibar, psi) end function vlr_ff @ <>= pure function tva_ff (gv, ga, psibar, psi) result (t) type(tensor2odd) :: t complex(kind=default), intent(in) :: gv, ga type(bispinor), intent(in) :: psibar type(bispinor), intent(in) :: psi complex(kind=default) :: gl, gr complex(kind=default) :: g11, g22, g33, g44, g1p2, g3p4 gr = gv + ga gl = gv - ga g11 = psibar%a(1)*psi%a(1) g22 = psibar%a(2)*psi%a(2) g1p2 = psibar%a(1)*psi%a(2) + psibar%a(2)*psi%a(1) g3p4 = psibar%a(3)*psi%a(4) + psibar%a(4)*psi%a(3) g33 = psibar%a(3)*psi%a(3) g44 = psibar%a(4)*psi%a(4) t%e(1) = (gl * ( - g11 + g22) + gr * ( - g33 + g44)) * (0, 1) t%e(2) = gl * ( g11 + g22) + gr * ( g33 + g44) t%e(3) = (gl * ( g1p2 ) + gr * ( g3p4 )) * (0, 1) t%b(1) = gl * ( g11 - g22) + gr * ( - g33 + g44) t%b(2) = (gl * ( g11 + g22) + gr * ( - g33 - g44)) * (0, 1) t%b(3) = gl * ( - g1p2 ) + gr * ( g3p4 ) end function tva_ff @ <>= pure function tlr_ff (gl, gr, psibar, psi) result (t) type(tensor2odd) :: t complex(kind=default), intent(in) :: gl, gr type(bispinor), intent(in) :: psibar type(bispinor), intent(in) :: psi t = tva_ff (gr+gl, gr-gl, psibar, psi) end function tlr_ff @ <>= pure function tvam_ff (gv, ga, psibar, psi, p) result (j) type(vector) :: j complex(kind=default), intent(in) :: gv, ga type(bispinor), intent(in) :: psibar type(bispinor), intent(in) :: psi type(momentum), intent(in) :: p j = (tva_ff(gv, ga, psibar, psi) * p) * (0,1) end function tvam_ff @ <>= pure function tlrm_ff (gl, gr, psibar, psi, p) result (j) type(vector) :: j complex(kind=default), intent(in) :: gl, gr type(bispinor), intent(in) :: psibar type(bispinor), intent(in) :: psi type(momentum), intent(in) :: p j = tvam_ff (gr+gl, gr-gl, psibar, psi, p) end function tlrm_ff @ and \begin{equation} \fmslash{v} - \fmslash{a}\gamma_5 = \begin{pmatrix} 0 & 0 & v_- - a_- & - v^* + a^* \\ 0 & 0 & - v + a & v_+ - a_+ \\ v_+ + a_+ & v^* + a^* & 0 & 0 \\ v + a & v_- + a_- & 0 & 0 \end{pmatrix} \end{equation} with $v_\pm=v_0\pm v_3$, $a_\pm=a_0\pm a_3$, $v=v_1+\ii v_2$, $v^*=v_1-\ii v_2$, $a=a_1+\ii a_2$, and $a^*=a_1-\ii a_2$. But note that~$\cdot^*$ is \emph{not} complex conjugation for complex~$v_\mu$ or~$a_\mu$. <>= public :: f_vaf, f_vf, f_af, f_vlf, f_vrf, f_vlrf, f_va2f, & f_tvaf, f_tlrf, f_tvamf, f_tlrmf @ <>= pure function f_vaf (gv, ga, v, psi) result (vpsi) type(bispinor) :: vpsi complex(kind=default), intent(in) :: gv, ga type(vector), intent(in) :: v type(bispinor), intent(in) :: psi complex(kind=default) :: gl, gr complex(kind=default) :: vp, vm, v12, v12s gl = gv + ga gr = gv - ga vp = v%t + v%x(3) vm = v%t - v%x(3) v12 = v%x(1) + (0,1)*v%x(2) v12s = v%x(1) - (0,1)*v%x(2) vpsi%a(1) = gr * ( vm * psi%a(3) - v12s * psi%a(4)) vpsi%a(2) = gr * ( - v12 * psi%a(3) + vp * psi%a(4)) vpsi%a(3) = gl * ( vp * psi%a(1) + v12s * psi%a(2)) vpsi%a(4) = gl * ( v12 * psi%a(1) + vm * psi%a(2)) end function f_vaf @ <>= pure function f_va2f (gva, v, psi) result (vpsi) type(bispinor) :: vpsi complex(kind=default), intent(in), dimension(2) :: gva type(vector), intent(in) :: v type(bispinor), intent(in) :: psi complex(kind=default) :: gl, gr complex(kind=default) :: vp, vm, v12, v12s gl = gva(1) + gva(2) gr = gva(1) - gva(2) vp = v%t + v%x(3) vm = v%t - v%x(3) v12 = v%x(1) + (0,1)*v%x(2) v12s = v%x(1) - (0,1)*v%x(2) vpsi%a(1) = gr * ( vm * psi%a(3) - v12s * psi%a(4)) vpsi%a(2) = gr * ( - v12 * psi%a(3) + vp * psi%a(4)) vpsi%a(3) = gl * ( vp * psi%a(1) + v12s * psi%a(2)) vpsi%a(4) = gl * ( v12 * psi%a(1) + vm * psi%a(2)) end function f_va2f @ <>= pure function f_vf (gv, v, psi) result (vpsi) type(bispinor) :: vpsi complex(kind=default), intent(in) :: gv type(vector), intent(in) :: v type(bispinor), intent(in) :: psi complex(kind=default) :: vp, vm, v12, v12s vp = v%t + v%x(3) vm = v%t - v%x(3) v12 = v%x(1) + (0,1)*v%x(2) v12s = v%x(1) - (0,1)*v%x(2) vpsi%a(1) = gv * ( vm * psi%a(3) - v12s * psi%a(4)) vpsi%a(2) = gv * ( - v12 * psi%a(3) + vp * psi%a(4)) vpsi%a(3) = gv * ( vp * psi%a(1) + v12s * psi%a(2)) vpsi%a(4) = gv * ( v12 * psi%a(1) + vm * psi%a(2)) end function f_vf @ <>= pure function f_af (ga, v, psi) result (vpsi) type(bispinor) :: vpsi complex(kind=default), intent(in) :: ga type(vector), intent(in) :: v type(bispinor), intent(in) :: psi complex(kind=default) :: vp, vm, v12, v12s vp = v%t + v%x(3) vm = v%t - v%x(3) v12 = v%x(1) + (0,1)*v%x(2) v12s = v%x(1) - (0,1)*v%x(2) vpsi%a(1) = ga * ( - vm * psi%a(3) + v12s * psi%a(4)) vpsi%a(2) = ga * ( v12 * psi%a(3) - vp * psi%a(4)) vpsi%a(3) = ga * ( vp * psi%a(1) + v12s * psi%a(2)) vpsi%a(4) = ga * ( v12 * psi%a(1) + vm * psi%a(2)) end function f_af @ <>= pure function f_vlf (gl, v, psi) result (vpsi) type(bispinor) :: vpsi complex(kind=default), intent(in) :: gl type(vector), intent(in) :: v type(bispinor), intent(in) :: psi complex(kind=default) :: gl2 complex(kind=default) :: vp, vm, v12, v12s gl2 = 2 * gl vp = v%t + v%x(3) vm = v%t - v%x(3) v12 = v%x(1) + (0,1)*v%x(2) v12s = v%x(1) - (0,1)*v%x(2) vpsi%a(1) = 0 vpsi%a(2) = 0 vpsi%a(3) = gl2 * ( vp * psi%a(1) + v12s * psi%a(2)) vpsi%a(4) = gl2 * ( v12 * psi%a(1) + vm * psi%a(2)) end function f_vlf @ <>= pure function f_vrf (gr, v, psi) result (vpsi) type(bispinor) :: vpsi complex(kind=default), intent(in) :: gr type(vector), intent(in) :: v type(bispinor), intent(in) :: psi complex(kind=default) :: gr2 complex(kind=default) :: vp, vm, v12, v12s gr2 = 2 * gr vp = v%t + v%x(3) vm = v%t - v%x(3) v12 = v%x(1) + (0,1)*v%x(2) v12s = v%x(1) - (0,1)*v%x(2) vpsi%a(1) = gr2 * ( vm * psi%a(3) - v12s * psi%a(4)) vpsi%a(2) = gr2 * ( - v12 * psi%a(3) + vp * psi%a(4)) vpsi%a(3) = 0 vpsi%a(4) = 0 end function f_vrf @ <>= pure function f_vlrf (gl, gr, v, psi) result (vpsi) type(bispinor) :: vpsi complex(kind=default), intent(in) :: gl, gr type(vector), intent(in) :: v type(bispinor), intent(in) :: psi vpsi = f_vaf (gl+gr, gl-gr, v, psi) end function f_vlrf @ <>= pure function f_tvaf (gv, ga, t, psi) result (tpsi) type(bispinor) :: tpsi complex(kind=default), intent(in) :: gv, ga type(tensor2odd), intent(in) :: t type(bispinor), intent(in) :: psi complex(kind=default) :: gl, gr complex(kind=default) :: e21, e21s, b12, b12s, be3, be3s gr = gv + ga gl = gv - ga e21 = t%e(2) + t%e(1)*(0,1) e21s = t%e(2) - t%e(1)*(0,1) b12 = t%b(1) + t%b(2)*(0,1) b12s = t%b(1) - t%b(2)*(0,1) be3 = t%b(3) + t%e(3)*(0,1) be3s = t%b(3) - t%e(3)*(0,1) tpsi%a(1) = 2*gl * ( psi%a(1) * be3 + psi%a(2) * ( e21 +b12s)) tpsi%a(2) = 2*gl * ( - psi%a(2) * be3 + psi%a(1) * (-e21s+b12 )) tpsi%a(3) = 2*gr * ( psi%a(3) * be3s + psi%a(4) * (-e21 +b12s)) tpsi%a(4) = 2*gr * ( - psi%a(4) * be3s + psi%a(3) * ( e21s+b12 )) end function f_tvaf @ <>= pure function f_tlrf (gl, gr, t, psi) result (tpsi) type(bispinor) :: tpsi complex(kind=default), intent(in) :: gl, gr type(tensor2odd), intent(in) :: t type(bispinor), intent(in) :: psi tpsi = f_tvaf (gr+gl, gr-gl, t, psi) end function f_tlrf @ <>= pure function f_tvamf (gv, ga, v, psi, k) result (vpsi) type(bispinor) :: vpsi complex(kind=default), intent(in) :: gv, ga type(vector), intent(in) :: v type(bispinor), intent(in) :: psi type(momentum), intent(in) :: k type(tensor2odd) :: t t = (v.wedge.k) * (0, 0.5) vpsi = f_tvaf(gv, ga, t, psi) end function f_tvamf @ <>= pure function f_tlrmf (gl, gr, v, psi, k) result (vpsi) type(bispinor) :: vpsi complex(kind=default), intent(in) :: gl, gr type(vector), intent(in) :: v type(bispinor), intent(in) :: psi type(momentum), intent(in) :: k vpsi = f_tvamf (gr+gl, gr-gl, v, psi, k) end function f_tlrmf @ \subsection{Fermionic Scalar and Pseudo Scalar Couplings} <>= public :: sp_ff, s_ff, p_ff, sl_ff, sr_ff, slr_ff @ <>= pure function sp_ff (gs, gp, psil, psir) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gs, gp type(bispinor), intent(in) :: psil, psir j = (gs - gp) * (psil%a(1)*psir%a(2) - psil%a(2)*psir%a(1)) & + (gs + gp) * (- psil%a(3)*psir%a(4) + psil%a(4)*psir%a(3)) end function sp_ff @ <>= pure function s_ff (gs, psil, psir) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gs type(bispinor), intent(in) :: psil, psir j = gs * (psil * psir) end function s_ff @ <>= pure function p_ff (gp, psil, psir) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gp type(bispinor), intent(in) :: psil, psir j = gp * (- psil%a(1)*psir%a(2) + psil%a(2)*psir%a(1) & - psil%a(3)*psir%a(4) + psil%a(4)*psir%a(3)) end function p_ff @ <>= pure function sl_ff (gl, psil, psir) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gl type(bispinor), intent(in) :: psil, psir j = 2 * gl * (psil%a(1)*psir%a(2) - psil%a(2)*psir%a(1)) end function sl_ff @ <>= pure function sr_ff (gr, psil, psir) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gr type(bispinor), intent(in) :: psil, psir j = 2 * gr * (- psil%a(3)*psir%a(4) + psil%a(4)*psir%a(3)) end function sr_ff @ <>= pure function slr_ff (gl, gr, psibar, psi) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gl, gr type(bispinor), intent(in) :: psibar type(bispinor), intent(in) :: psi j = sp_ff (gr+gl, gr-gl, psibar, psi) end function slr_ff @ <>= public :: f_spf, f_sf, f_pf, f_slf, f_srf, f_slrf @ <>= pure function f_spf (gs, gp, phi, psi) result (phipsi) type(bispinor) :: phipsi complex(kind=default), intent(in) :: gs, gp complex(kind=default), intent(in) :: phi type(bispinor), intent(in) :: psi phipsi%a(1:2) = ((gs - gp) * phi) * psi%a(1:2) phipsi%a(3:4) = ((gs + gp) * phi) * psi%a(3:4) end function f_spf @ <>= pure function f_sf (gs, phi, psi) result (phipsi) type(bispinor) :: phipsi complex(kind=default), intent(in) :: gs complex(kind=default), intent(in) :: phi type(bispinor), intent(in) :: psi phipsi%a = (gs * phi) * psi%a end function f_sf @ <>= pure function f_pf (gp, phi, psi) result (phipsi) type(bispinor) :: phipsi complex(kind=default), intent(in) :: gp complex(kind=default), intent(in) :: phi type(bispinor), intent(in) :: psi phipsi%a(1:2) = (- gp * phi) * psi%a(1:2) phipsi%a(3:4) = ( gp * phi) * psi%a(3:4) end function f_pf @ <>= pure function f_slf (gl, phi, psi) result (phipsi) type(bispinor) :: phipsi complex(kind=default), intent(in) :: gl complex(kind=default), intent(in) :: phi type(bispinor), intent(in) :: psi phipsi%a(1:2) = (2 * gl * phi) * psi%a(1:2) phipsi%a(3:4) = 0 end function f_slf @ <>= pure function f_srf (gr, phi, psi) result (phipsi) type(bispinor) :: phipsi complex(kind=default), intent(in) :: gr complex(kind=default), intent(in) :: phi type(bispinor), intent(in) :: psi phipsi%a(1:2) = 0 phipsi%a(3:4) = (2 * gr * phi) * psi%a(3:4) end function f_srf @ <>= pure function f_slrf (gl, gr, phi, psi) result (phipsi) type(bispinor) :: phipsi complex(kind=default), intent(in) :: gl, gr complex(kind=default), intent(in) :: phi type(bispinor), intent(in) :: psi phipsi = f_spf (gr+gl, gr-gl, phi, psi) end function f_slrf @ \subsection{Couplings for BRST Transformations} \subsubsection{3-Couplings} The lists of needed gamma matrices can be found in the next subsection with the gravitino couplings. <>= private :: vv_ff, f_vvf @ <>= public :: vmom_ff, mom_ff, mom5_ff, moml_ff, momr_ff, lmom_ff, rmom_ff @ <>= pure function vv_ff (psibar, psi, k) result (psibarpsi) type(vector) :: psibarpsi type(bispinor), intent(in) :: psibar, psi type(vector), intent(in) :: k complex(kind=default) :: kp, km, k12, k12s type(bispinor) :: kgpsi1, kgpsi2, kgpsi3, kgpsi4 kp = k%t + k%x(3) km = k%t - k%x(3) k12 = k%x(1) + (0,1)*k%x(2) k12s = k%x(1) - (0,1)*k%x(2) kgpsi1%a(1) = -k%x(3) * psi%a(1) - k12s * psi%a(2) kgpsi1%a(2) = -k12 * psi%a(1) + k%x(3) * psi%a(2) kgpsi1%a(3) = k%x(3) * psi%a(3) + k12s * psi%a(4) kgpsi1%a(4) = k12 * psi%a(3) - k%x(3) * psi%a(4) kgpsi2%a(1) = ((0,-1) * k%x(2)) * psi%a(1) - km * psi%a(2) kgpsi2%a(2) = - kp * psi%a(1) + ((0,1) * k%x(2)) * psi%a(2) kgpsi2%a(3) = ((0,-1) * k%x(2)) * psi%a(3) + kp * psi%a(4) kgpsi2%a(4) = km * psi%a(3) + ((0,1) * k%x(2)) * psi%a(4) kgpsi3%a(1) = (0,1) * (k%x(1) * psi%a(1) + km * psi%a(2)) kgpsi3%a(2) = (0,-1) * (kp * psi%a(1) + k%x(1) * psi%a(2)) kgpsi3%a(3) = (0,1) * (k%x(1) * psi%a(3) - kp * psi%a(4)) kgpsi3%a(4) = (0,1) * (km * psi%a(3) - k%x(1) * psi%a(4)) kgpsi4%a(1) = -k%t * psi%a(1) - k12s * psi%a(2) kgpsi4%a(2) = k12 * psi%a(1) + k%t * psi%a(2) kgpsi4%a(3) = k%t * psi%a(3) - k12s * psi%a(4) kgpsi4%a(4) = k12 * psi%a(3) - k%t * psi%a(4) psibarpsi%t = 2 * (psibar * kgpsi1) psibarpsi%x(1) = 2 * (psibar * kgpsi2) psibarpsi%x(2) = 2 * (psibar * kgpsi3) psibarpsi%x(3) = 2 * (psibar * kgpsi4) end function vv_ff @ <>= pure function f_vvf (v, psi, k) result (kvpsi) type(bispinor) :: kvpsi type(bispinor), intent(in) :: psi type(vector), intent(in) :: k, v complex(kind=default) :: kv30, kv21, kv01, kv31, kv02, kv32 complex(kind=default) :: ap, am, bp, bm, bps, bms kv30 = k%x(3) * v%t - k%t * v%x(3) kv21 = (0,1) * (k%x(2) * v%x(1) - k%x(1) * v%x(2)) kv01 = k%t * v%x(1) - k%x(1) * v%t kv31 = k%x(3) * v%x(1) - k%x(1) * v%x(3) kv02 = (0,1) * (k%t * v%x(2) - k%x(2) * v%t) kv32 = (0,1) * (k%x(3) * v%x(2) - k%x(2) * v%x(3)) ap = 2 * (kv30 + kv21) am = 2 * (-kv30 + kv21) bp = 2 * (kv01 + kv31 + kv02 + kv32) bm = 2 * (kv01 - kv31 + kv02 - kv32) bps = 2 * (kv01 + kv31 - kv02 - kv32) bms = 2 * (kv01 - kv31 - kv02 + kv32) kvpsi%a(1) = am * psi%a(1) + bms * psi%a(2) kvpsi%a(2) = bp * psi%a(1) - am * psi%a(2) kvpsi%a(3) = ap * psi%a(3) - bps * psi%a(4) kvpsi%a(4) = -bm * psi%a(3) - ap * psi%a(4) end function f_vvf @ <>= pure function vmom_ff (g, psibar, psi, k) result (psibarpsi) type(vector) :: psibarpsi complex(kind=default), intent(in) :: g type(bispinor), intent(in) :: psibar, psi type(momentum), intent(in) :: k type(vector) :: vk vk = k psibarpsi = g * vv_ff (psibar, psi, vk) end function vmom_ff @ <>= pure function mom_ff (g, m, psibar, psi, k) result (psibarpsi) complex(kind=default) :: psibarpsi type(bispinor), intent(in) :: psibar, psi type(momentum), intent(in) :: k complex(kind=default), intent(in) :: g, m type(bispinor) :: kmpsi complex(kind=default) :: kp, km, k12, k12s kp = k%t + k%x(3) km = k%t - k%x(3) k12 = k%x(1) + (0,1)*k%x(2) k12s = k%x(1) - (0,1)*k%x(2) kmpsi%a(1) = km * psi%a(3) - k12s * psi%a(4) kmpsi%a(2) = kp * psi%a(4) - k12 * psi%a(3) kmpsi%a(3) = kp * psi%a(1) + k12s * psi%a(2) kmpsi%a(4) = k12 * psi%a(1) + km * psi%a(2) psibarpsi = g * (psibar * kmpsi) + s_ff (m, psibar, psi) end function mom_ff @ <>= pure function mom5_ff (g, m, psibar, psi, k) result (psibarpsi) complex(kind=default) :: psibarpsi type(bispinor), intent(in) :: psibar, psi type(momentum), intent(in) :: k complex(kind=default), intent(in) :: g, m type(bispinor) :: g5psi g5psi%a(1:2) = - psi%a(1:2) g5psi%a(3:4) = psi%a(3:4) psibarpsi = mom_ff (g, m, psibar, g5psi, k) end function mom5_ff @ <>= pure function moml_ff (g, m, psibar, psi, k) result (psibarpsi) complex(kind=default) :: psibarpsi type(bispinor), intent(in) :: psibar, psi type(momentum), intent(in) :: k complex(kind=default), intent(in) :: g, m type(bispinor) :: leftpsi leftpsi%a(1:2) = 2 * psi%a(1:2) leftpsi%a(3:4) = 0 psibarpsi = mom_ff (g, m, psibar, leftpsi, k) end function moml_ff @ <>= pure function momr_ff (g, m, psibar, psi, k) result (psibarpsi) complex(kind=default) :: psibarpsi type(bispinor), intent(in) :: psibar, psi type(momentum), intent(in) :: k complex(kind=default), intent(in) :: g, m type(bispinor) :: rightpsi rightpsi%a(1:2) = 0 rightpsi%a(3:4) = 2 * psi%a(3:4) psibarpsi = mom_ff (g, m, psibar, rightpsi, k) end function momr_ff @ <>= pure function lmom_ff (g, m, psibar, psi, k) result (psibarpsi) complex(kind=default) :: psibarpsi type(bispinor), intent(in) :: psibar, psi type(momentum), intent(in) :: k complex(kind=default), intent(in) :: g, m psibarpsi = mom_ff (g, m, psibar, psi, k) + & mom5_ff (g,-m, psibar, psi, k) end function lmom_ff @ <>= pure function rmom_ff (g, m, psibar, psi, k) result (psibarpsi) complex(kind=default) :: psibarpsi type(bispinor), intent(in) :: psibar, psi type(momentum), intent(in) :: k complex(kind=default), intent(in) :: g, m psibarpsi = mom_ff (g, m, psibar, psi, k) - & mom5_ff (g,-m, psibar, psi, k) end function rmom_ff @ <>= public :: f_vmomf, f_momf, f_mom5f, f_momlf, f_momrf, f_lmomf, f_rmomf @ <>= pure function f_vmomf (g, v, psi, k) result (kvpsi) type(bispinor) :: kvpsi type(bispinor), intent(in) :: psi complex(kind=default), intent(in) :: g type(momentum), intent(in) :: k type(vector), intent(in) :: v type(vector) :: vk vk = k kvpsi = g * f_vvf (v, psi, vk) end function f_vmomf @ <>= pure function f_momf (g, m, phi, psi, k) result (kmpsi) type(bispinor) :: kmpsi type(bispinor), intent(in) :: psi complex(kind=default), intent(in) :: phi, g, m type(momentum), intent(in) :: k complex(kind=default) :: kp, km, k12, k12s kp = k%t + k%x(3) km = k%t - k%x(3) k12 = k%x(1) + (0,1)*k%x(2) k12s = k%x(1) - (0,1)*k%x(2) kmpsi%a(1) = km * psi%a(3) - k12s * psi%a(4) kmpsi%a(2) = -k12 * psi%a(3) + kp * psi%a(4) kmpsi%a(3) = kp * psi%a(1) + k12s * psi%a(2) kmpsi%a(4) = k12 * psi%a(1) + km * psi%a(2) kmpsi = g * (phi * kmpsi) + f_sf (m, phi, psi) end function f_momf @ <>= pure function f_mom5f (g, m, phi, psi, k) result (kmpsi) type(bispinor) :: kmpsi type(bispinor), intent(in) :: psi complex(kind=default), intent(in) :: phi, g, m type(momentum), intent(in) :: k type(bispinor) :: g5psi g5psi%a(1:2) = - psi%a(1:2) g5psi%a(3:4) = psi%a(3:4) kmpsi = f_momf (g, m, phi, g5psi, k) end function f_mom5f @ <>= pure function f_momlf (g, m, phi, psi, k) result (kmpsi) type(bispinor) :: kmpsi type(bispinor), intent(in) :: psi complex(kind=default), intent(in) :: phi, g, m type(momentum), intent(in) :: k type(bispinor) :: leftpsi leftpsi%a(1:2) = 2 * psi%a(1:2) leftpsi%a(3:4) = 0 kmpsi = f_momf (g, m, phi, leftpsi, k) end function f_momlf @ <>= pure function f_momrf (g, m, phi, psi, k) result (kmpsi) type(bispinor) :: kmpsi type(bispinor), intent(in) :: psi complex(kind=default), intent(in) :: phi, g, m type(momentum), intent(in) :: k type(bispinor) :: rightpsi rightpsi%a(1:2) = 0 rightpsi%a(3:4) = 2 * psi%a(3:4) kmpsi = f_momf (g, m, phi, rightpsi, k) end function f_momrf @ <>= pure function f_lmomf (g, m, phi, psi, k) result (kmpsi) type(bispinor) :: kmpsi type(bispinor), intent(in) :: psi complex(kind=default), intent(in) :: phi, g, m type(momentum), intent(in) :: k kmpsi = f_momf (g, m, phi, psi, k) + & f_mom5f (g,-m, phi, psi, k) end function f_lmomf @ <>= pure function f_rmomf (g, m, phi, psi, k) result (kmpsi) type(bispinor) :: kmpsi type(bispinor), intent(in) :: psi complex(kind=default), intent(in) :: phi, g, m type(momentum), intent(in) :: k kmpsi = f_momf (g, m, phi, psi, k) - & f_mom5f (g,-m, phi, psi, k) end function f_rmomf @ \subsubsection{4-Couplings} <>= public :: v2_ff, sv1_ff, sv2_ff, pv1_ff, pv2_ff, svl1_ff, svl2_ff, & svr1_ff, svr2_ff, svlr1_ff, svlr2_ff @ <>= pure function v2_ff (g, psibar, v, psi) result (v2) type(vector) :: v2 complex (kind=default), intent(in) :: g type(bispinor), intent(in) :: psibar, psi type(vector), intent(in) :: v v2 = (-g) * vv_ff (psibar, psi, v) end function v2_ff @ <>= pure function sv1_ff (g, psibar, v, psi) result (phi) complex(kind=default) :: phi type(bispinor), intent(in) :: psibar, psi type(vector), intent(in) :: v complex(kind=default), intent(in) :: g phi = psibar * f_vf (g, v, psi) end function sv1_ff @ <>= pure function sv2_ff (g, psibar, phi, psi) result (v) type(vector) :: v complex(kind=default), intent(in) :: phi, g type(bispinor), intent(in) :: psibar, psi v = phi * v_ff (g, psibar, psi) end function sv2_ff @ <>= pure function pv1_ff (g, psibar, v, psi) result (phi) complex(kind=default) :: phi type(bispinor), intent(in) :: psibar, psi type(vector), intent(in) :: v complex(kind=default), intent(in) :: g phi = - (psibar * f_af (g, v, psi)) end function pv1_ff @ <>= pure function pv2_ff (g, psibar, phi, psi) result (v) type(vector) :: v complex(kind=default), intent(in) :: phi, g type(bispinor), intent(in) :: psibar, psi v = -(phi * a_ff (g, psibar, psi)) end function pv2_ff @ <>= pure function svl1_ff (g, psibar, v, psi) result (phi) complex(kind=default) :: phi type(bispinor), intent(in) :: psibar, psi type(vector), intent(in) :: v complex(kind=default), intent(in) :: g phi = psibar * f_vlf (g, v, psi) end function svl1_ff @ <>= pure function svl2_ff (g, psibar, phi, psi) result (v) type(vector) :: v complex(kind=default), intent(in) :: phi, g type(bispinor), intent(in) :: psibar, psi v = phi * vl_ff (g, psibar, psi) end function svl2_ff @ <>= pure function svr1_ff (g, psibar, v, psi) result (phi) complex(kind=default) :: phi type(bispinor), intent(in) :: psibar, psi type(vector), intent(in) :: v complex(kind=default), intent(in) :: g phi = psibar * f_vrf (g, v, psi) end function svr1_ff @ <>= pure function svr2_ff (g, psibar, phi, psi) result (v) type(vector) :: v complex(kind=default), intent(in) :: phi, g type(bispinor), intent(in) :: psibar, psi v = phi * vr_ff (g, psibar, psi) end function svr2_ff @ <>= pure function svlr1_ff (gl, gr, psibar, v, psi) result (phi) complex(kind=default) :: phi type(bispinor), intent(in) :: psibar, psi type(vector), intent(in) :: v complex(kind=default), intent(in) :: gl, gr phi = psibar * f_vlrf (gl, gr, v, psi) end function svlr1_ff @ <>= pure function svlr2_ff (gl, gr, psibar, phi, psi) result (v) type(vector) :: v complex(kind=default), intent(in) :: phi, gl, gr type(bispinor), intent(in) :: psibar, psi v = phi * vlr_ff (gl, gr, psibar, psi) end function svlr2_ff @ <>= public :: f_v2f, f_svf, f_pvf, f_svlf, f_svrf, f_svlrf @ <>= pure function f_v2f (g, v1, v2, psi) result (vpsi) type(bispinor) :: vpsi complex(kind=default), intent(in) :: g type(bispinor), intent(in) :: psi type(vector), intent(in) :: v1, v2 vpsi = g * f_vvf (v2, psi, v1) end function f_v2f @ <>= pure function f_svf (g, phi, v, psi) result (pvpsi) type(bispinor) :: pvpsi complex(kind=default), intent(in) :: g, phi type(bispinor), intent(in) :: psi type(vector), intent(in) :: v pvpsi = phi * f_vf (g, v, psi) end function f_svf @ <>= pure function f_pvf (g, phi, v, psi) result (pvpsi) type(bispinor) :: pvpsi complex(kind=default), intent(in) :: g, phi type(bispinor), intent(in) :: psi type(vector), intent(in) :: v pvpsi = -(phi * f_af (g, v, psi)) end function f_pvf @ <>= pure function f_svlf (g, phi, v, psi) result (pvpsi) type(bispinor) :: pvpsi complex(kind=default), intent(in) :: g, phi type(bispinor), intent(in) :: psi type(vector), intent(in) :: v pvpsi = phi * f_vlf (g, v, psi) end function f_svlf @ <>= pure function f_svrf (g, phi, v, psi) result (pvpsi) type(bispinor) :: pvpsi complex(kind=default), intent(in) :: g, phi type(bispinor), intent(in) :: psi type(vector), intent(in) :: v pvpsi = phi * f_vrf (g, v, psi) end function f_svrf @ <>= pure function f_svlrf (gl, gr, phi, v, psi) result (pvpsi) type(bispinor) :: pvpsi complex(kind=default), intent(in) :: gl, gr, phi type(bispinor), intent(in) :: psi type(vector), intent(in) :: v pvpsi = phi * f_vlrf (gl, gr, v, psi) end function f_svlrf @ \subsection{Gravitino Couplings} <>= public :: pot_grf, pot_fgr, s_grf, s_fgr, p_grf, p_fgr, & sl_grf, sl_fgr, sr_grf, sr_fgr, slr_grf, slr_fgr @ <>= private :: fgvgr, fgvg5gr, fggvvgr, grkgf, grkggf, grkkggf, & fgkgr, fg5gkgr, grvgf, grg5vgf, grkgggf, fggkggr @ <>= pure function pot_grf (g, gravbar, psi) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: g type(vectorspinor), intent(in) :: gravbar type(bispinor), intent(in) :: psi type(vectorspinor) :: gamma_psi gamma_psi%psi(1)%a(1) = psi%a(3) gamma_psi%psi(1)%a(2) = psi%a(4) gamma_psi%psi(1)%a(3) = psi%a(1) gamma_psi%psi(1)%a(4) = psi%a(2) gamma_psi%psi(2)%a(1) = psi%a(4) gamma_psi%psi(2)%a(2) = psi%a(3) gamma_psi%psi(2)%a(3) = - psi%a(2) gamma_psi%psi(2)%a(4) = - psi%a(1) gamma_psi%psi(3)%a(1) = (0,-1) * psi%a(4) gamma_psi%psi(3)%a(2) = (0,1) * psi%a(3) gamma_psi%psi(3)%a(3) = (0,1) * psi%a(2) gamma_psi%psi(3)%a(4) = (0,-1) * psi%a(1) gamma_psi%psi(4)%a(1) = psi%a(3) gamma_psi%psi(4)%a(2) = - psi%a(4) gamma_psi%psi(4)%a(3) = - psi%a(1) gamma_psi%psi(4)%a(4) = psi%a(2) j = g * (gravbar * gamma_psi) end function pot_grf @ <>= pure function pot_fgr (g, psibar, grav) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: g type(bispinor), intent(in) :: psibar type(vectorspinor), intent(in) :: grav type(bispinor) :: gamma_grav gamma_grav%a(1) = grav%psi(1)%a(3) - grav%psi(2)%a(4) + & ((0,1)*grav%psi(3)%a(4)) - grav%psi(4)%a(3) gamma_grav%a(2) = grav%psi(1)%a(4) - grav%psi(2)%a(3) - & ((0,1)*grav%psi(3)%a(3)) + grav%psi(4)%a(4) gamma_grav%a(3) = grav%psi(1)%a(1) + grav%psi(2)%a(2) - & ((0,1)*grav%psi(3)%a(2)) + grav%psi(4)%a(1) gamma_grav%a(4) = grav%psi(1)%a(2) + grav%psi(2)%a(1) + & ((0,1)*grav%psi(3)%a(1)) - grav%psi(4)%a(2) j = g * (psibar * gamma_grav) end function pot_fgr @ <>= pure function grvgf (gravbar, psi, k) result (j) complex(kind=default) :: j complex(kind=default) :: kp, km, k12, k12s type(vectorspinor), intent(in) :: gravbar type(bispinor), intent(in) :: psi type(vector), intent(in) :: k type(vectorspinor) :: kg_psi kp = k%t + k%x(3) km = k%t - k%x(3) k12 = k%x(1) + (0,1)*k%x(2) k12s = k%x(1) - (0,1)*k%x(2) !!! Since we are taking the spinor product here, NO explicit !!! charge conjugation matrix is needed! kg_psi%psi(1)%a(1) = km * psi%a(1) - k12s * psi%a(2) kg_psi%psi(1)%a(2) = (-k12) * psi%a(1) + kp * psi%a(2) kg_psi%psi(1)%a(3) = kp * psi%a(3) + k12s * psi%a(4) kg_psi%psi(1)%a(4) = k12 * psi%a(3) + km * psi%a(4) kg_psi%psi(2)%a(1) = k12s * psi%a(1) - km * psi%a(2) kg_psi%psi(2)%a(2) = (-kp) * psi%a(1) + k12 * psi%a(2) kg_psi%psi(2)%a(3) = k12s * psi%a(3) + kp * psi%a(4) kg_psi%psi(2)%a(4) = km * psi%a(3) + k12 * psi%a(4) kg_psi%psi(3)%a(1) = (0,1) * (k12s * psi%a(1) + km * psi%a(2)) kg_psi%psi(3)%a(2) = (0,1) * (- kp * psi%a(1) - k12 * psi%a(2)) kg_psi%psi(3)%a(3) = (0,1) * (k12s * psi%a(3) - kp * psi%a(4)) kg_psi%psi(3)%a(4) = (0,1) * (km * psi%a(3) - k12 * psi%a(4)) kg_psi%psi(4)%a(1) = (-km) * psi%a(1) - k12s * psi%a(2) kg_psi%psi(4)%a(2) = k12 * psi%a(1) + kp * psi%a(2) kg_psi%psi(4)%a(3) = kp * psi%a(3) - k12s * psi%a(4) kg_psi%psi(4)%a(4) = k12 * psi%a(3) - km * psi%a(4) j = gravbar * kg_psi end function grvgf @ <>= pure function grg5vgf (gravbar, psi, k) result (j) complex(kind=default) :: j type(vectorspinor), intent(in) :: gravbar type(bispinor), intent(in) :: psi type(vector), intent(in) :: k type(bispinor) :: g5_psi g5_psi%a(1:2) = - psi%a(1:2) g5_psi%a(3:4) = psi%a(3:4) j = grvgf (gravbar, g5_psi, k) end function grg5vgf @ <>= pure function s_grf (g, gravbar, psi, k) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: g type(vectorspinor), intent(in) :: gravbar type(bispinor), intent(in) :: psi type(momentum), intent(in) :: k type(vector) :: vk vk = k j = g * grvgf (gravbar, psi, vk) end function s_grf @ <>= pure function sl_grf (gl, gravbar, psi, k) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gl type(vectorspinor), intent(in) :: gravbar type(bispinor), intent(in) :: psi type(bispinor) :: psi_l type(momentum), intent(in) :: k psi_l%a(1:2) = psi%a(1:2) psi_l%a(3:4) = 0 j = s_grf (gl, gravbar, psi_l, k) end function sl_grf @ <>= pure function sr_grf (gr, gravbar, psi, k) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gr type(vectorspinor), intent(in) :: gravbar type(bispinor), intent(in) :: psi type(bispinor) :: psi_r type(momentum), intent(in) :: k psi_r%a(1:2) = 0 psi_r%a(3:4) = psi%a(3:4) j = s_grf (gr, gravbar, psi_r, k) end function sr_grf @ <>= pure function slr_grf (gl, gr, gravbar, psi, k) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gl, gr type(vectorspinor), intent(in) :: gravbar type(bispinor), intent(in) :: psi type(momentum), intent(in) :: k j = sl_grf (gl, gravbar, psi, k) + sr_grf (gr, gravbar, psi, k) end function slr_grf @ <>= pure function fgkgr (psibar, grav, k) result (j) complex(kind=default) :: j complex(kind=default) :: kp, km, k12, k12s type(bispinor), intent(in) :: psibar type(vectorspinor), intent(in) :: grav type(vector), intent(in) :: k type(bispinor) :: gk_grav kp = k%t + k%x(3) km = k%t - k%x(3) k12 = k%x(1) + (0,1)*k%x(2) k12s = k%x(1) - (0,1)*k%x(2) !!! Since we are taking the spinor product here, NO explicit !!! charge conjugation matrix is needed! gk_grav%a(1) = kp * grav%psi(1)%a(1) + k12s * grav%psi(1)%a(2) & - k12 * grav%psi(2)%a(1) - km * grav%psi(2)%a(2) & + (0,1) * k12 * grav%psi(3)%a(1) & + (0,1) * km * grav%psi(3)%a(2) & - kp * grav%psi(4)%a(1) - k12s * grav%psi(4)%a(2) gk_grav%a(2) = k12 * grav%psi(1)%a(1) + km * grav%psi(1)%a(2) & - kp * grav%psi(2)%a(1) - k12s * grav%psi(2)%a(2) & - (0,1) * kp * grav%psi(3)%a(1) & - (0,1) * k12s * grav%psi(3)%a(2) & + k12 * grav%psi(4)%a(1) + km * grav%psi(4)%a(2) gk_grav%a(3) = km * grav%psi(1)%a(3) - k12s * grav%psi(1)%a(4) & - k12 * grav%psi(2)%a(3) + kp * grav%psi(2)%a(4) & + (0,1) * k12 * grav%psi(3)%a(3) & - (0,1) * kp * grav%psi(3)%a(4) & + km * grav%psi(4)%a(3) - k12s * grav%psi(4)%a(4) gk_grav%a(4) = - k12 * grav%psi(1)%a(3) + kp * grav%psi(1)%a(4) & + km * grav%psi(2)%a(3) - k12s * grav%psi(2)%a(4) & + (0,1) * km * grav%psi(3)%a(3) & - (0,1) * k12s * grav%psi(3)%a(4) & + k12 * grav%psi(4)%a(3) - kp * grav%psi(4)%a(4) j = psibar * gk_grav end function fgkgr @ <>= pure function fg5gkgr (psibar, grav, k) result (j) complex(kind=default) :: j type(bispinor), intent(in) :: psibar type(vectorspinor), intent(in) :: grav type(vector), intent(in) :: k type(bispinor) :: psibar_g5 psibar_g5%a(1:2) = - psibar%a(1:2) psibar_g5%a(3:4) = psibar%a(3:4) j = fgkgr (psibar_g5, grav, k) end function fg5gkgr @ <>= pure function s_fgr (g, psibar, grav, k) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: g type(bispinor), intent(in) :: psibar type(vectorspinor), intent(in) :: grav type(momentum), intent(in) :: k type(vector) :: vk vk = k j = g * fgkgr (psibar, grav, vk) end function s_fgr @ <>= pure function sl_fgr (gl, psibar, grav, k) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gl type(bispinor), intent(in) :: psibar type(bispinor) :: psibar_l type(vectorspinor), intent(in) :: grav type(momentum), intent(in) :: k psibar_l%a(1:2) = psibar%a(1:2) psibar_l%a(3:4) = 0 j = s_fgr (gl, psibar_l, grav, k) end function sl_fgr @ <>= pure function sr_fgr (gr, psibar, grav, k) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gr type(bispinor), intent(in) :: psibar type(bispinor) :: psibar_r type(vectorspinor), intent(in) :: grav type(momentum), intent(in) :: k psibar_r%a(1:2) = 0 psibar_r%a(3:4) = psibar%a(3:4) j = s_fgr (gr, psibar_r, grav, k) end function sr_fgr @ @ <>= pure function slr_fgr (gl, gr, psibar, grav, k) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gl, gr type(bispinor), intent(in) :: psibar type(vectorspinor), intent(in) :: grav type(momentum), intent(in) :: k j = sl_fgr (gl, psibar, grav, k) + sr_fgr (gr, psibar, grav, k) end function slr_fgr @ <>= pure function p_grf (g, gravbar, psi, k) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: g type(vectorspinor), intent(in) :: gravbar type(bispinor), intent(in) :: psi type(momentum), intent(in) :: k type(vector) :: vk vk = k j = g * grg5vgf (gravbar, psi, vk) end function p_grf @ <>= pure function p_fgr (g, psibar, grav, k) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: g type(bispinor), intent(in) :: psibar type(vectorspinor), intent(in) :: grav type(momentum), intent(in) :: k type(vector) :: vk vk = k j = g * fg5gkgr (psibar, grav, vk) end function p_fgr @ <>= public :: f_potgr, f_sgr, f_pgr, f_vgr, f_vlrgr, f_slgr, f_srgr, f_slrgr @ <>= pure function f_potgr (g, phi, psi) result (phipsi) type(bispinor) :: phipsi complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: phi type(vectorspinor), intent(in) :: psi phipsi%a(1) = (g * phi) * (psi%psi(1)%a(3) - psi%psi(2)%a(4) + & ((0,1)*psi%psi(3)%a(4)) - psi%psi(4)%a(3)) phipsi%a(2) = (g * phi) * (psi%psi(1)%a(4) - psi%psi(2)%a(3) - & ((0,1)*psi%psi(3)%a(3)) + psi%psi(4)%a(4)) phipsi%a(3) = (g * phi) * (psi%psi(1)%a(1) + psi%psi(2)%a(2) - & ((0,1)*psi%psi(3)%a(2)) + psi%psi(4)%a(1)) phipsi%a(4) = (g * phi) * (psi%psi(1)%a(2) + psi%psi(2)%a(1) + & ((0,1)*psi%psi(3)%a(1)) - psi%psi(4)%a(2)) end function f_potgr @ The slashed notation: \begin{equation} \fmslash{k} = \begin{pmatrix} 0 & 0 & k_- & - k^* \\ 0 & 0 & - k & k_+ \\ k_+ & k^* & 0 & 0 \\ k & k_- & 0 & 0 \end{pmatrix} , \qquad \fmslash{k}\gamma_5 = \begin{pmatrix} 0 & 0 & k_- & - k^* \\ 0 & 0 & - k & k_+ \\ - k_+ & - k^* & 0 & 0 \\ - k & - k_- & 0 & 0 \end{pmatrix} \end{equation} with $k_\pm=k_0\pm k_3$, $k=k_1+\ii k_2$, $k^*=k_1-\ii k_2$. But note that~$\cdot^*$ is \emph{not} complex conjugation for complex~$k_\mu$. \begin{subequations} \begin{alignat}{2} \gamma^0 \fmslash{k} &= \begin{pmatrix} k_+ & k^* & 0 & 0 \\ k & k_- & 0 & 0 \\ 0 & 0 & k_- & - k^* \\ 0 & 0 & - k & k_+ \end{pmatrix} , & \qquad \gamma^0 \fmslash{k} \gamma^5 & = \begin{pmatrix} - k_+ & - k^* & 0 & 0 \\ - k & - k_- & 0 & 0 \\ 0 & 0 & k_- & - k^* \\ 0 & 0 & - k & k_+ \end{pmatrix} \\ \gamma^1 \fmslash{k} &= \begin{pmatrix} k & k_- & 0 & 0 \\ k_+ & k^* & 0 & 0 \\ 0 & 0 & k & - k_+ \\ 0 & 0 & - k_- & k^* \end{pmatrix}, & \qquad \gamma^1 \fmslash{k} \gamma^5 & = \begin{pmatrix} - k & - k_- & 0 & 0 \\ - k_+ & - k^* & 0 & 0 \\ 0 & 0 & k & - k_+ \\ 0 & 0 & - k_- & k^* \end{pmatrix} \\ \gamma^2 \fmslash{k} &= \begin{pmatrix} - \ii k & - \ii k_- & 0 & 0 \\ \ii k_+ & \ii k^* & 0 & 0 \\ 0 & 0 & - \ii k & \ii k_+ \\ 0 & 0 & - \ii k_- & \ii k^* \end{pmatrix}, & \qquad \gamma^2 \fmslash{k} \gamma^5 & = \begin{pmatrix} \ii k & \ii k_- & 0 & 0 \\ - \ii k_+ & - \ii k^* & 0 & 0 \\ 0 & 0 & - \ii k & \ii k_+ \\ 0 & 0 & - \ii k_- & \ii k^* \end{pmatrix} \\ \gamma^3 \fmslash{k} &= \begin{pmatrix} k_+ & k^* & 0 & 0 \\ - k & - k_- & 0 & 0 \\ 0 & 0 & - k_- & k^* \\ 0 & 0 & - k & k_+ \end{pmatrix}, & \qquad \gamma^3 \fmslash{k} \gamma^5 & = \begin{pmatrix} - k_+ & - k^* & 0 & 0 \\ k & k_- & 0 & 0 \\ 0 & 0 & - k_- & k^* \\ 0 & 0 & - k & k_+ \end{pmatrix} \end{alignat} \end{subequations} and \begin{subequations} \begin{alignat}{2} \fmslash{k} \gamma^0&= \begin{pmatrix} k_- & - k^* & 0 & 0 \\ - k & k_+ & 0 & 0 \\ 0 & 0 & k_+ & k^* \\ 0 & 0 & k & k_- \end{pmatrix} , & \qquad \fmslash{k} \gamma^0 \gamma^5 & = \begin{pmatrix} - k_- & k^* & 0 & 0 \\ k & - k_+ & 0 & 0 \\ 0 & 0 & k_+ & k^* \\ 0 & 0 & k & k_- \end{pmatrix} \\ \fmslash{k} \gamma^1 &= \begin{pmatrix} k^* & - k_- & 0 & 0 \\ - k_+ & k & 0 & 0 \\ 0 & 0 & k^* & k_+ \\ 0 & 0 & k_- & k \end{pmatrix}, & \qquad \fmslash{k} \gamma^1 \gamma^5 & = \begin{pmatrix} - k^* & k_- & 0 & 0 \\ k_+ & - k & 0 & 0 \\ 0 & 0 & k^* & k_+ \\ 0 & 0 & k_- & k \end{pmatrix} \\ \fmslash{k} \gamma^2 &= \begin{pmatrix} \ii k^* & \ii k_- & 0 & 0 \\ - \ii k_+ & - \ii k & 0 & 0 \\ 0 & 0 & \ii k^* & - \ii k_+ \\ 0 & 0 & \ii k_- & - \ii k \end{pmatrix}, & \qquad \fmslash{k} \gamma^2 \gamma^5 & = \begin{pmatrix} - \ii k^* & - \ii k_- & 0 & 0 \\ \ii k_+ & \ii k & 0 & 0 \\ 0 & 0 & \ii k^* & - \ii k_+ \\ 0 & 0 & \ii k_- & - \ii k \end{pmatrix} \\ \fmslash{k} \gamma^3 &= \begin{pmatrix} - k_- & - k^* & 0 & 0 \\ k & k_+ & 0 & 0 \\ 0 & 0 & k_+ & - k^* \\ 0 & 0 & k & - k_- \end{pmatrix}, & \qquad \fmslash{k} \gamma^3 \gamma^5 & = \begin{pmatrix} k_- & k^* & 0 & 0 \\ - k & - k_+ & 0 & 0 \\ 0 & 0 & k_+ & - k^* \\ 0 & 0 & k & - k_- \end{pmatrix} \end{alignat} \end{subequations} and \begin{subequations} \begin{alignat}{2} C \gamma^0 \fmslash{k} &= \begin{pmatrix} k & k_- & 0 & 0 \\ - k_+ & - k^* & 0 & 0 \\ 0 & 0 & k & - k_+ \\ 0 & 0 & k_- & - k^* \end{pmatrix} , & \qquad C \gamma^0 \fmslash{k} \gamma^5 & = \begin{pmatrix} - k & - k_- & 0 & 0 \\ k_+ & k^* & 0 & 0 \\ 0 & 0 & k & - k_+ \\ 0 & 0 & k_- & - k^* \end{pmatrix} \\ C \gamma^1 \fmslash{k} &= \begin{pmatrix} k_+ & k^* & 0 & 0 \\ - k & - k_- & 0 & 0 \\ 0 & 0 & k_- & - k^* \\ 0 & 0 & k & - k_+ \end{pmatrix}, & \qquad C \gamma^1 \fmslash{k} \gamma^5 & = \begin{pmatrix} - k_+ & - k^* & 0 & 0 \\ k & k_- & 0 & 0 \\ 0 & 0 & k_- & - k^* \\ 0 & 0 & k & - k_+ \end{pmatrix} \\ C \gamma^2 \fmslash{k} &= \begin{pmatrix} \ii k_+ & \ii k^* & 0 & 0 \\ \ii k & \ii k_- & 0 & 0 \\ 0 & 0 & \ii k_- & - \ii k^* \\ 0 & 0 & - \ii k & \ii k_+ \end{pmatrix}, & \qquad C \gamma^2 \fmslash{k} \gamma^5 & = \begin{pmatrix} - \ii k_+ & - \ii k^* & 0 & 0 \\ - \ii k & - \ii k_- & 0 & 0 \\ 0 & 0 & \ii k_- & - \ii k^* \\ 0 & 0 & - \ii k & \ii k_+ \end{pmatrix} \\ C \gamma^3 \fmslash{k} &= \begin{pmatrix} - k & - k_- & 0 & 0 \\ - k_+ & - k^* & 0 & 0 \\ 0 & 0 & k & - k_+ \\ 0 & 0 & - k_- & k^* \end{pmatrix}, & \qquad C \gamma^3 \fmslash{k} \gamma^5 & = \begin{pmatrix} k & k_- & 0 & 0 \\ k_+ & k^* & 0 & 0 \\ 0 & 0 & k & - k_+ \\ 0 & 0 & - k_- & k^* \end{pmatrix} \end{alignat} \end{subequations} and \begin{subequations} \begin{alignat}{2} C \fmslash{k} \gamma^0&= \begin{pmatrix} - k & k^+ & 0 & 0 \\ - k_- & k^* & 0 & 0 \\ 0 & 0 & - k & - k_- \\ 0 & 0 & k_+ & k^* \end{pmatrix} , & \qquad C \fmslash{k} \gamma^0 \gamma^5 & = \begin{pmatrix} k & - k_+ & 0 & 0 \\ k_- & - k^* & 0 & 0 \\ 0 & 0 & - k & - k_- \\ 0 & 0 & k_+ & k^* \end{pmatrix} \\ C \fmslash{k} \gamma^1 &= \begin{pmatrix} - k_+ & k & 0 & 0 \\ - k^* & k_- & 0 & 0 \\ 0 & 0 & - k_- & - k \\ 0 & 0 & k^* & k_+ \end{pmatrix}, & \qquad C \fmslash{k} \gamma^1 \gamma^5 & = \begin{pmatrix} k_+ & - k & 0 & 0 \\ k^* & - k_- & 0 & 0 \\ 0 & 0 & - k_- & - k \\ 0 & 0 & k^* & k_+ \end{pmatrix} \\ C \fmslash{k} \gamma^2 &= \begin{pmatrix} - \ii k_+ & - \ii k & 0 & 0 \\ - \ii k^* & - \ii k_- & 0 & 0 \\ 0 & 0 & - \ii k_- & \ii k \\ 0 & 0 & \ii k^* & - \ii k_+ \end{pmatrix}, & \qquad C \fmslash{k} \gamma^2 \gamma^5 & = \begin{pmatrix} \ii k_+ & \ii k & 0 & 0 \\ \ii k^* & \ii k_- & 0 & 0 \\ 0 & 0 & - \ii k_- & \ii k \\ 0 & 0 & \ii k^* & - \ii k_+ \end{pmatrix} \\ C \fmslash{k} \gamma^3 &= \begin{pmatrix} k & k_+ & 0 & 0 \\ k_- & k^* & 0 & 0 \\ 0 & 0 & - k & k_- \\ 0 & 0 & k_+ & - k^* \end{pmatrix}, & \qquad C \fmslash{k} \gamma^3 \gamma^5 & = \begin{pmatrix} - k & - k_+ & 0 & 0 \\ - k_- & - k^* & 0 & 0 \\ 0 & 0 & - k & k_- \\ 0 & 0 & k_+ & - k^* \end{pmatrix} \end{alignat} \end{subequations} <>= pure function fgvgr (psi, k) result (kpsi) type(bispinor) :: kpsi complex(kind=default) :: kp, km, k12, k12s type(vector), intent(in) :: k type(vectorspinor), intent(in) :: psi kp = k%t + k%x(3) km = k%t - k%x(3) k12 = k%x(1) + (0,1)*k%x(2) k12s = k%x(1) - (0,1)*k%x(2) kpsi%a(1) = kp * psi%psi(1)%a(1) + k12s * psi%psi(1)%a(2) & - k12 * psi%psi(2)%a(1) - km * psi%psi(2)%a(2) & + (0,1) * k12 * psi%psi(3)%a(1) + (0,1) * km * psi%psi(3)%a(2) & - kp * psi%psi(4)%a(1) - k12s * psi%psi(4)%a(2) kpsi%a(2) = k12 * psi%psi(1)%a(1) + km * psi%psi(1)%a(2) & - kp * psi%psi(2)%a(1) - k12s * psi%psi(2)%a(2) & - (0,1) * kp * psi%psi(3)%a(1) - (0,1) * k12s * psi%psi(3)%a(2) & + k12 * psi%psi(4)%a(1) + km * psi%psi(4)%a(2) kpsi%a(3) = km * psi%psi(1)%a(3) - k12s * psi%psi(1)%a(4) & - k12 * psi%psi(2)%a(3) + kp * psi%psi(2)%a(4) & + (0,1) * k12 * psi%psi(3)%a(3) - (0,1) * kp * psi%psi(3)%a(4) & + km * psi%psi(4)%a(3) - k12s * psi%psi(4)%a(4) kpsi%a(4) = - k12 * psi%psi(1)%a(3) + kp * psi%psi(1)%a(4) & + km * psi%psi(2)%a(3) - k12s * psi%psi(2)%a(4) & + (0,1) * km * psi%psi(3)%a(3) - (0,1) * k12s * psi%psi(3)%a(4) & + k12 * psi%psi(4)%a(3) - kp * psi%psi(4)%a(4) end function fgvgr @ <>= pure function f_sgr (g, phi, psi, k) result (phipsi) type(bispinor) :: phipsi complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: phi type(momentum), intent(in) :: k type(vectorspinor), intent(in) :: psi type(vector) :: vk vk = k phipsi = (g * phi) * fgvgr (psi, vk) end function f_sgr @ <>= pure function f_slgr (gl, phi, psi, k) result (phipsi) type(bispinor) :: phipsi complex(kind=default), intent(in) :: gl complex(kind=default), intent(in) :: phi type(momentum), intent(in) :: k type(vectorspinor), intent(in) :: psi phipsi = f_sgr (gl, phi, psi, k) phipsi%a(3:4) = 0 end function f_slgr @ <>= pure function f_srgr (gr, phi, psi, k) result (phipsi) type(bispinor) :: phipsi complex(kind=default), intent(in) :: gr complex(kind=default), intent(in) :: phi type(momentum), intent(in) :: k type(vectorspinor), intent(in) :: psi phipsi = f_sgr (gr, phi, psi, k) phipsi%a(1:2) = 0 end function f_srgr @ <>= pure function f_slrgr (gl, gr, phi, psi, k) result (phipsi) type(bispinor) :: phipsi, phipsi_l, phipsi_r complex(kind=default), intent(in) :: gl, gr complex(kind=default), intent(in) :: phi type(momentum), intent(in) :: k type(vectorspinor), intent(in) :: psi phipsi_l = f_slgr (gl, phi, psi, k) phipsi_r = f_srgr (gr, phi, psi, k) phipsi%a(1:2) = phipsi_l%a(1:2) phipsi%a(3:4) = phipsi_r%a(3:4) end function f_slrgr @ <>= pure function fgvg5gr (psi, k) result (kpsi) type(bispinor) :: kpsi type(vector), intent(in) :: k type(vectorspinor), intent(in) :: psi type(bispinor) :: kpsi_dum kpsi_dum = fgvgr (psi, k) kpsi%a(1:2) = - kpsi_dum%a(1:2) kpsi%a(3:4) = kpsi_dum%a(3:4) end function fgvg5gr @ <>= pure function f_pgr (g, phi, psi, k) result (phipsi) type(bispinor) :: phipsi complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: phi type(momentum), intent(in) :: k type(vectorspinor), intent(in) :: psi type(vector) :: vk vk = k phipsi = (g * phi) * fgvg5gr (psi, vk) end function f_pgr @ The needed construction of gamma matrices involving the commutator of two gamma matrices. For the slashed terms we use as usual the abbreviations $k_\pm=k_0\pm k_3$, $k=k_1+\ii k_2$, $k^*=k_1-\ii k_2$ and analogous expressions for the vector $v^\mu$. We remind you that~$\cdot^*$ is \emph{not} complex conjugation for complex~$k_\mu$. Furthermore we introduce (in what follows the brackets around the vector indices have the usual meaning of antisymmetrizing with respect to the indices inside the brackets, here without a factor two in the denominator) \begin{subequations} \begin{alignat}{2} a_+ &= \; k_+ v_- + k v^* - k_- v_+ - k^* v & \; = & \; 2 (k_{[3} v_{0]} + \ii k_{[2} v_{1]}) \\ a_- &= \; k_- v_+ + k v^* - k_+ v_- - k^* v & \; = & \; 2 (-k_{[3} v_{0]} + \ii k_{[2} v_{1]}) \\ b_+ &= \; 2 (k_+ v - k v_+) & \; = & \; 2 (k_{[0} v_{1]} + k_{[3} v_{1]} + \ii k_{[0} v_{2]} + \ii k_{[3} v_{2]}) \\ b_- &= \; 2 (k_- v - k v_-) & \; = & \; 2 (k_{[0} v_{1]} - k_{[3} v_{1]} + \ii k_{[0} v_{2]} - \ii k_{[3} v_{2]}) \\ b_{+*} &= \; 2 (k_+ v^* - k^* v_+) & \; = & \; 2 (k_{[0} v_{1]} + k_{[3} v_{1]} - \ii k_{[0} v_{2]} - \ii k_{[3} v_{2]}) \\ b_{-*} &= \; 2 (k_- v^* - k^* v_-) & \; = & \; 2 (k_{[0} v_{1]} - k_{[3} v_{1]} - \ii k_{[0} v_{2]} + \ii k_{[3} v_{2]}) \end{alignat} \end{subequations} Of course, one could introduce a more advanced notation, but we don't want to become confused. \begin{subequations} \begin{align} \lbrack \fmslash{k} , \gamma^0 \rbrack &= \begin{pmatrix} -2k_3 & -2 k^* & 0 & 0 \\ -2k & 2k_3 & 0 & 0 \\ 0 & 0 & 2k_3 & 2k^* \\ 0 & 0 & 2k & -2k_3 \end{pmatrix} \\ \lbrack \fmslash{k} , \gamma^1 \rbrack &= \begin{pmatrix} -2\ii k_2 & -2k_- & 0 & 0 \\ -2k_+ & 2\ii k_2 & 0 & 0 \\ 0 & 0 & -2\ii k_2 & 2k_+ \\ 0 & 0 & 2k_- & 2\ii k_2 \end{pmatrix} \\ \lbrack \fmslash{k} , \gamma^2 \rbrack &= \begin{pmatrix} 2\ii k_1 & 2\ii k_- & 0 & 0 \\ -2\ii k_+ & -2\ii k_1 & 0 & 0 \\ 0 & 0 & 2\ii k_1 & -2\ii k_+ \\ 0 & 0 & 2\ii k_- & -2\ii k_1 \end{pmatrix} \\ \lbrack \fmslash{k} , \gamma^3 \rbrack &= \begin{pmatrix} -2k_0 & -2k^* & 0 & 0 \\ 2k & 2k_0 & 0 & 0 \\ 0 & 0 & 2k_0 & -2k^* \\ 0 & 0 & 2k & -2k_0 \end{pmatrix} \\ \lbrack \fmslash{k} , \fmslash{V} \rbrack &= \begin{pmatrix} a_- & b_{-*} & 0 & 0 \\ b_+ & -a_- & 0 & 0 \\ 0 & 0 & a_+ & -b_{+*} \\ 0 & 0 & -b_- & -a_+ \end{pmatrix} \\ \gamma^5\gamma^0 \lbrack \fmslash{k} , \fmslash{V} \rbrack &= \begin{pmatrix} 0 & 0 & - a_+ & b_{+*} \\ 0 & 0 & b_- & a_+ \\ a_- & b_{-*} & 0 & 0 \\ b_+ & - a_- & 0 & 0 \end{pmatrix} \\ \gamma^5\gamma^1 \lbrack \fmslash{k} , \fmslash{V} \rbrack &= \begin{pmatrix} 0 & 0 & b_- & a_+ \\ 0 & 0 & -a_+ & b_{+*} \\ -b_+ & a_- & 0 & 0 & \\ -a_- & -b_{-*} & 0 & 0 \end{pmatrix} \\ \gamma^5\gamma^2 \lbrack \fmslash{k} , \fmslash{V} \rbrack &= \begin{pmatrix} 0 & 0 & -\ii b_- & -\ii a_+ \\ 0 & 0 & -\ii a_+ & \ii b_{+*} \\ \ii b_+ & -\ii a_- & 0 & 0 \\ -\ii a_- & -\ii b_{-*} & 0 & 0 \end{pmatrix} \\ \gamma^5\gamma^3 \lbrack \fmslash{k} , \fmslash{V} \rbrack &= \begin{pmatrix} 0 & 0 & -a_+ & b_{+*} \\ 0 & 0 & -b_- & -a_+ \\ -a_- & -b_{-*} & 0 & 0 \\ b_+ & -a_- & 0 & 0 \end{pmatrix} \end{align} \end{subequations} and \begin{subequations} \begin{align} \lbrack \fmslash{k} , \fmslash{V} \rbrack \gamma^0 \gamma^5 &= \begin{pmatrix} 0 & 0 & a_- & b_{-*} \\ 0 & 0 & b_+ & -a_- \\ -a_+ & b_{+*} & 0 & 0 \\ b_- & a_+ & 0 & 0 \end{pmatrix} \\ \lbrack \fmslash{k} , \fmslash{V} \rbrack \gamma^1 \gamma^5 &= \begin{pmatrix} 0 & 0 & b_{-*} & a_- \\ 0 & 0 & -a_- & b_+ \\ -b_{+*} & a_+ & 0 & 0 \\ -a_+ & -b_- & 0 & 0 \end{pmatrix} \\ \lbrack \fmslash{k} , \fmslash{V} \rbrack \gamma^2 \gamma^5 &= \begin{pmatrix} 0 & 0 & \ii b_{-*} & -\ii a_- \\ 0 & 0 & -\ii a_- & -\ii b_+ \\ -\ii b_{+*} & -\ii a_+ & 0 & 0 \\ -\ii a_+ & \ii b_- & 0 & 0 \end{pmatrix} \\ \lbrack \fmslash{k} , \fmslash{V} \rbrack \gamma^3 \gamma^5 &= \begin{pmatrix} 0 & 0 & a_- & - b_{-*} \\ 0 & 0 & b_+ & a_- \\ a_+ & b_{+*} & 0 & 0 \\ -b_- & a_+ & 0 & 0 \end{pmatrix} \end{align} \end{subequations} In what follows $l$ always means twice the value of $k$, e.g. $l_+$ = $2 k_+$. We use the abbreviation $C^{\mu\nu} \equiv C \lbrack \fmslash{k}, \gamma^\mu \rbrack \gamma^\nu \gamma^5$. \begin{subequations} \begin{alignat}{2} C^{00} &= \begin{pmatrix} 0 & 0 & -l & -l_3 \\ 0 & 0 & l_3 & l^* \\ l & -l_3 & 0 & 0 \\ -l_3 & -l^* & 0 & 0 \end{pmatrix} , & \qquad C^{20} &= \begin{pmatrix} 0 & 0 & -\ii l_+ & -\ii l_1 \\ 0 & 0 & -\ii l_1 & -\ii l_- \\ \ii l_- & -\ii l_1 & 0 & 0 \\ -\ii l_1 & \ii l_+ & 0 & 0 \end{pmatrix} \\ C^{01} &= \begin{pmatrix} 0 & 0 & l_3 & -l \\ 0 & 0 & l^* & l_3 \\ l_3 & -l & 0 & 0 \\ l^* & l_3 & 0 & 0 \end{pmatrix} , & \qquad C^{21} &= \begin{pmatrix} 0 & 0 & -\ii l_1 & -\ii l_+ \\ 0 & 0 & -\ii l_- & -\ii l_1 \\ \ii l_1 & -\ii l_- & 0 & 0 \\ -\ii l_+ & \ii l_1 & 0 & 0 \end{pmatrix} \\ C^{02} &= \begin{pmatrix} 0 & 0 & \ii l_3 & \ii l \\ 0 & 0 & \ii l^* & -\ii l_3 \\ \ii l_3 & \ii l & 0 & 0 \\ \ii l^* & -\ii l_3 & 0 & 0 \end{pmatrix} , & \qquad C^{22} &= \begin{pmatrix} 0 & 0 & l_1 & -l_+ \\ 0 & 0 & l_- & -l_1 \\ -l_1 & -l_- & 0 & 0 \\ l_+ & l_1 & 0 & 0 \end{pmatrix} \\ C^{03} &= \begin{pmatrix} 0 & 0 & -l & -l_3 \\ 0 & 0 & l_3 & -l^* \\ -l & -l_3 & 0 & 0 \\ l_3 & -l^* & 0 & 0 \end{pmatrix} , & \qquad C^{23} &= \begin{pmatrix} 0 & 0 & -\ii l_+ & \ii l_1 \\ 0 & 0 & -\ii l_1 & \ii l_- \\ -\ii l_- & -\ii l_1 & 0 & 0 \\ \ii l_1 & \ii l_+ & 0 & 0 \end{pmatrix} \\ C^{10} &= \begin{pmatrix} 0 & 0 & -l_+ & \ii l_2 \\ 0 & 0 & \ii l_2 & l_- \\ l_- & \ii l_2 & 0 & 0 \\ \ii l_2 & -l_+ & 0 & 0 \end{pmatrix} , & \qquad C^{30} &= \begin{pmatrix} 0 & 0 & l & l_0 \\ 0 & 0 & l_0 & l^* \\ l & -l_0 & 0 & 0 \\ -l_0 & l^* & 0 & 0 \end{pmatrix} \\ C^{11} &= \begin{pmatrix} 0 & 0 & \ii l_2 & -l_+ \\ 0 & 0 & l_- & \ii l_2 \\ -\ii l_2 & -l_- & 0 & 0 \\ l_+ & -\ii l_2 & 0 & 0 \end{pmatrix} , & \qquad C^{31} &= \begin{pmatrix} 0 & 0 & l_0 & l \\ 0 & 0 & l^* & l_0 \\ l_0 & -l & 0 & 0 \\ -l^* & l_0 & 0 & 0 \end{pmatrix} \\ C^{12} &= \begin{pmatrix} 0 & 0 & -l_2 & \ii l_+ \\ 0 & 0 & \ii l_- & l_2 \\ l_2 & \ii l_- & 0 & 0 \\ \ii l_+ & -l_2 & 0 & 0 \end{pmatrix} , & \qquad C^{32} &= \begin{pmatrix} 0 & 0 & \ii l_0 & -\ii l \\ 0 & 0 & \ii l^* & -\ii l_0 \\ \ii l_0 & \ii l & 0 & 0 \\ -\ii l^* & -\ii l_0 & 0 & 0 \end{pmatrix} \\ C^{13} &= \begin{pmatrix} 0 & 0 & -l_+ & -\ii l_2 \\ 0 & 0 & \ii l_2 & - l_- \\ -l_- & \ii l_2 & 0 & 0 \\ -\ii l_2 & -l_+ & 0 & 0 \end{pmatrix} , & \qquad C^{33} &= \begin{pmatrix} 0 & 0 & l & -l_0 \\ 0 & 0 & l_0 & -l^* \\ -l & -l_0 & 0 & 0 \\ l_0 & l^* & 0 & 0 \end{pmatrix} \end{alignat} \end{subequations} and, with the abbreviation $\tilde{C}^{\mu\nu} \equiv C \gamma^5 \gamma^\nu \lbrack \fmslash{k} , \gamma^\mu \rbrack$ (note the reversed order of the indices!) \begin{subequations} \begin{alignat}{2} \tilde{C}^{00} &= \begin{pmatrix} 0 & 0 & -l & l_3 \\ 0 & 0 & l_3 & l^* \\ l & -l_3 & 0 & 0 \\ -l_3 & -l^* & 0 & 0 \end{pmatrix} , & \qquad \tilde{C}^{20} &= \begin{pmatrix} 0 & 0 & -\ii l_- & \ii l_1 \\ 0 & 0 & \ii l_1 & -\ii l_+ \\ \ii l_+ & \ii l_1 & 0 & 0 \\ \ii l_1 & \ii l_- & 0 & 0 \end{pmatrix} \\ \tilde{C}^{01} &= \begin{pmatrix} 0 & 0 & -l_3 & -l^* \\ 0 & 0 & l & -l_3 \\ -l_3 & -l^* & 0 & 0 \\ l & -l_3 & 0 & 0 \end{pmatrix} , & \qquad \tilde{C}^{21} &= \begin{pmatrix} 0 & 0 & -\ii l_1 & \ii l_+ \\ 0 & 0 & \ii l_- & -\ii l_1 \\ \ii l_1 & \ii l_- & 0 & 0 \\ \ii l_+ & \ii l_1 & 0 & 0 \end{pmatrix} \\ \tilde{C}^{02} &= \begin{pmatrix} 0 & 0 & -\ii l_3 & -\ii l^* \\ 0 & 0 & -\ii l & \ii l_3 \\ -\ii l_3 & -\ii l^* & 0 & 0 \\ -\ii l & \ii l_3 & 0 & 0 \end{pmatrix} , & \qquad \tilde{C}^{22} &= \begin{pmatrix} 0 & 0 & l_1 & -l_+ \\ 0 & 0 & l_- & -l_1 \\ -l_1 & -l_- & 0 & 0 \\ l_+ & l_1 & 0 & 0 \end{pmatrix} \\ \tilde{C}^{03} &= \begin{pmatrix} 0 & 0 & l & -l_3 \\ 0 & 0 & l_3 & l^* \\ l & -l_3 & 0 & 0 \\ l_3 & l^* & 0 & 0 \end{pmatrix} , & \qquad \tilde{C}^{23} &= \begin{pmatrix} 0 & 0 & \ii l_- & -\ii l_1 \\ 0 & 0 & \ii l_1 & -\ii l_+ \\ \ii l_+ & \ii l_1 & 0 & 0 \\ -\ii l_1 & -\ii l_- & 0 & 0 \end{pmatrix} \\ \tilde{C}^{10} &= \begin{pmatrix} 0 & 0 & -l_- & -\ii l_2 \\ 0 & 0 & -\ii l_2 & l_+ \\ l_+ & -\ii l_2 & 0 & 0 \\ -\ii l_2 & -l_- & 0 & 0 \end{pmatrix} , & \qquad \tilde{C}^{30} &= \begin{pmatrix} 0 & 0 & -l & l_0 \\ 0 & 0 & l_0 & -l^* \\ -l & -l_0 & 0 & 0 \\ -l_0 & -l^* & 0 & 0 \end{pmatrix} \\ \tilde{C}^{11} &= \begin{pmatrix} 0 & 0 & \ii l_2 & -l_+ \\ 0 & 0 & l_- & \ii l_2 \\ -\ii l_2 & -l_- & 0 & 0 \\ l_+ & -\ii l_2 & 0 & 0 \end{pmatrix} , & \qquad \tilde{C}^{31} &= \begin{pmatrix} 0 & 0 & -l_0 & l^* \\ 0 & 0 & l & -l_0 \\ -l_0 & -l^* & 0 & 0 \\ -l & -l_0 & 0 & 0 \end{pmatrix} \\ \tilde{C}^{12} &= \begin{pmatrix} 0 & 0 & -l_2 & -\ii l_+ \\ 0 & 0 & -\ii l_- & l_2 \\ l_2 & -\ii l_- & 0 & 0 \\ -\ii l_+ & -l_2 & 0 & 0 \end{pmatrix} , & \qquad \tilde{C}^{32} &= \begin{pmatrix} 0 & 0 & -\ii l_0 & \ii l^* \\ 0 & 0 & -\ii l & \ii l_0 \\ -\ii l_0 & -\ii l^* & 0 & 0 \\ \ii l & \ii l_0 & 0 & 0 \end{pmatrix} \\ \tilde{C}^{13} &= \begin{pmatrix} 0 & 0 & l_- & \ii l_2 \\ 0 & 0 & -\ii l_2 & l_+ \\ l_+ & -\ii l_2 & 0 & 0 \\ \ii l_2 & l_- & 0 & 0 \end{pmatrix} , & \qquad \tilde{C}^{33} &= \begin{pmatrix} 0 & 0 & l & -l_0 \\ 0 & 0 & l_0 & -l^* \\ -l & -l_0 & 0 & 0 \\ l_0 & l^* & 0 & 0 \end{pmatrix} \end{alignat} \end{subequations} <>= pure function fggvvgr (v, psi, k) result (psikv) type(bispinor) :: psikv type(vectorspinor), intent(in) :: psi type(vector), intent(in) :: v, k complex(kind=default) :: kv30, kv21, kv01, kv31, kv02, kv32 complex(kind=default) :: ap, am, bp, bm, bps, bms kv30 = k%x(3) * v%t - k%t * v%x(3) kv21 = (0,1) * (k%x(2) * v%x(1) - k%x(1) * v%x(2)) kv01 = k%t * v%x(1) - k%x(1) * v%t kv31 = k%x(3) * v%x(1) - k%x(1) * v%x(3) kv02 = (0,1) * (k%t * v%x(2) - k%x(2) * v%t) kv32 = (0,1) * (k%x(3) * v%x(2) - k%x(2) * v%x(3)) ap = 2 * (kv30 + kv21) am = 2 * (-kv30 + kv21) bp = 2 * (kv01 + kv31 + kv02 + kv32) bm = 2 * (kv01 - kv31 + kv02 - kv32) bps = 2 * (kv01 + kv31 - kv02 - kv32) bms = 2 * (kv01 - kv31 - kv02 + kv32) psikv%a(1) = (-ap) * psi%psi(1)%a(3) + bps * psi%psi(1)%a(4) & + (-bm) * psi%psi(2)%a(3) + (-ap) * psi%psi(2)%a(4) & + (0,1) * (bm * psi%psi(3)%a(3) + ap * psi%psi(3)%a(4)) & + ap * psi%psi(4)%a(3) + (-bps) * psi%psi(4)%a(4) psikv%a(2) = bm * psi%psi(1)%a(3) + ap * psi%psi(1)%a(4) & + ap * psi%psi(2)%a(3) + (-bps) * psi%psi(2)%a(4) & + (0,1) * (ap * psi%psi(3)%a(3) - bps * psi%psi(3)%a(4)) & + bm * psi%psi(4)%a(3) + ap * psi%psi(4)%a(4) psikv%a(3) = am * psi%psi(1)%a(1) + bms * psi%psi(1)%a(2) & + bp * psi%psi(2)%a(1) + (-am) * psi%psi(2)%a(2) & + (0,-1) * (bp * psi%psi(3)%a(1) + (-am) * psi%psi(3)%a(2)) & + am * psi%psi(4)%a(1) + bms * psi%psi(4)%a(2) psikv%a(4) = bp * psi%psi(1)%a(1) + (-am) * psi%psi(1)%a(2) & + am * psi%psi(2)%a(1) + bms * psi%psi(2)%a(2) & + (0,1) * (am * psi%psi(3)%a(1) + bms * psi%psi(3)%a(2)) & + (-bp) * psi%psi(4)%a(1) + am * psi%psi(4)%a(2) end function fggvvgr @ <>= pure function f_vgr (g, v, psi, k) result (psikkkv) type(bispinor) :: psikkkv type(vectorspinor), intent(in) :: psi type(vector), intent(in) :: v type(momentum), intent(in) :: k complex(kind=default), intent(in) :: g type(vector) :: vk vk = k psikkkv = g * (fggvvgr (v, psi, vk)) end function f_vgr @ <>= pure function f_vlrgr (gl, gr, v, psi, k) result (psikv) type(bispinor) :: psikv type(vectorspinor), intent(in) :: psi type(vector), intent(in) :: v type(momentum), intent(in) :: k complex(kind=default), intent(in) :: gl, gr type(vector) :: vk vk = k psikv = fggvvgr (v, psi, vk) psikv%a(1:2) = gl * psikv%a(1:2) psikv%a(3:4) = gr * psikv%a(3:4) end function f_vlrgr @ <>= public :: gr_potf, gr_sf, gr_pf, gr_vf, gr_vlrf, gr_slf, gr_srf, gr_slrf @ <>= pure function gr_potf (g, phi, psi) result (phipsi) type(vectorspinor) :: phipsi complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: phi type(bispinor), intent(in) :: psi phipsi%psi(1)%a(1) = (g * phi) * psi%a(3) phipsi%psi(1)%a(2) = (g * phi) * psi%a(4) phipsi%psi(1)%a(3) = (g * phi) * psi%a(1) phipsi%psi(1)%a(4) = (g * phi) * psi%a(2) phipsi%psi(2)%a(1) = (g * phi) * psi%a(4) phipsi%psi(2)%a(2) = (g * phi) * psi%a(3) phipsi%psi(2)%a(3) = ((-g) * phi) * psi%a(2) phipsi%psi(2)%a(4) = ((-g) * phi) * psi%a(1) phipsi%psi(3)%a(1) = ((0,-1) * g * phi) * psi%a(4) phipsi%psi(3)%a(2) = ((0,1) * g * phi) * psi%a(3) phipsi%psi(3)%a(3) = ((0,1) * g * phi) * psi%a(2) phipsi%psi(3)%a(4) = ((0,-1) * g * phi) * psi%a(1) phipsi%psi(4)%a(1) = (g * phi) * psi%a(3) phipsi%psi(4)%a(2) = ((-g) * phi) * psi%a(4) phipsi%psi(4)%a(3) = ((-g) * phi) * psi%a(1) phipsi%psi(4)%a(4) = (g * phi) * psi%a(2) end function gr_potf @ <>= pure function grkgf (psi, k) result (kpsi) type(vectorspinor) :: kpsi complex(kind=default) :: kp, km, k12, k12s type(bispinor), intent(in) :: psi type(vector), intent(in) :: k kp = k%t + k%x(3) km = k%t - k%x(3) k12 = k%x(1) + (0,1)*k%x(2) k12s = k%x(1) - (0,1)*k%x(2) kpsi%psi(1)%a(1) = km * psi%a(1) - k12s * psi%a(2) kpsi%psi(1)%a(2) = (-k12) * psi%a(1) + kp * psi%a(2) kpsi%psi(1)%a(3) = kp * psi%a(3) + k12s * psi%a(4) kpsi%psi(1)%a(4) = k12 * psi%a(3) + km * psi%a(4) kpsi%psi(2)%a(1) = k12s * psi%a(1) - km * psi%a(2) kpsi%psi(2)%a(2) = (-kp) * psi%a(1) + k12 * psi%a(2) kpsi%psi(2)%a(3) = k12s * psi%a(3) + kp * psi%a(4) kpsi%psi(2)%a(4) = km * psi%a(3) + k12 * psi%a(4) kpsi%psi(3)%a(1) = (0,1) * (k12s * psi%a(1) + km * psi%a(2)) kpsi%psi(3)%a(2) = (0,-1) * (kp * psi%a(1) + k12 * psi%a(2)) kpsi%psi(3)%a(3) = (0,1) * (k12s * psi%a(3) - kp * psi%a(4)) kpsi%psi(3)%a(4) = (0,1) * (km * psi%a(3) - k12 * psi%a(4)) kpsi%psi(4)%a(1) = -(km * psi%a(1) + k12s * psi%a(2)) kpsi%psi(4)%a(2) = k12 * psi%a(1) + kp * psi%a(2) kpsi%psi(4)%a(3) = kp * psi%a(3) - k12s * psi%a(4) kpsi%psi(4)%a(4) = k12 * psi%a(3) - km * psi%a(4) end function grkgf @ <>= pure function gr_sf (g, phi, psi, k) result (phipsi) type(vectorspinor) :: phipsi complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: phi type(bispinor), intent(in) :: psi type(momentum), intent(in) :: k type(vector) :: vk vk = k phipsi = (g * phi) * grkgf (psi, vk) end function gr_sf @ <>= pure function gr_slf (gl, phi, psi, k) result (phipsi) type(vectorspinor) :: phipsi complex(kind=default), intent(in) :: gl complex(kind=default), intent(in) :: phi type(bispinor), intent(in) :: psi type(bispinor) :: psi_l type(momentum), intent(in) :: k psi_l%a(1:2) = psi%a(1:2) psi_l%a(3:4) = 0 phipsi = gr_sf (gl, phi, psi_l, k) end function gr_slf @ <>= pure function gr_srf (gr, phi, psi, k) result (phipsi) type(vectorspinor) :: phipsi complex(kind=default), intent(in) :: gr complex(kind=default), intent(in) :: phi type(bispinor), intent(in) :: psi type(bispinor) :: psi_r type(momentum), intent(in) :: k psi_r%a(1:2) = 0 psi_r%a(3:4) = psi%a(3:4) phipsi = gr_sf (gr, phi, psi_r, k) end function gr_srf @ <>= pure function gr_slrf (gl, gr, phi, psi, k) result (phipsi) type(vectorspinor) :: phipsi complex(kind=default), intent(in) :: gl, gr complex(kind=default), intent(in) :: phi type(bispinor), intent(in) :: psi type(momentum), intent(in) :: k phipsi = gr_slf (gl, phi, psi, k) + gr_srf (gr, phi, psi, k) end function gr_slrf @ <>= pure function grkggf (psi, k) result (kpsi) type(vectorspinor) :: kpsi complex(kind=default) :: kp, km, k12, k12s type(bispinor), intent(in) :: psi type(vector), intent(in) :: k kp = k%t + k%x(3) km = k%t - k%x(3) k12 = k%x(1) + (0,1)*k%x(2) k12s = k%x(1) - (0,1)*k%x(2) kpsi%psi(1)%a(1) = (-km) * psi%a(1) + k12s * psi%a(2) kpsi%psi(1)%a(2) = k12 * psi%a(1) - kp * psi%a(2) kpsi%psi(1)%a(3) = kp * psi%a(3) + k12s * psi%a(4) kpsi%psi(1)%a(4) = k12 * psi%a(3) + km * psi%a(4) kpsi%psi(2)%a(1) = (-k12s) * psi%a(1) + km * psi%a(2) kpsi%psi(2)%a(2) = kp * psi%a(1) - k12 * psi%a(2) kpsi%psi(2)%a(3) = k12s * psi%a(3) + kp * psi%a(4) kpsi%psi(2)%a(4) = km * psi%a(3) + k12 * psi%a(4) kpsi%psi(3)%a(1) = (0,-1) * (k12s * psi%a(1) + km * psi%a(2)) kpsi%psi(3)%a(2) = (0,1) * (kp * psi%a(1) + k12 * psi%a(2)) kpsi%psi(3)%a(3) = (0,1) * (k12s * psi%a(3) - kp * psi%a(4)) kpsi%psi(3)%a(4) = (0,1) * (km * psi%a(3) - k12 * psi%a(4)) kpsi%psi(4)%a(1) = km * psi%a(1) + k12s * psi%a(2) kpsi%psi(4)%a(2) = -(k12 * psi%a(1) + kp * psi%a(2)) kpsi%psi(4)%a(3) = kp * psi%a(3) - k12s * psi%a(4) kpsi%psi(4)%a(4) = k12 * psi%a(3) - km * psi%a(4) end function grkggf @ <>= pure function gr_pf (g, phi, psi, k) result (phipsi) type(vectorspinor) :: phipsi complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: phi type(bispinor), intent(in) :: psi type(momentum), intent(in) :: k type(vector) :: vk vk = k phipsi = (g * phi) * grkggf (psi, vk) end function gr_pf @ <>= pure function grkkggf (v, psi, k) result (psikv) type(vectorspinor) :: psikv type(bispinor), intent(in) :: psi type(vector), intent(in) :: v, k complex(kind=default) :: kv30, kv21, kv01, kv31, kv02, kv32 complex(kind=default) :: ap, am, bp, bm, bps, bms, imago imago = (0.0_default,1.0_default) kv30 = k%x(3) * v%t - k%t * v%x(3) kv21 = imago * (k%x(2) * v%x(1) - k%x(1) * v%x(2)) kv01 = k%t * v%x(1) - k%x(1) * v%t kv31 = k%x(3) * v%x(1) - k%x(1) * v%x(3) kv02 = imago * (k%t * v%x(2) - k%x(2) * v%t) kv32 = imago * (k%x(3) * v%x(2) - k%x(2) * v%x(3)) ap = 2 * (kv30 + kv21) am = 2 * ((-kv30) + kv21) bp = 2 * (kv01 + kv31 + kv02 + kv32) bm = 2 * (kv01 - kv31 + kv02 - kv32) bps = 2 * (kv01 + kv31 - kv02 - kv32) bms = 2 * (kv01 - kv31 - kv02 + kv32) psikv%psi(1)%a(1) = am * psi%a(3) + bms * psi%a(4) psikv%psi(1)%a(2) = bp * psi%a(3) + (-am) * psi%a(4) psikv%psi(1)%a(3) = (-ap) * psi%a(1) + bps * psi%a(2) psikv%psi(1)%a(4) = bm * psi%a(1) + ap * psi%a(2) psikv%psi(2)%a(1) = bms * psi%a(3) + am * psi%a(4) psikv%psi(2)%a(2) = (-am) * psi%a(3) + bp * psi%a(4) psikv%psi(2)%a(3) = (-bps) * psi%a(1) + ap * psi%a(2) psikv%psi(2)%a(4) = (-ap) * psi%a(1) + (-bm) * psi%a(2) psikv%psi(3)%a(1) = imago * (bms * psi%a(3) - am * psi%a(4)) psikv%psi(3)%a(2) = (-imago) * (am * psi%a(3) + bp * psi%a(4)) psikv%psi(3)%a(3) = (-imago) * (bps * psi%a(1) + ap * psi%a(2)) psikv%psi(3)%a(4) = imago * ((-ap) * psi%a(1) + bm * psi%a(2)) psikv%psi(4)%a(1) = am * psi%a(3) + (-bms) * psi%a(4) psikv%psi(4)%a(2) = bp * psi%a(3) + am * psi%a(4) psikv%psi(4)%a(3) = ap * psi%a(1) + bps * psi%a(2) psikv%psi(4)%a(4) = (-bm) * psi%a(1) + ap * psi%a(2) end function grkkggf @ <>= pure function gr_vf (g, v, psi, k) result (psikv) type(vectorspinor) :: psikv type(bispinor), intent(in) :: psi type(vector), intent(in) :: v type(momentum), intent(in) :: k complex(kind=default), intent(in) :: g type(vector) :: vk vk = k psikv = g * (grkkggf (v, psi, vk)) end function gr_vf @ <>= pure function gr_vlrf (gl, gr, v, psi, k) result (psikv) type(vectorspinor) :: psikv type(bispinor), intent(in) :: psi type(bispinor) :: psi_l, psi_r type(vector), intent(in) :: v type(momentum), intent(in) :: k complex(kind=default), intent(in) :: gl, gr type(vector) :: vk vk = k psi_l%a(1:2) = psi%a(1:2) psi_l%a(3:4) = 0 psi_r%a(1:2) = 0 psi_r%a(3:4) = psi%a(3:4) psikv = gl * grkkggf (v, psi_l, vk) + gr * grkkggf (v, psi_r, vk) end function gr_vlrf @ <>= public :: v_grf, v_fgr @ <>= public :: vlr_grf, vlr_fgr @ $V^\mu = \psi_\rho^T C^{\mu\rho} \psi$ <>= pure function grkgggf (psil, psir, k) result (j) type(vector) :: j type(vectorspinor), intent(in) :: psil type(bispinor), intent(in) :: psir type(vector), intent(in) :: k type(vectorspinor) :: c_psir0, c_psir1, c_psir2, c_psir3 complex(kind=default) :: kp, km, k12, k12s, ik2 kp = k%t + k%x(3) km = k%t - k%x(3) k12 = (k%x(1) + (0,1)*k%x(2)) k12s = (k%x(1) - (0,1)*k%x(2)) ik2 = (0,1) * k%x(2) !!! New version: c_psir0%psi(1)%a(1) = (-k%x(3)) * psir%a(3) + (-k12s) * psir%a(4) c_psir0%psi(1)%a(2) = (-k12) * psir%a(3) + k%x(3) * psir%a(4) c_psir0%psi(1)%a(3) = (-k%x(3)) * psir%a(1) + (-k12s) * psir%a(2) c_psir0%psi(1)%a(4) = (-k12) * psir%a(1) + k%x(3) * psir%a(2) c_psir0%psi(2)%a(1) = (-k12s) * psir%a(3) + (-k%x(3)) * psir%a(4) c_psir0%psi(2)%a(2) = k%x(3) * psir%a(3) + (-k12) * psir%a(4) c_psir0%psi(2)%a(3) = k12s * psir%a(1) + k%x(3) * psir%a(2) c_psir0%psi(2)%a(4) = (-k%x(3)) * psir%a(1) + k12 * psir%a(2) c_psir0%psi(3)%a(1) = (0,1) * ((-k12s) * psir%a(3) + k%x(3) * psir%a(4)) c_psir0%psi(3)%a(2) = (0,1) * (k%x(3) * psir%a(3) + k12 * psir%a(4)) c_psir0%psi(3)%a(3) = (0,1) * (k12s * psir%a(1) + (-k%x(3)) * psir%a(2)) c_psir0%psi(3)%a(4) = (0,1) * ((-k%x(3)) * psir%a(1) + (-k12) * psir%a(2)) c_psir0%psi(4)%a(1) = (-k%x(3)) * psir%a(3) + k12s * psir%a(4) c_psir0%psi(4)%a(2) = (-k12) * psir%a(3) + (-k%x(3)) * psir%a(4) c_psir0%psi(4)%a(3) = k%x(3) * psir%a(1) + (-k12s) * psir%a(2) c_psir0%psi(4)%a(4) = k12 * psir%a(1) + k%x(3) * psir%a(2) !!! c_psir1%psi(1)%a(1) = (-ik2) * psir%a(3) + (-km) * psir%a(4) c_psir1%psi(1)%a(2) = (-kp) * psir%a(3) + ik2 * psir%a(4) c_psir1%psi(1)%a(3) = ik2 * psir%a(1) + (-kp) * psir%a(2) c_psir1%psi(1)%a(4) = (-km) * psir%a(1) + (-ik2) * psir%a(2) c_psir1%psi(2)%a(1) = (-km) * psir%a(3) + (-ik2) * psir%a(4) c_psir1%psi(2)%a(2) = ik2 * psir%a(3) + (-kp) * psir%a(4) c_psir1%psi(2)%a(3) = kp * psir%a(1) + (-ik2) * psir%a(2) c_psir1%psi(2)%a(4) = ik2 * psir%a(1) + km * psir%a(2) c_psir1%psi(3)%a(1) = ((0,-1) * km) * psir%a(3) + (-k%x(2)) * psir%a(4) c_psir1%psi(3)%a(2) = (-k%x(2)) * psir%a(3) + ((0,1) * kp) * psir%a(4) c_psir1%psi(3)%a(3) = ((0,1) * kp) * psir%a(1) + (-k%x(2)) * psir%a(2) c_psir1%psi(3)%a(4) = (-k%x(2)) * psir%a(1) + ((0,-1) * km) * psir%a(2) c_psir1%psi(4)%a(1) = (-ik2) * psir%a(3) + km * psir%a(4) c_psir1%psi(4)%a(2) = (-kp) * psir%a(3) + (-ik2) * psir%a(4) c_psir1%psi(4)%a(3) = (-ik2) * psir%a(1) + (-kp) * psir%a(2) c_psir1%psi(4)%a(4) = km * psir%a(1) + (-ik2) * psir%a(2) !!! c_psir2%psi(1)%a(1) = (0,1) * (k%x(1) * psir%a(3) + km * psir%a(4)) c_psir2%psi(1)%a(2) = (0,-1) * (kp * psir%a(3) + k%x(1) * psir%a(4)) c_psir2%psi(1)%a(3) = (0,1) * ((-k%x(1)) * psir%a(1) + kp * psir%a(2)) c_psir2%psi(1)%a(4) = (0,1) * ((-km) * psir%a(1) + k%x(1) * psir%a(2)) c_psir2%psi(2)%a(1) = (0,1) * (km * psir%a(3) + k%x(1) * psir%a(4)) c_psir2%psi(2)%a(2) = (0,-1) * (k%x(1) * psir%a(3) + kp * psir%a(4)) c_psir2%psi(2)%a(3) = (0,-1) * (kp * psir%a(1) + (-k%x(1)) * psir%a(2)) c_psir2%psi(2)%a(4) = (0,-1) * (k%x(1) * psir%a(1) + (-km) * psir%a(2)) c_psir2%psi(3)%a(1) = (-km) * psir%a(3) + k%x(1) * psir%a(4) c_psir2%psi(3)%a(2) = k%x(1) * psir%a(3) + (-kp) * psir%a(4) c_psir2%psi(3)%a(3) = kp * psir%a(1) + k%x(1) * psir%a(2) c_psir2%psi(3)%a(4) = k%x(1) * psir%a(1) + km * psir%a(2) c_psir2%psi(4)%a(1) = (0,1) * (k%x(1) * psir%a(3) + (-km) * psir%a(4)) c_psir2%psi(4)%a(2) = (0,1) * ((-kp) * psir%a(3) + k%x(1) * psir%a(4)) c_psir2%psi(4)%a(3) = (0,1) * (k%x(1) * psir%a(1) + kp * psir%a(2)) c_psir2%psi(4)%a(4) = (0,1) * (km * psir%a(1) + k%x(1) * psir%a(2)) !!! c_psir3%psi(1)%a(1) = (-k%t) * psir%a(3) - k12s * psir%a(4) c_psir3%psi(1)%a(2) = k12 * psir%a(3) + k%t * psir%a(4) c_psir3%psi(1)%a(3) = (-k%t) * psir%a(1) + k12s * psir%a(2) c_psir3%psi(1)%a(4) = (-k12) * psir%a(1) + k%t * psir%a(2) c_psir3%psi(2)%a(1) = (-k12s) * psir%a(3) + (-k%t) * psir%a(4) c_psir3%psi(2)%a(2) = k%t * psir%a(3) + k12 * psir%a(4) c_psir3%psi(2)%a(3) = (-k12s) * psir%a(1) + k%t * psir%a(2) c_psir3%psi(2)%a(4) = (-k%t) * psir%a(1) + k12 * psir%a(2) c_psir3%psi(3)%a(1) = (0,-1) * (k12s * psir%a(3) + (-k%t) * psir%a(4)) c_psir3%psi(3)%a(2) = (0,1) * (k%t * psir%a(3) + (-k12) * psir%a(4)) c_psir3%psi(3)%a(3) = (0,-1) * (k12s * psir%a(1) + k%t * psir%a(2)) c_psir3%psi(3)%a(4) = (0,-1) * (k%t * psir%a(1) + k12 * psir%a(2)) c_psir3%psi(4)%a(1) = (-k%t) * psir%a(3) + k12s * psir%a(4) c_psir3%psi(4)%a(2) = k12 * psir%a(3) + (-k%t) * psir%a(4) c_psir3%psi(4)%a(3) = k%t * psir%a(1) + k12s * psir%a(2) c_psir3%psi(4)%a(4) = k12 * psir%a(1) + k%t * psir%a(2) j%t = 2 * (psil * c_psir0) j%x(1) = 2 * (psil * c_psir1) j%x(2) = 2 * (psil * c_psir2) j%x(3) = 2 * (psil * c_psir3) end function grkgggf @ <>= pure function v_grf (g, psil, psir, k) result (j) type(vector) :: j complex(kind=default), intent(in) :: g type(vectorspinor), intent(in) :: psil type(bispinor), intent(in) :: psir type(momentum), intent(in) :: k type(vector) :: vk vk = k j = g * grkgggf (psil, psir, vk) end function v_grf @ <>= pure function vlr_grf (gl, gr, psil, psir, k) result (j) type(vector) :: j complex(kind=default), intent(in) :: gl, gr type(vectorspinor), intent(in) :: psil type(bispinor), intent(in) :: psir type(bispinor) :: psir_l, psir_r type(momentum), intent(in) :: k type(vector) :: vk vk = k psir_l%a(1:2) = psir%a(1:2) psir_l%a(3:4) = 0 psir_r%a(1:2) = 0 psir_r%a(3:4) = psir%a(3:4) j = gl * grkgggf (psil, psir_l, vk) + gr * grkgggf (psil, psir_r, vk) end function vlr_grf @ $V^\mu = \psi^T \tilde{C}^{\mu\rho} \psi_\rho$; remember the reversed index order in $\tilde{C}$. <>= pure function fggkggr (psil, psir, k) result (j) type(vector) :: j type(vectorspinor), intent(in) :: psir type(bispinor), intent(in) :: psil type(vector), intent(in) :: k type(bispinor) :: c_psir0, c_psir1, c_psir2, c_psir3 complex(kind=default) :: kp, km, k12, k12s, ik1, ik2 kp = k%t + k%x(3) km = k%t - k%x(3) k12 = k%x(1) + (0,1)*k%x(2) k12s = k%x(1) - (0,1)*k%x(2) ik1 = (0,1) * k%x(1) ik2 = (0,1) * k%x(2) c_psir0%a(1) = k%x(3) * (psir%psi(1)%a(4) + psir%psi(4)%a(4) & + psir%psi(2)%a(3) + (0,1) * psir%psi(3)%a(3)) & - k12 * (psir%psi(1)%a(3) + psir%psi(4)%a(3)) & + k12s * (psir%psi(2)%a(4) + (0,1) * psir%psi(3)%a(4)) c_psir0%a(2) = k%x(3) * (psir%psi(1)%a(3) - psir%psi(4)%a(3) + & psir%psi(2)%a(4) - (0,1) * psir%psi(3)%a(4)) + & k12s * (psir%psi(1)%a(4) - psir%psi(4)%a(4)) - & k12 * (psir%psi(2)%a(3) - (0,1) * psir%psi(3)%a(3)) c_psir0%a(3) = k%x(3) * (-psir%psi(1)%a(2) + psir%psi(4)%a(2) + & psir%psi(2)%a(1) + (0,1) * psir%psi(3)%a(1)) + & k12 * (psir%psi(1)%a(1) - psir%psi(4)%a(1)) + & k12s * (psir%psi(2)%a(2) + (0,1) * psir%psi(3)%a(2)) c_psir0%a(4) = k%x(3) * (-psir%psi(1)%a(1) - psir%psi(4)%a(1) + & psir%psi(2)%a(2) - (0,1) * psir%psi(3)%a(2)) - & k12s * (psir%psi(1)%a(2) + psir%psi(4)%a(2)) - & k12 * (psir%psi(2)%a(1) - (0,1) * psir%psi(3)%a(1)) !!! c_psir1%a(1) = ik2 * (-psir%psi(1)%a(4) - psir%psi(4)%a(4) - & psir%psi(2)%a(3) - (0,1) * psir%psi(3)%a(3)) - & km * (psir%psi(1)%a(3) + psir%psi(4)%a(3)) + & kp * (psir%psi(2)%a(4) + (0,1) * psir%psi(3)%a(4)) c_psir1%a(2) = ik2 * (-psir%psi(1)%a(3) - psir%psi(2)%a(4) + & psir%psi(4)%a(3) + (0,1) * psir%psi(3)%a(4)) + & kp * (psir%psi(1)%a(4) - psir%psi(4)%a(4)) - & km * (psir%psi(2)%a(3) - (0,1) * psir%psi(3)%a(3)) c_psir1%a(3) = ik2 * (-psir%psi(1)%a(2) + psir%psi(2)%a(1) + & psir%psi(4)%a(2) + (0,1) * psir%psi(3)%a(1)) + & kp * (psir%psi(1)%a(1) - psir%psi(4)%a(1)) + & km * (psir%psi(2)%a(2) + (0,1) * psir%psi(3)%a(2)) c_psir1%a(4) = ik2 * (-psir%psi(1)%a(1) + psir%psi(2)%a(2) - & psir%psi(4)%a(1) - (0,1) * psir%psi(3)%a(2)) - & km * (psir%psi(1)%a(2) + psir%psi(4)%a(2)) - & kp * (psir%psi(2)%a(1) - (0,1) * psir%psi(3)%a(1)) !!! c_psir2%a(1) = ik1 * (psir%psi(2)%a(3) + psir%psi(1)%a(4) & + psir%psi(4)%a(4) + (0,1) * psir%psi(3)%a(3)) - & ((0,1)*km) * (psir%psi(1)%a(3) + psir%psi(4)%a(3)) & + kp * (psir%psi(3)%a(4) - (0,1) * psir%psi(2)%a(4)) c_psir2%a(2) = ik1 * (psir%psi(1)%a(3) + psir%psi(2)%a(4) - & psir%psi(4)%a(3) - (0,1) * psir%psi(3)%a(4)) - & ((0,1)*kp) * (psir%psi(1)%a(4) - psir%psi(4)%a(4)) & - km * (psir%psi(3)%a(3) + (0,1) * psir%psi(2)%a(3)) c_psir2%a(3) = ik1 * (psir%psi(1)%a(2) - psir%psi(2)%a(1) - & psir%psi(4)%a(2) - (0,1) * psir%psi(3)%a(1)) + & ((0,1)*kp) * (psir%psi(1)%a(1) - psir%psi(4)%a(1)) & + km * (psir%psi(3)%a(2) - (0,1) * psir%psi(2)%a(2)) c_psir2%a(4) = ik1 * (psir%psi(1)%a(1) - psir%psi(2)%a(2) + & psir%psi(4)%a(1) + (0,1) * psir%psi(3)%a(2)) + & ((0,1)*km) * (psir%psi(1)%a(2) + psir%psi(4)%a(2)) - & kp * (psir%psi(3)%a(1) + (0,1) * psir%psi(2)%a(1)) !!! c_psir3%a(1) = k%t * (psir%psi(1)%a(4) + psir%psi(4)%a(4) + & psir%psi(2)%a(3) + (0,1) * psir%psi(3)%a(3)) - & k12 * (psir%psi(1)%a(3) + psir%psi(4)%a(3)) - & k12s * (psir%psi(2)%a(4) + (0,1) * psir%psi(3)%a(4)) c_psir3%a(2) = k%t * (psir%psi(1)%a(3) - psir%psi(4)%a(3) + & psir%psi(2)%a(4) - (0,1) * psir%psi(3)%a(4)) - & k12s * (psir%psi(1)%a(4) - psir%psi(4)%a(4)) - & k12 * (psir%psi(2)%a(3) - (0,1) * psir%psi(3)%a(3)) c_psir3%a(3) = k%t * (-psir%psi(1)%a(2) + psir%psi(2)%a(1) + & psir%psi(4)%a(2) + (0,1) * psir%psi(3)%a(1)) - & k12 * (psir%psi(1)%a(1) - psir%psi(4)%a(1)) + & k12s * (psir%psi(2)%a(2) + (0,1) * psir%psi(3)%a(2)) c_psir3%a(4) = k%t * (-psir%psi(1)%a(1) + psir%psi(2)%a(2) - & psir%psi(4)%a(1) - (0,1) * psir%psi(3)%a(2)) - & k12s * (psir%psi(1)%a(2) + psir%psi(4)%a(2)) + & k12 * (psir%psi(2)%a(1) - (0,1) * psir%psi(3)%a(1)) !!! Because we explicitly multiplied the charge conjugation matrix !!! we have to omit it from the spinor product and take the !!! ordinary product! j%t = 2 * dot_product (conjg (psil%a), c_psir0%a) j%x(1) = 2 * dot_product (conjg (psil%a), c_psir1%a) j%x(2) = 2 * dot_product (conjg (psil%a), c_psir2%a) j%x(3) = 2 * dot_product (conjg (psil%a), c_psir3%a) end function fggkggr @ <>= pure function v_fgr (g, psil, psir, k) result (j) type(vector) :: j complex(kind=default), intent(in) :: g type(vectorspinor), intent(in) :: psir type(bispinor), intent(in) :: psil type(momentum), intent(in) :: k type(vector) :: vk vk = k j = g * fggkggr (psil, psir, vk) end function v_fgr @ <>= pure function vlr_fgr (gl, gr, psil, psir, k) result (j) type(vector) :: j complex(kind=default), intent(in) :: gl, gr type(vectorspinor), intent(in) :: psir type(bispinor), intent(in) :: psil type(bispinor) :: psil_l type(bispinor) :: psil_r type(momentum), intent(in) :: k type(vector) :: vk vk = k psil_l%a(1:2) = psil%a(1:2) psil_l%a(3:4) = 0 psil_r%a(1:2) = 0 psil_r%a(3:4) = psil%a(3:4) j = gl * fggkggr (psil_l, psir, vk) + gr * fggkggr (psil_r, psir, vk) end function vlr_fgr @ \subsection{Gravitino 4-Couplings} <>= public :: f_s2gr, f_svgr, f_slvgr, f_srvgr, f_slrvgr, f_pvgr, f_v2gr, f_v2lrgr @ <>= pure function f_s2gr (g, phi1, phi2, psi) result (phipsi) type(bispinor) :: phipsi type(vectorspinor), intent(in) :: psi complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: phi1, phi2 phipsi = phi2 * f_potgr (g, phi1, psi) end function f_s2gr @ <>= pure function f_svgr (g, phi, v, grav) result (phigrav) type(bispinor) :: phigrav type(vectorspinor), intent(in) :: grav type(vector), intent(in) :: v complex(kind=default), intent(in) :: g, phi phigrav = (g * phi) * fgvg5gr (grav, v) end function f_svgr @ <>= pure function f_slvgr (gl, phi, v, grav) result (phigrav) type(bispinor) :: phigrav, phidum type(vectorspinor), intent(in) :: grav type(vector), intent(in) :: v complex(kind=default), intent(in) :: gl, phi phidum = (gl * phi) * fgvg5gr (grav, v) phigrav%a(1:2) = phidum%a(1:2) phigrav%a(3:4) = 0 end function f_slvgr @ <>= pure function f_srvgr (gr, phi, v, grav) result (phigrav) type(bispinor) :: phigrav, phidum type(vectorspinor), intent(in) :: grav type(vector), intent(in) :: v complex(kind=default), intent(in) :: gr, phi phidum = (gr * phi) * fgvg5gr (grav, v) phigrav%a(1:2) = 0 phigrav%a(3:4) = phidum%a(3:4) end function f_srvgr @ <>= pure function f_slrvgr (gl, gr, phi, v, grav) result (phigrav) type(bispinor) :: phigrav type(vectorspinor), intent(in) :: grav type(vector), intent(in) :: v complex(kind=default), intent(in) :: gl, gr, phi phigrav = f_slvgr (gl, phi, v, grav) + f_srvgr (gr, phi, v, grav) end function f_slrvgr @ <>= pure function f_pvgr (g, phi, v, grav) result (phigrav) type(bispinor) :: phigrav type(vectorspinor), intent(in) :: grav type(vector), intent(in) :: v complex(kind=default), intent(in) :: g, phi phigrav = (g * phi) * fgvgr (grav, v) end function f_pvgr @ <>= pure function f_v2gr (g, v1, v2, grav) result (psi) type(bispinor) :: psi complex(kind=default), intent(in) :: g type(vectorspinor), intent(in) :: grav type(vector), intent(in) :: v1, v2 psi = g * fggvvgr (v2, grav, v1) end function f_v2gr @ <>= pure function f_v2lrgr (gl, gr, v1, v2, grav) result (psi) type(bispinor) :: psi complex(kind=default), intent(in) :: gl, gr type(vectorspinor), intent(in) :: grav type(vector), intent(in) :: v1, v2 psi = fggvvgr (v2, grav, v1) psi%a(1:2) = gl * psi%a(1:2) psi%a(3:4) = gr * psi%a(3:4) end function f_v2lrgr @ <>= public :: gr_s2f, gr_svf, gr_pvf, gr_slvf, gr_srvf, gr_slrvf, gr_v2f, gr_v2lrf @ <>= pure function gr_s2f (g, phi1, phi2, psi) result (phipsi) type(vectorspinor) :: phipsi type(bispinor), intent(in) :: psi complex(kind=default), intent(in) :: g complex(kind=default), intent(in) :: phi1, phi2 phipsi = phi2 * gr_potf (g, phi1, psi) end function gr_s2f @ <>= pure function gr_svf (g, phi, v, psi) result (phipsi) type(vectorspinor) :: phipsi type(bispinor), intent(in) :: psi type(vector), intent(in) :: v complex(kind=default), intent(in) :: g, phi phipsi = (g * phi) * grkggf (psi, v) end function gr_svf @ <>= pure function gr_slvf (gl, phi, v, psi) result (phipsi) type(vectorspinor) :: phipsi type(bispinor), intent(in) :: psi type(bispinor) :: psi_l type(vector), intent(in) :: v complex(kind=default), intent(in) :: gl, phi psi_l%a(1:2) = psi%a(1:2) psi_l%a(3:4) = 0 phipsi = (gl * phi) * grkggf (psi_l, v) end function gr_slvf @ <>= pure function gr_srvf (gr, phi, v, psi) result (phipsi) type(vectorspinor) :: phipsi type(bispinor), intent(in) :: psi type(bispinor) :: psi_r type(vector), intent(in) :: v complex(kind=default), intent(in) :: gr, phi psi_r%a(1:2) = 0 psi_r%a(3:4) = psi%a(3:4) phipsi = (gr * phi) * grkggf (psi_r, v) end function gr_srvf @ <>= pure function gr_slrvf (gl, gr, phi, v, psi) result (phipsi) type(vectorspinor) :: phipsi type(bispinor), intent(in) :: psi type(vector), intent(in) :: v complex(kind=default), intent(in) :: gl, gr, phi phipsi = gr_slvf (gl, phi, v, psi) + gr_srvf (gr, phi, v, psi) end function gr_slrvf @ <>= pure function gr_pvf (g, phi, v, psi) result (phipsi) type(vectorspinor) :: phipsi type(bispinor), intent(in) :: psi type(vector), intent(in) :: v complex(kind=default), intent(in) :: g, phi phipsi = (g * phi) * grkgf (psi, v) end function gr_pvf @ <>= pure function gr_v2f (g, v1, v2, psi) result (vvpsi) type(vectorspinor) :: vvpsi complex(kind=default), intent(in) :: g type(bispinor), intent(in) :: psi type(vector), intent(in) :: v1, v2 vvpsi = g * grkkggf (v2, psi, v1) end function gr_v2f @ <>= pure function gr_v2lrf (gl, gr, v1, v2, psi) result (vvpsi) type(vectorspinor) :: vvpsi complex(kind=default), intent(in) :: gl, gr type(bispinor), intent(in) :: psi type(bispinor) :: psi_l, psi_r type(vector), intent(in) :: v1, v2 psi_l%a(1:2) = psi%a(1:2) psi_l%a(3:4) = 0 psi_r%a(1:2) = 0 psi_r%a(3:4) = psi%a(3:4) vvpsi = gl * grkkggf (v2, psi_l, v1) + gr * grkkggf (v2, psi_r, v1) end function gr_v2lrf @ <>= public :: s2_grf, s2_fgr, sv1_grf, sv2_grf, sv1_fgr, sv2_fgr, & slv1_grf, slv2_grf, slv1_fgr, slv2_fgr, & srv1_grf, srv2_grf, srv1_fgr, srv2_fgr, & slrv1_grf, slrv2_grf, slrv1_fgr, slrv2_fgr, & pv1_grf, pv2_grf, pv1_fgr, pv2_fgr, v2_grf, v2_fgr, & v2lr_grf, v2lr_fgr @ <>= pure function s2_grf (g, gravbar, phi, psi) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: g, phi type(vectorspinor), intent(in) :: gravbar type(bispinor), intent(in) :: psi j = phi * pot_grf (g, gravbar, psi) end function s2_grf @ <>= pure function s2_fgr (g, psibar, phi, grav) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: g, phi type(bispinor), intent(in) :: psibar type(vectorspinor), intent(in) :: grav j = phi * pot_fgr (g, psibar, grav) end function s2_fgr @ <>= pure function sv1_grf (g, gravbar, v, psi) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: g type(vectorspinor), intent(in) :: gravbar type(bispinor), intent(in) :: psi type(vector), intent(in) :: v j = g * grg5vgf (gravbar, psi, v) end function sv1_grf @ <>= pure function slv1_grf (gl, gravbar, v, psi) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gl type(vectorspinor), intent(in) :: gravbar type(bispinor), intent(in) :: psi type(bispinor) :: psi_l type(vector), intent(in) :: v psi_l%a(1:2) = psi%a(1:2) psi_l%a(3:4) = 0 j = gl * grg5vgf (gravbar, psi_l, v) end function slv1_grf @ <>= pure function srv1_grf (gr, gravbar, v, psi) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gr type(vectorspinor), intent(in) :: gravbar type(bispinor), intent(in) :: psi type(bispinor) :: psi_r type(vector), intent(in) :: v psi_r%a(1:2) = 0 psi_r%a(3:4) = psi%a(3:4) j = gr * grg5vgf (gravbar, psi_r, v) end function srv1_grf @ <>= pure function slrv1_grf (gl, gr, gravbar, v, psi) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gl, gr type(vectorspinor), intent(in) :: gravbar type(bispinor), intent(in) :: psi type(bispinor) :: psi_l, psi_r type(vector), intent(in) :: v psi_l%a(1:2) = psi%a(1:2) psi_l%a(3:4) = 0 psi_r%a(1:2) = 0 psi_r%a(3:4) = psi%a(3:4) j = gl * grg5vgf (gravbar, psi_l, v) + gr * grg5vgf (gravbar, psi_r, v) end function slrv1_grf @ \begin{subequations} \begin{align} C \gamma^0 \gamma^0 = - C \gamma^1 \gamma^1 = - C \gamma^2 \gamma^2 = C \gamma^3 \gamma^3 = C &= \begin{pmatrix} 0 & 1 & 0 & 0 \\ -1 & 0 & 0 & 0 \\ 0 & 0 & 0 & -1 \\ 0 & 0 & 1 & 0 \end{pmatrix} \\ C \gamma^0 \gamma^1 = - C \gamma^1 \gamma^0 &= \begin{pmatrix} -1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & -1 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} \\ C \gamma^0 \gamma^2 = - C \gamma^2 \gamma^0 &= \begin{pmatrix} -\ii & 0 & 0 & 0 \\ 0 & -\ii & 0 & 0 \\ 0 & 0 & -\ii & 0 \\ 0 & 0 & 0 & -\ii \end{pmatrix} \\ C \gamma^0 \gamma^3 = - C \gamma^3 \gamma^0 &= \begin{pmatrix} 0 & 1 & 0 & 0 \\ 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \end{pmatrix} \\ C \gamma^1 \gamma^2 = - C \gamma^2 \gamma^1 &= \begin{pmatrix} 0 & \ii & 0 & 0 \\ \ii & 0 & 0 & 0 \\ 0 & 0 & 0 & -\ii \\ 0 & 0 & -\ii & 0 \end{pmatrix} \\ C \gamma^1 \gamma^3 = - C \gamma^3 \gamma^1 &= \begin{pmatrix} -1 & 0 & 0 & 0 \\ 0 & -1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} \\ C \gamma^2 \gamma^3 = - C \gamma^3 \gamma^2 &= \begin{pmatrix} -\ii & 0 & 0 & 0 \\ 0 & \ii & 0 & 0 \\ 0 & 0 & \ii & 0 \\ 0 & 0 & 0 & -\ii \end{pmatrix} \end{align} \end{subequations} @ <>= pure function sv2_grf (g, gravbar, phi, psi) result (j) type(vector) :: j complex(kind=default), intent(in) :: g, phi type(vectorspinor), intent(in) :: gravbar type(bispinor), intent(in) :: psi type(vectorspinor) :: g0_psi, g1_psi, g2_psi, g3_psi g0_psi%psi(1)%a(1:2) = - psi%a(1:2) g0_psi%psi(1)%a(3:4) = psi%a(3:4) g0_psi%psi(2)%a(1) = psi%a(2) g0_psi%psi(2)%a(2) = psi%a(1) g0_psi%psi(2)%a(3) = psi%a(4) g0_psi%psi(2)%a(4) = psi%a(3) g0_psi%psi(3)%a(1) = (0,-1) * psi%a(2) g0_psi%psi(3)%a(2) = (0,1) * psi%a(1) g0_psi%psi(3)%a(3) = (0,-1) * psi%a(4) g0_psi%psi(3)%a(4) = (0,1) * psi%a(3) g0_psi%psi(4)%a(1) = psi%a(1) g0_psi%psi(4)%a(2) = - psi%a(2) g0_psi%psi(4)%a(3) = psi%a(3) g0_psi%psi(4)%a(4) = - psi%a(4) g1_psi%psi(1)%a(1:4) = - g0_psi%psi(2)%a(1:4) g1_psi%psi(2)%a(1:4) = - g0_psi%psi(1)%a(1:4) g1_psi%psi(3)%a(1) = (0,1) * psi%a(1) g1_psi%psi(3)%a(2) = (0,-1) * psi%a(2) g1_psi%psi(3)%a(3) = (0,-1) * psi%a(3) g1_psi%psi(3)%a(4) = (0,1) * psi%a(4) g1_psi%psi(4)%a(1) = - psi%a(2) g1_psi%psi(4)%a(2) = psi%a(1) g1_psi%psi(4)%a(3) = psi%a(4) g1_psi%psi(4)%a(4) = - psi%a(3) g2_psi%psi(1)%a(1:4) = - g0_psi%psi(3)%a(1:4) g2_psi%psi(2)%a(1:4) = - g1_psi%psi(3)%a(1:4) g2_psi%psi(3)%a(1:4) = - g0_psi%psi(1)%a(1:4) g2_psi%psi(4)%a(1) = (0,1) * psi%a(2) g2_psi%psi(4)%a(2) = (0,1) * psi%a(1) g2_psi%psi(4)%a(3) = (0,-1) * psi%a(4) g2_psi%psi(4)%a(4) = (0,-1) * psi%a(3) g3_psi%psi(1)%a(1:4) = - g0_psi%psi(4)%a(1:4) g3_psi%psi(2)%a(1:4) = - g1_psi%psi(4)%a(1:4) g3_psi%psi(3)%a(1:4) = - g2_psi%psi(4)%a(1:4) g3_psi%psi(4)%a(1:4) = - g0_psi%psi(1)%a(1:4) j%t = (g * phi) * (gravbar * g0_psi) j%x(1) = (g * phi) * (gravbar * g1_psi) j%x(2) = (g * phi) * (gravbar * g2_psi) j%x(3) = (g * phi) * (gravbar * g3_psi) end function sv2_grf @ <>= pure function slv2_grf (gl, gravbar, phi, psi) result (j) type(vector) :: j complex(kind=default), intent(in) :: gl, phi type(vectorspinor), intent(in) :: gravbar type(bispinor), intent(in) :: psi type(bispinor) :: psi_l psi_l%a(1:2) = psi%a(1:2) psi_l%a(3:4) = 0 j = sv2_grf (gl, gravbar, phi, psi_l) end function slv2_grf @ <>= pure function srv2_grf (gr, gravbar, phi, psi) result (j) type(vector) :: j complex(kind=default), intent(in) :: gr, phi type(vectorspinor), intent(in) :: gravbar type(bispinor), intent(in) :: psi type(bispinor) :: psi_r psi_r%a(1:2) = 0 psi_r%a(3:4) = psi%a(3:4) j = sv2_grf (gr, gravbar, phi, psi_r) end function srv2_grf @ <>= pure function slrv2_grf (gl, gr, gravbar, phi, psi) result (j) type(vector) :: j complex(kind=default), intent(in) :: gl, gr, phi type(vectorspinor), intent(in) :: gravbar type(bispinor), intent(in) :: psi type(bispinor) :: psi_l, psi_r psi_l%a(1:2) = psi%a(1:2) psi_l%a(3:4) = 0 psi_r%a(1:2) = 0 psi_r%a(3:4) = psi%a(3:4) j = sv2_grf (gl, gravbar, phi, psi_l) + sv2_grf (gr, gravbar, phi, psi_r) end function slrv2_grf @ <>= pure function sv1_fgr (g, psibar, v, grav) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: g type(bispinor), intent(in) :: psibar type(vectorspinor), intent(in) :: grav type(vector), intent(in) :: v j = g * fg5gkgr (psibar, grav, v) end function sv1_fgr @ <>= pure function slv1_fgr (gl, psibar, v, grav) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gl type(bispinor), intent(in) :: psibar type(bispinor) :: psibar_l type(vectorspinor), intent(in) :: grav type(vector), intent(in) :: v psibar_l%a(1:2) = psibar%a(1:2) psibar_l%a(3:4) = 0 j = gl * fg5gkgr (psibar_l, grav, v) end function slv1_fgr @ <>= pure function srv1_fgr (gr, psibar, v, grav) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gr type(bispinor), intent(in) :: psibar type(bispinor) :: psibar_r type(vectorspinor), intent(in) :: grav type(vector), intent(in) :: v psibar_r%a(1:2) = 0 psibar_r%a(3:4) = psibar%a(3:4) j = gr * fg5gkgr (psibar_r, grav, v) end function srv1_fgr @ <>= pure function slrv1_fgr (gl, gr, psibar, v, grav) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: gl, gr type(bispinor), intent(in) :: psibar type(bispinor) :: psibar_l, psibar_r type(vectorspinor), intent(in) :: grav type(vector), intent(in) :: v psibar_l%a(1:2) = psibar%a(1:2) psibar_l%a(3:4) = 0 psibar_r%a(1:2) = 0 psibar_r%a(3:4) = psibar%a(3:4) j = gl * fg5gkgr (psibar_l, grav, v) + gr * fg5gkgr (psibar_r, grav, v) end function slrv1_fgr @ <>= pure function sv2_fgr (g, psibar, phi, grav) result (j) type(vector) :: j complex(kind=default), intent(in) :: g, phi type(bispinor), intent(in) :: psibar type(vectorspinor), intent(in) :: grav type(bispinor) :: g0_grav, g1_grav, g2_grav, g3_grav g0_grav%a(1) = -grav%psi(1)%a(1) + grav%psi(2)%a(2) - & (0,1) * grav%psi(3)%a(2) + grav%psi(4)%a(1) g0_grav%a(2) = -grav%psi(1)%a(2) + grav%psi(2)%a(1) + & (0,1) * grav%psi(3)%a(1) - grav%psi(4)%a(2) g0_grav%a(3) = grav%psi(1)%a(3) + grav%psi(2)%a(4) - & (0,1) * grav%psi(3)%a(4) + grav%psi(4)%a(3) g0_grav%a(4) = grav%psi(1)%a(4) + grav%psi(2)%a(3) + & (0,1) * grav%psi(3)%a(3) - grav%psi(4)%a(4) !!! g1_grav%a(1) = grav%psi(1)%a(2) - grav%psi(2)%a(1) + & (0,1) * grav%psi(3)%a(1) - grav%psi(4)%a(2) g1_grav%a(2) = grav%psi(1)%a(1) - grav%psi(2)%a(2) - & (0,1) * grav%psi(3)%a(2) + grav%psi(4)%a(1) g1_grav%a(3) = grav%psi(1)%a(4) + grav%psi(2)%a(3) - & (0,1) * grav%psi(3)%a(3) + grav%psi(4)%a(4) g1_grav%a(4) = grav%psi(1)%a(3) + grav%psi(2)%a(4) + & (0,1) * grav%psi(3)%a(4) - grav%psi(4)%a(3) !!! g2_grav%a(1) = (0,1) * (-grav%psi(1)%a(2) - grav%psi(2)%a(1) + & grav%psi(4)%a(2)) - grav%psi(3)%a(1) g2_grav%a(2) = (0,1) * (grav%psi(1)%a(1) + grav%psi(2)%a(2) + & grav%psi(4)%a(1)) - grav%psi(3)%a(2) g2_grav%a(3) = (0,1) * (-grav%psi(1)%a(4) + grav%psi(2)%a(3) - & grav%psi(4)%a(4)) + grav%psi(3)%a(3) g2_grav%a(4) = (0,1) * (grav%psi(1)%a(3) - grav%psi(2)%a(4) - & grav%psi(4)%a(3)) + grav%psi(3)%a(4) !!! g3_grav%a(1) = -grav%psi(1)%a(2) + grav%psi(2)%a(2) - & (0,1) * grav%psi(3)%a(2) - grav%psi(4)%a(1) g3_grav%a(2) = grav%psi(1)%a(1) - grav%psi(2)%a(1) - & (0,1) * grav%psi(3)%a(1) - grav%psi(4)%a(2) g3_grav%a(3) = -grav%psi(1)%a(2) - grav%psi(2)%a(4) + & (0,1) * grav%psi(3)%a(4) + grav%psi(4)%a(3) g3_grav%a(4) = -grav%psi(1)%a(4) + grav%psi(2)%a(3) + & (0,1) * grav%psi(3)%a(3) + grav%psi(4)%a(4) j%t = (g * phi) * (psibar * g0_grav) j%x(1) = (g * phi) * (psibar * g1_grav) j%x(2) = (g * phi) * (psibar * g2_grav) j%x(3) = (g * phi) * (psibar * g3_grav) end function sv2_fgr @ <>= pure function slv2_fgr (gl, psibar, phi, grav) result (j) type(vector) :: j complex(kind=default), intent(in) :: gl, phi type(bispinor), intent(in) :: psibar type(bispinor) :: psibar_l type(vectorspinor), intent(in) :: grav psibar_l%a(1:2) = psibar%a(1:2) psibar_l%a(3:4) = 0 j = sv2_fgr (gl, psibar_l, phi, grav) end function slv2_fgr @ <>= pure function srv2_fgr (gr, psibar, phi, grav) result (j) type(vector) :: j complex(kind=default), intent(in) :: gr, phi type(bispinor), intent(in) :: psibar type(bispinor) :: psibar_r type(vectorspinor), intent(in) :: grav psibar_r%a(1:2) = 0 psibar_r%a(3:4) = psibar%a(3:4) j = sv2_fgr (gr, psibar_r, phi, grav) end function srv2_fgr @ <>= pure function slrv2_fgr (gl, gr, psibar, phi, grav) result (j) type(vector) :: j complex(kind=default), intent(in) :: gl, gr, phi type(bispinor), intent(in) :: psibar type(bispinor) :: psibar_l, psibar_r type(vectorspinor), intent(in) :: grav psibar_l%a(1:2) = psibar%a(1:2) psibar_l%a(3:4) = 0 psibar_r%a(1:2) = 0 psibar_r%a(3:4) = psibar%a(3:4) j = sv2_fgr (gl, psibar_l, phi, grav) + sv2_fgr (gr, psibar_r, phi, grav) end function slrv2_fgr @ <>= pure function pv1_grf (g, gravbar, v, psi) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: g type(vectorspinor), intent(in) :: gravbar type(bispinor), intent(in) :: psi type(vector), intent(in) :: v j = g * grvgf (gravbar, psi, v) end function pv1_grf @ <>= pure function pv2_grf (g, gravbar, phi, psi) result (j) type(vector) :: j complex(kind=default), intent(in) :: g, phi type(vectorspinor), intent(in) :: gravbar type(bispinor), intent(in) :: psi type(bispinor) :: g5_psi g5_psi%a(1:2) = - psi%a(1:2) g5_psi%a(3:4) = psi%a(3:4) j = sv2_grf (g, gravbar, phi, g5_psi) end function pv2_grf @ <>= pure function pv1_fgr (g, psibar, v, grav) result (j) complex(kind=default) :: j complex(kind=default), intent(in) :: g type(bispinor), intent(in) :: psibar type(vectorspinor), intent(in) :: grav type(vector), intent(in) :: v j = g * fgkgr (psibar, grav, v) end function pv1_fgr @ <>= pure function pv2_fgr (g, psibar, phi, grav) result (j) type(vector) :: j complex(kind=default), intent(in) :: g, phi type(vectorspinor), intent(in) :: grav type(bispinor), intent(in) :: psibar type(bispinor) :: psibar_g5 psibar_g5%a(1:2) = - psibar%a(1:2) psibar_g5%a(3:4) = psibar%a(3:4) j = sv2_fgr (g, psibar_g5, phi, grav) end function pv2_fgr @ <>= pure function v2_grf (g, gravbar, v, psi) result (j) type(vector) :: j complex(kind=default), intent(in) :: g type(vectorspinor), intent(in) :: gravbar type(bispinor), intent(in) :: psi type(vector), intent(in) :: v j = -g * grkgggf (gravbar, psi, v) end function v2_grf @ <>= pure function v2lr_grf (gl, gr, gravbar, v, psi) result (j) type(vector) :: j complex(kind=default), intent(in) :: gl, gr type(vectorspinor), intent(in) :: gravbar type(bispinor), intent(in) :: psi type(bispinor) :: psi_l, psi_r type(vector), intent(in) :: v psi_l%a(1:2) = psi%a(1:2) psi_l%a(3:4) = 0 psi_r%a(1:2) = 0 psi_r%a(3:4) = psi%a(3:4) j = -(gl * grkgggf (gravbar, psi_l, v) + gr * grkgggf (gravbar, psi_r, v)) end function v2lr_grf @ <>= pure function v2_fgr (g, psibar, v, grav) result (j) type(vector) :: j complex(kind=default), intent(in) :: g type(vectorspinor), intent(in) :: grav type(bispinor), intent(in) :: psibar type(vector), intent(in) :: v j = -g * fggkggr (psibar, grav, v) end function v2_fgr @ <>= pure function v2lr_fgr (gl, gr, psibar, v, grav) result (j) type(vector) :: j complex(kind=default), intent(in) :: gl, gr type(vectorspinor), intent(in) :: grav type(bispinor), intent(in) :: psibar type(bispinor) :: psibar_l, psibar_r type(vector), intent(in) :: v psibar_l%a(1:2) = psibar%a(1:2) psibar_l%a(3:4) = 0 psibar_r%a(1:2) = 0 psibar_r%a(3:4) = psibar%a(3:4) j = -(gl * fggkggr (psibar_l, grav, v) + gr * fggkggr (psibar_r, grav, v)) end function v2lr_fgr @ \subsection{On Shell Wave Functions} <>= public :: u, v, ghost @ \begin{subequations} \begin{align} \chi_+(\vec p) &= \frac{1}{\sqrt{2|\vec p|(|\vec p|+p_3)}} \begin{pmatrix} |\vec p|+p_3 \\ p_1 + \ii p_2 \end{pmatrix} \\ \chi_-(\vec p) &= \frac{1}{\sqrt{2|\vec p|(|\vec p|+p_3)}} \begin{pmatrix} - p_1 + \ii p_2 \\ |\vec p|+p_3 \end{pmatrix} \end{align} \end{subequations} @ \begin{equation} u_\pm(p) = \begin{pmatrix} \sqrt{p_0\mp|\vec p|} \cdot \chi_\pm(\vec p) \\ \sqrt{p_0\pm|\vec p|} \cdot \chi_\pm(\vec p) \end{pmatrix} \end{equation} <>= pure function u (mass, p, s) result (psi) type(bispinor) :: psi real(kind=default), intent(in) :: mass type(momentum), intent(in) :: p integer, intent(in) :: s complex(kind=default), dimension(2) :: chip, chim real(kind=default) :: pabs, norm, delta, m m = abs(mass) pabs = sqrt (dot_product (p%x, p%x)) if (m < epsilon (m) * pabs) then delta = 0 else delta = sqrt (max (p%t - pabs, 0._default)) end if if (pabs + p%x(3) <= 1000 * epsilon (pabs) * pabs) then chip = (/ cmplx ( 0.0, 0.0, kind=default), & cmplx ( 1.0, 0.0, kind=default) /) chim = (/ cmplx (-1.0, 0.0, kind=default), & cmplx ( 0.0, 0.0, kind=default) /) else norm = 1 / sqrt (2*pabs*(pabs + p%x(3))) chip = norm * (/ cmplx (pabs + p%x(3), kind=default), & cmplx (p%x(1), p%x(2), kind=default) /) chim = norm * (/ cmplx (-p%x(1), p%x(2), kind=default), & cmplx (pabs + p%x(3), kind=default) /) end if if (s > 0) then psi%a(1:2) = delta * chip psi%a(3:4) = sqrt (p%t + pabs) * chip else psi%a(1:2) = sqrt (p%t + pabs) * chim psi%a(3:4) = delta * chim end if pabs = m ! make the compiler happy and use m if (mass < 0) then psi%a(1:2) = - imago * psi%a(1:2) psi%a(3:4) = + imago * psi%a(3:4) end if end function u @ \begin{equation} v_\pm(p) = \begin{pmatrix} \mp\sqrt{p_0\pm|\vec p|} \cdot \chi_\mp(\vec p) \\ \pm\sqrt{p_0\mp|\vec p|} \cdot \chi_\mp(\vec p) \end{pmatrix} \end{equation} <>= pure function v (mass, p, s) result (psi) type(bispinor) :: psi real(kind=default), intent(in) :: mass type(momentum), intent(in) :: p integer, intent(in) :: s complex(kind=default), dimension(2) :: chip, chim real(kind=default) :: pabs, norm, delta, m pabs = sqrt (dot_product (p%x, p%x)) m = abs(mass) if (m < epsilon (m) * pabs) then delta = 0 else delta = sqrt (max (p%t - pabs, 0._default)) end if if (pabs + p%x(3) <= 1000 * epsilon (pabs) * pabs) then chip = (/ cmplx ( 0.0, 0.0, kind=default), & cmplx ( 1.0, 0.0, kind=default) /) chim = (/ cmplx (-1.0, 0.0, kind=default), & cmplx ( 0.0, 0.0, kind=default) /) else norm = 1 / sqrt (2*pabs*(pabs + p%x(3))) chip = norm * (/ cmplx (pabs + p%x(3), kind=default), & cmplx (p%x(1), p%x(2), kind=default) /) chim = norm * (/ cmplx (-p%x(1), p%x(2), kind=default), & cmplx (pabs + p%x(3), kind=default) /) end if if (s > 0) then psi%a(1:2) = - sqrt (p%t + pabs) * chim psi%a(3:4) = delta * chim else psi%a(1:2) = delta * chip psi%a(3:4) = - sqrt (p%t + pabs) * chip end if pabs = m ! make the compiler happy and use m if (mass < 0) then psi%a(1:2) = - imago * psi%a(1:2) psi%a(3:4) = + imago * psi%a(3:4) end if end function v @ <>= pure function ghost (m, p, s) result (psi) type(bispinor) :: psi real(kind=default), intent(in) :: m type(momentum), intent(in) :: p integer, intent(in) :: s psi%a(:) = 0 select case (s) case (1) psi%a(1) = 1 psi%a(2:4) = 0 case (2) psi%a(1) = 0 psi%a(2) = 1 psi%a(3:4) = 0 case (3) psi%a(1:2) = 0 psi%a(3) = 1 psi%a(4) = 0 case (4) psi%a(1:3) = 0 psi%a(4) = 1 case (5) psi%a(1) = 1.4 psi%a(2) = - 2.3 psi%a(3) = - 71.5 psi%a(4) = 0.1 end select end function ghost @ \subsection{Off Shell Wave Functions} This is the same as for the Dirac fermions except that the expressions for [ubar] and [vbar] are missing. <>= public :: brs_u, brs_v @ In momentum space we have: \begin{equation} brs u(p)=(-i) (\fmslash p-m)u(p) \end{equation} <>= pure function brs_u (m, p, s) result (dpsi) type(bispinor) :: dpsi, psi real(kind=default), intent(in) :: m type(momentum), intent(in) :: p integer, intent(in) :: s type (vector)::vp complex(kind=default), parameter :: one = (1, 0) vp=p psi=u(m,p,s) dpsi=cmplx(0.0,-1.0)*(f_vf(one,vp,psi)-m*psi) end function brs_u @ \begin{equation} brs v(p)=i (\fmslash p+m)v(p) \end{equation} <>= pure function brs_v (m, p, s) result (dpsi) type(bispinor) :: dpsi, psi real(kind=default), intent(in) :: m type(momentum), intent(in) :: p integer, intent(in) :: s type (vector)::vp complex(kind=default), parameter :: one = (1, 0) vp=p psi=v(m,p,s) dpsi=cmplx(0.0,1.0)*(f_vf(one,vp,psi)+m*psi) end function brs_v @ \subsection{Propagators} <>= public :: pr_psi, pr_grav public :: pj_psi, pg_psi @ \begin{equation} \frac{\ii(-\fmslash{p}+m)}{p^2-m^2+\ii m\Gamma}\psi \end{equation} NB: the sign of the momentum comes about because all momenta are treated as \emph{outgoing} and the particle charge flow is therefore opposite to the momentum. <>= pure function pr_psi (p, m, w, cms, psi) result (ppsi) type(bispinor) :: ppsi type(momentum), intent(in) :: p real(kind=default), intent(in) :: m, w type(bispinor), intent(in) :: psi logical, intent(in) :: cms type(vector) :: vp complex(kind=default), parameter :: one = (1, 0) complex(kind=default) :: num_mass vp = p if (cms) then num_mass = sqrt(cmplx(m**2, -m*w, kind=default)) else num_mass = cmplx (m, 0, kind=default) end if ppsi = (1 / cmplx (p*p - m**2, m*w, kind=default)) & * (- f_vf (one, vp, psi) + num_mass * psi) end function pr_psi @ \begin{equation} \sqrt{\frac{\pi}{M\Gamma}} (-\fmslash{p}+m)\psi \end{equation} <>= pure function pj_psi (p, m, w, psi) result (ppsi) type(bispinor) :: ppsi type(momentum), intent(in) :: p real(kind=default), intent(in) :: m, w type(bispinor), intent(in) :: psi type(vector) :: vp complex(kind=default), parameter :: one = (1, 0) vp = p ppsi = (0, -1) * sqrt (PI / m / w) * (- f_vf (one, vp, psi) + m * psi) end function pj_psi @ <>= pure function pg_psi (p, m, w, psi) result (ppsi) type(bispinor) :: ppsi type(momentum), intent(in) :: p real(kind=default), intent(in) :: m, w type(bispinor), intent(in) :: psi type(vector) :: vp complex(kind=default), parameter :: one = (1, 0) vp = p ppsi = gauss (p*p, m, w) * (- f_vf (one, vp, psi) + m * psi) end function pg_psi @ \begin{equation} \dfrac{\ii\biggl\{(-\fmslash{p} + m)\left(-\eta_{\mu\nu} + \dfrac{p_\mu p_\nu}{m^2}\right) + \dfrac{1}{3} \left(\gamma_\mu -\dfrac{p_\mu}{m}\right) (\fmslash{p} + m)\left(\gamma_\nu - \dfrac{p_\nu}{m}\right)\biggr\}}{p^2 - m^2 + \ii m \Gamma} \; \psi^\nu \end{equation} <>= pure function pr_grav (p, m, w, grav) result (propgrav) type(vectorspinor) :: propgrav type(momentum), intent(in) :: p real(kind=default), intent(in) :: m, w type(vectorspinor), intent(in) :: grav type(vector) :: vp type(bispinor) :: pgrav, ggrav, ggrav1, ggrav2, ppgrav type(vectorspinor) :: etagrav_dum, etagrav, pppgrav, & gg_grav_dum, gg_grav complex(kind=default), parameter :: one = (1, 0) real(kind=default) :: minv integer :: i vp = p minv = 1/m pgrav = p%t * grav%psi(1) - p%x(1) * grav%psi(2) - & p%x(2) * grav%psi(3) - p%x(3) * grav%psi(4) ggrav%a(1) = grav%psi(1)%a(3) - grav%psi(2)%a(4) + (0,1) * & grav%psi(3)%a(4) - grav%psi(4)%a(3) ggrav%a(2) = grav%psi(1)%a(4) - grav%psi(2)%a(3) - (0,1) * & grav%psi(3)%a(3) + grav%psi(4)%a(4) ggrav%a(3) = grav%psi(1)%a(1) + grav%psi(2)%a(2) - (0,1) * & grav%psi(3)%a(2) + grav%psi(4)%a(1) ggrav%a(4) = grav%psi(1)%a(2) + grav%psi(2)%a(1) + (0,1) * & grav%psi(3)%a(1) - grav%psi(4)%a(2) ggrav1 = ggrav - minv * pgrav ggrav2 = f_vf (one, vp, ggrav1) + m * ggrav - pgrav ppgrav = (-minv**2) * f_vf (one, vp, pgrav) + minv * pgrav do i = 1, 4 etagrav_dum%psi(i) = f_vf (one, vp, grav%psi(i)) end do etagrav = etagrav_dum - m * grav pppgrav%psi(1) = p%t * ppgrav pppgrav%psi(2) = p%x(1) * ppgrav pppgrav%psi(3) = p%x(2) * ppgrav pppgrav%psi(4) = p%x(3) * ppgrav gg_grav_dum%psi(1) = p%t * ggrav2 gg_grav_dum%psi(2) = p%x(1) * ggrav2 gg_grav_dum%psi(3) = p%x(2) * ggrav2 gg_grav_dum%psi(4) = p%x(3) * ggrav2 gg_grav = gr_potf (one, one, ggrav2) - minv * gg_grav_dum propgrav = (1 / cmplx (p*p - m**2, m*w, kind=default)) * & (etagrav + pppgrav + (1/3.0_default) * gg_grav) end function pr_grav @ \section{Polarization vectorspinors} Here we construct the wavefunctions for (massive) gravitinos out of the wavefunctions of (massive) vectorbosons and (massive) Majorana fermions. \begin{subequations} \begin{align} \psi^\mu_{(u; 3/2)} (k) &= \; \epsilon^\mu_+ (k) \cdot u (k, +) \\ \psi^\mu_{(u; 1/2)} (k) &= \; \sqrt{\dfrac{1}{3}} \, \epsilon^\mu_+ (k) \cdot u (k, -) + \sqrt{\dfrac{2}{3}} \, \epsilon^\mu_0 (k) \cdot u (k, +) \\ \psi^\mu_{(u; -1/2)} (k) &= \; \sqrt{\dfrac{2}{3}} \, \epsilon^\mu_0 (k) \cdot u (k, -) + \sqrt{\dfrac{1}{3}} \, \epsilon^\mu_- (k) \cdot u (k, +) \\ \psi^\mu_{(u; -3/2)} (k) &= \; \epsilon^\mu_- (k) \cdot u (k, -) \end{align} \end{subequations} and in the same manner for $\psi^\mu_{(v; s)}$ with $u$ replaced by $v$ and with the conjugated polarization vectors. These gravitino wavefunctions obey the Dirac equation, they are transverse and they fulfill the irreducibility condition \begin{equation} \gamma_\mu \psi^\mu_{(u/v; s)} = 0 . \end{equation} <<[[omega_vspinor_polarizations.f90]]>>= <> module omega_vspinor_polarizations use kinds use constants use omega_vectors use omega_bispinors use omega_bispinor_couplings use omega_vectorspinors implicit none <> integer, parameter, public :: omega_vspinor_pols_2010_01_A = 0 contains <> end module omega_vspinor_polarizations @ <>= public :: ueps, veps private :: eps private :: outer_product @ Here we implement the polarization vectors for vectorbosons with trigonometric functions, without the rotating of components done in HELAS~\cite{HELAS}. These are only used for generating the polarization vectorspinors. \begin{subequations} \begin{align} \epsilon^\mu_+(k) &= \frac{- e^{+\ii\phi}}{\sqrt{2}} \left(0; \cos\theta\cos\phi - \ii\sin\phi, \cos\theta\sin\phi + \ii\cos\phi, -\sin\theta \right) \\ \epsilon^\mu_-(k) &= \frac{e^{-\ii\phi}}{\sqrt{2}} \left(0; \cos\theta\cos\phi + \ii \sin\phi, \cos\theta\sin\phi - \ii \cos\phi, - \sin\theta \right) \\ \epsilon^\mu_0(k) &= \frac{1}{m} \left(|\vec k|; k^0\sin\theta\cos\phi, k^0\sin\theta\sin\phi, k^0\cos\theta\right) \end{align} \end{subequations} Determining the mass from the momenta is a numerically haphazardous for light particles. Therefore, we accept some redundancy and pass the mass explicitely. For the case that the momentum lies totally in the $z$-direction we take the convention $\cos\phi=1$ and $\sin\phi=0$. <>= pure function eps (mass, k, s) result (e) type(vector) :: e real(kind=default), intent(in) :: mass type(momentum), intent(in) :: k integer, intent(in) :: s real(kind=default) :: kabs, kabs2, sqrt2, m real(kind=default) :: cos_phi, sin_phi, cos_th, sin_th complex(kind=default) :: epiphi, emiphi sqrt2 = sqrt (2.0_default) kabs2 = dot_product (k%x, k%x) m = abs(mass) if (kabs2 > 0) then kabs = sqrt (kabs2) if ((k%x(1) == 0) .and. (k%x(2) == 0)) then cos_phi = 1 sin_phi = 0 else cos_phi = k%x(1) / sqrt(k%x(1)**2 + k%x(2)**2) sin_phi = k%x(2) / sqrt(k%x(1)**2 + k%x(2)**2) end if cos_th = k%x(3) / kabs sin_th = sqrt(1 - cos_th**2) epiphi = cos_phi + (0,1) * sin_phi emiphi = cos_phi - (0,1) * sin_phi e%t = 0 e%x = 0 select case (s) case (1) e%x(1) = epiphi * (-cos_th * cos_phi + (0,1) * sin_phi) / sqrt2 e%x(2) = epiphi * (-cos_th * sin_phi - (0,1) * cos_phi) / sqrt2 e%x(3) = epiphi * ( sin_th / sqrt2) case (-1) e%x(1) = emiphi * ( cos_th * cos_phi + (0,1) * sin_phi) / sqrt2 e%x(2) = emiphi * ( cos_th * sin_phi - (0,1) * cos_phi) / sqrt2 e%x(3) = emiphi * (-sin_th / sqrt2) case (0) if (m > 0) then e%t = kabs / m e%x = k%t / (m*kabs) * k%x end if case (4) if (m > 0) then e = (1 / m) * k else e = (1 / k%t) * k end if end select else !!! for particles in their rest frame defined to be !!! polarized along the 3-direction e%t = 0 e%x = 0 select case (s) case (1) e%x(1) = cmplx ( - 1, 0, kind=default) / sqrt2 e%x(2) = cmplx ( 0, 1, kind=default) / sqrt2 case (-1) e%x(1) = cmplx ( 1, 0, kind=default) / sqrt2 e%x(2) = cmplx ( 0, 1, kind=default) / sqrt2 case (0) if (m > 0) then e%x(3) = 1 end if case (4) if (m > 0) then e = (1 / m) * k else e = (1 / k%t) * k end if end select end if end function eps @ <>= pure function ueps (m, k, s) result (t) type(vectorspinor) :: t real(kind=default), intent(in) :: m type(momentum), intent(in) :: k integer, intent(in) :: s integer :: i type(vector) :: ep, e0, em type(bispinor) :: up, um do i = 1, 4 t%psi(i)%a = 0 end do select case (s) case (2) ep = eps (m, k, 1) up = u (m, k, 1) t = outer_product (ep, up) case (1) ep = eps (m, k, 1) e0 = eps (m, k, 0) up = u (m, k, 1) um = u (m, k, -1) t = (1 / sqrt (3.0_default)) * (outer_product (ep, um) & + sqrt (2.0_default) * outer_product (e0, up)) case (-1) e0 = eps (m, k, 0) em = eps (m, k, -1) up = u (m, k, 1) um = u (m, k, -1) t = (1 / sqrt (3.0_default)) * (sqrt (2.0_default) * & outer_product (e0, um) + outer_product (em, up)) case (-2) em = eps (m, k, -1) um = u (m, k, -1) t = outer_product (em, um) end select end function ueps @ <>= pure function veps (m, k, s) result (t) type(vectorspinor) :: t real(kind=default), intent(in) :: m type(momentum), intent(in) :: k integer, intent(in) :: s integer :: i type(vector) :: ep, e0, em type(bispinor) :: vp, vm do i = 1, 4 t%psi(i)%a = 0 end do select case (s) case (2) ep = conjg(eps (m, k, 1)) vp = v (m, k, 1) t = outer_product (ep, vp) case (1) ep = conjg(eps (m, k, 1)) e0 = conjg(eps (m, k, 0)) vp = v (m, k, 1) vm = v (m, k, -1) t = (1 / sqrt (3.0_default)) * (outer_product (ep, vm) & + sqrt (2.0_default) * outer_product (e0, vp)) case (-1) e0 = conjg(eps (m, k, 0)) em = conjg(eps (m, k, -1)) vp = v (m, k, 1) vm = v (m, k, -1) t = (1 / sqrt (3.0_default)) * (sqrt (2.0_default) & * outer_product (e0, vm) + outer_product (em, vp)) case (-2) em = conjg(eps (m, k, -1)) vm = v (m, k, -1) t = outer_product (em, vm) end select end function veps @ <>= pure function outer_product (ve, sp) result (vs) type(vectorspinor) :: vs type(vector), intent(in) :: ve type(bispinor), intent(in) :: sp integer :: i vs%psi(1)%a(1:4) = ve%t * sp%a(1:4) do i = 1, 3 vs%psi((i+1))%a(1:4) = ve%x(i) * sp%a(1:4) end do end function outer_product @ \section{Color} <<[[omega_color.f90]]>>= <> module omega_color use kinds implicit none private <> <> integer, parameter, public :: omega_color_2010_01_A = 0 contains <> end module omega_color @ \subsection{Color Sum} <>= public :: omega_color_factor type omega_color_factor integer :: i1, i2 real(kind=default) :: factor end type omega_color_factor @ <>= public :: omega_color_sum @ The [[!$omp]] instruction will result in parallel code if compiled with support for OpenMP otherwise it is ignored. @ <>= <<[[pure]] unless OpenMP>> function omega_color_sum (flv, hel, amp, cf) result (amp2) complex(kind=default) :: amp2 integer, intent(in) :: flv, hel complex(kind=default), dimension(:,:,:), intent(in) :: amp type(omega_color_factor), dimension(:), intent(in) :: cf integer :: n amp2 = 0 !$omp parallel do reduction(+:amp2) do n = 1, size (cf) amp2 = amp2 + cf(n)%factor * & amp(flv,cf(n)%i1,hel) * conjg (amp(flv,cf(n)%i2,hel)) end do !$omp end parallel do end function omega_color_sum @ In the bytecode for the OVM, we only save the symmetric part of the color factor table. This almost halves the size of $n$ gluon amplitudes for $n>6$. For $2\,\to\,(5,6)\,g$ the reduced color factor table still amounts for $\sim(75,93)\%$ of the bytecode, making it desirable to omit it completely by computing it dynamically to reduce memory requirements. Note that $2\text{Re}(A_{i_1}A_{i_2}^*)=A_{i_1}A_{i_2}^*+A_{i_2}A_{i_1}^*$. <>= public :: ovm_color_sum @ <>= <<[[pure]] unless OpenMP>> function ovm_color_sum (flv, hel, amp, cf) result (amp2) real(kind=default) :: amp2 integer, intent(in) :: flv, hel complex(kind=default), dimension(:,:,:), intent(in) :: amp type(omega_color_factor), dimension(:), intent(in) :: cf integer :: n amp2 = 0 !$omp parallel do reduction(+:amp2) do n = 1, size (cf) if (cf(n)%i1 == cf(n)%i2) then amp2 = amp2 + cf(n)%factor * & real(amp(flv,cf(n)%i1,hel) * conjg(amp(flv,cf(n)%i2,hel))) else amp2 = amp2 + cf(n)%factor * 2 * & real(amp(flv,cf(n)%i1,hel) * conjg(amp(flv,cf(n)%i2,hel))) end if end do !$omp end parallel do end function ovm_color_sum @ \section{Utilities} <<[[omega_utils.f90]]>>= <> module omega_utils use kinds use omega_vectors use omega_polarizations implicit none private <> <> integer, parameter, public :: omega_utils_2010_01_A = 0 contains <> end module omega_utils @ \subsection{Helicity Selection Rule Heuristics} <>= public :: omega_update_helicity_selection @ <>= pure subroutine omega_update_helicity_selection & (count, amp, max_abs, sum_abs, mask, threshold, cutoff, mask_dirty) integer, intent(inout) :: count complex(kind=default), dimension(:,:,:), intent(in) :: amp real(kind=default), dimension(:), intent(inout) :: max_abs real(kind=default), intent(inout) :: sum_abs logical, dimension(:), intent(inout) :: mask real(kind=default), intent(in) :: threshold integer, intent(in) :: cutoff logical, intent(out) :: mask_dirty integer :: h real(kind=default) :: avg mask_dirty = .false. if (threshold > 0) then count = count + 1 if (count <= cutoff) then forall (h = lbound (amp, 3) : ubound (amp, 3)) max_abs(h) = max (max_abs(h), maxval (abs (amp(:,:,h)))) end forall sum_abs = sum_abs + sum (abs (amp)) if (count == cutoff) then avg = sum_abs / size (amp) / cutoff mask = max_abs >= threshold * epsilon (avg) * avg mask_dirty = .true. end if end if end if end subroutine omega_update_helicity_selection @ \subsection{Diagnostics} <>= public :: omega_report_helicity_selection @ We shoul try to use [[msg_message]] from WHIZARD's [[diagnostics]] module, but this would spoil independent builds. <>= subroutine omega_report_helicity_selection (mask, spin_states, threshold, unit) logical, dimension(:), intent(in) :: mask integer, dimension(:,:), intent(in) :: spin_states real(kind=default), intent(in) :: threshold integer, intent(in), optional :: unit integer :: u integer :: h, i if (present(unit)) then u = unit else u = 6 end if if (u >= 0) then write (unit = u, & fmt = "('| ','Contributing Helicity Combinations: ', I5, ' of ', I5)") & count (mask), size (mask) write (unit = u, & fmt = "('| ','Threshold: amp / avg > ', E9.2, ' = ', E9.2, ' * epsilon()')") & threshold * epsilon (threshold), threshold i = 0 do h = 1, size (mask) if (mask(h)) then i = i + 1 write (unit = u, fmt = "('| ',I4,': ',20I4)") i, spin_states (:, h) end if end do end if end subroutine omega_report_helicity_selection @ <>= public :: omega_ward_warn, omega_ward_panic @ The O'Mega amplitudes have only one particle off shell and are the sum of \emph{all} possible diagrams with the other particles on-shell. \begin{dubious} The problem with these gauge checks is that are numerically very small amplitudes that vanish analytically and that violate transversality. The hard part is to determine the thresholds that make threse tests usable. \end{dubious} <>= subroutine omega_ward_warn (name, m, k, e) character(len=*), intent(in) :: name real(kind=default), intent(in) :: m type(momentum), intent(in) :: k type(vector), intent(in) :: e type(vector) :: ek real(kind=default) :: abs_eke, abs_ek_abs_e ek = eps (m, k, 4) abs_eke = abs (ek * e) abs_ek_abs_e = abs (ek) * abs (e) print *, name, ":", abs_eke / abs_ek_abs_e, abs (ek), abs (e) if (abs_eke > 1000 * epsilon (abs_ek_abs_e)) then print *, "O'Mega: warning: non-transverse vector field: ", & name, ":", abs_eke / abs_ek_abs_e, abs (e) end if end subroutine omega_ward_warn @ <>= subroutine omega_ward_panic (name, m, k, e) character(len=*), intent(in) :: name real(kind=default), intent(in) :: m type(momentum), intent(in) :: k type(vector), intent(in) :: e type(vector) :: ek real(kind=default) :: abs_eke, abs_ek_abs_e ek = eps (m, k, 4) abs_eke = abs (ek * e) abs_ek_abs_e = abs (ek) * abs (e) if (abs_eke > 1000 * epsilon (abs_ek_abs_e)) then print *, "O'Mega: panic: non-transverse vector field: ", & name, ":", abs_eke / abs_ek_abs_e, abs (e) stop end if end subroutine omega_ward_panic @ <>= public :: omega_slavnov_warn, omega_slavnov_panic @ <>= subroutine omega_slavnov_warn (name, m, k, e, phi) character(len=*), intent(in) :: name real(kind=default), intent(in) :: m type(momentum), intent(in) :: k type(vector), intent(in) :: e complex(kind=default), intent(in) :: phi type(vector) :: ek real(kind=default) :: abs_eke, abs_ek_abs_e ek = eps (m, k, 4) abs_eke = abs (ek * e - phi) abs_ek_abs_e = abs (ek) * abs (e) print *, name, ":", abs_eke / abs_ek_abs_e, abs (ek), abs (e) if (abs_eke > 1000 * epsilon (abs_ek_abs_e)) then print *, "O'Mega: warning: non-transverse vector field: ", & name, ":", abs_eke / abs_ek_abs_e, abs (e) end if end subroutine omega_slavnov_warn @ <>= subroutine omega_slavnov_panic (name, m, k, e, phi) character(len=*), intent(in) :: name real(kind=default), intent(in) :: m type(momentum), intent(in) :: k type(vector), intent(in) :: e complex(kind=default), intent(in) :: phi type(vector) :: ek real(kind=default) :: abs_eke, abs_ek_abs_e ek = eps (m, k, 4) abs_eke = abs (ek * e - phi) abs_ek_abs_e = abs (ek) * abs (e) if (abs_eke > 1000 * epsilon (abs_ek_abs_e)) then print *, "O'Mega: panic: non-transverse vector field: ", & name, ":", abs_eke / abs_ek_abs_e, abs (e) stop end if end subroutine omega_slavnov_panic @ <>= public :: omega_check_arguments_warn, omega_check_arguments_panic @ <>= subroutine omega_check_arguments_warn (n, k) integer, intent(in) :: n real(kind=default), dimension(0:,:), intent(in) :: k integer :: i i = size(k,dim=1) if (i /= 4) then print *, "O'Mega: warning: wrong # of dimensions:", i end if i = size(k,dim=2) if (i /= n) then print *, "O'Mega: warning: wrong # of momenta:", i, & ", expected", n end if end subroutine omega_check_arguments_warn @ <>= subroutine omega_check_arguments_panic (n, k) integer, intent(in) :: n real(kind=default), dimension(0:,:), intent(in) :: k logical :: error integer :: i error = .false. i = size(k,dim=1) if (i /= n) then print *, "O'Mega: warning: wrong # of dimensions:", i error = .true. end if i = size(k,dim=2) if (i /= n) then print *, "O'Mega: warning: wrong # of momenta:", i, & ", expected", n error = .true. end if if (error) then stop end if end subroutine omega_check_arguments_panic @ <>= public :: omega_check_helicities_warn, omega_check_helicities_panic private :: omega_check_helicity @ <>= function omega_check_helicity (m, smax, s) result (error) real(kind=default), intent(in) :: m integer, intent(in) :: smax, s logical :: error select case (smax) case (0) error = (s /= 0) case (1) error = (abs (s) /= 1) case (2) if (m == 0.0_default) then error = .not. (abs (s) == 1 .or. abs (s) == 4) else error = .not. (abs (s) <= 1 .or. abs (s) == 4) end if case (4) error = .true. case default error = .true. end select end function omega_check_helicity @ <>= subroutine omega_check_helicities_warn (m, smax, s) real(kind=default), dimension(:), intent(in) :: m integer, dimension(:), intent(in) :: smax, s integer :: i do i = 1, size (m) if (omega_check_helicity (m(i), smax(i), s(i))) then print *, "O'Mega: warning: invalid helicity", s(i) end if end do end subroutine omega_check_helicities_warn @ <>= subroutine omega_check_helicities_panic (m, smax, s) real(kind=default), dimension(:), intent(in) :: m integer, dimension(:), intent(in) :: smax, s logical :: error logical :: error1 integer :: i error = .false. do i = 1, size (m) error1 = omega_check_helicity (m(i), smax(i), s(i)) if (error1) then print *, "O'Mega: panic: invalid helicity", s(i) error = .true. end if end do if (error) then stop end if end subroutine omega_check_helicities_panic @ <>= public :: omega_check_momenta_warn, omega_check_momenta_panic private :: check_momentum_conservation, check_mass_shell @ <>= integer, parameter, private :: MOMENTUM_TOLERANCE = 10000 @ <>= function check_momentum_conservation (k) result (error) real(kind=default), dimension(0:,:), intent(in) :: k logical :: error error = any (abs (sum (k(:,3:), dim = 2) - k(:,1) - k(:,2)) > & MOMENTUM_TOLERANCE * epsilon (maxval (abs (k), dim = 2))) if (error) then print *, sum (k(:,3:), dim = 2) - k(:,1) - k(:,2) print *, MOMENTUM_TOLERANCE * epsilon (maxval (abs (k), dim = 2)), & maxval (abs (k), dim = 2) end if end function check_momentum_conservation @ <>= integer, parameter, private :: ON_SHELL_TOLERANCE = 1000000 @ <>= function check_mass_shell (m, k) result (error) real(kind=default), intent(in) :: m real(kind=default), dimension(0:), intent(in) :: k real(kind=default) :: e2 logical :: error e2 = k(1)**2 + k(2)**2 + k(3)**2 + m**2 error = abs (k(0)**2 - e2) > ON_SHELL_TOLERANCE * epsilon (max (k(0)**2, e2)) if (error) then print *, k(0)**2 - e2 print *, ON_SHELL_TOLERANCE * epsilon (max (k(0)**2, e2)), max (k(0)**2, e2) end if end function check_mass_shell @ <>= subroutine omega_check_momenta_warn (m, k) real(kind=default), dimension(:), intent(in) :: m real(kind=default), dimension(0:,:), intent(in) :: k integer :: i if (check_momentum_conservation (k)) then print *, "O'Mega: warning: momentum not conserved" end if do i = 1, size(m) if (check_mass_shell (m(i), k(:,i))) then print *, "O'Mega: warning: particle #", i, "not on-shell" end if end do end subroutine omega_check_momenta_warn @ <>= subroutine omega_check_momenta_panic (m, k) real(kind=default), dimension(:), intent(in) :: m real(kind=default), dimension(0:,:), intent(in) :: k logical :: error logical :: error1 integer :: i error = check_momentum_conservation (k) if (error) then print *, "O'Mega: panic: momentum not conserved" end if do i = 1, size(m) error1 = check_mass_shell (m(i), k(0:,i)) if (error1) then print *, "O'Mega: panic: particle #", i, "not on-shell" error = .true. end if end do if (error) then stop end if end subroutine omega_check_momenta_panic @ \subsection{Obsolete Summation} \subsubsection{Spin/Helicity Summation} <>= public :: omega_sum, omega_sum_nonzero, omega_nonzero private :: state_index @ <>= pure function omega_sum (omega, p, states, fixed) result (sigma) real(kind=default) :: sigma real(kind=default), dimension(0:,:), intent(in) :: p integer, dimension(:), intent(in), optional :: states, fixed <<[[interface]] for O'Mega Amplitude>> integer, dimension(size(p,dim=2)) :: s, nstates integer :: j complex(kind=default) :: a if (present (states)) then nstates = states else nstates = 2 end if sigma = 0 s = -1 sum_spins: do if (present (fixed)) then !!! print *, 's = ', s, ', fixed = ', fixed, ', nstates = ', nstates, & !!! ', fixed|s = ', merge (fixed, s, mask = nstates == 0) a = omega (p, merge (fixed, s, mask = nstates == 0)) else a = omega (p, s) end if sigma = sigma + a * conjg(a) <> end do sum_spins sigma = sigma / num_states (2, nstates(1:2)) end function omega_sum @ We're looping over all spins like a $n$-ary numbers $(-1,\ldots,-1,-1)$, $(-1,\ldots,-1,0)$, $(-1,\ldots,-1,1)$, $(-1,\ldots,0,-1)$, \ldots, $(1,\ldots,1,0)$, $(1,\ldots,1,1)$: <>= do j = size (p, dim = 2), 1, -1 select case (nstates (j)) case (3) ! massive vectors s(j) = modulo (s(j) + 2, 3) - 1 case (2) ! spinors, massless vectors s(j) = - s(j) case (1) ! scalars s(j) = -1 case (0) ! fized spin s(j) = -1 case default ! ??? s(j) = -1 end select if (s(j) /= -1) then cycle sum_spins end if end do exit sum_spins @ The dual operation evaluates an $n$-number: <>= pure function state_index (s, states) result (n) integer, dimension(:), intent(in) :: s integer, dimension(:), intent(in), optional :: states integer :: n integer :: j, p n = 1 p = 1 if (present (states)) then do j = size (s), 1, -1 select case (states(j)) case (3) n = n + p * (s(j) + 1) case (2) n = n + p * (s(j) + 1) / 2 end select p = p * states(j) end do else do j = size (s), 1, -1 n = n + p * (s(j) + 1) / 2 p = p * 2 end do end if end function state_index @ <<[[interface]] for O'Mega Amplitude>>= interface pure function omega (p, s) result (me) use kinds implicit none complex(kind=default) :: me real(kind=default), dimension(0:,:), intent(in) :: p integer, dimension(:), intent(in) :: s end function omega end interface @ <>= public :: num_states @ <>= pure function num_states (n, states) result (ns) integer, intent(in) :: n integer, dimension(:), intent(in), optional :: states integer :: ns if (present (states)) then ns = product (states, mask = states == 2 .or. states == 3) else ns = 2**n end if end function num_states @ \section{\texttt{omega95}} <<[[omega95.f90]]>>= <> module omega95 use constants use omega_spinors use omega_vectors use omega_polarizations use omega_tensors use omega_tensor_polarizations use omega_couplings use omega_spinor_couplings use omega_color use omega_utils public end module omega95 @ \section{\texttt{omega95} Revisited} <<[[omega95_bispinors.f90]]>>= <> module omega95_bispinors use constants use omega_bispinors use omega_vectors use omega_vectorspinors use omega_polarizations use omega_vspinor_polarizations use omega_couplings use omega_bispinor_couplings use omega_color use omega_utils public end module omega95_bispinors @ \section{Testing} <<[[omega_testtools.f90]]>>= <> module omega_testtools use kinds implicit none private real(kind=default), parameter, private :: ABS_THRESHOLD_DEFAULT = 1E-17 real(kind=default), parameter, private :: THRESHOLD_DEFAULT = 0.6 real(kind=default), parameter, private :: THRESHOLD_WARN = 0.8 <> contains <> end module omega_testtools @ Quantify the agreement of two real or complex numbers \begin{equation} \text{agreement}(x,y) = \frac{\ln \Delta(x,y)}{\ln\epsilon} \in[0,1] \end{equation} with \begin{equation} \Delta(x,y) = \frac{|x-y|}{\max(|x|,|y|)} \end{equation} and values outside~$[0,1]$ replaced the closed value in the interval. In other words \begin{itemize} \item $1$ for $x-y=\max(|x|,|y|)\cdot\mathcal{O}(\epsilon)$ and \item $0$~for $x-y=\max(|x|,|y|)\cdot\mathcal{O}(1)$ \end{itemize} with logarithmic interpolation. The cases~$x=0$ and~$y=0$ must be treated separately. <>= public :: agreement interface agreement module procedure agreement_real, agreement_complex, & agreement_real_complex, agreement_complex_real, & agreement_integer_complex, agreement_complex_integer, & agreement_integer_real, agreement_real_integer end interface private :: agreement_real, agreement_complex, & agreement_real_complex, agreement_complex_real, & agreement_integer_complex, agreement_complex_integer, & agreement_integer_real, agreement_real_integer @ <>= elemental function agreement_real (x, y, base) result (a) real(kind=default) :: a real(kind=default), intent(in) :: x, y real(kind=default), intent(in), optional :: base real(kind=default) :: scale, dxy if (present (base)) then scale = max (abs (x), abs (y), abs (base)) else scale = max (abs (x), abs (y)) end if if (ieee_is_nan (x) .or. ieee_is_nan (y)) then a = 0 else if (scale <= 0) then a = -1 else dxy = abs (x - y) / scale if (dxy <= 0.0_default) then a = 1 else a = log (dxy) / log (epsilon (scale)) a = max (0.0_default, min (1.0_default, a)) if (ieee_is_nan (a)) then a = 0 end if end if end if if (ieee_is_nan (a)) then a = 0 end if end function agreement_real @ Poor man's replacement <>= elemental function ieee_is_nan (x) result (yorn) logical :: yorn real (kind=default), intent(in) :: x yorn = (x /= x) end function ieee_is_nan @ <>= elemental function agreement_complex (x, y, base) result (a) real(kind=default) :: a complex(kind=default), intent(in) :: x, y real(kind=default), intent(in), optional :: base real(kind=default) :: scale, dxy if (present (base)) then scale = max (abs (x), abs (y), abs (base)) else scale = max (abs (x), abs (y)) end if if ( ieee_is_nan (real (x, kind=default)) .or. ieee_is_nan (aimag (x)) & .or. ieee_is_nan (real (y, kind=default)) .or. ieee_is_nan (aimag (y))) then a = 0 else if (scale <= 0) then a = -1 else dxy = abs (x - y) / scale if (dxy <= 0.0_default) then a = 1 else a = log (dxy) / log (epsilon (scale)) a = max (0.0_default, min (1.0_default, a)) if (ieee_is_nan (a)) then a = 0 end if end if end if if (ieee_is_nan (a)) then a = 0 end if end function agreement_complex @ <>= elemental function agreement_real_complex (x, y, base) result (a) real(kind=default) :: a real(kind=default), intent(in) :: x complex(kind=default), intent(in) :: y real(kind=default), intent(in), optional :: base a = agreement_complex (cmplx (x, kind=default), y, base) end function agreement_real_complex @ <>= elemental function agreement_complex_real (x, y, base) result (a) real(kind=default) :: a complex(kind=default), intent(in) :: x real(kind=default), intent(in) :: y real(kind=default), intent(in), optional :: base a = agreement_complex (x, cmplx (y, kind=default), base) end function agreement_complex_real @ <>= elemental function agreement_integer_complex (x, y, base) result (a) real(kind=default) :: a integer, intent(in) :: x complex(kind=default), intent(in) :: y real(kind=default), intent(in), optional :: base a = agreement_complex (cmplx (x, kind=default), y, base) end function agreement_integer_complex @ <>= elemental function agreement_complex_integer (x, y, base) result (a) real(kind=default) :: a complex(kind=default), intent(in) :: x integer, intent(in) :: y real(kind=default), intent(in), optional :: base a = agreement_complex (x, cmplx (y, kind=default), base) end function agreement_complex_integer @ <>= elemental function agreement_integer_real (x, y, base) result (a) real(kind=default) :: a integer, intent(in) :: x real(kind=default), intent(in) :: y real(kind=default), intent(in), optional :: base a = agreement_real (real(x, kind=default), y, base) end function agreement_integer_real @ <>= elemental function agreement_real_integer (x, y, base) result (a) real(kind=default) :: a real(kind=default), intent(in) :: x integer, intent(in) :: y real(kind=default), intent(in), optional :: base a = agreement_real (x, real (y, kind=default), base) end function agreement_real_integer @ <>= public:: vanishes interface vanishes module procedure vanishes_real, vanishes_complex end interface private :: vanishes_real, vanishes_complex @ <>= elemental function vanishes_real (x, scale) result (a) real(kind=default) :: a real(kind=default), intent(in) :: x real(kind=default), intent(in), optional :: scale real(kind=default) :: scaled_x if (x == 0.0_default) then a = 1 return else if (ieee_is_nan (x)) then a = 0 return end if scaled_x = x if (present (scale)) then if (scale /= 0) then scaled_x = x / abs (scale) else a = 0 return end if else end if a = log (abs (scaled_x)) / log (epsilon (scaled_x)) a = max (0.0_default, min (1.0_default, a)) if (ieee_is_nan (a)) then a = 0 end if end function vanishes_real @ <>= elemental function vanishes_complex (x, scale) result (a) real(kind=default) :: a complex(kind=default), intent(in) :: x real(kind=default), intent(in), optional :: scale a = vanishes_real (abs (x), scale) end function vanishes_complex @ <>= public :: expect interface expect module procedure expect_integer, expect_real, expect_complex, & expect_real_integer, expect_integer_real, & expect_complex_integer, expect_integer_complex, & expect_complex_real, expect_real_complex end interface private :: expect_integer, expect_real, expect_complex, & expect_real_integer, expect_integer_real, & expect_complex_integer, expect_integer_complex, & expect_complex_real, expect_real_complex @ <>= subroutine expect_integer (x, x0, msg, passed, quiet, buffer, unit) integer, intent(in) :: x, x0 character(len=*), intent(in) :: msg logical, intent(inout), optional :: passed logical, intent(in), optional :: quiet character(len=*), intent(inout), optional :: buffer integer, intent(in), optional :: unit logical :: failed, verbose character(len=*), parameter :: fmt = "(1X,A,': ',A)" character(len=*), parameter :: & fmt_verbose = "(1X,A,': ',A,' [expected ',I6,', got ',I6,']')" failed = .false. verbose = .true. if (present (quiet)) then verbose = .not.quiet end if if (x == x0) then if (verbose) then if (.not. (present (buffer) .or. present (unit))) then write (unit = *, fmt = fmt) msg, "passed" end if if (present (unit)) then write (unit = unit, fmt = fmt) msg, "passed" end if if (present (buffer)) then write (unit = buffer, fmt = fmt) msg, "passed" end if end if else if (.not. (present (buffer) .or. present (unit))) then write (unit = *, fmt = fmt_verbose) msg, "failed", x0, x end if if (present (unit)) then write (unit = unit, fmt = fmt_verbose) msg, "failed", x0, x end if if (present (buffer)) then write (unit = buffer, fmt = fmt_verbose) msg, "failed", x0, x end if failed = .true. end if if (present (passed)) then passed = passed .and. .not.failed end if end subroutine expect_integer @ <>= subroutine expect_real (x, x0, msg, passed, threshold, quiet, abs_threshold) real(kind=default), intent(in) :: x, x0 character(len=*), intent(in) :: msg logical, intent(inout), optional :: passed real(kind=default), intent(in), optional :: threshold real(kind=default), intent(in), optional :: abs_threshold logical, intent(in), optional :: quiet logical :: failed, verbose real(kind=default) :: agreement_threshold, abs_agreement_threshold character(len=*), parameter :: fmt = "(1X,A,': ',A,' at ',I4,'%')" character(len=*), parameter :: fmt_verbose = "(1X,A,': ',A,' at ',I4,'%'," // & "' [expected ',E10.3,', got ',E10.3,']')" real(kind=default) :: a failed = .false. verbose = .true. if (present (quiet)) then verbose = .not.quiet end if if (x == x0) then if (verbose) then write (unit = *, fmt = fmt) msg, "passed", 100 end if else if (x0 == 0) then a = vanishes (x) else a = agreement (x, x0) end if if (present (threshold)) then agreement_threshold = threshold else agreement_threshold = THRESHOLD_DEFAULT end if if (present (abs_threshold)) then abs_agreement_threshold = abs_threshold else abs_agreement_threshold = ABS_THRESHOLD_DEFAULT end if if (a >= agreement_threshold .or. & max(abs(x), abs(x0)) <= abs_agreement_threshold) then if (verbose) then if (a >= THRESHOLD_WARN) then write (unit = *, fmt = fmt) msg, "passed", int (a * 100) else write (unit = *, fmt = fmt_verbose) msg, "passed", int (a * 100), x0, x end if end if else failed = .true. write (unit = *, fmt = fmt_verbose) msg, "failed", int (a * 100), x0, x end if end if if (present (passed)) then passed = passed .and. .not. failed end if end subroutine expect_real @ <>= subroutine expect_complex (x, x0, msg, passed, threshold, quiet, abs_threshold) complex(kind=default), intent(in) :: x, x0 character(len=*), intent(in) :: msg logical, intent(inout), optional :: passed real(kind=default), intent(in), optional :: threshold real(kind=default), intent(in), optional :: abs_threshold logical, intent(in), optional :: quiet logical :: failed, verbose real(kind=default) :: agreement_threshold, abs_agreement_threshold character(len=*), parameter :: fmt = "(1X,A,': ',A,' at ',I4,'%')" character(len=*), parameter :: fmt_verbose = "(1X,A,': ',A,' at ',I4,'%'," // & "' [expected (',E10.3,',',E10.3,'), got (',E10.3,',',E10.3,')]')" character(len=*), parameter :: fmt_phase = "(1X,A,': ',A,' at ',I4,'%'," // & "' [modulus passed at ',I4,'%',', phases ',F5.3,' vs. ',F5.3,']')" real(kind=default) :: a, a_modulus failed = .false. verbose = .true. if (present (quiet)) then verbose = .not.quiet end if if (x == x0) then if (verbose) then write (unit = *, fmt = fmt) msg, "passed", 100 end if else if (x0 == 0) then a = vanishes (x) else a = agreement (x, x0) end if if (present (threshold)) then agreement_threshold = threshold else agreement_threshold = THRESHOLD_DEFAULT end if if (present (abs_threshold)) then abs_agreement_threshold = abs_threshold else abs_agreement_threshold = ABS_THRESHOLD_DEFAULT end if if (a >= agreement_threshold .or. & max(abs(x), abs(x0)) <= abs_agreement_threshold) then if (verbose) then if (a >= THRESHOLD_WARN) then write (unit = *, fmt = fmt) msg, "passed", int (a * 100) else write (unit = *, fmt = fmt_verbose) msg, "passed", int (a * 100), x0, x end if end if else a_modulus = agreement (abs (x), abs (x0)) if (a_modulus >= agreement_threshold) then write (unit = *, fmt = fmt_phase) msg, "failed", int (a * 100), & int (a_modulus * 100), & atan2 (real (x, kind=default), aimag (x)), & atan2 (real (x0, kind=default), aimag (x0)) else write (unit = *, fmt = fmt_verbose) msg, "failed", int (a * 100), x0, x end if failed = .true. end if end if if (present (passed)) then passed = passed .and. .not.failed end if end subroutine expect_complex @ <>= subroutine expect_real_integer (x, x0, msg, passed, threshold, quiet) real(kind=default), intent(in) :: x integer, intent(in) :: x0 character(len=*), intent(in) :: msg real(kind=default), intent(in), optional :: threshold logical, intent(inout), optional :: passed logical, intent(in), optional :: quiet call expect_real (x, real (x0, kind=default), msg, passed, threshold, quiet) end subroutine expect_real_integer @ <>= subroutine expect_integer_real (x, x0, msg, passed, threshold, quiet) integer, intent(in) :: x real(kind=default), intent(in) :: x0 character(len=*), intent(in) :: msg real(kind=default), intent(in), optional :: threshold logical, intent(inout), optional :: passed logical, intent(in), optional :: quiet call expect_real (real (x, kind=default), x0, msg, passed, threshold, quiet) end subroutine expect_integer_real @ <>= subroutine expect_complex_integer (x, x0, msg, passed, threshold, quiet) complex(kind=default), intent(in) :: x integer, intent(in) :: x0 character(len=*), intent(in) :: msg logical, intent(inout), optional :: passed real(kind=default), intent(in), optional :: threshold logical, intent(in), optional :: quiet call expect_complex (x, cmplx (x0, kind=default), msg, passed, threshold, quiet) end subroutine expect_complex_integer @ <>= subroutine expect_integer_complex (x, x0, msg, passed, threshold, quiet) integer, intent(in) :: x complex(kind=default), intent(in) :: x0 character(len=*), intent(in) :: msg logical, intent(inout), optional :: passed real(kind=default), intent(in), optional :: threshold logical, intent(in), optional :: quiet call expect_complex (cmplx (x, kind=default), x0, msg, passed, threshold, quiet) end subroutine expect_integer_complex @ <>= subroutine expect_complex_real (x, x0, msg, passed, threshold, quiet) complex(kind=default), intent(in) :: x real(kind=default), intent(in) :: x0 character(len=*), intent(in) :: msg logical, intent(inout), optional :: passed real(kind=default), intent(in), optional :: threshold logical, intent(in), optional :: quiet call expect_complex (x, cmplx (x0, kind=default), msg, passed, threshold, quiet) end subroutine expect_complex_real @ <>= subroutine expect_real_complex (x, x0, msg, passed, threshold, quiet) real(kind=default), intent(in) :: x complex(kind=default), intent(in) :: x0 character(len=*), intent(in) :: msg logical, intent(inout), optional :: passed real(kind=default), intent(in), optional :: threshold logical, intent(in), optional :: quiet call expect_complex (cmplx (x, kind=default), x0, msg, passed, threshold, quiet) end subroutine expect_real_complex @ <>= public :: expect_zero interface expect_zero module procedure expect_zero_integer, expect_zero_real, expect_zero_complex end interface private :: expect_zero_integer, expect_zero_real, expect_zero_complex @ <>= subroutine expect_zero_integer (x, msg, passed) integer, intent(in) :: x character(len=*), intent(in) :: msg logical, intent(inout), optional :: passed call expect_integer (x, 0, msg, passed) end subroutine expect_zero_integer @ <>= subroutine expect_zero_real (x, scale, msg, passed, threshold, quiet) real(kind=default), intent(in) :: x, scale character(len=*), intent(in) :: msg logical, intent(inout), optional :: passed real(kind=default), intent(in), optional :: threshold logical, intent(in), optional :: quiet logical :: failed, verbose real(kind=default) :: agreement_threshold character(len=*), parameter :: fmt = "(1X,A,': ',A,' at ',I4,'%')" character(len=*), parameter :: fmt_verbose = "(1X,A,': ',A,' at ',I4,'%'," // & "' [expected 0 (relative to ',E10.3,') got ',E10.3,']')" real(kind=default) :: a failed = .false. verbose = .true. if (present (quiet)) then verbose = .not.quiet end if if (x == 0) then if (verbose) then write (unit = *, fmt = fmt) msg, "passed", 100 end if else a = vanishes (x, scale = scale) if (present (threshold)) then agreement_threshold = threshold else agreement_threshold = THRESHOLD_DEFAULT end if if (a >= agreement_threshold) then if (verbose) then if (a >= THRESHOLD_WARN) then write (unit = *, fmt = fmt) msg, "passed", int (a * 100) else write (unit = *, fmt = fmt_verbose) msg, "passed", int (a * 100), scale, x end if end if else failed = .true. write (unit = *, fmt = fmt_verbose) msg, "failed", int (a * 100), scale, x end if end if if (present (passed)) then passed = passed .and. .not.failed end if end subroutine expect_zero_real @ <>= subroutine expect_zero_complex (x, scale, msg, passed, threshold, quiet) complex(kind=default), intent(in) :: x real(kind=default), intent(in) :: scale character(len=*), intent(in) :: msg logical, intent(inout), optional :: passed real(kind=default), intent(in), optional :: threshold logical, intent(in), optional :: quiet call expect_zero_real (abs (x), scale, msg, passed, threshold, quiet) end subroutine expect_zero_complex @ <>= subroutine print_matrix (a) complex(kind=default), dimension(:,:), intent(in) :: a integer :: row do row = 1, size (a, dim=1) write (unit = *, fmt = "(10(tr2, f5.2, '+', f5.2, 'I'))") a(row,:) end do end subroutine print_matrix @ <>= public :: print_matrix @ <<[[test_omega95.f90]]>>= <> program test_omega95 use kinds use omega95 use omega_testtools implicit none real(kind=default) :: m, pabs, qabs, w real(kind=default), dimension(0:3) :: r complex(kind=default) :: c_one, c_nil type(momentum) :: p, q, p0 type(vector) :: vp, vq, vtest, v0 type(tensor) :: ttest type(spinor) :: test_psi, test_spinor1, test_spinor2 type(conjspinor) :: test_psibar, test_conjspinor1, test_conjspinor2 integer, dimension(8) :: date_time integer :: rsize, i logical :: passed call date_and_time (values = date_time) call random_seed (size = rsize) call random_seed (put = spread (product (date_time), dim = 1, ncopies = rsize)) w = 1.4142 c_one = 1.0_default c_nil = 0.0_default m = 13 pabs = 42 qabs = 137 call random_number (r) vtest%t = cmplx (10.0_default * r(0), kind=default) vtest%x(1:3) = cmplx (10.0_default * r(1:3), kind=default) ttest = vtest.tprod.vtest call random_momentum (p, pabs, m) call random_momentum (q, qabs, m) call random_momentum (p0, 0.0_default, m) vp = p vq = q v0 = p0 passed = .true. <> if (.not. passed) then stop 1 end if end program test_omega95 @ <>= print *, "*** Checking the equations of motion ***:" call expect (abs(f_vf(c_one,vp,u(m,p,+1))-m*u(m,p,+1)), 0, "|[p-m]u(+)|=0", passed) call expect (abs(f_vf(c_one,vp,u(m,p,-1))-m*u(m,p,-1)), 0, "|[p-m]u(-)|=0", passed) call expect (abs(f_vf(c_one,vp,v(m,p,+1))+m*v(m,p,+1)), 0, "|[p+m]v(+)|=0", passed) call expect (abs(f_vf(c_one,vp,v(m,p,-1))+m*v(m,p,-1)), 0, "|[p+m]v(-)|=0", passed) call expect (abs(f_fv(c_one,ubar(m,p,+1),vp)-m*ubar(m,p,+1)), 0, "|ubar(+)[p-m]|=0", passed) call expect (abs(f_fv(c_one,ubar(m,p,-1),vp)-m*ubar(m,p,-1)), 0, "|ubar(-)[p-m]|=0", passed) call expect (abs(f_fv(c_one,vbar(m,p,+1),vp)+m*vbar(m,p,+1)), 0, "|vbar(+)[p+m]|=0", passed) call expect (abs(f_fv(c_one,vbar(m,p,-1),vp)+m*vbar(m,p,-1)), 0, "|vbar(-)[p+m]|=0", passed) print *, "*** Checking the equations of motion for negative mass***:" call expect (abs(f_vf(c_one,vp,u(-m,p,+1))+m*u(-m,p,+1)), 0, "|[p+m]u(+)|=0", passed) call expect (abs(f_vf(c_one,vp,u(-m,p,-1))+m*u(-m,p,-1)), 0, "|[p+m]u(-)|=0", passed) call expect (abs(f_vf(c_one,vp,v(-m,p,+1))-m*v(-m,p,+1)), 0, "|[p-m]v(+)|=0", passed) call expect (abs(f_vf(c_one,vp,v(-m,p,-1))-m*v(-m,p,-1)), 0, "|[p-m]v(-)|=0", passed) call expect (abs(f_fv(c_one,ubar(-m,p,+1),vp)+m*ubar(-m,p,+1)), 0, "|ubar(+)[p+m]|=0", passed) call expect (abs(f_fv(c_one,ubar(-m,p,-1),vp)+m*ubar(-m,p,-1)), 0, "|ubar(-)[p+m]|=0", passed) call expect (abs(f_fv(c_one,vbar(-m,p,+1),vp)-m*vbar(-m,p,+1)), 0, "|vbar(+)[p-m]|=0", passed) call expect (abs(f_fv(c_one,vbar(-m,p,-1),vp)-m*vbar(-m,p,-1)), 0, "|vbar(-)[p-m]|=0", passed) @ <>= print *, "*** Spin Sums" test_psi%a = [one, two, three, four] test_spinor1 = f_vf (c_one, vp, test_psi) + m * test_psi test_spinor2 = u (m, p, +1) * (ubar (m, p, +1) * test_psi) + & u (m, p, -1) * (ubar (m, p, -1) * test_psi) do i = 1, 4 call expect (test_spinor1%a(i), test_spinor2%a(i), "(p+m)1=(sum u ubar)1", passed) end do test_spinor1 = f_vf (c_one, vp, test_psi) - m * test_psi test_spinor2 = v (m, p, +1) * (vbar (m, p, +1) * test_psi) + & v (m, p, -1) * (vbar (m, p, -1) * test_psi) do i = 1, 4 call expect (test_spinor1%a(i), test_spinor2%a(i), "(p-m)1=(sum v vbar)1", passed) end do test_psibar%a = [one, two, three, four] test_conjspinor1 = f_fv (c_one, test_psibar, vp) - m * test_psibar test_conjspinor2 = (test_psibar * v (m, p, +1)) * vbar (m, p, +1) + & (test_psibar * v (m, p, -1)) * vbar (m, p, -1) do i = 1, 4 call expect (test_conjspinor1%a(i), test_conjspinor2%a(i), "(p-m)1=(sum v vbar)1", passed) end do @ <>= print *, "*** Checking the normalization ***:" call expect (ubar(m,p,+1)*u(m,p,+1), +2*m, "ubar(+)*u(+)=+2m", passed) call expect (ubar(m,p,-1)*u(m,p,-1), +2*m, "ubar(-)*u(-)=+2m", passed) call expect (vbar(m,p,+1)*v(m,p,+1), -2*m, "vbar(+)*v(+)=-2m", passed) call expect (vbar(m,p,-1)*v(m,p,-1), -2*m, "vbar(-)*v(-)=-2m", passed) call expect (ubar(m,p,+1)*v(m,p,+1), 0, "ubar(+)*v(+)=0 ", passed) call expect (ubar(m,p,-1)*v(m,p,-1), 0, "ubar(-)*v(-)=0 ", passed) call expect (vbar(m,p,+1)*u(m,p,+1), 0, "vbar(+)*u(+)=0 ", passed) call expect (vbar(m,p,-1)*u(m,p,-1), 0, "vbar(-)*u(-)=0 ", passed) print *, "*** Checking the normalization for negative masses***:" call expect (ubar(-m,p,+1)*u(-m,p,+1), -2*m, "ubar(+)*u(+)=-2m", passed) call expect (ubar(-m,p,-1)*u(-m,p,-1), -2*m, "ubar(-)*u(-)=-2m", passed) call expect (vbar(-m,p,+1)*v(-m,p,+1), +2*m, "vbar(+)*v(+)=+2m", passed) call expect (vbar(-m,p,-1)*v(-m,p,-1), +2*m, "vbar(-)*v(-)=+2m", passed) call expect (ubar(-m,p,+1)*v(-m,p,+1), 0, "ubar(+)*v(+)=0 ", passed) call expect (ubar(-m,p,-1)*v(-m,p,-1), 0, "ubar(-)*v(-)=0 ", passed) call expect (vbar(-m,p,+1)*u(-m,p,+1), 0, "vbar(+)*u(+)=0 ", passed) call expect (vbar(-m,p,-1)*u(-m,p,-1), 0, "vbar(-)*u(-)=0 ", passed) @ <>= print *, "*** Checking the currents ***:" call expect (abs(v_ff(c_one,ubar(m,p,+1),u(m,p,+1))-2*vp), 0, "ubar(+).V.u(+)=2p", passed) call expect (abs(v_ff(c_one,ubar(m,p,-1),u(m,p,-1))-2*vp), 0, "ubar(-).V.u(-)=2p", passed) call expect (abs(v_ff(c_one,vbar(m,p,+1),v(m,p,+1))-2*vp), 0, "vbar(+).V.v(+)=2p", passed) call expect (abs(v_ff(c_one,vbar(m,p,-1),v(m,p,-1))-2*vp), 0, "vbar(-).V.v(-)=2p", passed) print *, "*** Checking the currents for negative masses***:" call expect (abs(v_ff(c_one,ubar(-m,p,+1),u(-m,p,+1))-2*vp), 0, "ubar(+).V.u(+)=2p", passed) call expect (abs(v_ff(c_one,ubar(-m,p,-1),u(-m,p,-1))-2*vp), 0, "ubar(-).V.u(-)=2p", passed) call expect (abs(v_ff(c_one,vbar(-m,p,+1),v(-m,p,+1))-2*vp), 0, "vbar(+).V.v(+)=2p", passed) call expect (abs(v_ff(c_one,vbar(-m,p,-1),v(-m,p,-1))-2*vp), 0, "vbar(-).V.v(-)=2p", passed) @ <>= print *, "*** Checking current conservation ***:" call expect ((vp-vq)*v_ff(c_one,ubar(m,p,+1),u(m,q,+1)), 0, "d(ubar(+).V.u(+))=0", passed) call expect ((vp-vq)*v_ff(c_one,ubar(m,p,-1),u(m,q,-1)), 0, "d(ubar(-).V.u(-))=0", passed) call expect ((vp-vq)*v_ff(c_one,vbar(m,p,+1),v(m,q,+1)), 0, "d(vbar(+).V.v(+))=0", passed) call expect ((vp-vq)*v_ff(c_one,vbar(m,p,-1),v(m,q,-1)), 0, "d(vbar(-).V.v(-))=0", passed) print *, "*** Checking current conservation for negative masses***:" call expect ((vp-vq)*v_ff(c_one,ubar(-m,p,+1),u(-m,q,+1)), 0, "d(ubar(+).V.u(+))=0", passed) call expect ((vp-vq)*v_ff(c_one,ubar(-m,p,-1),u(-m,q,-1)), 0, "d(ubar(-).V.u(-))=0", passed) call expect ((vp-vq)*v_ff(c_one,vbar(-m,p,+1),v(-m,q,+1)), 0, "d(vbar(+).V.v(+))=0", passed) call expect ((vp-vq)*v_ff(c_one,vbar(-m,p,-1),v(-m,q,-1)), 0, "d(vbar(-).V.v(-))=0", passed) @ <>= if (m == 0) then print *, "*** Checking axial current conservation ***:" call expect ((vp-vq)*a_ff(c_one,ubar(m,p,+1),u(m,q,+1)), 0, "d(ubar(+).A.u(+))=0", passed) call expect ((vp-vq)*a_ff(c_one,ubar(m,p,-1),u(m,q,-1)), 0, "d(ubar(-).A.u(-))=0", passed) call expect ((vp-vq)*a_ff(c_one,vbar(m,p,+1),v(m,q,+1)), 0, "d(vbar(+).A.v(+))=0", passed) call expect ((vp-vq)*a_ff(c_one,vbar(m,p,-1),v(m,q,-1)), 0, "d(vbar(-).A.v(-))=0", passed) end if @ <>= print *, "*** Checking implementation of the sigma vertex funktions ***:" call expect ((vp*tvam_ff(c_one,c_nil,ubar(m,p,+1),u(m,q,+1),q) - (p*q-m**2)*(ubar(m,p,+1)*u(m,q,+1))), 0, & "p*[ubar(p,+).(Isigma*q).u(q,+)] - (p*q-m^2)*ubar(p,+).u(q,+) = 0", passed) call expect ((vp*tvam_ff(c_one,c_nil,ubar(m,p,-1),u(m,q,-1),q) - (p*q-m**2)*(ubar(m,p,-1)*u(m,q,-1))), 0, & "p*[ubar(p,-).(Isigma*q).u(q,-)] - (p*q-m^2)*ubar(p,-).u(q,-) = 0", passed) call expect ((vp*tvam_ff(c_one,c_nil,vbar(m,p,+1),v(m,q,+1),q) - (p*q-m**2)*(vbar(m,p,+1)*v(m,q,+1))), 0, & "p*[vbar(p,+).(Isigma*q).v(q,+)] - (p*q-m^2)*vbar(p,+).v(q,+) = 0", passed) call expect ((vp*tvam_ff(c_one,c_nil,vbar(m,p,-1),v(m,q,-1),q) - (p*q-m**2)*(vbar(m,p,-1)*v(m,q,-1))), 0, & "p*[vbar(p,-).(Isigma*q).v(q,-)] - (p*q-m^2)*vbar(p,-).v(q,-) = 0", passed) call expect ((ubar(m,p,+1)*f_tvamf(c_one,c_nil,vp,u(m,q,+1),q) - (p*q-m**2)*(ubar(m,p,+1)*u(m,q,+1))), 0, & "ubar(p,+).[p*(Isigma*q).u(q,+)] - (p*q-m^2)*ubar(p,+).u(q,+) = 0", passed) call expect ((ubar(m,p,-1)*f_tvamf(c_one,c_nil,vp,u(m,q,-1),q) - (p*q-m**2)*(ubar(m,p,-1)*u(m,q,-1))), 0, & "ubar(p,-).[p*(Isigma*q).u(q,-)] - (p*q-m^2)*ubar(p,-).u(q,-) = 0", passed) call expect ((vbar(m,p,+1)*f_tvamf(c_one,c_nil,vp,v(m,q,+1),q) - (p*q-m**2)*(vbar(m,p,+1)*v(m,q,+1))), 0, & "vbar(p,+).[p*(Isigma*q).v(q,+)] - (p*q-m^2)*vbar(p,+).v(q,+) = 0", passed) call expect ((vbar(m,p,-1)*f_tvamf(c_one,c_nil,vp,v(m,q,-1),q) - (p*q-m**2)*(vbar(m,p,-1)*v(m,q,-1))), 0, & "vbar(p,-).[p*(Isigma*q).v(q,-)] - (p*q-m^2)*vbar(p,-).v(q,-) = 0", passed) call expect ((f_ftvam(c_one,c_nil,ubar(m,p,+1),vp,q)*u(m,q,+1) - (p*q-m**2)*(ubar(m,p,+1)*u(m,q,+1))), 0, & "[ubar(p,+).p*(Isigma*q)].u(q,+) - (p*q-m^2)*ubar(p,+).u(q,+) = 0", passed) call expect ((f_ftvam(c_one,c_nil,ubar(m,p,-1),vp,q)*u(m,q,-1) - (p*q-m**2)*(ubar(m,p,-1)*u(m,q,-1))), 0, & "[ubar(p,-).p*(Isigma*q)].u(q,-) - (p*q-m^2)*ubar(p,-).u(q,-) = 0", passed) call expect ((f_ftvam(c_one,c_nil,vbar(m,p,+1),vp,q)*v(m,q,+1) - (p*q-m**2)*(vbar(m,p,+1)*v(m,q,+1))), 0, & "[vbar(p,+).p*(Isigma*q)].v(q,+) - (p*q-m^2)*vbar(p,+).v(q,+) = 0", passed) call expect ((f_ftvam(c_one,c_nil,vbar(m,p,-1),vp,q)*v(m,q,-1) - (p*q-m**2)*(vbar(m,p,-1)*v(m,q,-1))), 0, & "[vbar(p,-).p*(Isigma*q)].v(q,-) - (p*q-m^2)*vbar(p,-).v(q,-) = 0", passed) call expect ((vp*tvam_ff(c_nil,c_one,ubar(m,p,+1),u(m,q,+1),q) - (p*q+m**2)*p_ff(c_one,ubar(m,p,+1),u(m,q,+1))), 0, & "p*[ubar(p,+).(Isigma*q).g5.u(q,+)] - (p*q+m^2)*ubar(p,+).g5.u(q,+) = 0", passed) call expect ((vp*tvam_ff(c_nil,c_one,ubar(m,p,-1),u(m,q,-1),q) - (p*q+m**2)*p_ff(c_one,ubar(m,p,-1),u(m,q,-1))), 0, & "p*[ubar(p,-).(Isigma*q).g5.u(q,-)] - (p*q+m^2)*ubar(p,-).g5.u(q,-) = 0", passed) call expect ((vp*tvam_ff(c_nil,c_one,vbar(m,p,+1),v(m,q,+1),q) - (p*q+m**2)*p_ff(c_one,vbar(m,p,+1),v(m,q,+1))), 0, & "p*[vbar(p,+).(Isigma*q).g5.v(q,+)] - (p*q+m^2)*vbar(p,+).g5.v(q,+) = 0", passed) call expect ((vp*tvam_ff(c_nil,c_one,vbar(m,p,-1),v(m,q,-1),q) - (p*q+m**2)*p_ff(c_one,vbar(m,p,-1),v(m,q,-1))), 0, & "p*[vbar(p,-).(Isigma*q).g5.v(q,-)] - (p*q+m^2)*vbar(p,-).g5.v(q,-) = 0", passed) call expect ((ubar(m,p,+1)*f_tvamf(c_nil,c_one,vp,u(m,q,+1),q) - (p*q+m**2)*p_ff(c_one,ubar(m,p,+1),u(m,q,+1))), 0, & "p*[ubar(p,+).(Isigma*q).g5.u(q,+)] - (p*q+m^2)*ubar(p,+).g5.u(q,+) = 0", passed) call expect ((ubar(m,p,-1)*f_tvamf(c_nil,c_one,vp,u(m,q,-1),q) - (p*q+m**2)*p_ff(c_one,ubar(m,p,-1),u(m,q,-1))), 0, & "p*[ubar(p,-).(Isigma*q).g5.u(q,-)] - (p*q+m^2)*ubar(p,-).g5.u(q,-) = 0", passed) call expect ((vbar(m,p,+1)*f_tvamf(c_nil,c_one,vp,v(m,q,+1),q) - (p*q+m**2)*p_ff(c_one,vbar(m,p,+1),v(m,q,+1))), 0, & "p*[vbar(p,+).(Isigma*q).g5.v(q,+)] - (p*q+m^2)*vbar(p,+).g5.v(q,+) = 0", passed) call expect ((vbar(m,p,-1)*f_tvamf(c_nil,c_one,vp,v(m,q,-1),q) - (p*q+m**2)*p_ff(c_one,vbar(m,p,-1),v(m,q,-1))), 0, & "p*[vbar(p,-).(Isigma*q).g5.v(q,-)] - (p*q+m^2)*vbar(p,-).g5.v(q,-) = 0", passed) call expect ((f_ftvam(c_nil,c_one,ubar(m,p,+1),vp,q)*u(m,q,+1) - (p*q+m**2)*p_ff(c_one,ubar(m,p,+1),u(m,q,+1))), 0, & "p*[ubar(p,+).(Isigma*q).g5.u(q,+)] - (p*q+m^2)*ubar(p,+).g5.u(q,+) = 0", passed) call expect ((f_ftvam(c_nil,c_one,ubar(m,p,-1),vp,q)*u(m,q,-1) - (p*q+m**2)*p_ff(c_one,ubar(m,p,-1),u(m,q,-1))), 0, & "p*[ubar(p,-).(Isigma*q).g5.u(q,-)] - (p*q+m^2)*ubar(p,-).g5.u(q,-) = 0", passed) call expect ((f_ftvam(c_nil,c_one,vbar(m,p,+1),vp,q)*v(m,q,+1) - (p*q+m**2)*p_ff(c_one,vbar(m,p,+1),v(m,q,+1))), 0, & "p*[vbar(p,+).(Isigma*q).g5.v(q,+)] - (p*q+m^2)*vbar(p,+).g5.v(q,+) = 0", passed) call expect ((f_ftvam(c_nil,c_one,vbar(m,p,-1),vp,q)*v(m,q,-1) - (p*q+m**2)*p_ff(c_one,vbar(m,p,-1),v(m,q,-1))), 0, & "p*[vbar(p,-).(Isigma*q).g5.v(q,-)] - (p*q+m^2)*vbar(p,-).g5.v(q,-) = 0", passed) @ <>= print *, "*** Checking polarisation vectors: ***" call expect (conjg(eps(m,p, 1))*eps(m,p, 1), -1, "e( 1).e( 1)=-1", passed) call expect (conjg(eps(m,p, 1))*eps(m,p,-1), 0, "e( 1).e(-1)= 0", passed) call expect (conjg(eps(m,p,-1))*eps(m,p, 1), 0, "e(-1).e( 1)= 0", passed) call expect (conjg(eps(m,p,-1))*eps(m,p,-1), -1, "e(-1).e(-1)=-1", passed) call expect ( p*eps(m,p, 1), 0, " p.e( 1)= 0", passed) call expect ( p*eps(m,p,-1), 0, " p.e(-1)= 0", passed) if (m > 0) then call expect (conjg(eps(m,p, 1))*eps(m,p, 0), 0, "e( 1).e( 0)= 0", passed) call expect (conjg(eps(m,p, 0))*eps(m,p, 1), 0, "e( 0).e( 1)= 0", passed) call expect (conjg(eps(m,p, 0))*eps(m,p, 0), -1, "e( 0).e( 0)=-1", passed) call expect (conjg(eps(m,p, 0))*eps(m,p,-1), 0, "e( 0).e(-1)= 0", passed) call expect (conjg(eps(m,p,-1))*eps(m,p, 0), 0, "e(-1).e( 0)= 0", passed) call expect ( p*eps(m,p, 0), 0, " p.e( 0)= 0", passed) end if @ <>= print *, "*** Checking epsilon tensor: ***" call expect ( pseudo_scalar(eps(m,p,1),eps(m,q,1),eps(m,p,0),eps(m,q,0)), & - pseudo_scalar(eps(m,q,1),eps(m,p,1),eps(m,p,0),eps(m,q,0)), "eps(1<->2)", passed) call expect ( pseudo_scalar(eps(m,p,1),eps(m,q,1),eps(m,p,0),eps(m,q,0)), & - pseudo_scalar(eps(m,p,0),eps(m,q,1),eps(m,p,1),eps(m,q,0)), "eps(1<->3)", passed) call expect ( pseudo_scalar(eps(m,p,1),eps(m,q,1),eps(m,p,0),eps(m,q,0)), & - pseudo_scalar(eps(m,q,0),eps(m,q,1),eps(m,p,0),eps(m,p,1)), "eps(1<->4)", passed) call expect ( pseudo_scalar(eps(m,p,1),eps(m,q,1),eps(m,p,0),eps(m,q,0)), & - pseudo_scalar(eps(m,p,1),eps(m,p,0),eps(m,q,1),eps(m,q,0)), "eps(2<->3)", passed) call expect ( pseudo_scalar(eps(m,p,1),eps(m,q,1),eps(m,p,0),eps(m,q,0)), & - pseudo_scalar(eps(m,p,1),eps(m,q,0),eps(m,p,0),eps(m,q,1)), "eps(2<->4)", passed) call expect ( pseudo_scalar(eps(m,p,1),eps(m,q,1),eps(m,p,0),eps(m,q,0)), & - pseudo_scalar(eps(m,p,1),eps(m,q,1),eps(m,q,0),eps(m,p,0)), "eps(3<->4)", passed) call expect ( pseudo_scalar(eps(m,p,1),eps(m,q,1),eps(m,p,0),eps(m,q,0)), & eps(m,p,1)*pseudo_vector(eps(m,q,1),eps(m,p,0),eps(m,q,0)), "eps'", passed) @ \begin{equation} \frac{1}{2} [x\wedge y]^*_{\mu\nu} [x\wedge y]^{\mu\nu} = \frac{1}{2} (x^*_\mu y^*_\nu-x^*_\nu y^*_\mu) (x^\mu y^\nu-x^\nu y^\mu) = (x^*x) (y^*y) - (x^*y) (y^*x) \end{equation} <>= print *, "*** Checking tensors: ***" call expect (conjg(p.wedge.q)*(p.wedge.q), (p*p)*(q*q)-(p*q)**2, & "[p,q].[q,p]=p.p*q.q-p.q^2", passed) call expect (conjg(p.wedge.q)*(q.wedge.p), (p*q)**2-(p*p)*(q*q), & "[p,q].[q,p]=p.q^2-p.p*q.q", passed) @ i.\,e. \begin{equation} \frac{1}{2} [p\wedge\epsilon(p,i)]^*_{\mu\nu} [p\wedge\epsilon(p,j)]^{\mu\nu} = - p^2 \delta_{ij} \end{equation} <>= call expect (conjg(p.wedge.eps(m,p, 1))*(p.wedge.eps(m,p, 1)), -p*p, & "[p,e( 1)].[p,e( 1)]=-p.p", passed) call expect (conjg(p.wedge.eps(m,p, 1))*(p.wedge.eps(m,p,-1)), 0, & "[p,e( 1)].[p,e(-1)]=0", passed) call expect (conjg(p.wedge.eps(m,p,-1))*(p.wedge.eps(m,p, 1)), 0, & "[p,e(-1)].[p,e( 1)]=0", passed) call expect (conjg(p.wedge.eps(m,p,-1))*(p.wedge.eps(m,p,-1)), -p*p, & "[p,e(-1)].[p,e(-1)]=-p.p", passed) if (m > 0) then call expect (conjg(p.wedge.eps(m,p, 1))*(p.wedge.eps(m,p, 0)), 0, & "[p,e( 1)].[p,e( 0)]=0", passed) call expect (conjg(p.wedge.eps(m,p, 0))*(p.wedge.eps(m,p, 1)), 0, & "[p,e( 0)].[p,e( 1)]=0", passed) call expect (conjg(p.wedge.eps(m,p, 0))*(p.wedge.eps(m,p, 0)), -p*p, & "[p,e( 0)].[p,e( 0)]=-p.p", passed) call expect (conjg(p.wedge.eps(m,p, 0))*(p.wedge.eps(m,p,-1)), 0, & "[p,e( 1)].[p,e(-1)]=0", passed) call expect (conjg(p.wedge.eps(m,p,-1))*(p.wedge.eps(m,p, 0)), 0, & "[p,e(-1)].[p,e( 0)]=0", passed) end if @ also \begin{align} [x\wedge y]_{\mu\nu} z^\nu &= x_\mu (yz) - y_\mu (xz) \\ z_\mu [x\wedge y]^{\mu\nu} &= (zx) y^\nu - (zy) x^\nu \end{align} <>= call expect (abs ((p.wedge.eps(m,p, 1))*p + (p*p)*eps(m,p, 1)), 0, & "[p,e( 1)].p=-p.p*e( 1)]", passed) call expect (abs ((p.wedge.eps(m,p, 0))*p + (p*p)*eps(m,p, 0)), 0, & "[p,e( 0)].p=-p.p*e( 0)]", passed) call expect (abs ((p.wedge.eps(m,p,-1))*p + (p*p)*eps(m,p,-1)), 0, & "[p,e(-1)].p=-p.p*e(-1)]", passed) call expect (abs (p*(p.wedge.eps(m,p, 1)) - (p*p)*eps(m,p, 1)), 0, & "p.[p,e( 1)]=p.p*e( 1)]", passed) call expect (abs (p*(p.wedge.eps(m,p, 0)) - (p*p)*eps(m,p, 0)), 0, & "p.[p,e( 0)]=p.p*e( 0)]", passed) call expect (abs (p*(p.wedge.eps(m,p,-1)) - (p*p)*eps(m,p,-1)), 0, & "p.[p,e(-1)]=p.p*e(-1)]", passed) @ <>= print *, "*** Checking polarisation tensors: ***" call expect (conjg(eps2(m,p, 2))*eps2(m,p, 2), 1, "e2( 2).e2( 2)=1", passed) call expect (conjg(eps2(m,p, 2))*eps2(m,p,-2), 0, "e2( 2).e2(-2)=0", passed) call expect (conjg(eps2(m,p,-2))*eps2(m,p, 2), 0, "e2(-2).e2( 2)=0", passed) call expect (conjg(eps2(m,p,-2))*eps2(m,p,-2), 1, "e2(-2).e2(-2)=1", passed) if (m > 0) then call expect (conjg(eps2(m,p, 2))*eps2(m,p, 1), 0, "e2( 2).e2( 1)=0", passed) call expect (conjg(eps2(m,p, 2))*eps2(m,p, 0), 0, "e2( 2).e2( 0)=0", passed) call expect (conjg(eps2(m,p, 2))*eps2(m,p,-1), 0, "e2( 2).e2(-1)=0", passed) call expect (conjg(eps2(m,p, 1))*eps2(m,p, 2), 0, "e2( 1).e2( 2)=0", passed) call expect (conjg(eps2(m,p, 1))*eps2(m,p, 1), 1, "e2( 1).e2( 1)=1", passed) call expect (conjg(eps2(m,p, 1))*eps2(m,p, 0), 0, "e2( 1).e2( 0)=0", passed) call expect (conjg(eps2(m,p, 1))*eps2(m,p,-1), 0, "e2( 1).e2(-1)=0", passed) call expect (conjg(eps2(m,p, 1))*eps2(m,p,-2), 0, "e2( 1).e2(-2)=0", passed) call expect (conjg(eps2(m,p, 0))*eps2(m,p, 2), 0, "e2( 0).e2( 2)=0", passed) call expect (conjg(eps2(m,p, 0))*eps2(m,p, 1), 0, "e2( 0).e2( 1)=0", passed) call expect (conjg(eps2(m,p, 0))*eps2(m,p, 0), 1, "e2( 0).e2( 0)=1", passed) call expect (conjg(eps2(m,p, 0))*eps2(m,p,-1), 0, "e2( 0).e2(-1)=0", passed) call expect (conjg(eps2(m,p, 0))*eps2(m,p,-2), 0, "e2( 0).e2(-2)=0", passed) call expect (conjg(eps2(m,p,-1))*eps2(m,p, 2), 0, "e2(-1).e2( 2)=0", passed) call expect (conjg(eps2(m,p,-1))*eps2(m,p, 1), 0, "e2(-1).e2( 1)=0", passed) call expect (conjg(eps2(m,p,-1))*eps2(m,p, 0), 0, "e2(-1).e2( 0)=0", passed) call expect (conjg(eps2(m,p,-1))*eps2(m,p,-1), 1, "e2(-1).e2(-1)=1", passed) call expect (conjg(eps2(m,p,-1))*eps2(m,p,-2), 0, "e2(-1).e2(-2)=0", passed) call expect (conjg(eps2(m,p,-2))*eps2(m,p, 1), 0, "e2(-2).e2( 1)=0", passed) call expect (conjg(eps2(m,p,-2))*eps2(m,p, 0), 0, "e2(-2).e2( 0)=0", passed) call expect (conjg(eps2(m,p,-2))*eps2(m,p,-1), 0, "e2(-2).e2(-1)=0", passed) end if @ <>= call expect ( abs(p*eps2(m,p, 2) ), 0, " |p.e2( 2)| =0", passed) call expect ( abs(eps2(m,p, 2)*p), 0, " |e2( 2).p|=0", passed) call expect ( abs(p*eps2(m,p,-2) ), 0, " |p.e2(-2)| =0", passed) call expect ( abs(eps2(m,p,-2)*p), 0, " |e2(-2).p|=0", passed) if (m > 0) then call expect ( abs(p*eps2(m,p, 1) ), 0, " |p.e2( 1)| =0", passed) call expect ( abs(eps2(m,p, 1)*p), 0, " |e2( 1).p|=0", passed) call expect ( abs(p*eps2(m,p, 0) ), 0, " |p.e2( 0)| =0", passed) call expect ( abs(eps2(m,p, 0)*p), 0, " |e2( 0).p|=0", passed) call expect ( abs(p*eps2(m,p,-1) ), 0, " |p.e2(-1)| =0", passed) call expect ( abs(eps2(m,p,-1)*p), 0, " |e2(-1).p|=0", passed) end if @ <>= print *, " *** Checking the polarization tensors for massive gravitons:" call expect (abs(p * eps2(m,p,2)), 0, "p.e(+2)=0", passed) call expect (abs(p * eps2(m,p,1)), 0, "p.e(+1)=0", passed) call expect (abs(p * eps2(m,p,0)), 0, "p.e( 0)=0", passed) call expect (abs(p * eps2(m,p,-1)), 0, "p.e(-1)=0", passed) call expect (abs(p * eps2(m,p,-2)), 0, "p.e(-2)=0", passed) call expect (abs(trace(eps2 (m,p,2))), 0, "Tr[e(+2)]=0", passed) call expect (abs(trace(eps2 (m,p,1))), 0, "Tr[e(+1)]=0", passed) call expect (abs(trace(eps2 (m,p,0))), 0, "Tr[e( 0)]=0", passed) call expect (abs(trace(eps2 (m,p,-1))), 0, "Tr[e(-1)]=0", passed) call expect (abs(trace(eps2 (m,p,-2))), 0, "Tr[e(-2)]=0", passed) call expect (abs(eps2(m,p,2) * eps2(m,p,2)), 1, & "e(2).e(2) = 1", passed) call expect (abs(eps2(m,p,2) * eps2(m,p,1)), 0, & "e(2).e(1) = 0", passed) call expect (abs(eps2(m,p,2) * eps2(m,p,0)), 0, & "e(2).e(0) = 0", passed) call expect (abs(eps2(m,p,2) * eps2(m,p,-1)), 0, & "e(2).e(-1) = 0", passed) call expect (abs(eps2(m,p,2) * eps2(m,p,-2)), 0, & "e(2).e(-2) = 0", passed) call expect (abs(eps2(m,p,1) * eps2(m,p,1)), 1, & "e(1).e(1) = 1", passed) call expect (abs(eps2(m,p,1) * eps2(m,p,0)), 0, & "e(1).e(0) = 0", passed) call expect (abs(eps2(m,p,1) * eps2(m,p,-1)), 0, & "e(1).e(-1) = 0", passed) call expect (abs(eps2(m,p,1) * eps2(m,p,-2)), 0, & "e(1).e(-2) = 0", passed) call expect (abs(eps2(m,p,0) * eps2(m,p,0)), 1, & "e(0).e(0) = 1", passed) call expect (abs(eps2(m,p,0) * eps2(m,p,-1)), 0, & "e(0).e(-1) = 0", passed) call expect (abs(eps2(m,p,0) * eps2(m,p,-2)), 0, & "e(0).e(-2) = 0", passed) call expect (abs(eps2(m,p,-1) * eps2(m,p,-1)), 1, & "e(-1).e(-1) = 1", passed) call expect (abs(eps2(m,p,-1) * eps2(m,p,-2)), 0, & "e(-1).e(-2) = 0", passed) call expect (abs(eps2(m,p,-2) * eps2(m,p,-2)), 1, & "e(-2).e(-2) = 1", passed) @ <>= print *, " *** Checking the graviton propagator:" call expect (abs(p * (cmplx (p*p - m**2, m*w, kind=default) * & pr_tensor(p,m,w,eps2(m,p,-2)))), 0, "p.pr.e(-2)", passed) call expect (abs(p * (cmplx (p*p - m**2, m*w, kind=default) * & pr_tensor(p,m,w,eps2(m,p,-1)))), 0, "p.pr.e(-1)", passed) call expect (abs(p * (cmplx (p*p - m**2, m*w, kind=default) * & pr_tensor(p,m,w,eps2(m,p,0)))), 0, "p.pr.e(0)", passed) call expect (abs(p * (cmplx (p*p - m**2, m*w, kind=default) * & pr_tensor(p,m,w,eps2(m,p,1)))), 0, "p.pr.e(1)", passed) call expect (abs(p * (cmplx (p*p - m**2, m*w, kind=default) * & pr_tensor(p,m,w,eps2(m,p,2)))), 0, "p.pr.e(2)", passed) call expect (abs(p * (cmplx (p*p - m**2, m*w, kind=default) * & pr_tensor(p,m,w,ttest))), 0, "p.pr.ttest", passed) @ <<[[test_omega95_bispinors.f90]]>>= <> program test_omega95_bispinors use kinds use omega95_bispinors use omega_vspinor_polarizations use omega_testtools implicit none integer :: i, j real(kind=default) :: m, pabs, qabs, tabs, zabs, w real(kind=default), dimension(4) :: r complex(kind=default) :: c_nil, c_one, c_two type(momentum) :: p, q, t, z, p_0 type(vector) :: vp, vq, vt, vz type(vectorspinor) :: testv type(bispinor) :: vv logical :: passed call random_seed () c_nil = 0.0_default c_one = 1.0_default c_two = 2.0_default w = 1.4142 m = 13 pabs = 42 qabs = 137 tabs = 84 zabs = 3.1415 p_0%t = m p_0%x = 0 call random_momentum (p, pabs, m) call random_momentum (q, qabs, m) call random_momentum (t, tabs, m) call random_momentum (z, zabs, m) call random_number (r) do i = 1, 4 testv%psi(1)%a(i) = (0.0_default, 0.0_default) end do do i = 2, 3 do j = 1, 4 testv%psi(i)%a(j) = cmplx (10.0_default * r(j), kind=default) end do end do testv%psi(4)%a(1) = (1.0_default, 0.0_default) testv%psi(4)%a(2) = (0.0_default, 2.0_default) testv%psi(4)%a(3) = (1.0_default, 0.0_default) testv%psi(4)%a(4) = (3.0_default, 0.0_default) vp = p vq = q vt = t vz = z passed = .true. vv%a(1) = (1.0_default, 0.0_default) vv%a(2) = (0.0_default, 2.0_default) vv%a(3) = (1.0_default, 0.0_default) vv%a(4) = (3.0_default, 0.0_default) vv = pr_psi(p, m, w, .false., vv) <> if (.not. passed) then stop 1 end if end program test_omega95_bispinors @ <>= print *, "*** Checking the equations of motion ***:" call expect (abs(f_vf(c_one,vp,u(m,p,+1))-m*u(m,p,+1)), 0, "|[p-m]u(+)|=0", passed) call expect (abs(f_vf(c_one,vp,u(m,p,-1))-m*u(m,p,-1)), 0, "|[p-m]u(-)|=0", passed) call expect (abs(f_vf(c_one,vp,v(m,p,+1))+m*v(m,p,+1)), 0, "|[p+m]v(+)|=0", passed) call expect (abs(f_vf(c_one,vp,v(m,p,-1))+m*v(m,p,-1)), 0, "|[p+m]v(-)|=0", passed) print *, "*** Checking the equations of motion for negative masses***:" call expect (abs(f_vf(c_one,vp,u(-m,p,+1))+m*u(-m,p,+1)), 0, "|[p+m]u(+)|=0", passed) call expect (abs(f_vf(c_one,vp,u(-m,p,-1))+m*u(-m,p,-1)), 0, "|[p+m]u(-)|=0", passed) call expect (abs(f_vf(c_one,vp,v(-m,p,+1))-m*v(-m,p,+1)), 0, "|[p-m]v(+)|=0", passed) call expect (abs(f_vf(c_one,vp,v(-m,p,-1))-m*v(-m,p,-1)), 0, "|[p-m]v(-)|=0", passed) @ <>= print *, "*** Checking the normalization ***:" call expect (s_ff(c_one,v(m,p,+1),u(m,p,+1)), +2*m, "ubar(+)*u(+)=+2m", passed) call expect (s_ff(c_one,v(m,p,-1),u(m,p,-1)), +2*m, "ubar(-)*u(-)=+2m", passed) call expect (s_ff(c_one,u(m,p,+1),v(m,p,+1)), -2*m, "vbar(+)*v(+)=-2m", passed) call expect (s_ff(c_one,u(m,p,-1),v(m,p,-1)), -2*m, "vbar(-)*v(-)=-2m", passed) call expect (s_ff(c_one,v(m,p,+1),v(m,p,+1)), 0, "ubar(+)*v(+)=0 ", passed) call expect (s_ff(c_one,v(m,p,-1),v(m,p,-1)), 0, "ubar(-)*v(-)=0 ", passed) call expect (s_ff(c_one,u(m,p,+1),u(m,p,+1)), 0, "vbar(+)*u(+)=0 ", passed) call expect (s_ff(c_one,u(m,p,-1),u(m,p,-1)), 0, "vbar(-)*u(-)=0 ", passed) print *, "*** Checking the normalization for negative masses***:" call expect (s_ff(c_one,v(-m,p,+1),u(-m,p,+1)), -2*m, "ubar(+)*u(+)=-2m", passed) call expect (s_ff(c_one,v(-m,p,-1),u(-m,p,-1)), -2*m, "ubar(-)*u(-)=-2m", passed) call expect (s_ff(c_one,u(-m,p,+1),v(-m,p,+1)), +2*m, "vbar(+)*v(+)=+2m", passed) call expect (s_ff(c_one,u(-m,p,-1),v(-m,p,-1)), +2*m, "vbar(-)*v(-)=+2m", passed) call expect (s_ff(c_one,v(-m,p,+1),v(-m,p,+1)), 0, "ubar(+)*v(+)=0 ", passed) call expect (s_ff(c_one,v(-m,p,-1),v(-m,p,-1)), 0, "ubar(-)*v(-)=0 ", passed) call expect (s_ff(c_one,u(-m,p,+1),u(-m,p,+1)), 0, "vbar(+)*u(+)=0 ", passed) call expect (s_ff(c_one,u(-m,p,-1),u(-m,p,-1)), 0, "vbar(-)*u(-)=0 ", passed) @ <>= print *, "*** Checking the currents ***:" call expect (abs(v_ff(c_one,v(m,p,+1),u(m,p,+1))-2*vp), 0, "ubar(+).V.u(+)=2p", passed) call expect (abs(v_ff(c_one,v(m,p,-1),u(m,p,-1))-2*vp), 0, "ubar(-).V.u(-)=2p", passed) call expect (abs(v_ff(c_one,u(m,p,+1),v(m,p,+1))-2*vp), 0, "vbar(+).V.v(+)=2p", passed) call expect (abs(v_ff(c_one,u(m,p,-1),v(m,p,-1))-2*vp), 0, "vbar(-).V.v(-)=2p", passed) print *, "*** Checking the currents for negative masses***:" call expect (abs(v_ff(c_one,v(-m,p,+1),u(-m,p,+1))-2*vp), 0, "ubar(+).V.u(+)=2p", passed) call expect (abs(v_ff(c_one,v(-m,p,-1),u(-m,p,-1))-2*vp), 0, "ubar(-).V.u(-)=2p", passed) call expect (abs(v_ff(c_one,u(-m,p,+1),v(-m,p,+1))-2*vp), 0, "vbar(+).V.v(+)=2p", passed) call expect (abs(v_ff(c_one,u(-m,p,-1),v(-m,p,-1))-2*vp), 0, "vbar(-).V.v(-)=2p", passed) @ <>= print *, "*** Checking current conservation ***:" call expect ((vp-vq)*v_ff(c_one,v(m,p,+1),u(m,q,+1)), 0, "d(ubar(+).V.u(+))=0", passed) call expect ((vp-vq)*v_ff(c_one,v(m,p,-1),u(m,q,-1)), 0, "d(ubar(-).V.u(-))=0", passed) call expect ((vp-vq)*v_ff(c_one,u(m,p,+1),v(m,q,+1)), 0, "d(vbar(+).V.v(+))=0", passed) call expect ((vp-vq)*v_ff(c_one,u(m,p,-1),v(m,q,-1)), 0, "d(vbar(-).V.v(-))=0", passed) <>= print *, "*** Checking current conservation for negative masses***:" call expect ((vp-vq)*v_ff(c_one,v(-m,p,+1),u(-m,q,+1)), 0, "d(ubar(+).V.u(+))=0", passed) call expect ((vp-vq)*v_ff(c_one,v(-m,p,-1),u(-m,q,-1)), 0, "d(ubar(-).V.u(-))=0", passed) call expect ((vp-vq)*v_ff(c_one,u(-m,p,+1),v(-m,q,+1)), 0, "d(vbar(+).V.v(+))=0", passed) call expect ((vp-vq)*v_ff(c_one,u(-m,p,-1),v(-m,q,-1)), 0, "d(vbar(-).V.v(-))=0", passed) @ <>= if (m == 0) then print *, "*** Checking axial current conservation ***:" call expect ((vp-vq)*a_ff(c_one,v(m,p,+1),u(m,q,+1)), 0, "d(ubar(+).A.u(+))=0", passed) call expect ((vp-vq)*a_ff(c_one,v(m,p,-1),u(m,q,-1)), 0, "d(ubar(-).A.u(-))=0", passed) call expect ((vp-vq)*a_ff(c_one,u(m,p,+1),v(m,q,+1)), 0, "d(vbar(+).A.v(+))=0", passed) call expect ((vp-vq)*a_ff(c_one,u(m,p,-1),v(m,q,-1)), 0, "d(vbar(-).A.v(-))=0", passed) end if <>= print *, "*** Checking implementation of the sigma vertex funktions ***:" call expect ((vp*tvam_ff(c_one,c_nil,v(m,p,+1),u(m,q,+1),q) - (p*q-m**2)*(v(m,p,+1)*u(m,q,+1))), 0, & "p*[ubar(p,+).(Isigma*q).u(q,+)] - (p*q-m^2)*ubar(p,+).u(q,+) = 0", passed) call expect ((vp*tvam_ff(c_one,c_nil,v(m,p,-1),u(m,q,-1),q) - (p*q-m**2)*(v(m,p,-1)*u(m,q,-1))), 0, & "p*[ubar(p,-).(Isigma*q).u(q,-)] - (p*q-m^2)*ubar(p,-).u(q,-) = 0", passed) call expect ((vp*tvam_ff(c_one,c_nil,u(m,p,+1),v(m,q,+1),q) - (p*q-m**2)*(u(m,p,+1)*v(m,q,+1))), 0, & "p*[vbar(p,+).(Isigma*q).v(q,+)] - (p*q-m^2)*vbar(p,+).v(q,+) = 0", passed) call expect ((vp*tvam_ff(c_one,c_nil,u(m,p,-1),v(m,q,-1),q) - (p*q-m**2)*(u(m,p,-1)*v(m,q,-1))), 0, & "p*[vbar(p,-).(Isigma*q).v(q,-)] - (p*q-m^2)*vbar(p,-).v(q,-) = 0", passed) call expect ((v(m,p,+1)*f_tvamf(c_one,c_nil,vp,u(m,q,+1),q) - (p*q-m**2)*(v(m,p,+1)*u(m,q,+1))), 0, & "ubar(p,+).[p*(Isigma*q).u(q,+)] - (p*q-m^2)*ubar(p,+).u(q,+) = 0", passed) call expect ((v(m,p,-1)*f_tvamf(c_one,c_nil,vp,u(m,q,-1),q) - (p*q-m**2)*(v(m,p,-1)*u(m,q,-1))), 0, & "ubar(p,-).[p*(Isigma*q).u(q,-)] - (p*q-m^2)*ubar(p,-).u(q,-) = 0", passed) call expect ((u(m,p,+1)*f_tvamf(c_one,c_nil,vp,v(m,q,+1),q) - (p*q-m**2)*(u(m,p,+1)*v(m,q,+1))), 0, & "vbar(p,+).[p*(Isigma*q).v(q,+)] - (p*q-m^2)*vbar(p,+).v(q,+) = 0", passed) call expect ((u(m,p,-1)*f_tvamf(c_one,c_nil,vp,v(m,q,-1),q) - (p*q-m**2)*(u(m,p,-1)*v(m,q,-1))), 0, & "vbar(p,-).[p*(Isigma*q).v(q,-)] - (p*q-m^2)*vbar(p,-).v(q,-) = 0", passed) call expect ((vp*tvam_ff(c_nil,c_one,v(m,p,+1),u(m,q,+1),q) - (p*q+m**2)*p_ff(c_one,v(m,p,+1),u(m,q,+1))), 0, & "p*[ubar(p,+).(Isigma*q).g5.u(q,+)] - (p*q+m^2)*ubar(p,+).g5.u(q,+) = 0", passed) call expect ((vp*tvam_ff(c_nil,c_one,v(m,p,-1),u(m,q,-1),q) - (p*q+m**2)*p_ff(c_one,v(m,p,-1),u(m,q,-1))), 0, & "p*[ubar(p,-).(Isigma*q).g5.u(q,-)] - (p*q+m^2)*ubar(p,-).g5.u(q,-) = 0", passed) call expect ((vp*tvam_ff(c_nil,c_one,u(m,p,+1),v(m,q,+1),q) - (p*q+m**2)*p_ff(c_one,u(m,p,+1),v(m,q,+1))), 0, & "p*[vbar(p,+).(Isigma*q).g5.v(q,+)] - (p*q+m^2)*vbar(p,+).g5.v(q,+) = 0", passed) call expect ((vp*tvam_ff(c_nil,c_one,u(m,p,-1),v(m,q,-1),q) - (p*q+m**2)*p_ff(c_one,u(m,p,-1),v(m,q,-1))), 0, & "p*[vbar(p,-).(Isigma*q).g5.v(q,-)] - (p*q+m^2)*vbar(p,-).g5.v(q,-) = 0", passed) call expect ((v(m,p,+1)*f_tvamf(c_nil,c_one,vp,u(m,q,+1),q) - (p*q+m**2)*p_ff(c_one,v(m,p,+1),u(m,q,+1))), 0, & "p*[ubar(p,+).(Isigma*q).g5.u(q,+)] - (p*q+m^2)*ubar(p,+).g5.u(q,+) = 0", passed) call expect ((v(m,p,-1)*f_tvamf(c_nil,c_one,vp,u(m,q,-1),q) - (p*q+m**2)*p_ff(c_one,v(m,p,-1),u(m,q,-1))), 0, & "p*[ubar(p,-).(Isigma*q).g5.u(q,-)] - (p*q+m^2)*ubar(p,-).g5.u(q,-) = 0", passed) call expect ((u(m,p,+1)*f_tvamf(c_nil,c_one,vp,v(m,q,+1),q) - (p*q+m**2)*p_ff(c_one,u(m,p,+1),v(m,q,+1))), 0, & "p*[vbar(p,+).(Isigma*q).g5.v(q,+)] - (p*q+m^2)*vbar(p,+).g5.v(q,+) = 0", passed) call expect ((u(m,p,-1)*f_tvamf(c_nil,c_one,vp,v(m,q,-1),q) - (p*q+m**2)*p_ff(c_one,u(m,p,-1),v(m,q,-1))), 0, & "p*[vbar(p,-).(Isigma*q).g5.v(q,-)] - (p*q+m^2)*vbar(p,-).g5.v(q,-) = 0", passed) @ <>= print *, "*** Checking polarization vectors: ***" call expect (conjg(eps(m,p, 1))*eps(m,p, 1), -1, "e( 1).e( 1)=-1", passed) call expect (conjg(eps(m,p, 1))*eps(m,p,-1), 0, "e( 1).e(-1)= 0", passed) call expect (conjg(eps(m,p,-1))*eps(m,p, 1), 0, "e(-1).e( 1)= 0", passed) call expect (conjg(eps(m,p,-1))*eps(m,p,-1), -1, "e(-1).e(-1)=-1", passed) call expect ( p*eps(m,p, 1), 0, " p.e( 1)= 0", passed) call expect ( p*eps(m,p,-1), 0, " p.e(-1)= 0", passed) if (m > 0) then call expect (conjg(eps(m,p, 1))*eps(m,p, 0), 0, "e( 1).e( 0)= 0", passed) call expect (conjg(eps(m,p, 0))*eps(m,p, 1), 0, "e( 0).e( 1)= 0", passed) call expect (conjg(eps(m,p, 0))*eps(m,p, 0), -1, "e( 0).e( 0)=-1", passed) call expect (conjg(eps(m,p, 0))*eps(m,p,-1), 0, "e( 0).e(-1)= 0", passed) call expect (conjg(eps(m,p,-1))*eps(m,p, 0), 0, "e(-1).e( 0)= 0", passed) call expect ( p*eps(m,p, 0), 0, " p.e( 0)= 0", passed) end if @ <>= print *, "*** Checking polarization vectorspinors: ***" call expect (abs(p * ueps(m, p, 2)), 0, "p.ueps ( 2)= 0", passed) call expect (abs(p * ueps(m, p, 1)), 0, "p.ueps ( 1)= 0", passed) call expect (abs(p * ueps(m, p, -1)), 0, "p.ueps (-1)= 0", passed) call expect (abs(p * ueps(m, p, -2)), 0, "p.ueps (-2)= 0", passed) call expect (abs(p * veps(m, p, 2)), 0, "p.veps ( 2)= 0", passed) call expect (abs(p * veps(m, p, 1)), 0, "p.veps ( 1)= 0", passed) call expect (abs(p * veps(m, p, -1)), 0, "p.veps (-1)= 0", passed) call expect (abs(p * veps(m, p, -2)), 0, "p.veps (-2)= 0", passed) print *, "*** Checking polarization vectorspinors (neg. masses): ***" call expect (abs(p * ueps(-m, p, 2)), 0, "p.ueps ( 2)= 0", passed) call expect (abs(p * ueps(-m, p, 1)), 0, "p.ueps ( 1)= 0", passed) call expect (abs(p * ueps(-m, p, -1)), 0, "p.ueps (-1)= 0", passed) call expect (abs(p * ueps(-m, p, -2)), 0, "p.ueps (-2)= 0", passed) call expect (abs(p * veps(-m, p, 2)), 0, "p.veps ( 2)= 0", passed) call expect (abs(p * veps(-m, p, 1)), 0, "p.veps ( 1)= 0", passed) call expect (abs(p * veps(-m, p, -1)), 0, "p.veps (-1)= 0", passed) call expect (abs(p * veps(-m, p, -2)), 0, "p.veps (-2)= 0", passed) print *, "*** in the rest frame ***" call expect (abs(p_0 * ueps(m, p_0, 2)), 0, "p0.ueps ( 2)= 0", passed) call expect (abs(p_0 * ueps(m, p_0, 1)), 0, "p0.ueps ( 1)= 0", passed) call expect (abs(p_0 * ueps(m, p_0, -1)), 0, "p0.ueps (-1)= 0", passed) call expect (abs(p_0 * ueps(m, p_0, -2)), 0, "p0.ueps (-2)= 0", passed) call expect (abs(p_0 * veps(m, p_0, 2)), 0, "p0.veps ( 2)= 0", passed) call expect (abs(p_0 * veps(m, p_0, 1)), 0, "p0.veps ( 1)= 0", passed) call expect (abs(p_0 * veps(m, p_0, -1)), 0, "p0.veps (-1)= 0", passed) call expect (abs(p_0 * veps(m, p_0, -2)), 0, "p0.veps (-2)= 0", passed) print *, "*** in the rest frame (neg. masses) ***" call expect (abs(p_0 * ueps(-m, p_0, 2)), 0, "p0.ueps ( 2)= 0", passed) call expect (abs(p_0 * ueps(-m, p_0, 1)), 0, "p0.ueps ( 1)= 0", passed) call expect (abs(p_0 * ueps(-m, p_0, -1)), 0, "p0.ueps (-1)= 0", passed) call expect (abs(p_0 * ueps(-m, p_0, -2)), 0, "p0.ueps (-2)= 0", passed) call expect (abs(p_0 * veps(-m, p_0, 2)), 0, "p0.veps ( 2)= 0", passed) call expect (abs(p_0 * veps(-m, p_0, 1)), 0, "p0.veps ( 1)= 0", passed) call expect (abs(p_0 * veps(-m, p_0, -1)), 0, "p0.veps (-1)= 0", passed) call expect (abs(p_0 * veps(-m, p_0, -2)), 0, "p0.veps (-2)= 0", passed) @ <>= print *, "*** Checking the irreducibility condition: ***" call expect (abs(f_potgr (c_one, c_one, ueps(m, p, 2))), 0, "g.ueps ( 2)", passed) call expect (abs(f_potgr (c_one, c_one, ueps(m, p, 1))), 0, "g.ueps ( 1)", passed) call expect (abs(f_potgr (c_one, c_one, ueps(m, p, -1))), 0, "g.ueps (-1)", passed) call expect (abs(f_potgr (c_one, c_one, ueps(m, p, -2))), 0, "g.ueps (-2)", passed) call expect (abs(f_potgr (c_one, c_one, veps(m, p, 2))), 0, "g.veps ( 2)", passed) call expect (abs(f_potgr (c_one, c_one, veps(m, p, 1))), 0, "g.veps ( 1)", passed) call expect (abs(f_potgr (c_one, c_one, veps(m, p, -1))), 0, "g.veps (-1)", passed) call expect (abs(f_potgr (c_one, c_one, veps(m, p, -2))), 0, "g.veps (-2)", passed) print *, "*** Checking the irreducibility condition (neg. masses): ***" call expect (abs(f_potgr (c_one, c_one, ueps(-m, p, 2))), 0, "g.ueps ( 2)", passed) call expect (abs(f_potgr (c_one, c_one, ueps(-m, p, 1))), 0, "g.ueps ( 1)", passed) call expect (abs(f_potgr (c_one, c_one, ueps(-m, p, -1))), 0, "g.ueps (-1)", passed) call expect (abs(f_potgr (c_one, c_one, ueps(-m, p, -2))), 0, "g.ueps (-2)", passed) call expect (abs(f_potgr (c_one, c_one, veps(-m, p, 2))), 0, "g.veps ( 2)", passed) call expect (abs(f_potgr (c_one, c_one, veps(-m, p, 1))), 0, "g.veps ( 1)", passed) call expect (abs(f_potgr (c_one, c_one, veps(-m, p, -1))), 0, "g.veps (-1)", passed) call expect (abs(f_potgr (c_one, c_one, veps(-m, p, -2))), 0, "g.veps (-2)", passed) print *, "*** in the rest frame ***" call expect (abs(f_potgr (c_one, c_one, ueps(m, p_0, 2))), 0, "g.ueps ( 2)", passed) call expect (abs(f_potgr (c_one, c_one, ueps(m, p_0, 1))), 0, "g.ueps ( 1)", passed) call expect (abs(f_potgr (c_one, c_one, ueps(m, p_0, -1))), 0, "g.ueps (-1)", passed) call expect (abs(f_potgr (c_one, c_one, ueps(m, p_0, -2))), 0, "g.ueps (-2)", passed) call expect (abs(f_potgr (c_one, c_one, veps(m, p_0, 2))), 0, "g.veps ( 2)", passed) call expect (abs(f_potgr (c_one, c_one, veps(m, p_0, 1))), 0, "g.veps ( 1)", passed) call expect (abs(f_potgr (c_one, c_one, veps(m, p_0, -1))), 0, "g.veps (-1)", passed) call expect (abs(f_potgr (c_one, c_one, veps(m, p_0, -2))), 0, "g.veps (-2)", passed) print *, "*** in the rest frame (neg. masses) ***" call expect (abs(f_potgr (c_one, c_one, ueps(m, p_0, 2))), 0, "g.ueps ( 2)", passed) call expect (abs(f_potgr (c_one, c_one, ueps(m, p_0, 1))), 0, "g.ueps ( 1)", passed) call expect (abs(f_potgr (c_one, c_one, ueps(m, p_0, -1))), 0, "g.ueps (-1)", passed) call expect (abs(f_potgr (c_one, c_one, ueps(m, p_0, -2))), 0, "g.ueps (-2)", passed) call expect (abs(f_potgr (c_one, c_one, veps(m, p_0, 2))), 0, "g.veps ( 2)", passed) call expect (abs(f_potgr (c_one, c_one, veps(m, p_0, 1))), 0, "g.veps ( 1)", passed) call expect (abs(f_potgr (c_one, c_one, veps(m, p_0, -1))), 0, "g.veps (-1)", passed) call expect (abs(f_potgr (c_one, c_one, veps(m, p_0, -2))), 0, "g.veps (-2)", passed) @ <>= print *, "*** Testing vectorspinor normalization ***" call expect (veps(m,p, 2)*ueps(m,p, 2), -2*m, "ueps( 2).ueps( 2)= -2m", passed) call expect (veps(m,p, 1)*ueps(m,p, 1), -2*m, "ueps( 1).ueps( 1)= -2m", passed) call expect (veps(m,p,-1)*ueps(m,p,-1), -2*m, "ueps(-1).ueps(-1)= -2m", passed) call expect (veps(m,p,-2)*ueps(m,p,-2), -2*m, "ueps(-2).ueps(-2)= -2m", passed) call expect (ueps(m,p, 2)*veps(m,p, 2), 2*m, "veps( 2).veps( 2)= +2m", passed) call expect (ueps(m,p, 1)*veps(m,p, 1), 2*m, "veps( 1).veps( 1)= +2m", passed) call expect (ueps(m,p,-1)*veps(m,p,-1), 2*m, "veps(-1).veps(-1)= +2m", passed) call expect (ueps(m,p,-2)*veps(m,p,-2), 2*m, "veps(-2).veps(-2)= +2m", passed) call expect (ueps(m,p, 2)*ueps(m,p, 2), 0, "ueps( 2).veps( 2)= 0", passed) call expect (ueps(m,p, 1)*ueps(m,p, 1), 0, "ueps( 1).veps( 1)= 0", passed) call expect (ueps(m,p,-1)*ueps(m,p,-1), 0, "ueps(-1).veps(-1)= 0", passed) call expect (ueps(m,p,-2)*ueps(m,p,-2), 0, "ueps(-2).veps(-2)= 0", passed) call expect (veps(m,p, 2)*veps(m,p, 2), 0, "veps( 2).ueps( 2)= 0", passed) call expect (veps(m,p, 1)*veps(m,p, 1), 0, "veps( 1).ueps( 1)= 0", passed) call expect (veps(m,p,-1)*veps(m,p,-1), 0, "veps(-1).ueps(-1)= 0", passed) call expect (veps(m,p,-2)*veps(m,p,-2), 0, "veps(-2).ueps(-2)= 0", passed) print *, "*** Testing vectorspinor normalization (neg. masses) ***" call expect (veps(-m,p, 2)*ueps(-m,p, 2), +2*m, "ueps( 2).ueps( 2)= +2m", passed) call expect (veps(-m,p, 1)*ueps(-m,p, 1), +2*m, "ueps( 1).ueps( 1)= +2m", passed) call expect (veps(-m,p,-1)*ueps(-m,p,-1), +2*m, "ueps(-1).ueps(-1)= +2m", passed) call expect (veps(-m,p,-2)*ueps(-m,p,-2), +2*m, "ueps(-2).ueps(-2)= +2m", passed) call expect (ueps(-m,p, 2)*veps(-m,p, 2), -2*m, "veps( 2).veps( 2)= -2m", passed) call expect (ueps(-m,p, 1)*veps(-m,p, 1), -2*m, "veps( 1).veps( 1)= -2m", passed) call expect (ueps(-m,p,-1)*veps(-m,p,-1), -2*m, "veps(-1).veps(-1)= -2m", passed) call expect (ueps(-m,p,-2)*veps(-m,p,-2), -2*m, "veps(-2).veps(-2)= -2m", passed) call expect (ueps(-m,p, 2)*ueps(-m,p, 2), 0, "ueps( 2).veps( 2)= 0", passed) call expect (ueps(-m,p, 1)*ueps(-m,p, 1), 0, "ueps( 1).veps( 1)= 0", passed) call expect (ueps(-m,p,-1)*ueps(-m,p,-1), 0, "ueps(-1).veps(-1)= 0", passed) call expect (ueps(-m,p,-2)*ueps(-m,p,-2), 0, "ueps(-2).veps(-2)= 0", passed) call expect (veps(-m,p, 2)*veps(-m,p, 2), 0, "veps( 2).ueps( 2)= 0", passed) call expect (veps(-m,p, 1)*veps(-m,p, 1), 0, "veps( 1).ueps( 1)= 0", passed) call expect (veps(-m,p,-1)*veps(-m,p,-1), 0, "veps(-1).ueps(-1)= 0", passed) call expect (veps(-m,p,-2)*veps(-m,p,-2), 0, "veps(-2).ueps(-2)= 0", passed) print *, "*** in the rest frame ***" call expect (veps(m,p_0, 2)*ueps(m,p_0, 2), -2*m, "ueps( 2).ueps( 2)= -2m", passed) call expect (veps(m,p_0, 1)*ueps(m,p_0, 1), -2*m, "ueps( 1).ueps( 1)= -2m", passed) call expect (veps(m,p_0,-1)*ueps(m,p_0,-1), -2*m, "ueps(-1).ueps(-1)= -2m", passed) call expect (veps(m,p_0,-2)*ueps(m,p_0,-2), -2*m, "ueps(-2).ueps(-2)= -2m", passed) call expect (ueps(m,p_0, 2)*veps(m,p_0, 2), 2*m, "veps( 2).veps( 2)= +2m", passed) call expect (ueps(m,p_0, 1)*veps(m,p_0, 1), 2*m, "veps( 1).veps( 1)= +2m", passed) call expect (ueps(m,p_0,-1)*veps(m,p_0,-1), 2*m, "veps(-1).veps(-1)= +2m", passed) call expect (ueps(m,p_0,-2)*veps(m,p_0,-2), 2*m, "veps(-2).veps(-2)= +2m", passed) call expect (ueps(m,p_0, 2)*ueps(m,p_0, 2), 0, "ueps( 2).veps( 2)= 0", passed) call expect (ueps(m,p_0, 1)*ueps(m,p_0, 1), 0, "ueps( 1).veps( 1)= 0", passed) call expect (ueps(m,p_0,-1)*ueps(m,p_0,-1), 0, "ueps(-1).veps(-1)= 0", passed) call expect (ueps(m,p_0,-2)*ueps(m,p_0,-2), 0, "ueps(-2).veps(-2)= 0", passed) call expect (veps(m,p_0, 2)*veps(m,p_0, 2), 0, "veps( 2).ueps( 2)= 0", passed) call expect (veps(m,p_0, 1)*veps(m,p_0, 1), 0, "veps( 1).ueps( 1)= 0", passed) call expect (veps(m,p_0,-1)*veps(m,p_0,-1), 0, "veps(-1).ueps(-1)= 0", passed) call expect (veps(m,p_0,-2)*veps(m,p_0,-2), 0, "veps(-2).ueps(-2)= 0", passed) print *, "*** in the rest frame (neg. masses) ***" call expect (veps(-m,p_0, 2)*ueps(-m,p_0, 2), +2*m, "ueps( 2).ueps( 2)= +2m", passed) call expect (veps(-m,p_0, 1)*ueps(-m,p_0, 1), +2*m, "ueps( 1).ueps( 1)= +2m", passed) call expect (veps(-m,p_0,-1)*ueps(-m,p_0,-1), +2*m, "ueps(-1).ueps(-1)= +2m", passed) call expect (veps(-m,p_0,-2)*ueps(-m,p_0,-2), +2*m, "ueps(-2).ueps(-2)= +2m", passed) call expect (ueps(-m,p_0, 2)*veps(-m,p_0, 2), -2*m, "veps( 2).veps( 2)= -2m", passed) call expect (ueps(-m,p_0, 1)*veps(-m,p_0, 1), -2*m, "veps( 1).veps( 1)= -2m", passed) call expect (ueps(-m,p_0,-1)*veps(-m,p_0,-1), -2*m, "veps(-1).veps(-1)= -2m", passed) call expect (ueps(-m,p_0,-2)*veps(-m,p_0,-2), -2*m, "veps(-2).veps(-2)= -2m", passed) call expect (ueps(-m,p_0, 2)*ueps(-m,p_0, 2), 0, "ueps( 2).veps( 2)= 0", passed) call expect (ueps(-m,p_0, 1)*ueps(-m,p_0, 1), 0, "ueps( 1).veps( 1)= 0", passed) call expect (ueps(-m,p_0,-1)*ueps(-m,p_0,-1), 0, "ueps(-1).veps(-1)= 0", passed) call expect (ueps(-m,p_0,-2)*ueps(-m,p_0,-2), 0, "ueps(-2).veps(-2)= 0", passed) call expect (veps(-m,p_0, 2)*veps(-m,p_0, 2), 0, "veps( 2).ueps( 2)= 0", passed) call expect (veps(-m,p_0, 1)*veps(-m,p_0, 1), 0, "veps( 1).ueps( 1)= 0", passed) call expect (veps(-m,p_0,-1)*veps(-m,p_0,-1), 0, "veps(-1).ueps(-1)= 0", passed) call expect (veps(-m,p_0,-2)*veps(-m,p_0,-2), 0, "veps(-2).ueps(-2)= 0", passed) @ <>= print *, "*** Majorana properties of gravitino vertices: ***" call expect (abs(u (m,q,1) * f_sgr (c_one, c_one, ueps(m,p,2), t) + & ueps(m,p,2) * gr_sf(c_one,c_one,u(m,q,1),t)), 0, "f_sgr + gr_sf = 0", passed) !!! call expect (abs(u (m,q,-1) * f_sgr (c_one, c_one, ueps(m,p,2), t) + & !!! ueps(m,p,2) * gr_sf(c_one,c_one,u(m,q,-1),t)), 0, "f_sgr + gr_sf = 0", passed) !!! call expect (abs(u (m,q,1) * f_sgr (c_one, c_one, ueps(m,p,1), t) + & !!! ueps(m,p,1) * gr_sf(c_one,c_one,u(m,q,1),t)), 0, "f_sgr + gr_sf = 0", passed) !!! call expect (abs(u (m,q,-1) * f_sgr (c_one, c_one, ueps(m,p,1), t) + & !!! ueps(m,p,1) * gr_sf(c_one,c_one,u(m,q,-1),t)), 0, "f_sgr + gr_sf = 0", passed) !!! call expect (abs(u (m,q,1) * f_sgr (c_one, c_one, ueps(m,p,-1), t) + & !!! ueps(m,p,-1) * gr_sf(c_one,c_one,u(m,q,1),t)), 0, "f_sgr + gr_sf = 0", passed) !!! call expect (abs(u (m,q,-1) * f_sgr (c_one, c_one, ueps(m,p,-1), t) + & !!! ueps(m,p,-1) * gr_sf(c_one,c_one,u(m,q,-1),t)), 0, "f_sgr + gr_sf = 0", passed) !!! call expect (abs(u (m,q,1) * f_sgr (c_one, c_one, ueps(m,p,-2), t) + & !!! ueps(m,p,-2) * gr_sf(c_one,c_one,u(m,q,1),t)), 0, "f_sgr + gr_sf = 0", passed) !!! call expect (abs(u (m,q,-1) * f_sgr (c_one, c_one, ueps(m,p,-2), t) + & !!! ueps(m,p,-2) * gr_sf(c_one,c_one,u(m,q,-1),t)), 0, "f_sgr + gr_sf = 0", passed) call expect (abs(u (m,q,1) * f_slgr (c_one, c_one, ueps(m,p,2), t) + & ueps(m,p,2) * gr_slf(c_one,c_one,u(m,q,1),t)), 0, "f_slgr + gr_slf = 0", passed, threshold = 0.5_default) call expect (abs(u (m,q,1) * f_srgr (c_one, c_one, ueps(m,p,2), t) + & ueps(m,p,2) * gr_srf(c_one,c_one,u(m,q,1),t)), 0, "f_srgr + gr_srf = 0", passed, threshold = 0.5_default) call expect (abs(u (m,q,1) * f_slrgr (c_one, c_two, c_one, ueps(m,p,2), t) + & ueps(m,p,2) * gr_slrf(c_one,c_two,c_one,u(m,q,1),t)), 0, "f_slrgr + gr_slrf = 0", passed, threshold = 0.5_default) call expect (abs(u (m,q,1) * f_pgr (c_one, c_one, ueps(m,p,2), t) + & ueps(m,p,2) * gr_pf(c_one,c_one,u(m,q,1),t)), 0, "f_pgr + gr_pf = 0", passed, threshold = 0.5_default) call expect (abs(u (m,q,1) * f_vgr (c_one, vt, ueps(m,p,2), p+q) + & ueps(m,p,2) * gr_vf(c_one,vt,u(m,q,1),p+q)), 0, "f_vgr + gr_vf = 0", passed, threshold = 0.5_default) call expect (abs(u (m,q,1) * f_vlrgr (c_one, c_two, vt, ueps(m,p,2), p+q) + & ueps(m,p,2) * gr_vlrf(c_one,c_two,vt,u(m,q,1),p+q)), 0, "f_vlrgr + gr_vlrf = 0", & passed, threshold = 0.5_default) !!! call expect (abs(u (m,q,-1) * f_vgr (c_one, vt, ueps(m,p,2), p+q) + & !!! ueps(m,p,2) * gr_vf(c_one,vt,u(m,q,-1),p+q)), 0, "f_vgr + gr_vf = 0", passed) !!! call expect (abs(u (m,q,1) * f_vgr (c_one, vt, ueps(m,p,1), p+q) + & !!! ueps(m,p,1) * gr_vf(c_one,vt,u(m,q,1),p+q)), 0, "f_vgr + gr_vf = 0", passed) !!! call expect (abs(u (m,q,-1) * f_vgr (c_one, vt, ueps(m,p,1), p+q) + & !!! ueps(m,p,1) * gr_vf(c_one,vt,u(m,q,-1),p+q)), 0, "f_vgr + gr_vf = 0", passed) !!! call expect (abs(u (m,q,1) * f_vgr (c_one, vt, ueps(m,p,-1), p+q) + & !!! ueps(m,p,-1) * gr_vf(c_one,vt,u(m,q,1),p+q)), 0, "f_vgr + gr_vf = 0", passed) !!! call expect (abs(u (m,q,-1) * f_vgr (c_one, vt, veps(m,p,-1), p+q) + & !!! veps(m,p,-1) * gr_vf(c_one,vt,u(m,q,-1),p+q)), 0, "f_vgr + gr_vf = 0", passed) !!! call expect (abs(v (m,q,1) * f_vgr (c_one, vt, ueps(m,p,-2), p+q) + & !!! ueps(m,p,-2) * gr_vf(c_one,vt,v(m,q,1),p+q)), 0, "f_vgr + gr_vf = 0", passed) !!! call expect (abs(u (m,q,-1) * f_vgr (c_one, vt, ueps(m,p,-2), p+q) + & !!! ueps(m,p,-2) * gr_vf(c_one,vt,u(m,q,-1),p+q)), 0, "f_vgr + gr_vf = 0", passed) call expect (abs(s_grf (c_one, ueps(m,p,2), u(m,q,1),t) + & s_fgr(c_one,u(m,q,1),ueps(m,p,2),t)), 0, "s_grf + s_fgr = 0", passed) call expect (abs(sl_grf (c_one, ueps(m,p,2), u(m,q,1),t) + & sl_fgr(c_one,u(m,q,1),ueps(m,p,2),t)), 0, "sl_grf + sl_fgr = 0", passed) call expect (abs(sr_grf (c_one, ueps(m,p,2), u(m,q,1),t) + & sr_fgr(c_one,u(m,q,1),ueps(m,p,2),t)), 0, "sr_grf + sr_fgr = 0", passed) call expect (abs(slr_grf (c_one, c_two, ueps(m,p,2), u(m,q,1),t) + & slr_fgr(c_one,c_two,u(m,q,1),ueps(m,p,2),t)), 0, "slr_grf + slr_fgr = 0", passed) call expect (abs(p_grf (c_one, ueps(m,p,2), u(m,q,1),t) + & p_fgr(c_one,u(m,q,1),ueps(m,p,2),t)), 0, "p_grf + p_fgr = 0", passed) call expect (abs(v_grf (c_one, ueps(m,p,2), u(m,q,1),t) + & v_fgr(c_one,u(m,q,1),ueps(m,p,2),t)), 0, "v_grf + v_fgr = 0", passed) call expect (abs(vlr_grf (c_one, c_two, ueps(m,p,2), u(m,q,1),t) + & vlr_fgr(c_one,c_two,u(m,q,1),ueps(m,p,2),t)), 0, "vlr_grf + vlr_fgr = 0", passed) call expect (abs(u(m,p,1) * f_potgr (c_one,c_one,testv) - testv * gr_potf & (c_one,c_one,u (m,p,1))), 0, "f_potgr - gr_potf = 0", passed) call expect (abs (pot_fgr (c_one,u(m,p,1),testv) - pot_grf(c_one, & testv,u(m,p,1))), 0, "pot_fgr - pot_grf = 0", passed) call expect (abs(u(m,p,1) * f_s2gr (c_one,c_one,c_one,testv) - testv * gr_s2f & (c_one,c_one,c_one,u (m,p,1))), 0, "f_s2gr - gr_s2f = 0", passed) call expect (abs (s2_fgr (c_one,u(m,p,1),c_one,testv) - s2_grf(c_one, & testv,c_one,u(m,p,1))), 0, "s2_fgr - s2_grf = 0", passed) call expect (abs(u (m,q,1) * f_svgr (c_one, c_one, vt, ueps(m,p,2)) + & ueps(m,p,2) * gr_svf(c_one,c_one,vt,u(m,q,1))), 0, "f_svgr + gr_svf = 0", passed) call expect (abs(u (m,q,1) * f_slvgr (c_one, c_one, vt, ueps(m,p,2)) + & ueps(m,p,2) * gr_slvf(c_one,c_one,vt,u(m,q,1))), 0, "f_slvgr + gr_slvf = 0", passed) call expect (abs(u (m,q,1) * f_srvgr (c_one, c_one, vt, ueps(m,p,2)) + & ueps(m,p,2) * gr_srvf(c_one,c_one,vt,u(m,q,1))), 0, "f_srvgr + gr_srvf = 0", passed) call expect (abs(u (m,q,1) * f_slrvgr (c_one, c_two, c_one, vt, ueps(m,p,2)) + & ueps(m,p,2) * gr_slrvf(c_one,c_two,c_one,vt,u(m,q,1))), 0, "f_slrvgr + gr_slrvf = 0", passed) call expect (abs (sv1_fgr (c_one,u(m,p,1),vt,ueps(m,q,2)) + sv1_grf(c_one, & ueps(m,q,2),vt,u(m,p,1))), 0, "sv1_fgr + sv1_grf = 0", passed) call expect (abs (sv2_fgr (c_one,u(m,p,1),c_one,ueps(m,q,2)) + sv2_grf(c_one, & ueps(m,q,2),c_one,u(m,p,1))), 0, "sv2_fgr + sv2_grf = 0", passed) call expect (abs (slv1_fgr (c_one,u(m,p,1),vt,ueps(m,q,2)) + slv1_grf(c_one, & ueps(m,q,2),vt,u(m,p,1))), 0, "slv1_fgr + slv1_grf = 0", passed) call expect (abs (srv2_fgr (c_one,u(m,p,1),c_one,ueps(m,q,2)) + srv2_grf(c_one, & ueps(m,q,2),c_one,u(m,p,1))), 0, "srv2_fgr + srv2_grf = 0", passed) call expect (abs (slrv1_fgr (c_one,c_two,u(m,p,1),vt,ueps(m,q,2)) + slrv1_grf(c_one,c_two, & ueps(m,q,2),vt,u(m,p,1))), 0, "slrv1_fgr + slrv1_grf = 0", passed) call expect (abs (slrv2_fgr (c_one,c_two,u(m,p,1),c_one,ueps(m,q,2)) + slrv2_grf(c_one, & c_two,ueps(m,q,2),c_one,u(m,p,1))), 0, "slrv2_fgr + slrv2_grf = 0", passed) call expect (abs(u (m,q,1) * f_pvgr (c_one, c_one, vt, ueps(m,p,2)) + & ueps(m,p,2) * gr_pvf(c_one,c_one,vt,u(m,q,1))), 0, "f_pvgr + gr_pvf = 0", passed) call expect (abs (pv1_fgr (c_one,u(m,p,1),vt,ueps(m,q,2)) + pv1_grf(c_one, & ueps(m,q,2),vt,u(m,p,1))), 0, "pv1_fgr + pv1_grf = 0", passed) call expect (abs (pv2_fgr (c_one,u(m,p,1),c_one,ueps(m,q,2)) + pv2_grf(c_one, & ueps(m,q,2),c_one,u(m,p,1))), 0, "pv2_fgr + pv2_grf = 0", passed) call expect (abs(u (m,q,1) * f_v2gr (c_one, vt, vz, ueps(m,p,2)) + & ueps(m,p,2) * gr_v2f(c_one,vt,vz,u(m,q,1))), 0, "f_v2gr + gr_v2f = 0", passed) call expect (abs(u (m,q,1) * f_v2lrgr (c_one, c_two, vt, vz, ueps(m,p,2)) + & ueps(m,p,2) * gr_v2lrf(c_one,c_two,vt,vz,u(m,q,1))), 0, "f_v2lrgr + gr_v2lrf = 0", passed) call expect (abs (v2_fgr (c_one,u(m,p,1),vt,ueps(m,q,2)) + v2_grf(c_one, & ueps(m,q,2),vt,u(m,p,1))), 0, "v2_fgr + v2_grf = 0", passed) call expect (abs (v2lr_fgr (c_one,c_two,u(m,p,1),vt,ueps(m,q,2)) + v2lr_grf(c_one, c_two, & ueps(m,q,2),vt,u(m,p,1))), 0, "v2lr_fgr + v2lr_grf = 0", passed) @ <>= print *, "*** Testing the gravitino propagator: ***" print *, "Transversality:" call expect (abs(p * (cmplx (p*p - m**2, m*w, kind=default) * & pr_grav(p,m,w,testv))), 0, "p.pr.test", passed) call expect (abs(p * (cmplx (p*p - m**2, m*w, kind=default) * & pr_grav(p,m,w,ueps(m,p,2)))), 0, "p.pr.ueps ( 2)", passed) call expect (abs(p * (cmplx (p*p - m**2, m*w, kind=default) * & pr_grav(p,m,w,ueps(m,p,1)))), 0, "p.pr.ueps ( 1)", passed) call expect (abs(p * (cmplx (p*p - m**2, m*w, kind=default) * & pr_grav(p,m,w,ueps(m,p,-1)))), 0, "p.pr.ueps (-1)", passed) call expect (abs(p * (cmplx (p*p - m**2, m*w, kind=default) * & pr_grav(p,m,w,ueps(m,p,-2)))), 0, "p.pr.ueps (-2)", passed) call expect (abs(p * (cmplx (p*p - m**2, m*w, kind=default) * & pr_grav(p,m,w,veps(m,p,2)))), 0, "p.pr.veps ( 2)", passed) call expect (abs(p * (cmplx (p*p - m**2, m*w, kind=default) * & pr_grav(p,m,w,veps(m,p,1)))), 0, "p.pr.veps ( 1)", passed) call expect (abs(p * (cmplx (p*p - m**2, m*w, kind=default) * & pr_grav(p,m,w,veps(m,p,-1)))), 0, "p.pr.veps (-1)", passed) call expect (abs(p * (cmplx (p*p - m**2, m*w, kind=default) * & pr_grav(p,m,w,veps(m,p,-2)))), 0, "p.pr.veps (-2)", passed) print *, "Irreducibility:" call expect (abs(f_potgr (c_one, c_one, (cmplx (p*p - m**2, m*w, & kind=default) * pr_grav(p,m,w,testv)))), 0, "g.pr.test", passed) call expect (abs(f_potgr (c_one, c_one, (cmplx (p*p - m**2, m*w, & kind=default) * pr_grav(p,m,w,ueps(m,p,2))))), 0, & "g.pr.ueps ( 2)", passed) call expect (abs(f_potgr (c_one, c_one, (cmplx (p*p - m**2, m*w, & kind=default) * pr_grav(p,m,w,ueps(m,p,1))))), 0, & "g.pr.ueps ( 1)", passed) call expect (abs(f_potgr (c_one, c_one, (cmplx (p*p - m**2, m*w, & kind=default) * pr_grav(p,m,w,ueps(m,p,-1))))), 0, & "g.pr.ueps (-1)", passed) call expect (abs(f_potgr (c_one, c_one, (cmplx (p*p - m**2, m*w, & kind=default) * pr_grav(p,m,w,ueps(m,p,-2))))), 0, & "g.pr.ueps (-2)", passed) call expect (abs(f_potgr (c_one, c_one, (cmplx (p*p - m**2, m*w, & kind=default) * pr_grav(p,m,w,veps(m,p,2))))), 0, & "g.pr.veps ( 2)", passed) call expect (abs(f_potgr (c_one, c_one, (cmplx (p*p - m**2, m*w, & kind=default) * pr_grav(p,m,w,veps(m,p,1))))), 0, & "g.pr.veps ( 1)", passed) call expect (abs(f_potgr (c_one, c_one, (cmplx (p*p - m**2, m*w, & kind=default) * pr_grav(p,m,w,veps(m,p,-1))))), 0, & "g.pr.veps (-1)", passed) call expect (abs(f_potgr (c_one, c_one, (cmplx (p*p - m**2, m*w, & kind=default) * pr_grav(p,m,w,veps(m,p,-2))))), 0, & "g.pr.veps (-2)", passed) @ <<[[omega_bundle.f90]]>>= <<[[omega_vectors.f90]]>> <<[[omega_spinors.f90]]>> <<[[omega_bispinors.f90]]>> <<[[omega_vectorspinors.f90]]>> <<[[omega_polarizations.f90]]>> <<[[omega_tensors.f90]]>> <<[[omega_tensor_polarizations.f90]]>> <<[[omega_couplings.f90]]>> <<[[omega_spinor_couplings.f90]]>> <<[[omega_bispinor_couplings.f90]]>> <<[[omega_vspinor_polarizations.f90]]>> <<[[omega_utils.f90]]>> <<[[omega95.f90]]>> <<[[omega95_bispinors.f90]]>> <<[[omega_parameters.f90]]>> <<[[omega_parameters_madgraph.f90]]>> @ <<[[omega_bundle_whizard.f90]]>>= <<[[omega_bundle.f90]]>> <<[[omega_parameters_whizard.f90]]>> @ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{O'Mega Virtual Machine} This module defines the O'Mega Virtual Machine (OVM) completely, whereby all environmental dependencies like masses, widths and couplings have to be given to the constructor [[vm%init]] at runtime. Support for Majorana particles and vectorspinors is only partially, especially all fusions are missing. Maybe it would be easier to make an additional [[omegavm95_bispinors]] to avoid namespace issues. Non-type specific chunks could be reused <<[[omegavm95.f90]]>>= <> module omegavm95 use kinds, only: default use constants use iso_varying_string, string_t => varying_string use, intrinsic :: iso_fortran_env, only : input_unit, output_unit, error_unit use omega95 use omega95_bispinors, only: bispinor, vectorspinor, veps, pr_grav use omega95_bispinors, only: bi_u => u use omega95_bispinors, only: bi_v => v use omega95_bispinors, only: bi_pr_psi => pr_psi use omega_bispinors, only: operator (*), operator (+) use omega_color, only: ovm_color_sum, OCF => omega_color_factor implicit none private <> <> <> contains <> <> end module omegavm95 @ This might not be the proper place but I don't know where to put it <>= integer, parameter, public :: stdin = input_unit integer, parameter, public :: stdout = output_unit integer, parameter, public :: stderr = error_unit integer, parameter :: MIN_UNIT = 11, MAX_UNIT = 99 @ <>= subroutine find_free_unit (u, iostat) integer, intent(out) :: u integer, intent(out), optional :: iostat logical :: exists, is_open integer :: i, status do i = MIN_UNIT, MAX_UNIT inquire (unit = i, exist = exists, opened = is_open, & iostat = status) if (status == 0) then if (exists .and. .not. is_open) then u = i if (present (iostat)) then iostat = 0 end if return end if end if end do if (present (iostat)) then iostat = -1 end if u = -1 end subroutine find_free_unit @ These abstract data types would ideally be the interface to communicate quantum numbers between O'Mega and Whizard. This gives full flexibility to change the representation at any time <>= public :: color_t type color_t contains procedure :: write => color_write end type color_t public :: col_discrete type, extends(color_t) :: col_discrete integer :: i end type col_discrete public :: flavor_t type flavor_t contains procedure :: write => flavor_write end type flavor_t public :: flv_discrete type, extends(flavor_t) :: flv_discrete integer :: i end type flv_discrete public :: helicity_t type :: helicity_t contains procedure :: write => helicity_write end type helicity_t public :: hel_discrete type, extends(helicity_t) :: hel_discrete integer :: i end type hel_discrete public :: hel_trigonometric type, extends(helicity_t) :: hel_trigonometric real :: theta end type hel_trigonometric public :: hel_exponential type, extends(helicity_t) :: hel_exponential real :: phi end type hel_exponential public :: hel_spherical type, extends(helicity_t) :: hel_spherical real :: theta, phi end type hel_spherical <>= subroutine color_write (color, fh) class(color_t), intent(in) :: color integer, intent(in) :: fh select type(color) type is (col_discrete) write(fh, *) 'color_discrete%i = ', color%i end select end subroutine color_write subroutine helicity_write (helicity, fh) class(helicity_t), intent(in) :: helicity integer, intent(in) :: fh select type(helicity) type is (hel_discrete) write(fh, *) 'helicity_discrete%i = ', helicity%i type is (hel_trigonometric) write(fh, *) 'helicity_trigonometric%theta = ', helicity%theta type is (hel_exponential) write(fh, *) 'helicity_exponential%phi = ', helicity%phi type is (hel_spherical) write(fh, *) 'helicity_spherical%phi = ', helicity%phi write(fh, *) 'helicity_spherical%theta = ', helicity%theta end select end subroutine helicity_write subroutine flavor_write (flavor, fh) class(flavor_t), intent(in) :: flavor integer, intent(in) :: fh select type(flavor) type is (flv_discrete) write(fh, *) 'flavor_discrete%i = ', flavor%i end select end subroutine flavor_write @ \subsection{Memory Layout} Some internal parameters <>= integer, parameter :: len_instructions = 8 integer, parameter :: N_version_lines = 2 ! Comment lines including the first header description line integer, parameter :: N_comments = 6 ! Actual data lines plus intermediate description lines ! 'description \n 1 2 3 \n description \n 3 2 1' would count as 3 integer, parameter :: N_header_lines = 5 real(default), parameter, public :: N_ = three @ This is the basic type of a VM <>= type :: basic_vm_t private logical :: verbose type(string_t) :: bytecode_file integer :: bytecode_fh, out_fh integer :: N_instructions, N_levels integer :: N_table_lines integer, dimension(:, :), allocatable :: instructions integer, dimension(:), allocatable :: levels end type @ To allow for a lazy evaluation of amplitudes, we have to keep track whether a wave function has already been computed, to avoid multiple-computing that would arise when the bytecode has redundant fusions, which is necessary for flavor and color MC (and helicity MC when we use Weyl-van-der-Waerden-spinors) <>= type :: vm_scalar logical :: c complex(kind=default) :: v end type type :: vm_spinor logical :: c type(spinor) :: v end type type :: vm_conjspinor logical :: c type(conjspinor) :: v end type type :: vm_bispinor logical :: c type(bispinor) :: v end type type :: vm_vector logical :: c type(vector) :: v end type type :: vm_tensor_2 logical :: c type(tensor) :: v end type type :: vm_tensor_1 logical :: c type(tensor2odd) :: v end type type :: vm_vectorspinor logical :: c type(vectorspinor) :: v end type @ We need a memory pool for all the intermediate results <>= type, public, extends (basic_vm_t) :: vm_t private type(string_t) :: version type(string_t) :: model integer :: N_momenta, N_particles, N_prt_in, N_prt_out, N_amplitudes ! helicities = helicity combinations integer :: N_helicities, N_col_flows, N_col_indices, N_flavors, N_col_factors integer :: N_scalars, N_spinors, N_conjspinors, N_bispinors integer :: N_vectors, N_tensors_2, N_tensors_1, N_vectorspinors integer :: N_coupl_real, N_coupl_real2, N_coupl_cmplx, N_coupl_cmplx2 integer, dimension(:, :), allocatable :: table_flavor integer, dimension(:, :, :), allocatable :: table_color_flows integer, dimension(:, :), allocatable :: table_spin logical, dimension(:, :), allocatable :: table_ghost_flags type(OCF), dimension(:), allocatable :: table_color_factors logical, dimension(:, :), allocatable :: table_flv_col_is_allowed real(default), dimension(:), allocatable :: coupl_real real(default), dimension(:, :), allocatable :: coupl_real2 complex(default), dimension(:), allocatable :: coupl_cmplx complex(default), dimension(:, :), allocatable :: coupl_cmplx2 real(default), dimension(:), allocatable :: mass real(default), dimension(:), allocatable :: width type(momentum), dimension(:), allocatable :: momenta complex(default), dimension(:), allocatable :: amplitudes complex(default), dimension(:, :, :), allocatable :: table_amplitudes class(flavor_t), dimension(:), allocatable :: flavor class(color_t), dimension(:), allocatable :: color ! gfortran 4.7 !class(helicity_t), dimension(:), pointer :: helicity => null() integer, dimension(:), allocatable :: helicity type(vm_scalar), dimension(:), allocatable :: scalars type(vm_spinor), dimension(:), allocatable :: spinors type(vm_conjspinor), dimension(:), allocatable :: conjspinors type(vm_bispinor), dimension(:), allocatable :: bispinors type(vm_vector), dimension(:), allocatable :: vectors type(vm_tensor_2), dimension(:), allocatable :: tensors_2 type(vm_tensor_1), dimension(:), allocatable :: tensors_1 type(vm_vectorspinor), dimension(:), allocatable :: vectorspinors logical, dimension(:), allocatable :: hel_is_allowed real(default), dimension(:), allocatable :: hel_max_abs real(default) :: hel_sum_abs = 0, hel_threshold = 1E10 integer :: hel_count = 0, hel_cutoff = 100 integer, dimension(:), allocatable :: hel_map integer :: hel_finite logical :: cms logical :: openmp contains <> end type @ <>= subroutine alloc_arrays (vm) type(vm_t), intent(inout) :: vm integer :: i allocate (vm%table_flavor(vm%N_particles, vm%N_flavors)) allocate (vm%table_color_flows(vm%N_col_indices, vm%N_particles, & vm%N_col_flows)) allocate (vm%table_spin(vm%N_particles, vm%N_helicities)) allocate (vm%table_ghost_flags(vm%N_particles, vm%N_col_flows)) allocate (vm%table_color_factors(vm%N_col_factors)) allocate (vm%table_flv_col_is_allowed(vm%N_flavors, vm%N_col_flows)) allocate (vm%momenta(vm%N_momenta)) allocate (vm%amplitudes(vm%N_amplitudes)) allocate (vm%table_amplitudes(vm%N_flavors, vm%N_col_flows, & vm%N_helicities)) vm%table_amplitudes = zero allocate (vm%scalars(vm%N_scalars)) allocate (vm%spinors(vm%N_spinors)) allocate (vm%conjspinors(vm%N_conjspinors)) allocate (vm%bispinors(vm%N_bispinors)) allocate (vm%vectors(vm%N_vectors)) allocate (vm%tensors_2(vm%N_tensors_2)) allocate (vm%tensors_1(vm%N_tensors_1)) allocate (vm%vectorspinors(vm%N_vectorspinors)) allocate (vm%hel_is_allowed(vm%N_helicities)) vm%hel_is_allowed = .True. allocate (vm%hel_max_abs(vm%N_helicities)) vm%hel_max_abs = 0 allocate (vm%hel_map(vm%N_helicities)) vm%hel_map = (/(i, i = 1, vm%N_helicities)/) vm%hel_finite = vm%N_helicities end subroutine alloc_arrays @ \subsection{Controlling the VM} These type-bound procedures steer the VM <>= procedure :: init => vm_init procedure :: write => vm_write procedure :: reset => vm_reset procedure :: run => vm_run procedure :: final => vm_final @ The [[init]] completely sets the environment for the OVM. Parameters can be changed with [[reset]] without reloading the bytecode. <>= subroutine vm_init (vm, bytecode_file, version, model, & coupl_real, coupl_real2, coupl_cmplx, coupl_cmplx2, & mass, width, verbose, out_fh, openmp) class(vm_t), intent(out) :: vm type(string_t), intent(in) :: bytecode_file type(string_t), intent(in) :: version type(string_t), intent(in) :: model real(default), dimension(:), optional, intent(in) :: coupl_real real(default), dimension(:, :), optional, intent(in) :: coupl_real2 complex(default), dimension(:), optional, intent(in) :: coupl_cmplx complex(default), dimension(:, :), optional, intent(in) :: coupl_cmplx2 real(default), dimension(:), optional, intent(in) :: mass real(default), dimension(:), optional, intent(in) :: width logical, optional, intent(in) :: verbose integer, optional, intent(in) :: out_fh logical, optional, intent(in) :: openmp vm%bytecode_file = bytecode_file vm%version = version vm%model = model if (present (coupl_real)) then allocate (vm%coupl_real (size (coupl_real)), source=coupl_real) end if if (present (coupl_real2)) then allocate (vm%coupl_real2 (2, size (coupl_real2, 2)), source=coupl_real2) end if if (present (coupl_cmplx)) then allocate (vm%coupl_cmplx (size (coupl_cmplx)), source=coupl_cmplx) end if if (present (coupl_cmplx2)) then allocate (vm%coupl_cmplx2 (2, size (coupl_cmplx2, 2)), & source=coupl_cmplx2) end if if (present (mass)) then allocate (vm%mass(size(mass)), source=mass) end if if (present (width)) then allocate (vm%width(size (width)), source=width) end if if (present (openmp)) then vm%openmp = openmp else vm%openmp = .false. end if vm%cms = .false. call basic_init (vm, verbose, out_fh) end subroutine vm_init @ <>= subroutine vm_reset (vm, & coupl_real, coupl_real2, coupl_cmplx, coupl_cmplx2, & mass, width, verbose, out_fh) class(vm_t), intent(inout) :: vm real(default), dimension(:), optional, intent(in) :: coupl_real real(default), dimension(:, :), optional, intent(in) :: coupl_real2 complex(default), dimension(:), optional, intent(in) :: coupl_cmplx complex(default), dimension(:, :), optional, intent(in) :: coupl_cmplx2 real(default), dimension(:), optional, intent(in) :: mass real(default), dimension(:), optional, intent(in) :: width logical, optional, intent(in) :: verbose integer, optional, intent(in) :: out_fh if (present (coupl_real)) then vm%coupl_real = coupl_real end if if (present (coupl_real2)) then vm%coupl_real2 = coupl_real2 end if if (present (coupl_cmplx)) then vm%coupl_cmplx = coupl_cmplx end if if (present (coupl_cmplx2)) then vm%coupl_cmplx2 = coupl_cmplx2 end if if (present (mass)) then vm%mass = mass end if if (present (width)) then vm%width = width end if if (present (verbose)) then vm%verbose = verbose end if if (present (out_fh)) then vm%out_fh = out_fh end if end subroutine vm_reset @ Mainly for debugging <>= subroutine vm_write (vm) class(vm_t), intent(in) :: vm integer :: i, j, k call basic_write (vm) write(vm%out_fh, *) 'table_flavor = ', vm%table_flavor write(vm%out_fh, *) 'table_color_flows = ', vm%table_color_flows write(vm%out_fh, *) 'table_spin = ', vm%table_spin write(vm%out_fh, *) 'table_ghost_flags = ', vm%table_ghost_flags write(vm%out_fh, *) 'table_color_factors = ' do i = 1, size(vm%table_color_factors) write(vm%out_fh, *) vm%table_color_factors(i)%i1, & vm%table_color_factors(i)%i2, & vm%table_color_factors(i)%factor end do write(vm%out_fh, *) 'table_flv_col_is_allowed = ', & vm%table_flv_col_is_allowed do i = 1, vm%N_flavors do j = 1, vm%N_col_flows do k = 1, vm%N_helicities write(vm%out_fh, *) 'table_amplitudes(f,c,h), f, c, h = ', vm%table_amplitudes(i,j,k), i, j, k end do end do end do if (allocated(vm%coupl_real)) then write(vm%out_fh, *) 'coupl_real = ', vm%coupl_real end if if (allocated(vm%coupl_real2)) then write(vm%out_fh, *) 'coupl_real2 = ', vm%coupl_real2 end if if (allocated(vm%coupl_cmplx)) then write(vm%out_fh, *) 'coupl_cmplx = ', vm%coupl_cmplx end if if (allocated(vm%coupl_cmplx2)) then write(vm%out_fh, *) 'coupl_cmplx2 = ', vm%coupl_cmplx2 end if write(vm%out_fh, *) 'mass = ', vm%mass write(vm%out_fh, *) 'width = ', vm%width write(vm%out_fh, *) 'momenta = ', vm%momenta ! gfortran 4.7 !do i = 1, size(vm%flavor) !call vm%flavor(i)%write (vm%out_fh) !end do !do i = 1, size(vm%color) !call vm%color(i)%write (vm%out_fh) !end do !do i = 1, size(vm%helicity) !call vm%helicity(i)%write (vm%out_fh) !end do write(vm%out_fh, *) 'helicity = ', vm%helicity write(vm%out_fh, *) 'amplitudes = ', vm%amplitudes write(vm%out_fh, *) 'scalars = ', vm%scalars write(vm%out_fh, *) 'spinors = ', vm%spinors write(vm%out_fh, *) 'conjspinors = ', vm%conjspinors write(vm%out_fh, *) 'bispinors = ', vm%bispinors write(vm%out_fh, *) 'vectors = ', vm%vectors write(vm%out_fh, *) 'tensors_2 = ', vm%tensors_2 write(vm%out_fh, *) 'tensors_1 = ', vm%tensors_1 !!! !!! !!! Regression with ifort 16.0.0 !!! write(vm%out_fh, *) 'vectorspinors = ', vm%vectorspinors write(vm%out_fh, *) 'N_momenta = ', vm%N_momenta write(vm%out_fh, *) 'N_particles = ', vm%N_particles write(vm%out_fh, *) 'N_prt_in = ', vm%N_prt_in write(vm%out_fh, *) 'N_prt_out = ', vm%N_prt_out write(vm%out_fh, *) 'N_amplitudes = ', vm%N_amplitudes write(vm%out_fh, *) 'N_helicities = ', vm%N_helicities write(vm%out_fh, *) 'N_col_flows = ', vm%N_col_flows write(vm%out_fh, *) 'N_col_indices = ', vm%N_col_indices write(vm%out_fh, *) 'N_flavors = ', vm%N_flavors write(vm%out_fh, *) 'N_col_factors = ', vm%N_col_factors write(vm%out_fh, *) 'N_scalars = ', vm%N_scalars write(vm%out_fh, *) 'N_spinors = ', vm%N_spinors write(vm%out_fh, *) 'N_conjspinors = ', vm%N_conjspinors write(vm%out_fh, *) 'N_bispinors = ', vm%N_bispinors write(vm%out_fh, *) 'N_vectors = ', vm%N_vectors write(vm%out_fh, *) 'N_tensors_2 = ', vm%N_tensors_2 write(vm%out_fh, *) 'N_tensors_1 = ', vm%N_tensors_1 write(vm%out_fh, *) 'N_vectorspinors = ', vm%N_vectorspinors write(vm%out_fh, *) 'Overall size of VM: ' ! GNU extension ! write(vm%out_fh, *) 'sizeof(wavefunctions) = ', & ! sizeof(vm%scalars) + sizeof(vm%spinors) + sizeof(vm%conjspinors) + & ! sizeof(vm%bispinors) + sizeof(vm%vectors) + sizeof(vm%tensors_2) + & ! sizeof(vm%tensors_1) + sizeof(vm%vectorspinors) ! write(vm%out_fh, *) 'sizeof(mometa) = ', sizeof(vm%momenta) ! write(vm%out_fh, *) 'sizeof(amplitudes) = ', sizeof(vm%amplitudes) ! write(vm%out_fh, *) 'sizeof(tables) = ', & ! sizeof(vm%table_amplitudes) + sizeof(vm%table_spin) + & ! sizeof(vm%table_flavor) + sizeof(vm%table_flv_col_is_allowed) + & ! sizeof(vm%table_color_flows) + sizeof(vm%table_color_factors) + & ! sizeof(vm%table_ghost_flags) end subroutine vm_write @ Most of this is redundant (Fortran will deallocate when we leave the scope) but when we change from [[allocatable]]s to [[pointer]]s, it is necessary to avoid leaks <>= subroutine vm_final (vm) class(vm_t), intent(inout) :: vm deallocate (vm%table_flavor) deallocate (vm%table_color_flows) deallocate (vm%table_spin) deallocate (vm%table_ghost_flags) deallocate (vm%table_color_factors) deallocate (vm%table_flv_col_is_allowed) if (allocated (vm%coupl_real)) then deallocate (vm%coupl_real) end if if (allocated (vm%coupl_real2)) then deallocate (vm%coupl_real2) end if if (allocated (vm%coupl_cmplx)) then deallocate (vm%coupl_cmplx) end if if (allocated (vm%coupl_cmplx2)) then deallocate (vm%coupl_cmplx2) end if if (allocated (vm%mass)) then deallocate (vm%mass) end if if (allocated (vm%width)) then deallocate (vm%width) end if deallocate (vm%momenta) deallocate (vm%flavor) deallocate (vm%color) deallocate (vm%helicity) deallocate (vm%amplitudes) deallocate (vm%table_amplitudes) deallocate (vm%scalars) deallocate (vm%spinors) deallocate (vm%conjspinors) deallocate (vm%bispinors) deallocate (vm%vectors) deallocate (vm%tensors_2) deallocate (vm%tensors_1) deallocate (vm%vectorspinors) end subroutine vm_final @ Handing over the polymorph object helicity didn't work out as planned. A work-around is the use of [[pointer]]s. [[flavor]] and [[color]] are not yet used but would have to be changed to [[pointer]]s as well. At least this potentially avoids copying. Actually, neither the allocatable nor the pointer version works in [[gfortran 4.7]] due to the broken [[select type]]. Back to Stone Age, i.e. integers. <>= subroutine vm_run (vm, mom, flavor, color, helicity) class(vm_t), intent(inout) :: vm real(default), dimension(0:3, *), intent(in) :: mom class(flavor_t), dimension(:), optional, intent(in) :: flavor class(color_t), dimension(:), optional, intent(in) :: color ! gfortran 4.7 !class(helicity_t), dimension(:), optional, target, intent(in) :: helicity integer, dimension(:), optional, intent(in) :: helicity integer :: i, h, hi do i = 1, vm%N_particles if (i <= vm%N_prt_in) then vm%momenta(i) = - mom(:, i) ! incoming, crossing symmetry else vm%momenta(i) = mom(:, i) ! outgoing end if end do if (present (flavor)) then allocate(vm%flavor(size(flavor)), source=flavor) else if (.not. (allocated (vm%flavor))) then allocate(flv_discrete::vm%flavor(vm%N_particles)) end if end if if (present (color)) then allocate(vm%color(size(color)), source=color) else if (.not. (allocated (vm%color))) then allocate(col_discrete::vm%color(vm%N_col_flows)) end if end if ! gfortran 4.7 if (present (helicity)) then !vm%helicity => helicity vm%helicity = helicity call vm_run_one_helicity (vm, 1) else !if (.not. (associated (vm%helicity))) then !allocate(hel_discrete::vm%helicity(vm%N_particles)) !end if if (.not. (allocated (vm%helicity))) then allocate(vm%helicity(vm%N_particles)) end if if (vm%hel_finite == 0) return do hi = 1, vm%hel_finite h = vm%hel_map(hi) !> vm%helicity = vm%table_spin(:,h) call vm_run_one_helicity (vm, h) end do end if end subroutine vm_run @ This only removes the [[ICE]] but still leads to a segmentation fault in [[gfortran 4.7]]. I am running out of ideas how to make this compiler work with arrays of polymorph datatypes. <>= integer :: hj <>= do hj = 1, size(vm%helicity) select type (hel => vm%helicity(hj)) type is (hel_discrete) hel%i = vm%table_spin(hj,h) end select end do @ <>= select type (hel => vm%helicity) type is (hel_discrete) hel(:)%i = vm%table_spin(:,h) end select @ <>= subroutine vm_run_one_helicity (vm, h) class(vm_t), intent(inout) :: vm integer, intent(in) :: h integer :: f, c, i vm%amplitudes = zero if (vm%N_levels > 0) then call null_all_wfs (vm) call iterate_instructions (vm) end if i = 1 do c = 1, vm%N_col_flows do f = 1, vm%N_flavors if (vm%table_flv_col_is_allowed(f,c)) then vm%table_amplitudes(f,c,h) = vm%amplitudes(i) i = i + 1 end if end do end do end subroutine @ <>= subroutine null_all_wfs (vm) type(vm_t), intent(inout) :: vm integer :: i, j vm%scalars%c = .False. vm%scalars%v = zero vm%spinors%c = .False. vm%conjspinors%c = .False. vm%bispinors%c = .False. vm%vectorspinors%c = .False. do i = 1, 4 vm%spinors%v%a(i) = zero vm%conjspinors%v%a(i) = zero vm%bispinors%v%a(i) = zero do j = 1, 4 vm%vectorspinors%v%psi(i)%a(j) = zero end do end do vm%vectors%c = .False. vm%vectors%v%t = zero vm%tensors_1%c = .False. vm%tensors_2%c = .False. do i = 1, 3 vm%vectors%v%x(i) = zero vm%tensors_1%v%e(i) = zero vm%tensors_1%v%b(i) = zero do j = 1, 3 vm%tensors_2%v%t(i,j) = zero end do end do end subroutine @ \subsection{Reading the bytecode} <>= subroutine load_header (vm, IO) type(vm_t), intent(inout) :: vm integer, intent(inout) :: IO integer, dimension(len_instructions) :: line read(vm%bytecode_fh, fmt = *, iostat = IO) line vm%N_momenta = line(1) vm%N_particles = line(2) vm%N_prt_in = line(3) vm%N_prt_out = line(4) vm%N_amplitudes = line(5) vm%N_helicities = line(6) vm%N_col_flows = line(7) if (vm%N_momenta == 0) then vm%N_col_indices = 2 else vm%N_col_indices = line(8) end if read(vm%bytecode_fh, fmt = *, iostat = IO) read(vm%bytecode_fh, fmt = *, iostat = IO) line vm%N_flavors = line(1) vm%N_col_factors = line(2) vm%N_scalars = line(3) vm%N_spinors = line(4) vm%N_conjspinors = line(5) vm%N_bispinors = line(6) vm%N_vectors = line(7) vm%N_tensors_2 = line(8) read(vm%bytecode_fh, fmt = *, iostat = IO) read(vm%bytecode_fh, fmt = *, iostat = IO) line vm%N_tensors_1 = line(1) vm%N_vectorspinors = line(2) ! Add 1 for seperating label lines like 'Another table' vm%N_table_lines = vm%N_helicities + 1 + vm%N_flavors + 1 + vm%N_col_flows & + 1 + vm%N_col_flows + 1 + vm%N_col_factors + 1 + vm%N_col_flows end subroutine load_header @ <>= subroutine read_tables (vm, IO) type(vm_t), intent(inout) :: vm integer, intent(inout) :: IO integer :: i integer, dimension(2) :: tmpcf integer, dimension(3) :: tmpfactor integer, dimension(vm%N_flavors) :: tmpF integer, dimension(vm%N_particles) :: tmpP real(default) :: factor do i = 1, vm%N_helicities read(vm%bytecode_fh, fmt = *, iostat = IO) vm%table_spin(:, i) end do read(vm%bytecode_fh, fmt = *, iostat = IO) do i = 1, vm%N_flavors read(vm%bytecode_fh, fmt = *, iostat = IO) vm%table_flavor(:, i) end do read(vm%bytecode_fh, fmt = *, iostat = IO) do i = 1, vm%N_col_flows read(vm%bytecode_fh, fmt = *, iostat = IO) vm%table_color_flows(:, :, i) end do read(vm%bytecode_fh, fmt = *, iostat = IO) do i = 1, vm%N_col_flows read(vm%bytecode_fh, fmt = *, iostat = IO) tmpP vm%table_ghost_flags(:, i) = int_to_log(tmpP) end do read(vm%bytecode_fh, fmt = *, iostat = IO) do i = 1, vm%N_col_factors read(vm%bytecode_fh, fmt = '(2I9)', iostat = IO, advance='no') tmpcf factor = zero do read(vm%bytecode_fh, fmt = '(3I9)', iostat = IO, advance='no', EOR=10) tmpfactor factor = factor + color_factor(tmpfactor(1), tmpfactor(2), tmpfactor(3)) end do 10 vm%table_color_factors(i) = OCF(tmpcf(1), tmpcf(2), factor) end do read(vm%bytecode_fh, fmt = *, iostat = IO) do i = 1, vm%N_col_flows read(vm%bytecode_fh, fmt = *, iostat = IO) tmpF vm%table_flv_col_is_allowed(:, i) = int_to_log(tmpF) end do end subroutine read_tables @ This checking has proven useful more than once <>= subroutine extended_version_check (vm, IO) type(vm_t), intent(in) :: vm integer, intent(inout) :: IO character(256) :: buffer read(vm%bytecode_fh, fmt = *, iostat = IO) buffer if (vm%model /= buffer) then print *, "Warning: Bytecode has been generated with an older SVN revision." else if (vm%verbose) then write (vm%out_fh, fmt = *) "Using the model: " write (vm%out_fh, fmt = *) char(vm%model) end if end if end subroutine extended_version_check @ This chunk is copied verbatim from the [[basic_vm]] <>= subroutine basic_init (vm, verbose, out_fh) type(vm_t), intent(inout) :: vm logical, optional, intent(in) :: verbose integer, optional, intent(in) :: out_fh if (present (verbose)) then vm%verbose = verbose else vm%verbose = .true. end if if (present (out_fh)) then vm%out_fh = out_fh else vm%out_fh = stdout end if call set_stream (vm) call alloc_and_count (vm) if (vm%N_levels > 0) then call read_bytecode (vm) call sanity_check (vm) end if close (vm%bytecode_fh) end subroutine basic_init subroutine basic_write (vm) type(vm_t), intent(in) :: vm integer :: i write (vm%out_fh, *) '=====> VM ', char(vm%version), ' <=====' write (vm%out_fh, *) 'verbose = ', vm%verbose write (vm%out_fh, *) 'bytecode_file = ', char (vm%bytecode_file) write (vm%out_fh, *) 'N_instructions = ', vm%N_instructions write (vm%out_fh, *) 'N_levels = ', vm%N_levels write (vm%out_fh, *) 'instructions = ' do i = 1, vm%N_instructions write (vm%out_fh, *) vm%instructions(:, i) end do write (vm%out_fh, *) 'levels = ', vm%levels end subroutine basic_write subroutine alloc_and_count (vm) type(vm_t), intent(inout) :: vm integer, dimension(len_instructions) :: line character(256) :: buffer integer :: i, IO read(vm%bytecode_fh, fmt = *, iostat = IO) buffer if (vm%version /= buffer) then print *, "Warning: Bytecode has been generated with an older SVN revision." else if (vm%verbose) then write (vm%out_fh, fmt = *) "Bytecode version fits." end if end if call extended_version_check (vm, IO) if (vm%verbose) then write (vm%out_fh, fmt = *) "Trying to allocate." end if do i = 1, N_comments read(vm%bytecode_fh, fmt = *, iostat = IO) end do call load_header (vm, IO) call alloc_arrays (vm) if (vm%N_momenta /= 0) then do i = 1, vm%N_table_lines + 1 read(vm%bytecode_fh, fmt = *, iostat = IO) end do vm%N_instructions = 0 vm%N_levels = 0 do read(vm%bytecode_fh, fmt = *, end = 42) line if (line(1) /= 0) then vm%N_instructions = vm%N_instructions + 1 else vm%N_levels = vm%N_levels + 1 end if end do 42 rewind(vm%bytecode_fh, iostat = IO) allocate (vm%instructions(len_instructions, vm%N_instructions)) allocate (vm%levels(vm%N_levels)) if (IO /= 0) then print *, "Error: vm.alloc : Couldn't load bytecode!" stop 1 end if end if end subroutine alloc_and_count subroutine read_bytecode (vm) type(vm_t), intent(inout) :: vm integer, dimension(len_instructions) :: line integer :: i, j, IO ! Jump over version number, comments, header and first table description do i = 1, N_version_lines + N_comments + N_header_lines + 1 read (vm%bytecode_fh, fmt = *, iostat = IO) end do call read_tables (vm, IO) read (vm%bytecode_fh, fmt = *, iostat = IO) i = 0; j = 0 do read (vm%bytecode_fh, fmt = *, iostat = IO) line if (IO /= 0) exit if (line(1) == 0) then if (j <= vm%N_levels) then j = j + 1 vm%levels(j) = i ! last index of a level is saved else print *, 'Error: vm.read_bytecode: File has more levels than anticipated!' stop 1 end if else if (i <= vm%N_instructions) then i = i + 1 ! A valid instruction line vm%instructions(:, i) = line else print *, 'Error: vm.read_bytecode: File is larger than anticipated!' stop 1 end if end if end do end subroutine read_bytecode subroutine iterate_instructions (vm) type(vm_t), intent(inout) :: vm integer :: i, j if (vm%openmp) then !$omp parallel do j = 1, vm%N_levels - 1 !$omp do schedule (static) do i = vm%levels (j) + 1, vm%levels (j + 1) call decode (vm, i) end do !$omp end do end do !$omp end parallel else do j = 1, vm%N_levels - 1 do i = vm%levels (j) + 1, vm%levels (j + 1) call decode (vm, i) end do end do end if end subroutine iterate_instructions subroutine set_stream (vm) type(vm_t), intent(inout) :: vm integer :: IO call find_free_unit (vm%bytecode_fh, IO) open (vm%bytecode_fh, file = char (vm%bytecode_file), form = 'formatted', & access = 'sequential', status = 'old', position = 'rewind', iostat = IO, & action = 'read') if (IO /= 0) then print *, "Error: vm.set_stream: Bytecode file '", char(vm%bytecode_file), & "' not found!" stop 1 end if end subroutine set_stream subroutine sanity_check (vm) type(vm_t), intent(in) :: vm if (vm%levels(1) /= 0) then print *, "Error: vm.vm_init: levels(1) != 0" stop 1 end if if (vm%levels(vm%N_levels) /= vm%N_instructions) then print *, "Error: vm.vm_init: levels(N_levels) != N_instructions" stop 1 end if if (vm%verbose) then write(vm%out_fh, *) "vm passed sanity check. Starting calculation." end if end subroutine sanity_check @ \subsection{Main Decode Function} This is the heart of the OVM <>= ! pure & ! if no warnings subroutine decode (vm, instruction_index) type(vm_t), intent(inout) :: vm integer, intent(in) :: instruction_index integer, dimension(len_instructions) :: i, curr complex(default) :: braket integer :: tmp real(default) :: w i = vm%instructions (:, instruction_index) select case (i(1)) case ( : -1) ! Jump over subinstructions <<[[case]]s of [[decode]]>> case (0) print *, 'Error: Levelbreak put in decode! Line:', & instruction_index stop 1 case default print *, "Error: Decode has case not catched! Line: ", & instruction_index stop 1 end select end subroutine decode @ \subsubsection{Momenta} The most trivial instruction <>= integer, parameter :: ovm_ADD_MOMENTA = 1 @ <<[[case]]s of [[decode]]>>= case (ovm_ADD_MOMENTA) vm%momenta(i(4)) = vm%momenta(i(5)) + vm%momenta(i(6)) if (i(7) > 0) then vm%momenta(i(4)) = vm%momenta(i(4)) + vm%momenta(i(7)) end if @ \subsubsection{Loading External states} <>= integer, parameter :: ovm_LOAD_SCALAR = 10 integer, parameter :: ovm_LOAD_SPINOR_INC = 11 integer, parameter :: ovm_LOAD_SPINOR_OUT = 12 integer, parameter :: ovm_LOAD_CONJSPINOR_INC = 13 integer, parameter :: ovm_LOAD_CONJSPINOR_OUT = 14 integer, parameter :: ovm_LOAD_MAJORANA_INC = 15 integer, parameter :: ovm_LOAD_MAJORANA_OUT = 16 integer, parameter :: ovm_LOAD_VECTOR_INC = 17 integer, parameter :: ovm_LOAD_VECTOR_OUT = 18 integer, parameter :: ovm_LOAD_VECTORSPINOR_INC = 19 integer, parameter :: ovm_LOAD_VECTORSPINOR_OUT = 20 integer, parameter :: ovm_LOAD_TENSOR2_INC = 21 integer, parameter :: ovm_LOAD_TENSOR2_OUT = 22 integer, parameter :: ovm_LOAD_BRS_SCALAR = 30 integer, parameter :: ovm_LOAD_BRS_SPINOR_INC = 31 integer, parameter :: ovm_LOAD_BRS_SPINOR_OUT = 32 integer, parameter :: ovm_LOAD_BRS_CONJSPINOR_INC = 33 integer, parameter :: ovm_LOAD_BRS_CONJSPINOR_OUT = 34 integer, parameter :: ovm_LOAD_BRS_VECTOR_INC = 37 integer, parameter :: ovm_LOAD_BRS_VECTOR_OUT = 38 integer, parameter :: ovm_LOAD_MAJORANA_GHOST_INC = 23 integer, parameter :: ovm_LOAD_MAJORANA_GHOST_OUT = 24 integer, parameter :: ovm_LOAD_BRS_MAJORANA_INC = 35 integer, parameter :: ovm_LOAD_BRS_MAJORANA_OUT = 36 @ <<[[case]]s of [[decode]]>>= case (ovm_LOAD_SCALAR) vm%scalars(i(4))%v = one vm%scalars(i(4))%c = .True. case (ovm_LOAD_SPINOR_INC) call load_spinor(vm%spinors(i(4)), - <

>, <>, & vm%helicity(i(5)), ovm_LOAD_SPINOR_INC) case (ovm_LOAD_SPINOR_OUT) call load_spinor(vm%spinors(i(4)), <

>, <>, & vm%helicity(i(5)), ovm_LOAD_SPINOR_OUT) case (ovm_LOAD_CONJSPINOR_INC) call load_conjspinor(vm%conjspinors(i(4)), - <

>, & <>, vm%helicity(i(5)), ovm_LOAD_CONJSPINOR_INC) case (ovm_LOAD_CONJSPINOR_OUT) call load_conjspinor(vm%conjspinors(i(4)), <

>, & <>, vm%helicity(i(5)), ovm_LOAD_CONJSPINOR_OUT) case (ovm_LOAD_MAJORANA_INC) call load_bispinor(vm%bispinors(i(4)), - <

>, & <>, vm%helicity(i(5)), ovm_LOAD_MAJORANA_INC) case (ovm_LOAD_MAJORANA_OUT) call load_bispinor(vm%bispinors(i(4)), <

>, <>, & vm%helicity(i(5)), ovm_LOAD_MAJORANA_OUT) case (ovm_LOAD_VECTOR_INC) call load_vector(vm%vectors(i(4)), - <

>, <>, & vm%helicity(i(5)), ovm_LOAD_VECTOR_INC) case (ovm_LOAD_VECTOR_OUT) call load_vector(vm%vectors(i(4)), <

>, <>, & vm%helicity(i(5)), ovm_LOAD_VECTOR_OUT) case (ovm_LOAD_VECTORSPINOR_INC) !select type (h => vm%helicity(i(5))) !type is (hel_discrete) !vm%vectorspinors(i(4))%v = veps(<>, - <

>, & !h%i) !end select vm%vectorspinors(i(4))%v = veps(<>, - <

>, & vm%helicity(i(5))) vm%vectorspinors(i(4))%c = .True. case (ovm_LOAD_VECTORSPINOR_OUT) !select type (h => vm%helicity(i(5))) !type is (hel_discrete) !vm%vectorspinors(i(4))%v = veps(<>, <

>, & !h%i) !end select vm%vectorspinors(i(4))%v = veps(<>, <

>, & vm%helicity(i(5))) vm%vectorspinors(i(4))%c = .True. case (ovm_LOAD_TENSOR2_INC) !select type (h => vm%helicity(i(5))) !type is (hel_discrete) !vm%tensors_2(i(4))%v = eps2(<>, - <

>, & !h%i) !end select vm%tensors_2(i(4))%c = .True. case (ovm_LOAD_TENSOR2_OUT) !select type (h => vm%helicity(i(5))) !type is (hel_discrete) !vm%tensors_2(i(4))%v = eps2(<>, <

>, h%i) !end select vm%tensors_2(i(4))%c = .True. case (ovm_LOAD_BRS_SCALAR) vm%scalars(i(4))%v = (0, -1) * (<

> * <

> - & <>**2) vm%scalars(i(4))%c = .True. case (ovm_LOAD_BRS_SPINOR_INC) print *, 'not implemented' stop 1 case (ovm_LOAD_BRS_SPINOR_OUT) print *, 'not implemented' stop 1 case (ovm_LOAD_BRS_CONJSPINOR_INC) print *, 'not implemented' stop 1 case (ovm_LOAD_BRS_CONJSPINOR_OUT) print *, 'not implemented' stop 1 case (ovm_LOAD_BRS_VECTOR_INC) print *, 'not implemented' stop 1 case (ovm_LOAD_BRS_VECTOR_OUT) print *, 'not implemented' stop 1 case (ovm_LOAD_MAJORANA_GHOST_INC) print *, 'not implemented' stop 1 case (ovm_LOAD_MAJORANA_GHOST_OUT) print *, 'not implemented' stop 1 case (ovm_LOAD_BRS_MAJORANA_INC) print *, 'not implemented' stop 1 case (ovm_LOAD_BRS_MAJORANA_OUT) print *, 'not implemented' stop 1 @ \subsubsection{Brakets and Fusions} NB: during, execution, the type of the coupling constant is implicit in the instruction <>= integer, parameter :: ovm_CALC_BRAKET = 2 integer, parameter :: ovm_FUSE_V_FF = -1 integer, parameter :: ovm_FUSE_F_VF = -2 integer, parameter :: ovm_FUSE_F_FV = -3 integer, parameter :: ovm_FUSE_VA_FF = -4 integer, parameter :: ovm_FUSE_F_VAF = -5 integer, parameter :: ovm_FUSE_F_FVA = -6 integer, parameter :: ovm_FUSE_VA2_FF = -7 integer, parameter :: ovm_FUSE_F_VA2F = -8 integer, parameter :: ovm_FUSE_F_FVA2 = -9 integer, parameter :: ovm_FUSE_A_FF = -10 integer, parameter :: ovm_FUSE_F_AF = -11 integer, parameter :: ovm_FUSE_F_FA = -12 integer, parameter :: ovm_FUSE_VL_FF = -13 integer, parameter :: ovm_FUSE_F_VLF = -14 integer, parameter :: ovm_FUSE_F_FVL = -15 integer, parameter :: ovm_FUSE_VR_FF = -16 integer, parameter :: ovm_FUSE_F_VRF = -17 integer, parameter :: ovm_FUSE_F_FVR = -18 integer, parameter :: ovm_FUSE_VLR_FF = -19 integer, parameter :: ovm_FUSE_F_VLRF = -20 integer, parameter :: ovm_FUSE_F_FVLR = -21 integer, parameter :: ovm_FUSE_SP_FF = -22 integer, parameter :: ovm_FUSE_F_SPF = -23 integer, parameter :: ovm_FUSE_F_FSP = -24 integer, parameter :: ovm_FUSE_S_FF = -25 integer, parameter :: ovm_FUSE_F_SF = -26 integer, parameter :: ovm_FUSE_F_FS = -27 integer, parameter :: ovm_FUSE_P_FF = -28 integer, parameter :: ovm_FUSE_F_PF = -29 integer, parameter :: ovm_FUSE_F_FP = -30 integer, parameter :: ovm_FUSE_SL_FF = -31 integer, parameter :: ovm_FUSE_F_SLF = -32 integer, parameter :: ovm_FUSE_F_FSL = -33 integer, parameter :: ovm_FUSE_SR_FF = -34 integer, parameter :: ovm_FUSE_F_SRF = -35 integer, parameter :: ovm_FUSE_F_FSR = -36 integer, parameter :: ovm_FUSE_SLR_FF = -37 integer, parameter :: ovm_FUSE_F_SLRF = -38 integer, parameter :: ovm_FUSE_F_FSLR = -39 integer, parameter :: ovm_FUSE_G_GG = -40 integer, parameter :: ovm_FUSE_V_SS = -41 integer, parameter :: ovm_FUSE_S_VV = -42 integer, parameter :: ovm_FUSE_S_VS = -43 integer, parameter :: ovm_FUSE_V_SV = -44 integer, parameter :: ovm_FUSE_S_SS = -45 integer, parameter :: ovm_FUSE_S_SVV = -46 integer, parameter :: ovm_FUSE_V_SSV = -47 integer, parameter :: ovm_FUSE_S_SSS = -48 integer, parameter :: ovm_FUSE_V_VVV = -49 integer, parameter :: ovm_FUSE_S_G2 = -50 integer, parameter :: ovm_FUSE_G_SG = -51 integer, parameter :: ovm_FUSE_G_GS = -52 integer, parameter :: ovm_FUSE_S_G2_SKEW = -53 integer, parameter :: ovm_FUSE_G_SG_SKEW = -54 integer, parameter :: ovm_FUSE_G_GS_SKEW = -55 @ Shorthands <

>= vm%momenta(i(5)) <>= vm%mass(i(2)) <>= vm%momenta(curr(6)) <>= vm%momenta(curr(8)) <>= vm%vectors(curr(5))%v <>= vm%vectors(curr(7))%v <>= vm%scalars(curr(5))%v <>= vm%scalars(curr(7))%v <>= sgn_coupl_cmplx(vm, curr(2)) <>= sgn_coupl_cmplx2(vm, curr(2), 1) <>= sgn_coupl_cmplx2(vm, curr(2), 2) @ <>= if ((i(4) == o%cols(1)) .or. (i(4) == o%cols(2)) .or. & ((mode%col_MC .eq. FULL_SUM) .or. (mode%col_MC .eq. DIAG_COL))) then @ Just a stub for now. Will be reimplemented with the polymorph type [[color]] similar to the [[select type(helicity)]] when we need it. <>= @ <<[[case]]s of [[decode]]>>= case (ovm_CALC_BRAKET) <> tmp = instruction_index + 1 do if (tmp > vm%N_instructions) exit curr = vm%instructions(:, tmp) if (curr(1) >= 0) exit ! End of fusions select case (curr(1)) case (ovm_FUSE_V_FF, ovm_FUSE_VL_FF, ovm_FUSE_VR_FF) braket = vm%vectors(curr(4))%v * vec_ff(vm, curr) case (ovm_FUSE_F_VF, ovm_FUSE_F_VLF, ovm_FUSE_F_VRF) braket = vm%conjspinors(curr(4))%v * ferm_vf(vm, curr) case (ovm_FUSE_F_FV, ovm_FUSE_F_FVL, ovm_FUSE_F_FVR) braket = ferm_fv(vm, curr) * vm%spinors(curr(4))%v case (ovm_FUSE_VA_FF) braket = vm%vectors(curr(4))%v * vec_ff2(vm, curr) case (ovm_FUSE_F_VAF) braket = vm%conjspinors(curr(4))%v * ferm_vf2(vm, curr) case (ovm_FUSE_F_FVA) braket = ferm_fv2(vm, curr) * vm%spinors(curr(4))%v case (ovm_FUSE_S_FF, ovm_FUSE_SP_FF) braket = vm%scalars(curr(4))%v * scal_ff(vm, curr) case (ovm_FUSE_F_SF, ovm_FUSE_F_SPF) braket = vm%conjspinors(curr(4))%v * ferm_sf(vm, curr) case (ovm_FUSE_F_FS, ovm_FUSE_F_FSP) braket = ferm_fs(vm, curr) * vm%spinors(curr(4))%v case (ovm_FUSE_G_GG) braket = vm%vectors(curr(4))%v * & g_gg(<>, & <>, <>, & <>, <>) case (ovm_FUSE_S_VV) braket = vm%scalars(curr(4))%v * <> * & (<> * vm%vectors(curr(6))%v) case (ovm_FUSE_V_SS) braket = vm%vectors(curr(4))%v * & v_ss(<>, <>, <>, & <>, <>) case (ovm_FUSE_S_G2, ovm_FUSE_S_G2_SKEW) braket = vm%scalars(curr(4))%v * scal_g2(vm, curr) case (ovm_FUSE_G_SG, ovm_FUSE_G_GS, ovm_FUSE_G_SG_SKEW, ovm_FUSE_G_GS_SKEW) braket = vm%vectors(curr(4))%v * gauge_sg(vm, curr) case (ovm_FUSE_S_VS) braket = vm%scalars(curr(4))%v * & s_vs(<>, & <>, <>, & <>, <>) case (ovm_FUSE_V_SV) braket = (vm%vectors(curr(4))%v * vm%vectors(curr(6))%v) * & (<> * <>) case (ovm_FUSE_S_SS) braket = vm%scalars(curr(4))%v * & <> * & (<> * vm%scalars(curr(6))%v) case (ovm_FUSE_S_SSS) braket = vm%scalars(curr(4))%v * & <> * & (<> * vm%scalars(curr(6))%v * & <>) case (ovm_FUSE_S_SVV) braket = vm%scalars(curr(4))%v * & <> * & <> * (vm%vectors(curr(6))%v * & <>) case (ovm_FUSE_V_SSV) braket = vm%vectors(curr(4))%v * & (<> * <> * & vm%scalars(curr(6))%v) * <> case (ovm_FUSE_V_VVV) braket = <> * & (<> * vm%vectors(curr(6))%v) * & (vm%vectors(curr(4))%v * <>) case default print *, 'Braket', curr(1), 'not implemented' stop 1 end select vm%amplitudes(i(4)) = vm%amplitudes(i(4)) + curr(3) * braket tmp = tmp + 1 end do vm%amplitudes(i(4)) = vm%amplitudes(i(4)) * i(2) if (i(5) > 1) then vm%amplitudes(i(4)) = vm%amplitudes(i(4)) * & ! Symmetry factor (one / sqrt(real(i(5), kind=default))) end if @ \subsubsection{Propagators} <>= integer, parameter :: ovm_PROPAGATE_SCALAR = 51 integer, parameter :: ovm_PROPAGATE_COL_SCALAR = 52 integer, parameter :: ovm_PROPAGATE_GHOST = 53 integer, parameter :: ovm_PROPAGATE_SPINOR = 54 integer, parameter :: ovm_PROPAGATE_CONJSPINOR = 55 integer, parameter :: ovm_PROPAGATE_MAJORANA = 56 integer, parameter :: ovm_PROPAGATE_COL_MAJORANA = 57 integer, parameter :: ovm_PROPAGATE_UNITARITY = 58 integer, parameter :: ovm_PROPAGATE_COL_UNITARITY = 59 integer, parameter :: ovm_PROPAGATE_FEYNMAN = 60 integer, parameter :: ovm_PROPAGATE_COL_FEYNMAN = 61 integer, parameter :: ovm_PROPAGATE_VECTORSPINOR = 62 integer, parameter :: ovm_PROPAGATE_TENSOR2 = 63 integer, parameter :: ovm_PROPAGATE_NONE = 64 @ <>= if ((mode%col_MC .eq. FULL_SUM) .or. (mode%col_MC .eq. DIAG_COL)) then select case(i(1)) case (ovm_PROPAGATE_PSI) go = .not. vm%spinors%c(i(4)) case (ovm_PROPAGATE_PSIBAR) go = .not. vm%conjspinors%c(i(4)) case (ovm_PROPAGATE_UNITARITY, ovm_PROPAGATE_FEYNMAN, & ovm_PROPAGATE_COL_FEYNMAN) go = .not. vm%vectors%c(i(4)) end select else go = (i(8) == o%cols(1)) .or. (i(8) == o%cols(2)) end if if (go) then <<[[case]]s of [[decode]]>>= <> case (ovm_PROPAGATE_SCALAR : ovm_PROPAGATE_NONE) tmp = instruction_index + 1 do curr = vm%instructions(:,tmp) if (curr(1) >= 0) exit ! End of fusions select case (curr(1)) case (ovm_FUSE_V_FF, ovm_FUSE_VL_FF, ovm_FUSE_VR_FF) vm%vectors(curr(4))%v = vm%vectors(curr(4))%v + curr(3) * & vec_ff(vm, curr) case (ovm_FUSE_F_VF, ovm_FUSE_F_VLF, ovm_FUSE_F_VRF) vm%spinors(curr(4))%v = vm%spinors(curr(4))%v + curr(3) * & ferm_vf(vm, curr) case (ovm_FUSE_F_FV, ovm_FUSE_F_FVL, ovm_FUSE_F_FVR) vm%conjspinors(curr(4))%v = vm%conjspinors(curr(4))%v + curr(3) * & ferm_fv(vm, curr) case (ovm_FUSE_VA_FF) vm%vectors(curr(4))%v = vm%vectors(curr(4))%v + curr(3) * & vec_ff2(vm, curr) case (ovm_FUSE_F_VAF) vm%spinors(curr(4))%v = vm%spinors(curr(4))%v + curr(3) * & ferm_vf2(vm, curr) case (ovm_FUSE_F_FVA) vm%conjspinors(curr(4))%v = vm%conjspinors(curr(4))%v + curr(3) * & ferm_fv2(vm, curr) case (ovm_FUSE_S_FF, ovm_FUSE_SP_FF) vm%scalars(curr(4))%v = vm%scalars(curr(4))%v + curr(3) * & scal_ff(vm, curr) case (ovm_FUSE_F_SF, ovm_FUSE_F_SPF) vm%spinors(curr(4))%v = vm%spinors(curr(4))%v + curr(3) * & ferm_sf(vm, curr) case (ovm_FUSE_F_FS, ovm_FUSE_F_FSP) vm%conjspinors(curr(4))%v = vm%conjspinors(curr(4))%v + curr(3) * & ferm_fs(vm, curr) case (ovm_FUSE_G_GG) vm%vectors(curr(4))%v = vm%vectors(curr(4))%v + curr(3) * & g_gg(<>, <>, & <>, <>, & <>) case (ovm_FUSE_S_VV) vm%scalars(curr(4))%v = vm%scalars(curr(4))%v + curr(3) * & <> * & (<> * vm%vectors(curr(6))%v) case (ovm_FUSE_V_SS) vm%vectors(curr(4))%v = vm%vectors(curr(4))%v + curr(3) * & v_ss(<>, <>, <>, & <>, <>) case (ovm_FUSE_S_G2, ovm_FUSE_S_G2_SKEW) vm%scalars(curr(4))%v = vm%scalars(curr(4))%v + & scal_g2(vm, curr) * curr(3) case (ovm_FUSE_G_SG, ovm_FUSE_G_GS, ovm_FUSE_G_SG_SKEW, ovm_FUSE_G_GS_SKEW) vm%vectors(curr(4))%v = vm%vectors(curr(4))%v + & gauge_sg(vm, curr) * curr(3) case (ovm_FUSE_S_VS) vm%scalars(curr(4))%v = vm%scalars(curr(4))%v + & s_vs(<>, & <>, <>, & <>, <>) * curr(3) case (ovm_FUSE_V_SV) vm%vectors(curr(4))%v = vm%vectors(curr(4))%v + & vm%vectors(curr(6))%v * & (<> * <> * curr(3)) case (ovm_FUSE_S_SS) vm%scalars(curr(4))%v = vm%scalars(curr(4))%v + & <> * & (<> * vm%scalars(curr(6))%v) * curr(3) case (ovm_FUSE_S_SSS) vm%scalars(curr(4))%v = vm%scalars(curr(4))%v + & <> * & (<> * vm%scalars(curr(6))%v * & <>) * curr(3) case (ovm_FUSE_S_SVV) vm%scalars(curr(4))%v = vm%scalars(curr(4))%v + & <> * & <> * (vm%vectors(curr(6))%v * & <>) * curr(3) case (ovm_FUSE_V_SSV) vm%vectors(curr(4))%v = vm%vectors(curr(4))%v + & (<> * <> * & vm%scalars(curr(6))%v) * <> * curr(3) case (ovm_FUSE_V_VVV) vm%vectors(curr(4))%v = vm%vectors(curr(4))%v + & (<> * (<> * & vm%vectors(curr(6))%v)) * curr(3) * <> case default print *, 'Fusion', curr(1), 'not implemented' stop 1 end select tmp = tmp + 1 end do select case (i(3)) case (0) w = zero case (1) w = vm%width(i(2)) vm%cms = .false. case (2) w = wd_tl(<

>, vm%width(i(2))) case (3) w = vm%width(i(2)) vm%cms = .true. + case (4) + w = wd_run(<

>, <>, vm%width(i(2))) + case default print *, 'not implemented' stop 1 end select select case (i(1)) <> end select @ <>= case (ovm_PROPAGATE_SCALAR) vm%scalars(i(4))%v = pr_phi(<

>, <>, & w, vm%scalars(i(4))%v) vm%scalars(i(4))%c = .True. case (ovm_PROPAGATE_COL_SCALAR) vm%scalars(i(4))%v = - one / N_ * pr_phi(<

>, & <>, w, vm%scalars(i(4))%v) vm%scalars(i(4))%c = .True. case (ovm_PROPAGATE_GHOST) vm%scalars(i(4))%v = imago * pr_phi(<

>, <>, & w, vm%scalars(i(4))%v) vm%scalars(i(4))%c = .True. case (ovm_PROPAGATE_SPINOR) vm%spinors(i(4))%v = pr_psi(<

>, <>, & w, vm%cms, vm%spinors(i(4))%v) vm%spinors(i(4))%c = .True. case (ovm_PROPAGATE_CONJSPINOR) vm%conjspinors(i(4))%v = pr_psibar(<

>, <>, & w, vm%cms, vm%conjspinors(i(4))%v) vm%conjspinors(i(4))%c = .True. case (ovm_PROPAGATE_MAJORANA) vm%bispinors(i(4))%v = bi_pr_psi(<

>, <>, & w, vm%cms, vm%bispinors(i(4))%v) vm%bispinors(i(4))%c = .True. case (ovm_PROPAGATE_COL_MAJORANA) vm%bispinors(i(4))%v = (- one / N_) * & bi_pr_psi(<

>, <>, & w, vm%cms, vm%bispinors(i(4))%v) vm%bispinors(i(4))%c = .True. case (ovm_PROPAGATE_UNITARITY) vm%vectors(i(4))%v = pr_unitarity(<

>, <>, & w, vm%cms, vm%vectors(i(4))%v) vm%vectors(i(4))%c = .True. case (ovm_PROPAGATE_COL_UNITARITY) vm%vectors(i(4))%v = - one / N_ * pr_unitarity(<

>, & <>, w, vm%cms, vm%vectors(i(4))%v) vm%vectors(i(4))%c = .True. case (ovm_PROPAGATE_FEYNMAN) vm%vectors(i(4))%v = pr_feynman(<

>, vm%vectors(i(4))%v) vm%vectors(i(4))%c = .True. case (ovm_PROPAGATE_COL_FEYNMAN) vm%vectors(i(4))%v = - one / N_ * & pr_feynman(<

>, vm%vectors(i(4))%v) vm%vectors(i(4))%c = .True. case (ovm_PROPAGATE_VECTORSPINOR) vm%vectorspinors(i(4))%v = pr_grav(<

>, <>, & w, vm%vectorspinors(i(4))%v) vm%vectorspinors(i(4))%c = .True. case (ovm_PROPAGATE_TENSOR2) vm%tensors_2(i(4))%v = pr_tensor(<

>, <>, & w, vm%tensors_2(i(4))%v) vm%tensors_2(i(4))%c = .True. case (ovm_PROPAGATE_NONE) ! This will not work with color MC. Appropriate type%c has to be set to ! .True. @ \subsection{Helper functions} Factoring out these parts helps a lot to keep sane but might hurt the performance of the VM noticably. In that case, we have to copy \& paste to avoid the additional function calls. Note that with preprocessor macros, we could maintain this factorized form (and factor out even more since types don't have to match), in case we would decide to allow this <>= !select type (h) !type is (hel_trigonometric) !wf%v = (cos (h%theta) * load_wf (m, p, + 1) + & !sin (h%theta) * load_wf (m, p, - 1)) * sqrt2 !type is (hel_exponential) !wf%v = exp (+ imago * h%phi) * load_wf (m, p, + 1) + & !exp (- imago * h%phi) * load_wf (m, p, - 1) !type is (hel_spherical) !wf%v = (exp (+ imago * h%phi) * cos (h%theta) * load_wf (m, p, + 1) + & !exp (- imago * h%phi) * sin (h%theta) * load_wf (m, p, - 1)) * & !sqrt2 !type is(hel_discrete) !wf%v = load_wf (m, p, h%i) !end select wf%v = load_wf (m, p, h) wf%c = .True. @ Caveat: Helicity MC not tested with Majorana particles but should be fine <>= if ((mode%col_MC .eq. FULL_SUM) .or. (mode%col_MC .eq. DIAG_COL)) then go = .not. vm%spinors%c(i(4)) else go = (i(8) == o%cols(1)) .or. (i(8) == o%cols(2)) end if if (go) .. <>= subroutine load_bispinor(wf, p, m, h, opcode) type(vm_bispinor), intent(out) :: wf type(momentum), intent(in) :: p real(default), intent(in) :: m !class(helicity_t), intent(in) :: h integer, intent(in) :: h integer, intent(in) :: opcode procedure(bi_u), pointer :: load_wf <> select case (opcode) case (ovm_LOAD_MAJORANA_INC) load_wf => bi_u case (ovm_LOAD_MAJORANA_OUT) load_wf => bi_v case default load_wf => null() end select <> end subroutine load_bispinor subroutine load_spinor(wf, p, m, h, opcode) type(vm_spinor), intent(out) :: wf type(momentum), intent(in) :: p real(default), intent(in) :: m !class(helicity_t), intent(in) :: h integer, intent(in) :: h integer, intent(in) :: opcode procedure(u), pointer :: load_wf <> select case (opcode) case (ovm_LOAD_SPINOR_INC) load_wf => u case (ovm_LOAD_SPINOR_OUT) load_wf => v case default load_wf => null() end select <> end subroutine load_spinor subroutine load_conjspinor(wf, p, m, h, opcode) type(vm_conjspinor), intent(out) :: wf type(momentum), intent(in) :: p real(default), intent(in) :: m !class(helicity_t), intent(in) :: h integer, intent(in) :: h integer, intent(in) :: opcode procedure(ubar), pointer :: load_wf <> select case (opcode) case (ovm_LOAD_CONJSPINOR_INC) load_wf => vbar case (ovm_LOAD_CONJSPINOR_OUT) load_wf => ubar case default load_wf => null() end select <> end subroutine load_conjspinor subroutine load_vector(wf, p, m, h, opcode) type(vm_vector), intent(out) :: wf type(momentum), intent(in) :: p real(default), intent(in) :: m !class(helicity_t), intent(in) :: h integer, intent(in) :: h integer, intent(in) :: opcode procedure(eps), pointer :: load_wf <> load_wf => eps <> if (opcode == ovm_LOAD_VECTOR_OUT) then wf%v = conjg(wf%v) end if end subroutine load_vector @ <>= function ferm_vf(vm, curr) result (x) type(spinor) :: x class(vm_t), intent(in) :: vm integer, dimension(:), intent(in) :: curr procedure(f_vf), pointer :: load_wf select case (curr(1)) case (ovm_FUSE_F_VF) load_wf => f_vf case (ovm_FUSE_F_VLF) load_wf => f_vlf case (ovm_FUSE_F_VRF) load_wf => f_vrf case default load_wf => null() end select x = load_wf(<>, <>, vm%spinors(curr(6))%v) end function ferm_vf function ferm_vf2(vm, curr) result (x) type(spinor) :: x class(vm_t), intent(in) :: vm integer, dimension(:), intent(in) :: curr procedure(f_vaf), pointer :: load_wf select case (curr(1)) case (ovm_FUSE_F_VAF) load_wf => f_vaf case default load_wf => null() end select x = f_vaf(<>, <>, <>, vm%spinors(curr(6))%v) end function ferm_vf2 function ferm_sf(vm, curr) result (x) type(spinor) :: x class(vm_t), intent(in) :: vm integer, dimension(:), intent(in) :: curr select case (curr(1)) case (ovm_FUSE_F_SF) x = f_sf(<>, <>, vm%spinors(curr(6))%v) case (ovm_FUSE_F_SPF) x = f_spf(<>, <>, <>, vm%spinors(curr(6))%v) case default end select end function ferm_sf function ferm_fv(vm, curr) result (x) type(conjspinor) :: x class(vm_t), intent(in) :: vm integer, dimension(:), intent(in) :: curr procedure(f_fv), pointer :: load_wf select case (curr(1)) case (ovm_FUSE_F_FV) load_wf => f_fv case (ovm_FUSE_F_FVL) load_wf => f_fvl case (ovm_FUSE_F_FVR) load_wf => f_fvr case default load_wf => null() end select x = load_wf(<>, vm%conjspinors(curr(5))%v, vm%vectors(curr(6))%v) end function ferm_fv function ferm_fv2(vm, curr) result (x) type(conjspinor) :: x class(vm_t), intent(in) :: vm integer, dimension(:), intent(in) :: curr procedure(f_fva), pointer :: load_wf select case (curr(1)) case (ovm_FUSE_F_FVA) load_wf => f_fva case default load_wf => null() end select x = f_fva(<>, <>, & vm%conjspinors(curr(5))%v, vm%vectors(curr(6))%v) end function ferm_fv2 function ferm_fs(vm, curr) result (x) type(conjspinor) :: x class(vm_t), intent(in) :: vm integer, dimension(:), intent(in) :: curr procedure(f_fs), pointer :: load_wf select case (curr(1)) case (ovm_FUSE_F_FS) x = f_fs(<>, vm%conjspinors(curr(5))%v, vm%scalars(curr(6))%v) case (ovm_FUSE_F_FSP) x = f_fsp(<>, <>, & vm%conjspinors(curr(5))%v, vm%scalars(curr(6))%v) case default x%a = zero end select end function ferm_fs function vec_ff(vm, curr) result (x) type(vector) :: x class(vm_t), intent(in) :: vm integer, dimension(:), intent(in) :: curr procedure(v_ff), pointer :: load_wf select case (curr(1)) case (ovm_FUSE_V_FF) load_wf => v_ff case (ovm_FUSE_VL_FF) load_wf => vl_ff case (ovm_FUSE_VR_FF) load_wf => vr_ff case default load_wf => null() end select x = load_wf(<>, vm%conjspinors(curr(5))%v, vm%spinors(curr(6))%v) end function vec_ff function vec_ff2(vm, curr) result (x) type(vector) :: x class(vm_t), intent(in) :: vm integer, dimension(:), intent(in) :: curr procedure(va_ff), pointer :: load_wf select case (curr(1)) case (ovm_FUSE_VA_FF) load_wf => va_ff case default load_wf => null() end select x = load_wf(<>, <>, & vm%conjspinors(curr(5))%v, vm%spinors(curr(6))%v) end function vec_ff2 function scal_ff(vm, curr) result (x) complex(default) :: x class(vm_t), intent(in) :: vm integer, dimension(:), intent(in) :: curr select case (curr(1)) case (ovm_FUSE_S_FF) x = s_ff(<>, & vm%conjspinors(curr(5))%v, vm%spinors(curr(6))%v) case (ovm_FUSE_SP_FF) x = sp_ff(<>, <>, & vm%conjspinors(curr(5))%v, vm%spinors(curr(6))%v) case default x = zero end select end function scal_ff function scal_g2(vm, curr) result (x) complex(default) :: x class(vm_t), intent(in) :: vm integer, dimension(:), intent(in) :: curr select case (curr(1)) case (ovm_FUSE_S_G2) x = <> * ((<> * <>) * & (<> * <>) - & (<> * <>) * & (<> * <>)) case (ovm_FUSE_S_G2_SKEW) x = - phi_vv(<>, <>, <>, & <>, <>) case default x = zero end select end function scal_g2 pure function gauge_sg(vm, curr) result (x) type(vector) :: x class(vm_t), intent(in) :: vm integer, dimension(:), intent(in) :: curr select case (curr(1)) case (ovm_FUSE_G_SG) x = <> * <> * ( & -((<> + <>) * & <>) * <> - & (-(<> + <>) * & <>) * <>) case (ovm_FUSE_G_GS) x = <> * <> * ( & -((<> + <>) * & <>) * <> - & (-(<> + <>) * & <>) * <>) case (ovm_FUSE_G_SG_SKEW) x = - v_phiv(<>, <>, <>, & <>, <>) case (ovm_FUSE_G_GS_SKEW) x = - v_phiv(<>, <>, <>, & <>, <>) case default x = [zero, zero, zero, zero] end select end function gauge_sg @ Some really tiny ones that hopefully get inlined by the compiler <>= elemental function sgn_coupl_cmplx(vm, j) result (s) class(vm_t), intent(in) :: vm integer, intent(in) :: j complex(default) :: s s = isign(1, j) * vm%coupl_cmplx(abs(j)) end function sgn_coupl_cmplx elemental function sgn_coupl_cmplx2(vm, j, i) result (s) class(vm_t), intent(in) :: vm integer, intent(in) :: j, i complex(default) :: s if (i == 1) then s = isign(1, j) * vm%coupl_cmplx2(i, abs(j)) else s = isign(1, j) * vm%coupl_cmplx2(i, abs(j)) end if end function sgn_coupl_cmplx2 elemental function int_to_log(i) result(yorn) integer, intent(in) :: i logical :: yorn if (i /= 0) then yorn = .true. else yorn = .false. end if end function elemental function color_factor(num, den, pwr) result (cf) integer, intent(in) :: num, den, pwr real(kind=default) :: cf if (pwr == 0) then cf = (one * num) / den else cf = (one * num) / den * (N_**pwr) end if end function color_factor @ \subsection{O'Mega Interface} We want to keep the interface close to the native Fortran code but of course one has to hand over the [[vm]] additionally <>= procedure :: number_particles_in => vm_number_particles_in procedure :: number_particles_out => vm_number_particles_out procedure :: number_color_indices => vm_number_color_indices procedure :: reset_helicity_selection => vm_reset_helicity_selection procedure :: new_event => vm_new_event procedure :: color_sum => vm_color_sum procedure :: spin_states => vm_spin_states procedure :: number_spin_states => vm_number_spin_states procedure :: number_color_flows => vm_number_color_flows procedure :: flavor_states => vm_flavor_states procedure :: number_flavor_states => vm_number_flavor_states procedure :: color_flows => vm_color_flows procedure :: color_factors => vm_color_factors procedure :: number_color_factors => vm_number_color_factors procedure :: is_allowed => vm_is_allowed procedure :: get_amplitude => vm_get_amplitude @ <>= elemental function vm_number_particles_in (vm) result (n) class(vm_t), intent(in) :: vm integer :: n n = vm%N_prt_in end function vm_number_particles_in elemental function vm_number_particles_out (vm) result (n) class(vm_t), intent(in) :: vm integer :: n n = vm%N_prt_out end function vm_number_particles_out elemental function vm_number_spin_states (vm) result (n) class(vm_t), intent(in) :: vm integer :: n n = vm%N_helicities end function vm_number_spin_states pure subroutine vm_spin_states (vm, a) class(vm_t), intent(in) :: vm integer, dimension(:,:), intent(out) :: a a = vm%table_spin end subroutine vm_spin_states elemental function vm_number_flavor_states (vm) result (n) class(vm_t), intent(in) :: vm integer :: n n = vm%N_flavors end function vm_number_flavor_states pure subroutine vm_flavor_states (vm, a) class(vm_t), intent(in) :: vm integer, dimension(:,:), intent(out) :: a a = vm%table_flavor end subroutine vm_flavor_states elemental function vm_number_color_indices (vm) result (n) class(vm_t), intent(in) :: vm integer :: n n = vm%N_col_indices end function vm_number_color_indices elemental function vm_number_color_flows (vm) result (n) class(vm_t), intent(in) :: vm integer :: n n = vm%N_col_flows end function vm_number_color_flows pure subroutine vm_color_flows (vm, a, g) class(vm_t), intent(in) :: vm integer, dimension(:,:,:), intent(out) :: a logical, dimension(:,:), intent(out) :: g a = vm%table_color_flows g = vm%table_ghost_flags end subroutine vm_color_flows elemental function vm_number_color_factors (vm) result (n) class(vm_t), intent(in) :: vm integer :: n n = vm%N_col_factors end function vm_number_color_factors pure subroutine vm_color_factors (vm, cf) class(vm_t), intent(in) :: vm type(OCF), dimension(:), intent(out) :: cf cf = vm%table_color_factors end subroutine vm_color_factors ! pure & ! pure unless OpenMp function vm_color_sum (vm, flv, hel) result (amp2) class(vm_t), intent(in) :: vm integer, intent(in) :: flv, hel real(default) :: amp2 amp2 = ovm_color_sum (flv, hel, vm%table_amplitudes, vm%table_color_factors) end function vm_color_sum subroutine vm_new_event (vm, p) class(vm_t), intent(inout) :: vm real(default), dimension(0:3,*), intent(in) :: p logical :: mask_dirty integer :: hel call vm%run (p) if ((vm%hel_threshold .gt. 0) .and. (vm%hel_count .le. vm%hel_cutoff)) then call omega_update_helicity_selection (vm%hel_count, vm%table_amplitudes, & vm%hel_max_abs, vm%hel_sum_abs, vm%hel_is_allowed, vm%hel_threshold, & vm%hel_cutoff, mask_dirty) if (mask_dirty) then vm%hel_finite = 0 do hel = 1, vm%N_helicities if (vm%hel_is_allowed(hel)) then vm%hel_finite = vm%hel_finite + 1 vm%hel_map(vm%hel_finite) = hel end if end do end if end if end subroutine vm_new_event pure subroutine vm_reset_helicity_selection (vm, threshold, cutoff) class(vm_t), intent(inout) :: vm real(kind=default), intent(in) :: threshold integer, intent(in) :: cutoff integer :: i vm%hel_is_allowed = .True. vm%hel_max_abs = 0 vm%hel_sum_abs = 0 vm%hel_count = 0 vm%hel_threshold = threshold vm%hel_cutoff = cutoff vm%hel_map = (/(i, i = 1, vm%N_helicities)/) vm%hel_finite = vm%N_helicities end subroutine vm_reset_helicity_selection pure function vm_is_allowed (vm, flv, hel, col) result (yorn) class(vm_t), intent(in) :: vm logical :: yorn integer, intent(in) :: flv, hel, col yorn = vm%table_flv_col_is_allowed(flv,col) .and. vm%hel_is_allowed(hel) end function vm_is_allowed pure function vm_get_amplitude (vm, flv, hel, col) result (amp_result) class(vm_t), intent(in) :: vm complex(kind=default) :: amp_result integer, intent(in) :: flv, hel, col amp_result = vm%table_amplitudes(flv, col, hel) end function vm_get_amplitude @ @ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% <>= ! omegalib.nw -- ! ! Copyright (C) 1999-2020 by ! Wolfgang Kilian ! Thorsten Ohl ! Juergen Reuter ! with contributions from ! Fabian Bach ! Bijan Chokoufe Nejad ! Christian Speckner ! ! WHIZARD is free software; you can redistribute it and/or modify it ! under the terms of the GNU General Public License as published by ! the Free Software Foundation; either version 2, or (at your option) ! any later version. ! ! WHIZARD is distributed in the hope that it will be useful, but ! WITHOUT ANY WARRANTY; without even the implied warranty of ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! GNU General Public License for more details. ! ! You should have received a copy of the GNU General Public License ! along with this program; if not, write to the Free Software ! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Index: trunk/omega/src/omega_Littlest_Zprime.ml =================================================================== --- trunk/omega/src/omega_Littlest_Zprime.ml (revision 8413) +++ trunk/omega/src/omega_Littlest_Zprime.ml (revision 8414) @@ -1,970 +1,972 @@ (* omega_Littlest_Zprime.ml -- Copyright (C) 1999-2020 by Wolfgang Kilian Thorsten Ohl Juergen Reuter with contributions from Christian Speckner WHIZARD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. WHIZARD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *) (* \thocwmodulesection{SM with Littlest Higgs Z'} *) module type SM_flags = sig val include_gluons : bool val include_anomalous : bool val include_supp : bool val k_matrix : bool end module SM_no_anomalous : SM_flags = struct let include_gluons = false let include_anomalous = false let include_supp = false let k_matrix = false end module SM_anomalous : SM_flags = struct let include_gluons = false let include_anomalous = true let include_supp = false let k_matrix = false end module SM_k_matrix : SM_flags = struct let include_gluons = false let include_anomalous = false let include_supp = false let k_matrix = true end module SM_gluons : SM_flags = struct let include_gluons = true let include_anomalous = false let include_supp = false let k_matrix = false end module SM_supp : SM_flags = struct let include_gluons = false let include_anomalous = false let include_supp = true let k_matrix = false end module Zprime (Flags : SM_flags) = struct open Coupling let default_width = ref Timelike let use_fudged_width = ref false let options = Options.create [ "constant_width", Arg.Unit (fun () -> default_width := Constant), "use constant width (also in t-channel)"; "fudged_width", Arg.Set use_fudged_width, "use fudge factor for charge particle width"; "custom_width", Arg.String (fun f -> default_width := Custom f), "use custom width"; "cancel_widths", Arg.Unit (fun () -> default_width := Vanishing), - "use vanishing width" ] + "use vanishing width"; + "running_width", Arg.Unit (fun () -> default_width := Running), + "use running width" ] (* We do not introduce the Goldstones for the heavy vectors here. *) type matter_field = L of int | N of int | U of int | D of int | TopH | TopHq | DH | DHq type gauge_boson = Ga | Wp | Wm | Z | Gl | Gl_aux | Xp | Xm | X0 | Y0 | ZH type other = Phip | Phim | Phi0 | H | Eta type flavor = M of matter_field | G of gauge_boson | O of other let matter_field f = M f let gauge_boson f = G f let other f = O f type field = | Matter of matter_field | Gauge of gauge_boson | Other of other let field = function | M f -> Matter f | G f -> Gauge f | O f -> Other f type gauge = unit let gauge_symbol () = failwith "Models.Zprime.gauge_symbol: internal error" let family n = List.map matter_field [ L n; N n; U n; D n ] let external_flavors () = [ "1st Generation", ThoList.flatmap family [1; -1]; "2nd Generation", ThoList.flatmap family [2; -2]; "3rd Generation", ThoList.flatmap family [3; -3]; "Heavy Quarks", List.map matter_field [TopH; TopHq; DH; DHq]; "Gauge Bosons", List.map gauge_boson [Ga; Z; Wp; Wm; Gl; Xp; Xm; X0; Y0; ZH]; "Higgs", List.map other [H; Eta]; "Goldstone Bosons", List.map other [Phip; Phim; Phi0] ] let flavors () = ThoList.flatmap snd (external_flavors ()) @ [ G Gl_aux] let squ = function | x -> Pow (Atom x, 2) let spinor n = if n >= 0 then Spinor else ConjSpinor let lorentz = function | M f -> begin match f with | L n -> spinor n | N n -> spinor n | U n -> spinor n | D n -> spinor n | TopH -> Spinor | TopHq -> ConjSpinor | DH -> Spinor | DHq -> ConjSpinor end | G f -> begin match f with | Ga | Gl -> Vector | Wp | Wm | Z | Xp | Xm | X0 | Y0 | ZH -> Massive_Vector | Gl_aux -> Tensor_1 end | O f -> Scalar let color = function | M (U n) -> Color.SUN (if n > 0 then 3 else -3) | M (D n) -> Color.SUN (if n > 0 then 3 else -3) | M TopH -> Color.SUN 3 | M TopHq -> Color.SUN (-3) | M DH -> Color.SUN 3 | M DHq -> Color.SUN (-3) | G Gl | G Gl_aux -> Color.AdjSUN 3 | _ -> Color.Singlet let prop_spinor n = if n >= 0 then Prop_Spinor else Prop_ConjSpinor let propagator = function | M f -> begin match f with | L n -> prop_spinor n | N n -> prop_spinor n | U n -> prop_spinor n | D n -> prop_spinor n | TopH -> Prop_Spinor | TopHq -> Prop_ConjSpinor | DH -> Prop_Spinor | DHq -> Prop_ConjSpinor end | G f -> begin match f with | Ga | Gl -> Prop_Feynman | Wp | Wm | Z | Xp | Xm | X0 | Y0 | ZH -> Prop_Unitarity | Gl_aux -> Aux_Tensor_1 end | O f -> begin match f with | Phip | Phim | Phi0 -> Only_Insertion | H | Eta -> Prop_Scalar end (* Optionally, ask for the fudge factor treatment for the widths of charged particles. Currently, this only applies to $W^\pm$ and top. *) let width f = if !use_fudged_width then match f with | G Wp | G Wm | M (U 3) | M (U (-3)) | M TopH | M TopHq | M DH | M DHq -> Fudged | _ -> !default_width else !default_width let goldstone = function | G f -> begin match f with | Wp -> Some (O Phip, Coupling.Const 1) | Wm -> Some (O Phim, Coupling.Const 1) | Z -> Some (O Phi0, Coupling.Const 1) | _ -> None end | _ -> None let conjugate = function | M f -> M (begin match f with | L n -> L (-n) | N n -> N (-n) | U n -> U (-n) | D n -> D (-n) | TopH -> TopHq | TopHq -> TopH | DH -> DHq | DHq -> DH end) | G f -> G (begin match f with | Gl -> Gl | Ga -> Ga | Z -> Z | Wp -> Wm | Wm -> Wp | Xp -> Xm | Xm -> Xp | X0 -> X0 | Y0 -> Y0 | ZH -> ZH | Gl_aux -> Gl_aux end) | O f -> O (begin match f with | Phip -> Phim | Phim -> Phip | Phi0 -> Phi0 | H -> H | Eta -> Eta end) let fermion = function | M f -> begin match f with | L n -> if n > 0 then 1 else -1 | N n -> if n > 0 then 1 else -1 | U n -> if n > 0 then 1 else -1 | D n -> if n > 0 then 1 else -1 | TopH -> 1 | TopHq -> -1 | DH -> 1 | DHq -> -1 end | G f -> begin match f with | Gl | Ga | Z | Wp | Wm | Gl_aux | Xp | Xm | X0 | Y0 | ZH -> 0 end | O _ -> 0 type constant = | Unit | Pi | Alpha_QED | Sin2thw | Sinthw | Costhw | E | G_weak | Vev | VHeavy | Supp | Supp2 | Sinpsi | Cospsi | Atpsi | Sccs (* Mixing angles of SU(2) *) | Q_lepton | Q_up | Q_down | Q_Z_up | G_CC | G_NC_neutrino | G_NC_lepton | G_NC_up | G_NC_down | G_NC_h_neutrino | G_NC_h_lepton | G_NC_h_up | G_NC_h_down | G_CC_heavy | G_zhthth | G_CC_supp1 | G_CC_supp2 | I_Q_W | I_G_ZWW | I_G_WWW | I_G_Z1 | I_G_Z2 | I_G_Z3 | I_G_Z4 | I_Q_H | I_Q_ZH | G_over4 | G_over4_sup | G_CC_sup | G_WWWW | G_ZZWW | G_AZWW | G_AAWW | I_G1_AWW | I_G1_ZWW | I_G1_plus_kappa_AWW | I_G1_plus_kappa_ZWW | I_G1_minus_kappa_AWW | I_G1_minus_kappa_ZWW | I_kappa_minus_G1_AWW | I_kappa_minus_G1_ZWW | I_lambda_AWW | I_lambda_ZWW | Alpha_WWWW0 | Alpha_ZZWW1 | Alpha_WWWW2 | Alpha_ZZWW0 | Alpha_ZZZZ | G_HWW | G_HHWW | G_HZZ | G_HHZZ | G_heavy_HVV | G_heavy_HWW | G_heavy_HZZ | G_heavy_HHVV | G_Htt | G_Hbb | G_Hcc | G_Htautau | G_H3 | G_H4 | G_Hthth | G_Htht | G_Ethth | G_Etht | G_Ett | G_Ebb | G_ZEH | G_ZHEH | G_XEH | G_HGaGa | G_HGaZ | G_EGaGa | G_EGaZ | G_EGlGl | G_strong | Mass of flavor | Width of flavor | K_Matrix_Coeff of int | K_Matrix_Pole of int (* \begin{dubious} The current abstract syntax for parameter dependencies is admittedly tedious. Later, there will be a parser for a convenient concrete syntax as a part of a concrete syntax for models. But as these examples show, it should include simple functions. \end{dubious} *) let input_parameters = [ Alpha_QED, 1. /. 137.0359895; Sin2thw, 0.23124; VHeavy, 2000.0; Mass (G Z), 91.187; Mass (M (N 1)), 0.0; Mass (M (L 1)), 0.51099907e-3; Mass (M (N 2)), 0.0; Mass (M (L 2)), 0.105658389; Mass (M (N 3)), 0.0; Mass (M (L 3)), 1.77705; Mass (M (U 1)), 5.0e-3; Mass (M (D 1)), 3.0e-3; Mass (M (U 2)), 1.2; Mass (M (D 2)), 0.1; Mass (M (U 3)), 174.0; Mass (M (D 3)), 4.2 ] (* hier, Hier, hallo, hier Higgs couplings still missing. *) let derived_parameters = [ Real E, Sqrt (Prod [Const 4; Atom Pi; Atom Alpha_QED]); Real Sinthw, Sqrt (Atom Sin2thw); Real Costhw, Sqrt (Diff (Const 1, Atom Sin2thw)); Real G_weak, Quot (Atom E, Atom Sinthw); Real (Mass (G Wp)), Prod [Atom Costhw; Atom (Mass (G Z))]; Real Vev, Quot (Prod [Const 2; Atom (Mass (G Wp))], Atom G_weak); Real Supp, Quot (Atom Vev, Atom VHeavy); Real Supp2, squ Supp; Real Atpsi, Quot (Atom Cospsi, Atom Sinpsi); Real Sccs, Prod [Atom Sinpsi; Atom Cospsi; Diff (squ Cospsi, squ Sinpsi)]; Real Q_lepton, Atom E; Real Q_up, Prod [Quot (Const (-2), Const 3); Atom E]; Real Q_down, Prod [Quot (Const 1, Const 3); Atom E]; Real G_CC, Neg (Quot (Atom G_weak, Prod [Const 2; Sqrt (Const 2)])); Real G_CC_heavy, Prod [Atom G_CC; Atom Atpsi]; (* Real G_NC_heavy, Quot (Prod [Atom G_weak; Atom Atpsi], Const 4); *) Complex I_Q_W, Prod [I; Atom E]; Complex I_G_ZWW, Prod [I; Atom G_weak; Atom Costhw]; Complex I_G_WWW, Prod [I; Atom G_weak]; Complex I_Q_ZH, Neg (Prod [I; Atom G_weak; Atom Supp2; Atom Sccs ]); Complex I_Q_H, Quot (Atom I_Q_ZH, Atom Costhw) ] (* \begin{equation} - \frac{g}{2\cos\theta_w} \end{equation} *) let g_over_2_costh = Quot (Neg (Atom G_weak), Prod [Const 2; Atom Costhw]) (* \begin{subequations} \begin{align} - \frac{g}{2\cos\theta_w} g_V &= - \frac{g}{2\cos\theta_w} (T_3 - 2 q \sin^2\theta_w) \\ - \frac{g}{2\cos\theta_w} g_A &= - \frac{g}{2\cos\theta_w} T_3 \end{align} \end{subequations} *) let nc_coupling c t3 q = (Real_Array c, [Prod [g_over_2_costh; Diff (t3, Prod [Const 2; q; Atom Sin2thw])]; Prod [g_over_2_costh; t3]]) let half = Quot (Const 1, Const 2) let derived_parameter_arrays = [ nc_coupling G_NC_neutrino half (Const 0); nc_coupling G_NC_lepton (Neg half) (Const (-1)); nc_coupling G_NC_up half (Quot (Const 2, Const 3)); nc_coupling G_NC_down (Neg half) (Quot (Const (-1), Const 3)) ] let parameters () = { input = input_parameters; derived = derived_parameters; derived_arrays = derived_parameter_arrays } module F = Modeltools.Fusions (struct type f = flavor type c = constant let compare = compare let conjugate = conjugate end) (* \begin{equation} \mathcal{L}_{\textrm{EM}} = - e \sum_i q_i \bar\psi_i\fmslash{A}\psi_i \end{equation} *) let mgm ((m1, g, m2), fbf, c) = ((M m1, G g, M m2), fbf, c) let mom ((m1, o, m2), fbf, c) = ((M m1, O o, M m2), fbf, c) let electromagnetic_currents n = List.map mgm [ ((L (-n), Ga, L n), FBF (1, Psibar, V, Psi), Q_lepton); ((U (-n), Ga, U n), FBF (1, Psibar, V, Psi), Q_up); ((D (-n), Ga, D n), FBF (1, Psibar, V, Psi), Q_down) ] let color_currents n = if Flags.include_gluons then List.map mgm [ ((U (-n), Gl, U n), FBF (1, Psibar, V, Psi), G_strong); ((D (-n), Gl, D n), FBF (1, Psibar, V, Psi), G_strong) ] else [] (* \begin{equation} \mathcal{L}_{\textrm{NC}} = - \frac{g}{2\cos\theta_W} \sum_i \bar\psi_i\fmslash{Z}(g_V^i-g_A^i\gamma_5)\psi_i \end{equation} *) let neutral_currents n = List.map mgm [ ((L (-n), Z, L n), FBF (1, Psibar, VA, Psi), G_NC_lepton); ((N (-n), Z, N n), FBF (1, Psibar, VA, Psi), G_NC_neutrino); ((U (-n), Z, U n), FBF (1, Psibar, VA, Psi), G_NC_up); ((D (-n), Z, D n), FBF (1, Psibar, VA, Psi), G_NC_down) ] (* The sign of this coupling is just the one of the T3, being -(1/2) for leptons and down quarks, and +(1/2) for neutrinos and up quarks. *) (* This version is the canonical Little Higgs which is universal couplings of the heavy Z to the SM fermions. let neutral_heavy_currents n = List.map mgm [ ((L (-n), ZH, L n), FBF (1, Psibar, VL, Psi), G_NC_heavy); ((N (-n), ZH, N n), FBF ((-1), Psibar, VL, Psi), G_NC_heavy); ((U (-n), ZH, U n), FBF ((-1), Psibar, VL, Psi), G_NC_heavy); ((D (-n), ZH, D n), FBF (1, Psibar, VL, Psi), G_NC_heavy) ] We want to allow for (almost) completely general couplings but maintain universality (generation independence). Maybe we should also separate the coupling to the top quark since the third generation is somewhat special. *) let neutral_heavy_currents n = List.map mgm [ ((L (-n), ZH, L n), FBF (1, Psibar, VLR, Psi), G_NC_h_lepton); ((N (-n), ZH, N n), FBF ((-1), Psibar, VLR, Psi), G_NC_h_neutrino); ((U (-n), ZH, U n), FBF ((-1), Psibar, VLR, Psi), G_NC_h_up); ((D (-n), ZH, D n), FBF (1, Psibar, VLR, Psi), G_NC_h_down); ] let heavy_top_currents = List.map mgm [ ((TopHq, Ga, TopH), FBF (1, Psibar, V, Psi), Q_up); ((DHq, Ga, DH), FBF (1, Psibar, V, Psi), Q_down); ((TopHq, Z, TopH), FBF (4, Psibar, V, Psi), Q_Z_up); ((DHq, Z, DH), FBF (1, Psibar, V, Psi), Q_Z_up); ((DHq, X0, D 1), FBF (1, Psibar, VL, Psi), G_over4); ((D (-1), X0, DH), FBF (1, Psibar, VL, Psi), G_over4); ((DHq, Y0, D 1), FBF (1, Psibar, VL, Psi), G_over4); ((D (-1), Y0, DH), FBF ((-1), Psibar, VL, Psi), G_over4); ((DHq, Xm, U 1), FBF (1, Psibar, VL, Psi), G_CC); ((U (-1), Xp, DH), FBF (1, Psibar, VL, Psi), G_CC); ((U (-3), X0, U 3), FBF (2, Psibar, VL, Psi), G_over4_sup); ((U (-3), Y0, U 3), FBF (2, Psibar, VL, Psi), G_over4_sup); ((U (-3), Xp, D 3), FBF (1, Psibar, VL, Psi), G_CC_sup); ((D (-3), Xm, U 3), FBF (1, Psibar, VL, Psi), G_CC_sup)] let neutral_supp_currents = List.map mgm [ ((TopHq, ZH, TopH), FBF (1, Psibar, VL, Psi), G_zhthth); ((DHq, ZH, DH), FBF (1, Psibar, VL, Psi), G_zhthth)] (* \begin{equation} \mathcal{L}_{\textrm{CC}} = - \frac{g}{2\sqrt2} \sum_i \bar\psi_i (T^+\fmslash{W}^+ + T^-\fmslash{W}^-)(1-\gamma_5)\psi_i \end{equation} *) let charged_currents n = List.map mgm [ ((L (-n), Wm, N n), FBF (1, Psibar, VL, Psi), G_CC); ((N (-n), Wp, L n), FBF (1, Psibar, VL, Psi), G_CC); ((D (-n), Wm, U n), FBF (1, Psibar, VL, Psi), G_CC); ((U (-n), Wp, D n), FBF (1, Psibar, VL, Psi), G_CC) ] let charged_heavy_currents n = List.map mgm [ ((L (-n), Xm, N n), FBF (1, Psibar, VL, Psi), G_CC_heavy); ((N (-n), Xp, L n), FBF (1, Psibar, VL, Psi), G_CC_heavy); ((D (-n), Xm, U n), FBF (1, Psibar, VL, Psi), G_CC_heavy); ((U (-n), Xp, D n), FBF (1, Psibar, VL, Psi), G_CC_heavy) ] (* let charged_supp_currents = List.map mgm [ ((TopHq, WHp, D 3), FBF (1, Psibar, VL, Psi), G_CC_supp1); ((D (-3), WHm, TopH), FBF (1, Psibar, VL, Psi), G_CC_supp1); ((TopHq, Wp, D 3), FBF (1, Psibar, VL, Psi), G_CC_supp2); ((D (-3), Wm, TopH), FBF (1, Psibar, VL, Psi), G_CC_supp2)] *) let yukawa = [ ((M (U (-3)), O H, M (U 3)), FBF (1, Psibar, S, Psi), G_Htt); ((M (D (-3)), O H, M (D 3)), FBF (1, Psibar, S, Psi), G_Hbb); ((M (U (-2)), O H, M (U 2)), FBF (1, Psibar, S, Psi), G_Hcc); ((M (L (-3)), O H, M (L 3)), FBF (1, Psibar, S, Psi), G_Htautau) ] let yukawa_add = [ ((M TopHq, O H, M TopH), FBF (1, Psibar, S, Psi), G_Hthth); ((M TopHq, O H, M (U 3)), FBF (1, Psibar, SLR, Psi), G_Htht); ((M (U (-3)), O H, M TopH), FBF (1, Psibar, SLR, Psi), G_Htht); ((M (U (-3)), O Eta, M (U 3)), FBF (1, Psibar, P, Psi), G_Ett); ((M TopHq, O Eta, M (U 3)), FBF (1, Psibar, SLR, Psi), G_Etht); ((M DHq, O Eta, M (D 1)), FBF (1, Psibar, SL, Psi), G_Ett); ((M (D (-3)), O Eta, M (D 3)), FBF (1, Psibar, P, Psi), G_Ebb); ((M (D (-1)), O Eta, M DH), FBF (1, Psibar, SR, Psi), G_Ett); ((M (U (-3)), O Eta, M TopH), FBF (1, Psibar, SLR, Psi), G_Etht)] (* \begin{equation} \mathcal{L}_{\textrm{TGC}} = - e \partial_\mu A_\nu W_+^\mu W_-^\nu + \ldots - e \cot\theta_w \partial_\mu Z_\nu W_+^\mu W_-^\nu + \ldots \end{equation} *) let tgc ((g1, g2, g3), t, c) = ((G g1, G g2, G g3), t, c) let standard_triple_gauge = List.map tgc [ ((Ga, Wm, Wp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Wm, Wp), Gauge_Gauge_Gauge 1, I_G_ZWW) ] let heavy_triple_gauge = List.map tgc [ ((Ga, Xm, Xp), Gauge_Gauge_Gauge 1, I_Q_W); ((Z, Xm, Xp), Gauge_Gauge_Gauge 1, I_Q_ZH); ((Z, X0, Y0), Gauge_Gauge_Gauge 1, I_G_Z1); ((ZH, X0, Y0), Gauge_Gauge_Gauge 1, I_G_Z2); ((Y0, Wm, Xp), Gauge_Gauge_Gauge 1, I_G_Z3); ((Y0, Wp, Xm), Gauge_Gauge_Gauge (-1), I_G_Z3); ((X0, Wm, Xp), Gauge_Gauge_Gauge 1, I_G_Z4); ((X0, Wp, Xm), Gauge_Gauge_Gauge 1, I_G_Z4); ] let triple_gluon = if Flags.include_gluons then List.map tgc [ ((Gl, Gl, Gl), Gauge_Gauge_Gauge 1, G_strong); ((Gl_aux, Gl, Gl), Aux_Gauge_Gauge 1, G_strong) ] else [] (* \begin{multline} \mathcal{L}_{\textrm{TGC}}(g_1,\kappa) = g_1 \mathcal{L}_T(V,W^+,W^-) \\ + \frac{\kappa+g_1}{2} \Bigl(\mathcal{L}_T(W^-,V,W^+) - \mathcal{L}_T(W^+,V,W^-)\Bigr)\\ + \frac{\kappa-g_1}{2} \Bigl(\mathcal{L}_L(W^-,V,W^+) - \mathcal{L}_T(W^+,V,W^-)\Bigr) \end{multline} *) let anomalous_triple_gauge = List.map tgc [ ((Ga, Wp, Wm), Dim4_Vector_Vector_Vector_T 1, I_G1_AWW); ((Z, Wp, Wm), Dim4_Vector_Vector_Vector_T 1, I_G1_ZWW); ((Wp, Wm, Ga), Dim4_Vector_Vector_Vector_T 1, I_G1_plus_kappa_AWW); ((Wp, Wm, Z), Dim4_Vector_Vector_Vector_T 1, I_G1_plus_kappa_ZWW); ((Wp, Wm, Ga), Dim4_Vector_Vector_Vector_L 1, I_G1_minus_kappa_AWW); ((Wp, Wm, Z), Dim4_Vector_Vector_Vector_L 1, I_G1_minus_kappa_ZWW); ((Wm, Ga, Wp), Dim4_Vector_Vector_Vector_T 1, I_G1_plus_kappa_AWW); ((Wm, Z, Wp), Dim4_Vector_Vector_Vector_T 1, I_G1_plus_kappa_ZWW); ((Wm, Ga, Wp), Dim4_Vector_Vector_Vector_L 1, I_kappa_minus_G1_AWW); ((Wm, Z, Wp), Dim4_Vector_Vector_Vector_L 1, I_kappa_minus_G1_ZWW); ((Ga, Wp, Wm), Dim6_Gauge_Gauge_Gauge 1, I_lambda_AWW); ((Z, Wp, Wm), Dim6_Gauge_Gauge_Gauge 1, I_lambda_ZWW) ] let triple_gauge = if Flags.include_anomalous then anomalous_triple_gauge else standard_triple_gauge @ heavy_triple_gauge let qgc ((g1, g2, g3, g4), t, c) = ((G g1, G g2, G g3, G g4), t, c) let gauge4 = Vector4 [(2, C_13_42); (-1, C_12_34); (-1, C_14_23)] let minus_gauge4 = Vector4 [(-2, C_13_42); (1, C_12_34); (1, C_14_23)] let standard_quartic_gauge = List.map qgc [ (Wm, Wp, Wm, Wp), gauge4, G_WWWW; (Wm, Z, Wp, Z), minus_gauge4, G_ZZWW; (Wm, Z, Wp, Ga), minus_gauge4, G_AZWW; (Wm, Ga, Wp, Ga), minus_gauge4, G_AAWW ] let anomalous_quartic_gauge = if Flags.include_anomalous then List.map qgc [ ((Wm, Wm, Wp, Wp), Vector4 [(1, C_13_42); (1, C_14_23)], Alpha_WWWW0); ((Wm, Wm, Wp, Wp), Vector4 [1, C_12_34], Alpha_WWWW2); ((Wm, Wp, Z, Z), Vector4 [1, C_12_34], Alpha_ZZWW0); ((Wm, Wp, Z, Z), Vector4 [(1, C_13_42); (1, C_14_23)], Alpha_ZZWW1); ((Z, Z, Z, Z), Vector4 [(1, C_12_34); (1, C_13_42); (1, C_14_23)], Alpha_ZZZZ) ] else [] (* In any diagonal channel~$\chi$, the scattering amplitude~$a_\chi(s)$ is unitary iff\footnote{% Trivial proof: \begin{equation} -1 = \textrm{Im}\left(\frac{1}{a_\chi(s)}\right) = \frac{\textrm{Im}(a_\chi^*(s))}{|a_\chi(s)|^2} = - \frac{\textrm{Im}(a_\chi(s))}{|a_\chi(s)|^2} \end{equation} i.\,e.~$\textrm{Im}(a_\chi(s)) = |a_\chi(s)|^2$.} \begin{equation} \textrm{Im}\left(\frac{1}{a_\chi(s)}\right) = -1 \end{equation} For a real perturbative scattering amplitude~$r_\chi(s)$ this can be enforced easily--and arbitrarily--by \begin{equation} \frac{1}{a_\chi(s)} = \frac{1}{r_\chi(s)} - \mathrm{i} \end{equation} *) let k_matrix_quartic_gauge = if Flags.k_matrix then List.map qgc [ ((Wm, Wp, Wm, Wp), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 0, K_Matrix_Pole 0]), Alpha_WWWW0); ((Wm, Wm, Wp, Wp), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 2, K_Matrix_Pole 2]), Alpha_WWWW0); ((Wm, Wp, Z, Z), Vector4_K_Matrix_tho (0, [(K_Matrix_Coeff 0, K_Matrix_Pole 0); (K_Matrix_Coeff 2, K_Matrix_Pole 2)]), Alpha_WWWW0); ((Wm, Z, Wp, Z), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 1, K_Matrix_Pole 1]), Alpha_WWWW0); ((Z, Z, Z, Z), Vector4_K_Matrix_tho (0, [K_Matrix_Coeff 0, K_Matrix_Pole 0]), Alpha_WWWW0) ] else [] let heavy_quartic_gauge = [] let quartic_gauge = standard_quartic_gauge @ anomalous_quartic_gauge @ k_matrix_quartic_gauge @ heavy_quartic_gauge let standard_gauge_higgs' = [ ((O H, G Wp, G Wm), Scalar_Vector_Vector 1, G_HWW); ((O H, G Z, G Z), Scalar_Vector_Vector 1, G_HZZ) ] let heavy_gauge_higgs = [ ((O H, G Wp, G Xm), Scalar_Vector_Vector 1, G_heavy_HWW); ((O H, G Wm, G Xp), Scalar_Vector_Vector 1, G_heavy_HWW); ((O H, G Z, G X0), Scalar_Vector_Vector 1, G_heavy_HVV); ((O H, G ZH, G X0), Scalar_Vector_Vector 1, G_heavy_HVV)] let standard_gauge_higgs = standard_gauge_higgs' @ heavy_gauge_higgs let standard_gauge_higgs4 = [ (O H, O H, G Wp, G Wm), Scalar2_Vector2 1, G_HHWW; (O H, O H, G Z, G Z), Scalar2_Vector2 1, G_HHZZ ] (* let standard_heavy_gauge_higgs4 = [ (O H, O H, G WHp, G Wm), Scalar2_Vector2 1, G_heavy_HHVV; (O H, O H, G Wp, G WHm), Scalar2_Vector2 1, G_heavy_HHVV; (O H, O H, G Z, G ZH), Scalar2_Vector2 1, G_heavy_HHVV ] *) let standard_higgs = [ (O H, O H, O H), Scalar_Scalar_Scalar 1, G_H3 ] let anomaly_higgs = [ (* (O H, G Ga, G Ga), Dim5_Scalar_Gauge2 1, G_HGaGa; (O H, G Ga, G Z), Dim5_Scalar_Gauge2 1, G_HGaZ;*) (O Eta, G Gl, G Gl), Dim5_Scalar_Gauge2_Skew 1, G_EGlGl; (O Eta, G Ga, G Ga), Dim5_Scalar_Gauge2_Skew 1, G_EGaGa; (O Eta, G Ga, G Z), Dim5_Scalar_Gauge2_Skew 1, G_EGaZ] let standard_higgs4 = [ (O H, O H, O H, O H), Scalar4 1, G_H4 ] let anomalous_gauge_higgs = [] let anomalous_gauge_higgs4 = [] let anomalous_higgs = [] let anomalous_higgs4 = [] let gauge_higgs = if Flags.include_anomalous then standard_gauge_higgs @ anomalous_gauge_higgs else standard_gauge_higgs let gauge_higgs4 = if Flags.include_anomalous then standard_gauge_higgs4 @ anomalous_gauge_higgs4 else standard_gauge_higgs4 let higgs = if Flags.include_anomalous then standard_higgs @ anomalous_higgs else standard_higgs let eta_higgs_gauge = [ (G Z, O Eta, O H), Vector_Scalar_Scalar 1, G_ZEH; (G ZH, O Eta, O H), Vector_Scalar_Scalar 1, G_ZHEH; (G X0, O Eta, O H), Vector_Scalar_Scalar 1, G_XEH ] let higgs4 = if Flags.include_anomalous then standard_higgs4 @ anomalous_higgs4 else standard_higgs4 let goldstone_vertices = [ ((O Phi0, G Wm, G Wp), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phip, G Ga, G Wm), Scalar_Vector_Vector 1, I_Q_W); ((O Phip, G Z, G Wm), Scalar_Vector_Vector 1, I_G_ZWW); ((O Phim, G Wp, G Ga), Scalar_Vector_Vector 1, I_Q_W); ((O Phim, G Wp, G Z), Scalar_Vector_Vector 1, I_G_ZWW) ] let vertices3' = (ThoList.flatmap electromagnetic_currents [1;2;3] @ ThoList.flatmap color_currents [1;2;3] @ ThoList.flatmap neutral_currents [1;2;3] @ ThoList.flatmap neutral_heavy_currents [1;2;3] @ ThoList.flatmap charged_currents [1;2;3] @ anomaly_higgs @ (* ThoList.flatmap charged_heavy_currents [1;2;3] @ *) heavy_top_currents @ eta_higgs_gauge @ yukawa @ yukawa_add @ triple_gauge @ triple_gluon @ gauge_higgs @ higgs @ goldstone_vertices) let vertices3 = if Flags.include_supp then vertices3' @ neutral_supp_currents (* @ charged_supp_currents *) else vertices3' let vertices4 = quartic_gauge @ gauge_higgs4 @ higgs4 let vertices () = (vertices3, vertices4, []) (* For efficiency, make sure that [F.of_vertices vertices] is evaluated only once. *) let table = F.of_vertices (vertices ()) let fuse2 = F.fuse2 table let fuse3 = F.fuse3 table let fuse = F.fuse table let max_degree () = 4 let flavor_of_string = function | "e-" -> M (L 1) | "e+" -> M (L (-1)) | "mu-" -> M (L 2) | "mu+" -> M (L (-2)) | "tau-" -> M (L 3) | "tau+" -> M (L (-3)) | "nue" -> M (N 1) | "nuebar" -> M (N (-1)) | "numu" -> M (N 2) | "numubar" -> M (N (-2)) | "nutau" -> M (N 3) | "nutaubar" -> M (N (-3)) | "u" -> M (U 1) | "ubar" -> M (U (-1)) | "c" -> M (U 2) | "cbar" -> M (U (-2)) | "t" -> M (U 3) | "tbar" -> M (U (-3)) | "d" -> M (D 1) | "dbar" -> M (D (-1)) | "s" -> M (D 2) | "sbar" -> M (D (-2)) | "b" -> M (D 3) | "bbar" -> M (D (-3)) | "th" -> M TopH | "thbar" -> M TopHq | "dh" -> M DH | "dhbar" -> M DHq | "eta" | "Eta" -> O Eta | "g" -> G Gl | "A" -> G Ga | "Z" | "Z0" -> G Z | "ZH" | "ZH0" | "Zh" | "Zh0" -> G ZH | "W+" -> G Wp | "W-" -> G Wm | "X+" -> G Xp | "X-" -> G Xm | "X0" -> G X0 | "Y0" -> G Y0 | "H" -> O H | _ -> invalid_arg "Models.Zprime.flavor_of_string" let flavor_to_string = function | M f -> begin match f with | L 1 -> "e-" | L (-1) -> "e+" | L 2 -> "mu-" | L (-2) -> "mu+" | L 3 -> "tau-" | L (-3) -> "tau+" | L _ -> invalid_arg "Models.Zprime.flavor_to_string: invalid lepton" | N 1 -> "nue" | N (-1) -> "nuebar" | N 2 -> "numu" | N (-2) -> "numubar" | N 3 -> "nutau" | N (-3) -> "nutaubar" | N _ -> invalid_arg "Models.Zprime.flavor_to_string: invalid neutrino" | U 1 -> "u" | U (-1) -> "ubar" | U 2 -> "c" | U (-2) -> "cbar" | U 3 -> "t" | U (-3) -> "tbar" | U _ -> invalid_arg "Models.Zprime.flavor_to_string: invalid up type quark" | D 1 -> "d" | D (-1) -> "dbar" | D 2 -> "s" | D (-2) -> "sbar" | D 3 -> "b" | D (-3) -> "bbar" | D _ -> invalid_arg "Models.Zprime.flavor_to_string: invalid down type quark" | TopH -> "th" | TopHq -> "thbar" | DH -> "dh" | DHq -> "dhbar" end | G f -> begin match f with | Gl -> "g" | Ga -> "A" | Z -> "Z" | Wp -> "W+" | Wm -> "W-" | Xp -> "X+" | Xm -> "X-" | X0 -> "X0" | Y0 -> "Y0" | ZH -> "ZH" | Gl_aux -> "gx" end | O f -> begin match f with | Phip -> "phi+" | Phim -> "phi-" | Phi0 -> "phi0" | H -> "H" | Eta -> "Eta" end let flavor_symbol = function | M f -> begin match f with | L n when n > 0 -> "l" ^ string_of_int n | L n -> "l" ^ string_of_int (abs n) ^ "b" | N n when n > 0 -> "n" ^ string_of_int n | N n -> "n" ^ string_of_int (abs n) ^ "b" | U n when n > 0 -> "u" ^ string_of_int n | U n -> "u" ^ string_of_int (abs n) ^ "b" | D n when n > 0 -> "d" ^ string_of_int n | D n -> "d" ^ string_of_int (abs n) ^ "b" | TopH -> "th" | TopHq -> "thb" | DH -> "dh" | DHq -> "dhb" end | G f -> begin match f with | Gl -> "gl" | Ga -> "a" | Z -> "z" | Wp -> "wp" | Wm -> "wm" | Xp -> "xp" | Xm -> "xm" | X0 -> "x0" | Y0 -> "y0" | ZH -> "zh" | Gl_aux -> "gx" end | O f -> begin match f with | Phip -> "pp" | Phim -> "pm" | Phi0 -> "p0" | H -> "h" | Eta -> "eta" end (* There are PDG numbers for Z', Z'', W', 32-34, respectively. We just introduce a number 38 for Y0 as a Z'''. As well, there is the number 8 for a t'. But we cheat a little bit and take the number 35 which is reserved for a heavy scalar Higgs for the Eta scalar. *) let pdg = function | M f -> begin match f with | L n when n > 0 -> 9 + 2*n | L n -> - 9 + 2*n | N n when n > 0 -> 10 + 2*n | N n -> - 10 + 2*n | U n when n > 0 -> 2*n | U n -> 2*n | D n when n > 0 -> - 1 + 2*n | D n -> 1 + 2*n | DH -> 7 | DHq -> (-7) | TopH -> 8 | TopHq -> (-8) end | G f -> begin match f with | Gl -> 21 | Ga -> 22 | Z -> 23 | Wp -> 24 | Wm -> (-24) | Xp -> 34 | Xm -> (-34) | ZH -> 32 | X0 -> 33 | Y0 -> 38 | Gl_aux -> 21 end | O f -> begin match f with | Phip | Phim -> 27 | Phi0 -> 26 | H -> 25 | Eta -> 36 end let mass_symbol f = "mass(" ^ string_of_int (abs (pdg f)) ^ ")" let width_symbol f = "width(" ^ string_of_int (abs (pdg f)) ^ ")" let constant_symbol = function | Unit -> "unit" | Pi -> "PI" | VHeavy -> "vheavy" | Alpha_QED -> "alpha" | E -> "e" | G_weak -> "g" | Vev -> "vev" | Sin2thw -> "sin2thw" | Sinthw -> "sinthw" | Costhw -> "costhw" | Sinpsi -> "sinpsi" | Cospsi -> "cospsi" | Atpsi -> "atpsi" | Sccs -> "sccs" | Supp -> "vF" | Supp2 -> "v2F2" | Q_lepton -> "qlep" | Q_up -> "qup" | Q_down -> "qdwn" | Q_Z_up -> "qzup" | G_over4 -> "gov4" | G_over4_sup -> "gov4sup" | G_CC_sup -> "gccsup" | G_zhthth -> "gzhthth" | G_NC_lepton -> "gnclep" | G_NC_neutrino -> "gncneu" | G_NC_up -> "gncup" | G_NC_down -> "gncdwn" | G_CC -> "gcc" | G_CC_heavy -> "gcch" | G_CC_supp1 -> "gsupp1" | G_CC_supp2 -> "gsupp2" | G_NC_h_lepton -> "gnchlep" | G_NC_h_neutrino -> "gnchneu" | G_NC_h_up -> "gnchup" | G_NC_h_down -> "gnchdwn" (* | G_NC_heavy -> "gnch" *) | I_Q_W -> "iqw" | I_G_ZWW -> "igzww" | I_G_WWW -> "igwww" | I_Q_H -> "iqh" | I_Q_ZH -> "iqzh" | I_G_Z1 -> "igz1" | I_G_Z2 -> "igz2" | I_G_Z3 -> "igz3" | I_G_Z4 -> "igz4" | G_WWWW -> "gw4" | G_ZZWW -> "gzzww" | G_AZWW -> "gazww" | G_AAWW -> "gaaww" | I_G1_AWW -> "ig1a" | I_G1_ZWW -> "ig1z" | I_G1_plus_kappa_AWW -> "ig1pka" | I_G1_plus_kappa_ZWW -> "ig1pkz" | I_G1_minus_kappa_AWW -> "ig1mka" | I_G1_minus_kappa_ZWW -> "ig1mkz" | I_kappa_minus_G1_AWW -> "ikmg1a" | I_kappa_minus_G1_ZWW -> "ikmg1z" | I_lambda_AWW -> "ila" | I_lambda_ZWW -> "ilz" | Alpha_WWWW0 -> "alww0" | Alpha_WWWW2 -> "alww2" | Alpha_ZZWW0 -> "alzw0" | Alpha_ZZWW1 -> "alzw1" | Alpha_ZZZZ -> "alzz" | G_HWW -> "ghww" | G_HZZ -> "ghzz" | G_heavy_HVV -> "ghyhvv" | G_heavy_HWW -> "ghyhww" | G_heavy_HZZ -> "ghyhzz" | G_HHWW -> "ghhww" | G_HHZZ -> "ghhzz" | G_heavy_HHVV -> "ghyhhvv" | G_Htt -> "ghtt" | G_Hbb -> "ghbb" | G_Htautau -> "ghtautau" | G_Hcc -> "ghcc" | G_Hthth -> "ghthth" | G_Htht -> "ghtht" | G_Ethth -> "gethth" | G_Etht -> "getht" | G_Ett -> "gett" | G_Ebb -> "gebb" | G_HGaGa -> "ghaa" | G_HGaZ -> "ghaz" | G_EGaGa -> "geaa" | G_EGaZ -> "geaz" | G_EGlGl -> "gegg" | G_ZEH -> "gzeh" | G_ZHEH -> "gzheh" | G_XEH -> "gxeh" | G_H3 -> "gh3" | G_H4 -> "gh4" | G_strong -> "gs" | Mass f -> "mass" ^ flavor_symbol f | Width f -> "width" ^ flavor_symbol f | K_Matrix_Coeff i -> "kc" ^ string_of_int i | K_Matrix_Pole i -> "kp" ^ string_of_int i end module O = Omega.Make(Fusion.Mixed23)(Targets.Fortran) (Zprime(SM_no_anomalous)) let _ = O.main () (*i * Local Variables: * mode:caml * indent-tabs-mode:nil * page-delimiter:"^(\\* .*\n" * End: i*)