00001
00002
00003
00004
00005
00006
00008
00009 #include <cassert>
00010 #include <cmath>
00011
00012 #include "HitCam.h"
00013 #include "TrackCam.h"
00014
00015 #include "Algorithm/AlgConfig.h"
00016 #include "Algorithm/AlgFactory.h"
00017 #include "Algorithm/AlgHandle.h"
00018
00019 #include "Candidate/CandContext.h"
00020
00021 #include "CandData/CandRecord.h"
00022 #include "CandData/CandHeader.h"
00023
00024 #include "CandTrackCam/AlgTrackCam.h"
00025 #include "CandTrackCam/AlgTrackCam.h"
00026 #include "CandTrackCam/CandTrackCamHandle.h"
00027 #include "CandTrackCam/TrackCam.h"
00028
00029 #include "Calibrator/Calibrator.h"
00030
00031 #include "MessageService/MsgService.h"
00032 #include "MinosObjectMap/MomNavigator.h"
00033
00034 #include "RecoBase/CandSliceHandle.h"
00035 #include "RecoBase/CandStripHandle.h"
00036 #include "RecoBase/CandTrackHandle.h"
00037 #include "RecoBase/AlgTrack.h"
00038 #include "RecoBase/CandSliceHandle.h"
00039 #include "RecoBase/PropagationVelocity.h"
00040
00041 #include "UgliGeometry/UgliGeomHandle.h"
00042 #include "Plex/PlexPlaneId.h"
00043 #include "Validity/VldContext.h"
00044 #include "Conventions/Munits.h"
00045
00046 #include "DataUtil/GetMomFromRange.h"
00047
00048 ClassImp(AlgTrackCam)
00049
00050 CVSID("$Id: AlgTrackCam.cxx,v 1.14 2008/10/24 10:55:23 blake Exp $");
00051
00052
00054 AlgTrackCam::AlgTrackCam()
00055 {
00056 }
00058
00059
00061 AlgTrackCam::~AlgTrackCam()
00062 {
00063 }
00065
00066
00068 void AlgTrackCam::RunAlg(AlgConfig &ac, CandHandle &ch, CandContext &cx)
00069 {
00070
00072 assert(ch.InheritsFrom("CandTrackCamHandle"));
00073 CandTrackCamHandle &cth = dynamic_cast<CandTrackCamHandle &>(ch);
00074
00075 assert(cx.GetDataIn());
00076 VldContext* vldc = (VldContext*)(cx.GetCandRecord()->GetVldContext());
00077
00078
00079 const double SoL = Munits::c_light;
00080 double fFibreIndex = 1.77;
00081 fFibreIndex = SoL/PropagationVelocity::Velocity(vldc->GetSimFlag());
00082
00083
00084 BeamFlag=true;
00085 if( ac.KeyExists("BeamFlag") ) {BeamFlag = ac.GetInt("BeamFlag");}
00086 PassTrack=true;
00087
00088
00089 const TObjArray* arr = dynamic_cast<const TObjArray*>(cx.GetDataIn());
00090 TrackCam* trku = (TrackCam*)(arr->At(0));
00091 TrackCam* trkv = (TrackCam*)(arr->At(1));
00092 CandSliceHandle* slice = (CandSliceHandle*)(arr->At(2));
00093 if(slice) cth.SetCandSlice(slice);
00094
00095
00097 UgliGeomHandle ugh(*vldc);
00098
00099 switch(vldc->GetDetector()){
00100 case Detector::kFar:
00101 ModuleType=1; break;
00102 case Detector::kNear:
00103 ModuleType=2; break;
00104 case Detector::kCalDet:
00105 ModuleType=3; break;
00106 default:
00107 ModuleType=-1; break;
00108 }
00110
00111
00112
00114 int i,bpln,epln;
00115 if(trku->GetBegPlane()<trkv->GetBegPlane()) {bpln=trku->GetBegPlane(); begplane2=trku->GetBegPlane(); begplane1=trkv->GetBegPlane();}
00116 else {bpln=trkv->GetBegPlane(); begplane2=trkv->GetBegPlane(); begplane1=trku->GetBegPlane();}
00117
00118 if(trku->GetEndPlane()>trkv->GetEndPlane()) {epln=trku->GetEndPlane(); endplane2=trku->GetEndPlane(); endplane1=trkv->GetEndPlane();}
00119 else {epln=trkv->GetEndPlane(); endplane2=trkv->GetEndPlane(); endplane1=trku->GetEndPlane();}
00120
00121 const int npln = 1+epln-bpln;
00123
00124
00125
00127 if(npln<1 || ((ModuleType==1 || ModuleType==3) && begplane1>endplane1) || (ModuleType==2 && (begplane1-endplane1)>40)) {
00128 MSG("AlgTrackCam", Msg::kDebug) << "Not enough planes. Not Making track..." <<endl;
00129
00130 for(int p=0; p<500; ++p) {fHitArr[p].clear();}
00131 fPlaneInfo.clear();
00132 return;
00133 }
00135
00136
00137
00139 TrkPlaneInfo tmpplane;
00140 tmpplane.plnvuw=-1; tmpplane.plnnum=0;
00141 tmpplane.U=0.0; tmpplane.V=0.0; tmpplane.Z=0.0; tmpplane.Q=0.0;
00142 tmpplane.Qm=0.0; tmpplane.Qp=0.0; tmpplane.CTm=0.0; tmpplane.CTp=0.0;
00143 tmpplane.Wm=0.0; tmpplane.Wp=0.0;
00144 for(i=0; i<npln; ++i) {fPlaneInfo.push_back(tmpplane);}
00146
00147
00148
00149
00151 MaxPlane=-20; MinPlane=500;
00152 ExtractHitProperties(trku, bpln, cth);
00153 ExtractHitProperties(trkv, bpln, cth);
00154
00155 if(PassTrack==false) {
00156 vector<CandStripHandle*> Daughters;
00157
00158 TIter TrackStripItr = cth.GetDaughterIterator();
00159 while(CandStripHandle* TrackStrip = dynamic_cast<CandStripHandle*>(TrackStripItr()))
00160 {Daughters.push_back(TrackStrip);}
00161
00162 for(unsigned int i=0; i<Daughters.size(); ++i) {cth.RemoveDaughter(Daughters[i]);}
00163 Daughters.clear();
00164
00165 for(int i=0; i<500; ++i) {fHitArr[i].clear();}
00166 fPlaneInfo.clear();
00167 return;
00168 }
00170
00171
00172
00174 int nplanes=0,nstrips=0;
00175 for(i=0;i<npln;i++) {
00176 if(fPlaneInfo[i].plnvuw>-1 && fPlaneInfo[i].Q>0.0) {
00177 fPlaneInfo[i].U/=fPlaneInfo[i].Q; fPlaneInfo[i].V/=fPlaneInfo[i].Q;
00178 nstrips+=fPlaneInfo[i].plnnum; ++nplanes;
00179 }
00180 }
00182
00183
00184
00186
00187 InterpolateTrackPosition();
00188
00189
00190
00191 SetupTimingInfo(&ugh, fFibreIndex);
00192
00193
00194
00195 int plnm=-1; int plnp=-1;
00196 SetTrackCoordinates(bpln,plnm,plnp);
00197
00198
00199
00200 double begCoord[3], begDir[3];
00201 SetVertexEndProperties(begCoord,begDir,0,plnm);
00202
00203
00204 double endCoord[3], endDir[3];
00205 SetVertexEndProperties(endCoord,endDir,1,plnp);
00207
00208
00209
00210
00212 double utmp(0.),vtmp(0.),ztmp(0.);
00213 double dq,du,dv,dz,ds;
00214 double range_thru_detector(0.),range_thru_steel(0.);
00215 double sumz_thru_steel(0.),sumz_thru_detector(0.);
00216 double range_thru_steel_xtra(0.), range_thru_detector_xtra(0.);
00217 int flag=0;
00218 for(i=0;i<npln;i++) {
00219 if(fPlaneInfo[i].plnvuw>-1) {
00220 if(flag) {
00221 du=fPlaneInfo[i].U-utmp; dv=fPlaneInfo[i].V-vtmp; dz=fPlaneInfo[i].Z-ztmp;
00222 ds=sqrt(du*du+dv*dv+dz*dz);
00223 if(dz>1.0) dq=2.0; else dq=1.0;
00224 range_thru_steel+=dq*ds*(0.0254/dz);
00225 sumz_thru_steel+=dq*0.0254;
00226 range_thru_detector+=ds;
00227 sumz_thru_detector+=dz;
00228 }
00229 fPlaneInfo[i].dS=range_thru_detector;
00230 fPlaneInfo[i].dSsteel=range_thru_steel;
00231 utmp=fPlaneInfo[i].U; vtmp=fPlaneInfo[i].V; ztmp=fPlaneInfo[i].Z;
00232 flag=1;
00233 }
00234 }
00235
00236 if(range_thru_detector>0.0) {
00237 range_thru_steel_xtra = 0.0127*(1.0/begDir[2]+1.0/endDir[2]);
00238 range_thru_detector_xtra = 0.0296*(1.0/begDir[2]+1.0/endDir[2]);
00239 range_thru_steel+=range_thru_steel_xtra;
00240 range_thru_detector+=range_thru_detector_xtra;
00241 }
00243
00244
00245
00246
00248 double begtrace(0.),endtrace(0.);
00249 double begtraceZ(0.),endtraceZ(0.);
00250
00251 if(vldc->GetDetector()==Detector::kFar) {
00252
00253 double m[2] = {begDir[0]/begDir[2], begDir[1]/begDir[2]};
00254 double c[2] = {begCoord[0]-(m[0]*begCoord[2]), begCoord[1]-(m[1]*begCoord[2])};
00255 double Coord[3] = {begCoord[0], begCoord[1], begCoord[2]};
00256 double Trace[3] = {1.e99,1.e99,1.e99};
00257
00258 bool TraceSuccess = CalculateTrace(m,c,Coord,Trace);
00259 if(TraceSuccess==true) {
00260 begtrace = pow(pow(Trace[0],2) + pow(Trace[1],2) + pow(Trace[2],2), 0.5);
00261 begtraceZ = fabs(Trace[2]);
00262 }
00263
00264
00265
00266 m[0] = endDir[0]/endDir[2];
00267 m[1] = endDir[1]/endDir[2];
00268 c[0] = endCoord[0]-(m[0]*endCoord[2]);
00269 c[1] = endCoord[1]-(m[1]*endCoord[2]);
00270 Coord[0] = endCoord[0]; Coord[1] = endCoord[1]; Coord[2] = endCoord[2];
00271 Trace[0] = 1.e99; Trace[1]=1.e99; Trace[2]=1.e99;
00272
00273 TraceSuccess = CalculateTrace(m,c,Coord,Trace);
00274 if(TraceSuccess==true) {
00275 endtrace = pow(pow(Trace[0],2) + pow(Trace[1],2) + pow(Trace[2],2), 0.5);
00276 endtraceZ = fabs(Trace[2]);
00277 }
00278 }
00280
00281
00282
00284 double dir(0.), mytimeoffset(0.);
00285 CalculateTimingFits(dir,mytimeoffset,cth);
00287
00288
00289
00291 SetUVZ(&cth);
00292
00293 int begplane, endplane;
00294 double dt=1.;
00295
00296 if(dir>=0 || BeamFlag) {
00297 begplane=MinPlane;
00298 endplane=MaxPlane;
00299
00300 cth.SetVtxTrace(begtrace);
00301 cth.SetVtxTraceZ(begtraceZ);
00302
00303 cth.SetEndTrace(endtrace);
00304 cth.SetEndTraceZ(endtraceZ);
00305
00306 cth.SetVtxT((mytimeoffset+StripListTime)/(3.0e8));
00307 cth.SetEndT((mytimeoffset+range_thru_detector+StripListTime)/(3.0e8));
00308 }
00309 else{
00310 begplane=MaxPlane;
00311 endplane=MinPlane;
00312
00313 cth.SetVtxTrace(endtrace);
00314 cth.SetVtxTraceZ(endtraceZ);
00315
00316 cth.SetEndTrace(begtrace);
00317 cth.SetEndTraceZ(begtraceZ);
00318
00319 cth.SetVtxT((mytimeoffset-range_thru_detector+StripListTime)/(3.0e8));
00320 cth.SetEndT((mytimeoffset+StripListTime)/(3.0e8));
00321
00322 dt=-1.;
00323 }
00324
00325 cth.SetVtxPlane(begplane);
00326 cth.SetVtxZ(cth.GetZ(begplane));
00327 cth.SetVtxU(cth.GetU(begplane));
00328 cth.SetVtxV(cth.GetV(begplane));
00329 cth.SetDirCosU(dt*cth.GetDirCosU(begplane));
00330 cth.SetDirCosV(dt*cth.GetDirCosV(begplane));
00331 cth.SetDirCosZ(dt*cth.GetDirCosZ(begplane));
00332
00333 cth.SetEndPlane(endplane);
00334 cth.SetEndZ(cth.GetZ(endplane));
00335 cth.SetEndU(cth.GetU(endplane));
00336 cth.SetEndV(cth.GetV(endplane));
00337 cth.SetEndDirCosU(dt*cth.GetDirCosU(endplane));
00338 cth.SetEndDirCosV(dt*cth.GetDirCosV(endplane));
00339 cth.SetEndDirCosZ(dt*cth.GetDirCosZ(endplane));
00340
00341
00342
00343 SetT(&cth);
00344
00345
00346 SetdS(&cth);
00347
00348
00349
00350 double range = cth.GetRange();
00351 if (range>0.) {cth.SetMomentum(GetMomFromRange(range));}
00352 else {cth.SetMomentum(0.);}
00353
00354
00355 Calibrator& cal = Calibrator::Instance();
00356 cal.ReInitialise(*vldc);
00357 Calibrate(&cth);
00359
00360
00361 for(i=0; i<500; ++i) {fHitArr[i].clear();}
00362 fPlaneInfo.clear();
00363
00364
00365 return;
00366 }
00368
00369
00370
00372 void AlgTrackCam::SetVertexEndProperties( double* Coord, double* Dir,const int& end, const int& coordpln)
00373 {
00374 const int npln = (int)fPlaneInfo.size();
00375
00376
00377 if(coordpln<0 || coordpln>=npln) return;
00378
00379 double mu(0.0),mv(0.0),u,v,z,w,precou,precov,precos,precoz;
00380 double Uw(0.0),Uwz(0.0),Uwzz(0.0),Uwu(0.0),Uwuu(0.0),Uwzu(0.0);
00381 double Vw(0.0),Vwz(0.0),Vwzz(0.0),Vwv(0.0),Vwvv(0.0),Vwzv(0.0);
00382
00383 int Upts(0),Vpts(0),MAXpts(4);
00384 int increment=(end==0)?1:-1;
00385 double extrapdist=(end==0)?-0.02:0.04;
00386 int i=coordpln;
00387 while(i>=0 && i<npln)
00388 {
00389 if(fPlaneInfo[i].plnvuw>-1)
00390 {
00391 u=fPlaneInfo[i].U; v=fPlaneInfo[i].V; z=fPlaneInfo[i].Z; w=1.0;
00392
00393 if(fPlaneInfo[i].plnvuw==0 && Upts<MAXpts)
00394 {
00395 Uw+=w;
00396 Uwu+=w*u; Uwz+=w*z; Uwuu+=w*u*u;
00397 Uwzu+=w*u*z; Uwzz+=w*z*z;
00398 ++Upts;
00399 }
00400
00401 if(fPlaneInfo[i].plnvuw==1 && Vpts<MAXpts)
00402 {
00403 Vw+=w;
00404 Vwv+=w*v; Vwz+=w*z; Vwvv+=w*v*v;
00405 Vwzv+=w*v*z; Vwzz+=w*z*z;
00406 ++Vpts;
00407 }
00408 }
00409 if(Upts==MAXpts && Vpts==MAXpts) break;
00410 i+=increment;
00411 }
00412
00413 if(Upts>1 && Vpts>1)
00414 {
00415 mu=(Uw*Uwzu-Uwz*Uwu)/(Uw*Uwzz-Uwz*Uwz);
00416 mv=(Vw*Vwzv-Vwz*Vwv)/(Vw*Vwzz-Vwz*Vwz);
00417 }
00418
00419 precou=mu; precov=mv;
00420 precos=sqrt(precou*precou+precov*precov+1.0);
00421 precou=precou/precos; precov=precov/precos; precoz=1.0/precos;
00422 Dir[0]=precou; Dir[1]=precov; Dir[2]=precoz;
00423
00424 Coord[0]=fPlaneInfo[coordpln].U+extrapdist*(Dir[0]/Dir[2]);
00425 Coord[1]=fPlaneInfo[coordpln].V+extrapdist*(Dir[1]/Dir[2]);
00426 Coord[2]=fPlaneInfo[coordpln].Z+extrapdist;
00427
00428 return;
00429 }
00431
00432
00433
00435 void AlgTrackCam::InterpolateTrackPosition()
00436 {
00437
00438 const int npln = (int)fPlaneInfo.size();
00439
00440 int flag,vuw;
00441 int pln;
00442 int k,km1,kp1,km2,kp2;
00443
00444 for(pln=0;pln<npln;pln++) {
00445
00446 if(fPlaneInfo[pln].plnvuw>-1) {
00447 flag=0;
00448 vuw=fPlaneInfo[pln].plnvuw;
00449 k=0; km1=-1; km2=-1;
00450
00451 while(pln-k>0 && km2<0) {
00452 k++;
00453 if(fPlaneInfo[pln-k].plnvuw>-1 && fPlaneInfo[pln-k].plnvuw!=vuw) {
00454 if(km1<0) km1=k; else km2=k;
00455 }
00456 }
00457
00458 k=0; kp1=-1; kp2=-1;
00459
00460 while(pln+k<npln-1 && kp2<0) {
00461 k++;
00462
00463 if(fPlaneInfo[pln+k].plnvuw>-1 && fPlaneInfo[pln+k].plnvuw!=vuw) {
00464 if(kp1<0) kp1=k; else kp2=k;
00465 }
00466 }
00467
00468 if(km1>0 && kp1>0) {
00469 if(vuw==0) fPlaneInfo[pln].V=fPlaneInfo[pln-km1].V
00470 +((fPlaneInfo[pln+kp1].V-fPlaneInfo[pln-km1].V)/(fPlaneInfo[pln+kp1].Z-fPlaneInfo[pln-km1].Z))
00471 *(fPlaneInfo[pln].Z-fPlaneInfo[pln-km1].Z);
00472
00473 if(vuw==1) fPlaneInfo[pln].U=fPlaneInfo[pln-km1].U
00474 +((fPlaneInfo[pln+kp1].U-fPlaneInfo[pln-km1].U)/(fPlaneInfo[pln+kp1].Z-fPlaneInfo[pln-km1].Z))
00475 *(fPlaneInfo[pln].Z-fPlaneInfo[pln-km1].Z);
00476 flag=1;
00477 }
00478 else {
00479 if(km1>0) {
00480 if(vuw==0) {
00481 if(km2>0) {fPlaneInfo[pln].V=fPlaneInfo[pln-km1].V
00482 +(fPlaneInfo[pln].Z-fPlaneInfo[pln-km1].Z)
00483 *(fPlaneInfo[pln-km1].V-fPlaneInfo[pln-km2].V)/(fPlaneInfo[pln-km1].Z-fPlaneInfo[pln-km2].Z);}
00484 else {fPlaneInfo[pln].V=fPlaneInfo[pln-km1].V;}
00485 }
00486
00487 if(vuw==1) {
00488 if(km2>0) {fPlaneInfo[pln].U=fPlaneInfo[pln-km1].U
00489 +(fPlaneInfo[pln].Z-fPlaneInfo[pln-km1].Z)
00490 *(fPlaneInfo[pln-km1].U-fPlaneInfo[pln-km2].U)/(fPlaneInfo[pln-km1].Z-fPlaneInfo[pln-km2].Z);}
00491 else {fPlaneInfo[pln].U=fPlaneInfo[pln-km1].U;}
00492 }
00493
00494 flag=1;
00495 }
00496
00497 if(kp1>0) {
00498 if(vuw==0) {
00499 if(kp2>0) {fPlaneInfo[pln].V=fPlaneInfo[pln+kp1].V
00500 +(fPlaneInfo[pln].Z-fPlaneInfo[pln+kp1].Z)
00501 *(fPlaneInfo[pln+kp1].V-fPlaneInfo[pln+kp2].V)/(fPlaneInfo[pln+kp1].Z-fPlaneInfo[pln+kp2].Z);}
00502 else {fPlaneInfo[pln].V=fPlaneInfo[pln+kp1].V;}
00503 }
00504
00505 if(vuw==1) {
00506 if(kp2>0) {fPlaneInfo[pln].U=fPlaneInfo[pln+kp1].U
00507 +(fPlaneInfo[pln].Z-fPlaneInfo[pln+kp1].Z)
00508 *(fPlaneInfo[pln+kp1].U-fPlaneInfo[pln+kp2].U)/(fPlaneInfo[pln+kp1].Z-fPlaneInfo[pln+kp2].Z);}
00509 else {fPlaneInfo[pln].U=fPlaneInfo[pln+kp1].U;}
00510 }
00511
00512 flag=1;
00513 }
00514 }
00515
00516 if(flag==0){ fPlaneInfo[pln].plnvuw=-1; }
00517 }
00518 }
00519
00520 return;
00521 }
00523
00524
00525
00527 void AlgTrackCam::ExtractHitProperties(const TrackCam* trkc, const int& bpln, CandTrackHandle& cth)
00528 {
00529
00530
00531
00532 unsigned int nhits = trkc->GetEntries();
00533 int pln, hitplane;
00534 double PartnerBegTPos, PartnerEndTPos;
00535
00536 int Counter=0;
00537
00538 TrackCam* Partner = trkc->GetPartner();
00539 PartnerBegTPos=fabs(Partner->GetBegTPos());
00540 PartnerEndTPos=fabs(Partner->GetEndTPos());
00541
00542
00543 for(unsigned int i=0; i<nhits; ++i) {
00544 HitCam* hit = trkc->GetHit(i);
00545
00546 if(hit->GetUID()<0) {continue;}
00547
00548 hitplane=hit->GetPlane();
00549
00550
00551 if( ModuleType==1 && !BeamFlag && ( (PartnerBegTPos<3.9 && PartnerBegTPos>0.2 && hitplane<begplane1-4)
00552 || (PartnerEndTPos<3.9 && PartnerEndTPos>0.2 && hitplane>endplane1+4) ) ) {continue;}
00553
00554 CandStripHandle* strip = hit->GetCandStripHandle();
00555
00556 pln = hitplane-bpln;
00557 fHitArr[pln].push_back(hit);
00558 if(fPlaneInfo[pln].plnvuw<0) {
00559 fPlaneInfo[pln].plnvuw = hit->GetPlaneView();
00560 fPlaneInfo[pln].Z = hit->GetZPos();
00561 }
00562
00563 if(fPlaneInfo[pln].plnvuw==0) fPlaneInfo[pln].U += hit->GetCharge()*hit->GetTPos();
00564 if(fPlaneInfo[pln].plnvuw==1) fPlaneInfo[pln].V += hit->GetCharge()*hit->GetTPos();
00565 fPlaneInfo[pln].Q += hit->GetCharge();
00566 cth.AddDaughterLink(*strip);
00567 Counter++;
00568
00569 if(hitplane>MaxPlane) {MaxPlane=hitplane;}
00570 if(hitplane<MinPlane) {MinPlane=hitplane;}
00571
00572 (fPlaneInfo[pln].plnnum)++;
00573 }
00574
00575 if(Counter<2) {PassTrack=false;}
00576
00577
00578 return;
00579 }
00581
00582
00583
00585 bool AlgTrackCam::CalculateTrace(double* m, double* c, double* Coord, double* Trace)
00586 {
00587 MSG("AlgTrackCam",Msg::kDebug) << "CalculateTrace" << endl;
00588
00589 bool TraceSuccess=false;
00590 double TempTrace[3]={0.,0.,0.}; double TempSum=0.;
00591 double TraceLength(1.e99);
00592
00593 for(int i=0; i<8; ++i) {
00594 TempSum=0.;
00595
00596 DetectorSides(m,c,TempTrace, i);
00597
00598 for(int j=0; j<3; ++j) {TempSum+=pow(Coord[j]-TempTrace[j],2);}
00599 TempSum=pow(TempSum,0.5);
00600
00601 if(TempSum<TraceLength) {
00602 for(int j=0; j<3; ++j) {Trace[j]=TempTrace[j]-Coord[j];}
00603 TraceLength=TempSum;
00604 TraceSuccess=true;
00605 }
00606 }
00607
00608 return TraceSuccess;
00609 }
00611
00612
00613
00615 void AlgTrackCam::DetectorSides(double* m, double* c, double* position, int side)
00616 {
00617 position[2]=-1.e99;
00618
00619 switch(side) {
00620 case 0: if(m[0]!=-m[1]) {position[2] = (pow(32.,0.5)-c[0]-c[1])/(m[0]+m[1]);} break;
00621 case 1: if(m[0]!=0.) {position[2] = (4.-c[0])/m[0];} break;
00622 case 2: if(m[0]!=m[1]) {position[2] = (pow(32.,0.5)-c[0]+c[1])/(m[0]-m[1]);} break;
00623 case 3: if(m[1]!=0.) {position[2] = (-4.-c[1])/m[1];} break;
00624 case 4: if(m[0]!=-m[1]) {position[2] = (-pow(32.,0.5)-c[0]-c[1])/(m[0]+m[1]);} break;
00625 case 5: if(m[0]!=0.) {position[2] = (-4.-c[0])/m[0];} break;
00626 case 6: if(m[0]!=m[1]) {position[2] = (-pow(32.,0.5)-c[0]+c[1])/(m[0]-m[1]);} break;
00627 case 7: if(m[1]!=0.) {position[2] = (4.-c[1])/m[1];} break;
00628 default: position[2] = -1.e99; break;
00629 }
00630
00631 if(position[2]!=-1.e99) {
00632 position[0]=m[0]*position[2]+c[0];
00633 position[1]=m[1]*position[2]+c[1];
00634 }
00635 else {position[0]=-1.e99; position[1]=-1.e99;}
00636
00637 return;
00638 }
00640
00641
00642
00644 void AlgTrackCam::SetupTimingInfo(UgliGeomHandle* ugh, const double& fFibreIndex)
00645 {
00646 double tpos(0.), fibre, ctime, digchg;
00647
00648 HitCam* hit = 0; CandStripHandle* strip = 0;
00649 const unsigned int npln = fPlaneInfo.size();
00650
00651
00652 StripListTime=9.e30;
00653
00654 for(unsigned int pln=0;pln<npln;pln++) {
00655
00656 for(unsigned int g=0; g<fHitArr[pln].size(); ++g) {
00657 hit = fHitArr[pln][g];
00658 strip = hit->GetCandStripHandle();
00659
00660 if( strip->GetPlaneView()==PlaneView::kU
00661 || strip->GetPlaneView()==PlaneView::kX ) tpos = -fPlaneInfo[pln].V;
00662 if( strip->GetPlaneView()==PlaneView::kV
00663 || strip->GetPlaneView()==PlaneView::kY ) tpos = fPlaneInfo[pln].U;
00664 PlexStripEndId stripid = strip->GetStripEndId();
00665 UgliStripHandle striphandle = ugh->GetStripHandle(stripid);
00666
00667 if(strip->GetNDigit(StripEnd::kPositive)>0) {
00668 fibre = striphandle.ClearFiber(StripEnd::kPositive)+striphandle.WlsPigtail(StripEnd::kPositive)+striphandle.GetHalfLength()-tpos;
00669 ctime = 3.0e8*strip->GetTime(StripEnd::kPositive)-fFibreIndex*fibre;
00670 digchg=strip->GetCharge(StripEnd::kPositive);
00671 fPlaneInfo[pln].Qp+=digchg; fPlaneInfo[pln].CTp+=digchg*ctime;
00672
00673 if(ctime<StripListTime) {StripListTime=ctime;}
00674 }
00675
00676 if(strip->GetNDigit(StripEnd::kNegative)>0) {
00677 fibre = striphandle.ClearFiber(StripEnd::kNegative)+striphandle.WlsPigtail(StripEnd::kNegative)+striphandle.GetHalfLength()+tpos;
00678 ctime = 3.0e8*strip->GetTime(StripEnd::kNegative)-fFibreIndex*fibre;
00679 digchg=strip->GetCharge(StripEnd::kNegative);
00680 fPlaneInfo[pln].Qm+=digchg; fPlaneInfo[pln].CTm+=digchg*ctime;
00681
00682 if(ctime<StripListTime) {StripListTime=ctime;}
00683 }
00684 }
00685 }
00686
00687
00688 if(StripListTime<8.e30) {
00689 for(unsigned int pln=0;pln<npln;pln++) {
00690 if(fPlaneInfo[pln].plnvuw>-1) {
00691 fPlaneInfo[pln].CTp-=StripListTime*fPlaneInfo[pln].Qp;
00692 fPlaneInfo[pln].CTm-=StripListTime*fPlaneInfo[pln].Qm;
00693 }
00694 }
00695 }
00696 else {StripListTime=0.;}
00697
00698 return;
00699 }
00701
00702
00703
00705 void AlgTrackCam::WeightsForTimingFits()
00706 {
00707
00708
00709
00710
00711 double ErrorParam[3] = { 0.58, 0.69, -0.33 };
00712 double MinUncertainty = ErrorParam[0];
00713 double Uncertainty = MinUncertainty;
00714
00715 const int npln = (int)fPlaneInfo.size();
00716
00717 int ctflag;
00718 double ctmin,ctmax,ctave,ctrms;
00719 double sq,sqct,sqctct,swgt;
00720 double wm,wp;
00721
00722 for(int i=0;i<npln;i++) {
00723
00724 fPlaneInfo[i].Wm = 0.0;
00725 fPlaneInfo[i].Wp = 0.0;
00726
00727 if(fPlaneInfo[i].plnvuw>-1) {
00728 wm=0.0; wp=0.0;
00729 ctflag=0; ctmin=0.0; ctmax=0.0; ctave=0.0; ctrms=0.0;
00730 sq=0.0; sqct=0.0; sqctct=0.0; swgt=0.0;
00731
00732 for(int j=-4;j<5;j++) {
00733 if( j!=0 && i+j>-1 && i+j<npln && fPlaneInfo[i+j].plnvuw>-1 ) {
00734 if( fPlaneInfo[i+j].Qm>1.0 && !( fPlaneInfo[i+j].Qp>0.0 && !(fPlaneInfo[i+j].CTm-fPlaneInfo[i+j].CTp>-4.0&&fPlaneInfo[i+j].CTm-fPlaneInfo[i+j].CTp<4.0) ) ) {
00735 if(ctflag) {
00736 if(fPlaneInfo[i+j].CTm<ctmin) {ctmin=fPlaneInfo[i+j].CTm;}
00737 if(fPlaneInfo[i+j].CTm>ctmax) {ctmax=fPlaneInfo[i+j].CTm;}
00738 }
00739 else {ctmin=fPlaneInfo[i+j].CTm; ctmax=fPlaneInfo[i+j].CTm; ctflag=1;}
00740
00741 sq+=fPlaneInfo[i+j].Qm; sqct+=fPlaneInfo[i+j].Qm*fPlaneInfo[i+j].CTm;
00742 sqctct+=fPlaneInfo[i+j].Qm*fPlaneInfo[i+j].CTm*fPlaneInfo[i+j].CTm;
00743 swgt+=1.0;
00744 }
00745
00746 if( fPlaneInfo[i+j].Qp>1.0 && !( fPlaneInfo[i+j].Qm>0.0 && !(fPlaneInfo[i+j].CTp-fPlaneInfo[i+j].CTm>-4.0&&fPlaneInfo[i+j].CTp-fPlaneInfo[i+j].CTm<4.0) ) ) {
00747 if(ctflag) {
00748 if(fPlaneInfo[i+j].CTp<ctmin) {ctmin=fPlaneInfo[i+j].CTp;}
00749 if(fPlaneInfo[i+j].CTp>ctmax) {ctmax=fPlaneInfo[i+j].CTp;}
00750 }
00751 else {ctmin=fPlaneInfo[i+j].CTp; ctmax=fPlaneInfo[i+j].CTp; ctflag=1;}
00752
00753 sq+=fPlaneInfo[i+j].Qp; sqct+=fPlaneInfo[i+j].Qp*fPlaneInfo[i+j].CTp;
00754 sqctct+=fPlaneInfo[i+j].Qp*fPlaneInfo[i+j].CTp*fPlaneInfo[i+j].CTp;
00755 swgt+=1.0;
00756 }
00757 }
00758 }
00759
00760
00761 if(swgt>1.0) {
00762 ctave=sqct/sq; ctrms=0.0;
00763 if((sqctct/sq)-(sqct/sq)*(sqct/sq)>0.0) {ctrms=sqrt((sqctct/sq)-(sqct/sq)*(sqct/sq));}
00764
00765 if( (fPlaneInfo[i].Qm>1.0) && (fPlaneInfo[i].CTm-ctmin>-2.0 && fPlaneInfo[i].CTm-ctmax<2.0)
00766 && (fPlaneInfo[i].CTm-ctave<ctrms+3.0 && fPlaneInfo[i].CTm-ctave>-ctrms-3.0) )
00767 {wm=fPlaneInfo[i].Qm;}
00768
00769 if( (fPlaneInfo[i].Qp>1.0) && (fPlaneInfo[i].CTp-ctmin>-2.0 && fPlaneInfo[i].CTp-ctmax<2.0)
00770 && (fPlaneInfo[i].CTp-ctave<ctrms+3.0 && fPlaneInfo[i].CTp-ctave>-ctrms-3.0) )
00771 {wp=fPlaneInfo[i].Qp;}
00772 }
00773
00774 if( wm>0.0 ){
00775 if( wm<25 ) { Uncertainty = ErrorParam[0]+exp(ErrorParam[1]+ErrorParam[2]*wm); }
00776 else{ Uncertainty=MinUncertainty; }
00777 fPlaneInfo[i].Wm = 1.0/pow(Uncertainty,2.0);
00778
00779 }
00780
00781 if( wp>0.0 ){
00782 if (wp<25 ){ Uncertainty = ErrorParam[0]+exp(ErrorParam[1]+ErrorParam[2]*wp); }
00783 else { Uncertainty=MinUncertainty; }
00784 fPlaneInfo[i].Wp = 1.0/pow(Uncertainty,2.0);
00785
00786 }
00787
00788 }
00789 }
00790
00791 return;
00792 }
00794
00795
00796
00798 void AlgTrackCam::SetTrackCoordinates(const int& bpln, int& plnm, int& plnp)
00799 {
00800 int pln;
00801 const int npln = (int)fPlaneInfo.size();
00802
00803 for(int i=0;i<npln;i++) {
00804 pln=bpln+i;
00805 if(fPlaneInfo[i].plnvuw>-1) {
00806 if(fPlaneInfo[i].Qm>0.0) {
00807 fPlaneInfo[i].CTm/=fPlaneInfo[i].Qm;
00808 }
00809 if(fPlaneInfo[i].Qp>0.0) {
00810 fPlaneInfo[i].CTp/=fPlaneInfo[i].Qp;
00811 }
00812 if(plnm<0||i<plnm) {plnm=i;}
00813 if(plnp<0||i>plnp) {plnp=i;}
00814 }
00815 }
00816
00817 return;
00818 }
00820
00821
00822
00824 void AlgTrackCam::CalculateTimingFits(double& dir, double& mytimeoffset, CandTrackHandle& cth)
00825 {
00826 WeightsForTimingFits();
00827 const int npln = (int)fPlaneInfo.size();
00828
00829
00830 double ctimeslope=0.0,ctimeoffset=0.0,ctimeaverage=0.0, RMS=0.0, CTCut=0.0, MinCT=-3000.;
00831 double Sq,Sqs,Sqss,Sqt,Sqtt,Sqst;
00832 double s,t,w;
00833 int npts=0;
00834 int* SkipM = new int[npln];
00835 int* SkipP = new int[npln];
00836 for(int i=0;i<npln;i++) { SkipM[i]=0; SkipP[i]=0; }
00837 Sq=0.0; Sqs=0.0; Sqss=0.0; Sqt=0.0; Sqtt=0.0; Sqst=0.0;
00838
00839
00840
00841 for(int itr=0; itr<3; ++itr) {
00842
00843 for(int i=0;i<npln;i++) {
00844
00845 if( fPlaneInfo[i].plnvuw>-1 ) {
00846
00847
00848 if( fPlaneInfo[i].Wm>0.0 && fPlaneInfo[i].CTm>MinCT ) {
00849 s=fPlaneInfo[i].dS; t=fPlaneInfo[i].CTm; w=fPlaneInfo[i].Wm;
00850
00851 if(itr==0) {
00852 Sqs+=w*s; Sqss+=w*s*s; Sqt+=w*t; Sqtt+=w*t*t; Sqst+=w*s*t;
00853 Sq+=w; npts++;
00854 }
00855 else if(fabs(t-ctimeoffset-(s*ctimeslope))>CTCut && SkipM[i]==0) {
00856 Sqs-=w*s; Sqss-=w*s*s; Sqt-=w*t; Sqtt-=w*t*t; Sqst-=w*s*t;
00857 Sq-=w; npts--; SkipM[i]=1;
00858 }
00859 }
00860
00861
00862 if( fPlaneInfo[i].Wp>0.0 && fPlaneInfo[i].CTp>MinCT ) {
00863 s=fPlaneInfo[i].dS; t=fPlaneInfo[i].CTp; w=fPlaneInfo[i].Wp;
00864
00865 if(itr==0) {
00866 Sqs+=w*s; Sqss+=w*s*s; Sqt+=w*t; Sqtt+=w*t*t; Sqst+=w*s*t;
00867 Sq+=w; npts++;
00868 }
00869 else if(fabs(t-ctimeoffset-(s*ctimeslope))>CTCut && SkipP[i]==0) {
00870 Sqs-=w*s; Sqss-=w*s*s; Sqt-=w*t; Sqtt-=w*t*t; Sqst-=w*s*t;
00871 Sq-=w; npts--; SkipP[i]=1;
00872 }
00873 }
00874
00875 }
00876 }
00877
00878 if(npts>2){
00879 ctimeslope=(Sq*Sqst-Sqs*Sqt)/(Sq*Sqss-Sqs*Sqs);
00880 ctimeoffset=(Sqt*Sqss-Sqs*Sqst)/(Sq*Sqss-Sqs*Sqs);
00881 ctimeaverage=(Sqt/Sq);
00882 if( ((Sqtt/Sq)-((Sqt/Sq)*(Sqt/Sq)))>0.0 ) {
00883 RMS = pow((Sqtt/Sq)-((Sqt/Sq)*(Sqt/Sq)),0.5);
00884 CTCut = 3.+RMS;
00885 }
00886 else {CTCut = 3.5;}
00887 }
00888
00889 }
00890
00891 delete[] SkipM;
00892 delete[] SkipP;
00894
00895
00896
00897 double Sw[2],Swt[2],Swtt[2];
00898 double chisqp=0.0,chisqm=0.0;
00899 int chisqndfp=0,chisqndfm=0;
00900 double time_score=0.0;
00901 double CTIntercept[2], Csigma[2],Ctrunc[2];
00902 double cp,cm;
00903 int Npts[2];
00904 MSG("AlgTrackCam", Msg::kDebug) << " POSITIVE FIT: " << endl;
00905 chisqp=-99999.9; cp=-99999.9;
00906 chisqm=-99999.9; cm=-99999.9;
00907 CTIntercept[0]=ctimeaverage; Csigma[0]=-99999.9; Ctrunc[0]=-99999.9;
00908 CTIntercept[1]=ctimeaverage; Csigma[1]=-99999.9; Ctrunc[1]=-99999.9;
00909
00910 for(int itr=0;itr<2;itr++)
00911 {
00912 Swtt[0]=0.0; Swt[0]=0.0; Sw[0]=0.0; Npts[0]=0;
00913 Swtt[1]=0.0; Swt[1]=0.0; Sw[1]=0.0; Npts[1]=0;
00914 for(int pln=0;pln<npln;pln++)
00915 {
00916 if( fPlaneInfo[pln].plnvuw>-1 )
00917 {
00918
00919 if( fPlaneInfo[pln].Wm>0.0 && fPlaneInfo[pln].CTm>MinCT )
00920 {
00921 w=fPlaneInfo[pln].Wm;
00922
00923 t=fPlaneInfo[pln].CTm-fPlaneInfo[pln].dS+CTIntercept[0];
00924 if( Ctrunc[0]<0.0 || fabs(t)<Ctrunc[0] ) { Swtt[0]+=w*t*t; Swt[0]+=w*t; Sw[0]+=w; Npts[0]++; }
00925
00926 t=fPlaneInfo[pln].CTm+fPlaneInfo[pln].dS+CTIntercept[1];
00927 if( Ctrunc[1]<0.0 || fabs(t)<Ctrunc[1] ) { Swtt[1]+=w*t*t; Swt[1]+=w*t; Sw[1]+=w; Npts[1]++; }
00928 }
00929 if( fPlaneInfo[pln].Wp>0.0 && fPlaneInfo[pln].CTp>MinCT )
00930 {
00931 w=fPlaneInfo[pln].Wp;
00932
00933 t=fPlaneInfo[pln].CTp-fPlaneInfo[pln].dS+CTIntercept[0];
00934 if( Ctrunc[0]<0.0 || fabs(t)<Ctrunc[0] ) { Swtt[0]+=w*t*t; Swt[0]+=w*t; Sw[0]+=w; Npts[0]++; }
00935
00936 t=fPlaneInfo[pln].CTp+fPlaneInfo[pln].dS+CTIntercept[1];
00937 if( Ctrunc[1]<0.0 || fabs(t)<Ctrunc[1] ) { Swtt[1]+=w*t*t; Swt[1]+=w*t; Sw[1]+=w; Npts[1]++; }
00938 }
00939 }
00940 }
00941 if(Npts[0]>1)
00942 {
00943 CTIntercept[0]=CTIntercept[0]-Swt[0]/Sw[0]; Csigma[0]=0.0;
00944 if((Swtt[0]/Sw[0])-(Swt[0]/Sw[0])*(Swt[0]/Sw[0])>0.0)
00945 {
00946 Csigma[0]=sqrt((Swtt[0]/Sw[0])-(Swt[0]/Sw[0])*(Swt[0]/Sw[0]));
00947 }
00948 chisqp=Csigma[0]; chisqndfp=Npts[0]-1; cp=-CTIntercept[0];
00949 Ctrunc[0]=Csigma[0]+3.0;
00950 }
00951 if(Npts[1]>1)
00952 {
00953 CTIntercept[1]=CTIntercept[1]-Swt[1]/Sw[1]; Csigma[1]=0.0;
00954 if((Swtt[1]/Sw[1])-(Swt[1]/Sw[1])*(Swt[1]/Sw[1])>0.0)
00955 {
00956 Csigma[1]=sqrt((Swtt[1]/Sw[1])-(Swt[1]/Sw[1])*(Swt[1]/Sw[1]));
00957 }
00958 chisqm=Csigma[1]; chisqndfm=Npts[1]-1; cm=-CTIntercept[1];
00959 Ctrunc[1]=Csigma[1]+3.0;
00960 }
00961 }
00962 MSG("AlgTrackCam", Msg::kDebug) << " *** CTIntercept[0]=" << CTIntercept[0] << " Csigma[0]=" << Csigma[0] << " *** " << endl;
00963 MSG("AlgTrackCam", Msg::kDebug) << " *** CTIntercept[1]=" << CTIntercept[1] << " Csigma[1]=" << Csigma[1] << " *** " << endl;
00964
00965
00966 dir=0.0;
00967 time_score=0.0; mytimeoffset=0.0;
00968 if(chisqm>0.0 && chisqp>0.0)
00969 {
00970 if(chisqp>chisqm) { dir=-1.0; time_score=1-chisqm/chisqp; mytimeoffset=cm; }
00971 else { dir=+1.0; time_score=1-chisqp/chisqm; mytimeoffset=cp; }
00972 time_score=dir*time_score;
00973 }
00974 if(time_score>0.0) dir=1.0; if(time_score<0.0) dir=-1.0;
00975
00976 MSG("AlgTrackCam", Msg::kDebug) << " timing parameters " << endl
00977 << " chisqp=" << chisqp << " (" << chisqndfp << ") "
00978 << " chisqm=" << chisqm << " (" << chisqndfm << ") " << endl
00979 << " score=" << time_score << endl;
00980
00981
00982 cth.SetTimeSlope((ctimeslope)/(3.0e8));
00983 cth.SetTimeOffset((ctimeoffset+StripListTime)/(3.0e8));
00984 cth.SetTimeForwardFitRMS(chisqp);
00985 cth.SetTimeForwardFitNDOF(chisqndfp);
00986 cth.SetTimeBackwardFitRMS(chisqm);
00987 cth.SetTimeBackwardFitNDOF(chisqndfm);
00988
00989 return;
00990 }
00992
00993
00994
00996 void AlgTrackCam::Trace(const char * ) const
00997 {
00998 }