StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StTrgMaker.cxx
1 /***************************************************************************
2  *
3  * $Id: StTrgMaker.cxx,v 1.11 2007/05/29 23:11:44 fine Exp $
4  *
5  * Author: Herbert Ward April 2001
6  ***************************************************************************
7  *
8  * Description: Accepts a .event.root file as input, outputs a .out
9  * containing the CTB slat ADCs and also information
10  * about which slats were hit by tracks. The .out file
11  * is ASCII; you can parse it
12  * yourself or use an API from Herb Ward
13  * for reading it.
14  *
15  ***************************************************************************
16  *
17  * $Log: StTrgMaker.cxx,v $
18  * Revision 1.11 2007/05/29 23:11:44 fine
19  * Introduce logger-based output
20  *
21  * Revision 1.10 2004/05/03 23:30:28 perev
22  * Possible non init WarnOff
23  *
24  * Revision 1.9 2003/09/02 17:59:14 perev
25  * gcc 3.2 updates + WarnOff
26  *
27  * Revision 1.8 2002/03/25 21:34:18 ward
28  * Three bug fixes.
29  *
30  * Revision 1.7 2002/03/06 18:16:49 ward
31  * Filter out tracks which begin beyone the MWC. Remove dead weight from trigCtb.C.
32  *
33  * Revision 1.6 2001/12/25 20:01:19 ward
34  * Outputs error (closeness to edge) of track extension subsector selection.
35  *
36  * Revision 1.5 2001/12/22 20:10:04 ward
37  * New code for MWC.
38  *
39  * Revision 1.4 2001/07/27 17:40:18 ward
40  * Handles reversed B field, also has code for chking triggerWord.
41  *
42  * Revision 1.3 2001/07/22 23:00:27 ward
43  * Added diagnostics to output file. Also doc improvements.
44  *
45  * Revision 1.2 2001/07/17 19:14:38 ward
46  * Avoid edges of CTB slats and other wild situations.
47  *
48  * Revision 1.1 2001/04/23 20:00:27 ward
49  * Outputs info for CTB calib: slat ADCs and TPC track extensions.
50  *
51  *
52  **************************************************************************/
53 
54 #include <assert.h>
55 #include "StTrgMaker.h"
56 #include "StEventTypes.h"
57 #include "TNtuple.h"
58 #include "TFile.h"
59 #include "StMessMgr.h"
60 #define OO fprintf(oo,
61 
62 #define RPD 0.0174533 // Radians per degree.
63 #define INNERRADIUS 215.75 /* centimeters, inner slats */
64 #define OUTERRADIUS 212.58 /* centimeters, outer slats */
65 #define INNER_OUTER_ZBOUNDARY 112.0
66 #define DEAD_ZONE 12.0
67 #define OUTER_ZBOUNDARY 231.1
68 #define PI 3.1415926
69 #define ZCUT 50.0 // cm
70 #define MAXTRKS 500000
71 
72 ClassImp(StTrgMaker)
73 
74 StTrgMaker::StTrgMaker(const Char_t *name) : StMaker(name) {
75  mEventCounter = 0;
76 }
77 StTrgMaker::~StTrgMaker() {
78  /* noop */
79 }
80 Int_t StTrgMaker::Init() {
81  FILE *ff;
82  ff=fopen("StTrgMaker.out","w");
83  assert(ff); fclose(ff);
84  return StMaker::Init();
85 }
86 void StTrgMaker::Clear(Option_t *opt) {
88 }
90  return kStOK;
91 }
93  FILE *out; double curvature,phi0,psi,r0,tanl,z0; long q; int adc,i,j;
94  out=fopen("StTrgMaker.out","a"); assert(out);
95  mEventCounter++; // increase counter
96 
97  StEvent* event;
98  event = (StEvent *) GetInputDS("StEvent");
99  if (!event) { fclose(out); return kStOK; }
100  if(!event->primaryVertex()) {
101  fprintf(out,"# Event %3d: has no primary vertex\n",mEventCounter);
102  fclose(out); return kStOK;
103  }
104  StThreeVectorD vertexPos(0,0,0);
105  vertexPos=event->primaryVertex()->position();
106  LOG_INFO << Form("Event %3d: the position of the primary vertex is (%g %g %g)",
107  mEventCounter,vertexPos.x(), vertexPos.y(), vertexPos.z()) << endm;
108  if(vertexPos.z()>50.0||vertexPos.z()<-50.0) {
109  fprintf(out,"# Event %3d: the primary vertex is out of z-range: %6.1f.\n",mEventCounter,vertexPos.z());
110  fclose(out);
111  return kStOK;
112  }
113 
114  StEventSummary *summary = event->summary(); // This should be in StTrgMaker::Init(). It wastes time
115  assert(summary); // every event. But no
116  mMagneticField = summary->magneticField(); // big deal.
117 
118  StTriggerDetectorCollection *theTriggers = event->triggerDetectorCollection();
119  if (!theTriggers) {
120  fprintf(out,"# Event %3d: triggerDetectorCollection is missing\n",mEventCounter);
121  fclose(out);
122  return kStOK;
123  }
124  StL0Trigger *l0Trigger = event->l0Trigger();
125  if(!l0Trigger) {
126  fprintf(out,"# Event %3d: l0Trigger is missing\n",mEventCounter);
127  fclose(out);
128  return kStOK;
129  }
130  fprintf(out,"# Event %3d, triggerWord = 0x%04x\n",mEventCounter,l0Trigger->triggerWord());
131 
132  StCtbTriggerDetector &theCtb = theTriggers->ctb();
133 
134  fprintf(out,"e %d\n",mEventCounter);
135  for(unsigned int islat=0; islat<theCtb.numberOfSlats(); islat++)
136  for(unsigned int itray=0; itray<theCtb.numberOfTrays(); itray++) {
137  adc=(int)(theCtb.mips(itray, islat, 0)+0.5);
138  if(adc) fprintf(out,"a%d:%d %d\n",itray+1,islat+1,adc);
139  }
140 
141  // Output the MWC and ZDC data.
142  StZdcTriggerDetector &theZdc = theTriggers->zdc();
143  if(theZdc.adcSum()>0) fprintf(out,"z%g\n",theZdc.adcSum());
144  StMwcTriggerDetector &theMwc = theTriggers->mwc();
145  for(i=0;i<24;i++) for(j=0;j<4;j++) fprintf(out,"m%02d:%d %g\n",i+1,j+1,theMwc.mips(i,j,0));
146 
147  // Get the tracks and use them.
149  StSPtrVecTrackNode& nodes = event->trackNodes();
150  StThreeVectorF o,momentum;
151  for(unsigned int j=0;j<nodes.size();j++) {
152  track = nodes[j]->track(global);
153  if(accept(track)) {
154  geo=track->geometry();
155  o=geo->origin();
156  momentum=geo->momentum();
157  fprintf(out,"P%g\n",momentum.magnitude());
158  fprintf(out,"D%g\n",0.0); // This is supposed to be de/dx, I'm putting in 0.0 as a quick fix.
159  q=geo->charge();
160  curvature=geo->curvature();
161  phi0=o.phi()*180/3.1415926; // StEvent is in radians, contrary to STAR convention.
162  psi=geo->psi()*180/3.1415926; // StEvent is in radians, contrary to STAR convention.
163  r0=::sqrt(o.x()*o.x()+o.y()*o.y());
164  tanl=tan(geo->dipAngle());
165  z0=o.z();
166  // fprintf(out,"%2d %2d %g %g %g %g %g %g\n",++BBB,q,curvature,phi0,psi,r0,tanl,z0);
167  DoOneTrackCtb(out,q,curvature,phi0,psi,r0,tanl,z0);
168  DoOneTrackMwc(out,q,curvature,phi0,psi,r0,tanl,z0);
169  }
170  }
171 
172  fclose(out); return kStOK;
173 }
174 bool StTrgMaker::accept(StTrack* track) {
175  if(track) assert(track->flag()!=0); // Lee Barnby, starsoft mail Mar 22 2002.
176  return track && track->flag() > 0;
177 }
178 void StTrgMaker::FindIntersectionOfTwoCircles(
179  double center1x,double center1y,double radius1, /* input (circle 1) */
180  double center2x,double center2y,double radius2, /* input (circle 2) */
181  int *numIntersectionPoints, /* output */
182  double *intersection1x,double *intersection1y, /* output */
183  double *intersection2x,double *intersection2y /* output */
184 ) {
185 
186  double tempx,tempy,radicand,transX,transY,angle;
187 
188  if(center1x==center2x&&center1y==center2y&&radius1==radius2) { *numIntersectionPoints=0; return; }
189  /* PP"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n"); */
190  /* Do a translation: put circle1's center at the origin and circle2's center on the x-axis. */
191  transX=-center1x; transY=-center1y; /* Translation necessary to put center of circle 1 at origin. */
192  center1x=0; center1y=0; center2x+=transX; center2y+=transY; /* Do translation. */
193  angle=-atan2(center2y,center2x); /* Rotation necessary to put center of circle 2 on x-axis. */
194  center2x=::sqrt(center2x*center2x+center2y*center2y); center2y=0; /* Do rotation. */
195 
196  /* The two intersection points have the same x coordinate. A little simple algebra gives */
197  /* this x value and also the two y values (by symmetry, y1 = -y2). */
198  *intersection1x=(radius1*radius1-radius2*radius2+center2x*center2x)/(2*center2x);
199  /* PP"BBB intersection1x = %g\n",*intersection1x); */
200  *intersection2x=*intersection1x;
201  radicand=radius1*radius1-(*intersection1x)*(*intersection1x);
202  /* PP"BBB radicand = %g\n",radicand); */
203 
204  if(radicand< 0) *numIntersectionPoints=0;
205  else if(radicand==0) *numIntersectionPoints=1;
206  else *numIntersectionPoints=2;
207 
208  /* PP"BBB nip = %d\n",*numIntersectionPoints); */
209 
210  if(*numIntersectionPoints>0) {
211  *intersection1y=+::sqrt(radicand);
212  *intersection2y=-::sqrt(radicand);
213 
214  /* Now rotate and tranlate the two intersection points back to the original frame. */
215  /* PP"BBB angle = %g degrees\n",angle*180/PI); */
216  /* PP"BBB trans = %g %g\n",transX,transY); */
217  tempx=cos(-angle)*(*intersection1x)-sin(-angle)*(*intersection1y);
218  tempy=sin(-angle)*(*intersection1x)+cos(-angle)*(*intersection1y);
219  tempx-=transX; tempy-=transY;
220  *intersection1x=tempx; *intersection1y=tempy;
221  tempx=cos(-angle)*(*intersection2x)-sin(-angle)*(*intersection2y);
222  tempy=sin(-angle)*(*intersection2x)+cos(-angle)*(*intersection2y);
223  tempx-=transX; tempy-=transY;
224  *intersection2x=tempx; *intersection2y=tempy;
225  } else {
226  *intersection1x=0; *intersection1y=0; *intersection2x=0; *intersection2y=0;
227  }
228 
229 }
230 void StTrgMaker::CalcCenterOfCircleDefinedByTrack(int q,double radius,double psi,double r0,
231  double phi0,double *xcenter,double *ycenter) {
232  double angleOffset,xstart,ystart;
233  xstart=r0*cos(RPD*phi0);
234  ystart=r0*sin(RPD*phi0);
235  if(mMagneticField>0) { if(q>=0) angleOffset=-90; else angleOffset= 90; }
236  else { if(q>=0) angleOffset= 90; else angleOffset=-90; }
237  *xcenter=xstart+radius*cos(RPD*(psi+angleOffset));
238  *ycenter=ystart+radius*sin(RPD*(psi+angleOffset));
239 }
240 // bbb You might want to assert a positive mag field in DoOneTrackMwc.
241 #define MWC_LOCATION 200 // z location, centimeters bbb
242 // comment 62a: This line has || instead of &&.
243 void StTrgMaker::Location2Sector(double tanl,double xAtMwc,
244  double yAtMwc,int *sect,int *subsect,double *errDistPhi,double *errDistRad) {
245  double errPhi,angleDiff,rad,ang,mid,rmid,radDiff;
246 
247  *subsect=-123; *sect=-123;
248 
249  ang=atan2(yAtMwc,xAtMwc)/RPD;
250  while(ang<-180) ang+=360;
251  while(ang> 180) ang-=360;
252  if( -15<=ang && ang<= 15) { *sect= 3; mid= 0; }
253  else if( 15<=ang && ang<= 45) { *sect= 2; mid= 30; }
254  else if( 45<=ang && ang<= 75) { *sect= 1; mid= 60; }
255  else if( 75<=ang && ang<= 105) { *sect=12; mid= 90; }
256  else if( 105<=ang && ang<= 135) { *sect=11; mid= 120; }
257  else if( 135<=ang && ang<= 165) { *sect=10; mid= 150; }
258  else if( 165<=ang || ang<=-165) { *sect= 9; if(ang>0) mid=180; else mid=-180; } // See comment 62a
259  else if(-165<=ang && ang<=-135) { *sect= 8; mid=-150; }
260  else if(-135<=ang && ang<=-105) { *sect= 7; mid=-120; }
261  else if(-105<=ang && ang<= -75) { *sect= 6; mid= -90; }
262  else if( -75<=ang && ang<= -45) { *sect= 5; mid= -60; }
263  else if( -45<=ang && ang<= -15) { *sect= 4; mid= -30; }
264  else assert(0);
265 
266  rad=::sqrt(xAtMwc*xAtMwc+yAtMwc*yAtMwc); rmid = 0.;
267  if(rad >= 53.000 && rad < 85.000 ) { *subsect=1; rmid=( 53.000+ 85.000)/2.0; }
268  if(rad >= 85.000 && rad < 117.000 ) { *subsect=2; rmid=( 85.000+117.000)/2.0; }
269  if(rad >= 125.395 && rad < 157.395 ) { *subsect=3; rmid=(125.395+157.395)/2.0; }
270  if(rad >= 157.395 && rad < 189.395 ) { *subsect=4; rmid=(157.395+189.395)/2.0; }
271  assert(rmid>0);
272 
273  if(*subsect>0&&*sect>0) {
274 
275  angleDiff=ang-mid;
276  if(angleDiff>0) errPhi=15-angleDiff; else errPhi=15+angleDiff; // Width of subsectors = 30 degrees
277  *errDistPhi=RPD*errPhi*rad;
278  assert(*errDistPhi>0.0);
279 
280  radDiff=rad-rmid;
281  if(radDiff>0) *errDistRad=16-radDiff; else *errDistRad=16+radDiff; // Radial len of subsectors = 32cm
282  assert(*errDistRad>0.0);
283 
284  } else {
285  *errDistPhi=-1.0;
286  *errDistRad=-1.0;
287  }
288 
289  if(*sect>0&&*subsect>0&&tanl<0) {
290  if(*sect==12) *sect=24; else *sect=24-*sect;
291  }
292  assert(*sect<=24);
293  assert(*subsect<=4);
294 }
295 void StTrgMaker::DoOneTrackMwc(FILE *oo,long q,double curvatureCircle2,double phi0Circle1, // www
296  double psi,double r0Circle1,double tanl,double z0) {
297  // There are two trigonometric circles here.
298  // One centered at (0,0) uses variables r0Circle1 and phi0Circle1.
299  // Another, centered at (xCenterCircle2,yCenterCircle2), uses variables
300  // radiusCircle2, radiansAtStartCircle2,radiansInFlightCircle2, and radiansAtMwcCircle2.
301  int sector,subsector;
302  double xstart,ystart,xCenterCircle2,yCenterCircle2,dist,radiusCircle2,radiansInFlightCircle2;
303  double xAtMwc,yAtMwc,radiansAtStartCircle2,radiansAtMwcCircle2,errDistPhi,errDistRad;
304  assert(curvatureCircle2>=0); // Not physical, just a convention for the code below.
305  if(tanl>0) {
306  dist=MWC_LOCATION-z0;
307  if(dist<0) { fprintf(oo,"M-1:-1\nR999\nN999\n"); return; } // ignore trk which begins beyond the MWC
308  } else {
309  dist=-MWC_LOCATION-z0;
310  if(dist>0) { fprintf(oo,"M-1:-1\nR999\nN999\n"); return; } // ignore trk which begins beyond the MWC
311  }
312  radiusCircle2=1/curvatureCircle2;
313  radiansInFlightCircle2=dist/(radiusCircle2*tanl);
314  // printf("BBB z0=%7.1f dist=%7.1f radiusCircle2=%5.1f tanl=%5.2f q=%2d, radiansInFlightCircle2 = %6.2f\n",
315  // z0,dist,radiusCircle2,tanl,q,radiansInFlightCircle2);
316  assert(radiansInFlightCircle2>=0); // May become neg below.
317  if(radiansInFlightCircle2>PI) { fprintf(oo,"M-1:-1\nR999\nN999\n"); return; } // don't extend so shallow a trk
318  if(q>0) radiansInFlightCircle2*=-1;
319  CalcCenterOfCircleDefinedByTrack(q,radiusCircle2,psi,r0Circle1,phi0Circle1,&xCenterCircle2,&yCenterCircle2);
320  xstart=r0Circle1*cos(RPD*phi0Circle1); ystart=r0Circle1*sin(RPD*phi0Circle1);
321  radiansAtStartCircle2=atan2(ystart-yCenterCircle2,xstart-xCenterCircle2);
322  radiansAtMwcCircle2=radiansAtStartCircle2+radiansInFlightCircle2;
323  xAtMwc=xCenterCircle2+radiusCircle2*cos(radiansAtMwcCircle2);
324  yAtMwc=yCenterCircle2+radiusCircle2*sin(radiansAtMwcCircle2);
325  Location2Sector(tanl,xAtMwc,yAtMwc,&sector,&subsector,&errDistPhi,&errDistRad);
326  OO"M%d:%d\n",sector,subsector);
327  OO"R%4.2f\n",errDistRad); // dist from edge of MWC subsector in radial direction, cm
328  OO"N%4.2f\n",errDistPhi); // dist from edge of MWC subsector in phi direction, cm
329 }
330 void StTrgMaker::DoOneTrackCtb(FILE *oo,long q,double curvature,double phi0,
331  double psi,double r0,double tanl,double z0) {
332  double xcenter,ycenter,radius;
333  char inner,noIntersectionInner=0,noIntersectionOuter=0; /* These are boolean values (T/F). */
334  int traynumber,count=0,numberIntersectionPointsInner,numberIntersectionPointsOuter;
335  double xintersection,yintersection,zintersection,angle=0;
336  double intersectionInner1X,intersectionInner1Y,intersectionInner2X,intersectionInner2Y;
337  double intersectionOuter1X,intersectionOuter1Y,intersectionOuter2X,intersectionOuter2Y;
338  double xUnitVector,yUnitVector,xstart,ystart,dotProduct1,dotProduct2;
339  double innerIntersectionX=0,innerIntersectionY=0;
340  double outerIntersectionX=0,outerIntersectionY=0;
341 
342  /* Calculate the radius and center (x,y) of the circle. */
343  radius=1/curvature; CalcCenterOfCircleDefinedByTrack(q,radius,psi,r0,phi0,&xcenter,&ycenter);
344 
345  /* Find 2 intersection points (of the circle) with the inner slats, and 2 with the outer slats. */
346  FindIntersectionOfTwoCircles(0.0,0.0,INNERRADIUS,xcenter,ycenter,radius,&numberIntersectionPointsInner,
347  &intersectionInner1X,&intersectionInner1Y,
348  &intersectionInner2X,&intersectionInner2Y);
349  FindIntersectionOfTwoCircles(0.0,0.0,OUTERRADIUS,xcenter,ycenter,radius,&numberIntersectionPointsOuter,
350  &intersectionOuter1X,&intersectionOuter1Y,
351  &intersectionOuter2X,&intersectionOuter2Y);
352 
353  /*
354  PP"r0,phi0,psi %g %g %g\n",r0,phi0,psi);
355  PP"xcenter,ycenter,radius %g %g %g\n",xcenter,ycenter,radius);
356  PP"# i pts %d %d\n",numberIntersectionPointsInner,numberIntersectionPointsOuter);
357  */
358  /* Eliminate one of each pair: the one which represents the second (chronologically) intersection. */
359  /* Do this using direction cosines calculated from vector dot products. */
360  /* It is, of course, not necessary if the "pair" is not a pair */
361  /* (numberIntersectionPointsInner<2 or numberIntersectionPointsOuter<2). */
362  xUnitVector=cos(RPD*psi); yUnitVector=sin(RPD*psi); /* Direction of path at beginning of track. */
363  xstart=r0*cos(RPD*phi0); ystart=r0*sin(RPD*phi0); /* This is (x,y) at beginning of track. */
364  /* Do the points for the inner slats first. */
365  if(numberIntersectionPointsInner==2) {
366  dotProduct1=xUnitVector*(intersectionInner1X-xstart)+yUnitVector*(intersectionInner1Y-ystart);
367  dotProduct1/=::sqrt((intersectionInner1X-xstart)*(intersectionInner1X-xstart)+
368  (intersectionInner1Y-ystart)*(intersectionInner1Y-ystart)); /* Normalize. */
369  dotProduct2=xUnitVector*(intersectionInner2X-xstart)+yUnitVector*(intersectionInner2Y-ystart);
370  dotProduct2/=::sqrt((intersectionInner2X-xstart)*(intersectionInner2X-xstart)+
371  (intersectionInner2Y-ystart)*(intersectionInner2Y-ystart)); /* Normalize. */
372  if(dotProduct1>=dotProduct2) {
373  innerIntersectionX=intersectionInner1X; innerIntersectionY=intersectionInner1Y;
374  } else {
375  innerIntersectionX=intersectionInner2X; innerIntersectionY=intersectionInner2Y;
376  }
377  } else if(numberIntersectionPointsInner==1) {
378  innerIntersectionX=intersectionInner1X; innerIntersectionY=intersectionInner1Y;
379  } else if(numberIntersectionPointsInner==0) {
380  noIntersectionInner=7;
381  } else assert(0);
382  /* Now do the points for the outer slats. */
383  if(numberIntersectionPointsOuter==2) {
384  dotProduct1=xUnitVector*(intersectionOuter1X-xstart)+yUnitVector*(intersectionOuter1Y-ystart);
385  dotProduct1/=::sqrt((intersectionOuter1X-xstart)*(intersectionOuter1X-xstart)+
386  (intersectionOuter1Y-ystart)*(intersectionOuter1Y-ystart)); /* Normalize. */
387  dotProduct2=xUnitVector*(intersectionOuter2X-xstart)+yUnitVector*(intersectionOuter2Y-ystart);
388  dotProduct2/=::sqrt((intersectionOuter2X-xstart)*(intersectionOuter2X-xstart)+
389  (intersectionOuter2Y-ystart)*(intersectionOuter2Y-ystart)); /* Normalize. */
390  if(dotProduct1>=dotProduct2) {
391  outerIntersectionX=intersectionOuter1X; outerIntersectionY=intersectionOuter1Y;
392  } else {
393  outerIntersectionX=intersectionOuter2X; outerIntersectionY=intersectionOuter2Y;
394  }
395  } else if(numberIntersectionPointsOuter==1) {
396  outerIntersectionX=intersectionOuter1X; outerIntersectionY=intersectionOuter1Y;
397  } else if(numberIntersectionPointsOuter==0) {
398  noIntersectionOuter=7;
399  } else assert(0);
400 
401  /* At this point we have q,invp,curvature,length,phi0,psi,r0,tanl,z0, */
402  /* xstart,ystart,xcenter,ycenter,radius, */
403  /* noIntersectionInner,innerIntersectionX,innerIntersectionY, */
404  /* noIntersectionOuter,outerIntersectionX,outerIntersectionY */
405 
406  /* Now we use tanl to set xintersection, yintersection, and zintersection. */
407  /* After we do this, the variables */
408  /* noIntersectionInner,innerIntersectionX,innerIntersectionY, */
409  /* noIntersectionOuter,outerIntersectionX,outerIntersectionY */
410  /* will be obsolete. */
411  /* The variable angle is in radians, contrary to STAR convention. */
412  if(!noIntersectionInner) {
413  angle+=atan2(innerIntersectionY-ycenter,innerIntersectionX-xcenter)-atan2(ystart-ycenter,xstart-xcenter);
414  count++;
415  }
416  if(!noIntersectionOuter) {
417  angle+=atan2(outerIntersectionY-ycenter,outerIntersectionX-xcenter)-atan2(ystart-ycenter,xstart-xcenter);
418  count++;
419  }
420  // The 180 below does this. if(fabs(tanl)>0.8) { FakeInfo(oo,101); return; }
421  if(count<1) { FakeInfo(oo,124); return; } /* The track does not intersect the CTB because of low pt. */
422  angle/=count; zintersection=z0+tanl*radius*fabs(angle);
423  if(fabs(zintersection)>180.0) { FakeInfo(oo,107); return; }
424  if(fabs(zintersection)<INNER_OUTER_ZBOUNDARY-DEAD_ZONE) {
425  inner=7; if(noIntersectionInner) { FakeInfo(oo,121); return; }
426  xintersection=innerIntersectionX; yintersection=innerIntersectionY;
427  } else if(fabs(zintersection)>INNER_OUTER_ZBOUNDARY+DEAD_ZONE&&fabs(zintersection)<=OUTER_ZBOUNDARY) {
428  inner=0;
429  xintersection=outerIntersectionX; yintersection=outerIntersectionY;
430  if(noIntersectionOuter) { FakeInfo(oo,122); return; }
431  } else { FakeInfo(oo,123); return; /* Return if the track left via the endcap. */ }
432 
433  /* Now we can determine the slat number. */
434  traynumber=TrayNumber(xintersection,yintersection,zintersection);
435  if(traynumber<1) { FakeInfo(oo,129); return; }
436 
437  /* Output. */
438  OO"X%1.1f\n",xintersection);
439  OO"Y%1.1f\n",yintersection);
440  OO"Z%1.1f\n",zintersection);
441  OO"S%d:%d\n",traynumber,inner?1:2);
442 
443  /* This debugging section is commented out for production. --------------------
444  PP"q=%2d invp=%5.2f curv=%8.6f len=%4.0f phi0=%3.0f psi=%3.0f r0=%3.0f tanl=%9.5f z0=%4.0f i/c=%5.2f\n",
445  q,invp,curvature,length,phi0,psi,r0,tanl,z0,invp/curvature);
446  PP"start point = %6.1f %6.1f\n",xstart,ystart);
447  PP"center of circle = (%6.1f %6.1f), radius=%6.1f\n",xcenter,ycenter,radius);
448  PP"plot 0 0 216 0 0 213 %6.1f %6.1f %6.1f\n",xcenter,ycenter,radius);
449  PP"noIntersectionInner=%d, innerIntersectionX=%6.1f, innerIntersectionY=%6.1f\n",
450  noIntersectionInner,innerIntersectionX,innerIntersectionY);
451  PP"noIntersectionOuter=%d, outerIntersectionX=%6.1f, outerIntersectionY=%6.1f\n",
452  noIntersectionOuter,outerIntersectionX,outerIntersectionY);
453  PP"angle from start point to intersection is %6.1f degrees.\n",angle/RPD);
454  PP"The intersection point is %6.1f %6.1f %6.1f\n",xintersection,yintersection,zintersection);
455  -------------------------------------------------------------------------------*/
456 }
457 /*
458 FILE *oo,
459 long q,
460 double invp,
461 double curvature,
462 double length,
463 double phi0,
464 double psi,
465 double r0,
466 double tanl,
467 double z0,
468 */
469 #define FIDUCIAL 0.4 // This tells how much of the slat on either side of the centerline
470  // to accept as fiducial. Thus, 0.5 would use the "entire" slat.
471  // If you want to reject tracks which strike close to the edge, make
472  // it a little smaller, say 0.4.
473 int StTrgMaker::TrayNumber(double x,double y,double z) {
474  double tv,angle; int rv;
475  angle=atan2(y,x);
476  while(angle< 0.0) angle+=2*PI;
477  while(angle>2*PI) angle-=2*PI;
478  angle*=60/(2*PI); /* Var "angle" is in units of 1/60th of circle, ccw from x-axis. */
479  if(z>0) {
480  tv=120-angle+13.5; /* "120" avoids probs w double -> int conversion of negative doubles (next line). */
481  rv=(int)tv;
482  if(fabs((double)(tv-rv-0.5))>FIDUCIAL) return -1; /* Track is not close enough to centerline of slat. */
483  while(rv< 1) rv+=60; while(rv> 60) rv-=60;
484  } else {
485  tv=120+angle+103.5; /* "120" avoids probs w double -> int conversion of negative doubles (next line). */
486  rv=(int)tv;
487  if(fabs((double)(tv-rv-0.5))>FIDUCIAL) return -1; /* Track is not close enough to centerline of slat. */
488  while(rv< 61) rv+=60; while(rv>120) rv-=60;
489  }
490  return rv;
491 }
492 void StTrgMaker::FakeInfo(FILE *oo,int code) {
493  OO"X0 # %d\n",code);
494  OO"Y0\n");
495  OO"Z0\n");
496  OO"S-123:1\n");
497 }
498 
void Clear(Option_t *option="")
User defined functions.
Definition: StTrgMaker.cxx:86
Int_t Make()
Definition: StTrgMaker.cxx:92
virtual void Clear(Option_t *option="")
User defined functions.
Definition: StMaker.cxx:634
Int_t Finish()
Definition: StTrgMaker.cxx:89
Definition: Stypes.h:40