00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #include <assert.h>
00055 #include "StTrgMaker.h"
00056 #include "StEventTypes.h"
00057 #include "TNtuple.h"
00058 #include "TFile.h"
00059 #include "StMessMgr.h"
00060 #define OO fprintf(oo,
00061
00062 #define RPD 0.0174533 // Radians per degree.
00063 #define INNERRADIUS 215.75
00064 #define OUTERRADIUS 212.58
00065 #define INNER_OUTER_ZBOUNDARY 112.0
00066 #define DEAD_ZONE 12.0
00067 #define OUTER_ZBOUNDARY 231.1
00068 #define PI 3.1415926
00069 #define ZCUT 50.0 // cm
00070 #define MAXTRKS 500000
00071
00072 ClassImp(StTrgMaker)
00073
00074 StTrgMaker::StTrgMaker(const Char_t *name) : StMaker(name) {
00075 mEventCounter = 0;
00076 }
00077 StTrgMaker::~StTrgMaker() {
00078
00079 }
00080 Int_t StTrgMaker::Init() {
00081 FILE *ff;
00082 ff=fopen("StTrgMaker.out","w");
00083 assert(ff); fclose(ff);
00084 return StMaker::Init();
00085 }
00086 void StTrgMaker::Clear(Option_t *opt) {
00087 StMaker::Clear();
00088 }
00089 Int_t StTrgMaker::Finish() {
00090 return kStOK;
00091 }
00092 Int_t StTrgMaker::Make() {
00093 FILE *out; double curvature,phi0,psi,r0,tanl,z0; long q; int adc,i,j;
00094 out=fopen("StTrgMaker.out","a"); assert(out);
00095 mEventCounter++;
00096
00097 StEvent* event;
00098 event = (StEvent *) GetInputDS("StEvent");
00099 if (!event) { fclose(out); return kStOK; }
00100 if(!event->primaryVertex()) {
00101 fprintf(out,"# Event %3d: has no primary vertex\n",mEventCounter);
00102 fclose(out); return kStOK;
00103 }
00104 StThreeVectorD vertexPos(0,0,0);
00105 vertexPos=event->primaryVertex()->position();
00106 LOG_INFO << Form("Event %3d: the position of the primary vertex is (%g %g %g)",
00107 mEventCounter,vertexPos.x(), vertexPos.y(), vertexPos.z()) << endm;
00108 if(vertexPos.z()>50.0||vertexPos.z()<-50.0) {
00109 fprintf(out,"# Event %3d: the primary vertex is out of z-range: %6.1f.\n",mEventCounter,vertexPos.z());
00110 fclose(out);
00111 return kStOK;
00112 }
00113
00114 StEventSummary *summary = event->summary();
00115 assert(summary);
00116 mMagneticField = summary->magneticField();
00117
00118 StTriggerDetectorCollection *theTriggers = event->triggerDetectorCollection();
00119 if (!theTriggers) {
00120 fprintf(out,"# Event %3d: triggerDetectorCollection is missing\n",mEventCounter);
00121 fclose(out);
00122 return kStOK;
00123 }
00124 StL0Trigger *l0Trigger = event->l0Trigger();
00125 if(!l0Trigger) {
00126 fprintf(out,"# Event %3d: l0Trigger is missing\n",mEventCounter);
00127 fclose(out);
00128 return kStOK;
00129 }
00130 fprintf(out,"# Event %3d, triggerWord = 0x%04x\n",mEventCounter,l0Trigger->triggerWord());
00131
00132 StCtbTriggerDetector &theCtb = theTriggers->ctb();
00133
00134 fprintf(out,"e %d\n",mEventCounter);
00135 for(unsigned int islat=0; islat<theCtb.numberOfSlats(); islat++)
00136 for(unsigned int itray=0; itray<theCtb.numberOfTrays(); itray++) {
00137 adc=(int)(theCtb.mips(itray, islat, 0)+0.5);
00138 if(adc) fprintf(out,"a%d:%d %d\n",itray+1,islat+1,adc);
00139 }
00140
00141
00142 StZdcTriggerDetector &theZdc = theTriggers->zdc();
00143 if(theZdc.adcSum()>0) fprintf(out,"z%g\n",theZdc.adcSum());
00144 StMwcTriggerDetector &theMwc = theTriggers->mwc();
00145 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));
00146
00147
00148 StTrack *track; StTrackGeometry *geo;
00149 StSPtrVecTrackNode& nodes = event->trackNodes();
00150 StThreeVectorF o,momentum;
00151 for(unsigned int j=0;j<nodes.size();j++) {
00152 track = nodes[j]->track(global);
00153 if(accept(track)) {
00154 geo=track->geometry();
00155 o=geo->origin();
00156 momentum=geo->momentum();
00157 fprintf(out,"P%g\n",momentum.magnitude());
00158 fprintf(out,"D%g\n",0.0);
00159 q=geo->charge();
00160 curvature=geo->curvature();
00161 phi0=o.phi()*180/3.1415926;
00162 psi=geo->psi()*180/3.1415926;
00163 r0=::sqrt(o.x()*o.x()+o.y()*o.y());
00164 tanl=tan(geo->dipAngle());
00165 z0=o.z();
00166
00167 DoOneTrackCtb(out,q,curvature,phi0,psi,r0,tanl,z0);
00168 DoOneTrackMwc(out,q,curvature,phi0,psi,r0,tanl,z0);
00169 }
00170 }
00171
00172 fclose(out); return kStOK;
00173 }
00174 bool StTrgMaker::accept(StTrack* track) {
00175 if(track) assert(track->flag()!=0);
00176 return track && track->flag() > 0;
00177 }
00178 void StTrgMaker::FindIntersectionOfTwoCircles(
00179 double center1x,double center1y,double radius1,
00180 double center2x,double center2y,double radius2,
00181 int *numIntersectionPoints,
00182 double *intersection1x,double *intersection1y,
00183 double *intersection2x,double *intersection2y
00184 ) {
00185
00186 double tempx,tempy,radicand,transX,transY,angle;
00187
00188 if(center1x==center2x&¢er1y==center2y&&radius1==radius2) { *numIntersectionPoints=0; return; }
00189
00190
00191 transX=-center1x; transY=-center1y;
00192 center1x=0; center1y=0; center2x+=transX; center2y+=transY;
00193 angle=-atan2(center2y,center2x);
00194 center2x=::sqrt(center2x*center2x+center2y*center2y); center2y=0;
00195
00196
00197
00198 *intersection1x=(radius1*radius1-radius2*radius2+center2x*center2x)/(2*center2x);
00199
00200 *intersection2x=*intersection1x;
00201 radicand=radius1*radius1-(*intersection1x)*(*intersection1x);
00202
00203
00204 if(radicand< 0) *numIntersectionPoints=0;
00205 else if(radicand==0) *numIntersectionPoints=1;
00206 else *numIntersectionPoints=2;
00207
00208
00209
00210 if(*numIntersectionPoints>0) {
00211 *intersection1y=+::sqrt(radicand);
00212 *intersection2y=-::sqrt(radicand);
00213
00214
00215
00216
00217 tempx=cos(-angle)*(*intersection1x)-sin(-angle)*(*intersection1y);
00218 tempy=sin(-angle)*(*intersection1x)+cos(-angle)*(*intersection1y);
00219 tempx-=transX; tempy-=transY;
00220 *intersection1x=tempx; *intersection1y=tempy;
00221 tempx=cos(-angle)*(*intersection2x)-sin(-angle)*(*intersection2y);
00222 tempy=sin(-angle)*(*intersection2x)+cos(-angle)*(*intersection2y);
00223 tempx-=transX; tempy-=transY;
00224 *intersection2x=tempx; *intersection2y=tempy;
00225 } else {
00226 *intersection1x=0; *intersection1y=0; *intersection2x=0; *intersection2y=0;
00227 }
00228
00229 }
00230 void StTrgMaker::CalcCenterOfCircleDefinedByTrack(int q,double radius,double psi,double r0,
00231 double phi0,double *xcenter,double *ycenter) {
00232 double angleOffset,xstart,ystart;
00233 xstart=r0*cos(RPD*phi0);
00234 ystart=r0*sin(RPD*phi0);
00235 if(mMagneticField>0) { if(q>=0) angleOffset=-90; else angleOffset= 90; }
00236 else { if(q>=0) angleOffset= 90; else angleOffset=-90; }
00237 *xcenter=xstart+radius*cos(RPD*(psi+angleOffset));
00238 *ycenter=ystart+radius*sin(RPD*(psi+angleOffset));
00239 }
00240
00241 #define MWC_LOCATION 200 // z location, centimeters bbb
00242
00243 void StTrgMaker::Location2Sector(double tanl,double xAtMwc,
00244 double yAtMwc,int *sect,int *subsect,double *errDistPhi,double *errDistRad) {
00245 double errPhi,angleDiff,rad,ang,mid,rmid,radDiff;
00246
00247 *subsect=-123; *sect=-123;
00248
00249 ang=atan2(yAtMwc,xAtMwc)/RPD;
00250 while(ang<-180) ang+=360;
00251 while(ang> 180) ang-=360;
00252 if( -15<=ang && ang<= 15) { *sect= 3; mid= 0; }
00253 else if( 15<=ang && ang<= 45) { *sect= 2; mid= 30; }
00254 else if( 45<=ang && ang<= 75) { *sect= 1; mid= 60; }
00255 else if( 75<=ang && ang<= 105) { *sect=12; mid= 90; }
00256 else if( 105<=ang && ang<= 135) { *sect=11; mid= 120; }
00257 else if( 135<=ang && ang<= 165) { *sect=10; mid= 150; }
00258 else if( 165<=ang || ang<=-165) { *sect= 9; if(ang>0) mid=180; else mid=-180; }
00259 else if(-165<=ang && ang<=-135) { *sect= 8; mid=-150; }
00260 else if(-135<=ang && ang<=-105) { *sect= 7; mid=-120; }
00261 else if(-105<=ang && ang<= -75) { *sect= 6; mid= -90; }
00262 else if( -75<=ang && ang<= -45) { *sect= 5; mid= -60; }
00263 else if( -45<=ang && ang<= -15) { *sect= 4; mid= -30; }
00264 else assert(0);
00265
00266 rad=::sqrt(xAtMwc*xAtMwc+yAtMwc*yAtMwc); rmid = 0.;
00267 if(rad >= 53.000 && rad < 85.000 ) { *subsect=1; rmid=( 53.000+ 85.000)/2.0; }
00268 if(rad >= 85.000 && rad < 117.000 ) { *subsect=2; rmid=( 85.000+117.000)/2.0; }
00269 if(rad >= 125.395 && rad < 157.395 ) { *subsect=3; rmid=(125.395+157.395)/2.0; }
00270 if(rad >= 157.395 && rad < 189.395 ) { *subsect=4; rmid=(157.395+189.395)/2.0; }
00271 assert(rmid>0);
00272
00273 if(*subsect>0&&*sect>0) {
00274
00275 angleDiff=ang-mid;
00276 if(angleDiff>0) errPhi=15-angleDiff; else errPhi=15+angleDiff;
00277 *errDistPhi=RPD*errPhi*rad;
00278 assert(*errDistPhi>0.0);
00279
00280 radDiff=rad-rmid;
00281 if(radDiff>0) *errDistRad=16-radDiff; else *errDistRad=16+radDiff;
00282 assert(*errDistRad>0.0);
00283
00284 } else {
00285 *errDistPhi=-1.0;
00286 *errDistRad=-1.0;
00287 }
00288
00289 if(*sect>0&&*subsect>0&&tanl<0) {
00290 if(*sect==12) *sect=24; else *sect=24-*sect;
00291 }
00292 assert(*sect<=24);
00293 assert(*subsect<=4);
00294 }
00295 void StTrgMaker::DoOneTrackMwc(FILE *oo,long q,double curvatureCircle2,double phi0Circle1,
00296 double psi,double r0Circle1,double tanl,double z0) {
00297
00298
00299
00300
00301 int sector,subsector;
00302 double xstart,ystart,xCenterCircle2,yCenterCircle2,dist,radiusCircle2,radiansInFlightCircle2;
00303 double xAtMwc,yAtMwc,radiansAtStartCircle2,radiansAtMwcCircle2,errDistPhi,errDistRad;
00304 assert(curvatureCircle2>=0);
00305 if(tanl>0) {
00306 dist=MWC_LOCATION-z0;
00307 if(dist<0) { fprintf(oo,"M-1:-1\nR999\nN999\n"); return; }
00308 } else {
00309 dist=-MWC_LOCATION-z0;
00310 if(dist>0) { fprintf(oo,"M-1:-1\nR999\nN999\n"); return; }
00311 }
00312 radiusCircle2=1/curvatureCircle2;
00313 radiansInFlightCircle2=dist/(radiusCircle2*tanl);
00314
00315
00316 assert(radiansInFlightCircle2>=0);
00317 if(radiansInFlightCircle2>PI) { fprintf(oo,"M-1:-1\nR999\nN999\n"); return; }
00318 if(q>0) radiansInFlightCircle2*=-1;
00319 CalcCenterOfCircleDefinedByTrack(q,radiusCircle2,psi,r0Circle1,phi0Circle1,&xCenterCircle2,&yCenterCircle2);
00320 xstart=r0Circle1*cos(RPD*phi0Circle1); ystart=r0Circle1*sin(RPD*phi0Circle1);
00321 radiansAtStartCircle2=atan2(ystart-yCenterCircle2,xstart-xCenterCircle2);
00322 radiansAtMwcCircle2=radiansAtStartCircle2+radiansInFlightCircle2;
00323 xAtMwc=xCenterCircle2+radiusCircle2*cos(radiansAtMwcCircle2);
00324 yAtMwc=yCenterCircle2+radiusCircle2*sin(radiansAtMwcCircle2);
00325 Location2Sector(tanl,xAtMwc,yAtMwc,§or,&subsector,&errDistPhi,&errDistRad);
00326 OO"M%d:%d\n",sector,subsector);
00327 OO"R%4.2f\n",errDistRad);
00328 OO"N%4.2f\n",errDistPhi);
00329 }
00330 void StTrgMaker::DoOneTrackCtb(FILE *oo,long q,double curvature,double phi0,
00331 double psi,double r0,double tanl,double z0) {
00332 double xcenter,ycenter,radius;
00333 char inner,noIntersectionInner=0,noIntersectionOuter=0;
00334 int traynumber,count=0,numberIntersectionPointsInner,numberIntersectionPointsOuter;
00335 double xintersection,yintersection,zintersection,angle=0;
00336 double intersectionInner1X,intersectionInner1Y,intersectionInner2X,intersectionInner2Y;
00337 double intersectionOuter1X,intersectionOuter1Y,intersectionOuter2X,intersectionOuter2Y;
00338 double xUnitVector,yUnitVector,xstart,ystart,dotProduct1,dotProduct2;
00339 double innerIntersectionX=0,innerIntersectionY=0;
00340 double outerIntersectionX=0,outerIntersectionY=0;
00341
00342
00343 radius=1/curvature; CalcCenterOfCircleDefinedByTrack(q,radius,psi,r0,phi0,&xcenter,&ycenter);
00344
00345
00346 FindIntersectionOfTwoCircles(0.0,0.0,INNERRADIUS,xcenter,ycenter,radius,&numberIntersectionPointsInner,
00347 &intersectionInner1X,&intersectionInner1Y,
00348 &intersectionInner2X,&intersectionInner2Y);
00349 FindIntersectionOfTwoCircles(0.0,0.0,OUTERRADIUS,xcenter,ycenter,radius,&numberIntersectionPointsOuter,
00350 &intersectionOuter1X,&intersectionOuter1Y,
00351 &intersectionOuter2X,&intersectionOuter2Y);
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 xUnitVector=cos(RPD*psi); yUnitVector=sin(RPD*psi);
00363 xstart=r0*cos(RPD*phi0); ystart=r0*sin(RPD*phi0);
00364
00365 if(numberIntersectionPointsInner==2) {
00366 dotProduct1=xUnitVector*(intersectionInner1X-xstart)+yUnitVector*(intersectionInner1Y-ystart);
00367 dotProduct1/=::sqrt((intersectionInner1X-xstart)*(intersectionInner1X-xstart)+
00368 (intersectionInner1Y-ystart)*(intersectionInner1Y-ystart));
00369 dotProduct2=xUnitVector*(intersectionInner2X-xstart)+yUnitVector*(intersectionInner2Y-ystart);
00370 dotProduct2/=::sqrt((intersectionInner2X-xstart)*(intersectionInner2X-xstart)+
00371 (intersectionInner2Y-ystart)*(intersectionInner2Y-ystart));
00372 if(dotProduct1>=dotProduct2) {
00373 innerIntersectionX=intersectionInner1X; innerIntersectionY=intersectionInner1Y;
00374 } else {
00375 innerIntersectionX=intersectionInner2X; innerIntersectionY=intersectionInner2Y;
00376 }
00377 } else if(numberIntersectionPointsInner==1) {
00378 innerIntersectionX=intersectionInner1X; innerIntersectionY=intersectionInner1Y;
00379 } else if(numberIntersectionPointsInner==0) {
00380 noIntersectionInner=7;
00381 } else assert(0);
00382
00383 if(numberIntersectionPointsOuter==2) {
00384 dotProduct1=xUnitVector*(intersectionOuter1X-xstart)+yUnitVector*(intersectionOuter1Y-ystart);
00385 dotProduct1/=::sqrt((intersectionOuter1X-xstart)*(intersectionOuter1X-xstart)+
00386 (intersectionOuter1Y-ystart)*(intersectionOuter1Y-ystart));
00387 dotProduct2=xUnitVector*(intersectionOuter2X-xstart)+yUnitVector*(intersectionOuter2Y-ystart);
00388 dotProduct2/=::sqrt((intersectionOuter2X-xstart)*(intersectionOuter2X-xstart)+
00389 (intersectionOuter2Y-ystart)*(intersectionOuter2Y-ystart));
00390 if(dotProduct1>=dotProduct2) {
00391 outerIntersectionX=intersectionOuter1X; outerIntersectionY=intersectionOuter1Y;
00392 } else {
00393 outerIntersectionX=intersectionOuter2X; outerIntersectionY=intersectionOuter2Y;
00394 }
00395 } else if(numberIntersectionPointsOuter==1) {
00396 outerIntersectionX=intersectionOuter1X; outerIntersectionY=intersectionOuter1Y;
00397 } else if(numberIntersectionPointsOuter==0) {
00398 noIntersectionOuter=7;
00399 } else assert(0);
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 if(!noIntersectionInner) {
00413 angle+=atan2(innerIntersectionY-ycenter,innerIntersectionX-xcenter)-atan2(ystart-ycenter,xstart-xcenter);
00414 count++;
00415 }
00416 if(!noIntersectionOuter) {
00417 angle+=atan2(outerIntersectionY-ycenter,outerIntersectionX-xcenter)-atan2(ystart-ycenter,xstart-xcenter);
00418 count++;
00419 }
00420
00421 if(count<1) { FakeInfo(oo,124); return; }
00422 angle/=count; zintersection=z0+tanl*radius*fabs(angle);
00423 if(fabs(zintersection)>180.0) { FakeInfo(oo,107); return; }
00424 if(fabs(zintersection)<INNER_OUTER_ZBOUNDARY-DEAD_ZONE) {
00425 inner=7; if(noIntersectionInner) { FakeInfo(oo,121); return; }
00426 xintersection=innerIntersectionX; yintersection=innerIntersectionY;
00427 } else if(fabs(zintersection)>INNER_OUTER_ZBOUNDARY+DEAD_ZONE&&fabs(zintersection)<=OUTER_ZBOUNDARY) {
00428 inner=0;
00429 xintersection=outerIntersectionX; yintersection=outerIntersectionY;
00430 if(noIntersectionOuter) { FakeInfo(oo,122); return; }
00431 } else { FakeInfo(oo,123); return; }
00432
00433
00434 traynumber=TrayNumber(xintersection,yintersection,zintersection);
00435 if(traynumber<1) { FakeInfo(oo,129); return; }
00436
00437
00438 OO"X%1.1f\n",xintersection);
00439 OO"Y%1.1f\n",yintersection);
00440 OO"Z%1.1f\n",zintersection);
00441 OO"S%d:%d\n",traynumber,inner?1:2);
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456 }
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469 #define FIDUCIAL 0.4 // This tells how much of the slat on either side of the centerline
00470
00471
00472
00473 int StTrgMaker::TrayNumber(double x,double y,double z) {
00474 double tv,angle; int rv;
00475 angle=atan2(y,x);
00476 while(angle< 0.0) angle+=2*PI;
00477 while(angle>2*PI) angle-=2*PI;
00478 angle*=60/(2*PI);
00479 if(z>0) {
00480 tv=120-angle+13.5;
00481 rv=(int)tv;
00482 if(fabs((double)(tv-rv-0.5))>FIDUCIAL) return -1;
00483 while(rv< 1) rv+=60; while(rv> 60) rv-=60;
00484 } else {
00485 tv=120+angle+103.5;
00486 rv=(int)tv;
00487 if(fabs((double)(tv-rv-0.5))>FIDUCIAL) return -1;
00488 while(rv< 61) rv+=60; while(rv>120) rv-=60;
00489 }
00490 return rv;
00491 }
00492 void StTrgMaker::FakeInfo(FILE *oo,int code) {
00493 OO"X0 # %d\n",code);
00494 OO"Y0\n");
00495 OO"Z0\n");
00496 OO"S-123:1\n");
00497 }
00498