(file) Return to radc.f CVS log (file) (dir) Up to [HallC] / Poltar

  1 jones 1.1 !--------------------------------------------------------------------------
  2           
  3           	subroutine basicrad(itail,Egamma_lo,Egamma_hi,Egamma,weight,val_reciprocal)
  4           
  5           	implicit none
  6           	include 'radc.inc'
  7           
  8           	integer itail
  9           	real*8 Egamma_lo, Egamma_hi, Egamma, weight, val_reciprocal
 10           	real*8 power_lo, power_hi
 11           	real*8 x, y, ymin
 12           
 13           	real*8 grnd
 14           
 15           !--------------------------------------------------------------------------
 16           !
 17           ! Generate Egamma inside the requested region, using the function 
 18           !	    g * Egamma**(g-1)
 19           !	-------------------------------
 20           !	(Egamma_max**g - Egamma_min**g)
 21           ! which has the BASICRAD shape, is "invertible" as a probability 
 22 jones 1.1 ! distribution,
 23           ! and integrates to 1 over the requested region { Egamma_min to Egamma_max }.
 24           ! Each radiative event we generate with this then has to be weighted with
 25           ! the _actual_ radiative tail form (which doesn't necessarily integrate to 1)
 26           ! _divided_by_ this generating function, so we return the RECIPROCAL of the 
 27           ! function's value (at the selected Egamma) as VAL_RECIPROCAL. If we're not 
 28           ! using anything fancier than BASICRAD, we can immediately determine what
 29           ! that 
 30           ! quotient is:
 31           !		  C
 32           !	weight = --- * (Egamma_max**g - Egamma_min**g)
 33           !		  g
 34           ! We return that as (you guessed it!) WEIGHT.
 35           ! If we want to use BASICRAD x the phi function (correction to external tail
 36           ! shape), all we need to do is multiply WEIGHT by PHI evaluated at the
 37           ! selected photon energy. That's dont outside this routine, in GENERATE_RAD.
 38           ! Note that if we're not using the BASICRAD prescription at all (except as
 39           ! a generation tool), WEIGHT is not used again. 
 40           !
 41           ! Note this routine handles the possibilities Egamma_lo < 0, Egamma_hi <
 42           ! Egamma_lo, and Egamma_hi < 0
 43 jones 1.1 !---------------------------------------------------------------------------
 44           
 45           ! Initialize
 46           
 47           	Egamma = 0.0
 48           	weight = 0.0
 49           	val_reciprocal = 0.0
 50           
 51           ! ... is radiation in this direction turned off?
 52           
 53           	if(itail.eq.0)itail=4
 54           	if (g(itail).le.0) then
 55           	  weight = 1.0
 56           	  return
 57           	endif
 58           
 59           ! ... do we have a chance?
 60           
 61           	if (Egamma_hi.le.Egamma_lo .or. Egamma_hi.le.0) return
 62           
 63           ! ... want to evaluate powers as INfrequently as possible!
 64 jones 1.1 
 65           	power_hi = Egamma_hi**g(itail)
 66           	power_lo = 0.0
 67           	if (Egamma_lo.gt.0) power_lo = Egamma_lo**g(itail)
 68           
 69           ! ... obtain y region: from (Egamma_lo/Egamma_hi)**g to 1, generate flat y.
 70           
 71           	ymin = power_lo/power_hi
 72           	y = ymin + grnd()*(1.-ymin)
 73           	x = y**(1./g(itail))
 74           	Egamma = x*Egamma_hi
 75           
 76           ! The value of our generating function at the selected point
 77           
 78           	if (Egamma.gt.0) val_reciprocal = Egamma**(1.-g(itail)) *
 79                >		(power_hi-power_lo) / g(itail)
 80           
 81           ! Event weight = probability radiation falls inside requested range,
 82           ! in full BASICRAD prescription
 83           
 84           	weight = c(itail)/g(itail) * (power_hi-power_lo)
 85 jones 1.1 
 86           	if(itail.eq.4)itail=0
 87           	return
 88           	end
 89           
 90           !-------------------------------------------------------------------------
 91           
 92           	real*8 function gamma(x)
 93           
 94           	implicit none
 95           
 96           	integer i, n, s
 97           	real*8	x, y
 98           
 99           ! Compute gamma function for xin
