(file) Return to event.f CVS log (file) (dir) Up to [HallC] / simc_semi

   1 gaskelld 1.1 	subroutine limits_update(main,vertex,orig,recon,doing_deuterium,
   2                   >		doing_pion,doing_kaon,doing_delta,doing_rho,contrib,slop)
   3              
   4              	include 'structures.inc'
   5              	include 'radc.inc'
   6              	record /event_main/ main
   7              	record /event/ vertex, orig, recon
   8              	record /contrib/ contrib
   9              	record /slop/ slop
  10              	integer i
  11              	logical	doing_deuterium, doing_pion, doing_kaon, doing_delta, doing_rho
  12              
  13              ! Update the "contribution limits" records
  14              
  15              ! ... GENERATION values
  16              	call update_range(vertex.e.delta, contrib.gen.e.delta)
  17              	call update_range(vertex.e.yptar, contrib.gen.e.yptar)
  18              	call update_range(vertex.e.xptar, contrib.gen.e.xptar)
  19              	call update_range(vertex.p.delta, contrib.gen.p.delta)
  20              	call update_range(vertex.p.yptar, contrib.gen.p.yptar)
  21              	call update_range(vertex.p.xptar, contrib.gen.p.xptar)
  22 gaskelld 1.1 	call update_range(main.Trec, contrib.gen.Trec)
  23              
  24              ! ........ another tricky shift
  25              	if (doing_deuterium .or. doing_pion .or. doing_kaon .or. doing_delta .or. doing_rho) then
  26              	  call update_range(vertex.e.E-main.Ein_shift,contrib.gen.sumEgen)
  27              	else
  28              	  call update_range(vertex.e.E+vertex.p.E-main.Ein_shift,contrib.gen.sumEgen)
  29              	endif
  30              
  31              ! ... TRUE values
  32              ! ........ tricky shift here, remember this'll get compared with edge.e.E,
  33              ! ........ compensate for main.target.Coulomb to
  34              ! ........ copy the shift made to the edge in generate
  35              	call update_range(orig.e.E-main.Ee_shift, contrib.tru.e.E)
  36              	call update_range(orig.e.xptar, contrib.tru.e.xptar)
  37              	call update_range(orig.e.yptar, contrib.tru.e.yptar)
  38              	call update_range(orig.e.xptar, contrib.tru.e.xptar)
  39              	call update_range(orig.p.E, contrib.tru.p.E)
  40              	call update_range(orig.p.yptar, contrib.tru.p.yptar)
  41              	call update_range(orig.p.xptar, contrib.tru.p.xptar)
  42              
  43 gaskelld 1.1 ! ........ another tricky shift
  44              	call update_range(orig.Em-main.Ein_shift+main.Ee_shift,contrib.tru.Em)
  45              	call update_range(orig.Pm, contrib.tru.Pm)
  46              	call update_range(orig.Trec, contrib.tru.Trec)
  47              
  48              ! ... SPECTROMETER values
  49              	call update_range(main.SP.e.delta, contrib.SP.e.delta)
  50              	call update_range(main.SP.e.yptar, contrib.SP.e.yptar)
  51              	call update_range(main.SP.e.xptar, contrib.SP.e.xptar)
  52              	call update_range(main.SP.p.delta, contrib.SP.p.delta)
  53              	call update_range(main.SP.p.yptar, contrib.SP.p.yptar)
  54              	call update_range(main.SP.p.xptar, contrib.SP.p.xptar)
  55              
  56              ! ... VERTEX values
  57              	call update_range(vertex.Trec, contrib.vertex.Trec)
  58              	call update_range(vertex.Em, contrib.vertex.Em)
  59              	call update_range(vertex.Pm, contrib.vertex.Pm)
  60              
  61              ! ... RADIATION stuff
  62              ! ??? should be looking at Egamma2+3 cause we do use limits on that, indirectly
  63              
  64 gaskelld 1.1 	do i = 1, 3
  65              	  call update_range(Egamma_used(i), contrib.rad.Egamma(i))
  66              	enddo
  67              	call update_range(Egamma_used(1)+Egamma_used(2)+Egamma_used(3),
  68                   >		contrib.rad.Egamma_total)
  69              
  70              ! Update the "slop limits" records
  71              ! ... MC slops
  72              	call update_range(main.RECON.e.delta-main.SP.e.delta,slop.MC.e.delta)
  73              	call update_range(main.RECON.e.yptar-main.SP.e.yptar,slop.MC.e.yptar)
  74              	call update_range(main.RECON.e.xptar-main.SP.e.xptar,slop.MC.e.xptar)
  75              	call update_range(main.RECON.p.delta-main.SP.p.delta,slop.MC.p.delta)
  76              	call update_range(main.RECON.p.yptar-main.SP.p.yptar,slop.MC.p.yptar)
  77              	call update_range(main.RECON.p.xptar-main.SP.p.xptar,slop.MC.p.xptar)
  78              
  79              ! ... total slops
  80              ! ........ that tricky shift again, slops accounted for by the shift not
  81              ! ........ included in slop.total.Em.
  82              	call update_range(recon.Em-(orig.Em-main.Ein_shift+main.Ee_shift),
  83                   >		slop.total.Em)
  84              	call update_range(abs(recon.Pm)-abs(orig.Pm), slop.total.Pm)
  85 gaskelld 1.1 
  86              	return
  87              	end
  88              
  89              !-------------------------------------------------------------------
  90              
  91              	subroutine update_range(val,range)
  92              
  93              	include 'structures.inc'
  94              	record /range/ range
  95              	real*8	val
  96              
  97              	range.lo = min(range.lo, val)
  98              	range.hi = max(range.hi, val)
  99              
 100              	return
 101              	end
 102              
 103              !----------------------------------------------------------------------
 104              ! THE routine to GENERATE the (max of 7) random quantities we need to get
 105              ! a full description of our event.
 106 gaskelld 1.1 
 107              	subroutine generate(main,vertex,orig,success)
 108              
 109              	implicit none
 110              	include 'simulate.inc'
 111              
 112              	integer i, ii
 113              	real*8 Emin, Emax
 114              	real*8 ranprob,ranth1,ranth,ranph,t3,t4,t5,t6
 115              	real*8 pferlo,pferhi
 116              	real*8 m_spec		!spectator (A-1) mass based on missing energy
 117              	real*8 gauss1
 118              	logical success
 119              	real*8 grnd		!random # generator.
 120              	record /event_main/ main
 121              	record /event/ vertex, orig
 122              
 123              	real*8 nsig_max
 124              	parameter(nsig_max=3.0d0)      !max #/sigma for gaussian ran #s.
 125              
 126              
 127 gaskelld 1.1 ! Randomize the position of the interaction inside the available region.
 128              ! gen.xwid and gen.ywid are the intrinsic beam widths (one sigma value).
 129              ! Use a gaussian beam distribution with +/- 3.0 sigma (add raster afterwards).
 130 gaskelld 1.2 
 131 gaskelld 1.4 C DJG As best I can figger, main.target.y is positive when the beam is high in the lab
 132              C DJG and main.target.x is positive when the beam is right when looking downstream.
 133              C DJG Don't ask me why, but it seems to be this way.
 134              C DJG Note that this means that +fry points down. I will make frx point left. 
 135              
 136 gaskelld 1.1 	main.target.x = gauss1(nsig_max)*gen.xwid+targ.xoffset
 137              	main.target.y = gauss1(nsig_max)*gen.ywid+targ.yoffset
 138              
 139 gaskelld 1.5 ! fr_pattern=1 - old bedpost raster rectangle - targ.fr1/fr2 are the x/y raster half-widths.
 140 gaskelld 1.1 ! fr_pattern=2 - circle - targ.fr1/fr2 are the inner and outer radii.
 141 gaskelld 1.5 ! fr_pattern=3 - new flat raster rectangle - targ.fr1/fr2 are the x/y raster half-widths.
 142 gaskelld 1.1 
 143 gaskelld 1.5 	if (targ.fr_pattern .eq. 1) then		!old bedpost, square raster
 144 gaskelld 1.1 	  t3=grnd()*pi
 145              	  t4=grnd()*pi
 146              	  t5=cos(t3)*targ.fr1
 147              	  t6=cos(t4)*targ.fr2
 148              	elseif (targ.fr_pattern .eq. 2) then		!circular raster
 149              	  t3=grnd()*2.*pi
 150              	  t4=sqrt(grnd())*(targ.fr2-targ.fr1)+targ.fr1
 151              	  t5=cos(t3)*t4
 152              	  t6=sin(t3)*t4
 153 gaskelld 1.5 	elseif (targ.fr_pattern .eq. 3) then		!new, flat square raster
 154              	  t3=2.*grnd()-1.0
 155              	  t4=2.*grnd()-1.0
 156              	  t5=targ.fr1*t3
 157              	  t6=targ.fr2*t4
 158 gaskelld 1.1 	else						!no raster
 159              	  t5=0.0
 160              	  t6=0.0
 161              	endif
 162              
 163              	main.target.x = main.target.x+t5
 164              	main.target.y = main.target.y+t6
 165              	main.target.z = (0.5-grnd())*targ.length+targ.zoffset
 166              	main.target.rastery = t6	!'raster' contribution to vert. pos.
 167 gaskelld 1.4 	main.target.rasterx = t5	! points right as you look downstream  - need to flip sign later.
 168 gaskelld 1.1 
 169              ! Take fluctuations of the beam energy into account, and remember to correct
 170              ! for ionization loss in the target and Coulomb acceleration of incoming
 171              ! electron.  Remove targ.zoffset from the z position of the scattering
 172              ! in order to get the position relative to the center of the target.
 173              
 174              	call trip_thru_target (1, main.target.z-targ.zoffset, Ebeam, 0.0d0,
 175                   >		main.target.Eloss(1), main.target.teff(1),Me,1)
 176              	if (.not.using_Eloss) main.target.Eloss(1) = 0.0
 177              	if (using_Coulomb) then
 178              	  main.target.Coulomb=targ.Coulomb_constant*(3.-(grnd())**(2./3.))
 179              	else
 180              	  main.target.Coulomb=0.0
 181              	endif
 182              	vertex.Ein = Ebeam + (grnd()-0.5)*dEbeam +
 183                   >		main.target.Coulomb - main.target.Eloss(1)
 184              
 185              ! ... deterimine known variation in Ein from Ebeam_vertex_ave and in
 186              ! ... Ee due to Coulomb energy to compare limits to generated event by event.
 187              ! ... (USED TO SHIFT 'LIMIT' VALUES IN UPDATE_RANGE CALLS.  ARE THEY NEEDED???)
 188              
 189 gaskelld 1.1         main.Ein_shift = vertex.Ein - Ebeam_vertex_ave
 190                      main.Ee_shift = main.target.Coulomb - targ.Coulomb.ave
 191              
 192              ! Initialize success code and fractional weight due to radiation and
 193              ! generation tricks
 194              
 195              5	success = .false.
 196              	main.gen_weight = 1.0
 197              
 198              ! Generated quantities: (phase_space NOT YET IMPLEMENTED).
 199              !
 200              ! phase_space: Generate electron E,yptar,xptar and hadron yptar,xptar??
 201              ! doing_hyd_elast: Generate electron angles. Solve for everything else.
 202              ! doing_deuterium: Generate electron energy and angles, proton angles.
 203              !	Solve for proton momentum, p_fermi.
 204              ! doing_eep, A>2: generate electron and hadron energy, angles. Solve for Em,Pm.
 205              ! doing_pion: generate electron energy and angles, hadron angles, p_fermi, Em.
 206              !	Solve for hadron momentum.
 207              ! doing_kaon: as doing_pion.
 208              ! doing_delta: as doing_pion.
 209              ! doing_rho: as doing_pion.
 210 gaskelld 1.1 ! doing_semi: Generate electron E,yptar,xptar and hadron E, yptar,xptar
 211              !
 212              ! The above is summarized in the following table:
 213              !
 214              !                    ELECTRON                  HADRON
 215              !               ------------------      ------------------
 216              !               E       yptar   xptar   E       yptar   xptar   p_fermi	Em
 217              !
 218              !H(e,e'p)		X	X
 219              !D(e,e'p)	X	X	X		X	X
 220              !A(e,e'p)	X	X	X	X	X	X
 221              !----------------------------------------------------------------------
 222              !H(e,e'pi)	X	X	X		X	X
 223              !A(e,e'pi)	X	X	X		X	X	X	X
 224              !H(e,e'K)	X	X	X		X	X
 225              !A(e,e'K)	X	X	X		X	X	X	X
 226              !H(e,e'p)pi	X	X	X		X	X
 227              !A(e,e'p)pi	X	X	X		X	X	X	X
 228              !----------------------------------------------------------------------
 229              !phase_space	X	X	X	?	X	X
 230              !
 231 gaskelld 1.1 ! So our procedure is the following:
 232              ! 1) Always generate electron yptar and xptar
 233              ! 2) generate hadron yptar and xptar for all cases except H(e,e'p).
 234              ! 3) Generate hadron E for A(e,e'p)
 235              ! 4) generate electron E for all but hydrogen elastic.
 236              ! 5) generate p_fermi, Em for A(e,e'pi) and A(e,e'K).
 237              !
 238              ! After we generate xptar/yptar/energy, we calculate physics angles (theta/phi),
 239              !  momenta, unit vectors, etc... here and/or in complete_ev.
 240              !
 241              ! Note that there are also jacobians associated with some and/or all of
 242              ! the above.
 243              ! 1: We generate uniformly in xptar/yptar, not theta/phi.  We define the
 244              ! phase space volume (genvol contribution) as the product of the xptar/yptar
 245              ! range, and have a jacobian for each event taking into account the mapping
 246              ! between the solid angle on the unit sphere, and the dxptar/dyptar volume
 247              ! (the jacobian is 1/cos**3(dtheta), where dtheta is the angle between the
 248              ! event and the central spectrometer vector
 249              ! 2: For the D(e,e'p), we take Em as fixed in order to calculate the proton
 250              ! energy.  There is a jacobian ( |dEp'/dEm| ).  It comes from integrating
 251              ! over the energy conservation delta function: delta(E_D - E_p - E_n - Em).
 252 gaskelld 1.1 
 253              ! Generate Electron Angles (all cases):
 254              	vertex.e.yptar=gen.e.yptar.min+grnd()*(gen.e.yptar.max-gen.e.yptar.min)
 255              	vertex.e.xptar=gen.e.xptar.min+grnd()*(gen.e.xptar.max-gen.e.xptar.min)
 256              
 257              ! Generate Hadron Angles (all but H(e,e'p)):
 258              	if (doing_deuterium.or.doing_heavy.or.doing_pion.or.doing_kaon
 259 gaskelld 1.2 	1    .or.doing_delta.or.doing_semi) then
 260 gaskelld 1.1 	  vertex.p.yptar=gen.p.yptar.min+grnd()*
 261              	1	(gen.p.yptar.max-gen.p.yptar.min)
 262              	  vertex.p.xptar=gen.p.xptar.min+grnd()*
 263              	1      (gen.p.xptar.max-gen.p.xptar.min)
 264              	endif
 265              
 266              ! Generate Hadron Momentum (A(e,e'p) or semi-inclusive production).
 267              	if (doing_heavy .or. doing_semi) then
 268              	  Emin = max(gen.p.E.min, gen.sumEgen.min - gen.e.E.max)
 269              	  Emax = min(gen.p.E.max, gen.sumEgen.max - gen.e.E.min)
 270              	  if (Emin.gt.Emax) goto 100
 271              	  main.gen_weight=main.gen_weight*(Emax-Emin)/(gen.p.E.max-gen.p.E.min)
 272              	  vertex.p.E = Emin + grnd()*(Emax-Emin)
 273              	  vertex.p.P = sqrt(vertex.p.E**2 - Mh2)
 274              	  vertex.p.delta = 100.*(vertex.p.P-spec.p.P)/spec.p.P
 275              	endif
 276              
 277              ! Generate Electron Energy (all but hydrogen elastic)
 278              	if (doing_deuterium.or.doing_heavy.or.doing_pion.or.doing_kaon
 279              	1    .or.doing_delta.or.doing_rho.or.doing_semi) then
 280              	  Emin=gen.e.E.min
 281 gaskelld 1.1 	  Emax=gen.e.E.max
 282              	  if (doing_deuterium .or. doing_pion .or. doing_kaon .or. doing_delta .or. doing_rho) then
 283              	    Emin = max(Emin,gen.sumEgen.min)
 284              	    Emax = min(Emax,gen.sumEgen.max)
 285              	  else if (doing_heavy) then		! A(e,e'p)
 286              	    Emin = max(Emin, gen.sumEgen.min - vertex.p.E)
 287              	    Emax = min(Emax, gen.sumEgen.max - vertex.p.E)
 288              	  endif
 289              	  if (Emin.gt.Emax) goto 100
 290              	  main.gen_weight=main.gen_weight*(Emax-Emin)/(gen.e.E.max-gen.e.E.min)
 291              	  vertex.e.E = Emin + grnd()*(Emax-Emin)
 292              	  vertex.e.P = vertex.e.E
 293              	  vertex.e.delta = 100.*(vertex.e.P-spec.e.P)/spec.e.P
 294              	endif	!not (doing_hyd_elast)
 295              
 296              
 297              ! Calculate the electron and proton PHYSICS angles from the spectrometer angles.
 298              ! Note that the proton angles are not yet know for hydrogen elastic.
 299              
 300              	call physics_angles(spec.e.theta,spec.e.phi,
 301                   &		vertex.e.xptar,vertex.e.yptar,vertex.e.theta,vertex.e.phi)
 302 gaskelld 1.1 	call physics_angles(spec.p.theta,spec.p.phi,
 303                   &		vertex.p.xptar,vertex.p.yptar,vertex.p.theta,vertex.p.phi)
 304              
 305              ! Generate Fermi Momentum and Em for A(e,e'pi) and A(e,e'K). 
 306              	pfer=0.0
 307              	pferx=0.0
 308              	pfery=0.0
 309              	pferz=0.0
 310              	vertex.Em=0.0
 311              	efer=targ.Mtar_struck		!used for pion/kaon xsec calcs.
 312              	if(doing_deutpi.or.doing_hepi.or.doing_deutkaon.or.doing_hekaon.or.
 313              	1    doing_deutdelta.or.doing_hedelta.or.doing_deutrho.or.doing_herho
 314              	2    .or.doing_deutsemi)then
 315              	  ranprob=grnd()
 316              	  ii=1
 317              	  do while (ranprob.gt.mprob(ii) .and. ii.lt.nump)
 318              	    ii=ii+1
 319              	  enddo
 320              	  if (ii.eq.1) then
 321              	    pferlo=0
 322              	  else
 323 gaskelld 1.1 	    pferlo=(pval(ii-1)+pval(ii))/2
 324              	  endif
 325              	  if (ii.eq.nump) then
 326              	    pferhi=pval(nump)
 327              	  else
 328              	    pferhi=(pval(ii)+pval(ii+1))/2
 329              	  endif
 330              	  pfer=pferlo+(pferhi-pferlo)*grnd()
 331              	  ranth1=grnd()*2.-1.0
 332              	  ranth=acos(ranth1)
 333              	  ranph=grnd()*2.*pi
 334              	  pferx=sin(ranth)*cos(ranph)
 335              	  pfery=sin(ranth)*sin(ranph)
 336              	  pferz=cos(ranth)
 337              
 338              	  if (doing_deutpi.or.doing_deutkaon.or.doing_deutdelta
 339              	1      .or.doing_deutrho .or.doing_deutsemi) then !Em = binding energy
 340              	    vertex.Em = Mp + Mn - targ.M
 341              	    m_spec = targ.M - targ.Mtar_struck + vertex.Em != Mn(Mp) for pi+(-)
 342              	    efer = targ.M - sqrt(m_spec**2+pfer**2)
 343              	  endif
 344 gaskelld 1.1 	  if (doing_hepi .or. doing_hekaon .or. doing_hedelta .or. doing_herho) then
 345              	    call generate_em(pfer,vertex.Em)		!Generate Em
 346              	    m_spec = targ.M - targ.Mtar_struck + vertex.Em != M^*_{A-1}
 347              	    efer = targ.M - sqrt(m_spec**2+pfer**2)
 348              	  endif
 349              	endif
 350              
 351              ! Compute all non-generated quantities
 352              
 353              	if (debug(5)) write(6,*)'gen: calling comp_ev with false, main, vertex'
 354              	if (debug(3)) write(6,*)'gen: calling comp_ev with false, main, vertex'
 355              	if (debug(3)) write(6,*)'gen: Ein, E =',vertex.Ein,vertex.e.E
 356 gaskelld 1.2 
 357 gaskelld 1.1 	call complete_ev(main,vertex,success)
 358              
 359 gaskelld 1.2 
 360 gaskelld 1.1 	main.sigcc = 1.0
 361              
 362              	if (debug(2)) write(6,*)'gen: initial success =',success
 363              	if (.not.success) goto 100
 364              
 365              ! ........ temporary storage of Trec for generated event
 366              
 367              	main.Trec = vertex.Trec
 368              
 369              ! Radiate the event, if requested. If we get an event weight of zero (i.e.
 370              ! if we CAN'T radiate our event into the acceptance) then success is
 371              ! false.  generate_rad also set orig kinematics, and cuts on Em/Pm.
 372              ! If not using_rad, must do these here.
 373              
 374              	if (using_rad) then
 375              	  call generate_rad(main,vertex,orig,success)
 376              	  if (debug(2)) write(6,*)'gen: after gen_rad, success =',success
 377              	else
 378              	  success = .true.
 379              	  if (doing_heavy) success = 
 380                   >		(vertex.Em .ge. VERTEXedge.Em.min .and.
 381 gaskelld 1.1      >		 vertex.Em .le. VERTEXedge.Em.max .and.
 382                   >		 vertex.Pm .ge. VERTEXedge.Pm.min .and. 
 383                   >		 vertex.Pm .le. VERTEXedge.Pm.max)
 384              	  if (success) then
 385              	    do i = 1, neventfields
 386              	      orig.all(i) = vertex.all(i)
 387              	    enddo
 388              	  endif
 389              	endif
 390              
 391              
 392              C DJG need to decay the rho here before we begin transporting through the
 393              C DJG spectrometer
 394 gaskelld 1.2 
 395 gaskelld 1.1 	if(doing_rho) then
 396 gaskelld 1.2 	   call rho_decay(orig,spec.p.P,main.epsilon,success)
 397 gaskelld 1.1 	endif
 398              	
 399              100	if (debug(2)) write(6,*)'gen: final success =',success
 400              	if (debug(2)) write(6,*)'gen: ending'
 401              	return
 402              	end
 403              
 404              !---------------------------------------------------------------------
 405              
 406              	subroutine complete_ev(main,vertex,success)
 407              
 408              	implicit none
 409              	include 'simulate.inc'
 410              
 411              	real*8 a, b, c, r, t, QA, QB, QC, radical
 412              	real*8 p_new_x,p_new_y,new_x_x,new_x_y,new_x_z
 413 gaskelld 1.4 	real*8 targ_new_x,targ_new_y
 414 gaskelld 1.1 	real*8 new_y_x,new_y_y,new_y_z,dummy
 415 gaskelld 1.9 	real*8 targx,targy,targz
 416 gaskelld 1.1 	real*8 px,py,pz,qx,qy,qz
 417              	real*8 oop_x,oop_y
 418              	real*8 krel,krelx,krely,krelz
 419              	real*8 MM
 420              
 421              	real*8 Ehad2,E_rec
 422              	real*8 W2
 423              	real*8 grnd		!random # generator.
 424              
 425              	logical success
 426              	record /event_main/ main
 427              	record /event/	vertex
 428              
 429              !-----------------------------------------------------------------------
 430              ! Calculate everything left in the /event/ structure, given all necessary
 431              !  GENERATION values (some set of xptar,yptar,delta for both arms and p_fermi,
 432              !  and p_fermi, depending on the scattering process: see table in generate.f 
 433              !
 434              ! The SINGLE element of /event/ NOT computed here is sigcc.
 435              !
 436              ! Another small anomaly is that main.jacobian IS computed here.
 437 gaskelld 1.1 ! This is because all the necessary terms have to be
 438              ! computed here anyway to calculate /event/ qties.
 439              !
 440              !-----------------------------------------------------------------------
 441              
 442              ! Initialize
 443              
 444              	success = .false.
 445              	main.jacobian = 1.0
 446              
 447              ! ... unit vector components of outgoing e,p
 448              ! ... z is DOWNSTREAM, x is DOWN and y is LEFT looking downstream.
 449              
 450              	if (debug(4)) write(6,*)'comp_ev: at 1'
 451              	vertex.ue.x = sin(vertex.e.theta)*cos(vertex.e.phi)
 452              	vertex.ue.y = sin(vertex.e.theta)*sin(vertex.e.phi)
 453              	vertex.ue.z = cos(vertex.e.theta)
 454 gaskelld 1.2 	if ((.not.doing_hyd_elast).and.(.not.doing_rho)) then
 455 gaskelld 1.1 	  vertex.up.x = sin(vertex.p.theta)*cos(vertex.p.phi)
 456              	  vertex.up.y = sin(vertex.p.theta)*sin(vertex.p.phi)
 457              	  vertex.up.z = cos(vertex.p.theta)
 458              	endif
 459              	if (debug(4)) write(6,*)'comp_ev: at 2'
 460              
 461              ! First finish off the e side
 462              ! Calculate scattered electron energy for hydrogen/deuterium (e,e'p)
 463              
 464              	if (doing_hyd_elast) then
 465              	  vertex.e.E = vertex.Ein*Mh/(Mh+vertex.Ein*(1.-vertex.ue.z))
 466              
 467              	  if (vertex.e.E.gt.vertex.Ein) return
 468              	  vertex.e.P = vertex.e.E
 469              	  vertex.e.delta = (vertex.e.P - spec.e.P)*100./spec.e.P
 470              	  if (debug(4)) write(6,*)'comp_ev: at 3'
 471              	endif
 472              
 473              ! The q vector
 474              
 475              	if (debug(5)) write(6,*)'comp_ev: Ein,E,uez=',vertex.Ein,vertex.e.E,vertex.ue.z
 476 gaskelld 1.1 
 477              	vertex.nu = vertex.Ein - vertex.e.E
 478              	vertex.Q2 = 2*vertex.Ein*vertex.e.E*(1.-vertex.ue.z)
 479              	vertex.q = sqrt(vertex.Q2 + vertex.nu**2)
 480              	vertex.xbj = vertex.Q2/2./Mp/vertex.nu
 481              
 482              	vertex.uq.x = - vertex.e.P*vertex.ue.x / vertex.q
 483              	vertex.uq.y = - vertex.e.P*vertex.ue.y / vertex.q
 484              	vertex.uq.z =(vertex.Ein - vertex.e.P*vertex.ue.z)/ vertex.q
 485              	if (abs(vertex.uq.x**2+vertex.uq.y**2+vertex.uq.z**2-1).gt.0.01)
 486                   >		stop 'Error in q vector normalization'
 487              	if (debug(4)) write(6,*)'comp_ev: at 5'
 488              
 489              ! Now complete the p side, along with vertex.Em, vertex.Pm, vertex.Mrec.
 490              ! NOTE: Coherent pion/kaon production (bound final state) is treated as
 491              ! hydrogen, but with targ.Mtar_struck=targ.M, targ.Mtar_rec=bound final state.
 492              
 493              	if (doing_hyd_elast) then	!p = q
 494              	  vertex.Em = 0.0
 495              	  vertex.Pm = 0.0
 496              	  vertex.Mrec = 0.0
 497 gaskelld 1.1 	  vertex.up.x = vertex.uq.x
 498              	  vertex.up.y = vertex.uq.y
 499              	  vertex.up.z = vertex.uq.z
 500              	  vertex.p.P = vertex.q
 501              	  vertex.p.theta = acos(vertex.up.z)
 502              	  if (abs(vertex.up.x/sin(vertex.p.theta)).gt.1)
 503                   >	    write(6,*) 'cos(phi)=',vertex.up.x/sin(vertex.p.theta)
 504              	  vertex.p.phi = atan2(vertex.up.y,vertex.up.x)
 505              	  if (vertex.p.phi.lt.0.) vertex.p.phi=vertex.p.phi+2.*pi
 506              	  call spectrometer_angles(spec.p.theta,spec.p.phi,
 507                   &		vertex.p.xptar,vertex.p.yptar,vertex.p.theta,vertex.p.phi)
 508              	  vertex.p.E = sqrt(vertex.p.P**2+Mh2)
 509              	  vertex.p.delta = (vertex.p.P - spec.p.P)*100./spec.p.P
 510              	  if (debug(4)) write(6,*)'comp_ev: at 6'
 511              
 512              	elseif (doing_deuterium) then	!need Ep, and a jacobian.
 513              
 514              	  vertex.Em = targ.Mtar_struck + targ.Mrec - targ.M	!=2.2249 MeV
 515              	  vertex.Mrec = targ.M - targ.Mtar_struck + vertex.Em	!=targ.Mrec
 516              
 517              	  a = -1.*vertex.q*(vertex.uq.x*vertex.up.x+vertex.uq.y*vertex.up.y+vertex.uq.z*vertex.up.z)
 518 gaskelld 1.1 	  b = vertex.q**2
 519              	  c = vertex.nu + targ.M
 520              	  t = c**2 - b + Mh2 - vertex.Mrec**2
 521              	  QA = 4.*(a**2 - c**2)
 522              	  QB = 4.*c*t
 523              	  QC = -4.*a**2*Mh2 - t**2
 524              	  radical = QB**2 - 4.*QA*QC
 525              	  if (radical.lt.0) return
 526              	  vertex.p.E = (-QB - sqrt(radical))/2./QA
 527              
 528              ! Check for two solutions
 529              !	  if ( (-QB + sqrt(radical))/2./QA .gt. Mh ) then
 530              !	    write(6,*) 'There are two valid solutions for the hadron momentum'
 531              !	    write(6,*) 'We always pick one, so this may be a problem, and needs to be checked'
 532              !	    write(6,*) 'solns=',(-QB - sqrt(radical))/2./QA,(-QB + sqrt(radical))/2./QA
 533              !	  endif
 534              
 535              ! Check for two solutions, but only print warning if both are within
 536              ! event generation limits.
 537              	  Ehad2 = (-QB + sqrt(radical))/2./QA
 538              	  if (Ehad2.gt.edge.p.E.min .and. Ehad2.lt.edge.p.E.max .and. ntried.le.5000) then
 539 gaskelld 1.1 	    write(6,*) 'The low-momentum solution to E_hadron is within the spectrometer generation'
 540              	    write(6,*) 'limits.  If it is in the acceptance, Its the end of the world as we know it!!!'
 541              	    write(6,*) 'E_hadron solns=',vertex.p.E,Ehad2
 542              	  endif
 543              
 544              
 545              	  if (vertex.p.E.le.Mh) return
 546              	  vertex.p.P = sqrt(vertex.p.E**2 - Mh2)
 547              	  vertex.p.delta = (vertex.p.P - spec.p.P)*100./spec.p.P
 548              
 549              ! ........ the Jacobian here is |dEp'/dEm|
 550              	  main.jacobian = (t*(c-vertex.p.E) + 2*c*vertex.p.E*(vertex.p.E-c)) /
 551              	1		(2*(a**2-c**2)*vertex.p.E + c*t)
 552              	  main.jacobian = abs(main.jacobian)
 553              
 554              
 555 gaskelld 1.2 	elseif (doing_pion .or. doing_kaon .or. doing_delta) then
 556 gaskelld 1.1 	   
 557 gaskelld 1.2 c	  if (doing_rho) then 
 558              c	     Mh = Mrho
 559 gaskelld 1.1 ! DJG give the rho mass some width (non-relativistic Breit-Wigner)
 560 gaskelld 1.2 c	     Mh = Mh + 0.5*150.2*tan((2.*grnd()-1.)*atan(2.*500./150.2))
 561              c	     Mh2 = Mh*Mh
 562              c	     ntup.rhomass=Mh
 563 gaskelld 1.1 c            write(6,*) 'rho mass is', Mh
 564 gaskelld 1.2 c	  endif
 565 gaskelld 1.1 	      
 566              
 567              
 568              	  vertex.Pm = pfer	!vertex.Em generated at beginning.
 569              	  vertex.Mrec = targ.M - targ.Mtar_struck + vertex.Em
 570              	  a = -1.*vertex.q*(vertex.uq.x*vertex.up.x+vertex.uq.y*vertex.up.y+vertex.uq.z*vertex.up.z)
 571              	  b = vertex.q**2
 572              	  c = vertex.nu + targ.M
 573              
 574              ! For nuclei, correct for fermi motion and missing energy.  Also, check
 575              ! second solution to quadratic equation - there are often two valid
 576              ! solutions, and we always pick the larger one (which is the forward going
 577              ! one in the center of mass) and HOPE that the smaller one is never in the
 578              ! acceptance.  If the low momentum solution IS within the acceptance, we
 579              ! have big problems.
 580              	  if (doing_deutpi.or.doing_hepi.or.doing_deutkaon.or.doing_hekaon.or.
 581 gaskelld 1.2 	1      doing_deutdelta.or.doing_hedelta) then
 582 gaskelld 1.1 	    a = a - abs(pfer)*(pferx*vertex.up.x+pfery*vertex.up.y+pferz*vertex.up.z)
 583              	    b = b + pfer**2 + 2*vertex.q*abs(pfer)*
 584              	1	 (pferx*vertex.uq.x+pfery*vertex.uq.y+pferz*vertex.uq.z)
 585              ***	    c = c - sqrt(vertex.Mrec**2+pfer**2)
 586              	    c = vertex.nu + efer !same as above, but this way if we redefine
 587              				    !'efer', it's the same everywhere.
 588              	  endif
 589              	  t = c**2 - b + Mh2 - targ.Mrec_struck**2
 590              	  QA = 4.*(a**2 - c**2)
 591              	  QB = 4.*c*t
 592              	  QC = -4.*a**2*Mh2 - t**2
 593              
 594              !	write(6,*) '    '
 595              !	write(6,*) '    '
 596              !	write(6,*) 'E0=',vertex.Ein
 597              !	write(6,*) 'P_elec,P_prot=',vertex.e.P/1000.,vertex.p.P/1000.
 598              !	write(6,*) 'thetae,phie=',vertex.e.theta*180./pi,vertex.e.phi*180./pi
 599              !	write(6,*) 'thetap,phip=',vertex.p.theta*180./pi,vertex.p.phi*180./pi
 600              !	write(6,*) 'q,nu,costhetapq=',vertex.q,vertex.nu,(vertex.uq.x*vertex.up.x+vertex.uq.y*vertex.up.y+vertex.uq.z*vertex.up.z)
 601              !	write(6,*) 'a,b,c=',a/1000.,b/1000000.,c/1000.
 602              !	write(6,*) 't=',t/1000000.
 603 gaskelld 1.1 !	write(6,*) 'A,B,C=',QA/1.d6,QB/1.d9,QC/1.d12
 604              !	write(6,*) 'rad=',QB**2 - 4.*QA*QC
 605              !	write(6,*) 'e1,e2=',(-QB-sqrt(radical))/2000./QA,(-QB+sqrt(radical))/2000./QA
 606              !	write(6,*) 'E_pi1,2=',vertex.nu+targ.M-(-QB-sqrt(radical))/2./QA,
 607              !     >				vertex.nu+targ.M-(-QB+sqrt(radical))/2./QA
 608              
 609              
 610              	  radical = QB**2 - 4.*QA*QC
 611              	  if (radical.lt.0) return
 612              	  vertex.p.E = (-QB - sqrt(radical))/2./QA
 613              	  Ehad2 = (-QB + sqrt(radical))/2./QA
 614              
 615 gaskelld 1.2 	  if (doing_delta) then		!choose one of the two solutions.
 616 gaskelld 1.1 !	    write(6,*) ' e1, e2=',vertex.p.E,Ehad2
 617              	    if (grnd().gt.0.5) vertex.p.E = Ehad2
 618              	  else				!verify that 'backwards' soln. is no good.
 619              	    if (Ehad2.gt.edge.p.E.min .and. Ehad2.lt.edge.p.E.max .and. ntried.le.5000) then
 620              	      write(6,*) 'The low-momentum solution to E_hadron is within the spectrometer generation'
 621              	      write(6,*) 'limits.  If it is in the acceptance, Its the end of the world as we know it!!!'
 622              	      write(6,*) 'E_hadron solns=',vertex.p.E,Ehad2
 623              	    endif
 624              	  endif
 625              
 626              	  E_rec=c-vertex.p.E	!energy of recoil system
 627              	  if (E_rec.le.targ.Mrec_struck) return	!non-physical solution
 628              
 629              	  if (vertex.p.E.le.Mh) return
 630              	  vertex.p.P = sqrt(vertex.p.E**2 - Mh2)
 631              	  vertex.p.delta = (vertex.p.P - spec.p.P)*100./spec.p.P
 632              !	write(6,*) 'p,e=',vertex.p.P,vertex.p.E
 633              
 634 gaskelld 1.2 	elseif (doing_rho) then
 635              	   call generate_rho(vertex,success)  !generate rho in 4pi in CM
 636              	   if(.not.success) then
 637              	      return
 638              	   else  ! we have a success, but set back to false for rest of complete_ev
 639              	      success=.false.
 640              	   endif
 641              
 642 gaskelld 1.1 	elseif (doing_phsp) then
 643              
 644              	  vertex.p.P = spec.p.P		!????? single arm phsp??
 645              	  vertex.p.E= sqrt(Mh2+vertex.p.P**2)
 646              	  vertex.p.delta = (vertex.p.P - spec.p.P)*100./spec.p.P
 647              	  if (debug(4)) write(6,*)'comp_ev: at 7.5',Mh2,vertex.p.E
 648              
 649              	endif
 650              
 651              	if (debug(4)) write(6,*)'comp_ev: at 7'
 652              
 653              ! Compute some pion and kaon stuff.  Some of these should be OK for proton too.
 654              
 655 gaskelld 1.2 
 656 gaskelld 1.1 	if (doing_pion .or. doing_kaon .or. doing_delta .or. doing_rho .or. doing_semi) then
 657 gaskelld 1.7 	  W2 = targ.Mtar_struck**2 + 2.*targ.Mtar_struck*vertex.nu - vertex.Q2
 658 gaskelld 1.1 	  main.W = sqrt(abs(W2)) * W2/abs(W2) 
 659              	  main.epsilon=1./(1. + 2.*(1+vertex.nu**2/vertex.Q2)*tan(vertex.e.theta/2.)**2)
 660 gaskelld 1.4 	  main.theta_pq=acos(vertex.up.x*vertex.uq.x+vertex.up.y*vertex.uq.y+vertex.up.z*vertex.uq.z)
 661 gaskelld 1.1 	  main.t = vertex.Q2 - Mh2 + 2*vertex.nu*vertex.p.E -
 662                   >		2*vertex.p.P*vertex.q*cos(main.theta_pq)
 663              	  main.tmin = vertex.Q2 - Mh2 + 2*vertex.p.E*vertex.nu -
 664                   >		2*vertex.p.P*vertex.q
 665              	  main.q2 = vertex.Q2
 666              
 667              ! CALCULATE ANGLE PHI BETWEEN SCATTERING PLANE AND REACTION PLANE.
 668              ! Therefore, define a new system with the z axis parallel to q, and
 669              ! the x axis inside the q-z-plane: z' = q, y' = q X z, x' = y' X q
 670              ! this gives phi the way it is usually defined, i.e. phi=0 for in-plane
 671              ! particles closer to the downstream beamline than q.
 672              ! phi=90 is above the horizontal plane when q points to the right, and
 673              ! below the horizontal plane when q points to the left.
 674              ! Also take into account the different definitions of x, y and z in
 675              ! replay and SIMC:
 676              ! As seen looking downstream:  		replay	SIMC	(old_simc)
 677              !				x	right	down	(left)
 678              !				y	down	left	(up)
 679              !				z	all have z pointing downstream
 680              !
 681              ! SO: x_replay=-y_simc, y_replay=x_simc, z_replay= z_simc
 682 gaskelld 1.1 
 683              	  qx = -vertex.uq.y		!convert to 'replay' coord. system
 684              	  qy =  vertex.uq.x
 685              	  qz =  vertex.uq.z
 686              	  px = -vertex.up.y
 687              	  py =  vertex.up.x
 688              	  pz =  vertex.up.z
 689              
 690              	  dummy=sqrt((qx**2+qy**2)*(qx**2+qy**2+qz**2))
 691              	  new_x_x = -qx*qz/dummy
 692              	  new_x_y = -qy*qz/dummy
 693              	  new_x_z = (qx**2 + qy**2)/dummy
 694              
 695              	  dummy   = sqrt(qx**2 + qy**2)
 696              	  new_y_x =  qy/dummy
 697              	  new_y_y = -qx/dummy
 698              	  new_y_z =  0.0
 699              
 700              	  p_new_x = px*new_x_x + py*new_x_y + pz*new_x_z
 701              	  p_new_y = px*new_y_x + py*new_y_y + pz*new_y_z
 702              
 703 gaskelld 1.1 	  main.phi_pq = atan2(p_new_y,p_new_x)		!atan2(y,x)=atan(y/x)
 704              	  if (main.phi_pq.lt.0.d0) main.phi_pq=main.phi_pq+2.*pi
 705              !	  if (p_new_y.lt.0.) then
 706              !	    main.phi_pq = 2*pi - main.phi_pq
 707              !	  endif
 708              
 709              !	  if ((p_new_x**2+p_new_y**2).eq.0.) then
 710              !	    main.phi_pq = 0.0
 711              !	  else
 712              !	    main.phi_pq = acos(p_new_x/sqrt(p_new_x**2+p_new_y**2))
 713              !	  endif
 714              !	  if (p_new_y.lt.0.) then
 715              !	    main.phi_pq = 2*pi - main.phi_pq
 716              !	  endif
 717              
 718              	  if (debug(2)) then
 719              	    write(6,*)'comp_ev: nu =',vertex.nu
 720              	    write(6,*)'comp_ev: Q2 =',vertex.Q2
 721              	    write(6,*)'comp_ev: theta_e =',vertex.e.theta
 722              	    write(6,*)'comp_ev: epsilon =',main.epsilon
 723              	    write(6,*)'comp_ev: theta_pq =',main.theta_pq
 724 gaskelld 1.1 	    write(6,*)'comp_ev: phi_pq =',main.phi_pq
 725              	    write(6,*)'comp_ev: E_hadron =',vertex.p.E
 726              	  endif
 727 gaskelld 1.4 
 728              
 729 gaskelld 1.6 	  if(using_tgt_field) then   !calculate some azimuthal angles that only make
 730              	                             !sense for polarized target
 731 gaskelld 1.4 ! CALCULATE ANGLE PHI BETWEEN SCATTERING PLANE AND TARGET POLARIZATION.
 732              ! As seen looking downstream:  		replay	SIMC	(old_simc)
 733              !				x	right	down	(left)
 734              !				y	down	left	(up)
 735              !				z	all have z pointing downstream
 736              !
 737              ! SO: x_replay=-y_simc, y_replay=x_simc, z_replay= z_simc
 738              
 739 gaskelld 1.6 	     qx = -vertex.uq.y	!convert to 'replay' coord. system
 740              	     qy =  vertex.uq.x
 741              	     qz =  vertex.uq.z
 742 gaskelld 1.4 
 743              c Target in-plane, so targy=0
 744 gaskelld 1.6 	     targx = -targ_pol*sin(abs(targ_Bangle)) ! replay coordinates
 745              	     targy = 0.0
 746              	     targz = targ_pol*cos(abs(targ_Bangle)) 
 747 gaskelld 1.4 
 748              c Target out of plane, so targx=0
 749 gaskelld 1.6 c       targx = 0.0      ! replay coordinates
 750              c       targy = -targ_pol*sin(abs(targ_Bangle))
 751              c       targz = targ_pol*cos(abs(targ_Bangle)) 
 752              	     
 753              	     dummy=sqrt((qx**2+qy**2)*(qx**2+qy**2+qz**2))
 754              	     new_x_x = -qx*qz/dummy
 755              	     new_x_y = -qy*qz/dummy
 756              	     new_x_z = (qx**2 + qy**2)/dummy
 757              	     
 758              	     dummy   = sqrt(qx**2 + qy**2)
 759              	     new_y_x =  qy/dummy
 760              	     new_y_y = -qx/dummy
 761              	     new_y_z =  0.0
 762 gaskelld 1.4 
 763 gaskelld 1.6 	     p_new_x = targx*new_x_x + targy*new_x_y + targz*new_x_z
 764              	     p_new_y = targx*new_y_x + targy*new_y_y + targz*new_y_z
 765 gaskelld 1.4 
 766 gaskelld 1.6 	     main.phi_targ = atan2(p_new_y,p_new_x) !atan2(y,x)=atan(y/x)
 767              	     if(main.phi_targ.lt.0.) main.phi_targ = 2.*pi+main.phi_targ
 768 gaskelld 1.4 
 769              
 770              ! CALCULATE ANGLE BETA BETWEEN REACTION PLANE AND TRANSVERSE TARGET 
 771              ! POLARIZATION.
 772              ! As seen looking downstream:		replay	SIMC	(old_simc)
 773              !				x	right	down	(left)
 774              !				y	down	left	(up)
 775              !				z	all have z pointing downstream
 776              !
 777              ! SO: x_replay=-y_simc, y_replay=x_simc, z_replay= z_simc
 778              
 779 gaskelld 1.6 	     qx = -vertex.uq.y	!convert to 'replay' coord. system
 780              	     qy =  vertex.uq.x
 781              	     qz =  vertex.uq.z
 782 gaskelld 1.4 
 783              C Taret in plane
 784 gaskelld 1.6 	     targx = -targ_pol*sin(abs(targ_Bangle)) ! 'replay' coordinates
 785              	     targy = 0.0
 786              	     targz = targ_pol*cos(abs(targ_Bangle)) 
 787 gaskelld 1.4 
 788              C Target out of plane
 789              
 790              c	targx = 0.0		! 'replay' coordinates
 791              c	targy = -targ_pol*sin(abs(targ_Bangle))
 792              c	targz = targ_pol*cos(abs(targ_Bangle)) 
 793              
 794 gaskelld 1.6 	     px = -vertex.up.y
 795              	     py =  vertex.up.x
 796              	     pz =  vertex.up.z
 797              	     
 798              	     dummy   = sqrt((qy*pz-qz*py)**2 + (qz*px-qx*pz)**2 + (qx*py-qy*px)**2)
 799              	     new_y_x =  (qy*pz-qz*py)/dummy
 800              	     new_y_y =  (qz*px-qx*pz)/dummy
 801              	     new_y_z =  (qx*py-qy*px)/dummy
 802              	     
 803              	     dummy   = sqrt((new_y_y*qz-new_y_z*qy)**2 + (new_y_z*qx-new_y_x*qz)**2
 804              	1	  + (new_y_x*qy-new_y_y*qx)**2)
 805              
 806              	     new_x_x = (new_y_y*qz - new_y_z*qy)/dummy
 807              	     new_x_y = (new_y_z*qx - new_y_x*qz)/dummy
 808              	     new_x_z = (new_y_x*qy - new_y_y*qx)/dummy
 809              	     
 810 gaskelld 1.4 
 811 gaskelld 1.6 	     targ_new_x = targx*new_x_x + targy*new_x_y + targz*new_x_z
 812              	     targ_new_y = targx*new_y_x + targy*new_y_y + targz*new_y_z
 813 gaskelld 1.4 
 814 gaskelld 1.6 	     main.beta = atan2(targ_new_y,targ_new_x)
 815              	     if(main.beta .lt. 0.) main.beta = 2*pi+main.beta
 816 gaskelld 1.4 
 817              
 818              CDJG Calculate the "Collins" (phi_pq+phi_targ) and "Sivers"(phi_pq-phi_targ) angles
 819 gaskelld 1.6 	     vertex.phi_s = main.phi_pq-main.phi_targ
 820              	     if(vertex.phi_s .lt. 0.) vertex.phi_s = 2*pi+vertex.phi_s
 821 gaskelld 1.4 
 822 gaskelld 1.6 	     vertex.phi_c = main.phi_pq+main.phi_targ
 823              	     if(vertex.phi_c .gt. 2.*pi) vertex.phi_c = vertex.phi_c-2*pi
 824              	     if(vertex.phi_c .lt. 0.0) vertex.phi_c = 2*pi+vertex.phi_c
 825              
 826              	     
 827              	     dummy = sqrt((qx**2+qy**2+qz**2))*sqrt((targx**2+targy**2+targz**2))
 828              	     main.theta_tarq = acos((qx*targx+qy*targy+qz*targz)/dummy)
 829 gaskelld 1.4 
 830 gaskelld 1.6 	  endif !polarized-target specific azimuthal angles
 831 gaskelld 1.4 
 832              
 833 gaskelld 1.1 	endif		!end of pion/kaon specific stuff.
 834              
 835              	if (debug(4)) write(6,*)'comp_ev: at 8'
 836              
 837              ! Compute the Pm vector in in SIMC LAB system, with x down, and y to the left.
 838              ! Computer Parallel, Perpendicular, and Out of Plane componenants.
 839              ! Parallel is component along q_hat.  Out/plane is component along
 840              ! (e_hat) x (q_hat)  (oop_x,oop_y are components of out/plane unit vector)
 841              ! Perp. component is what's left: along (q_hat) x (oop_hat).
 842              ! So looking along q, out of plane is down, perp. is left.
 843              
 844              	vertex.Pmx = vertex.p.P*vertex.up.x - vertex.q*vertex.uq.x
 845              	vertex.Pmy = vertex.p.P*vertex.up.y - vertex.q*vertex.uq.y
 846              	vertex.Pmz = vertex.p.P*vertex.up.z - vertex.q*vertex.uq.z
 847              	vertex.Pmiss = sqrt(vertex.Pmx**2+vertex.Pmy**2+vertex.Pmz**2)
 848              	vertex.Emiss = vertex.nu + targ.M - vertex.p.E
 849              
 850              !STILL NEED SIGN FOR PmPer!!!!!!
 851              
 852              	oop_x = -vertex.uq.y	! oop_x = q_y *(z_hat x y_hat) = q_y *-(x_hat)
 853              	oop_y =  vertex.uq.x	! oop_y = q_x *(z_hat x x_hat) = q_x * (y_hat)
 854 gaskelld 1.1 	vertex.PmPar = (vertex.Pmx*vertex.uq.x + vertex.Pmy*vertex.uq.y + vertex.Pmz*vertex.uq.z)
 855              	vertex.PmOop = (vertex.Pmx*oop_x + vertex.Pmy*oop_y) / sqrt(oop_x**2+oop_y**2)
 856              	vertex.PmPer = sqrt( max(0.d0, vertex.Pm**2 - vertex.PmPar**2 - vertex.PmOop**2 ) )
 857              
 858              	if (debug(4)) write(6,*)'comp_ev: at 9',vertex.Pmx,vertex.Pmy,vertex.Pmz
 859              
 860              ! Calculate Em, Pm, Mrec, Trec for all cases not already done.
 861              ! For doing_heavy, get Mrec from nu+M=Ep+Erec, and Erec**2=Mrec**2+Pm**2
 862              ! For (e,e'pi/K), could go back and determine momentum of recoil struck
 863              ! particle, and get Mrec and Trec seperately for struck nucleon(hyperon)
 864              ! and A-1 system.  For now, just take Trec for the A-1 system, and ignore
 865              ! the recoiling struck nucleon (hyperon), so Trec=0 for hydrogen target.
 866              
 867              	if (doing_hyd_elast) then
 868              	  vertex.Trec = 0.0
 869              	else if (doing_deuterium) then
 870              	  vertex.Pm = vertex.Pmiss
 871              	  vertex.Trec = sqrt(vertex.Mrec**2 + vertex.Pm**2) - vertex.Mrec
 872              	else if (doing_heavy) then
 873              	  vertex.Pm = vertex.Pmiss
 874              	  vertex.Mrec = sqrt(vertex.Emiss**2-vertex.Pmiss**2)
 875 gaskelld 1.1 	  vertex.Em = targ.Mtar_struck + vertex.Mrec - targ.M
 876              	  vertex.Trec = sqrt(vertex.Mrec**2 + vertex.Pm**2) - vertex.Mrec
 877              	else if (doing_hydpi .or. doing_hydkaon .or. doing_hyddelta .or. doing_hydrho) then
 878              	  vertex.Trec = 0.0
 879              	else if (doing_deutpi.or.doing_hepi.or.doing_deutkaon.or.doing_hekaon
 880              	1      .or.doing_deutdelta.or.doing_hedelta.or.doing_deutrho.or.doing_herho) then
 881              	  vertex.Trec = sqrt(vertex.Mrec**2 + vertex.Pm**2) - vertex.Mrec
 882              	else if (doing_semi) then
 883              	   vertex.Pm = vertex.Pmiss
 884              	   vertex.Em = vertex.Emiss
 885              	endif
 886              
 887              	if (debug(5)) write(6,*) 'vertex.Pm,vertex.Trec,vertex.Em',vertex.Pm,vertex.Trec,vertex.Em
 888              	if (debug(4)) write(6,*)'comp_ev: at 10'
 889              
 890              
 891              ! calculate krel for deuteron/heavy pion(kaon).  Deuteron is straightforward.
 892              ! A>2 case is some approximation for 3He (DJG).
 893              
 894              	if (doing_deutpi .or. doing_deutkaon .or. doing_deutdelta .or. doing_deutrho) then
 895              	  if ((vertex.Emiss**2-vertex.Pmiss**2).lt.0) write(6,*) 'BAD MM!!!!! Emiss,Pmiss=',vertex.Emiss, vertex.Pmiss
 896 gaskelld 1.1 	  MM = sqrt(max(0.d0,vertex.Emiss**2-vertex.Pmiss**2))
 897              	  krel = sqrt( max(0.d0,MM**2-4.*targ.Mrec_struck**2) )
 898              	else if (doing_hepi .or. doing_hekaon .or. doing_hedelta .or. doing_herho) then
 899              	  if ((vertex.Emiss**2-vertex.Pmiss**2).lt.0) write(6,*) 'BAD MM!!!!! Emiss,Pmiss=',vertex.Emiss, vertex.Pmiss
 900              	  MM = sqrt(max(0.d0,vertex.Emiss**2-vertex.Pmiss**2))
 901              	  krelx = vertex.Pmx + 1.5*pferx*pfer
 902              	  krely = vertex.Pmy + 1.5*pfery*pfer
 903              	  krelz = vertex.Pmz + 1.5*pferz*pfer
 904              	  krel = sqrt(krelx**2+krely**2+krelz**2)
 905              	  if(vertex.Em.lt.6.0) krel = -krel		!bound state test???
 906              	endif
 907              	ntup.krel = krel
 908              
 909              	if(doing_semi) then
 910              CDJG	   if ((vertex.Emiss**2-vertex.Pmiss**2).lt.0) then
 911              CDJG I should be testing that the missing mass is above two pion
 912              CDJG threshold! Otherwise, it's just exclusive
 913 gaskelld 1.4 c	   if ((vertex.Emiss**2-vertex.Pmiss**2).lt.(Mp+Mpi0)**2) then
 914              	   if (((targ.Mtar_struck+vertex.nu-vertex.p.E)**2-vertex.Pmiss**2).lt.(Mp+Mpi0)**2) then
 915 gaskelld 1.1 	      success=.false.
 916              	      return
 917              	   endif
 918              	endif
 919              
 920              	if(doing_semi) then
 921              	   vertex.zhad = vertex.p.E/vertex.nu
 922 gaskelld 1.4 	   vertex.pt2 = vertex.p.P**2*(1.0-cos(main.theta_pq)**2)
 923 gaskelld 1.1 	   if(vertex.zhad.gt.1.0) then
 924              	      success=.false.
 925              	      return
 926              	   endif
 927              	endif
 928              
 929              
 930              ! Determine PHYSICS scattering angles theta/phi for the two spectrometer
 931              ! vectors, and the Jacobian which we must include in our xsec computation
 932              ! to take into account the fact that we're not generating in the physics
 933              ! solid angle d(omega) but in 'spectrometer angles' yptar,xptar.
 934              ! NOTE: the conversion from spectrometer to physics angles was done when
 935              ! the angles were first generated (except for the proton angle for hydrogen
 936              ! elastic, where it was done earlier in complete_ev).
 937              !
 938              !	call physics_angles(spec.e.theta,spec.e.phi,
 939              !     &		vertex.e.xptar,vertex.e.yptar,vertex.e.theta,vertex.e.phi)
 940              !	call physics_angles(spec.p.theta,spec.p.phi,
 941              !     &		vertex.p.xptar,vertex.p.yptar,vertex.p.theta,vertex.p.phi)
 942              
 943              	r = sqrt(1.+vertex.e.yptar**2+vertex.e.xptar**2) !r=cos(theta-theta0)
 944 gaskelld 1.1 	main.jacobian = main.jacobian / r**3		 !1/cos**3(theta-theta0)
 945              
 946 gaskelld 1.2 C DJG Since we generate rho's in 4pi (in spherical angles) we don't need no
 947              C DJG stinkin' Jacobian!
 948              
 949 gaskelld 1.1 	if (doing_heavy .or. doing_pion .or. doing_kaon .or. 
 950 gaskelld 1.2 	1    doing_delta .or. doing_semi) then
 951 gaskelld 1.1 	  r = sqrt(1.+vertex.p.yptar**2+vertex.p.xptar**2)
 952              	  main.jacobian = main.jacobian / r**3		 !1/cos**3(theta-theta0)
 953              	endif
 954              
 955              	if (debug(4)) write(6,*)'comp_ev: at 11'
 956              
 957              ! The effective target thickness that the scattered particles see, and the
 958              ! resulting energy losses
 959              
 960              	call trip_thru_target (2, main.target.z-targ.zoffset, vertex.e.E,
 961                   >		vertex.e.theta, main.target.Eloss(2), main.target.teff(2),Me,1)
 962              	call trip_thru_target (3, main.target.z-targ.zoffset, vertex.p.E,
 963                   >		vertex.p.theta, main.target.Eloss(3), main.target.teff(3),Mh,1)
 964              	if (.not.using_Eloss) then
 965              	  main.target.Eloss(2) = 0.0
 966              	  main.target.Eloss(3) = 0.0
 967              	endif
 968              	if (debug(4)) write(6,*)'comp_ev: at 12'
 969              
 970              ! Initialize parameters necessary for radiative corrections
 971              
 972 gaskelld 1.1 	call radc_init_ev(main,vertex)
 973              
 974              ! Success code
 975              
 976              	success = .true.
 977              	if(debug(2)) write(6,*)'comp_ev: at end...'
 978              	return
 979              	end
 980              
 981              !---------------------------------------------------------------------
 982              
 983              	subroutine complete_recon_ev(recon,success)
 984              
 985              	implicit none
 986              	include 'simulate.inc'
 987              
 988              	real*8 p_new_x,p_new_y,new_x_x,new_x_y,new_x_z
 989              	real*8 new_y_x,new_y_y,new_y_z,dummy
 990 gaskelld 1.4 	real*8 targ_new_x,targ_new_y
 991 gaskelld 1.1 	real*8 px,py,pz,qx,qy,qz
 992 gaskelld 1.10 	real*8 targx,targy,targz
 993 gaskelld 1.1  	real*8 W2
 994               	real*8 oop_x,oop_y
 995               	real*8 mm,mmA,mm2,mmA2,t
 996               
 997               	logical success
 998               	record /event/	recon
 999               
1000               !-----------------------------------------------------------------------
1001               ! Calculate everything left in the /event/ structure, given
1002               !	recon.Ein, and the following for both recon.e AND recon.p:
1003               ! delta,xptar,yptar, z,P,E,theta,phi (with E,P corrected for eloss, if desired).
1004               !
1005               ! The SINGLE element of /event/ NOT computed here is sigcc (for (e,e'p)).
1006               !
1007               !-----------------------------------------------------------------------
1008               
1009               ! Initialize
1010               
1011               	success = .false.
1012               
1013               	recon.Ein = Ebeam_vertex_ave	!lowered by most probable eloss (init.f)
1014 gaskelld 1.1  
1015               ! ... unit vector components of outgoing e,p
1016               ! ... z is DOWNSTREAM, x is DOWN and y is LEFT looking downstream.
1017               
1018               	if (debug(4)) write(6,*)'comp_rec_ev: at 1'
1019               	recon.ue.x = sin(recon.e.theta)*cos(recon.e.phi)
1020               	recon.ue.y = sin(recon.e.theta)*sin(recon.e.phi)
1021               	recon.ue.z = cos(recon.e.theta)
1022               	recon.up.x = sin(recon.p.theta)*cos(recon.p.phi)
1023               	recon.up.y = sin(recon.p.theta)*sin(recon.p.phi)
1024               	recon.up.z = cos(recon.p.theta)
1025               	if (debug(4)) write(6,*)'comp_rec_ev: at 2'
1026               
1027               ! The q vector
1028               
1029               	if (debug(5)) write(6,*)'comp_rec_ev: Ein,E,uez=',recon.Ein,recon.e.E,recon.ue.z
1030               	recon.nu = recon.Ein - recon.e.E
1031               	recon.Q2 = 2*recon.Ein*recon.e.E*(1-recon.ue.z)
1032               	recon.q	= sqrt(recon.Q2 + recon.nu**2)
1033               	recon.uq.x = - recon.e.P*recon.ue.x / recon.q
1034               	recon.uq.y = - recon.e.P*recon.ue.y / recon.q
1035 gaskelld 1.1  	recon.uq.z =(recon.Ein - recon.e.P*recon.ue.z)/ recon.q
1036 gaskelld 1.8  	if (doing_pion .or. doing_kaon .or. doing_delta .or. doing_rho .or. doing_semi) then
1037               	   W2 = targ.mtar_struck**2 + 2.*targ.mtar_struck*recon.nu - recon.Q2
1038               	else
1039               	   W2 = targ.M**2 + 2.*targ.M*recon.nu - recon.Q2
1040               	endif
1041               
1042               	W2 = mp**2 + 2.*mp*recon.nu - recon.Q2
1043 gaskelld 1.1  	recon.W = sqrt(abs(W2)) * W2/abs(W2) 
1044               	recon.xbj = recon.Q2/2./Mp/recon.nu
1045               	if (debug(4)) write(6,*)'comp_rec_ev: at 5'
1046               
1047               ! Now complete the p side
1048               
1049               	if(doing_phsp)then
1050               	  recon.p.P=spec.p.P
1051               	  recon.p.E=sqrt(Mh2+recon.p.P**2)
1052               	  if (debug(4)) write(6,*)'comp_rec_ev: at 7.5',Mh2,recon.p.E
1053               	endif
1054               
1055               ! Compute some pion/kaon stuff.
1056               
1057               	recon.epsilon=1./(1. + 2.*(1+recon.nu**2/recon.Q2)*tan(recon.e.theta/2.)**2)
1058 gaskelld 1.4  	recon.theta_pq=acos(min(1.0,recon.up.x*recon.uq.x+recon.up.y*recon.uq.y+recon.up.z*recon.uq.z))
1059 gaskelld 1.1  
1060               ! CALCULATE ANGLE PHI BETWEEN SCATTERING PLANE AND REACTION PLANE.
1061               ! Therefore, define a new system with the z axis parallel to q, and
1062               ! the x axis inside the q-z-plane: z' = q, y' = q X z, x' = y' X q
1063               ! this gives phi the way it is usually defined, i.e. phi=0 for in-plane
1064               ! particles closer to the downstream beamline than q.
1065               ! phi=90 is above the horizontal plane when q points to the right, and
1066               ! below the horizontal plane when q points to the left.
1067               ! Also take into account the different definitions of x, y and z in
1068               ! replay and SIMC:
1069               ! As seen looking downstream:		replay	SIMC	(old_simc)
1070               !				x	right	down	(left)
1071               !				y	down	left	(up)
1072               !				z	all have z pointing downstream
1073               !
1074               ! SO: x_replay=-y_simc, y_replay=x_simc, z_replay= z_simc
1075               
1076               	qx = -recon.uq.y		!convert to 'replay' coord. system
1077               	qy =  recon.uq.x
1078               	qz =  recon.uq.z
1079               	px = -recon.up.y
1080 gaskelld 1.1  	py =  recon.up.x
1081               	pz =  recon.up.z
1082               
1083               	dummy=sqrt((qx**2+qy**2)*(qx**2+qy**2+qz**2))
1084               	new_x_x = -qx*qz/dummy
1085               	new_x_y = -qy*qz/dummy
1086               	new_x_z = (qx**2 + qy**2)/dummy
1087               
1088               	dummy   = sqrt(qx**2 + qy**2)
1089               	new_y_x =  qy/dummy
1090               	new_y_y = -qx/dummy
1091               	new_y_z =  0.0
1092               
1093               	p_new_x = px*new_x_x + py*new_x_y + pz*new_x_z
1094               	p_new_y = px*new_y_x + py*new_y_y + pz*new_y_z
1095               
1096               	if ((p_new_x**2+p_new_y**2).eq.0.) then
1097               	  recon.phi_pq = 0.0
1098               	else
1099               	  recon.phi_pq = acos(p_new_x/sqrt(p_new_x**2+p_new_y**2))
1100               	endif
1101 gaskelld 1.1  	if (p_new_y.lt.0.) then
1102               	  recon.phi_pq = 2*pi - recon.phi_pq
1103               	endif
1104               
1105 gaskelld 1.4  
1106 gaskelld 1.6  	if(using_tgt_field) then !calculate polarized-target specific azimuthal angles
1107 gaskelld 1.4  
1108               ! CALCULATE ANGLE PHI BETWEEN SCATTERING PLANE AND TARGET POL.
1109 gaskelld 1.6  ! Take into account the different definitions of x, y and z in
1110 gaskelld 1.4  ! replay and SIMC:
1111               ! As seen looking downstream:		replay	SIMC	(old_simc)
1112               !				x	right	down	(left)
1113               !				y	down	left	(up)
1114               !				z	all have z pointing downstream
1115               !
1116               ! SO: x_replay=-y_simc, y_replay=x_simc, z_replay= z_simc
1117               
1118 gaskelld 1.6  	   qx = -recon.uq.y	!convert to 'replay' coord. system
1119               	   qy =  recon.uq.x
1120               	   qz =  recon.uq.z
1121 gaskelld 1.4  
1122               C In-plane target
1123 gaskelld 1.6  	   targx = -targ_pol*sin(abs(targ_Bangle)) ! 'replay' coordinates
1124               	   targy = 0.0
1125               	   targz = targ_pol*cos(abs(targ_Bangle)) 
1126 gaskelld 1.4  
1127               C out of plane target
1128               c	targx = 0.0       ! 'replay' coordinates
1129               c	targy = -targ_pol*sin(abs(targ_Bangle)) 
1130               c	targz = targ_pol*cos(abs(targ_Bangle)) 
1131               
1132 gaskelld 1.6  	   dummy=sqrt((qx**2+qy**2)*(qx**2+qy**2+qz**2))
1133               	   new_x_x = -qx*qz/dummy
1134               	   new_x_y = -qy*qz/dummy
1135               	   new_x_z = (qx**2 + qy**2)/dummy
1136               
1137               	   dummy   = sqrt(qx**2 + qy**2)
1138               	   new_y_x =  qy/dummy
1139               	   new_y_y = -qx/dummy
1140               	   new_y_z =  0.0
1141               
1142               	   p_new_x = targx*new_x_x + targy*new_x_y + targz*new_x_z
1143               	   p_new_y = targx*new_y_x + targy*new_y_y + targz*new_y_z
1144               	   
1145 gaskelld 1.4  
1146 gaskelld 1.6  	   recon.phi_targ = atan2(p_new_y,p_new_x)
1147               	   if(recon.phi_targ.lt.0.) recon.phi_targ = 2.*pi + recon.phi_targ
1148 gaskelld 1.4  
1149               
1150               ! CALCULATE ANGLE BETA BETWEEN REACTION PLANE AND (TRANSVERSE) TARGET 
1151               ! POLARIZATION.
1152               ! Also take into account the different definitions of x, y and z in
1153               ! replay and SIMC:
1154               ! As seen looking downstream:		replay	SIMC	(old_simc)
1155               !				x	right	down	(left)
1156               !				y	down	left	(up)
1157               !				z	all have z pointing downstream
1158               !
1159               ! SO: x_replay=-y_simc, y_replay=x_simc, z_replay= z_simc
1160               
1161 gaskelld 1.6  	   qx = -recon.uq.y	!convert to 'replay' coord. system
1162               	   qy =  recon.uq.x
1163               	   qz =  recon.uq.z
1164               
1165               	   targx = -targ_pol*sin(abs(targ_Bangle)) ! 'replay' coordinates
1166               	   targy = 0.0
1167               	   targz = targ_pol*cos(abs(targ_Bangle)) 
1168 gaskelld 1.4  
1169               c	targx = 0.0              ! 'replay' coordinates
1170               c	targy = -targ_pol*sin(abs(targ_Bangle))
1171               c	targz = targ_pol*cos(abs(targ_Bangle)) 
1172               
1173               
1174 gaskelld 1.6  	   px = -recon.up.y
1175               	   py =  recon.up.x
1176               	   pz =  recon.up.z
1177 gaskelld 1.4  
1178 gaskelld 1.6  	   dummy   = sqrt((qy*pz-qz*py)**2 + (qz*px-qx*pz)**2 + (qx*py-qy*px)**2)
1179               	   new_y_x =  (qy*pz-qz*py)/dummy
1180               	   new_y_y =  (qz*px-qx*pz)/dummy
1181               	   new_y_z =  (qx*py-qy*px)/dummy
1182 gaskelld 1.4  
1183 gaskelld 1.6  	   dummy   = sqrt((new_y_y*qz-new_y_z*qy)**2 + (new_y_z*qx-new_y_x*qz)**2
1184               	1	+ (new_y_x*qy-new_y_y*qx)**2)
1185 gaskelld 1.4  
1186 gaskelld 1.6  	   new_x_x = (new_y_y*qz - new_y_z*qy)/dummy
1187               	   new_x_y = (new_y_z*qx - new_y_x*qz)/dummy
1188               	   new_x_z = (new_y_x*qy - new_y_y*qx)/dummy
1189 gaskelld 1.4  
1190               
1191 gaskelld 1.6  	   targ_new_x = targx*new_x_x + targy*new_x_y + targz*new_x_z
1192               	   targ_new_y = targx*new_y_x + targy*new_y_y + targz*new_y_z
1193 gaskelld 1.4  
1194 gaskelld 1.6  	   recon.beta = atan2(targ_new_y,targ_new_x)
1195               	   if(recon.beta.lt.0.) recon.beta = 2.*pi + recon.beta
1196 gaskelld 1.4  
1197               CDJG Calculate the "Collins" (phi_pq+phi_targ) and "Sivers"(phi_pq-phi_targ) angles
1198 gaskelld 1.6  	   recon.phi_s = recon.phi_pq-recon.phi_targ
1199               	   if(recon.phi_s .lt. 0.) recon.phi_s = 2*pi+recon.phi_s
1200 gaskelld 1.4  
1201 gaskelld 1.6  	   recon.phi_c = recon.phi_pq+recon.phi_targ
1202               	   if(recon.phi_c .gt. 2.*pi) recon.phi_c = recon.phi_c-2*pi
1203               	   if(recon.phi_c .lt. 0.) recon.phi_c = 2*pi+recon.phi_c
1204               
1205               	   dummy = sqrt((qx**2+qy**2+qz**2))*sqrt((targx**2+targy**2+targz**2))
1206               	   recon.theta_tarq = acos((qx*targx+qy*targy+qz*targz)/dummy)
1207               	endif !polarized-target specific stuff
1208 gaskelld 1.4  
1209 gaskelld 1.1  	if (debug(2)) then
1210               	  write(6,*)'comp_rec_ev: nu =',recon.nu
1211               	  write(6,*)'comp_rec_ev: Q2 =',recon.Q2
1212               	  write(6,*)'comp_rec_ev: theta_e =',recon.e.theta
1213               	  write(6,*)'comp_rec_ev: epsilon =',recon.epsilon
1214               	  write(6,*)'comp_rec_ev: theta_pq =',recon.theta_pq
1215               	  write(6,*)'comp_rec_ev: phi_pq =',recon.phi_pq
1216               	endif
1217               
1218               	if (debug(4)) write(6,*)'comp_rec_ev: at 8'
1219               
1220               ! Compute the Pm vector in in SIMC LAB system, with x down, and y to the left.
1221               ! Computer Parallel, Perpendicular, and Out of Plane componenants.
1222               ! Parallel is component along q_hat.  Out/plane is component along
1223               ! (e_hat) x (q_hat)  (oop_x,oop_y are components of out/plane unit vector)
1224               ! Perp. component is what's left: along (q_hat) x (oop_hat).
1225               ! So looking along q, out of plane is down, perp. is left.
1226               
1227               	recon.Pmx = recon.p.P*recon.up.x - recon.q*recon.uq.x
1228               	recon.Pmy = recon.p.P*recon.up.y - recon.q*recon.uq.y
1229               	recon.Pmz = recon.p.P*recon.up.z - recon.q*recon.uq.z
1230 gaskelld 1.1  	recon.Pm = sqrt(recon.Pmx**2+recon.Pmy**2+recon.Pmz**2)
1231               
1232               !STILL NEED SIGN FOR PmPer!!!!!!
1233               
1234               	oop_x = -recon.uq.y	! oop_x = q_y *(z_hat x y_hat) = q_y *-(x_hat)
1235               	oop_y =  recon.uq.x	! oop_y = q_x *(z_hat x x_hat) = q_x * (y_hat)
1236 gaskelld 1.4  	recon.PmPar = (recon.Pmx*recon.uq.x + recon.Pmy*recon.uq.y + recon.Pmz*recon.uq.z)
1237 gaskelld 1.1  	recon.PmOop = (recon.Pmx*oop_x + recon.Pmy*oop_y) / sqrt(oop_x**2+oop_y**2)
1238 gaskelld 1.4  	recon.PmPer = sqrt( max(0.d0, recon.Pm**2 - recon.PmPar**2 - recon.PmOop**2 ) )
1239 gaskelld 1.1  
1240               	if (doing_pion .or. doing_kaon .or. doing_delta .or. doing_rho .or. doing_semi) then
1241               	  recon.Em = recon.nu + targ.Mtar_struck - recon.p.E
1242                         mm2 = recon.Em**2 - recon.Pm**2
1243                         mm  = sqrt(abs(mm2)) * abs(mm2)/mm2
1244                         mmA2= (recon.nu + targ.M - recon.p.E)**2 - recon.Pm**2
1245                         mmA = sqrt(abs(mmA2)) * abs(mmA2)/mmA2
1246                         t = recon.Q2 - Mh2
1247                    >      + 2*(recon.nu*recon.p.E - recon.p.P*recon.q*cos(recon.theta_pq))
1248               	  ntup.mm = mm
1249               	  ntup.mmA = mmA
1250               	  ntup.t = t
1251               	endif
1252               
1253               	if(doing_semi.or.doing_rho) then
1254               	   recon.zhad = recon.p.E/recon.nu
1255 gaskelld 1.4  	   recon.pt2 = recon.p.P**2*(1.0-cos(recon.theta_pq)**2)
1256 gaskelld 1.1  	endif
1257               
1258               ! Calculate Trec, Em. Trec for (A-1) system (eep), or for struck nucleon (pi/K)
1259               ! Note that there are other ways to calculate 'Em' for the pion/kaon case.
1260               ! This Em for pi/kaon gives roughly E_m + E_rec + T_{A-1}  (I think)
1261               	if (doing_hyd_elast) then
1262               	  recon.Trec = 0.0
1263               	  recon.Em = recon.nu + targ.M - recon.p.E - recon.Trec
1264               	else if (doing_deuterium .or. doing_heavy) then
1265               	  recon.Trec = sqrt(recon.Pm**2+targ.Mrec**2) - targ.Mrec
1266               	  recon.Em = recon.nu + targ.Mtar_struck - recon.p.E - recon.Trec
1267               	else if (doing_pion .or. doing_kaon .or. doing_delta .or. doing_rho) then
1268               	  recon.Em = recon.nu + targ.Mtar_struck - recon.p.E
1269               	endif
1270               
1271               	if (debug(5)) write(6,*) 'recon.Pm,recon.Trec,recon.Em',recon.Pm,recon.Trec,recon.Em
1272               	if (debug(4)) write(6,*)'comp_rec_ev: at 10'
1273               
1274               	success=.true.
1275               	return
1276               	end
1277 gaskelld 1.1  
1278               !------------------------------------------------------------------------
1279               
1280               	subroutine complete_main(force_sigcc,main,vertex,vertex0,recon,success)
1281               
1282               	implicit none
1283               	include 'simulate.inc'
1284               
1285               	integer		i, iPm1
1286               	real*8		a, b, r, frac, peepi, peeK, peedelta, peerho, peepiX
1287 gaskelld 1.4  	real*8		survivalprob, semi_dilution
1288 gaskelld 1.1  	real*8		weight, width, sigep, deForest, tgtweight
1289               	logical		force_sigcc, success
1290               	record /event_main/ main
1291               	record /event/	vertex, vertex0, recon
1292               
1293               !-----------------------------------------------------------------------
1294               ! Calculate everything left in the /main/ structure that hasn't been
1295               ! required up til now. This routine is called ONLY after we
1296               ! know an event IS going to contribute, don't want to be doing these
1297               ! calculations if they're not needed!
1298               !
1299               ! A small anomaly is that sigcc from the /event/ structure is computed
1300               ! here since it's not needed til now, and was not calculated by
1301               ! COMPLETE_ev.
1302               !-----------------------------------------------------------------------
1303               
1304               
1305               ! Initialize success code
1306               
1307               	if (debug(2)) write(6,*)'comp_main:  entering...'
1308               	success = .false.
1309 gaskelld 1.1  
1310               ! The spectral function weighting
1311               
1312               	if (doing_hyd_elast.or.doing_pion.or.doing_kaon.or.doing_delta.or.doing_phsp.or.doing_rho.or.doing_semi) then !no SF.
1313               	  main.SF_weight=1.0
1314               	else if (doing_deuterium .or. doing_heavy) then
1315               	  main.SF_weight = 0.0
1316               	  do i=1,nrhoPm
1317               	    weight = 0.0
1318               
1319               ! ... use linear interpolation to determine rho(pm)
1320               
1321               	    r = (vertex.Pm-Pm_theory(i).min)/Pm_theory(i).bin
1322               	    if (r.ge.0 .and. r.le.Pm_theory(i).n) then
1323               	      iPm1 = nint(r)
1324               	      if (iPm1.eq.0) iPm1 = 1
1325               	      if (iPm1.eq.Pm_theory(i).n) iPm1 = Pm_theory(i).n-1
1326               	      frac = r+0.5-float(iPm1)
1327               	      b = theory(i,iPm1)
1328               	      a = theory(i,iPm1+1)-b
1329               	      weight = a*frac + b
1330 gaskelld 1.1  	    endif
1331               
1332               	    if (doing_heavy) then
1333               
1334               	      width=Emsig_theory(i)/2.0
1335               	      if (vertex.Em.lt.E_Fermi) weight = 0.0
1336               	      weight=weight/pi/Em_int_theory(i) * width/
1337                    >				((vertex.Em-Em_theory(i))**2+width**2)
1338               	    endif
1339               	    main.SF_weight = main.SF_weight+weight*nprot_theory(i)
1340               	  enddo ! <i=1,nrhoPm>
1341               	endif
1342               
1343               ! ... if we have come up with weight<=, quit now (avoid weight<0 in ntuple)
1344               ! ... unless FORCE_SIGCC is on (to get central sigcc).
1345               
1346               	if (debug(5))write(6,*)'comp_main: calculating cross section'
1347               	if (main.SF_weight.le.0 .and. .not.force_sigcc) return
1348               
1349               ! ... Cross section, for BOTH vertex and recon (where possible)
1350               ! ... Note that all of these are cross section per nucleon.  For A(e,e'p)
1351 gaskelld 1.1  ! ... this becomes cross section per nucleus because of the weighting of
1352               ! ... the spectral function.  For pion/kaon production, we explicitly
1353               ! ... apply a weight for the number of nucleons involved (protons for pi+ or Y0,
1354               ! ... neutrons for pi- or Y-) (Y=hyperon)
1355               
1356               	tgtweight = 1.0
1357               
1358               	if (doing_phsp) then
1359               	  main.sigcc = 1.0
1360               	  main.sigcc_recon = 1.0
1361               
1362               	elseif (doing_hyd_elast) then
1363               	  main.sigcc = sigep(vertex)
1364               	  main.sigcc_recon = sigep(recon)
1365               
1366               	elseif (doing_deuterium.or.doing_heavy) then
1367               	  main.sigcc = deForest(vertex)		
1368               	  main.sigcc_recon = deForest(recon)
1369               
1370               	elseif (doing_pion) then
1371               	  main.sigcc = peepi(vertex,main)
1372 gaskelld 1.1  	  main.sigcc_recon = 1.0
1373               	  if (which_pion.eq.1 .or. which_pion.eq.11) then  !OK for coherent???
1374               	    tgtweight = targ.N
1375               	  else
1376               	    tgtweight = targ.Z
1377               	  endif
1378               
1379               	elseif (doing_kaon) then
1380               	  main.sigcc = peeK(vertex,main,survivalprob)
1381               	  main.sigcc_recon = 1.0
1382               	  if (which_kaon.eq.2 .or. which_kaon.eq.12) then  !OK for coherent???
1383               	    tgtweight = targ.N
1384               	  else
1385               	    tgtweight = targ.Z
1386               	  endif
1387               
1388               	elseif (doing_delta) then
1389               	  main.sigcc = peedelta(vertex,main)	!Need new xsec model.
1390               	  main.sigcc_recon = 1.0
1391               
1392               	elseif (doing_rho) then
1393 gaskelld 1.1  	  main.sigcc = peerho(vertex,main)
1394               	  main.sigcc_recon = 1.0
1395               
1396               	elseif (doing_semi) then
1397               	  main.sigcc = peepiX(vertex,vertex0,main,survivalprob,.FALSE.)
1398               	  main.sigcc_recon = 1.0
1399               	  main.sigcent = peepiX(vertex,vertex0,main,survivalprob,.TRUE.)
1400 gaskelld 1.4  	  ntup.dilu = semi_dilution(vertex,main) 
1401 gaskelld 1.1  
1402               	else
1403               	  main.sigcc = 1.0
1404               	  main.sigcc_recon = 1.0
1405               	endif
1406               
1407               	if (debug(3)) then
1408               	  write(6,*)'======================================'
1409               	  write(6,*)'complete_main:'
1410               	  write(6,*)'theta_e =',vertex.e.theta
1411               	  write(6,*)'q mag =',vertex.q
1412               	  write(6,*)'nu =',vertex.nu
1413               	  write(6,*)'Q2 =',vertex.Q2/1000000.
1414               	  write(6,*)'Ein =',vertex.Ein
1415               	  write(6,*)'hadron mom =',vertex.p.P
1416               	  write(6,*)'e mom =',vertex.e.P
1417               	  write(6,*)'mass =',Mh
1418               	  write(6,*)'epsilon =',main.epsilon
1419               	  write(6,*)'phi_pq =',main.phi_pq
1420               	  write(6,*)'theta_pq =',main.theta_pq
1421               	  write(6,*)'======================================'
1422 gaskelld 1.1  	endif
1423               
1424               ! The total contributing weight from this event -- this weight is
1425               ! proportional to # experimental counts represented by the event.
1426               ! Apply survival probability to kaons if we're not modeling decay.
1427               
1428               	main.weight = main.SF_weight*main.jacobian*main.gen_weight*main.sigcc
1429               	main.weight = main.weight * tgtweight	!correct for #/nucleons involved
1430               	if ((doing_kaon.or.doing_semika) .and. .not.doing_decay) 
1431                    >		main.weight = main.weight*survivalprob
1432               	if (debug(5))write(6,*) 'gen_weight = ',main.gen_weight,
1433                    >		main.jacobian,main.sigcc
1434               
1435               	success = .true.
1436               
1437               	if (debug(2)) write(6,*)'comp_main: ending, success =',success
1438               	return
1439               	end
1440               
1441               
1442               	subroutine physics_angles(theta0,phi0,dx,dy,theta,phi)
1443 gaskelld 1.1  
1444               !Generate physics angles in lab frame.  Theta is angle from beamline.
1445               !phi is projection on x-y plane (so phi=0 is down, sos=pi/2, hms=3*pi/2.
1446               !
1447               !theta=acos( (cos(theta0)-dy*sin(theta0)*sin(phi0))/ sqrt(1+dx**2+dy**2) )
1448               !phi=atan( (dy*cos(theta0)+sin(theta0)*sin(phi0)) / (sin(theta0)*cos(phi0)+dx) )
1449               !
1450               ! Note that these formulae assume phi0=pi/2 or 3*pi/2 (thus the sin(phi0)
1451               ! gives a -/+ sign for the HMS/SOS).  Thus, we set the cos(phi0) term to zero.
1452               
1453               	real*8 dx,dy		!dx/dy (xptar/yptar) for event.
1454               	real*8 theta0,phi0	!central physics angles of spectrometer.
1455               	real*8 theta,phi	!physics angles for event.
1456               	real*8 r,sinth,costh,sinph,cosph	!intermediate variables.
1457               	real*8 tmp
1458               
1459               	include 'constants.inc'
1460               
1461               	costh = cos(theta0)
1462               	sinth = sin(theta0)
1463               	sinph = sin(phi0)
1464 gaskelld 1.1  	cosph = cos(phi0)
1465               	r = sqrt( 1. + dx**2 + dy**2 )
1466               
1467               	if (abs(cosph).gt.0.0001) then	!phi not at +/- pi/2
1468               	  write(6,*) 'theta,phi will be incorrect if phi0 <> pi/2 or 3*pi/2'
1469               	  write(6,*) 'phi0=',phi0,'=',phi0*180/pi,'degrees'
1470               	endif
1471               
1472               	tmp=(costh - dy*sinth*sinph) / r
1473               	if (abs(tmp).gt.1) write(6,*) 'tmp=',tmp
1474               	theta = acos( (costh - dy*sinth*sinph) / r )
1475               	if (dx.ne.0.0) then
1476               	  phi = atan( (dy*costh + sinth*sinph) / dx )	!gives -90 to 90 deg.
1477               	  if (phi.le.0) phi=phi+pi			!make 0 to 180 deg.
1478               	  if (sinph.lt.0.) phi=phi+pi		!add pi to phi for HMS
1479               	else
1480               	  phi = phi0
1481               	endif
1482               
1483               	return
1484               	end
1485 gaskelld 1.1  
1486               
1487               
1488               	subroutine spectrometer_angles(theta0,phi0,dx,dy,theta,phi)
1489               
1490               !Generate spectrometer angles from physics angles in lab frame.
1491               !Theta is angle from beamline.
1492               !phi is projection on x-y plane (so phi=0 is down, sos=pi/2, hms=3*pi/2.
1493               
1494               	real*8 dx,dy		!dx/dy (xptar/yptar) for event.
1495               	real*8 theta0,phi0	!central physics angles of spectrometer.
1496               	real*8 theta,phi	!physics angles for event.
1497               	real*8 x,y,z				!intermediate variables.
1498               	real*8 x0,y0,z0				!intermediate variables.
1499               	real*8 cos_dtheta,y_event
1500               
1501               	include 'constants.inc'
1502               
1503               	x = sin(theta)*cos(phi)
1504               	y = sin(theta)*sin(phi)
1505               	z = cos(theta)
1506 gaskelld 1.1  	x0 = sin(theta0)*cos(phi0)
1507               	y0 = sin(theta0)*sin(phi0)
1508               	z0 = cos(theta0)
1509               
1510               	cos_dtheta = x*x0 + y*y0 + z*z0
1511               	dx = x / cos_dtheta
1512               	dy = sqrt(1/cos_dtheta**2-1.-dx**2)
1513               
1514               	y_event = y/cos_dtheta	!projected to plane perp. to spectrometer.
1515               	if (y_event .lt. y0) dy = -dy
1516               
1517               	return
1518               	end

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