55 #include "StTrgMaker.h"
56 #include "StEventTypes.h"
59 #include "StMessMgr.h"
60 #define OO fprintf(oo,
62 #define RPD 0.0174533 // Radians per degree.
63 #define INNERRADIUS 215.75
64 #define OUTERRADIUS 212.58
65 #define INNER_OUTER_ZBOUNDARY 112.0
66 #define DEAD_ZONE 12.0
67 #define OUTER_ZBOUNDARY 231.1
69 #define ZCUT 50.0 // cm
70 #define MAXTRKS 500000
77 StTrgMaker::~StTrgMaker() {
80 Int_t StTrgMaker::Init() {
82 ff=fopen(
"StTrgMaker.out",
"w");
83 assert(ff); fclose(ff);
84 return StMaker::Init();
93 FILE *out;
double curvature,phi0,psi,r0,tanl,z0;
long q;
int adc,i,j;
94 out=fopen(
"StTrgMaker.out",
"a"); assert(out);
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;
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());
116 mMagneticField = summary->magneticField();
120 fprintf(out,
"# Event %3d: triggerDetectorCollection is missing\n",mEventCounter);
126 fprintf(out,
"# Event %3d: l0Trigger is missing\n",mEventCounter);
130 fprintf(out,
"# Event %3d, triggerWord = 0x%04x\n",mEventCounter,l0Trigger->triggerWord());
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);
143 if(theZdc.adcSum()>0) fprintf(out,
"z%g\n",theZdc.adcSum());
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));
149 StSPtrVecTrackNode& nodes =
event->trackNodes();
151 for(
unsigned int j=0;j<nodes.size();j++) {
152 track = nodes[j]->track(global);
154 geo=track->geometry();
156 momentum=geo->momentum();
157 fprintf(out,
"P%g\n",momentum.magnitude());
158 fprintf(out,
"D%g\n",0.0);
160 curvature=geo->curvature();
161 phi0=o.phi()*180/3.1415926;
162 psi=geo->psi()*180/3.1415926;
163 r0=::sqrt(o.x()*o.x()+o.y()*o.y());
164 tanl=tan(geo->dipAngle());
167 DoOneTrackCtb(out,q,curvature,phi0,psi,r0,tanl,z0);
168 DoOneTrackMwc(out,q,curvature,phi0,psi,r0,tanl,z0);
172 fclose(out);
return kStOK;
175 if(track) assert(track->flag()!=0);
176 return track && track->flag() > 0;
178 void StTrgMaker::FindIntersectionOfTwoCircles(
179 double center1x,
double center1y,
double radius1,
180 double center2x,
double center2y,
double radius2,
181 int *numIntersectionPoints,
182 double *intersection1x,
double *intersection1y,
183 double *intersection2x,
double *intersection2y
186 double tempx,tempy,radicand,transX,transY,angle;
188 if(center1x==center2x&¢er1y==center2y&&radius1==radius2) { *numIntersectionPoints=0;
return; }
191 transX=-center1x; transY=-center1y;
192 center1x=0; center1y=0; center2x+=transX; center2y+=transY;
193 angle=-atan2(center2y,center2x);
194 center2x=::sqrt(center2x*center2x+center2y*center2y); center2y=0;
198 *intersection1x=(radius1*radius1-radius2*radius2+center2x*center2x)/(2*center2x);
200 *intersection2x=*intersection1x;
201 radicand=radius1*radius1-(*intersection1x)*(*intersection1x);
204 if(radicand< 0) *numIntersectionPoints=0;
205 else if(radicand==0) *numIntersectionPoints=1;
206 else *numIntersectionPoints=2;
210 if(*numIntersectionPoints>0) {
211 *intersection1y=+::sqrt(radicand);
212 *intersection2y=-::sqrt(radicand);
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;
226 *intersection1x=0; *intersection1y=0; *intersection2x=0; *intersection2y=0;
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));
241 #define MWC_LOCATION 200 // z location, centimeters bbb
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;
247 *subsect=-123; *sect=-123;
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; }
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; }
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; }
273 if(*subsect>0&&*sect>0) {
276 if(angleDiff>0) errPhi=15-angleDiff;
else errPhi=15+angleDiff;
277 *errDistPhi=RPD*errPhi*rad;
278 assert(*errDistPhi>0.0);
281 if(radDiff>0) *errDistRad=16-radDiff;
else *errDistRad=16+radDiff;
282 assert(*errDistRad>0.0);
289 if(*sect>0&&*subsect>0&&tanl<0) {
290 if(*sect==12) *sect=24;
else *sect=24-*sect;
295 void StTrgMaker::DoOneTrackMwc(FILE *oo,
long q,
double curvatureCircle2,
double phi0Circle1,
296 double psi,
double r0Circle1,
double tanl,
double z0) {
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);
306 dist=MWC_LOCATION-z0;
307 if(dist<0) { fprintf(oo,
"M-1:-1\nR999\nN999\n");
return; }
309 dist=-MWC_LOCATION-z0;
310 if(dist>0) { fprintf(oo,
"M-1:-1\nR999\nN999\n");
return; }
312 radiusCircle2=1/curvatureCircle2;
313 radiansInFlightCircle2=dist/(radiusCircle2*tanl);
316 assert(radiansInFlightCircle2>=0);
317 if(radiansInFlightCircle2>PI) { fprintf(oo,
"M-1:-1\nR999\nN999\n");
return; }
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,§or,&subsector,&errDistPhi,&errDistRad);
326 OO
"M%d:%d\n",sector,subsector);
327 OO
"R%4.2f\n",errDistRad);
328 OO
"N%4.2f\n",errDistPhi);
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;
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;
343 radius=1/curvature; CalcCenterOfCircleDefinedByTrack(q,radius,psi,r0,phi0,&xcenter,&ycenter);
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);
362 xUnitVector=cos(RPD*psi); yUnitVector=sin(RPD*psi);
363 xstart=r0*cos(RPD*phi0); ystart=r0*sin(RPD*phi0);
365 if(numberIntersectionPointsInner==2) {
366 dotProduct1=xUnitVector*(intersectionInner1X-xstart)+yUnitVector*(intersectionInner1Y-ystart);
367 dotProduct1/=::sqrt((intersectionInner1X-xstart)*(intersectionInner1X-xstart)+
368 (intersectionInner1Y-ystart)*(intersectionInner1Y-ystart));
369 dotProduct2=xUnitVector*(intersectionInner2X-xstart)+yUnitVector*(intersectionInner2Y-ystart);
370 dotProduct2/=::sqrt((intersectionInner2X-xstart)*(intersectionInner2X-xstart)+
371 (intersectionInner2Y-ystart)*(intersectionInner2Y-ystart));
372 if(dotProduct1>=dotProduct2) {
373 innerIntersectionX=intersectionInner1X; innerIntersectionY=intersectionInner1Y;
375 innerIntersectionX=intersectionInner2X; innerIntersectionY=intersectionInner2Y;
377 }
else if(numberIntersectionPointsInner==1) {
378 innerIntersectionX=intersectionInner1X; innerIntersectionY=intersectionInner1Y;
379 }
else if(numberIntersectionPointsInner==0) {
380 noIntersectionInner=7;
383 if(numberIntersectionPointsOuter==2) {
384 dotProduct1=xUnitVector*(intersectionOuter1X-xstart)+yUnitVector*(intersectionOuter1Y-ystart);
385 dotProduct1/=::sqrt((intersectionOuter1X-xstart)*(intersectionOuter1X-xstart)+
386 (intersectionOuter1Y-ystart)*(intersectionOuter1Y-ystart));
387 dotProduct2=xUnitVector*(intersectionOuter2X-xstart)+yUnitVector*(intersectionOuter2Y-ystart);
388 dotProduct2/=::sqrt((intersectionOuter2X-xstart)*(intersectionOuter2X-xstart)+
389 (intersectionOuter2Y-ystart)*(intersectionOuter2Y-ystart));
390 if(dotProduct1>=dotProduct2) {
391 outerIntersectionX=intersectionOuter1X; outerIntersectionY=intersectionOuter1Y;
393 outerIntersectionX=intersectionOuter2X; outerIntersectionY=intersectionOuter2Y;
395 }
else if(numberIntersectionPointsOuter==1) {
396 outerIntersectionX=intersectionOuter1X; outerIntersectionY=intersectionOuter1Y;
397 }
else if(numberIntersectionPointsOuter==0) {
398 noIntersectionOuter=7;
412 if(!noIntersectionInner) {
413 angle+=atan2(innerIntersectionY-ycenter,innerIntersectionX-xcenter)-atan2(ystart-ycenter,xstart-xcenter);
416 if(!noIntersectionOuter) {
417 angle+=atan2(outerIntersectionY-ycenter,outerIntersectionX-xcenter)-atan2(ystart-ycenter,xstart-xcenter);
421 if(count<1) { FakeInfo(oo,124);
return; }
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) {
429 xintersection=outerIntersectionX; yintersection=outerIntersectionY;
430 if(noIntersectionOuter) { FakeInfo(oo,122);
return; }
431 }
else { FakeInfo(oo,123);
return; }
434 traynumber=TrayNumber(xintersection,yintersection,zintersection);
435 if(traynumber<1) { FakeInfo(oo,129);
return; }
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);
469 #define FIDUCIAL 0.4 // This tells how much of the slat on either side of the centerline
473 int StTrgMaker::TrayNumber(
double x,
double y,
double z) {
474 double tv,angle;
int rv;
476 while(angle< 0.0) angle+=2*PI;
477 while(angle>2*PI) angle-=2*PI;
482 if(fabs((
double)(tv-rv-0.5))>FIDUCIAL)
return -1;
483 while(rv< 1) rv+=60;
while(rv> 60) rv-=60;
487 if(fabs((
double)(tv-rv-0.5))>FIDUCIAL)
return -1;
488 while(rv< 61) rv+=60;
while(rv>120) rv-=60;
492 void StTrgMaker::FakeInfo(FILE *oo,
int code) {
void Clear(Option_t *option="")
User defined functions.
virtual void Clear(Option_t *option="")
User defined functions.