(**
     OutputRules.m
**)
BeginPackage["OutputRules`","FeynArts`"]

FeynCalcRules::usage ="
FeynCalcRules are some transformation rules for creating an output \n
for the world famous FeynCalc program package (written by R.Mertig)."

ReadRules::usage ="
ReadRules are a collection of transformation rules that produce a \n
more readable output (for Format[FeynAmp])."

LastRules::usage ="
LastRules makes the final layout of a Feynman amplitude."

Begin["`Private`"]

FeynCalcRules = {
FeynAmpDenominator[ a___PropagatorDenominator, 
    PropagatorDenominator[q[1],mass_], 
    b___PropagatorDenominator ] :>
    FeynAmpDenominator[ PropagatorDenominator[q[1],mass], a, b ],
    PropagatorDenominator[ Plus[ a___, sign_. q[1] , b___ ], mass_ ] :>
    PropagatorDenominator[ Expand[ sign *Plus[sign*q[1],a,b] ] , mass ],
    SpinorChain[a_LeptonSpinor,b___,c_LeptonSpinor]:>
                     Dot[a,b,c]/;FreeQ[{b},LeptonSpinor],
    SpinorChain[a_QuarkSpinor,b___,c_QuarkSpinor]:>
                                  Dot[a,b,c]/;FreeQ[{b},QuarkSpinor],
    SpinorChain[1,b___,1]:>Dot[b]/;FreeQ[{b},LeptonSpinor],
    SpinorChain[1,b___,1]:>Dot[b]/;FreeQ[{b},QuarkSpinor],
    SpinorChain[a__]:> GDTrace[Dot[a]]/;FreeQ[{a},LeptonSpinor],
    SpinorChain[a__]:> GDTrace[Dot[a]]/;FreeQ[{a},QuarkSpinor],
    GDTrace[a___]:> TraceRule[a],
    DiracTrace[Dot[]]:> 1,
    GellMannTrace[Dot[]]:> 1,
    PolarizationVector[ - k_,r___ ] :> Conjugate[PolarizationVector[k,r]],
    FeynAmp[n___,MomentumIntegration[  mom__ ],amp_] :>
    FeynAmp[ n, mom, amp ]
}

TraceRule[a__] := Module[{gpart,dpart,dummydot},
   gpart = Function[ z , If[!FreeQ[z,GellMannMatrix],
                            Select[ z,!FreeQ[#,GellMannMatrix]& ],
                            1] ] /@ If[Head[a]===Plus,dummydot@a,a] ;
   gpart = Select[ gpart,Not[#===1]& ]/.dummydot->Dot;
   dpart = a /. GellMannMatrix[___] :> 1 ;
   DiracTrace[ dpart ] GellMannTrace [ gpart ]
 ]

                                      (** readable `layout' **)
ReadRule1 = {
PropagatorDenominator[a_,b_]:>If[ a===0&&b===0,
                                  0 ,
                                  1/(a^2-b^2) ],
DiracTrace[a___] :> "tr"[a] ,
GellMannTrace[a___] :> "tr"[a] ,
LeptonSpinor[a_,b_] :> If[ Length[a]>1,"v"[-a,b],"u"[a,b] ] ,
QuarkSpinor[a_,b_] :> If[ Length[a]>1,"v"[-a,b],"u"[a,b] ] ,
DiracSlash[p_] :> "gs"[p] ,
ChiralityProjector[+1] :> (1+"ga"[5])/2 ,
ChiralityProjector[-1] :> (1-"ga"[5])/2 ,
DiracMatrix[p_] :> "ga"[p] ,
SU3Delta[a__] :> "d"[a] ,
SU3F[a___] :> "f"[a] ,
GellMannMatrix[a___] :> "la"[a] ,
GaugeXi[a_] :> "xi"[a] ,
Conjugate[PolarizationVector[a__]] :> "ep(*)"[a] ,
PolarizationVector[a__] :> "ep"[a] ,
MetricTensor[a__] :> "g"[a] ,
FourVector[a_,b_] :> a[b] 
}

ReadRule2 = 
{FeynAmpDenominator[a___] :>  1/(Times[##]& @@ (1/# & /@ {a})) ,
Conjugate[a_] :> "QMM(*)"[ StringTake[ToString[a],-2] ] } 

ReadRules = x_ :> ((x//.ReadRule1)/.ReadRule2)

                                      (** final `layout' **)
LastRules = {
p[i_] :> ToExpression[StringJoin["p",ToString[i]]],
q[i_] :> ToExpression[StringJoin["q",ToString[i]]],
k[i_] :> ToExpression[StringJoin["k",ToString[i]]],
li[i_]:> ToExpression[StringJoin["li",ToString[i]]],
gi[i_]:> ToExpression[StringJoin["gi",ToString[i]]],
SpinorChain[ 1, line___, 1 ] :> SpinorChain[line],
SpinorChain[ 1, 1 ] -> 1,
FeynAmp[ n___, MomentumIntegration[], amp_ ] :> FeynAmp[ n,amp ]
}

End[]

EndPackage[]
