def get_charge_from_code(self,lookUpCode): """A function to return the charge of a particle given its PDG code.""" assert assertions.all_are_numbers([lookUpCode]) assert self.has_key(abs(lookUpCode)) if (lookUpCode > 0.0): return self.__pDEs[lookUpCode].get_charge() return (-1.0 * self.__pDEs[abs(lookUpCode)].get_charge())
def produce_new_vectors(v1, v3, PperpSquared, y): """A function to boost two vectors, perform the kinematics and return the tResults after boosting back.""" ##Requires v3 to be the recoiling vector, consistent with all kinematics in this project. assert (fourVectors.check_is_fourVector(v1) and fourVectors.check_is_fourVector(v3)) assert (v1.__nonzero__() and v3.__nonzero__()) assert assertions.all_are_numbers([PperpSquared, y]) __energyIn = v1[0] + v3[ 0] ##This is in the 'lab frame' as these are never actually boosted in the code. __S123, __Pperp = Sijk([v1.copy(), v3.copy()]), math.sqrt(PperpSquared) __boostRotate = lorentz.boostAndRotate( v1.copy(), v3.copy(), 1) ##Given v3 as vector to recoil so need index 1 here. __nBRV1, __nBRV2, __nBRV3 = calculate_split_ps(__S123, __Pperp, y) assert precision.check_numbers_equal(0.0, __nBRV1[3] + __nBRV2[3] + __nBRV3[3]) __nV1, __nV2, __nV3 = __boostRotate / __nBRV1, __boostRotate / __nBRV2, __boostRotate / __nBRV3 ##Must also check energy out in the 'lab' frame too as not a Lorentz invariant quantity. __energyOut = __nV1[0] + __nV2[0] + __nV3[0] __energyDifference = __energyIn - __energyOut __nV2 = fix_energy_difference(__energyDifference, __nV2) ##Check conservation rules: assert precision.check_numbers_equal(__energyIn, __energyOut) assert precision.check_numbers_equal( __S123, Sijk([__nV1.copy(), __nV2.copy(), __nV3.copy()])) ##No check for any momentums here as no longer have to sum to zero in this frame. return __nV1, __nV2, __nV3
def calculate(self,QSquared): """A function for calculating the four-loop strong coupling constant at a given COM energy squared.""" ##Using approximate analytic solution. ##Source: 'Quantum Chromodynamics', Dissertori Group, Lpthe Group, P Salam, p3, equation 9.5. assert assertions.all_are_numbers([QSquared]) __QSquared = assertions.force_float_number(QSquared) __Nf, __pi = Nf(__QSquared), math.pi __beta0 = beta0(__Nf) / (4.0*__pi) __beta1 = beta1(__Nf) / ((4.0*__pi)*(4.0*__pi)) __beta2 = beta2(__Nf) / ((4.0*__pi)*(4.0*__pi)*(4.0*__pi)) __beta3 = beta3(__Nf) / ((4.0*__pi)*(4.0*__pi)*(4.0*__pi)*(4.0*__pi)) try: __denominator6 = (self.__fourLoopLambda*self.__fourLoopLambda) assert assertions.safe_division(__denominator6) __ln = math.log(__QSquared/__denominator6) __denominator7 = __beta0*__beta0*__ln assert assertions.safe_division(__denominator7) __term1 = __beta1*math.log(__ln)/__denominator7 __denominator8 = __beta0*__beta0*__beta0*__beta0*__ln*__ln assert assertions.safe_division(__denominator8) __term2 = ((__beta1*__beta1 * ((math.log(__ln)*math.log(__ln)) - math.log(__ln) - 1.0)) + __beta0*__beta2) / __denominator8 __term3P1 = (math.log(__ln)*math.log(__ln)*math.log(__ln)) - (5.0/2.0)*math.log(__ln)*math.log(__ln) - 2.0*math.log(__ln) + 0.5 __denominator9 = (__beta0*__beta0*__beta0*__beta0*__beta0*__beta0*__ln*__ln*__ln) assert assertions.safe_division(__denominator9) __term3 = (__beta1*__beta1*__beta1 * __term3P1) / __denominator9 __term4 = ((3.0*__beta0*__beta1*__beta2*math.log(__ln)) - (0.5*__beta0*__beta0*__beta3)) / __denominator9 __denominator10 = __beta0*__ln assert assertions.safe_division(__denominator10) __result = (1.0 - __term1 + __term2 - (__term3 + __term4)) / __denominator10 return __result except: print "Error in four-loop at QSquared =", __QSquared return -1.0
def calc_inv_G(valueIn,S123): """A function to calculate the inverse of G for for all processes.""" assert assertions.all_are_numbers([valueIn,S123]) __alphaSMax = alphaS.get_shower_max() __term1 = ((-4.0)*math.pi*valueIn) / (3.0*__alphaSMax) __exp = math.exp(math.sqrt(__term1)) return S123/__exp
def __init__(self,orderedListOfParticles,isLoop = False,maxPperpSquaredFromSplit = None): """A function to initialise a chain using the ordered list of particles given.""" ##Accepting an ordered list of particles allows the initialisation of a chain of any length at any stage. for particle in orderedListOfParticles: assert particles.check_is_particle(particle) assert (isLoop or not(isLoop)) assert ((maxPperpSquaredFromSplit == None) or (assertions.all_are_numbers([maxPperpSquaredFromSplit]))) self.__chainList = [] for i in range(len(orderedListOfParticles) - 1): ##Iterate through all particle pairs. self.__chainList.append(dipoles.dipole(orderedListOfParticles[i],orderedListOfParticles[i+1])) self.__isLoop = isLoop if (maxPperpSquaredFromSplit == None): if (len(self.__chainList) == 1): self.__maxPperpSquared = self.__chainList[0].get_mass_squared() else: print "\n! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !" print "Not sure what to do here yet!" #assert False self.__maxPperpSquared = self.__chainList[0].get_mass_squared() assertions.pause_loading_module() ##Or do you find that of the entire chain. Or do you find that of each -> Need list? else: self.__maxPperpSquared = maxPperpSquaredFromSplit self.__cutOff = constants.cut_off_energy()*constants.cut_off_energy() self.__nextPperpSquared = None ##Initiation value. self.__showeringCompleted = False
def calculate(self,Q): """A function for calculating the two-loop strong coupling constant at a given COM energy squared.""" ##Source: Paper 'Measurements of the strong coupling constant and the QCD colour factors using four-jet.. ##..observables from hadronic Z decays', p4, equations 2-5. ##Unlike the others, these equations are given as a function of Q not Q^2 and so use Mz and alphaS(Mz). assert assertions.all_are_numbers([Q]) __Q = assertions.force_float_number(Q) __Nf, __Cf, __twoLoopAlphaSOfMz = Nf(__Q*__Q), constants.Cf(), self.__twoLoopAlphaSOfMz __Mz = particleData.knownParticles.get_mass_from_code(particleData.knownParticles.get_code_from_name('Z-boson')) ##Adjust betas to those of this paper: __beta0 = beta0(__Nf) / __Cf __beta1 = beta1(__Nf) / (2.0*__Cf*__Cf) try: assert assertions.safe_division(__Q) __ln1 = math.log(__Mz/__Q) __wOfQ = 1.0 - (__beta0*__twoLoopAlphaSOfMz*__Cf*__ln1 / (2.0* math.pi)) __denominator4 = __beta0*2.0*math.pi*__wOfQ assert assertions.safe_division(__denominator4) __term1 = 1.0 - (__beta1*__twoLoopAlphaSOfMz*__Cf*math.log(__wOfQ)/__denominator4) __denominator5 = __wOfQ assert assertions.safe_division(__denominator5) __result = __twoLoopAlphaSOfMz*__term1 / __denominator5 return __result except: ##Breaks down below the cut-off energy as expected. print "Error in two-loop at Q =", __Q return -1.0
def force_float_vector(self): """A function to convert all vector integers to floats but leave doubles.""" for __i2 in range(4): assert assertions.all_are_numbers([__i2]) if (not assertions.check_float(self.__vector[__i2])): self.__vector[__i2] = assertions.force_float_number( self.__vector[__i2])
def calc_G(PperpSquared, S123): """A function to calculate the overestimation function G, the primitive of g(PperpSquared) = g1(PperpSquared)*int{g2(y) dy}, for all processes.""" assert assertions.all_are_numbers([PperpSquared, S123]) __alphaSMax = alphaS.get_shower_max() __term1 = ((-3.0) * __alphaSMax) / (4.0 * math.pi) return __term1 * math.log(S123 / PperpSquared) * math.log( S123 / PperpSquared)
def calc_inv_G(valueIn, S123): """A function to calculate the inverse of G for for all processes.""" assert assertions.all_are_numbers([valueIn, S123]) __alphaSMax = alphaS.get_shower_max() __term1 = ((-4.0) * math.pi * valueIn) / (3.0 * __alphaSMax) __exp = math.exp(math.sqrt(__term1)) return S123 / __exp
def sum_cSs(difCrossSecIds, S123, PperpSquared, y, code1, code2): """A function to return the sum of each cross section from its process code in the list given.""" assert (type(difCrossSecIds) == list) assert assertions.all_are_numbers([S123, PperpSquared, y]) __kQs = particleData.knownParticles.get_known_quarks() __gC = particleData.knownParticles.get_code_from_name('gluon') __expectedCodes = __kQs + [-x for x in __kQs] + [__gC] assert ((code1 in __expectedCodes) and (code2 in __expectedCodes)) __result = 0.0 for __difCrossSecId in difCrossSecIds: assert ((0 <= __difCrossSecId) and (__difCrossSecId <= 6)) if __difCrossSecId == 0: __result += qqBar_to_qgqBar_cS(S123, PperpSquared, y) elif __difCrossSecId == 1: __result += qg_to_qgg_cS(S123, PperpSquared, y) elif __difCrossSecId == 2: __result += gg_to_ggg_cS(S123, PperpSquared, y) elif __difCrossSecId == 3: __result += qg_to_qQQBar_cS(S123, PperpSquared, y) elif __difCrossSecId == 4: __result += gg_to_gQQBar_cS(S123, PperpSquared, y) elif __difCrossSecId == 5: __result += gg_to_gQQBar_cS(S123, PperpSquared, y) elif __difCrossSecId == 6: __result += qqBar_to_qpqBar_cS(S123, PperpSquared, y, code1, code2) return __result
def calc_g( PperpSquared, y ): ##Calculate the function g(Pperpsquared,y) = g1(Pperpsquared)*g2(y). """A function to calculate the overestimation function g for all processes.""" assert assertions.all_are_numbers([PperpSquared, y]) __alphaSMax = alphaS.get_shower_max() return (3.0 * __alphaSMax) / (2.0 * math.pi * PperpSquared)
def solve(PperpSquaredMax,S123,code1,code2): """A function to return the next Pperp^2, y and winning process for a given dipole.""" assert assertions.all_are_numbers([PperpSquaredMax,S123]) __kQs = particleData.knownParticles.get_known_quarks() __gC = particleData.knownParticles.get_code_from_name('gluon') __expectedCodes = __kQs + [-x for x in __kQs] + [__gC] assert ((code1 in __expectedCodes) and (code2 in __expectedCodes)) if ((code1 in __kQs) and ((-code2) in __kQs)): ##qqBar. __caseGroupId = 0 elif (((-code1) in __kQs) and (code2 in __kQs)): ##qBarq. __caseGroupId = 0 elif (((code1) in __kQs) and (code2 in __kQs)): ##qq. __caseGroupId = 0 elif (((-code1) in __kQs) and (-code2 in __kQs)): ##qBarqBar. __caseGroupId = 0 elif ((code1 in __kQs) and (code2 == __gC)): ##qg. __caseGroupId = 1 elif (((-code1) in __kQs) and (code2 == __gC)): ##qBarg. __caseGroupId = 1 elif ((code1 == __gC) and (code2 in __kQs)): ##gq. __caseGroupId = 1 elif ((code1 == __gC) and ((-code2) in __kQs)): ##gqBar. __caseGroupId = 1 elif ((code1 == __gC) and (code2 == __gC)): ##gg. __caseGroupId = 2 if (__caseGroupId == 0): __newPperpSquared, __newY, __newProcessCode = solve_case_group_0(PperpSquaredMax,S123,code1,code2) elif (__caseGroupId == 1): __newPperpSquared, __newY, __newProcessCode = solve_case_group_1(PperpSquaredMax,S123,code1,code2) elif (__caseGroupId == 2): __newPperpSquared, __newY, __newProcessCode = solve_case_group_2(PperpSquaredMax,S123,code1,code2) ##Process codes: 0 = stop shower, 1 = gluon emission, 2 = gluon splitting, 3 = photon emission. ##gg has two chances for a gluon to split but nothing specifies which is which so if occurs, randomly chosen later. return __newPperpSquared, __newY, __newProcessCode
def sum_cSs(difCrossSecIds,S123,PperpSquared,y,code1,code2): """A function to return the sum of each cross section from its process code in the list given.""" assert (type(difCrossSecIds) == list) assert assertions.all_are_numbers([S123,PperpSquared,y]) __kQs = particleData.knownParticles.get_known_quarks() __gC = particleData.knownParticles.get_code_from_name('gluon') __expectedCodes = __kQs + [-x for x in __kQs] + [__gC] assert ((code1 in __expectedCodes) and (code2 in __expectedCodes)) __result = 0.0 for __difCrossSecId in difCrossSecIds: assert ((0 <= __difCrossSecId) and (__difCrossSecId <= 6)) if __difCrossSecId == 0: __result += qqBar_to_qgqBar_cS(S123,PperpSquared,y) elif __difCrossSecId == 1: __result += qg_to_qgg_cS(S123,PperpSquared,y) elif __difCrossSecId == 2: __result += gg_to_ggg_cS(S123,PperpSquared,y) elif __difCrossSecId == 3: __result += qg_to_qQQBar_cS(S123,PperpSquared,y) elif __difCrossSecId == 4: __result += gg_to_gQQBar_cS(S123,PperpSquared,y) elif __difCrossSecId == 5: __result += gg_to_gQQBar_cS(S123,PperpSquared,y) elif __difCrossSecId == 6: __result += qqBar_to_qpqBar_cS(S123,PperpSquared,y,code1,code2) return __result
def calculate(self, Q): """A function for calculating the two-loop strong coupling constant at a given COM energy squared.""" ##Source: Paper 'Measurements of the strong coupling constant and the QCD colour factors using four-jet.. ##..observables from hadronic Z decays', p4, equations 2-5. ##Unlike the others, these equations are given as a function of Q not Q^2 and so use Mz and alphaS(Mz). assert assertions.all_are_numbers([Q]) __Q = assertions.force_float_number(Q) __Nf, __Cf, __twoLoopAlphaSOfMz = Nf( __Q * __Q), constants.Cf(), self.__twoLoopAlphaSOfMz __Mz = particleData.knownParticles.get_mass_from_code( particleData.knownParticles.get_code_from_name('Z-boson')) ##Adjust betas to those of this paper: __beta0 = beta0(__Nf) / __Cf __beta1 = beta1(__Nf) / (2.0 * __Cf * __Cf) try: assert assertions.safe_division(__Q) __ln1 = math.log(__Mz / __Q) __wOfQ = 1.0 - (__beta0 * __twoLoopAlphaSOfMz * __Cf * __ln1 / (2.0 * math.pi)) __denominator4 = __beta0 * 2.0 * math.pi * __wOfQ assert assertions.safe_division(__denominator4) __term1 = 1.0 - (__beta1 * __twoLoopAlphaSOfMz * __Cf * math.log(__wOfQ) / __denominator4) __denominator5 = __wOfQ assert assertions.safe_division(__denominator5) __result = __twoLoopAlphaSOfMz * __term1 / __denominator5 return __result except: ##Breaks down below the cut-off energy as expected. print "Error in two-loop at Q =", __Q return -1.0
def get_charge_from_code(self, lookUpCode): """A function to return the charge of a particle given its PDG code.""" assert assertions.all_are_numbers([lookUpCode]) assert self.has_key(abs(lookUpCode)) if (lookUpCode > 0.0): return self.__pDEs[lookUpCode].get_charge() return (-1.0 * self.__pDEs[abs(lookUpCode)].get_charge())
def __imul__(self, multiplier): ##Used for *= """A function for multiplying a four-vector by a scalar.""" assert assertions.all_are_numbers([multiplier]) assert self.__nonzero__() __multiplier = assertions.force_float_number(multiplier) for __i7 in range(4): self[__i7] *= __multiplier return self
def __setitem__(self, i6, newValue): """A function to assign an entry in a four-vector object.""" assert assertions.valid_four_vector_index(i6) assert assertions.all_are_numbers([newValue]) __newValue = assertions.force_float_number(newValue) self.__vector[i6] = __newValue self.__positionsEmpty[i6] = False self.update_empty()
def __imul__(self,multiplier): ##Used for *= """A function for multiplying a four-vector by a scalar.""" assert assertions.all_are_numbers([multiplier]) assert self.__nonzero__() __multiplier = assertions.force_float_number(multiplier) for __i7 in range(4): self[__i7] *= __multiplier return self
def calculate(self,QSquared): """A function for calculating the one-loop fine structure constant at a given COM energy squared.""" ##Source: "https://www.ippp.dur.ac.uk/~krauss/Lectures/QuarksLeptons/QCD/AsymptoticFreedom_1.html". assert assertions.all_are_numbers([QSquared]) __QSquared = assertions.force_float_number(QSquared) __Mz = particleData.knownParticles.get_mass_from_code(particleData.knownParticles.get_code_from_name('Z-boson')) __ln = math.log(__QSquared/(__Mz*__Mz)) __denominator = 1.0 - (self.__oneLoopAlphaEMOfMzSquared*__ln/(3.0*math.pi)) return self.__oneLoopAlphaEMOfMzSquared / __denominator
def __init__(self,nameToSet,massToSet = 0.0,widthToSet = 0.0,chargeToSet = 0.0,spinToSet = 0.0): """A function to initiate a PDG entry. Only particles not anti-knownParticles.""" assert (type(nameToSet) == str) assert assertions.all_are_numbers([massToSet,widthToSet,chargeToSet,spinToSet]) self.__name = nameToSet self.__mass = assertions.force_float_number(massToSet) self.__width = assertions.force_float_number(widthToSet) self.__charge = assertions.force_float_number(chargeToSet) self.__spin = assertions.force_float_number(spinToSet)
def __div__(self, denominator): ##Used for fVA / denominator. """A function for dividing a four-vector by a scalar.""" assert assertions.all_are_numbers([denominator]) assert assertions.safe_division(denominator) assert self.__nonzero__() __denominator = assertions.force_float_number(denominator) __result3 = self.copy() __result3 /= __denominator return __result3
def __idiv__(self,denominator): ##Used for /= """A function for dividing a four-vector by a scalar.""" assert assertions.all_are_numbers([denominator]) assert assertions.safe_division(denominator) assert self.__nonzero__() __denominator = assertions.force_float_number(denominator) for __i8 in range(4): self[__i8] /= __denominator return self
def __idiv__(self, denominator): ##Used for /= """A function for dividing a four-vector by a scalar.""" assert assertions.all_are_numbers([denominator]) assert assertions.safe_division(denominator) assert self.__nonzero__() __denominator = assertions.force_float_number(denominator) for __i8 in range(4): self[__i8] /= __denominator return self
def __div__(self,denominator): ##Used for fVA / denominator. """A function for dividing a four-vector by a scalar.""" assert assertions.all_are_numbers([denominator]) assert assertions.safe_division(denominator) assert self.__nonzero__() __denominator = assertions.force_float_number(denominator) __result3 = self.copy() __result3 /= __denominator return __result3
def gg_to_ggg_cS(S123,PperpSquared,y): ##difCrossSecId = 2 """A function to calculate the differential cross section for gg -> ggg.""" assert assertions.all_are_numbers([S123,PperpSquared,y]) __alphaSNow = alphaS.calculate(PperpSquared) __x1 = kinematics.calculate_x1(S123,math.sqrt(PperpSquared),y) __x3 = kinematics.calculate_x3(S123,math.sqrt(PperpSquared),y) __preFactor = (3.0*__alphaSNow)/(4.0*math.pi) __numerator = (__x1*__x1*__x1) + (__x3*__x3*__x3) __denominator = (1.0 - __x1)*(1.0 - __x3) return __preFactor*(__numerator/__denominator)
def Nf(QSquared): """A function to return the number of quark flavours that can be produced given a centre of mass energy squared.""" assert assertions.all_are_numbers([QSquared]) __QSquared = assertions.force_float_number(QSquared) __nf = 0 for __quarkCode in particleData.knownParticles.get_known_quarks(): __quarkMass = particleData.knownParticles.get_mass_from_code(__quarkCode) if (2.0*__quarkMass < math.sqrt(__QSquared)): __nf += 1 return __nf
def gg_to_ggg_cS(S123, PperpSquared, y): ##difCrossSecId = 2 """A function to calculate the differential cross section for gg -> ggg.""" assert assertions.all_are_numbers([S123, PperpSquared, y]) __alphaSNow = alphaS.calculate(PperpSquared) __x1 = kinematics.calculate_x1(S123, math.sqrt(PperpSquared), y) __x3 = kinematics.calculate_x3(S123, math.sqrt(PperpSquared), y) __preFactor = (3.0 * __alphaSNow) / (4.0 * math.pi) __numerator = (__x1 * __x1 * __x1) + (__x3 * __x3 * __x3) __denominator = (1.0 - __x1) * (1.0 - __x3) return __preFactor * (__numerator / __denominator)
def qg_to_qQQBar_cS(S123, PperpSquared, y): ##difCrossSecId = 3 """A function to calculate the differential cross section for qg -> qQQBar.""" assert assertions.all_are_numbers([S123, PperpSquared, y]) __alphaSNow = alphaS.calculate(PperpSquared) __x1 = kinematics.calculate_x1(S123, math.sqrt(PperpSquared), y) __x2 = kinematics.calculate_x2(S123, math.sqrt(PperpSquared), y) __x3 = kinematics.calculate_x3(S123, math.sqrt(PperpSquared), y) __preFactor = (3.0 * __alphaSNow) / (8.0 * math.pi) __numerator = ((1.0 - __x1) * (1.0 - __x1)) + ((1.0 - __x2) * (1.0 - __x2)) __denominator = (1.0 - __x3) return __preFactor * (__numerator / __denominator)
def qg_to_qQQBar_cS(S123,PperpSquared,y): ##difCrossSecId = 3 """A function to calculate the differential cross section for qg -> qQQBar.""" assert assertions.all_are_numbers([S123,PperpSquared,y]) __alphaSNow = alphaS.calculate(PperpSquared) __x1 = kinematics.calculate_x1(S123,math.sqrt(PperpSquared),y) __x2 = kinematics.calculate_x2(S123,math.sqrt(PperpSquared),y) __x3 = kinematics.calculate_x3(S123,math.sqrt(PperpSquared),y) __preFactor = (3.0*__alphaSNow)/(8.0*math.pi) __numerator = ((1.0 - __x1)*(1.0 - __x1)) + ((1.0 - __x2)*(1.0 - __x2)) __denominator = (1.0 - __x3) return __preFactor*(__numerator/__denominator)
def calculate(self, QSquared): """A function for calculating the one-loop fine structure constant at a given COM energy squared.""" ##Source: "https://www.ippp.dur.ac.uk/~krauss/Lectures/QuarksLeptons/QCD/AsymptoticFreedom_1.html". assert assertions.all_are_numbers([QSquared]) __QSquared = assertions.force_float_number(QSquared) __Mz = particleData.knownParticles.get_mass_from_code( particleData.knownParticles.get_code_from_name('Z-boson')) __ln = math.log(__QSquared / (__Mz * __Mz)) __denominator = 1.0 - (self.__oneLoopAlphaEMOfMzSquared * __ln / (3.0 * math.pi)) return self.__oneLoopAlphaEMOfMzSquared / __denominator
def __init__(self, tX0=None, tX1=None, tX2=None, tX3=None): """A function to initiate a four-vector object.""" for __anX in [tX0, tX1, tX2, tX3]: assert ((__anX == None) or assertions.all_are_numbers([__anX])) self.__positionsEmpty = [False,False,False,False] self.__initialX0 , self.__initialX1 , self.__initialX2, self.__initialX3 = tX0 , tX1 , tX2 , tX3 ##Track un-filled four-vectors (using self.__isEmpty = T/F) to prevent empty vector appearing as zero vector. self.count_initially_empty() assert ((self.__numberInitiallyEmpty == 0) or (self.__numberInitiallyEmpty == 4)) if (self.__numberInitiallyEmpty == 0): self.__isEmpty = False self.__initialX0, self.__initialX1 = self.__initialX0 , self.__initialX1 self.__initialX2, self.__initialX3 = self.__initialX2 , self.__initialX3 vector = [self.__initialX0,self.__initialX1,self.__initialX2,self.__initialX3] assert assertions.all_are_numbers(vector) self.__vector = vector elif self.__numberInitiallyEmpty == 4: self.__isEmpty = True self.__vector = [0.0, 0.0, 0.0, 0.0] self.force_float_vector()
def Nf(QSquared): """A function to return the number of quark flavours that can be produced given a centre of mass energy squared.""" assert assertions.all_are_numbers([QSquared]) __QSquared = assertions.force_float_number(QSquared) __nf = 0 for __quarkCode in particleData.knownParticles.get_known_quarks(): __quarkMass = particleData.knownParticles.get_mass_from_code( __quarkCode) if (2.0 * __quarkMass < math.sqrt(__QSquared)): __nf += 1 return __nf
def calculate(self,QSquared): """A function for calculating the one-loop strong coupling constant at a given COM energy squared.""" ##Source: 'Determination of the QCD coupling alphaS'. assert assertions.all_are_numbers([QSquared]) __QSquared = assertions.force_float_number(QSquared) __Nf= Nf(__QSquared) __Mz = particleData.knownParticles.get_mass_from_code(particleData.knownParticles.get_code_from_name('Z-boson')) ##Encorporate in factor of 1/4Pi to make the beta function match: __beta0 = beta0(__Nf) / (4.0*math.pi) __denominator1 = (__Mz*__Mz) __ln = math.log(__QSquared/__denominator1) __denominator2 = 1.0 + (self.__oneLoopAlphaSOfMzSquared * __beta0 * __ln) return self.__oneLoopAlphaSOfMzSquared / __denominator2
def solve_case_group_0(PperpSquaredMax,S123,code1,code2): """A function to return the next Pperp^2, y and winning process for case group 0/A.""" ##qqBar, qBarq, qq or qBarqBar so gluon emission or photon emission. assert assertions.all_are_numbers([PperpSquaredMax,S123]) __kQs = particleData.knownParticles.get_known_quarks() __expectedCodes = __kQs + [-x for x in __kQs] assert ((code1 in __expectedCodes) and (code2 in __expectedCodes)) __difCrossSecIds = [0] ##Gluon emission always possible. if assertions.EM_radiation_on(): __difCrossSecIds.append(6) ##Photon emission possible. __PperpSquared, __y, __difCrossSecId = solve_sudakovs(PperpSquaredMax,S123,__difCrossSecIds,code1,code2) __convertIdToProcessCode = {None:0,0:1,1:1,2:1,6:3} return __PperpSquared, __y, __convertIdToProcessCode[__difCrossSecId]
def calculate_kPerp(S123, Pperp, y): """A function to calculate the actual transverse momentum following a dipole splitting.""" assert assertions.all_are_numbers([S123, Pperp, y]) __E1, __E2, __E3 = calculate_E1(S123, Pperp, y), calculate_E2( S123, Pperp, y), calculate_E3(S123, Pperp, y) assert (__E2 < (__E1 + __E3)) ##+ve y -> E3>E1 but -ve y -> E1>E3. if ((__E2 > __E1) or (__E2 > __E3)): ##Too many of these would be a problem so track occurance. counters.kPerpProdWarningCounter.count() __term2 = (((__E1 * __E1) - (__E2 * __E2) + (__E3 * __E3)) / (2.0 * __E3)) kPerpSquared = (__E1 * __E1) - (__term2 * __term2) return math.sqrt(kPerpSquared)
def solve_case_group_0(PperpSquaredMax, S123, code1, code2): """A function to return the next Pperp^2, y and winning process for case group 0/A.""" ##qqBar, qBarq, qq or qBarqBar so gluon emission or photon emission. assert assertions.all_are_numbers([PperpSquaredMax, S123]) __kQs = particleData.knownParticles.get_known_quarks() __expectedCodes = __kQs + [-x for x in __kQs] assert ((code1 in __expectedCodes) and (code2 in __expectedCodes)) __difCrossSecIds = [0] ##Gluon emission always possible. if assertions.EM_radiation_on(): __difCrossSecIds.append(6) ##Photon emission possible. __PperpSquared, __y, __difCrossSecId = solve_sudakovs( PperpSquaredMax, S123, __difCrossSecIds, code1, code2) __convertIdToProcessCode = {None: 0, 0: 1, 1: 1, 2: 1, 6: 3} return __PperpSquared, __y, __convertIdToProcessCode[__difCrossSecId]
def calculate_split_ps(S123, Pperp, y): """A function to calculate the new p1,p2,p3 four-vectors following a dipole splitting.""" ##Letting p2 take +Pperp and p1 take -Pperp by convention. assert assertions.all_are_numbers([S123, Pperp, y]) assert ((S123 > 0.0) and (Pperp > 0.0)) __E1, __E2 = calculate_E1(S123, Pperp, y), calculate_E2(S123, Pperp, y) __E3, __kPerp = calculate_E3(S123, Pperp, y), calculate_kPerp(S123, Pperp, y) ##Store all energies produced for plotting graphs after showering: e1s.store(__E1) e2s.store(__E2) e3s.store(__E3) __randomPhi, __newP1 = get_random_phi(), fourVectors.fourVector( 0.0, 0.0, 0.0, 0.0) __newP2, __newP3 = fourVectors.fourVector(0.0, 0.0, 0.0, 0.0), fourVectors.fourVector( 0.0, 0.0, 0.0, 0.0) assert (0.0 < __randomPhi and __randomPhi < 2.0 * math.pi) ##Populate the first vector: __newP1[0] = __E1 __newP1[1] = (-1.0) * __kPerp * math.cos(__randomPhi) __newP1[2] = (-1.0) * __kPerp * math.sin(__randomPhi) __newP1[3] = math.sqrt((__E1 * __E1) - (__kPerp * __kPerp)) assert ((__newP1[0] > 0.0) and (__newP1[3] > 0.0)) ##Populate the second vector: __newP2[0] = __E2 __newP2[1] = __kPerp * math.cos(__randomPhi) __newP2[2] = __kPerp * math.sin(__randomPhi) __newP2[3] = math.sqrt((__E2 * __E2) - (__kPerp * __kPerp)) assert (__newP2[0] > 0.0) ##Populate the third vector. Entries 1 & 2 already 0 as required: __newP3[0] = __E3 __newP3[3] = (-1.0) * __E3 assert ((__newP3[0] > 0.0) and (__newP3[3] < 0.0)) ##Log x's for a produced particle for plotting after showering: tX1s.store(calculate_x1(S123, Pperp, y)) tX3s.store(calculate_x3(S123, Pperp, y)) ##Check the direction of the produced particle is consistent with parallel momentum conservation. ##This allows for different recoil configurations. if precision.check_numbers_equal(0.0, __newP1[3] + __newP2[3] + __newP3[3]): return __newP1, __newP2, __newP3 elif precision.check_numbers_equal(0.0, __newP1[3] - __newP2[3] + __newP3[3]): __newP2[3] = -__newP2[3] return __newP1, __newP2, __newP3 elif precision.check_numbers_equal(0.0, -__newP1[3] + __newP2[3] + __newP3[3]): __newP1[3] = -__newP1[3] return __newP1, __newP2, __newP3
def solve_case_group_2(PperpSquaredMax,S123,code1,code2): """A function to return the next Pperp^2, y and winning process for case group 2/C.""" ##qqBar or qBarq so gluon emission, gluon 1 splitting or gluon 2 splitting. assert assertions.all_are_numbers([PperpSquaredMax,S123]) __gC = particleData.knownParticles.get_code_from_name('gluon') assert ((code1 == __gC) and (code2 == __gC)) __difCrossSecIds = [2] ##Gluon emission always possible. if assertions.gluon_splitting_on(): __difCrossSecIds.append(4) ##Gluon 1 splitting possible. __difCrossSecIds.append(5) ##Gluon 2 splitting possible. ##Note that gluons 1,2 to not refer to a specific gluon in the dipole, only that there are two gluons. __PperpSquared, __y, __difCrossSecId = solve_sudakovs(PperpSquaredMax,S123,__difCrossSecIds,code1,code2) __convertIdToProcessCode = {None:0,0:1,1:1,2:1,3:2,4:2,5:2} return __PperpSquared, __y, __convertIdToProcessCode[__difCrossSecId]
def solve_case_group_2(PperpSquaredMax, S123, code1, code2): """A function to return the next Pperp^2, y and winning process for case group 2/C.""" ##qqBar or qBarq so gluon emission, gluon 1 splitting or gluon 2 splitting. assert assertions.all_are_numbers([PperpSquaredMax, S123]) __gC = particleData.knownParticles.get_code_from_name('gluon') assert ((code1 == __gC) and (code2 == __gC)) __difCrossSecIds = [2] ##Gluon emission always possible. if assertions.gluon_splitting_on(): __difCrossSecIds.append(4) ##Gluon 1 splitting possible. __difCrossSecIds.append(5) ##Gluon 2 splitting possible. ##Note that gluons 1,2 to not refer to a specific gluon in the dipole, only that there are two gluons. __PperpSquared, __y, __difCrossSecId = solve_sudakovs( PperpSquaredMax, S123, __difCrossSecIds, code1, code2) __convertIdToProcessCode = {None: 0, 0: 1, 1: 1, 2: 1, 3: 2, 4: 2, 5: 2} return __PperpSquared, __y, __convertIdToProcessCode[__difCrossSecId]
def __init__(self, tX0=None, tX1=None, tX2=None, tX3=None): """A function to initiate a four-vector object.""" for __anX in [tX0, tX1, tX2, tX3]: assert ((__anX == None) or assertions.all_are_numbers([__anX])) self.__positionsEmpty = [False, False, False, False] self.__initialX0, self.__initialX1, self.__initialX2, self.__initialX3 = tX0, tX1, tX2, tX3 ##Track un-filled four-vectors (using self.__isEmpty = T/F) to prevent empty vector appearing as zero vector. self.count_initially_empty() assert ((self.__numberInitiallyEmpty == 0) or (self.__numberInitiallyEmpty == 4)) if (self.__numberInitiallyEmpty == 0): self.__isEmpty = False self.__initialX0, self.__initialX1 = self.__initialX0, self.__initialX1 self.__initialX2, self.__initialX3 = self.__initialX2, self.__initialX3 vector = [ self.__initialX0, self.__initialX1, self.__initialX2, self.__initialX3 ] assert assertions.all_are_numbers(vector) self.__vector = vector elif self.__numberInitiallyEmpty == 4: self.__isEmpty = True self.__vector = [0.0, 0.0, 0.0, 0.0] self.force_float_vector()
def calculate(self, QSquared): """A function for calculating the one-loop strong coupling constant at a given COM energy squared.""" ##Source: 'Determination of the QCD coupling alphaS'. assert assertions.all_are_numbers([QSquared]) __QSquared = assertions.force_float_number(QSquared) __Nf = Nf(__QSquared) __Mz = particleData.knownParticles.get_mass_from_code( particleData.knownParticles.get_code_from_name('Z-boson')) ##Encorporate in factor of 1/4Pi to make the beta function match: __beta0 = beta0(__Nf) / (4.0 * math.pi) __denominator1 = (__Mz * __Mz) __ln = math.log(__QSquared / __denominator1) __denominator2 = 1.0 + (self.__oneLoopAlphaSOfMzSquared * __beta0 * __ln) return self.__oneLoopAlphaSOfMzSquared / __denominator2
def __init__(self, nameToSet, massToSet=0.0, widthToSet=0.0, chargeToSet=0.0, spinToSet=0.0): """A function to initiate a PDG entry. Only particles not anti-knownParticles.""" assert (type(nameToSet) == str) assert assertions.all_are_numbers( [massToSet, widthToSet, chargeToSet, spinToSet]) self.__name = nameToSet self.__mass = assertions.force_float_number(massToSet) self.__width = assertions.force_float_number(widthToSet) self.__charge = assertions.force_float_number(chargeToSet) self.__spin = assertions.force_float_number(spinToSet)
def qqBar_to_qpqBar_cS(S123,PperpSquared,y,code1,code2): ##difCrossSecId = 6 """A function to calculate the differential cross section for qqBar -> qpqBar.""" assert assertions.all_are_numbers([S123,PperpSquared,y]) __kQs = particleData.knownParticles.get_known_quarks() __expectedCodes = __kQs + [-x for x in __kQs] assert ((code1 in __expectedCodes) and (code2 in __expectedCodes)) __alphaEMNow = alphaEM.calculate(PperpSquared) __charge1 = particleData.knownParticles.get_charge_from_code(code1) __charge2 = particleData.knownParticles.get_charge_from_code(code2) __x1 = kinematics.calculate_x1(S123,math.sqrt(PperpSquared),y) __x3 = kinematics.calculate_x3(S123,math.sqrt(PperpSquared),y) __preFactor = (__alphaEMNow*abs(__charge1)*abs(__charge2))/(2.0*math.pi) __numerator = (__x1*__x1) + (__x3*__x3) __denominator = (1.0 - __x1)*(1.0 - __x3) return __preFactor*(__numerator/__denominator)
def solve_case_group_1(PperpSquaredMax,S123,code1,code2): """A function to return the next Pperp^2, y and winning process for case group 1/B.""" ##qqBar or qBarq so gluon emission or gluon splitting. assert assertions.all_are_numbers([PperpSquaredMax,S123]) __kQs = particleData.knownParticles.get_known_quarks() __gC = particleData.knownParticles.get_code_from_name('gluon') __expectedCodes = __kQs + [-x for x in __kQs] + [__gC] assert ((code1 in __expectedCodes) and (code2 in __expectedCodes)) assert ((code1 == __gC) or (code2 == __gC)) ##One must be a gluon. assert (not ((code1 == __gC) and (code2 == __gC))) ##One must be q/qBar. __difCrossSecIds = [1] ##Gluon emission always possible. if assertions.gluon_splitting_on(): __difCrossSecIds.append(3) ##Gluon splitting possible. __PperpSquared, __y, __difCrossSecId = solve_sudakovs(PperpSquaredMax,S123,__difCrossSecIds,code1,code2,1) __convertIdToProcessCode = {None:0,0:1,1:1,2:1,3:2,4:2,5:2} return __PperpSquared, __y, __convertIdToProcessCode[__difCrossSecId]
def solve_case_group_1(PperpSquaredMax, S123, code1, code2): """A function to return the next Pperp^2, y and winning process for case group 1/B.""" ##qqBar or qBarq so gluon emission or gluon splitting. assert assertions.all_are_numbers([PperpSquaredMax, S123]) __kQs = particleData.knownParticles.get_known_quarks() __gC = particleData.knownParticles.get_code_from_name('gluon') __expectedCodes = __kQs + [-x for x in __kQs] + [__gC] assert ((code1 in __expectedCodes) and (code2 in __expectedCodes)) assert ((code1 == __gC) or (code2 == __gC)) ##One must be a gluon. assert (not ((code1 == __gC) and (code2 == __gC))) ##One must be q/qBar. __difCrossSecIds = [1] ##Gluon emission always possible. if assertions.gluon_splitting_on(): __difCrossSecIds.append(3) ##Gluon splitting possible. __PperpSquared, __y, __difCrossSecId = solve_sudakovs( PperpSquaredMax, S123, __difCrossSecIds, code1, code2, 1) __convertIdToProcessCode = {None: 0, 0: 1, 1: 1, 2: 1, 3: 2, 4: 2, 5: 2} return __PperpSquared, __y, __convertIdToProcessCode[__difCrossSecId]
def qqBar_to_qpqBar_cS(S123, PperpSquared, y, code1, code2): ##difCrossSecId = 6 """A function to calculate the differential cross section for qqBar -> qpqBar.""" assert assertions.all_are_numbers([S123, PperpSquared, y]) __kQs = particleData.knownParticles.get_known_quarks() __expectedCodes = __kQs + [-x for x in __kQs] assert ((code1 in __expectedCodes) and (code2 in __expectedCodes)) __alphaEMNow = alphaEM.calculate(PperpSquared) __charge1 = particleData.knownParticles.get_charge_from_code(code1) __charge2 = particleData.knownParticles.get_charge_from_code(code2) __x1 = kinematics.calculate_x1(S123, math.sqrt(PperpSquared), y) __x3 = kinematics.calculate_x3(S123, math.sqrt(PperpSquared), y) __preFactor = (__alphaEMNow * abs(__charge1) * abs(__charge2)) / (2.0 * math.pi) __numerator = (__x1 * __x1) + (__x3 * __x3) __denominator = (1.0 - __x1) * (1.0 - __x3) return __preFactor * (__numerator / __denominator)
def calculate(self, QSquared): """A function for calculating the four-loop strong coupling constant at a given COM energy squared.""" ##Using approximate analytic solution. ##Source: 'Quantum Chromodynamics', Dissertori Group, Lpthe Group, P Salam, p3, equation 9.5. assert assertions.all_are_numbers([QSquared]) __QSquared = assertions.force_float_number(QSquared) __Nf, __pi = Nf(__QSquared), math.pi __beta0 = beta0(__Nf) / (4.0 * __pi) __beta1 = beta1(__Nf) / ((4.0 * __pi) * (4.0 * __pi)) __beta2 = beta2(__Nf) / ((4.0 * __pi) * (4.0 * __pi) * (4.0 * __pi)) __beta3 = beta3(__Nf) / ((4.0 * __pi) * (4.0 * __pi) * (4.0 * __pi) * (4.0 * __pi)) try: __denominator6 = (self.__fourLoopLambda * self.__fourLoopLambda) assert assertions.safe_division(__denominator6) __ln = math.log(__QSquared / __denominator6) __denominator7 = __beta0 * __beta0 * __ln assert assertions.safe_division(__denominator7) __term1 = __beta1 * math.log(__ln) / __denominator7 __denominator8 = __beta0 * __beta0 * __beta0 * __beta0 * __ln * __ln assert assertions.safe_division(__denominator8) __term2 = ((__beta1 * __beta1 * ( (math.log(__ln) * math.log(__ln)) - math.log(__ln) - 1.0)) + __beta0 * __beta2) / __denominator8 __term3P1 = (math.log(__ln) * math.log(__ln) * math.log(__ln) ) - (5.0 / 2.0) * math.log(__ln) * math.log( __ln) - 2.0 * math.log(__ln) + 0.5 __denominator9 = (__beta0 * __beta0 * __beta0 * __beta0 * __beta0 * __beta0 * __ln * __ln * __ln) assert assertions.safe_division(__denominator9) __term3 = (__beta1 * __beta1 * __beta1 * __term3P1) / __denominator9 __term4 = ((3.0 * __beta0 * __beta1 * __beta2 * math.log(__ln)) - (0.5 * __beta0 * __beta0 * __beta3)) / __denominator9 __denominator10 = __beta0 * __ln assert assertions.safe_division(__denominator10) __result = (1.0 - __term1 + __term2 - (__term3 + __term4)) / __denominator10 return __result except: print "Error in four-loop at QSquared =", __QSquared return -1.0
def solve(PperpSquaredMax, S123, code1, code2): """A function to return the next Pperp^2, y and winning process for a given dipole.""" assert assertions.all_are_numbers([PperpSquaredMax, S123]) __kQs = particleData.knownParticles.get_known_quarks() __gC = particleData.knownParticles.get_code_from_name('gluon') __expectedCodes = __kQs + [-x for x in __kQs] + [__gC] assert ((code1 in __expectedCodes) and (code2 in __expectedCodes)) if ((code1 in __kQs) and ((-code2) in __kQs)): ##qqBar. __caseGroupId = 0 elif (((-code1) in __kQs) and (code2 in __kQs)): ##qBarq. __caseGroupId = 0 elif (((code1) in __kQs) and (code2 in __kQs)): ##qq. __caseGroupId = 0 elif (((-code1) in __kQs) and (-code2 in __kQs)): ##qBarqBar. __caseGroupId = 0 elif ((code1 in __kQs) and (code2 == __gC)): ##qg. __caseGroupId = 1 elif (((-code1) in __kQs) and (code2 == __gC)): ##qBarg. __caseGroupId = 1 elif ((code1 == __gC) and (code2 in __kQs)): ##gq. __caseGroupId = 1 elif ((code1 == __gC) and ((-code2) in __kQs)): ##gqBar. __caseGroupId = 1 elif ((code1 == __gC) and (code2 == __gC)): ##gg. __caseGroupId = 2 if (__caseGroupId == 0): __newPperpSquared, __newY, __newProcessCode = solve_case_group_0( PperpSquaredMax, S123, code1, code2) elif (__caseGroupId == 1): __newPperpSquared, __newY, __newProcessCode = solve_case_group_1( PperpSquaredMax, S123, code1, code2) elif (__caseGroupId == 2): __newPperpSquared, __newY, __newProcessCode = solve_case_group_2( PperpSquaredMax, S123, code1, code2) ##Process codes: 0 = stop shower, 1 = gluon emission, 2 = gluon splitting, 3 = photon emission. ##gg has two chances for a gluon to split but nothing specifies which is which so if occurs, randomly chosen later. return __newPperpSquared, __newY, __newProcessCode
def force_float_vector(self): """A function to convert all vector integers to floats but leave doubles.""" for __i2 in range(4): assert assertions.all_are_numbers([__i2]) if (not assertions.check_float(self.__vector[__i2])): self.__vector[__i2] = assertions.force_float_number(self.__vector[__i2])
def calc_G(PperpSquared,S123): """A function to calculate the overestimation function G, the primitive of g(PperpSquared) = g1(PperpSquared)*int{g2(y) dy}, for all processes.""" assert assertions.all_are_numbers([PperpSquared,S123]) __alphaSMax = alphaS.get_shower_max() __term1 = ((-3.0)*__alphaSMax) / (4.0*math.pi) return __term1*math.log(S123/PperpSquared)*math.log(S123/PperpSquared)
def solve_sudakovs(PperpSquaredMax,S123,difCrossSecIds,code1,code2,logCrosSecs = None): """A function to generate a PperpSquared and y for an emission or splitting, using the Sudakov form factor.""" ##Codes 1,2 still needed to get the charges for EM radiation. ##Using veto algorithm in "PYTHIA 6.0 Physics and Manual". ##And p198 of "Monte Carlo simulations of hard QCD radiation" for bivariant algorithm. ##And p16 of "Initial-state showering based on colour dipoles connected to incoming parton lines" for real y limits. ##And p5 of "Fooling around with the Sudakov veto algorithm" for multiple emission form. assert assertions.all_are_numbers([PperpSquaredMax,S123]) assert (type(difCrossSecIds) == list) __kQs = particleData.knownParticles.get_known_quarks() __gC = particleData.knownParticles.get_code_from_name('gluon') __expectedCodes = __kQs + [-x for x in __kQs] + [__gC] assert ((code1 in __expectedCodes) and (code2 in __expectedCodes)) __cutOff = constants.cut_off_energy()*constants.cut_off_energy() if (PperpSquaredMax < __cutOff): return None, None, None __notChosen1, __y, __PperpSquaredi = True, 0, assertions.force_float_number(PperpSquaredMax) __PperpSquarediMinus1 = __PperpSquaredi while __notChosen1: ##i += 1 __notChosen2 = True while __notChosen2: __R1 = random.random() __PperpSquaredi = calc_inv_G((math.log(__R1) + calc_G(__PperpSquarediMinus1,S123)),S123) if (__PperpSquaredi > S123/4.0): ##The maximum physically possible! __notChosen2 = True __PperpSquarediMinus1 = __PperpSquaredi continue #Re-run the while loop if (__PperpSquaredi <= __PperpSquarediMinus1): ##Don't update __PperpSquaredi if fails as would start allowing higher values! __notChosen2 = False ##Move on if (__PperpSquaredi < __cutOff): return None, None, None __R2 = random.random() __ymin, __ymax = -0.5*math.log(S123/__PperpSquaredi), 0.5*math.log(S123/__PperpSquaredi) __yi = calc_inv_G2(__R2*(calc_G2(__ymax) - calc_G2(__ymin)) + calc_G2(__ymin)) if not check_rapidity_allowed(S123,__PperpSquaredi,__yi): ##Veto incorrect y-range. On the boundary is allowed. __PperpSquarediMinus1 = __PperpSquaredi continue ##Don't accept, notChosen1 == True, while will run again. __R3 = random.random() __numberCSIds = len(difCrossSecIds) __ratio = sum_cSs(difCrossSecIds,S123,__PperpSquaredi,__yi,code1,code2) / __numberCSIds*calc_g(__PperpSquaredi,__yi) if (__ratio <= __R3): __PperpSquarediMinus1 = __PperpSquaredi continue ##Don't accept, notChosen1 == True, while will run again. else: __notChosen1 = False ##Accept. ##Prepare weights for choosing Id of process occuring: __idWeights = {} ##Empty dictionary initiated. for __difCrossSecId in difCrossSecIds: ##Uses the Ids given so will weight for the chosen set. __idWeights[__difCrossSecId] = sum_cSs([__difCrossSecId],S123,__PperpSquaredi,__yi,code1,code2) __total = sum(__idWeights.itervalues()) __idWeights.update((x, y/__total) for x, y in __idWeights.items()) ##Normalise them assert precision.check_numbers_equal(sum(__idWeights.itervalues()),1.0) ##i.e they should now be normalised to 1. ##Choose which process: __R4 = random.random() ##Doesn't include 1 -> using < not <= for checks is fair. __sumSoFar = 0.0 __chosenId = None __chosen = False if (logCrosSecs == 1): crossSecsGluSplit.store(qg_to_qQQBar_cS(S123,__PperpSquaredi,__yi)) crossSecsGluProd.store(qg_to_qgg_cS(S123,__PperpSquaredi,__yi)) for __difCrossSecId in difCrossSecIds: if (not __chosen): __sumSoFar += __idWeights[__difCrossSecId] if (__R4 < __sumSoFar): __chosenId = __difCrossSecId __chosen = True assert (not (__chosenId == None)) ##Should have chosen by now! return __PperpSquaredi, __yi, __chosenId
def S123_to_E(S123): """A function to return E from S123.""" assert assertions.all_are_numbers([S123]) return math.sqrt(S123) / 2.0
def is_anti_particle(lookUpCode): """A function to check if a particle is an anti-particle given its PDG code.""" assert assertions.all_are_numbers([lookUpCode]) return (lookUpCode < 0.0)
def calc_G2(y): """A function to calculate the overestimation function G2, the primitive of g2, for all processes.""" assert assertions.all_are_numbers([y]) return y
def calc_inv_G2(valueIn): """A function to calculate the inverse of G2 for for all processes.""" assert assertions.all_are_numbers([valueIn]) return valueIn
def calc_g(PperpSquared,y): ##Calculate the function g(Pperpsquared,y) = g1(Pperpsquared)*g2(y). """A function to calculate the overestimation function g for all processes.""" assert assertions.all_are_numbers([PperpSquared,y]) __alphaSMax = alphaS.get_shower_max() return (3.0*__alphaSMax) / (2.0*math.pi*PperpSquared)
def calculate_E1(S123, Pperp, y): """A function to calculate a value of E1 following a dipole splitting.""" assert assertions.all_are_numbers([S123, Pperp, y]) __E1 = 0.5 * (math.sqrt(S123) - (Pperp * math.exp(y))) return __E1
def is_boson(self,lookUpCode): """A function to check if a particle is a boson given its PDG code.""" assert assertions.all_are_numbers([lookUpCode]) assert self.has_key(abs(lookUpCode)) return (self.__bosons.count(abs(lookUpCode)) > 0.0)