#include <AlgShowerSSList.h>
Inheritance diagram for AlgShowerSSList:

Public Member Functions | |
| AlgShowerSSList () | |
| virtual | ~AlgShowerSSList () |
| virtual void | RunAlg (AlgConfig &ac, CandHandle &ch, CandContext &cx) |
| virtual void | Trace (const char *c) const |
|
|
Definition at line 49 of file AlgShowerSSList.cxx. 00050 {
00051 }
|
|
|
Definition at line 54 of file AlgShowerSSList.cxx. 00055 {
00056 }
|
|
||||||||||||||||
|
We begin with a nested loop over all CandSlices, and over all CandClusters within each CandSlice, generating list of all clusters in the U and V planes. Next, we execute a nested loop over U-view and V-view CandClusters, checking for matching 2D clusters. The following criteria are used: Beginning planes for the two 2D 'long' CandClusters (defined by PlaneScale) must be within DiffViewPlaneMatch., or DiffViewPlaneMatchShort if one or more clusters is short. Beginning times for the two 2D CandClusters must be within DiffViewTimeMatch. The fractional overlap of U and V clusters must exceed DiffViewPlaneCoverage, if both clusters are long. The total pulse heights of the U and V clusters must agree to within DiffViewPulseHeightCut if at least one of the clusters is long. (Note: This should probably be changed to a charge ratio) If a U/V cluster set is found which satisfies these requirements, a second loop over U clusters is performed, searching for alternative U/V pairs involving the original V cluster satisfying the requirements above, but higher in total energy. If no better alternative is found a CandShower is constructed. In this way, a given CandCluster will only be used once, in the shower with the highest total energy. Reimplemented from AlgShowerSRList. Definition at line 60 of file AlgShowerSSList.cxx. References CandHandle::AddDaughterLink(), Registry::Get(), AlgFactory::GetAlgHandle(), CandSubShowerSRHandle::GetAvgDev(), CandRecoHandle::GetBegPlane(), CandContext::GetCandRecord(), CandRecoHandle::GetCandSlice(), CandStripHandle::GetCharge(), CandSubShowerSRHandle::GetClusterID(), CandContext::GetDataIn(), CandHandle::GetDaughterIterator(), CandRecoHandle::GetEndPlane(), CandShowerHandle::GetEnergy(), CandSubShowerSRHandle::GetEnergy(), AlgFactory::GetInstance(), CandSubShowerSRHandle::GetMaxU(), CandSubShowerSRHandle::GetMaxV(), CandSubShowerSRHandle::GetMinU(), CandSubShowerSRHandle::GetMinV(), CandContext::GetMom(), CandSubShowerSRHandle::GetPlaneView(), CandSubShowerSRHandle::GetSlope(), CandStripHandle::GetTPos(), RecMinos::GetVldContext(), CandRecoHandle::GetVtxU(), CandRecoHandle::GetVtxV(), CandShowerSR::MakeCandidate(), MSG, PITCHINMETRES, CandHandle::Print(), and CandRecoHandle::SetCandSlice(). 00061 {
00062
00063 assert(cx.GetDataIn());
00064 if (!(cx.GetDataIn()->InheritsFrom("TObjArray"))) {
00065 return;
00066 }
00067
00068 const CandSliceListHandle *slicelist = 0;
00069 const CandClusterListHandle *clusterlist = 0;
00070 const CandSubShowerSRListHandle *subshowerlist = 0;
00071 const TObjArray *cxin = dynamic_cast<const TObjArray *>(cx.GetDataIn());
00072 for (Int_t i=0; i<=cxin->GetLast(); i++) {
00073 TObject *tobj = cxin->At(i);
00074 if (tobj->InheritsFrom("CandSliceListHandle")) {
00075 slicelist = dynamic_cast<CandSliceListHandle*>(tobj);
00076 }
00077 if (tobj->InheritsFrom("CandClusterListHandle")) {
00078 clusterlist = dynamic_cast<CandClusterListHandle*>(tobj);
00079 }
00080 if (tobj->InheritsFrom("CandSubShowerSRListHandle")) {
00081 subshowerlist = dynamic_cast<CandSubShowerSRListHandle*>(tobj);
00082 }
00083 }
00084 if (!slicelist || !clusterlist || !subshowerlist) {
00085 MSG("AlgShowerSS",Msg::kError) <<
00086 "CandSliceListHandle, CandClusterListHandle or CandSubShowerSRListHandle missing\n";
00087 return;
00088 }
00089
00090 CandContext cxx(this,cx.GetMom());
00091
00092 Double_t MinNonPhysicsEnergy = 0.2; //in GeV
00093 Int_t MaxPlaneGap = 2;
00094 Int_t NPeakFindingBins = 32;
00095 //get config for AlgSubShowerSS
00096 const char *charShowerSSAlgConfig = 0;
00097 ac.Get("ShowerSSAlgConfig",charShowerSSAlgConfig);
00098 ac.Get("MaxPlaneGap",MaxPlaneGap);
00099 ac.Get("NPeakFindingBins",NPeakFindingBins);
00100 ac.Get("MinNonPhysicsEnergy",MinNonPhysicsEnergy);
00101
00102 //Get singleton instance of AlgFactory
00103 AlgFactory &af = AlgFactory::GetInstance();
00104 AlgHandle ah = af.GetAlgHandle("AlgShowerSS",charShowerSSAlgConfig);
00105
00106 const CandRecord *candrec = cx.GetCandRecord();
00107 assert(candrec);
00108 const VldContext *vldcptr = candrec->GetVldContext();
00109 assert(vldcptr);
00110 VldContext vldc = *vldcptr;
00111
00112 UgliGeomHandle ugh(vldc);
00113
00114 CandSliceHandleItr sliceItr(slicelist->GetDaughterIterator());
00115 Int_t nslice = 0;
00116 Int_t nsubshower = 0;
00117
00118 while (CandSliceHandle *slice = sliceItr()) { //slice loop
00119
00120 MSG("AlgShowerSS",Msg::kDebug) << "Slice: " << nslice << endl;
00121
00122 // Select SubShowers within this slice
00123 CandSubShowerSRHandleItr subshowerItr(subshowerlist->GetDaughterIterator());
00124
00125 // iterate over subshowers, and make a shower out of
00126 // all subshowers in each slice, in contiguous planes
00127 int plane[500] = {0};
00128 int firstPlane = 500;
00129 int lastPlane = 0;
00130 nsubshower = 0;
00131 while (CandSubShowerSRHandle *subshower = subshowerItr()) {
00132 if (*subshower->GetCandSlice()==*slice) {
00133 MSG("AlgShowerSS",Msg::kDebug) << "SubShower: " << nsubshower
00134 << " in slice " << nslice << endl;
00135 for(int i=subshower->GetBegPlane();i<=subshower->GetEndPlane();i++){
00136 MSG("AlgShowerSS",Msg::kDebug) << "Plane: " << i << endl;
00137 plane[i] = 1;
00138 if(i<firstPlane) firstPlane = i;
00139 if(i>lastPlane) lastPlane = i;
00140 }
00141 }
00142 nsubshower++;
00143 }
00144
00145 MSG("AlgShowerSS",Msg::kDebug) << "First Plane = " << firstPlane << endl;
00146 MSG("AlgShowerSS",Msg::kDebug) << "Last Plane = " << lastPlane << endl;
00147
00148 //separate up into plane chunks according to MaxPlaneGap
00149 Int_t nshower = 0;
00150 while(firstPlane<=lastPlane){ //while loop over planes
00151
00152 Int_t begPlane = 500;
00153 Int_t endPlane = 0;
00154 Int_t nGaps = 0;
00155
00156 for(int i=firstPlane;i<=lastPlane;i++){
00157 if(plane[i]==0) {
00158 if(begPlane!=500) nGaps+=1;
00159 }
00160 else {
00161 if(begPlane==500) begPlane = i;
00162 endPlane = i;
00163 }
00164 plane[i] = 0;
00165 if(nGaps>MaxPlaneGap) {
00166 MSG("AlgShowerSS",Msg::kDebug) << "begPlane = " << begPlane << endl;
00167 MSG("AlgShowerSS",Msg::kDebug) << "endPlane = " << endPlane << endl;
00168 break;
00169 }
00170 }
00171 firstPlane = endPlane+1;
00172
00173 //could have multiple showers per plane chunk
00174 //pull out all subshowers in plane chunk and look for TPos peaks:
00175
00176 //loop through subshower list again and histogram tposvtx
00177 //in order to look for peaks
00178 // (add an extra bin at each end outside of expected range,
00179 // in order to be able to detect peaks at (far) detector edges)
00180 TH1F *vtxUHistAll = new TH1F("vtxUHistAll","vtxUHistAll",NPeakFindingBins+2,
00181 -4. - 8./Float_t(NPeakFindingBins),
00182 +4. + 8./Float_t(NPeakFindingBins));
00183 TH1F *vtxVHistAll = new TH1F("vtxVHistAll","vtxVHistAll",NPeakFindingBins+2,
00184 -4. - 8./Float_t(NPeakFindingBins),
00185 +4. + 8./Float_t(NPeakFindingBins));
00186 TH1F *vtxUHist = new TH1F("vtxUHist","vtxUHist",NPeakFindingBins+2,
00187 -4. - 8./Float_t(NPeakFindingBins),
00188 +4. + 8./Float_t(NPeakFindingBins));
00189 TH1F *vtxVHist = new TH1F("vtxVHist","vtxVHist",NPeakFindingBins+2,
00190 -4. - 8./Float_t(NPeakFindingBins),
00191 +4. + 8./Float_t(NPeakFindingBins));
00192 subshowerItr.ResetFirst();
00193 nsubshower = 0;
00194 while (CandSubShowerSRHandle *subshower = subshowerItr()) {
00195 if (*subshower->GetCandSlice()==*slice) {
00196 if(subshower->GetBegPlane()>=begPlane &&
00197 subshower->GetBegPlane()<=endPlane){
00198 if(subshower->GetPlaneView()==PlaneView::kU ||
00199 subshower->GetPlaneView()==PlaneView::kX) {
00200 Float_t weightedCentre = subshower->GetVtxU() +
00201 subshower->GetSlope() * PITCHINMETRES *
00202 Float_t(subshower->GetEndPlane() - subshower->GetBegPlane() + 1)/2.;
00203 if(weightedCentre<-4. || weightedCentre>4.) weightedCentre = subshower->GetVtxU();
00204 MSG("AlgShowerSS",Msg::kDebug)
00205 << "Filling vtxUHist with Subshower " << nsubshower
00206 << " with vtvU = " << subshower->GetVtxU()
00207 << " and energy = " << subshower->GetEnergy()
00208 << " and slope = " << subshower->GetSlope()
00209 << " and AvgDev = " << subshower->GetAvgDev()
00210 << " and weightedCentre = " << weightedCentre
00211 << endl;
00212 CandStripHandleItr stripssItr(subshower->GetDaughterIterator());
00213 while (CandStripHandle *stp = stripssItr()) {
00214 Float_t val = stp->GetCharge(CalDigitType::kSigCorr) -
00215 vtxUHistAll->GetBinContent(vtxUHistAll->FindBin(stp->GetTPos()));
00216 if(val>0) vtxUHistAll->Fill(stp->GetTPos(),val);
00217 //vtxUHistAll->Fill(weightedCentre);
00218 if( subshower->GetClusterID()==ClusterType::kEMLike ||
00219 subshower->GetClusterID()==ClusterType::kHadLike ||
00220 subshower->GetClusterID()==ClusterType::kTrkLike){
00221 val = stp->GetCharge(CalDigitType::kSigCorr) -
00222 vtxUHist->GetBinContent(vtxUHist->FindBin(stp->GetTPos()));
00223 if(val>0) vtxUHist->Fill(stp->GetTPos(),val);
00224 //vtxUHist->Fill(weightedCentre);
00225 }
00226 }
00227 }
00228 else if(subshower->GetPlaneView()==PlaneView::kV ||
00229 subshower->GetPlaneView()==PlaneView::kY){
00230 Float_t weightedCentre = subshower->GetVtxV() +
00231 subshower->GetSlope() * PITCHINMETRES *
00232 Float_t(subshower->GetEndPlane() - subshower->GetBegPlane() + 1)/2;
00233 if(weightedCentre<-4. || weightedCentre>4.) weightedCentre = subshower->GetVtxV();
00234 MSG("AlgShowerSS",Msg::kDebug)
00235 << "Filling vtxVHist with Subshower " << nsubshower
00236 << " with vtvV = " << subshower->GetVtxV()
00237 << " and energy = " << subshower->GetEnergy()
00238 << " and slope = " << subshower->GetSlope()
00239 << " and AvgDev = " << subshower->GetAvgDev()
00240 << " and weightedCentre = " << weightedCentre
00241 << endl;
00242 CandStripHandleItr stripssItr(subshower->GetDaughterIterator());
00243 while (CandStripHandle *stp = stripssItr()) {
00244 //fill with max charge for this tpos
00245 Float_t val = stp->GetCharge(CalDigitType::kSigCorr) -
00246 vtxVHistAll->GetBinContent(vtxVHistAll->FindBin(stp->GetTPos()));
00247 if(val>0) vtxVHistAll->Fill(stp->GetTPos(),val);
00248 //vtxVHistAll->Fill(weightedCentre);
00249 if( subshower->GetClusterID()==ClusterType::kEMLike ||
00250 subshower->GetClusterID()==ClusterType::kHadLike ||
00251 subshower->GetClusterID()==ClusterType::kTrkLike){
00252 val = stp->GetCharge(CalDigitType::kSigCorr) -
00253 vtxVHist->GetBinContent(vtxVHist->FindBin(stp->GetTPos()));
00254 if(val>0) vtxVHist->Fill(stp->GetTPos(),val);
00255 //vtxVHist->Fill(weightedCentre);
00256 }
00257 }
00258 }
00259 }
00260 }
00261 nsubshower++;
00262 }
00263
00264 if(false){
00265 TCanvas *can = new TCanvas();
00266 can->Divide(2,2);
00267 can->cd(1);
00268 vtxUHistAll->Draw();
00269 can->cd(2);
00270 vtxVHistAll->Draw();
00271 can->cd(3);
00272 vtxUHist->Draw();
00273 can->cd(4);
00274 vtxVHist->Draw();
00275 char nomus[256];
00276 sprintf(nomus,"peakPlot_slice%i.eps",nslice);
00277 can->Print(nomus);
00278 delete can;
00279 }
00280
00281 TSpectrum *specUAll = new TSpectrum(10);
00282 specUAll->Search(vtxUHistAll,1);
00283 TSpectrum *specU = new TSpectrum(10);
00284 specU->Search(vtxUHist,1);
00285 TSpectrum *specVAll = new TSpectrum(10);
00286 specVAll->Search(vtxVHistAll,1);
00287 TSpectrum *specV = new TSpectrum(10);
00288 specV->Search(vtxVHist,1);
00289
00290 Int_t nUPeaksAll = specUAll->GetNPeaks();
00291 Int_t nUPeaks = specU->GetNPeaks();
00292 Float_t *peakUPos = specU->GetPositionX();
00293 Float_t *peakUVal = specU->GetPositionY();
00294
00295 Int_t nVPeaksAll = specVAll->GetNPeaks();
00296 Int_t nVPeaks = specV->GetNPeaks();
00297 Float_t *peakVPos = specV->GetPositionX();
00298 Float_t *peakVVal = specV->GetPositionY();
00299
00300 //if no peaks in either view
00301 if(nUPeaksAll==0 || nVPeaksAll==0) {
00302 //can't form a 3D shower in these conditions!
00303 MSG("AlgShowerSS",Msg::kDebug)
00304 << "nUPeaks = " << nUPeaks
00305 << " nVPeaks = " << nVPeaks
00306 << " Can't form a 3D shower" << endl;
00307 delete vtxUHist;
00308 delete vtxVHist;
00309 delete specU;
00310 delete specV;
00311 delete vtxUHistAll;
00312 delete vtxVHistAll;
00313 delete specUAll;
00314 delete specVAll;
00315 continue;
00316 }
00317
00318 //one or both views have no good "physics" subshower:
00319 if(nUPeaks==0 || nVPeaks==0){
00320 MSG("AlgShowerSS",Msg::kDebug) << "Have something in both views but "
00321 << "nUPeaks = " << nUPeaks
00322 << "and nVPeaks = " << nVPeaks
00323 << endl;
00324 //try to form anyway with whatever's there
00325 if(nUPeaks==0) nUPeaks = 1;
00326 if(nVPeaks==0) nVPeaks = 1;
00327 }
00328
00329 //Try to form some 3D showers, yeah!
00330
00331 //have one or more peak => maybe one or
00332 //more shower in this plane range
00333 //get boundaries that define each shower in each view:
00334 Float_t *peakUPosLow = new Float_t[nUPeaks];
00335 Float_t *peakUPosUpp = new Float_t[nUPeaks];
00336 MSG("AlgShowerSS",Msg::kDebug) << "Number of U Peaks found = "
00337 << nUPeaks << " with positions, heights "
00338 << "and bounds: " << endl;
00339 for (int i=0;i<nUPeaks;i++){
00340 if(i==0) peakUPosLow[i] = -4;
00341 else peakUPosLow[i] = peakUPosUpp[i-1];
00342 if(i==nUPeaks-1) peakUPosUpp[i] = 4;
00343 else {
00344 Int_t bin = vtxUHist->GetXaxis()->FindBin(peakUPos[i]);
00345 Int_t bestBin = vtxUHist->GetNbinsX();
00346 Float_t threeBinAve = 1000000; //sigcor!
00347 while(bin<vtxUHist->GetNbinsX() &&
00348 vtxUHist->GetBinCenter(bin)<peakUPos[i+1]) {
00349 Float_t ave = (vtxUHist->GetBinContent(bin-1) +
00350 vtxUHist->GetBinContent(bin) +
00351 vtxUHist->GetBinContent(bin+1));
00352 if(ave<threeBinAve) {
00353 threeBinAve = ave;
00354 bestBin = bin;
00355 }
00356 bin++;
00357 }
00358 peakUPosUpp[i] = vtxUHist->GetBinCenter(bestBin);
00359 }
00360 MSG("AlgShowerSS",Msg::kDebug) << peakUPos[i] << " "
00361 << peakUVal[i] << " ["
00362 << peakUPosLow[i] << ","
00363 << peakUPosUpp[i] << "]"
00364 << endl;
00365 }
00366
00367 Float_t *peakVPosLow = new Float_t[nVPeaks];
00368 Float_t *peakVPosUpp = new Float_t[nVPeaks];
00369 MSG("AlgShowerSS",Msg::kDebug) << "Number of V Peaks found = "
00370 << nVPeaks
00371 << " with positions, heights "
00372 << "and bounds: " << endl;
00373 for (int i=0;i<nVPeaks;i++){
00374 if(i==0) peakVPosLow[i] = -4;
00375 else peakVPosLow[i] = peakVPosUpp[i-1];
00376 if(i==nVPeaks-1) peakVPosUpp[i] = 4;
00377 else {
00378 Int_t bin = vtxVHist->GetXaxis()->FindBin(peakVPos[i]);
00379 Int_t bestBin = vtxVHist->GetNbinsX();
00380 Float_t threeBinAve = 1000000; //gev!
00381 while(bin<vtxVHist->GetNbinsX() &&
00382 vtxVHist->GetBinCenter(bin)<peakVPos[i+1]) {
00383 Float_t ave = (vtxVHist->GetBinContent(bin-1) +
00384 vtxVHist->GetBinContent(bin) +
00385 vtxVHist->GetBinContent(bin+1));
00386 if(ave<threeBinAve) {
00387 threeBinAve = ave;
00388 bestBin = bin;
00389 }
00390 bin++;
00391 }
00392 peakVPosUpp[i] = vtxVHist->GetBinCenter(bestBin);
00393 }
00394 MSG("AlgShowerSS",Msg::kDebug) << peakVPos[i] << " "
00395 << peakVVal[i] << " ["
00396 << peakVPosLow[i] << ","
00397 << peakVPosUpp[i] << "]"
00398 << endl;
00399 }
00400
00401 //for matching up U/V views of showers:
00402 Float_t *totUEnergy = new Float_t[nUPeaks];
00403 Float_t *approxVfromTime = new Float_t[nUPeaks];
00404 Float_t *maxPhysU = new Float_t[nUPeaks];
00405 Float_t *minPhysU = new Float_t[nUPeaks];
00406 Int_t *maxPlaneU = new Int_t[nUPeaks];
00407 Int_t *minPlaneU = new Int_t[nUPeaks];
00408 Int_t *nSubShowersU = new Int_t[nUPeaks];
00409 for(int i=0;i<nUPeaks;i++) {
00410 totUEnergy[i] = 0;
00411 approxVfromTime[i] = 0;
00412 maxPhysU[i] = -1; maxPlaneU[i] = -1;
00413 minPhysU[i] = 999; minPlaneU[i] = -1;
00414 nSubShowersU[i] = 0;
00415 }
00416 Float_t *totVEnergy = new Float_t[nVPeaks];
00417 Float_t *approxUfromTime = new Float_t[nVPeaks];
00418 Float_t *maxPhysV = new Float_t[nVPeaks];
00419 Float_t *minPhysV = new Float_t[nVPeaks];
00420 Int_t *maxPlaneV = new Int_t[nVPeaks];
00421 Int_t *minPlaneV = new Int_t[nVPeaks];
00422 Int_t *nSubShowersV = new Int_t[nVPeaks];
00423 for(int i=0;i<nVPeaks;i++) {
00424 totVEnergy[i] = 0;
00425 approxUfromTime[i] = 0;
00426 maxPhysV[i] = -1; maxPlaneV[i] = -1;
00427 minPhysV[i] = 999; minPlaneV[i] = -1;
00428 nSubShowersV[i] = 0;
00429 }
00430
00431 //loop through subshowerlist and add up energy of showers
00432 subshowerItr.ResetFirst();
00433 while (CandSubShowerSRHandle *subshower = subshowerItr()) {
00434 if (*subshower->GetCandSlice()==*slice) {
00435 if(subshower->GetBegPlane()>=begPlane &&
00436 subshower->GetEndPlane()<=endPlane) {
00437 if(subshower->GetPlaneView()==PlaneView::kU){
00438 for(int i=0;i<nUPeaks;i++){
00439 Float_t weightedCentre = subshower->GetVtxU() +
00440 subshower->GetSlope() * PITCHINMETRES *
00441 Float_t(subshower->GetEndPlane() - subshower->GetBegPlane() + 1)/2.;
00442 if(weightedCentre>peakUPosLow[i] &&
00443 weightedCentre<=peakUPosUpp[i]) {
00444 totUEnergy[i]+=subshower->GetEnergy();
00445 if(nUPeaks>1 &&
00446 subshower->GetClusterID()==ClusterType::kEMLike ||
00447 subshower->GetClusterID()==ClusterType::kHadLike ||
00448 subshower->GetClusterID()==ClusterType::kTrkLike){
00449 approxVfromTime[i]+=subshower->GetVtxV();
00450 nSubShowersU[i] += 1;
00451 for(int j=subshower->GetBegPlane();j<=subshower->GetEndPlane();j++){
00452 Float_t testMinU = subshower->GetMinU(j);
00453 Float_t testMaxU = subshower->GetMaxU(j);
00454 if(testMaxU>maxPhysU[i]) {
00455 maxPhysU[i] = testMaxU;
00456 maxPlaneU[i] = j;
00457 }
00458 if(testMinU<minPhysU[i]) {
00459 minPhysU[i] = testMinU;
00460 minPlaneU[i] = j;
00461 }
00462 }
00463 }
00464 }
00465 }
00466 }
00467 else if(subshower->GetPlaneView()==PlaneView::kV){
00468 for(int i=0;i<nVPeaks;i++){
00469 Float_t weightedCentre = subshower->GetVtxV() +
00470 subshower->GetSlope() * PITCHINMETRES *
00471 Float_t(subshower->GetEndPlane() - subshower->GetBegPlane() + 1)/2.;
00472 if(weightedCentre>peakVPosLow[i] &&
00473 weightedCentre<=peakVPosUpp[i]) {
00474 totVEnergy[i]+=subshower->GetEnergy();
00475 if(nVPeaks>1 &&
00476 subshower->GetClusterID()==ClusterType::kEMLike ||
00477 subshower->GetClusterID()==ClusterType::kHadLike ||
00478 subshower->GetClusterID()==ClusterType::kTrkLike){
00479 approxUfromTime[i]+=subshower->GetVtxU();
00480 nSubShowersV[i] += 1;
00481 for(int j=subshower->GetBegPlane();j<=subshower->GetEndPlane();j++){
00482 Float_t testMinV = subshower->GetMinV(j);
00483 Float_t testMaxV = subshower->GetMaxV(j);
00484 if(testMaxV>maxPhysV[i]) {
00485 maxPhysV[i] = testMaxV;
00486 maxPlaneV[i] = j;
00487 }
00488 if(testMinV<minPhysV[i]) {
00489 minPhysV[i] = testMinV;
00490 minPlaneV[i] = j;
00491 }
00492 }
00493 }
00494 }
00495 }
00496 }
00497 }
00498 }
00499 }
00500
00501 //Test to see if any peaks should be combined:
00502 //Look for adjacent peaks for which min - max "physics" strip difference is ~1
00503 for(int i=0;i<nUPeaks-1;i++){
00504 if(minPlaneU[i+1]==-1 || maxPlaneU[i]==-1 ||
00505 TMath::Abs(minPlaneU[i+1] - maxPlaneU[i]) > 3 ) //within +/- 1 plane in view
00506 continue;
00507 if(minPhysU[i+1] - maxPhysU[i] < 1.5*STRIPWIDTHINMETRES ) {//combine peaks
00508 //add energy to second peak and
00509 //remove energy from first peak
00510 totUEnergy[i+1] += totUEnergy[i];
00511 totUEnergy[i] = 0;
00512 //add other-view vertex estimate sum
00513 approxVfromTime[i+1] += approxVfromTime[i];
00514 approxVfromTime[i] = 0;
00515 nSubShowersU[i+1] += nSubShowersU[i];
00516 nSubShowersU[i] = 0;
00517 //shift min U of second peak down and
00518 //set min U plane of second peak
00519 minPhysU[i+1] = minPhysU[i];
00520 minPlaneU[i+1] = minPlaneU[i];
00521 //set min/max limits of first peak to be the same
00522 maxPhysU[i] = minPhysU[i];
00523 maxPlaneU[i] = minPlaneU[i];
00524 //set peak lower limit of second peak to that of first
00525 peakUPosLow[i+1] = peakUPosLow[i];
00526 //set peak lower and upper limit of first peak to be the same
00527 peakUPosUpp[i] = peakUPosLow[i];
00528 }
00529 }
00530 for(int i=0;i<nVPeaks-1;i++){
00531 if(minPlaneV[i+1]==-1 || maxPlaneV[i]==-1 ||
00532 TMath::Abs(minPlaneV[i+1] - maxPlaneV[i]) > 3 ) //within +/- 1 plane in view
00533 continue;
00534 if(minPhysV[i+1] - maxPhysV[i] < 1.5*STRIPWIDTHINMETRES ) {//combine peaks
00535 //add energy to second peak and
00536 //remove energy from first peak
00537 totVEnergy[i+1] += totVEnergy[i];
00538 totVEnergy[i] = 0;
00539 //add other-view vertex estimate sum
00540 approxUfromTime[i+1] += approxUfromTime[i];
00541 approxUfromTime[i] = 0;
00542 nSubShowersV[i+1] += nSubShowersV[i];
00543 nSubShowersV[i] = 0;
00544 //shift min V of second peak down and
00545 //set min V plane of second peak
00546 minPhysV[i+1] = minPhysV[i];
00547 minPlaneV[i+1] = minPlaneV[i];
00548 //set min/max limits of first peak to be the same
00549 maxPhysV[i] = minPhysV[i];
00550 maxPlaneV[i] = minPlaneV[i];
00551 //set peak lower limit of second peak to that of first
00552 peakVPosLow[i+1] = peakVPosLow[i];
00553 //set peak lower and upper limit of first peak to be the same
00554 peakVPosUpp[i] = peakVPosLow[i];
00555 }
00556 }
00557
00558 //get best order for matching subshower groups in U/V
00559 Int_t *bestOrderU = new Int_t[nUPeaks];
00560 Int_t *bestOrderV = new Int_t[nVPeaks];
00561 for(int i=0;i<nUPeaks;i++){
00562 if(totUEnergy[i]>0){
00563 Int_t nbigger = 0;
00564 for(int j=0;j<nUPeaks;j++){
00565 if(totUEnergy[i]<totUEnergy[j]) nbigger+=1;
00566 }
00567 bestOrderU[nbigger] = i;
00568 }
00569 else { // if there is no energy in this "peak"
00570 Int_t nsmaller = 0; // put zero peaks in reverse order
00571 for(int j=0;j<i;j++){ // purely to ensure that all indices
00572 if(totUEnergy[j]==0) nsmaller+=1; // of bestOrderX are filled
00573 } // with legitimate values (prevents
00574 bestOrderU[nUPeaks-1-nsmaller] = i; // against a rare case seg fault)
00575 }
00576 }
00577 for(int i=0;i<nVPeaks;i++){
00578 if(totVEnergy[i]>0){
00579 Int_t nbigger = 0;
00580 for(int j=0;j<nVPeaks;j++){
00581 if(totVEnergy[i]<totVEnergy[j]) nbigger+=1;
00582 }
00583 bestOrderV[nbigger] = i;
00584 }
00585 else {
00586 Int_t nsmaller = 0;
00587 for(int j=0;j<i;j++){
00588 if(totVEnergy[j]==0) nsmaller+=1;
00589 }
00590 bestOrderV[nVPeaks-1-nsmaller] = i;
00591 }
00592 }
00593
00594 Int_t nShowers = nUPeaks;
00595 if(nShowers>nVPeaks) nShowers = nVPeaks;
00596
00597 if(false){
00598 //check energy ordering is ok:
00599 for(int i=0;i<nShowers-1;i++){ //loop over showers
00600 Float_t EUi = totUEnergy[bestOrderU[i]];
00601 Float_t EVi = totVEnergy[bestOrderV[i]];
00602 Float_t EUii = totUEnergy[bestOrderU[i+1]];
00603 Float_t EVii = totVEnergy[bestOrderV[i+1]];
00604 if(EUi==0 || EUii==0 || EVi==0 || EVii==0) continue;
00605 //can we swap the order and still get two good energy matches?
00606 Float_t asym = TMath::Abs(EUi - EVi)/(EUi + EVi) +
00607 TMath::Abs(EUii - EVii)/(EUii + EVii);
00608 Float_t asymSwap = TMath::Abs(EUi - EVii)/(EUi + EVii) +
00609 TMath::Abs(EUii - EVi)/(EUii + EVi);
00610 //if difference between two asymmetry estimates is <10%
00611 //see if vertex estimate from timing helps
00612 if( TMath::Abs(asym - asymSwap)/asym < 0.1) {
00613 if(nSubShowersU[bestOrderU[i]]==0 ||
00614 nSubShowersV[bestOrderV[i]]==0 ||
00615 nSubShowersU[bestOrderU[i+1]]==0 ||
00616 nSubShowersV[bestOrderV[i+1]]==0) continue;
00617
00618 approxVfromTime[bestOrderU[i]] /= nSubShowersU[bestOrderU[i]];
00619 approxUfromTime[bestOrderV[i]] /= nSubShowersV[bestOrderV[i]];
00620 approxVfromTime[bestOrderU[i+1]] /= nSubShowersU[bestOrderU[i+1]];
00621 approxUfromTime[bestOrderV[i+1]] /= nSubShowersV[bestOrderV[i+1]];
00622
00623 //sum distance from both showers
00624 Float_t vertexDistance =
00625 TMath::Sqrt(TMath::Power(approxUfromTime[bestOrderV[i]] -
00626 peakUPos[bestOrderU[i]],2.) +
00627 TMath::Power(approxVfromTime[bestOrderU[i]] -
00628 peakVPos[bestOrderV[i]],2)) +
00629 TMath::Sqrt(TMath::Power(approxUfromTime[bestOrderV[i+1]] -
00630 peakUPos[bestOrderU[i+1]],2.) +
00631 TMath::Power(approxVfromTime[bestOrderU[i+1]] -
00632 peakVPos[bestOrderV[i+1]],2));
00633 Float_t vertexDistanceSwap =
00634 TMath::Sqrt(TMath::Power(approxUfromTime[bestOrderV[i+1]] -
00635 peakUPos[bestOrderU[i]],2.) +
00636 TMath::Power(approxVfromTime[bestOrderU[i]] -
00637 peakVPos[bestOrderV[i+1]],2)) +
00638 TMath::Sqrt(TMath::Power(approxUfromTime[bestOrderV[i]] -
00639 peakUPos[bestOrderU[i+1]],2.) +
00640 TMath::Power(approxVfromTime[bestOrderU[i+1]] -
00641 peakVPos[bestOrderV[i]],2));
00642
00643 if(vertexDistanceSwap<vertexDistance &&
00644 vertexDistanceSwap<0.5) { //check that best vertex is reasonable
00645 //swap!
00646 //arbitrary choice which view to switch:
00647 Int_t tempIndex = bestOrderU[i];
00648 bestOrderU[i] = bestOrderU[i+1];
00649 bestOrderU[i+1] = tempIndex;
00650 //start checks again so that clusters
00651 //can propagate if better matches are found
00652 i=0;
00653 }
00654 }
00655 }
00656 }
00657
00658 //get true number of physics peaks again
00659 //for final test
00660 nUPeaks = specU->GetNPeaks();
00661 nVPeaks = specV->GetNPeaks();
00662
00663 //loop over number of expected showers:
00664 for(int i=0;i<nShowers;i++){
00665 TObjArray newshower;
00666 Int_t nsubshower = 0;
00667 subshowerItr.ResetFirst();
00668 while (CandSubShowerSRHandle *subshower = subshowerItr()) {
00669 if (*subshower->GetCandSlice()==*slice) {
00670 if(subshower->GetBegPlane()>=begPlane &&
00671 subshower->GetEndPlane()<=endPlane) {
00672 if(subshower->GetPlaneView()==PlaneView::kU){
00673 Float_t weightedCentre = subshower->GetVtxU() +
00674 subshower->GetSlope() * PITCHINMETRES *
00675 Float_t(subshower->GetEndPlane() - subshower->GetBegPlane() + 1)/2.;
00676 if(weightedCentre>peakUPosLow[bestOrderU[i]] &&
00677 weightedCentre<=peakUPosUpp[bestOrderU[i]]) {
00678 newshower.Add(subshower);
00679 MSG("AlgShowerSS",Msg::kDebug)
00680 << "Adding SubShower: "
00681 << nsubshower << " in slice " << nslice
00682 << " to newshower " << i << endl;
00683 }
00684 }
00685 if(subshower->GetPlaneView()==PlaneView::kV){
00686 Float_t weightedCentre = subshower->GetVtxV() +
00687 subshower->GetSlope() * PITCHINMETRES *
00688 Float_t(subshower->GetEndPlane() - subshower->GetBegPlane() + 1)/2.;
00689 if(weightedCentre>peakVPosLow[bestOrderV[i]] &&
00690 weightedCentre<=peakVPosUpp[bestOrderV[i]]) {
00691 newshower.Add(subshower);
00692 MSG("AlgShowerSS",Msg::kDebug)
00693 << "Adding SubShower: "
00694 << nsubshower << " in slice " << nslice
00695 << " to newshower " << i << endl;
00696 }
00697 }
00698 }
00699 }
00700 nsubshower+=1;
00701 }
00702
00703 cxx.SetDataIn(&newshower);
00704 CandShowerSRHandle showerhandle = CandShowerSR::MakeCandidate(ah,cxx);
00705 if((showerhandle.GetEnergy()>0 && nUPeaks>0 && nVPeaks>0) ||
00706 showerhandle.GetEnergy()>MinNonPhysicsEnergy) {
00707 showerhandle.SetCandSlice(slice);
00708 ch.AddDaughterLink(showerhandle);
00709 }
00710 else {
00711 MSG("AlgShowerSS",Msg::kDebug) << "Shower " << nshower
00712 << " has zero energy."
00713 << " - Not adding shower to list."
00714 << endl;
00715 }
00716 }
00717
00718 delete [] peakUPosUpp;
00719 delete [] peakUPosLow;
00720 delete [] peakVPosUpp;
00721 delete [] peakVPosLow;
00722 delete [] totUEnergy;
00723 delete [] totVEnergy;
00724 delete [] approxVfromTime;
00725 delete [] approxUfromTime;
00726 delete [] nSubShowersU;
00727 delete [] nSubShowersV;
00728 delete [] maxPhysU;
00729 delete [] maxPhysV;
00730 delete [] minPhysU;
00731 delete [] minPhysV;
00732 delete [] maxPlaneU;
00733 delete [] maxPlaneV;
00734 delete [] minPlaneU;
00735 delete [] minPlaneV;
00736 delete [] bestOrderU;
00737 delete [] bestOrderV;
00738 delete vtxUHist;
00739 delete vtxVHist;
00740 delete vtxUHistAll;
00741 delete vtxVHistAll;
00742 delete specU;
00743 delete specV;
00744 delete specUAll;
00745 delete specVAll;
00746
00747 }
00748 nslice++;
00749 }
00750 }
|
|
|
Reimplemented from AlgShowerSRList. Definition at line 755 of file AlgShowerSSList.cxx. 00756 {
00757 }
|
1.3.9.1