00001
00002
00003
00004
00005
00006
00007
00009
00010 #include <cassert>
00011 #include <iostream>
00012
00013 #include "MessageService/MsgService.h"
00014 #include "CandShowerSR/CandShowerSR.h"
00015 #include "CandShowerSR/CandShowerSRHandle.h"
00016 #include "Navigation/NavKey.h"
00017 #include "Navigation/NavSet.h"
00018 #include "Validity/VldContext.h"
00019 #include "Algorithm/AlgConfig.h"
00020 #include "UgliGeometry/UgliGeomHandle.h"
00021 #include "UgliGeometry/UgliScintPlnHandle.h"
00022 #include "RecoBase/CandSliceHandle.h"
00023 #include "RecoBase/CandTrackHandle.h"
00024 #include "RecoBase/CandFitTrackHandle.h"
00025 #include "RecoBase/CandStripHandle.h"
00026 #include "Conventions/Mphysical.h"
00027 #include "Conventions/Munits.h"
00028 #include "TMath.h"
00029
00030 ClassImp(CandShowerSRHandle)
00031
00032
00033 CVSID("$Id: CandShowerSRHandle.cxx,v 1.26 2007/02/04 06:01:05 rhatcher Exp $");
00034
00035
00036 CandShowerSRHandle::CandShowerSRHandle()
00037 {
00038 }
00039
00040
00041 CandShowerSRHandle::CandShowerSRHandle(const CandShowerSRHandle &cdh) :
00042 CandShowerHandle(cdh)
00043 {
00044 }
00045
00046
00047 CandShowerSRHandle::CandShowerSRHandle(CandShowerSR *cd) :
00048 CandShowerHandle(cd)
00049 {
00050 }
00051
00052
00053 CandShowerSRHandle::~CandShowerSRHandle()
00054 {
00055 }
00056
00057
00058 CandShowerSRHandle *CandShowerSRHandle::DupHandle() const
00059 {
00060 return (new CandShowerSRHandle(*this));
00061 }
00062
00063
00064 void CandShowerSRHandle::Trace(const char *c) const
00065 {
00066 MSG("Cand", Msg::kDebug)
00067 << "**********Begin CandShowerSRHandle::Trace(\"" << c << "\")" << endl
00068 << "Information from CandShowerSRHandle's CandHandle: " << endl;
00069 CandHandle::Trace(c);
00070 MSG("Cand", Msg::kDebug)
00071 << "**********End CandShowerSRHandle::Trace(\"" << c << "\")" << endl;
00072 }
00073
00074
00075 void CandShowerSRHandle::AddSubShower(CandSubShowerSRHandle *subshower)
00076 {
00077 const TObjArray &subshowerlist =
00078 (dynamic_cast<CandShowerSR*>(GetOwnedCandBase()))->fSubShowerList;
00079 Bool_t found(0);
00080 for (Int_t i=0; i<=subshowerlist.GetLast() && !found; i++) {
00081 CandSubShowerSRHandle *target =
00082 dynamic_cast<CandSubShowerSRHandle*>(subshowerlist.At(i));
00083 if (*subshower == *target) found = 1;
00084 }
00085 if (!found) {
00086 if(subshower->GetPlaneView()==PlaneView::kU ||
00087 subshower->GetPlaneView()==PlaneView::kX) {
00088 (dynamic_cast<CandShowerSR*>(GetOwnedCandBase()))->fSubShowerList.
00089 Add(subshower->DupHandle());
00090 dynamic_cast<CandShowerSR*>(GetOwnedCandBase())->nUSubShowers+=1;
00091 }
00092 else if(subshower->GetPlaneView()==PlaneView::kV ||
00093 subshower->GetPlaneView()==PlaneView::kY) {
00094 (dynamic_cast<CandShowerSR*>(GetOwnedCandBase()))->fSubShowerList.
00095 Add(subshower->DupHandle());
00096 dynamic_cast<CandShowerSR*>(GetOwnedCandBase())->nVSubShowers+=1;
00097 }
00098 else {
00099 MSG("SubShowerSR",Msg::kWarning) << "Unknown SubShower View! Not adding it to ClusterList"
00100 << endl;
00101 }
00102 }
00103 return;
00104 }
00105
00106
00107 void CandShowerSRHandle::RemoveSubShower(CandSubShowerSRHandle *subshower)
00108 {
00109 const TObjArray &subshowerlist =
00110 (dynamic_cast<CandShowerSR*>(GetOwnedCandBase()))->fSubShowerList;
00111 Bool_t found(0);
00112 for (Int_t i=0; i<=subshowerlist.GetLast() && !found; i++) {
00113 CandSubShowerSRHandle *target =
00114 dynamic_cast<CandSubShowerSRHandle*>(subshowerlist.At(i));
00115 if (*subshower == *target){
00116 if(subshower->GetPlaneView()==PlaneView::kU ||
00117 subshower->GetPlaneView()==PlaneView::kX) {
00118 dynamic_cast<CandShowerSR*>(GetOwnedCandBase())->nUSubShowers-=1;
00119 }
00120 else if(subshower->GetPlaneView()==PlaneView::kV ||
00121 subshower->GetPlaneView()==PlaneView::kY) {
00122 dynamic_cast<CandShowerSR*>(GetOwnedCandBase())->nVSubShowers-=1;
00123 }
00124 (dynamic_cast<CandShowerSR*>(GetOwnedCandBase()))->fSubShowerList.
00125 RemoveAt(i);
00126 delete target;
00127 (dynamic_cast<CandShowerSR*>(GetOwnedCandBase()))->fSubShowerList.
00128 Compress();
00129 return;
00130 }
00131 }
00132 return;
00133 }
00134
00135
00136
00137 const CandSubShowerSRHandle *CandShowerSRHandle::GetSubShower(Int_t i) const
00138 {
00139 const TObjArray *fSubShowerList = &(dynamic_cast<const CandShowerSR*>
00140 (GetCandBase())->fSubShowerList);
00141 if (i>fSubShowerList->GetLast()) {
00142 return 0;
00143 }
00144 return dynamic_cast<const CandSubShowerSRHandle*>(fSubShowerList->At(i));
00145 }
00146
00147 Int_t CandShowerSRHandle::GetLastSubShower() const
00148 {
00149 return dynamic_cast<const CandShowerSR*>(GetCandBase())->fSubShowerList.
00150 GetLast();
00151 }
00152
00153
00154
00155 void CandShowerSRHandle::SetNumSubShowersU(Int_t nusubshw)
00156 {
00157 dynamic_cast<CandShowerSR*>(GetOwnedCandBase())->nUSubShowers = nusubshw;
00158 }
00159
00160 Int_t CandShowerSRHandle::GetNumSubShowersU() const
00161 {
00162 return dynamic_cast<const CandShowerSR*>(GetCandBase())->nUSubShowers;
00163 }
00164
00165
00166
00167 void CandShowerSRHandle::SetNumSubShowersV(Int_t nusubshw)
00168 {
00169 dynamic_cast<CandShowerSR*>(GetOwnedCandBase())->nVSubShowers = nusubshw;
00170 }
00171
00172 Int_t CandShowerSRHandle::GetNumSubShowersV() const
00173 {
00174 return dynamic_cast<const CandShowerSR*>(GetCandBase())->nVSubShowers;
00175 }
00176
00177
00178
00179 Float_t CandShowerSRHandle::GetMinPhysU(Int_t iplane) const{
00180 Float_t minU = 999;
00181 for(int i=0;i<=this->GetLastSubShower();i++){
00182 const CandSubShowerSRHandle *ssh = this->GetSubShower(i);
00183 if(ssh->GetPlaneView()==PlaneView::kU &&
00184 (ssh->GetClusterID()==ClusterType::kEMLike ||
00185 ssh->GetClusterID()==ClusterType::kHadLike ||
00186 ssh->GetClusterID()==ClusterType::kTrkLike) ) {
00187 Float_t testMinU = ssh->GetMinU(iplane);
00188 if(testMinU<minU) minU = testMinU;
00189 }
00190 }
00191
00192 return minU;
00193 }
00194
00195
00196 Float_t CandShowerSRHandle::GetMinPhysV(Int_t iplane) const{
00197 Float_t minV = 999;
00198 for(int i=0;i<=this->GetLastSubShower();i++){
00199 const CandSubShowerSRHandle *ssh = this->GetSubShower(i);
00200 if(ssh->GetPlaneView()==PlaneView::kV &&
00201 (ssh->GetClusterID()==ClusterType::kEMLike ||
00202 ssh->GetClusterID()==ClusterType::kHadLike ||
00203 ssh->GetClusterID()==ClusterType::kTrkLike) ) {
00204 Float_t testMinV = ssh->GetMinV(iplane);
00205 if(testMinV<minV) minV = testMinV;
00206 }
00207 }
00208
00209 return minV;
00210 }
00211
00212
00213
00214 Float_t CandShowerSRHandle::GetMaxPhysU(Int_t iplane) const{
00215 Float_t maxU = -999;
00216 for(int i=0;i<=this->GetLastSubShower();i++){
00217 const CandSubShowerSRHandle *ssh = this->GetSubShower(i);
00218 if(ssh->GetPlaneView()==PlaneView::kU &&
00219 (ssh->GetClusterID()==ClusterType::kEMLike ||
00220 ssh->GetClusterID()==ClusterType::kHadLike ||
00221 ssh->GetClusterID()==ClusterType::kTrkLike) ) {
00222 Float_t testMaxU = ssh->GetMaxU(iplane);
00223 if(testMaxU>maxU) maxU = testMaxU;
00224 }
00225 }
00226
00227 return maxU;
00228 }
00229
00230
00231
00232 Float_t CandShowerSRHandle::GetMaxPhysV(Int_t iplane) const {
00233 Float_t maxV = -999;
00234 for(int i=0;i<=this->GetLastSubShower();i++){
00235 const CandSubShowerSRHandle *ssh = this->GetSubShower(i);
00236 if(ssh->GetPlaneView()==PlaneView::kV &&
00237 (ssh->GetClusterID()==ClusterType::kEMLike ||
00238 ssh->GetClusterID()==ClusterType::kHadLike ||
00239 ssh->GetClusterID()==ClusterType::kTrkLike) ) {
00240 Float_t testMaxV = ssh->GetMaxV(iplane);
00241 if(testMaxV>maxV) maxV = testMaxV;
00242 }
00243 }
00244
00245 return maxV;
00246 }
00247
00248
00249 Int_t CandShowerSRHandle::GetNPhysStrips(Int_t iplane) const{
00250 Int_t nstrips=0;
00251 for(int i=0;i<=this->GetLastSubShower();i++){
00252 const CandSubShowerSRHandle *ssh = this->GetSubShower(i);
00253 if(ssh->GetClusterID()==ClusterType::kEMLike ||
00254 ssh->GetClusterID()==ClusterType::kHadLike ||
00255 ssh->GetClusterID()==ClusterType::kTrkLike ) {
00256 nstrips += ssh->GetNStrips(iplane);
00257 }
00258 }
00259 return nstrips;
00260 }
00261
00262
00263 Bool_t CandShowerSRHandle::BelongsWithTrack(CandTrackHandle * trk,
00264 AlgConfig & ac,
00265 const VldContext * vldcptr,
00266 Double_t tolTPos2,
00267 Double_t tolZPos,
00268 Double_t tolTime){
00269
00270 MSG("ShowerSR",Msg::kDebug) << "In CandShowerSRHandle::BelongsWithTrack()"
00271 << endl;
00272 if(!trk) return false;
00273 Int_t pSMPlaneLast = ac.GetInt("SMPlaneLast");
00274 Int_t pSMPlaneFirst = ac.GetInt("SMPlaneFirst");
00275 VldContext vldc = *vldcptr;
00276 UgliGeomHandle ugh(vldc);
00277
00278
00279 Double_t shwChargeU = 0; Double_t shwChargeV = 0;
00280 Double_t shwStripsU = 0; Double_t shwStripsV = 0;
00281 Bool_t noPhysicalSubShowersU = true;
00282 Bool_t noPhysicalSubShowersV = true;
00283 for(int i=0;i<=this->GetLastSubShower();i++){
00284 const CandSubShowerSRHandle *subshw = this->GetSubShower(i);
00285 if(subshw->GetPlaneView()==PlaneView::kU) {
00286 shwChargeU += subshw->GetCharge(CalStripType::kPE);
00287 shwStripsU += subshw->GetNStrip();
00288 if(subshw->GetClusterID()==ClusterType::kEMLike ||
00289 subshw->GetClusterID()==ClusterType::kHadLike ||
00290 subshw->GetClusterID()==ClusterType::kTrkLike) {
00291 noPhysicalSubShowersU = false;
00292 }
00293 }
00294 else if(subshw->GetPlaneView()==PlaneView::kV) {
00295 shwChargeV += subshw->GetCharge(CalStripType::kPE);
00296 shwStripsV += subshw->GetNStrip();
00297 if(subshw->GetClusterID()==ClusterType::kEMLike ||
00298 subshw->GetClusterID()==ClusterType::kHadLike ||
00299 subshw->GetClusterID()==ClusterType::kTrkLike) {
00300 noPhysicalSubShowersV = false;
00301 }
00302 }
00303 }
00304 Double_t shwChargeAsym = ( TMath::Abs(shwChargeU - shwChargeV) /
00305 (shwChargeU+shwChargeV) );
00306
00307
00308 Double_t dt = trk->GetVtxT() - this->GetVtxT();
00309 if(trk->IsTPosValid(this->GetVtxPlane())){
00310 dt = this->GetVtxT() - trk->GetT(this->GetVtxPlane());
00311 }
00312 if(TMath::Abs(dt*1e9)>1e5) dt = 0;
00313
00314
00315 Int_t fwdTrkPlane = min(trk->GetVtxPlane(),trk->GetEndPlane());
00316 Int_t bckTrkPlane = max(trk->GetVtxPlane(),trk->GetEndPlane());
00317 Int_t fwdShwPlane = min(this->GetVtxPlane(),this->GetEndPlane());
00318 Int_t bckShwPlane = max(this->GetVtxPlane(),this->GetEndPlane());
00319
00320 if( bckShwPlane>=fwdTrkPlane && fwdShwPlane<=bckTrkPlane &&
00321 TMath::Abs(dt)<tolTime) {
00322
00323 MSG("ShowerSR",Msg::kDebug) << " trk and shower overlap in Z and time "
00324 << endl;
00325
00326 Float_t tolTPos = 0.35;
00327
00328 Bool_t matchu=false;
00329 Bool_t matchv=false;
00330 Bool_t nonphysmatchu=false;
00331 Bool_t nonphysmatchv=false;
00332
00333 for (Int_t iplane=fwdShwPlane; iplane<=bckShwPlane;iplane++){
00334 PlexPlaneId plnid(GetVldContext()->GetDetector(),iplane,false);
00335 if(plnid.GetPlaneView()==PlaneView::kU){
00336 Double_t trkU = trk->GetU(iplane);
00337 if(!trk->IsTPosValid(iplane)){
00338 if(TMath::Abs(iplane - trk->GetVtxPlane()) <
00339 TMath::Abs(iplane - trk->GetEndPlane())) {
00340 UgliScintPlnHandle scintpln = ugh.GetScintPlnHandle(plnid);
00341 Double_t dz=scintpln.GetZ0()-trk->GetVtxZ();
00342 trkU = (trk->GetVtxU() +
00343 dz*trk->GetVtxDirCosU()/trk->GetVtxDirCosZ());
00344 }
00345 else{
00346 UgliScintPlnHandle scintpln = ugh.GetScintPlnHandle(plnid);
00347 Double_t dz=scintpln.GetZ0()-trk->GetEndZ();
00348 trkU = (trk->GetEndU() +
00349 dz*trk->GetEndDirCosU()/trk->GetEndDirCosZ());
00350 }
00351 }
00352 if(this->GetNPhysStrips(iplane)>0 &&
00353 trkU>=this->GetMinPhysU(iplane)-tolTPos &&
00354 trkU<=this->GetMaxPhysU(iplane)+tolTPos) {
00355 MSG("ShowerSR", Msg::kDebug) << " u match! (details follow)"
00356 << endl;
00357 matchu=true;
00358 }
00359 else if(noPhysicalSubShowersU &&
00360 trkU>=this->GetMinU(iplane)-tolTPos &&
00361 trkU<=this->GetMaxU(iplane)+tolTPos) {
00362 MSG("ShowerSR", Msg::kDebug) << " u match! (details follow)"
00363 << endl;
00364 nonphysmatchu=true;
00365 }
00366 MSG("ShowerSR",Msg::kDebug)
00367 << " plane " << iplane << " trk u " << trkU
00368 << " min/max U " << this->GetMinU(iplane) << "/"
00369 << this->GetMaxU(iplane)
00370 << " phys min/max U " << this->GetMinPhysU(iplane) << "/"
00371 << this->GetMaxPhysU(iplane) << endl;
00372 }
00373 else if(plnid.GetPlaneView()==PlaneView::kV){
00374 Double_t trkV = trk->GetV(iplane);
00375 if(!trk->IsTPosValid(iplane)){
00376 if(TMath::Abs(iplane - trk->GetVtxPlane()) <
00377 TMath::Abs(iplane - trk->GetEndPlane())) {
00378 UgliScintPlnHandle scintpln = ugh.GetScintPlnHandle(plnid);
00379 Double_t dz=scintpln.GetZ0()-trk->GetVtxZ();
00380 trkV = (trk->GetVtxV() +
00381 dz*trk->GetDirCosV()/trk->GetDirCosZ());
00382 }
00383 else{
00384 UgliScintPlnHandle scintpln = ugh.GetScintPlnHandle(plnid);
00385 Double_t dz=scintpln.GetZ0()-trk->GetEndZ();
00386 trkV= (trk->GetEndV() +
00387 dz*trk->GetEndDirCosV()/trk->GetEndDirCosZ());
00388 }
00389 }
00390 if(this->GetNPhysStrips(iplane)>0 &&
00391 trkV>=this->GetMinPhysV(iplane)-tolTPos &&
00392 trkV<=this->GetMaxPhysV(iplane)+tolTPos) {
00393 MSG("ShowerSR", Msg::kDebug) << " v match! (details follow)"
00394 << endl;
00395 matchv=true;
00396 }
00397 else if(noPhysicalSubShowersV &&
00398 trkV>=this->GetMinV(iplane)-tolTPos &&
00399 trkV<=this->GetMaxV(iplane)+tolTPos) {
00400 MSG("ShowerSR", Msg::kDebug) << " v match! (details follow)"
00401 << endl;
00402 nonphysmatchv=true;
00403 }
00404 MSG("ShowerSR",Msg::kDebug)
00405 << " plane " << iplane << " trk v " << trkV
00406 << " min/max V " << this->GetMinV(iplane) << "/"
00407 << this->GetMaxV(iplane)
00408 << " phys min/max V " << this->GetMinPhysV(iplane) << "/"
00409 << this->GetMaxPhysV(iplane) << endl;
00410 }
00411
00412 if(matchu && matchv) {
00413 MSG("ShowerSR", Msg::kDebug) << " Phys 3D match! " << endl;
00414 return true;
00415 }
00416 else if( matchu || matchv ){
00417 MSG("ShowerSR", Msg::kDebug)
00418 << "Match Stat: " << matchu << " " << matchv << " "
00419 << "Shower Charge: " << shwChargeU << " " << shwChargeV << " "
00420 << "Shower Charge Asymmetry: " << shwChargeAsym << endl;
00421 if(matchu && shwChargeV<10. &&
00422 shwChargeV/shwStripsV < 3. && shwChargeAsym>0.7 ) return true;
00423 else if(matchv && shwChargeU<10. &&
00424 shwChargeU/shwStripsU < 3. && shwChargeAsym>0.7 ) return true;
00425 else if( (matchu && nonphysmatchv) ||
00426 (matchv && nonphysmatchu) ) return true;
00427 }
00428 else if(nonphysmatchu && nonphysmatchv) {
00429 MSG("ShowerSR", Msg::kDebug) << " Non-Phys 3D match! " << endl;
00430 return true;
00431 }
00432 else if(nonphysmatchu || nonphysmatchv) {
00433 MSG("ShowerSR", Msg::kDebug)
00434 << "Match Stat: " << nonphysmatchu << " " << nonphysmatchv << " "
00435 << "Shower Charge: " << shwChargeU << " " << shwChargeV << " "
00436 << "Shower Charge Asymmetry: " << shwChargeAsym << endl;
00437 if(shwChargeU/shwStripsU < 3. || shwChargeV/shwStripsV < 3. ||
00438 shwChargeAsym > 0.6) return true;
00439 }
00440 }
00441
00442
00443
00444 Double_t phDistance = 0;
00445 Double_t phDistanceU = 0;
00446 Double_t phDistanceV = 0;
00447 TIter stripItr(GetDaughterIterator());
00448 while (CandStripHandle *strip =
00449 dynamic_cast<CandStripHandle*>(stripItr())) {
00450 if(strip->GetPlaneView()==PlaneView::kU) {
00451 if(!trk->IsTPosValid(strip->GetPlane())) continue;
00452 Double_t trkU = trk->GetU(strip->GetPlane());
00453 phDistance += strip->GetCharge(CalDigitType::kPE) *
00454 TMath::Power(strip->GetTPos()-trkU,2);
00455 phDistanceU += strip->GetCharge(CalDigitType::kPE) *
00456 TMath::Power(strip->GetTPos()-trkU,2);
00457 }
00458 else if(strip->GetPlaneView()==PlaneView::kV){
00459 if(!trk->IsTPosValid(strip->GetPlane())) continue;
00460 Double_t trkV = trk->GetV(strip->GetPlane());
00461 phDistance += strip->GetCharge(CalDigitType::kPE) *
00462 TMath::Power(strip->GetTPos()-trkV,2);
00463 phDistanceV += strip->GetCharge(CalDigitType::kPE) *
00464 TMath::Power(strip->GetTPos()-trkV,2);
00465 }
00466 }
00467 if(shwChargeU+shwChargeV>0) phDistance /= (shwChargeU+shwChargeV);
00468 phDistance = TMath::Sqrt(phDistance);
00469 if(shwChargeU>0) phDistanceU /= shwChargeU;
00470 phDistanceU = TMath::Sqrt(phDistanceU);
00471 if(shwChargeV>0) phDistanceV /= shwChargeV;
00472 phDistanceV = TMath::Sqrt(phDistanceV);
00473 MSG("ShowerSR",Msg::kDebug) << "phDistance = " << phDistance
00474 << " phDistanceU = " << phDistanceU
00475 << " phDistanceV = " << phDistanceV
00476 << endl;
00477 if(phDistance < tolTPos ||
00478 (phDistanceU < tolTPos && shwChargeAsym>0.6) ||
00479 (phDistanceV < tolTPos && shwChargeAsym>0.6) ) return true;
00480 }
00481
00482
00483
00484 if( this->GetVtxZ()>min(trk->GetVtxZ(),trk->GetEndZ())-tolZPos &&
00485 this->GetVtxZ()<max(trk->GetVtxZ(),trk->GetEndZ())+tolZPos) {
00486 Double_t du = trk->GetVtxU() - this->GetVtxU();
00487 Double_t dv = trk->GetVtxV() - this->GetVtxV();
00488 dt = trk->GetVtxT() - this->GetVtxT();
00489 if(trk->IsTPosValid(this->GetVtxPlane())){
00490 du = this->GetVtxU()-trk->GetU(this->GetVtxPlane());
00491 dv = this->GetVtxV()-trk->GetV(this->GetVtxPlane());
00492 dt = this->GetVtxT()-trk->GetT(this->GetVtxPlane());
00493 }
00494 MSG("ShowerSR",Msg::kDebug)
00495 << "Vertex check at plane " << this->GetVtxPlane()
00496 << ": du^{2}+dv^{2} = " << du*du+dv*dv << "(/" << tolTPos2
00497 << "); dt = " << dt*1.e9 << "(/" << tolTime*1e9 << ")" << endl;
00498
00499 if(dt<tolTime && du*du+dv*dv<tolTPos2) return true;
00500 }
00501
00502
00503 Double_t trkZ = trk->GetVtxZ();
00504 Double_t trkU = trk->GetVtxU();
00505 Double_t trkV = trk->GetVtxV();
00506 Double_t trkT = trk->GetVtxT();
00507 Int_t trkPlane = trk->GetVtxPlane();
00508 Double_t trkDirU = trk->GetVtxDirCosU();
00509 Double_t trkDirV = trk->GetVtxDirCosV();
00510 Double_t trkDirZ = trk->GetVtxDirCosZ();
00511
00512 if(TMath::Abs(this->GetVtxZ() - trk->GetEndZ()) <
00513 TMath::Abs(this->GetVtxZ() - trk->GetVtxZ())){
00514 trkZ = trk->GetEndZ();
00515 trkU = trk->GetEndU();
00516 trkV = trk->GetEndV();
00517 trkT = trk->GetEndT();
00518 trkDirU = trk->GetEndDirCosU();
00519 trkDirV = trk->GetEndDirCosV();
00520 trkDirZ = trk->GetEndDirCosZ();
00521 trkPlane = trk->GetEndPlane();
00522 }
00523
00524 Double_t dz = trkZ - this->GetVtxZ();
00525 Double_t du = trkU - this->GetVtxU();
00526 if(trkDirZ>0) du = (trkU - dz*trkDirU/trkDirZ) - this->GetVtxU();
00527 Double_t dv = trkV - this->GetVtxV();
00528 if(trkDirZ>0) dv = (trkV - dz*trkDirV/trkDirZ) - this->GetVtxV();
00529 dt = trkT - this->GetVtxT();
00530
00531
00532 if (vldcptr->GetDetector()==Detector::kFar) {
00533 if((trkPlane<=pSMPlaneLast && this->GetVtxPlane()>=pSMPlaneFirst) ||
00534 (trkPlane>=pSMPlaneLast && this->GetVtxPlane()<=pSMPlaneFirst))
00535 dz = (trkPlane - this->GetVtxPlane())*0.0594;
00536 }
00537
00538 MSG("ShowerSR",Msg::kDebug)
00539 << "Delta(vertex) shower/track (u,v,z,t): "
00540 << du << " " << dv << " " << dz <<" " << dt*1.e9 << endl;
00541 if (du*du+dv*dv<tolTPos2 && TMath::Abs(dz)<tolZPos &&
00542 TMath::Abs(dt)<tolTime) return true;
00543
00544
00545 dz = trkZ - this->GetEndZ();
00546 du = (trkU - dz*trkDirU/trkDirZ) - this->GetEndU();
00547 dv = (trkV - dz*trkDirV/trkDirZ) - this->GetEndV();
00548 dt = trkT - this->GetVtxT();
00549
00550
00551 if (vldcptr->GetDetector()==Detector::kFar) {
00552 if((trkPlane<=pSMPlaneLast && this->GetEndPlane()>=pSMPlaneFirst) ||
00553 (trkPlane>=pSMPlaneLast && this->GetEndPlane()<=pSMPlaneFirst))
00554 dz = (trkPlane - this->GetEndPlane())*0.0594;
00555 }
00556
00557 MSG("ShowerSR",Msg::kDebug)
00558 << "Delta(vertex) shower/track (u,v,z,t): "
00559 << du << " " << dv << " " << dz <<" " << dt*1.e9 << endl;
00560 if (du*du+dv*dv<tolTPos2 && TMath::Abs(dz)<tolZPos &&
00561 TMath::Abs(dt)<tolTime) return true;
00562
00563 return false;
00564 }
00565
00566
00567 Bool_t CandShowerSRHandle::BelongsWithShower(CandShowerHandle * shw,
00568 AlgConfig & ,
00569 const VldContext * ,
00570 Double_t tolTPos2,
00571 Double_t tolZPos,
00572 Double_t tolTime){
00573
00574 MSG("ShowerSR",Msg::kDebug) << "In BelongsWithShower()" << endl;
00575
00576 tolZPos = 10.0;
00577 tolTime = 7.5;
00578 tolTPos2 = 10.0*10.0;
00579
00580 if(shw->InheritsFrom("CandShowerSRHandle")) {
00581 CandShowerSRHandle *shwSR = dynamic_cast<CandShowerSRHandle*> (shw);
00582
00583 Double_t xyzDistance =
00584 TMath::Sqrt( ( TMath::Power(shwSR->GetVtxU()-this->GetVtxU(),2) +
00585 TMath::Power(shwSR->GetVtxV()-this->GetVtxV(),2) +
00586 TMath::Power(shwSR->GetVtxZ()-this->GetVtxZ(),2) ) );
00587 Double_t temp = 0;
00588 Double_t xyztDistance =
00589 TMath::Sqrt( ( TMath::Power(shwSR->GetVtxU()-this->GetVtxU(),2) +
00590 TMath::Power(shwSR->GetVtxV()-this->GetVtxV(),2) +
00591 TMath::Power(shwSR->GetVtxZ()-this->GetVtxZ(),2) +
00592 TMath::Power(Mphysical::c_light*
00593 (shwSR->GetPHWTime(temp) -
00594 this->GetPHWTime(temp)),2) ) );
00595
00596 MSG("ShowerSR",Msg::kDebug) << "xyzDistance = " << xyzDistance << endl;
00597 MSG("ShowerSR",Msg::kDebug) << "xyztDistance = " << xyztDistance << endl;
00598
00599 if(xyztDistance<1.5) return true;
00600 }
00601
00602 Double_t minZDistance = shw->GetVtxZ() - this->GetVtxZ();
00603 if(minZDistance<0) minZDistance = this->GetVtxZ() - shw->GetVtxZ();
00604 Double_t minTDistance2 = (TMath::Power(shw->GetVtxU() - this->GetVtxU(),2) +
00605 TMath::Power(shw->GetVtxV() - this->GetVtxV(),2) );
00606
00607 if( minZDistance > tolZPos ) return false;
00608 if( minTDistance2 > tolTPos2 ) return false;
00609
00610 MSG("ShowerSR",Msg::kDebug) << "Z Separation = " << minZDistance
00611 << " (< " << tolZPos << ")" << endl;
00612 MSG("ShowerSR",Msg::kDebug) << "TPos^2 Separation = " << minTDistance2
00613 << " (< " << tolTPos2 << ")" << endl;
00614
00615 Double_t realDistance = TMath::Sqrt(TMath::Power(minZDistance,2) +
00616 minTDistance2 );
00617 MSG("ShowerSR",Msg::kDebug) << "True Separation = "
00618 << realDistance << endl;
00619
00620
00621 Double_t uppShwEn = TMath::Power(0.55/2. +
00622 TMath::Sqrt(0.55*0.55/4. + shw->GetEnergy(CandShowerHandle::kCC)),2);
00623
00624 Double_t mOverE = (Mphysical::neutron_mass_c2/Munits::hep2baseMass)/
00625 shw->GetEnergy(CandShowerHandle::kCC);
00626 Double_t upp_mOverE = (Mphysical::neutron_mass_c2/Munits::hep2baseMass)/uppShwEn;
00627
00628 if(mOverE > 0.98) mOverE = upp_mOverE;
00629 if(mOverE > 0.98) mOverE = 0.98;
00630 Double_t neutronSpeed = ( TMath::Sqrt(1. - TMath::Power(mOverE,2)) *
00631 Mphysical::c_light );
00632
00633 Double_t predTime = 1.0e9*realDistance/neutronSpeed;
00634 Double_t predTime_c = 1.0e9*realDistance/Mphysical::c_light;
00635 if(shw->GetVtxZ() - this->GetVtxZ()<0) {
00636 predTime = -predTime;
00637 predTime_c = -predTime_c;
00638 }
00639
00640 Double_t realPHWTime = 0;
00641 Double_t realAveTime = 0;
00642 Double_t phErr1=0,phErr2=0,err1=0,err2=0;
00643 if(shw->InheritsFrom("CandShowerSRHandle")) {
00644 CandShowerSRHandle *shwSR = dynamic_cast<CandShowerSRHandle*> (shw);
00645 realPHWTime = 1.0e9*(shwSR->GetPHWTime(phErr2) - this->GetPHWTime(phErr1));
00646 realAveTime = 1.0e9*(shwSR->GetAveTime(err2) - this->GetAveTime(err1));
00647 phErr1*=1e9; phErr2*=1e9; err1*=1e9; err2*=1e9;
00648 }
00649 else {
00650 realPHWTime = 1.0e9*(shw->GetVtxT() - this->GetEndT());
00651 realAveTime = realPHWTime;
00652 }
00653
00654 Double_t realPHWTimeErr = TMath::Sqrt(phErr1*phErr1 + phErr2*phErr2);
00655 Double_t realAveTimeErr = TMath::Sqrt(err1*err1 + err2*err2);
00656
00657 MSG("ShowerSR",Msg::kDebug)
00658 << "\nPredicted Time Separation = " << predTime
00659 << " (assuming c = " << predTime_c << ")"
00660 << "\nActual Time Separation = (PH-weighted average,simple average) "
00661 << realPHWTime << " +/- " << realPHWTimeErr
00662 << " " << realAveTime << " +/- " << realAveTimeErr << endl;
00663
00664 if(TMath::Abs(predTime-realPHWTime)<realPHWTimeErr ||
00665 TMath::Abs(predTime-realAveTime)<realAveTimeErr ||
00666 ( realPHWTime+realPHWTimeErr>=predTime_c &&
00667 realPHWTime-realPHWTimeErr<=predTime) ||
00668 ( realAveTime+realAveTimeErr>=predTime_c &&
00669 realAveTime-realAveTimeErr<=predTime) ) return true;
00670 return false;
00671
00672 }
00673
00674
00675
00676 Bool_t CandShowerSRHandle::BuriedTrack(CandTrackHandle *track,
00677 Double_t pMinTrackIsolation,
00678 Int_t *stats)
00679 {
00680 if(stats) {
00681 for(int i=0;i<8;i++) stats[i] = -1;
00682 }
00683
00684 Int_t firstTrkPlane = TMath::Min(track->GetBegPlane(),
00685 track->GetEndPlane());
00686 Int_t lastTrkPlane = TMath::Max(track->GetBegPlane(),
00687 track->GetEndPlane());
00688 Int_t firstShwPlane = TMath::Min(this->GetBegPlane(),
00689 this->GetEndPlane());
00690 Int_t lastShwPlane = TMath::Max(this->GetBegPlane(),
00691 this->GetEndPlane());
00692
00693 Int_t firstSharedPlane = 500;
00694 Int_t lastSharedPlane = 0;
00695
00696 CandFitTrackHandle *fittrack = NULL;
00697 if(track->InheritsFrom("CandFitTrackHandle")) {
00698 fittrack = dynamic_cast<CandFitTrackHandle*> (track);
00699 MSG("ShowerSR",Msg::kDebug) << "Track Pass? " << fittrack->GetPass() << endl;
00700 }
00701
00702
00703 Int_t nSharedPlanes = lastShwPlane - firstTrkPlane + 1;
00704 if(nSharedPlanes<0) nSharedPlanes = 0;
00705 else {
00706 if(firstTrkPlane<firstShwPlane) {
00707 nSharedPlanes += firstTrkPlane-firstShwPlane;
00708 firstSharedPlane = firstShwPlane;
00709 }
00710 else firstSharedPlane = firstTrkPlane;
00711 if(lastTrkPlane<lastShwPlane) {
00712 nSharedPlanes += lastTrkPlane-lastShwPlane;
00713 lastSharedPlane = lastTrkPlane;
00714 }
00715 else lastSharedPlane = lastShwPlane;
00716 }
00717 if(nSharedPlanes<=0) return false;
00718 if(stats) stats[0] = nSharedPlanes;
00719
00720 MSG("ShowerSR",Msg::kDebug) << "lastTrkPlane = " << lastTrkPlane
00721 << " firstTrkPlane = " << firstTrkPlane
00722 << endl;
00723 MSG("ShowerSR",Msg::kDebug) << "lastShwPlane = " << lastShwPlane
00724 << " firstShwPlane = " << firstShwPlane
00725 << endl;
00726 MSG("ShowerSR",Msg::kDebug) << "nSharedPlanes = " << nSharedPlanes << endl;
00727
00728 Int_t nMissingIsoPlanes = 0;
00729 Int_t nMissingSharedPlanes = 0;
00730 Float_t planeCharge[500] = {};
00731 if(fittrack) {
00732 if(fittrack->GetPass()) {
00733 for(int iplane=firstTrkPlane;iplane<=lastTrkPlane;iplane++){
00734 MSG("ShowerSR",Msg::kVerbose) << iplane << " "
00735 << track->GetPlaneCharge(iplane) << endl;
00736 planeCharge[iplane] = track->GetPlaneCharge(iplane);
00737 if(track->GetPlaneCharge(iplane)==0) {
00738 if(iplane>=firstSharedPlane && iplane<=lastSharedPlane)
00739 nMissingSharedPlanes+=1;
00740 else nMissingIsoPlanes+=1;
00741 }
00742 }
00743 }
00744 else {
00745 const CandSliceHandle *slice = fittrack->GetCandSlice();
00746 nMissingSharedPlanes = lastSharedPlane - firstSharedPlane + 1;
00747 nMissingIsoPlanes = lastTrkPlane - firstTrkPlane + 1 - nMissingSharedPlanes;
00748 for(int iplane=firstTrkPlane;iplane<=lastTrkPlane;iplane++){
00749 TIter stripitr(slice->GetDaughterIterator());
00750 while(CandStripHandle *strip =
00751 dynamic_cast<CandStripHandle*>(stripitr())){
00752 if(strip->GetPlane()==iplane) {
00753 PlexPlaneId plnid(track->GetVldContext()->GetDetector(),
00754 iplane,false);
00755 if(plnid.GetPlaneView() == PlaneView::kU){
00756 Float_t trkU = track->GetU(iplane);
00757 if(trkU<strip->GetTPos()+0.0205 && trkU>strip->GetTPos()-0.0205) {
00758 planeCharge[iplane] = strip->GetCharge();
00759 if(iplane>=firstSharedPlane && iplane<=lastSharedPlane)
00760 nMissingSharedPlanes-=1;
00761 else nMissingIsoPlanes-=1;
00762 }
00763 }
00764 else if(plnid.GetPlaneView() == PlaneView::kV){
00765 Float_t trkV = track->GetV(iplane);
00766 if(trkV<strip->GetTPos()+0.0205 && trkV>strip->GetTPos()-0.0205) {
00767 planeCharge[iplane] = strip->GetCharge();
00768 if(iplane>=firstSharedPlane && iplane<=lastSharedPlane)
00769 nMissingSharedPlanes-=1;
00770 else nMissingIsoPlanes-=1;
00771 }
00772 }
00773 }
00774 }
00775 }
00776 }
00777 }
00778
00779 Int_t nIsolatedPlanes = ( lastTrkPlane - firstTrkPlane + 1 -
00780 nMissingIsoPlanes - nSharedPlanes);
00781
00782 MSG("ShowerSR",Msg::kDebug) << "nMissingIsoPlanes = "
00783 << nMissingIsoPlanes
00784 << " nMissingSharedPlanes = "
00785 << nMissingSharedPlanes
00786 << " nIsolatedPlanes = "
00787 << nIsolatedPlanes << endl;
00788
00789 if(stats) {
00790 stats[1] = nMissingIsoPlanes;
00791 stats[2] = nMissingSharedPlanes;
00792 }
00793 if(nIsolatedPlanes>=pMinTrackIsolation) return false;
00794
00795
00796 Int_t nBuriedPlanes = 0;
00797 Int_t nPhysBuriedPlanes = 0;
00798 for(int iplane=firstSharedPlane;iplane<=lastSharedPlane;iplane++){
00799 PlexPlaneId plnid(track->GetVldContext()->GetDetector(),iplane,false);
00800 if(planeCharge[iplane]==0) continue;
00801 if(plnid.GetPlaneView() == PlaneView::kU){
00802 Float_t minShw = this->GetMinU(iplane)-0.02;
00803 Float_t maxShw = this->GetMaxU(iplane)+0.02;
00804 Float_t minPhysShw = this->GetMinPhysU(iplane)-0.02;
00805 Float_t maxPhysShw = this->GetMaxPhysU(iplane)+0.02;
00806 Float_t trkU = track->GetU(iplane);
00807 if(trkU>minShw&&trkU<maxShw) nBuriedPlanes+=1;
00808 if(this->GetNPhysStrips(iplane)&&
00809 trkU>minPhysShw&&trkU<maxPhysShw) nPhysBuriedPlanes+=1;
00810 }
00811 else if(plnid.GetPlaneView() == PlaneView::kV){
00812 Float_t minShw = this->GetMinV(iplane)-0.02;
00813 Float_t maxShw = this->GetMaxV(iplane)+0.02;
00814 Float_t minPhysShw = this->GetMinPhysV(iplane)-0.02;
00815 Float_t maxPhysShw = this->GetMaxPhysV(iplane)+0.02;
00816 Float_t trkV = track->GetV(iplane);
00817 if(trkV>minShw&&trkV<maxShw) nBuriedPlanes+=1;
00818 if(this->GetNPhysStrips(iplane)&&
00819 trkV>minPhysShw&&trkV<maxPhysShw) nPhysBuriedPlanes+=1;
00820 }
00821 }
00822
00823 nIsolatedPlanes = ( lastTrkPlane - firstTrkPlane + 1 -
00824 nMissingIsoPlanes - nBuriedPlanes -
00825 nMissingSharedPlanes);
00826 MSG("ShowerSR",Msg::kDebug) << "nBuriedPlanes = " << nBuriedPlanes
00827 << " nIsolatedPlanes = " << nIsolatedPlanes << endl;
00828 if(stats) {
00829 stats[3] = nBuriedPlanes;
00830 stats[4] = nPhysBuriedPlanes;
00831 }
00832
00833 if(nIsolatedPlanes>=pMinTrackIsolation) return false;
00834
00835
00836
00837 Int_t nXTalk = 0;
00838 Int_t nTrkLike = 0;
00839 Int_t nTrkLikePH = 0;
00840 for(int iplane=firstSharedPlane;iplane<=lastSharedPlane;iplane++){
00841 PlexPlaneId plnid(track->GetVldContext()->GetDetector(),iplane,false);
00842 for(int i=0;i<=this->GetLastSubShower();i++){
00843 const CandSubShowerSRHandle *ssh = this->GetSubShower(i);
00844 if(ssh->GetPlaneView()!=plnid.GetPlaneView()) continue;
00845 if(iplane<ssh->GetBegPlane()||iplane>ssh->GetEndPlane()) continue;
00846 TIter stripItr(ssh->GetDaughterIterator());
00847 while(CandStripHandle *strip =
00848 dynamic_cast<CandStripHandle*>(stripItr())) {
00849 bool match = false;
00850 if(strip->GetPlane()!=iplane) continue;
00851 if(plnid.GetPlaneView()==PlaneView::kU &&
00852 TMath::Abs(strip->GetTPos()-track->GetU(iplane))<0.0205){
00853 match = true;
00854 }
00855 else if(plnid.GetPlaneView()==PlaneView::kV &&
00856 TMath::Abs(strip->GetTPos()-track->GetV(iplane))<0.0205){
00857 match = true;
00858 }
00859 if(match){
00860 if(ssh->GetClusterID()==ClusterType::kXTalk) nXTalk+=1;
00861 else if(ssh->GetClusterID()==ClusterType::kHalo &&
00862 strip->GetCharge(CalDigitType::kPE)<2.0) nXTalk+=1;
00863 else if(ssh->GetClusterID()==ClusterType::kTrkLike) nTrkLike+=1;
00864 else if(ssh->GetClusterID()==ClusterType::kEMLike ||
00865 ssh->GetClusterID()==ClusterType::kHadLike) {
00866 TIter stripItr2(this->GetDaughterIterator());
00867 Bool_t isolatedTrackHit = true;
00868 while(CandStripHandle *strip2 =
00869 dynamic_cast<CandStripHandle*>(stripItr2())) {
00870 if(strip2->GetPlane()!=iplane) continue;
00871 if(plnid.GetPlaneView()==PlaneView::kU) {
00872 if( TMath::Abs(strip2->GetTPos()-track->GetU(iplane)-0.041)<0.0205 ||
00873 TMath::Abs(strip2->GetTPos()-track->GetU(iplane)+0.041)<0.0205 )
00874 isolatedTrackHit = false;
00875 }
00876 else if(plnid.GetPlaneView()==PlaneView::kV){
00877 if( TMath::Abs(strip2->GetTPos()-track->GetV(iplane)-0.041)<0.0205 ||
00878 TMath::Abs(strip2->GetTPos()-track->GetV(iplane)+0.041)<0.0205 )
00879 isolatedTrackHit = false;
00880 }
00881 }
00882 if(isolatedTrackHit) nTrkLikePH++;
00883 }
00884 break;
00885 }
00886 }
00887 }
00888 }
00889
00890
00891 nIsolatedPlanes += nTrkLike;
00892 MSG("ShowerSR",Msg::kDebug) << "nTrkLike = " << nTrkLike
00893 << " nTrkLikePH = " << nTrkLikePH
00894 << " nIsolatedPlanes = " << nIsolatedPlanes << endl;
00895 if(stats) {
00896 stats[5] = nTrkLike;
00897 stats[6] = nTrkLikePH;
00898 stats[7] = nXTalk;
00899 }
00900 if(nIsolatedPlanes+nTrkLikePH>=pMinTrackIsolation) return false;
00901
00902
00903
00904
00905 nIsolatedPlanes += (nBuriedPlanes - nPhysBuriedPlanes - nXTalk);
00906 MSG("ShowerSR",Msg::kDebug) << "nPhysBuriedPlanes = " << nPhysBuriedPlanes
00907 << " nIsolatedPlanes = " << nIsolatedPlanes << endl;
00908 if(nIsolatedPlanes>=pMinTrackIsolation) return false;
00909
00910 return true;
00911
00912 }
00913
00914
00915
00916 Bool_t CandShowerSRHandle::IsUnphysical(Float_t xtalkFrac,
00917 Float_t xtalkCut)
00918 {
00919 Int_t nPhysSS = 0;
00920 for(int i=0;i<=this->GetLastSubShower();i++){
00921 const CandSubShowerSRHandle *ssh = this->GetSubShower(i);
00922 if(ssh->GetClusterID()==ClusterType::kEMLike ||
00923 ssh->GetClusterID()==ClusterType::kHadLike ||
00924 ssh->GetClusterID()==ClusterType::kTrkLike) nPhysSS+=1;
00925 }
00926 if(nPhysSS>1) return false;
00927 Int_t nXTlk = 0;
00928 Int_t nSig = 0;
00929 Float_t aveCharge = 0;
00930 Float_t maxTPosU = -4;
00931 Float_t minTPosU = +4;
00932 Float_t maxTPosV = -4;
00933 Float_t minTPosV = +4;
00934 TIter stripItr(this->GetDaughterIterator());
00935 while (CandStripHandle *strip =
00936 dynamic_cast<CandStripHandle*>(stripItr())) {
00937 aveCharge += strip->GetCharge(CalDigitType::kPE);
00938 if(strip->GetCharge(CalDigitType::kPE)<xtalkCut) nXTlk+=1;
00939 if(strip->GetCharge(CalDigitType::kPE)>5.0) nSig+=1;
00940 if(strip->GetPlaneView()==PlaneView::kU) {
00941 if(strip->GetTPos()>maxTPosU) maxTPosU = strip->GetTPos();
00942 if(strip->GetTPos()<minTPosU) minTPosU = strip->GetTPos();
00943 }
00944 else if(strip->GetPlaneView()==PlaneView::kV){
00945 if(strip->GetTPos()>maxTPosV) maxTPosV = strip->GetTPos();
00946 if(strip->GetTPos()<minTPosV) minTPosV = strip->GetTPos();
00947 }
00948 }
00949 if(nSig>1) return false;
00950 if(Float_t(nXTlk)/Float_t(this->GetNStrip())>xtalkFrac) return true;
00951 else if(aveCharge/Float_t(this->GetNStrip())<xtalkCut) return true;
00952 return false;
00953 }
00954
00955
00956
00957 Double_t CandShowerSRHandle::GetPHWTime(Double_t &error)
00958 {
00959
00960
00961 Double_t PHWTime = 0.;
00962 Double_t PHTot = 0.;
00963 Double_t AveTime = 0.;
00964 Double_t TimeSq = 0.;
00965 Double_t Tot = 0.;
00966 TIter stripItr(GetDaughterIterator());
00967 while (CandStripHandle *strip =
00968 dynamic_cast<CandStripHandle*>(stripItr())) {
00969 Tot += 1.;
00970 AveTime += strip->GetTime();
00971 TimeSq += strip->GetTime()*strip->GetTime();
00972 }
00973 Double_t mean = AveTime/Tot;
00974 Double_t rms = 0;
00975 if(TimeSq/Tot - mean*mean>0) rms = TMath::Sqrt(TimeSq/Tot - mean*mean);
00976 TimeSq = 0;
00977 stripItr.Reset();
00978 while (CandStripHandle *strip =
00979 dynamic_cast<CandStripHandle*>(stripItr())) {
00980 if(TMath::Abs(strip->GetTime() - mean) < rms) {
00981 PHTot += strip->GetCharge(CalDigitType::kPE);
00982 PHWTime += strip->GetCharge(CalDigitType::kPE) *
00983 strip->GetTime();
00984 TimeSq += strip->GetCharge(CalDigitType::kPE) *
00985 strip->GetTime()*strip->GetTime();
00986 }
00987 }
00988 error = -1;
00989 if(PHTot<=0) return 0;
00990 mean = PHWTime/PHTot;
00991 if(TimeSq/PHTot - mean*mean>0)
00992 error = TMath::Sqrt(TimeSq/PHTot - mean*mean);
00993 return mean;
00994 }
00995
00996
00997 Double_t CandShowerSRHandle::GetAveTime(Double_t &error)
00998 {
00999
01000
01001 Double_t AveTime = 0.;
01002 Double_t TimeSq = 0.;
01003 Double_t Tot = 0.;
01004 TIter stripItr(GetDaughterIterator());
01005 while (CandStripHandle *strip =
01006 dynamic_cast<CandStripHandle*>(stripItr())) {
01007 Tot += 1.;
01008 AveTime += strip->GetTime();
01009 TimeSq += strip->GetTime()*strip->GetTime();
01010 }
01011 if(Tot<=0) return 0;
01012 stripItr.Reset();
01013 Double_t mean = AveTime/Tot;
01014 Double_t rms = 0;
01015 if(TimeSq/Tot - mean*mean>0) rms = TMath::Sqrt(TimeSq/Tot - mean*mean);
01016 TimeSq = 0;
01017 AveTime = 0;
01018 Tot = 0;
01019 while (CandStripHandle *strip =
01020 dynamic_cast<CandStripHandle*>(stripItr())) {
01021 if(TMath::Abs(strip->GetTime()-mean) < rms){
01022 Tot += 1.;
01023 AveTime += strip->GetTime();
01024 TimeSq += strip->GetTime()*strip->GetTime();
01025 }
01026 }
01027 error = -1;
01028 if(Tot<=0) return 0;
01029 mean = AveTime/Tot;
01030 if(TimeSq/Tot - mean*mean>0)
01031 error = TMath::Sqrt(TimeSq/Tot - mean*mean);
01032 return mean;
01033 }
01034
01035 XXXITRIMP(CandShowerSRHandle)