100           ! The series computes gamma(1+y), and must be fed y between 0 and 1
101           ! This can be accomplished using the relation
102           ! gamma(y+n+1) = (y+n)*gamma(y+n) = ... = (y+n)*...*(y+1)*gamma(y+1)
103           
104           	gamma = 1.0
105           	n = nint((x-1)-0.5)
106 jones 1.1 	y = x-1 - n
107           	if (n.ne.0) then
108           	  s = sign(1,n)
109           	  do i = s, n, s
110           	    gamma = gamma*(y+1+i)**s
111           	  enddo
112           	endif
113           	gamma = gamma * (1. - 0.5748646*y + 0.9512363*y**2 -
114                >		 0.6998588*y**3 + 0.4245549*y**4 - 0.1010678*y**5)
115           	return
116           	end
117           
118           !--------------------------------------------------------------------------
119           
120           	subroutine generate_rad(main,vertex,orig,success)
121           
122           	implicit none
123           	include 'simulate.inc'
124           	include 'radc.inc'
125           	
126           	integer i, peaked_basis_flag
127 jones 1.1 	real*8 x, rad_weight
128           	real*8 peaked_rad_weight, basicrad_val_reciprocal
129           	real*8 basicrad_weight, extrad_phi
130           	real*8 max_delta_Trec, ebeam_min, ebeam_max
131           	logical force2		!force tail #2 to radiate.
132           	logical evsuccess,success
133           	record /event_main/ main
134           	record /event/	vertex, orig
135           
136           	real*8 grnd
137           
138           !---Generate Radiation-----------------------------------------------------
139           ! This routine radiates the incoming event
140           ! Here are comments from radc_init that describe rad_flag and extrad_flag:
141           !
142           ! First, about those (mysterious) 2 main 'radiative option' flags ...
143           !
144           ! The significance of RAD_FLAG:
145           !        RAD_FLAG  = 0  .. use best available formulas, generate in
146           !                       .. (ntail,Egamma) basis
147           !                  = 1  .. use BASICRAD only, generate in (ntail,Egamma)
148 jones 1.1 !                       .. basis
149           !                  = 2  .. use BASICRAD only, generate in (Egamma(1,2,3))
150           !                       .. basis but prevent overlap of tails (bogus, note)
151           !                  = 3  .. use BASICRAD only, generate in (Egamma(1,2,3))
152           !                       .. allowing radiation in all 3 directions
153           !                       .. simultaneously
154           ! The (ntail,Egamma) basis can be called the PEAKED basis since it allows
155           ! only 3 photon directions. PEAKED_BASIS_FLAG is set to zero below when
156           ! the peaked basis is being used, in this way we can conveniently tell
157           ! the BASICRAD routine to use the full Egamma formula to generate the gamma
158           ! energy whenever it's called.
159           !
160           ! (See N. Makins' thesis, section 4.5.6, for more help on this point)
161           !
162           ! The significance of EXTRAD_FLAG:
163           !       EXTRAD_FLAG = 1 .. use only BASIC external radiation formulas
164           !                       .. (phi = 1)
165           !                   = 2 .. use BASIC ext rad formulas x phi
166           !                   = 3 .. use Friedrich approximation the way we always
167           !                       .. have
168           !                   = 0 .. use DEFAULTS: 3 for RAD_FLAG = 0, 1 otherwise; note
169 jones 1.1 !                          that the defaults mimic the hardwired 'settings'
170           !                          in SIMULATE, which doesnt read EXTRAD_FLAG
171           !                          but determines what to do based on RAD_FLAG
172           !---------------------------------------------------------------------------
173           
174           ! Initialize.
175           ! ... ntup.radphot=sum energy of all radiated photons.
176           ! ... ntup.radarm=ntail, or 12 if tail 2 is forced.
177           
178           	lim1=0
179           	lim2=0
180           	lim3=0
181           	phot1=0
182           	phot2=0
183           	phot3=0
184           
185           	if (debug(2)) write(6,*)'gen_rad: entering...'
186           	success = .false.
187           	rad_weight = 1
188           	do i = 1,3
189           	  Egamma_used(i) = 0.0
190 jones 1.1 	enddo
191           	ntup.radphot=0.
192           	ntup.radarm=0.
193           	force2=.false.
194           
195           ! Which tail has to be radiated? Set ntail=0 if all tails allowed to radiate.
196           
197           	peaked_basis_flag = 1
198           	if (rad_flag.le.1) then
199           	  peaked_basis_flag = 0
200           	  x = grnd()
201           	  if (x.ge.frac(1)+frac(2)) then
202           	    ntail = 3
203           	  else if (x.ge.frac(1)) then
204           	    ntail = 2
205           	  else
206           	    ntail = 1
207           	  endif
208           	else if (rad_flag.eq.2) then
209           	  ntail = int(grnd()*3.) + 1
210           	  if (ntail.eq.4) ntail=3
211 jones 1.1 	else if (rad_flag.eq.3) then
212           	  ntail = 0
213           	else
214           	  stop 'Idiot! rad_flag is set stupidly'
215           	endif
216           	if (debug(5)) write(6,*) 'vertexradc',vertex.e.E,edge.e.E.max
217           
218           ! If the scattered electron energy is too high to be dectected, only events
219           ! where electron radiates will be accepted.  Force ntail=2, and apply extra
220           ! weight to event equal to frac(2) (the normal probability that ntail=2)
221           
222           	if (vertex.e.E .gt. edge.e.E.max) then
223           	  force2=.true.
224           	  ntail=2
225           	endif
226           ! Need maximum change in recoil momentum for some of the later limits (e,e'p).
227           
228           	max_delta_Trec = max((vertex.Trec - VERTEXedge.Trec.min),
229                >				 (VERTEXedge.Trec.max - vertex.Trec) )
230           
231           ! RADIATE TAIL #1: the incident electron tail
232 jones 1.1 
233           	if (doing_tail(1) .and. (ntail.eq.0.or.ntail.eq.1)) then
234           	  if (debug(5)) write(6,*) 'gen_rad: at 1'
235           
236           ! ... CASE 1: A(e,e'p) for A>2 - the effect of radiation on this tail alters
237           ! ... the VERTEX (actual) value of Em, so we want to make sure we're inside
238           ! ... any source spectral function cuts (like the Fermi surface).
239           ! ... Set Egamma_max to avoid getting below Em.min, and if Em is above Em.max,
240           ! ... set minimum to get below Em.max.  Radiating a photon decreases Em
241           ! ... (relative to pre-radiated value), but also shifts Pm, and thus Trec.
242           ! ... Allow Trec shift as well as Em.  Note that there are NO limits based on
243           ! ... spectrometer Em limits (cuts) because measured Em used Ebeam before rad.
244           
245           ! ... If only the incoming electron arm radiates, then we can compare Em
246           ! ... to edge.Em.min (the SPECTROMETER Em limit) as well.
247           
248           	  if (doing_heavy) then
249           	    if (debug(5)) write(6,*)'gen_rad: at 2a'
250           	if (debug(5)) write(6,*)'vertex.Em=',vertex.Em
251           	if (debug(5)) write(6,*)'VERTEXedge.Em.max=',VERTEXedge.Em.max
252           	if (debug(5)) write(6,*)'max_delta_Trec=',max_delta_Trec
253 jones 1.1 	    Egamma_min(1)=vertex.Em - VERTEXedge.Em.max - max_delta_Trec
254           	    Egamma_max(1)=vertex.Em - VERTEXedge.Em.min + max_delta_Trec
255           	    if (ntail.ne.0) Egamma_max(1)=min(Egamma_max(1),
256                >			vertex.Em - edge.Em.min + max_delta_Trec)
257           
258           ! ... CASE 2: H(e,e'p) - Require that Ebeam after radiation can generate
259           ! ... electron inside of electron arm acceptance (Ein_max for Ee'_max, etc...).
260           ! ... Also require MEASURED Em < edge.Em.max (Em_meas=egamma1+egamma2+egamma3)
261           
262           ! ... JRA: Note that we get ebeam max/min from E=mE'/(m+E'*(1-cos(theta)),
263           ! ... assuming that E'_max(min) gives E_max(min).  However, for very large
264           ! ... angles, or large E'_max, you can get a negative value for E_max.  When
265           ! ... this happens, just open up ebeam_max.  In the long run, we need to get
266           ! ... a true E_max, not just E for E'_max.
267           
268           	  else if (doing_hyd_elast) then
269           	    if (debug(5)) write(6,*)'gen_rad: at 2b'
270           	    ebeam_max = Mp*edge.e.E.max / (Mp-edge.e.E.max*(1.-vertex.ue.z))
271           	    if (ebeam_max.lt.0) ebeam_max=1.d10
272           	    ebeam_min = Mp*edge.e.E.min / (Mp-edge.e.E.min*(1.-vertex.ue.z))
273           	    Egamma_min(1) = vertex.Ein - ebeam_max
274 jones 1.1 	    Egamma_max(1) = vertex.Ein - ebeam_min
275           	    Egamma_max(1) = min(Egamma_max(1),edge.Em.max)
276           
277           ! ... CASE 3: D(e,e'p) - limit radiation so that E_beam > E' at the vertex.
278           
279           	  else if (doing_deuterium) then
280           	    Egamma_max(1) = min(Egamma1_max, gen.sumEgen.max - vertex.e.E)
281           	    if (ntail.ne.0) Egamma_min(1) = gen.sumEgen.min - vertex.e.E
282           
283           ! ... CASE 4: Pion production.  Too complicated to calculate min/max ebeam
284           ! ... from scattered particles.  Use sumEgen-vertex.e.E as limit for remaining
285           ! ... generated energy available.
286           
287           	  else if (doing_pion .or. doing_kaon) then
288           	    if (debug(5)) write(6,*)'gen_rad: at 2d'
289           	    Egamma_min(1) = 0.
290           	    Egamma_max(1) = gen.sumEgen.max - vertex.e.E
291           	    if (ntail.ne.0) Egamma_min(1) = gen.sumEgen.min - vertex.e.E
292           	  endif
293           
294           ! ... Constrain Egamma<Egamma1_max(from radc_init), and add energy 'slop'
295 jones 1.1 	  Egamma_max(1) = min(Egamma_max(1),Egamma1_max)
296           	  Egamma_min(1) = Egamma_min(1) - dE_edge_test
297           	  Egamma_max(1) = Egamma_max(1) + dE_edge_test
298           
299           ! ... override Egamma_max with limit from dbase (if entered)
300           	  lim1=egamma_max(1)
301           	  if (hardwired_rad) then
302           	    Egamma_max(1) = Egamma_gen_max
303           	    if (lim1.gt.Egamma_gen_max) write(6,*)
304                >		'SIMC found an Egamma(1) limit above your hardwired value'
305           	  endif
306           
307           ! ... radiate 
308           	  if (debug(5)) write(6,*)'gen_rad: init Egamma_min,max =',
309                >		Egamma_min(1),Egamma_max(1)
310           	  call basicrad(1*peaked_basis_flag,Egamma_min(1),Egamma_max(1),
311                >		Egamma_used(1),basicrad_weight,basicrad_val_reciprocal)
312           	  if (basicrad_weight.le.0) then
313           	    if (debug(4)) write(6,*)'gen_rad: failed at 4'
314           	     return
315           	  endif
316 jones 1.1 	  if (debug(5)) write(6,*)'Egamma_used',Egamma_used(1)
317           
318           ! ... adjust kinematics and call complete_ev.  If complete_ev fails, return.
319           
320           	  vertex.Ein = vertex.Ein - Egamma_used(1)
321           	  if (debug(5)) write(6,*) 'calling complete_ev from radc'
322           	  call complete_ev(main,vertex,evsuccess)
323           	  if (.not.evsuccess) then	!remove previous radiation, try again.
324           !!	    if (ntried.le.5000) write(6,'(1x,''COMPLETE_EV1 failed in GENERATE_RAD at event'',i7,''!'')') nevent
325           	    return
326           	  endif
327           	  if (debug(4)) write(6,*)'gen_rad: at 5'
328           	  rad_weight = rad_weight * basicrad_weight
329           	  if (rad_flag.le.1) then
330           	    rad_weight = peaked_rad_weight(vertex,Egamma_used(1),Egamma_min(1),
331                >		Egamma_max(1),basicrad_val_reciprocal,basicrad_weight)
332           	  else
333           	    rad_weight=rad_weight*extrad_phi(1,vertex.Ein,vertex.e.E,Egamma_used(1))
334           	  endif
335           	endif		!end of tail 1 (incoming electron)
336           
337 jones 1.1 ! The VERTEX kinematics are now set, so check that we are inside the
338           ! VERTEXedges (SF limits).
339           
340           	if (doing_heavy) then
341           	  if (debug(5)) write(6,*)'gen_rad: Em, min, max =',vertex.Em,
342                >		VERTEXedge.Em.min,VERTEXedge.Em.max
343           	  if (debug(5)) write(6,*)'gen_rad: Pm, min, max =',vertex.Pm,
344                >		VERTEXedge.Pm.min,VERTEXedge.Pm.max
345           	  if (vertex.Em .lt. VERTEXedge.Em.min .or.
346                >	      vertex.Em .gt. VERTEXedge.Em.max .or.
347                >	      vertex.Pm .lt. VERTEXedge.Pm.min .or.
348                >	      vertex.Pm .gt. VERTEXedge.Pm.max) then
349           	    if (debug(4)) write(6,*)'gen_rad: failed at 6'
350           	    return
351           	  endif
352           	endif
353           
354           ! RADIATE TAIL #2: the scattered electron tail
355           
356           	if (doing_tail(2) .and. (ntail.eq.0.or.ntail.eq.2)) then
357           	  if (debug(5)) write(6,*) 'we are at 2'
358 jones 1.1 
359           ! ... Find min/max Egammas that will make in into electron acceptance
360           
361           	  Egamma_min(2) = vertex.e.E - edge.e.E.max
362           	  Egamma_max(2) = vertex.e.E - edge.e.E.min
363           
364           ! ... Measured Em must be within acceptance after radiation.  Gives upper
365           ! ... limit on sum of photon energies, and lower limit if hadron arm does
366           ! ... not radiate.  Em_MEAS = Em_VERT+(Egamma1+Egamma2+Egamma3)+/-delta_trec.
367           
368           	  if (doing_eep) then
369           	    Egamma_max(2) = min(Egamma_max(2),
370                >		(edge.Em.max - vertex.Em) - Egamma_used(1) + max_delta_Trec )
371           	    if (ntail.ne.0 .or. .not.rad_proton_this_ev)
372                >		Egamma_min(2) = max(Egamma_min(2),
373                >		(edge.Em.min - vertex.Em) - Egamma_used(1) - max_delta_Trec )
374           	  endif
375           
376           	  Egamma_max(2) = min(Egamma_max(2),Egamma_tot_max-Egamma_used(1))
377           	  Egamma_min(2) = Egamma_min(2) - dE_edge_test
378           	  Egamma_max(2) = Egamma_max(2) + dE_edge_test
379 jones 1.1 
380           ! ... override Egamma_max with limit from dbase (if entered)
381           	  lim2=egamma_max(2)
382           	  if (hardwired_rad) then
383           	    Egamma_max(2) = Egamma_gen_max
384           	    if (lim2.gt.Egamma_gen_max) write(6,*)
385                >		'SIMC found an Egamma(2) limit above your hardwired value'
386           	  endif
387           
388           ! ... radiate
389           	  call basicrad(2*peaked_basis_flag,Egamma_min(2),Egamma_max(2),
390                >		Egamma_used(2),basicrad_weight,basicrad_val_reciprocal)
391           	  if (basicrad_weight.le.0) then
392           !	    write(6,*)'gen_rad: Maybe you need to change Em limits!'
393           !	    write(6,*)'min/max(2)=',egamma_min(2),egamma_max(2)
394           	    if (debug(4)) write(6,*)'gen_rad: failed at 7'
395           	    return
396           	  endif
397           	  if(debug(5))write(6,*)'gen_rad: peaked_basis_flag=',peaked_basis_flag
398           	  if(debug(5))write(6,*)'gen_rad: Egamma min,max,used=',
399                >		Egamma_min(2),Egamma_max(2),Egamma_used(2)
400 jones 1.1 	  if(debug(5))write(6,*)'gen_rad: basicrad_weight=',basicrad_weight
401           	  rad_weight = rad_weight * basicrad_weight
402           	  if (rad_flag.le.1) then
403           	    rad_weight = peaked_rad_weight(vertex,Egamma_used(2),Egamma_min(2),
404                >		Egamma_max(2),basicrad_val_reciprocal,basicrad_weight)
405           	  else 
406           	    rad_weight=rad_weight*extrad_phi(2,vertex.Ein,vertex.e.E,Egamma_used(2))
407           	  endif
408           	endif		!end of tail 2 (outgoing electron)
409           
410           ! RADIATE TAIL #3: the scattered proton tail
411           
412           	if (rad_proton_this_ev .and. (ntail.eq.0.or.ntail.eq.3)) then
413           	  if (debug(5)) write(6,*) 'we are at 3'
414           
415           ! ... Find min/max Egammas that will make in into hadron acceptance
416           
417           	  Egamma_min(3) = vertex.p.E - edge.p.E.max
418           	  Egamma_max(3) = vertex.p.E - edge.p.E.min
419           
420           ! ... Measured Em must be within acceptance after radiation.  Gives upper
421 jones 1.1 ! ... and lower limit on sum of photon energies (and thus on hadron radiation,
422           ! ... since other arms are done).
423           ! ... Em_MEAS = Em_VERT+(Egamma1+Egamma2+Egamma3)+/-delta_trec.
424           
425           	  if (doing_eep) then
426           	    Egamma_max(3) = min(Egamma_max(3), (edge.Em.max - vertex.Em) -
427                >		Egamma_used(1) - Egamma_used(2) + max_delta_Trec)
428           	    Egamma_min(3) = max(Egamma_min(3), (edge.Em.min - vertex.Em) -
429                >		Egamma_used(1) - Egamma_used(2) - max_delta_Trec )
430           	  endif
431           
432           	  Egamma_max(3) = min(Egamma_max(3),
433                >		Egamma_tot_max-Egamma_used(1)-Egamma_used(2) )
434           	  Egamma_min(3) = Egamma_min(3) - dE_edge_test
435           	  Egamma_max(3) = Egamma_max(3) + dE_edge_test
436           
437           ! ... override Egamma_max with limit from dbase (if entered)
438           	  lim3=egamma_max(3)
439           	  if (hardwired_rad) then
440           	    Egamma_max(3) = Egamma_gen_max
441           	    if (lim3.gt.Egamma_gen_max) write(6,*)
442 jones 1.1      >		'SIMC found an Egamma(3	) limit above your hardwired value'
443           	  endif
444           
445           ! ... radiate
446           	  call basicrad(3*peaked_basis_flag,Egamma_min(3),Egamma_max(3),
447                >		Egamma_used(3),basicrad_weight,basicrad_val_reciprocal)
448           	  if (basicrad_weight.le.0) then
449           	    if (debug(4)) write(6,*)'gen_rad: failed at 8'
450           	    return
451           	  endif
452           	  rad_weight = rad_weight * basicrad_weight
453           	  if (rad_flag.le.1) then
454           	    rad_weight = peaked_rad_weight(vertex,Egamma_used(3),Egamma_min(3),
455                >		Egamma_max(3),basicrad_val_reciprocal,basicrad_weight)
456           	  else
457           	    rad_weight=rad_weight*extrad_phi(3,vertex.Ein,vertex.e.E,Egamma_used(3))
458           	  endif
459           	endif		!end of tail 3 (outgoing hadron)
460           
461           ! Now obtain description of ORIG (orig = vertex + radiation) event.
462           ! ... Note that no kinematics have been changed yet, EXCEPT vertex.Ein, which
463 jones 1.1 ! ... has been reduced by Egamma_used(1).  orig.Ein is the initial (unradiated)
464           ! ... beam energy, so add back Egamma_used(1).  Reduce orig.e.E and orig.p.E
465           ! ... here, and they will be the values passed to the monte carlo (for mult.
466           ! ... scattering and monte carlo model).
467           
468           ! ... Remember that we have taken Ein(GEN)-Ebeam_vertex_ave into
469           ! ... account by shifting edge.Em)
470           
471           	do i = 1, neventfields
472           	  orig.all(i) = vertex.all(i)
473           	enddo
474           	if (debug(4)) write(6,*)'gen_rad: at 10: orig.p.E =',orig.p.E
475           
476           ! ... remove radiation from incoming electron.
477           
478           	orig.Ein = vertex.Ein + Egamma_used(1)
479           
480           ! ... adjust the e'/hadron momenta (if they radiated significantly)
481           
482           	orig.e.E = vertex.e.E - Egamma_used(2)
483           	orig.e.P = orig.e.E
484 jones 1.1 	orig.e.delta = (orig.e.P-spec.e.P)/spec.e.P*100.
485           
486           	orig.p.E = vertex.p.E - Egamma_used(3)
487           	if(orig.p.E.le.Mh) then
488           	  if (debug(4)) write(6,*)'gen_rad: failed at 11'
489           	  return
490           	endif
491           	orig.p.P = sqrt(orig.p.E**2-Mh2)
492           	orig.p.delta = (orig.p.P-spec.p.P)/spec.p.P*100.
493           
494           ! ... Record some information for other routines.
495           	phot1=Egamma_used(1)
496           	phot2=Egamma_used(2)
497           	phot3=Egamma_used(3)
498           	ntup.radphot = phot1 + phot2 + phot3
499           	ntup.radarm=ntail
500           	if (force2) ntup.radarm=12
501           
502           ! Complete determination of the event weight due to radiation.
503           
504           	main.gen_weight = main.gen_weight*rad_weight/hardcorfac
505 jones 1.1 	if (force2) main.gen_weight=main.gen_weight*frac(2)
506           	if (debug(5)) write(6,*) 'mgw',main.gen_weight,rad_weight,hardcorfac
507           	success = .true.
508           
509           	if (debug(2)) write(6,*)'gen_rad: exiting...'
510           	return
511           	end
512           
513           !--------------------------------------------------------------------------
514           
515           	real*8 function peaked_rad_weight(vertex,Egamma,
516                >		emin,emax,basicrad_val_reciprocal,basicrad_weight)
517           
518           	implicit none
519           	include 'radc.inc'
520           	include 'structures.inc'
521           
522           	real*8		Egamma, basicrad_val_reciprocal, basicrad_weight
523           	real*8		t1, t2, r, phi_ext, ein, eout, emin, emax
524           	real*8		brem, bremos, extrad_phi, gamma
525           	real*8		dhard, dsoft_intmin, dsoft_intmax
526 jones 1.1 	real*8          dsoft_ext1, dsoft_ext2, dsoft_extmin
527           	real*8		dsoft_int_primemin, dsoft_int_primemax
528           	real*8          dsoft_ext1_prime, dsoft_ext2_prime
529           	real*8		dsoft_ext_prime, dsoft_extmax, eul
530           	real*8          dsoft_int,dsoft_ext,dsoft_int_prime
531           	record /event/	vertex
532           
533           	real*8 zero
534           	parameter (zero=0.0d0)	!double precision zero for subroutine calls
535           
536           	basicrad_val_reciprocal=basicrad_val_reciprocal+0. !avoid unused variable error
537           ! Compute a more precise value for the radiative probability at the
538           ! selected Egamma, more precise than the BASICRAD distribution used to 
539           ! generate Egamma that is.
540           !
541           ! NB: This subroutine only deals with calculations done in the PEAKING
542           ! APPROXIMATION basis -
543           !    i.e. we only get here if RAD_FLAG = 0 or 1
544           !
545           ! ... (sort of) KLUGE -- if Egamma < res limit, these things might blow up,
546           ! ... so just screw the correction and leave
547 jones 1.1 	ein=vertex.Ein
548           	eout=vertex.e.E
549           	eul=0.577215665
550           c	if (Egamma.lt.Egamma_res_limit) then
551           c	  peaked_rad_weight = basicrad_weight
552           c	  return
553           c	endif
554           
555           ! ... External
556           
557           	phi_ext = 1.0
558           	if (extrad_flag.le.2) then
559           	  phi_ext = extrad_phi(0,ein,eout,Egamma)
560           	  if (rad_flag.eq.1) then
561           	    peaked_rad_weight = basicrad_weight * phi_ext
562           	    return
563           	  endif
564           	  if(emin.gt.0)then
565           	    dsoft_extmin = log(g_ext/c_ext(0)/emin**g_ext)
566           	  endif
567           	  dsoft_extmax = log(g_ext/c_ext(0)/emax**g_ext)
568 jones 1.1 	  dsoft_ext_prime = -g_ext/Egamma
569           	else
570           	  t1 = bt(1)/etatzai
571           	  t2 = bt(2)/etatzai
572           	  call extrad_friedrich(ein,Egamma,t1,dsoft_ext1,dsoft_ext1_prime)
573           	  call extrad_friedrich(eout,Egamma,t2,dsoft_ext2,dsoft_ext2_prime)
574           	  dsoft_ext = dsoft_ext1 + dsoft_ext2
575           	  dsoft_ext_prime = dsoft_ext1_prime + dsoft_ext2_prime
576           	endif
577           
578           ! ... Internal
579           ! ........ use full BREM calculation of deltas
580           
581           	if (rad_flag.eq.0) then
582           	  if (.not.use_offshell_rad) then
583           	    if(emin.gt.0)then
584           	      r = brem(ein,eout,emin,rad_proton_this_ev,
585                >			dsoft_intmin,dhard,dsoft_int_primemin)
586           	    else
587           	      dsoft_intmin=1.0
588           	    endif
589 jones 1.1 	    r = brem(ein,eout,emax,rad_proton_this_ev,
590                >			dsoft_intmax,dhard,dsoft_int_primemax)
591           	  else
592           	    if(emin.gt.0)then
593           	      r = bremos(emin, zero, zero, ein,
594                >			vertex.e.E*vertex.ue.x, vertex.e.E*vertex.ue.y,
595                >			vertex.e.E*vertex.ue.z,
596           c     >			vertex.Pmx, vertex.Pmy, vertex.Pmz,
597                >			zero,zero,zero,
598                >			vertex.p.P*vertex.up.x, vertex.p.P*vertex.up.y,
599                >			vertex.p.P*vertex.up.z, vertex.p.E,
600                >			rad_proton_this_ev,
601                >			dsoft_intmin, dhard, dsoft_int_primemin)
602           	    else 
603           	      dsoft_intmin=1.0
604           	    endif
605           	      r = bremos(emax, zero, zero, ein,
606                >			vertex.e.E*vertex.ue.x, vertex.e.E*vertex.ue.y,
607                >			vertex.e.E*vertex.ue.z,
608           c     >			vertex.Pmx, vertex.Pmy, vertex.Pmz
609                >			zero,zero,zero,
610 jones 1.1      >			vertex.p.P*vertex.up.x, vertex.p.P*vertex.up.y,
611                >			vertex.p.P*vertex.up.z, vertex.p.E,
612                >			rad_proton_this_ev,
613                >			dsoft_intmax, dhard, dsoft_int_primemax)
614           	  endif
615           
616           ! ........ use basic calculation of internal deltas
617           
618           	else
619           	  dsoft_int = log(g_int/c_int(0)/Egamma**g_int)
620           	  dsoft_int_prime = -g_int/Egamma
621           	endif
622           
623           ! ... All together now
624           
625           	if(emin.gt.0)then
626           	  peaked_rad_weight = c_ext(0)/g_ext*(exp(-dsoft_intmax)*
627                >		emax**g_ext-exp(-dsoft_intmin)*emin**g_ext)
628           	else
629           	  peaked_rad_weight = c_ext(0)/g_ext*(exp(-dsoft_intmax)*emax**g_ext)
630           	endif
631 jones 1.1 	peaked_rad_weight = peaked_rad_weight * exp(-eul*g(4))/gamma(1.+g(4))
632                >		* gamma(1.+g(4)-bt(1)-bt(2))*gamma(1.+bt(1))
633                >		* gamma(1.+bt(2))/gamma(1.+g(4))
634           	if (peaked_rad_weight.lt.0) peaked_rad_weight = 0
635           
636           	return
637           	end
638           
639           !---------------------------------------------------------------------------
640           
641           	subroutine extrad_friedrich(Ei,Ecutoff,trad,dbrem,dbrem_prime)
642           
643           	implicit none
644           	include 'simulate.inc'
645           	include 'radc.inc'
646           
647           	real*8	Ei, Ecutoff, trad, x, dbrem, dbrem_prime
648           
649           	x = Ecutoff/Ei
650           	dbrem = trad*(-(etatzai-0.5) - etatzai*log(x) + etatzai*x - 0.5*x**2)
651           	dbrem_prime = -trad/Ei * (etatzai/x - etatzai + x)
652 jones 1.1 
653           	return
654           	end
655           
656           !--------------------------------------------------------------------------
657           
658           	real*8 function extrad_phi(itail,E1,E2,Egamma)
659           
660           	implicit none
661           	include 'radc.inc'
662           
663           	integer itail
664           	real*8 E1, E2, Egamma, E(2), x, t, gamma
665           
666           	E(1) = E1
667           	E(2) = E2
668           
669           ! Compute the multiplicative external correction function PHI
670           
671           ! ... CASE 1: phi = 1
672           
673 jones 1.1 	extrad_phi = 1.0
674           
675           ! ... CASE 2: phi correctly computed according to Dave's formulas
676           
677           	if (extrad_flag.eq.2) then
678           	  if (itail.eq.0) then
679           	    extrad_phi = 1. - (bt(1)/E(1)+bt(2)/E(2)) / (g(1)+g(2)) * Egamma
680           	  else if (itail.eq.1.or.itail.eq.2) then
681           	    extrad_phi = 1. - bt(itail)/E(itail) / g(itail) * Egamma
682           	  endif
683           
684           ! ... CASE 3: phi computed in Friedrich prescription
685           
686           	else if (extrad_flag.eq.3) then
687           	  if (itail.eq.0) stop 'Idiot! a multiplicative factor EXTRAD_PHI is not defined for peaking approx and EXTRAD_FLAG>2!'
688           	  if (itail.eq.1.or.itail.eq.2) then
689           	    x = Egamma/E(itail)
690           	    t = bt(itail)/etatzai
691           	    extrad_phi = extrad_phi * (1. - x + x**2/etatzai) *
692                >		exp(t*((etatzai-0.5)-etatzai*x+x**2/2.)) * gamma(1.+bt(itail))
693           	  endif
694 jones 1.1 	endif
695           
696           	return
697           	end
698           
699           !------------------------------------------------------------------------
700           
701           	real*8 function schwinger(Ecutoff,vertex,include_hard,dsoft,dhard)
702           
703           	implicit none
704           	include 'simulate.inc'
705           	include 'radc.inc'
706           
707           	real*8		Ecutoff,lq,s2,b,spence,dsoft,dhard,spen
708           	logical		include_hard
709           	record /event/	vertex
710           
711           
712           	lq = log(vertex.Q2/Me**2)-1.0
713           	s2 = sin(vertex.e.theta/2.)**2
714           	b = 1.+2.*vertex.omega*s2/(targ.A*amu)
715 jones 1.1 	spence = spen(1.-s2)-2.5893784
716           	dsoft = alpi*lq*log( vertex.Ein/(etta**2)*vertex.e.E*b/(Ecutoff**2) )
717           	dhard = -alpi*(2.166666*lq + spence - log(vertex.Ein/vertex.e.E)**2/2.0)
718           
719           	if (use_expon.eq.0) then
720           	  schwinger = exp(dsoft)
721           	else
722           	  schwinger = 1.+dsoft
723           	endif
724           
725           	if (include_hard) schwinger = schwinger/(1.-dhard)
726           
727           	return
728           	end
729           
730           !--------------------------------------------------------------------------
731           
732           	real*8 function spen(x)
733           
734           	implicit none
735           
736 jones 1.1 	integer	i
737           	real*8	x,s,y
738           
739           ! Approximation formula for the Spence-function or -integral according to
740           ! abramowitz and stegun : formula 27.7.2
741           
742           	y = 1.0
743           	s = 0.0
744           	i = 0
745           	do while (i.le.100 .and. abs(y).gt.abs(s)*1.d-4)
746           	  i = i+1
747           	  y = x*y
748           	  s = s+y/float(i**2)
749           	enddo
750           	spen = s
751           
752           	return
753           	end
754           
755           !--------------------------------------------------------------------------
756           
757 jones 1.1 	real*8 function lambda_dave(itail,plus_flag,doing_proton,e1,e2,e3,p3,th)
758           
759           	implicit none
760           	include 'constants.inc'
761           
762           	integer		itail,plus_flag
763           	real*8		e1,e2,e3,p3,th
764           	real*8		plus_term
765           	logical		doing_proton, warned/.false./
766           
767           ! The extended peaking approximation
768           
769           	plus_term = 0.0
770           	if (plus_flag.eq.1 .and. itail.lt.3) then
771           	  plus_term = log((1.-cos(th))/2.)
772           
773           ! ... only add in term due to ep interference if we're using proton
774           ! ... radiation
775           
776           	  if (doing_proton) plus_term = plus_term + 2.*log(e1/e2)
777           	endif
778 jones 1.1 
779           ! Compute lambdas
780           
781           	if (itail.eq.1) then
782           	  lambda_dave	= alpi*(2.*log(2.*e1/Me) -1. + plus_term)
783           	else if (itail.eq.2) then  
784           	  lambda_dave	= alpi*(2.*log(2.*e2/Me) -1. + plus_term)
785           	else if (itail.eq.3) then
786           	  if (doing_proton) then
787           	    lambda_dave	= alpi*(log((e3+p3)/(e3-p3)) - 2.)
788           ! ... at low energies, this may fritz, prevent human from causing itself
789           ! ... too much damage
790           
791           	    if (lambda_dave.lt.0) then
792           	      lambda_dave = 0.0
793           	      if (.not.warned) then
794           	        write(6,'(1x,a)') '+-----------------------------------+'
795           	        write(6,'(1x,a)') '| WARNING: lambda_dave(3)<0, think  |'
796           	        write(6,'(1x,a)') '| about running with proton rad OFF |'
797           	        write(6,'(1x,a)') '+-----------------------------------+'
798           	        warned = .true.
799 jones 1.1 	      endif
800           	    endif
801           	  else
802           	    lambda_dave = 0.0
803           	  endif
804           	endif
805           
806           	return
807           	end

Analyzer/Replay: Mark Jones, Documents: Stephen Wood
Powered by
ViewCVS 0.9.2-cvsgraph-1.4.0