def run(self): """A function to run a shower for the given LHEF file.""" ##For e+e- -> qqBar (massless). __reader = LHEFHandlers.LHEFReader(self.__toLoad) self.__numEvents = __reader.get_number_events() __writer = LHEFHandlers.LHEFShowerWriter(__reader,self.__numEvents) __alertEvery = self.__numEvents/10 if __alertEvery > 1000: ##Slow enough to want to see something is happening! __alertEvery = 1000 elif (__alertEvery == 0): ##i.e < 10 events. __alertEvery = 1 for __eventIndex in range(self.__numEvents): if (__eventIndex%__alertEvery == 0): if (__eventIndex == 0): print "Begin showering...\n" else: print "Showering event", __eventIndex __MEParticle1 = __reader.get_event_particle(__eventIndex,0) __MEParticle2 = __reader.get_event_particle(__eventIndex,1) __EIn = __MEParticle1[0] + __MEParticle2[0] __S123In = kinematics.Sijk([__MEParticle1.get_four_momentum(), __MEParticle2.get_four_momentum()]) __particlesIn = [__MEParticle1,__MEParticle2] __showerParticle1 = __reader.get_event_particle(__eventIndex,2) __showerParticle2 = __reader.get_event_particle(__eventIndex,3) __showeri = showers.qqBarShower(__showerParticle1,__showerParticle2,self.__activeQCodes) __showeri.run_shower() __particlesOut = __showeri.export_results() __EOut = 0.0 __fourVectorsOut = [] for __p in __particlesOut: __ePV = __p.get_four_momentum() __EOut += __ePV[0] __fourVectorsOut.append(__ePV) assert precision.check_numbers_equal(kinematics.Sijk(__fourVectorsOut),__S123In) assert precision.check_numbers_equal(__EIn,__EOut) __trials, __muf2, __mur2 = __reader.get_event_trials(__eventIndex), __reader.get_event_muf2(__eventIndex), __reader.get_event_mur2(__eventIndex) __processID, __weight = __reader.get_event_process_ID(__eventIndex), __reader.get_event_weight(__eventIndex) __scale, __alphaEM = __reader.get_event_scale(__eventIndex), __reader.get_event_alphaEM(__eventIndex) __alphaS = __reader.get_event_alphaS(__eventIndex) __writer.add_event(__trials,__muf2,__mur2,__processID,__weight,__scale,__alphaEM,__alphaS,__particlesIn,__particlesOut) __writer.save() __numGluonsSplit = counters.gluonSplitCounter.counted() print "\nThere were", counters.gluonProdCounter.counted(), "gluons produced!" print "\nThere were", __numGluonsSplit, "gluons split!" print "\nThere were", counters.photonProdCounter.counted(), "photons produced!" print "\nThere were", counters.kPerpProdWarningCounter.counted(), "warnings for E1 or E3 < E2!\n" print "\n---------------------" print "Quark content report:" print "---------------------" __sumPercent = 0.0 for __aQCode in [1,2,3,4,5,6]: __qName = particleData.knownParticles.get_name_from_code(__aQCode) if precision.check_numbers_equal(__numGluonsSplit,0.0): __qPercent = 0.0 else: __qPercent = chains.producedQuarkCodes.output().count(__aQCode)*100.0/__numGluonsSplit __sumPercent += __qPercent print str(__qPercent) + "% are " + __qName + "s." print "This adds up to " + str(__sumPercent) + "%." assertions.pause(__name__)
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_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 scaled_quark_directions(S123,theta): """A function to return two quark directional vectors scaled to match a given S123 value.""" __cE = constants.cut_off_energy() assert ((type(S123) == float) and (S123 > __cE*__cE)) assert((type(theta) == float) and (0.0 <= theta) and (theta <= math.pi)) __E = math.sqrt(S123)/2.0 __dV1, __dV2 = produce_quark_directions(S123,theta) __magnitude = __dV1.calculate_cartesian_magnitude() __scale = __E/__magnitude __dV1 *= __scale __dV2 *= __scale __dV1[0], __dV2[0] = __E, __E ##Check massless: assert (precision.check_numbers_equal(__dV1*__dV1,0.0) and precision.check_numbers_equal(__dV2*__dV2,0.0)) return __dV1, __dV2
def get_quark_weights(S123, posQuarkCodes, cosTheta=None): """A function to calculate the quark weights to beused by the ME generator.""" __cE = constants.cut_off_energy() assert ((type(S123) == float) and (S123 > __cE * __cE)) assert (type(posQuarkCodes) == list) assert (((type(cosTheta) == float) and (-1.0 <= cosTheta) and (cosTheta <= 1.0)) or (cosTheta == None)) ##Using dictionary not list so you don't have to assume an order of the quark codes. __hardCodedQWeights = { 1: 16.05764282, 2: 11.94029851, 3: 16.05764282, 4: 24.32321153, 5: 31.62120432 } __qWeights = {} ##Empty dictionary initiated. for __qCode in posQuarkCodes: ##Uses the quark codes given to weight for the chosen set. if (cosTheta == None): __qWeights[__qCode] = __hardCodedQWeights[ __qCode] ##Only take the hard coded ones required so normalisation works. else: __qWeights[__qCode] = calc_f_for_cos_theta(S123, __qCode, cosTheta) __total = sum(__qWeights.itervalues()) __qWeights.update( (x, y / __total) for x, y in __qWeights.items()) ##Normalise them assert precision.check_numbers_equal( sum(__qWeights.itervalues()), 1.0) ##i.e they should now be normalised to 1. return __qWeights
def scaled_quark_directions(S123, theta): """A function to return two quark directional vectors scaled to match a given S123 value.""" __cE = constants.cut_off_energy() assert ((type(S123) == float) and (S123 > __cE * __cE)) assert ((type(theta) == float) and (0.0 <= theta) and (theta <= math.pi)) __E = math.sqrt(S123) / 2.0 __dV1, __dV2 = produce_quark_directions(S123, theta) __magnitude = __dV1.calculate_cartesian_magnitude() __scale = __E / __magnitude __dV1 *= __scale __dV2 *= __scale __dV1[0], __dV2[0] = __E, __E ##Check massless: assert (precision.check_numbers_equal(__dV1 * __dV1, 0.0) and precision.check_numbers_equal(__dV2 * __dV2, 0.0)) return __dV1, __dV2
def __eq__(self, other): """A function to check whether two four-vectors are equal up to the code precision.""" assert check_is_fourVector(other) assert (self.__nonzero__() and other.__nonzero__()) for __i11 in range(4): if not precision.check_numbers_equal(self[__i11], other[__i11]): return False return True
def zero_or(value): """A function to see if a value can be set to 0.0 when writing an LHEF file.""" ##Main use is to remove -ve energies that are actually zero with the code precision. assert (type(value) == float) if precision.check_numbers_equal(value,0.0): return 0.0 else: return value
def __eq__(self,other): """A function to check whether two four-vectors are equal up to the code precision.""" assert check_is_fourVector(other) assert (self.__nonzero__() and other.__nonzero__()) for __i11 in range(4): if not precision.check_numbers_equal(self[__i11],other[__i11]): return False return True
def zero_or(value): """A function to see if a value can be set to 0.0 when writing an LHEF file.""" ##Main use is to remove -ve energies that are actually zero with the code precision. assert (type(value) == float) if precision.check_numbers_equal(value, 0.0): return 0.0 else: return value
def add_event(self,trials,muf2,mur2,processID,weight,scale,alphaEM,alphaS,particlesIn,particlesOut): """A function to convert a produced particles data to LHEF and add to the writer.""" assert ((type(trials) == int) or (isinstance(trials, basestring))) assert ((type(muf2) == int) or (type(muf2) == float) or (isinstance(muf2, basestring))) assert ((type(mur2) == int) or (type(mur2) == float) or (isinstance(mur2, basestring))) assert ((type(processID) == int) or (isinstance(processID, basestring))) assert ((type(weight) == float) or (type(weight) == int) or (isinstance(weight, basestring))) assert ((type(scale) == float) or (isinstance(scale, basestring))) assert ((type(alphaEM) == float) or (isinstance(alphaEM, basestring))) assert ((type(alphaS) == float) or (isinstance(alphaS, basestring))) self.__numProdLogger.store(len(particlesOut) - 2) ##Log number of produced partons per event. if (self.__topWritten == False): self.write_top() self.__haveEvents = True ##Only called once here. __listOfParticles = particlesIn + particlesOut #Currently not sorting by order of production. #__listOfIDs = [x.get_unique_ID() for x in __listOfParticles] #__sortedListOfParticles = [x for (y,x) in sorted(zip(__listOfIDs,__listOfParticles), key=lambda pair: pair[0])] __sortedListOfParticles = __listOfParticles ##Replacement line to keep the chain ordering. for particle in __sortedListOfParticles: assert particles.check_is_particle(particle) assert particle.__nonzero__() __numberParticles = len(particlesIn) + len(particlesOut) __line1 = "\n<event>" # trials='" + str(trials) + "' muf2='" + str(muf2) + "' mur2='" + str(mur2) + "'>" __line2 = ("\n\t\t" + str(__numberParticles) + "\t" + str(processID) + "\t" + str(weight) + "\t" + str(scale)) __line2 += ("\t" + str(alphaEM) + "\t" + str(alphaS)) __inLines, __outLines = "", "" __endLine = "\n</event>" __zO = zero_or __pHS = "{:." + str(constants.LHEF_DS_number_decimal_places()) + "e}" for i, p in enumerate(__sortedListOfParticles): ##Iterate through both at once, but with particlesIn first! if not precision.check_numbers_equal(p.get_four_momentum()*p.get_four_momentum(),0.0): fFV = kinematics.fix_not_massless(p.get_four_momentum()) ##Adjust to make sure they are exactly massless for Pythia. else: fFV = p.get_four_momentum() if i <= 1: ##Carry on as normal for first two (initial-state) particles. __mum1, __mum2 = p.get_mother(0), p.get_mother(1) else: ##Set all mother values to 1 and 2 as required by Pythia 8.2. __mum1, __mum2 = 1, 2 __newLine = ("\n\t\t\t" + str(p.get_code()) + "\t" + str(p.get_status_code()) + "\t" + str(__mum1)) __newLine += ("\t" + str(__mum2) + "\t" + str(p.get_colour(0)) + "\t\t" + str(p.get_colour(1))) __newLine += ("\t\t" + __pHS.format(__zO(fFV[1])) + "\t" + __pHS.format(__zO(fFV[2])) + "\t") __newLine += (__pHS.format(__zO(fFV[3])) + "\t" + __pHS.format(__zO(fFV[0])) + "\t") __newLine += (__pHS.format(__zO(p.get_mass())) + "\t" + str(__zO(p.get_width())) + "\t\t" + str(p.get_spin())) __inLines += __newLine __toSave = __line1 + __line2 + __inLines + __outLines + __endLine __file = open(self.__saveName,'a') ##'a' means append to. __file.write(__toSave) __file.close() self.__numberEventsSaved += 1
def get_quark_weights(S123,posQuarkCodes,cosTheta = None): """A function to calculate the quark weights to beused by the ME generator.""" __cE = constants.cut_off_energy() assert ((type(S123) == float) and (S123 > __cE*__cE)) assert (type(posQuarkCodes) == list) assert (((type(cosTheta) == float) and (-1.0 <= cosTheta) and (cosTheta <= 1.0)) or (cosTheta == None)) ##Using dictionary not list so you don't have to assume an order of the quark codes. __hardCodedQWeights = {1:16.05764282,2:11.94029851,3:16.05764282,4:24.32321153,5:31.62120432} __qWeights = {} ##Empty dictionary initiated. for __qCode in posQuarkCodes: ##Uses the quark codes given to weight for the chosen set. if (cosTheta == None): __qWeights[__qCode] = __hardCodedQWeights[__qCode] ##Only take the hard coded ones required so normalisation works. else: __qWeights[__qCode] = calc_f_for_cos_theta(S123,__qCode,cosTheta) __total = sum(__qWeights.itervalues()) __qWeights.update((x, y/__total) for x, y in __qWeights.items()) ##Normalise them assert precision.check_numbers_equal(sum(__qWeights.itervalues()),1.0) ##i.e they should now be normalised to 1. return __qWeights
def add_event(self,trials,muf2,mur2,processID,weight,scale,alphaEM,alphaS,particlesIn,particlesOut): """A function to convert a produced particles data to LHEF and add to the writer.""" assert ((type(trials) == int) or (isinstance(trials, basestring))) assert ((type(muf2) == int) or (type(muf2) == float) or (isinstance(muf2, basestring))) assert ((type(mur2) == int) or (type(mur2) == float) or (isinstance(mur2, basestring))) assert ((type(processID) == int) or (isinstance(processID, basestring))) assert ((type(weight) == float) or (type(weight) == int) or (isinstance(weight, basestring))) assert ((type(scale) == float) or (isinstance(scale, basestring))) assert ((type(alphaEM) == float) or (isinstance(alphaEM, basestring))) assert ((type(alphaS) == float) or (isinstance(alphaS, basestring))) if (self.__topWritten == False): self.write_top() self.__haveEvents = True ##Only called once here. __listOfParticles = particlesIn + particlesOut __listOfIDs = [x.get_unique_ID() for x in __listOfParticles] __sortedListOfParticles = [x for (y,x) in sorted(zip(__listOfIDs,__listOfParticles), key=lambda pair: pair[0])] for particle in __sortedListOfParticles: assert particles.check_is_particle(particle) assert particle.__nonzero__() __numberParticles = len(particlesIn) + len(particlesOut) __line1 = "\n<event>" #trials='" + str(trials) + "' muf2='" + str(muf2) + "' mur2='" + str(mur2) + "'>" __line2 = ("\n\t\t" + str(__numberParticles) + "\t" + str(processID) + "\t" + str(weight) + "\t" + str(scale)) __line2 += ("\t" + str(alphaEM) + "\t" + str(alphaS)) __inLines, __outLines = "", "" __endLine = "\n</event>" __zO = zero_or __pHS = "{:." + str(constants.LHEF_ME_number_decimal_places()) + "e}" for p in __sortedListOfParticles: ##Iterate through both at once, but with particlesIn first! if not precision.check_numbers_equal(p.get_four_momentum()*p.get_four_momentum(),0.0): ##Shouldn't ever need to call it. fFV = kinematics.fix_not_massless(p.get_four_momentum()) ##Adjust to make sure they are exactly massless for Pythia. else: fFV = p.get_four_momentum() __newLine = ("\n\t\t\t" + str(p.get_code()) + "\t" + str(p.get_status_code()) + "\t" + str(p.get_mother(0))) __newLine += ("\t" + str(p.get_mother(1)) + "\t" + str(p.get_colour(0)) + "\t\t" + str(p.get_colour(1))) __newLine += ("\t\t" + __pHS.format(__zO(fFV[1])) + "\t" + __pHS.format(__zO(fFV[2])) + "\t") __newLine += (__pHS.format(__zO(fFV[3])) + "\t" + __pHS.format(__zO(fFV[0])) + "\t") __newLine += (__pHS.format(__zO(p.get_mass())) + "\t" + str(__zO(p.get_width())) + "\t\t" + str(p.get_spin())) __inLines += __newLine __toSave = __line1 + __line2 + __inLines + __outLines + __endLine __file = open(self.__saveName,'a') ##'a' means append to. __file.write(__toSave) __file.close() self.__numberEventsSaved += 1
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
pyplot.xlim(0.001, 10**6) assertions.show_graph() print "\nFinished testing Nf function." assertions.pause(__name__) ##Test beta0 function:## print "\n--------------------------------------------------\n" print "Testing beta0 function:" ##Using N=3 version from four-loop paper which is the same as Krauss'. for tNf1 in range(0, 7): if (tNf1 == 4): assertions.pause(__name__) tExpectedBeta0 = 11.0 - (2.0 / 3.0) * tNf1 print "\nbeta0(" + str(tNf1) + ") returns:", beta0(tNf1) print "The expected value is:", tExpectedBeta0 if precision.check_numbers_equal(beta0(tNf1), tExpectedBeta0): print "These are equal within the code precision: Test successful!" else: print "Not equal: Test failed!" print "\nFinished testing beta0 function." assertions.pause(__name__) ##Test beta1 function:## print "\n--------------------------------------------------\n" print "Testing beta1 function:" ##Using N=3 version from four-loop paper which is the same as Krauss'. for tNf2 in range(0, 7): if (tNf2 == 4): assertions.pause(__name__) tExpectedBeta1 = 102.0 - (38.0 / 3.0) * tNf2 print "\nbeta1(" + str(tNf2) + ") returns:", beta1(tNf2)
def add_event(self, trials, muf2, mur2, processID, weight, scale, alphaEM, alphaS, particlesIn, particlesOut): """A function to convert a produced particles data to LHEF and add to the writer.""" assert ((type(trials) == int) or (isinstance(trials, basestring))) assert ((type(muf2) == int) or (type(muf2) == float) or (isinstance(muf2, basestring))) assert ((type(mur2) == int) or (type(mur2) == float) or (isinstance(mur2, basestring))) assert ((type(processID) == int) or (isinstance(processID, basestring))) assert ((type(weight) == float) or (type(weight) == int) or (isinstance(weight, basestring))) assert ((type(scale) == float) or (isinstance(scale, basestring))) assert ((type(alphaEM) == float) or (isinstance(alphaEM, basestring))) assert ((type(alphaS) == float) or (isinstance(alphaS, basestring))) if (self.__topWritten == False): self.write_top() self.__haveEvents = True ##Only called once here. __listOfParticles = particlesIn + particlesOut __listOfIDs = [x.get_unique_ID() for x in __listOfParticles] __sortedListOfParticles = [ x for (y, x) in sorted(zip(__listOfIDs, __listOfParticles), key=lambda pair: pair[0]) ] for particle in __sortedListOfParticles: assert particles.check_is_particle(particle) assert particle.__nonzero__() __numberParticles = len(particlesIn) + len(particlesOut) __line1 = "\n<event>" #trials='" + str(trials) + "' muf2='" + str(muf2) + "' mur2='" + str(mur2) + "'>" __line2 = ("\n\t\t" + str(__numberParticles) + "\t" + str(processID) + "\t" + str(weight) + "\t" + str(scale)) __line2 += ("\t" + str(alphaEM) + "\t" + str(alphaS)) __inLines, __outLines = "", "" __endLine = "\n</event>" __zO = zero_or __pHS = "{:." + str(constants.LHEF_ME_number_decimal_places()) + "e}" for p in __sortedListOfParticles: ##Iterate through both at once, but with particlesIn first! if not precision.check_numbers_equal( p.get_four_momentum() * p.get_four_momentum(), 0.0): ##Shouldn't ever need to call it. fFV = kinematics.fix_not_massless(p.get_four_momentum( )) ##Adjust to make sure they are exactly massless for Pythia. else: fFV = p.get_four_momentum() __newLine = ("\n\t\t\t" + str(p.get_code()) + "\t" + str(p.get_status_code()) + "\t" + str(p.get_mother(0))) __newLine += ("\t" + str(p.get_mother(1)) + "\t" + str(p.get_colour(0)) + "\t\t" + str(p.get_colour(1))) __newLine += ("\t\t" + __pHS.format(__zO(fFV[1])) + "\t" + __pHS.format(__zO(fFV[2])) + "\t") __newLine += (__pHS.format(__zO(fFV[3])) + "\t" + __pHS.format(__zO(fFV[0])) + "\t") __newLine += (__pHS.format(__zO(p.get_mass())) + "\t" + str(__zO(p.get_width())) + "\t\t" + str(p.get_spin())) __inLines += __newLine __toSave = __line1 + __line2 + __inLines + __outLines + __endLine __file = open(self.__saveName, 'a') ##'a' means append to. __file.write(__toSave) __file.close() self.__numberEventsSaved += 1
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 run(self): """A function to run a shower for the given LHEF file.""" ##For e+e- -> qqBar (massless). __reader = LHEFHandlers.LHEFReader(self.__toLoad) self.__numEvents = __reader.get_number_events() __writer = LHEFHandlers.LHEFShowerWriter(__reader, self.__numEvents) __alertEvery = self.__numEvents / 10 if __alertEvery > 1000: ##Slow enough to want to see something is happening! __alertEvery = 1000 elif (__alertEvery == 0): ##i.e < 10 events. __alertEvery = 1 for __eventIndex in range(self.__numEvents): if (__eventIndex % __alertEvery == 0): if (__eventIndex == 0): print "Begin showering...\n" else: print "Showering event", __eventIndex __MEParticle1 = __reader.get_event_particle(__eventIndex, 0) __MEParticle2 = __reader.get_event_particle(__eventIndex, 1) __EIn = __MEParticle1[0] + __MEParticle2[0] __S123In = kinematics.Sijk([ __MEParticle1.get_four_momentum(), __MEParticle2.get_four_momentum() ]) __particlesIn = [__MEParticle1, __MEParticle2] __showerParticle1 = __reader.get_event_particle(__eventIndex, 2) __showerParticle2 = __reader.get_event_particle(__eventIndex, 3) __showeri = showers.qqBarShower(__showerParticle1, __showerParticle2, self.__activeQCodes) __showeri.run_shower() __particlesOut = __showeri.export_results() __EOut = 0.0 __fourVectorsOut = [] for __p in __particlesOut: __ePV = __p.get_four_momentum() __EOut += __ePV[0] __fourVectorsOut.append(__ePV) assert precision.check_numbers_equal( kinematics.Sijk(__fourVectorsOut), __S123In) assert precision.check_numbers_equal(__EIn, __EOut) __trials, __muf2, __mur2 = __reader.get_event_trials( __eventIndex), __reader.get_event_muf2( __eventIndex), __reader.get_event_mur2(__eventIndex) __processID, __weight = __reader.get_event_process_ID( __eventIndex), __reader.get_event_weight(__eventIndex) __scale, __alphaEM = __reader.get_event_scale( __eventIndex), __reader.get_event_alphaEM(__eventIndex) __alphaS = __reader.get_event_alphaS(__eventIndex) __writer.add_event(__trials, __muf2, __mur2, __processID, __weight, __scale, __alphaEM, __alphaS, __particlesIn, __particlesOut) __writer.save() __numGluonsSplit = counters.gluonSplitCounter.counted() print "\nThere were", counters.gluonProdCounter.counted( ), "gluons produced!" print "\nThere were", __numGluonsSplit, "gluons split!" print "\nThere were", counters.photonProdCounter.counted( ), "photons produced!" print "\nThere were", counters.kPerpProdWarningCounter.counted( ), "warnings for E1 or E3 < E2!\n" print "\n---------------------" print "Quark content report:" print "---------------------" __sumPercent = 0.0 for __aQCode in [1, 2, 3, 4, 5, 6]: __qName = particleData.knownParticles.get_name_from_code(__aQCode) if precision.check_numbers_equal(__numGluonsSplit, 0.0): __qPercent = 0.0 else: __qPercent = chains.producedQuarkCodes.output().count( __aQCode) * 100.0 / __numGluonsSplit __sumPercent += __qPercent print str(__qPercent) + "% are " + __qName + "s." print "This adds up to " + str(__sumPercent) + "%." assertions.pause(__name__)
pyplot.xlim(0.001,10**6) assertions.show_graph() print "\nFinished testing Nf function." assertions.pause(__name__) ##Test beta0 function:## print "\n--------------------------------------------------\n" print "Testing beta0 function:" ##Using N=3 version from four-loop paper which is the same as Krauss'. for tNf1 in range(0,7): if (tNf1 == 4): assertions.pause(__name__) tExpectedBeta0 = 11.0 - (2.0/3.0)*tNf1 print "\nbeta0("+str(tNf1)+") returns:" , beta0(tNf1) print "The expected value is:" , tExpectedBeta0 if precision.check_numbers_equal(beta0(tNf1),tExpectedBeta0): print "These are equal within the code precision: Test successful!" else: print "Not equal: Test failed!" print "\nFinished testing beta0 function." assertions.pause(__name__) ##Test beta1 function:## print "\n--------------------------------------------------\n" print "Testing beta1 function:" ##Using N=3 version from four-loop paper which is the same as Krauss'. for tNf2 in range(0,7): if (tNf2 == 4): assertions.pause(__name__) tExpectedBeta1 = 102.0 - (38.0/3.0)*tNf2 print "\nbeta1("+str(tNf2)+") returns:" , beta1(tNf2)
def add_event(self, trials, muf2, mur2, processID, weight, scale, alphaEM, alphaS, particlesIn, particlesOut): """A function to convert a produced particles data to LHEF and add to the writer.""" assert ((type(trials) == int) or (isinstance(trials, basestring))) assert ((type(muf2) == int) or (type(muf2) == float) or (isinstance(muf2, basestring))) assert ((type(mur2) == int) or (type(mur2) == float) or (isinstance(mur2, basestring))) assert ((type(processID) == int) or (isinstance(processID, basestring))) assert ((type(weight) == float) or (type(weight) == int) or (isinstance(weight, basestring))) assert ((type(scale) == float) or (isinstance(scale, basestring))) assert ((type(alphaEM) == float) or (isinstance(alphaEM, basestring))) assert ((type(alphaS) == float) or (isinstance(alphaS, basestring))) self.__numProdLogger.store( len(particlesOut) - 2) ##Log number of produced partons per event. if (self.__topWritten == False): self.write_top() self.__haveEvents = True ##Only called once here. __listOfParticles = particlesIn + particlesOut #Currently not sorting by order of production. #__listOfIDs = [x.get_unique_ID() for x in __listOfParticles] #__sortedListOfParticles = [x for (y,x) in sorted(zip(__listOfIDs,__listOfParticles), key=lambda pair: pair[0])] __sortedListOfParticles = __listOfParticles ##Replacement line to keep the chain ordering. for particle in __sortedListOfParticles: assert particles.check_is_particle(particle) assert particle.__nonzero__() __numberParticles = len(particlesIn) + len(particlesOut) __line1 = "\n<event>" # trials='" + str(trials) + "' muf2='" + str(muf2) + "' mur2='" + str(mur2) + "'>" __line2 = ("\n\t\t" + str(__numberParticles) + "\t" + str(processID) + "\t" + str(weight) + "\t" + str(scale)) __line2 += ("\t" + str(alphaEM) + "\t" + str(alphaS)) __inLines, __outLines = "", "" __endLine = "\n</event>" __zO = zero_or __pHS = "{:." + str(constants.LHEF_DS_number_decimal_places()) + "e}" for i, p in enumerate( __sortedListOfParticles ): ##Iterate through both at once, but with particlesIn first! if not precision.check_numbers_equal( p.get_four_momentum() * p.get_four_momentum(), 0.0): fFV = kinematics.fix_not_massless(p.get_four_momentum( )) ##Adjust to make sure they are exactly massless for Pythia. else: fFV = p.get_four_momentum() if i <= 1: ##Carry on as normal for first two (initial-state) particles. __mum1, __mum2 = p.get_mother(0), p.get_mother(1) else: ##Set all mother values to 1 and 2 as required by Pythia 8.2. __mum1, __mum2 = 1, 2 __newLine = ("\n\t\t\t" + str(p.get_code()) + "\t" + str(p.get_status_code()) + "\t" + str(__mum1)) __newLine += ("\t" + str(__mum2) + "\t" + str(p.get_colour(0)) + "\t\t" + str(p.get_colour(1))) __newLine += ("\t\t" + __pHS.format(__zO(fFV[1])) + "\t" + __pHS.format(__zO(fFV[2])) + "\t") __newLine += (__pHS.format(__zO(fFV[3])) + "\t" + __pHS.format(__zO(fFV[0])) + "\t") __newLine += (__pHS.format(__zO(p.get_mass())) + "\t" + str(__zO(p.get_width())) + "\t\t" + str(p.get_spin())) __inLines += __newLine __toSave = __line1 + __line2 + __inLines + __outLines + __endLine __file = open(self.__saveName, 'a') ##'a' means append to. __file.write(__toSave) __file.close() self.__numberEventsSaved += 1
for fC in tFermionCodes: for lI in tLowerIndices: print "Calling with lower index", lI, "and upper index", tG_N( fC), "returns:" print neutral_weak_couplings(lI, fC) results.append(neutral_weak_couplings(lI, fC)) assertions.pause(__name__) tExpected = [ -0.34582666666, -0.5, 0.19165333333, 0.5, -0.34582666666, -0.5, 0.19165333333, 0.5, -0.34582666666, -0.5, 0.19165333333, 0.5 ] tExpected += [ -0.03748, -0.5, 0.5, 0.5, -0.03748, -0.5, 0.5, 0.5, -0.03748, -0.5, 0.5, 0.5 ] tSuccessful = True for i, v in enumerate(results): if not precision.check_numbers_equal(results[i], tExpected[i]): tSuccessful = False if tSuccessful: print "\nTest successful!" else: print "\nTest failed!" print "\nFinished testing neutral_weak_couplings." assertions.pause(__name__) ##Done testing:## print "\n---------------------------------------------\n" print "///////////////////////////////////" print "Finished checking constants module!" print "///////////////////////////////////"
def check_lightlike(pV): """A function to check whether a momentum vector is light-like (i.e P.P = M^2 = 0).""" assert fourVectors.check_is_fourVector(pV) assert pV.__nonzero__() __MinkowskiSP = pV * pV return precision.check_numbers_equal(__MinkowskiSP,0.0)
##Test neutral_weak_couplings:## print "\n--------------------------------------------------\n" print "Testing neutral_weak_couplings:\n" tFermionCodes = particleData.knownParticles.get_known_fermions() tG_N = particleData.knownParticles.get_name_from_code results = [] for fC in tFermionCodes: for lI in tLowerIndices: print "Calling with lower index", lI ,"and upper index", tG_N(fC), "returns:" print neutral_weak_couplings(lI,fC) results.append(neutral_weak_couplings(lI,fC)) assertions.pause(__name__) tExpected = [-0.34582666666,-0.5,0.19165333333,0.5,-0.34582666666,-0.5,0.19165333333,0.5,-0.34582666666,-0.5,0.19165333333,0.5] tExpected += [-0.03748,-0.5,0.5,0.5,-0.03748,-0.5,0.5,0.5,-0.03748,-0.5,0.5,0.5] tSuccessful = True for i, v in enumerate(results): if not precision.check_numbers_equal(results[i],tExpected[i]): tSuccessful = False if tSuccessful: print "\nTest successful!" else: print "\nTest failed!" print "\nFinished testing neutral_weak_couplings." assertions.pause(__name__) ##Done testing:## print "\n---------------------------------------------\n" print "///////////////////////////////////" print "Finished checking constants module!" print "///////////////////////////////////"
math.sqrt(1.2 * 1.2 + 4.5 * 4.5 + 3.2 * 3.2), 1.2, 4.5, 3.2) tEdiff = 5.4 tEDiffVecOut = fix_energy_difference(tEdiff, tEDiffVector) print "Generating test variables completed" assertions.pause(__name__) ##Test Sijk function:## print "\n--------------------------------------------------\n" print "Testing Sijk function:\n" for tFourVector in tFourVectors: print "Momentum-" + tFourVector + " is:\n", tFourVectors[tFourVector] assertions.pause(__name__) print "\nFor a & b, Sijk returns:", Sijk( [tFourVectors['a'], tFourVectors['b']]) print "Compared to the expected value of:", tExpectedSab if precision.check_numbers_equal( Sijk([tFourVectors['a'], tFourVectors['b']]), tExpectedSab): print "\nFirst test, equal within the code precision: Test successful!" else: print "\nFirst test, not equal within the code precision: Test failed!" print "Possibly just a precision error?\n" print "{0:.20f}".format(Sijk([tFourVectors['a'], tFourVectors['b']])) print "{0:.20f}".format(tExpectedSab) print "\nFor a & b, Sijk returns:", Sijk( [tFourVectors['c'], tFourVectors['d']]) print "Compared to the expected value of:", tExpectedScd if precision.check_numbers_equal( Sijk([tFourVectors['c'], tFourVectors['d']]), tExpectedScd): print "\nSecond test, equal within the code precision: Test successful!" else: print "\nSecond test, not equal within the code precision: Test failed!" print "Possibly just a precision error?\n"
if check_timelike(tLightlike): tSuccessful = False if tSuccessful: print "\nTest successful!" else: print "\nTest failed!" print "\nFinished testing check_timelike and check_lightlike." assertions.pause(__name__) ##Test calculate_m_from_p_vector, check_v_not_faster_than_c and p_vector_to_v:## print "\n--------------------------------------------------\n" print "Testing calculate_m_from_p_vector, check_v_not_faster_than_c and p_vector_to_v:\n" tSuccessful = True print "Calling calculate_m_from_p_vector on tLightlike:", calculate_m_from_p_vector( tLightlike) if not precision.check_numbers_equal(calculate_m_from_p_vector(tLightlike), 0.0): tSuccessful = False print "Calling check_v_not_faster_than_c on", tNotTooFast1, ":", check_v_not_faster_than_c( tNotTooFast1) if not check_v_not_faster_than_c(tNotTooFast1): tSuccessful = False print "Calling check_v_not_faster_than_c on", tNotTooFast2, ":", check_v_not_faster_than_c( tNotTooFast2) if not check_v_not_faster_than_c(tNotTooFast2): tSuccessful = False print "Calling check_v_not_faster_than_c on", tTooFast1, ":", check_v_not_faster_than_c( tTooFast1) if check_v_not_faster_than_c(tTooFast1): tSuccessful = False print "Calling check_v_not_faster_than_c on", tTooFast2, ":", check_v_not_faster_than_c( tTooFast2)
print "Calling check_timelike on tLightlike:" , check_timelike(tLightlike) if check_timelike(tLightlike): tSuccessful = False if tSuccessful: print "\nTest successful!" else: print "\nTest failed!" print "\nFinished testing check_timelike and check_lightlike." assertions.pause(__name__) ##Test calculate_m_from_p_vector, check_v_not_faster_than_c and p_vector_to_v:## print "\n--------------------------------------------------\n" print "Testing calculate_m_from_p_vector, check_v_not_faster_than_c and p_vector_to_v:\n" tSuccessful = True print "Calling calculate_m_from_p_vector on tLightlike:" , calculate_m_from_p_vector(tLightlike) if not precision.check_numbers_equal(calculate_m_from_p_vector(tLightlike),0.0): tSuccessful = False print "Calling check_v_not_faster_than_c on" , tNotTooFast1 , ":" , check_v_not_faster_than_c(tNotTooFast1) if not check_v_not_faster_than_c(tNotTooFast1): tSuccessful = False print "Calling check_v_not_faster_than_c on" , tNotTooFast2 , ":" , check_v_not_faster_than_c(tNotTooFast2) if not check_v_not_faster_than_c(tNotTooFast2): tSuccessful = False print "Calling check_v_not_faster_than_c on" , tTooFast1 , ":" , check_v_not_faster_than_c(tTooFast1) if check_v_not_faster_than_c(tTooFast1): tSuccessful = False print "Calling check_v_not_faster_than_c on" , tTooFast2 , ":" , check_v_not_faster_than_c(tTooFast2) if check_v_not_faster_than_c(tTooFast2): tSuccessful = False print "Using" , tMomentum4V1 , "which has mass:" , calculate_m_from_p_vector(tMomentum4V1) tExpected = math.sqrt((tMomentum4V1[1]*tMomentum4V1[1]) + (tMomentum4V1[2]*tMomentum4V1[2]) + (tMomentum4V1[3]*tMomentum4V1[3]))
def check_lightlike(pV): """A function to check whether a momentum vector is light-like (i.e P.P = M^2 = 0).""" assert fourVectors.check_is_fourVector(pV) assert pV.__nonzero__() __MinkowskiSP = pV * pV return precision.check_numbers_equal(__MinkowskiSP, 0.0)