Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

AlgAltDeMuxBase.cxx

Go to the documentation of this file.
00001 
00002 // $Id: AlgAltDeMuxBase.cxx,v 1.21 2008/11/18 17:07:13 rhatcher Exp $
00003 //
00004 // AlgAltDeMuxBase
00005 //
00006 // An Algorithm Base class for the Alternative DeMuxing Algoriths 
00007 // developed in Cambridge.
00008 //
00009 // Author:  M. Thomson April 2003
00011 #include <cassert>
00012 #include <cmath>
00013 #include <algorithm>
00014 #include <vector>
00015 #include "Candidate/CandContext.h"
00016 #include "Candidate/CandHandle.h"
00017 #include "CandDigit/CandDeMuxDigitHandle.h"
00018 #include "CandDigit/CandDeMuxDigitListHandle.h"
00019 #include "MessageService/MsgService.h"
00020 #include "Algorithm/AlgConfig.h"
00021 #include "Algorithm/AlgFactory.h"
00022 #include "Algorithm/AlgHandle.h"
00023 #include "TObjArray.h"
00024 #include "TH1.h"
00025 #include "TFolder.h"
00026 #include "TROOT.h"
00027 #include "TPolyMarker.h"
00028 #include "CandData/CandRecord.h"           // DigitList handling
00029 #include "CandDigit/CandDigitListHandle.h" // "                "
00030 #include "CandDigit/CandDigitHandle.h"     // "                "
00031 #include "UgliGeometry/UgliGeomHandle.h"
00032 #include "UgliGeometry/UgliPlnNode.h"
00033 #include "Validity/VldContext.h"
00034 #include "Plex/PlexPlaneId.h"
00035 #include "AltDeMuxPatternMaster.h"
00036 #include "AlgAltDeMuxBase.h"
00037 
00038 ClassImp(AlgAltDeMuxBase)
00039   
00040 
00041 //-----------------------------------------------------------------------
00042 
00043 CVSID("$Id: AlgAltDeMuxBase.cxx,v 1.21 2008/11/18 17:07:13 rhatcher Exp $");
00044 
00045 //-----------------------------------------------------------------------
00046 
00047 AlgAltDeMuxBase::AlgAltDeMuxBase()
00048 {
00049   //default constructor
00050   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase() Constructor" << endl;
00051 
00052   this->Initialize("");
00053   
00054   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase Leaving Constructor" << endl;
00055 }
00056 
00057 AlgAltDeMuxBase::AlgAltDeMuxBase(const char* name)
00058 {
00059   //default constructor
00060   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase(name) Constructor" << endl;
00061 
00062   this->Initialize(name);
00063   
00064   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase Leaving Constructor" << endl;
00065   
00066 }
00067 
00068 void AlgAltDeMuxBase::Initialize(const char* name)
00069 {
00070   
00071   fList = new TList();
00072   fXTalkFraction        = 0.05;
00073   fXTalk1PEFraction     = 0.25;
00074   fXTalk2PEFraction     = 0.15;
00075   fXTalk5PEFraction     = 0.10;
00076   fNoiseTimeWindow      = 100.;
00077   fSigmasForTimingWindow = 2.5;
00078 
00079   // Far Detector Monte Calro
00080 
00081   fScintillatorNMC = 1.75;  
00082   fWLSFibreNMC     = 1.75; 
00083   fClearFibreNMC   = 1.75;  
00084   fSigmaTMC        = 2.5; //(ns)
00085 
00086   // Far Detector DATA
00087 
00088   fScintillatorN = 1.77;  
00089   fWLSFibreN     = 1.77; 
00090   fClearFibreN   = 1.77;  
00091   fSigmaTData    = 2.5; //(ns)
00092                            
00093   fNumberOfStrips = 192;
00094   fEventType = UNKNOWN;
00095   fDiagnosticPlots = false;
00096   //  amWriting = false;
00097   amShowing = false;
00098   pCalculator = new AltDeMuxCalc();
00099   this->Setup();
00100   
00101   diagnosticCanvastitle = name;
00102   diagnosticCanvas = false;
00103 
00104   _pixelToVaChannel[0]  = 3;
00105   _pixelToVaChannel[1]  = 5;
00106   _pixelToVaChannel[2]  = 14;
00107   _pixelToVaChannel[3]  = 16;
00108   _pixelToVaChannel[4]  = 7;
00109   _pixelToVaChannel[5]  = 9;
00110   _pixelToVaChannel[6]  = 10;
00111   _pixelToVaChannel[7]  = 12;
00112   _pixelToVaChannel[8]  = 11;
00113   _pixelToVaChannel[9]  = 13;
00114   _pixelToVaChannel[10] = 6;
00115   _pixelToVaChannel[11] = 8;
00116   _pixelToVaChannel[12] = 17;
00117   _pixelToVaChannel[13] = 15;
00118   _pixelToVaChannel[14] = 2;
00119   _pixelToVaChannel[15] = 4;
00120 
00121   for(int i = 0; i<8; i++){
00122     for(int j = 0; j<9; j++){
00123       _pixelSpotXTalkMap[i][j]=0.0;
00124     }
00125   }
00126   
00127   // spot 0
00128 
00129   _pixelSpotXTalkMap[3][0] = 0.007; 
00130   _pixelSpotXTalkMap[3][1] = 0.025;
00131   _pixelSpotXTalkMap[3][2] = 0.002;
00132   _pixelSpotXTalkMap[3][3] = 0.025;
00133   _pixelSpotXTalkMap[3][5] = 0.003;
00134   _pixelSpotXTalkMap[3][6] = 0.001;
00135   _pixelSpotXTalkMap[3][7] = 0.003;
00136   _pixelSpotXTalkMap[3][8] = 0.002;
00137   
00138   // spot 1
00139 
00140   _pixelSpotXTalkMap[2][0] = 0.003; 
00141   _pixelSpotXTalkMap[2][1] = 0.025;
00142   _pixelSpotXTalkMap[2][2] = 0.003;
00143   _pixelSpotXTalkMap[2][3] = 0.006;
00144   _pixelSpotXTalkMap[2][5] = 0.006;
00145   _pixelSpotXTalkMap[2][6] = 0.001;
00146   _pixelSpotXTalkMap[2][7] = 0.004;
00147   _pixelSpotXTalkMap[2][8] = 0.001;
00148   
00149 
00150   // spot 2
00151 
00152   _pixelSpotXTalkMap[1][0] = 0.002; 
00153   _pixelSpotXTalkMap[1][1] = 0.025;
00154   _pixelSpotXTalkMap[1][2] = 0.007;
00155   _pixelSpotXTalkMap[1][3] = 0.003;
00156   _pixelSpotXTalkMap[1][5] = 0.025;
00157   _pixelSpotXTalkMap[1][6] = 0.001;
00158   _pixelSpotXTalkMap[1][7] = 0.003;
00159   _pixelSpotXTalkMap[1][8] = 0.002;
00160   
00161   // spot 3
00162 
00163   _pixelSpotXTalkMap[5][0] = 0.002; 
00164   _pixelSpotXTalkMap[5][1] = 0.008;
00165   _pixelSpotXTalkMap[5][2] = 0.001;
00166   _pixelSpotXTalkMap[5][3] = 0.011;
00167   _pixelSpotXTalkMap[5][5] = 0.004;
00168   _pixelSpotXTalkMap[5][6] = 0.002;
00169   _pixelSpotXTalkMap[5][7] = 0.008;
00170   _pixelSpotXTalkMap[5][8] = 0.001;
00171   
00172 
00173   // spot 4
00174 
00175   _pixelSpotXTalkMap[4][0] = 0.001; 
00176   _pixelSpotXTalkMap[4][1] = 0.008;
00177   _pixelSpotXTalkMap[4][2] = 0.002;
00178   _pixelSpotXTalkMap[4][3] = 0.004;
00179   _pixelSpotXTalkMap[4][5] = 0.011;
00180   _pixelSpotXTalkMap[4][6] = 0.001;
00181   _pixelSpotXTalkMap[4][7] = 0.008;
00182   _pixelSpotXTalkMap[4][8] = 0.002;
00183   
00184 
00185   // spot 5
00186 
00187   _pixelSpotXTalkMap[8][0] = 0.002; 
00188   _pixelSpotXTalkMap[8][1] = 0.003;
00189   _pixelSpotXTalkMap[8][2] = 0.001;
00190   _pixelSpotXTalkMap[8][3] = 0.025;
00191   _pixelSpotXTalkMap[8][5] = 0.003;
00192   _pixelSpotXTalkMap[8][6] = 0.007;
00193   _pixelSpotXTalkMap[8][7] = 0.025;
00194   _pixelSpotXTalkMap[8][8] = 0.002;
00195   
00196 
00197   // spot 6
00198 
00199   _pixelSpotXTalkMap[7][0] = 0.001; 
00200   _pixelSpotXTalkMap[7][1] = 0.004;
00201   _pixelSpotXTalkMap[7][2] = 0.001;
00202   _pixelSpotXTalkMap[7][3] = 0.006;
00203   _pixelSpotXTalkMap[7][5] = 0.006;
00204   _pixelSpotXTalkMap[7][6] = 0.003;
00205   _pixelSpotXTalkMap[7][7] = 0.025;
00206   _pixelSpotXTalkMap[7][8] = 0.003;
00207   
00208 
00209   // spot 7
00210 
00211   _pixelSpotXTalkMap[6][0] = 0.001; 
00212   _pixelSpotXTalkMap[6][1] = 0.003;
00213   _pixelSpotXTalkMap[6][2] = 0.002;
00214   _pixelSpotXTalkMap[6][3] = 0.003;
00215   _pixelSpotXTalkMap[6][5] = 0.025;
00216   _pixelSpotXTalkMap[6][6] = 0.002;
00217   _pixelSpotXTalkMap[6][7] = 0.025;
00218   _pixelSpotXTalkMap[6][8] = 0.007;
00219 
00220   for(Int_t i=0; i<MAX_NUMBER_OF_PMTS; i++){
00221     fPMTtot[i]=0.0;
00222     for(int j=0; j<16; j++){
00223       fPMTmap[i][j]=0.0;
00224       fXTalkmap[i][j]=0.0;
00225     }
00226     for(int j=0; j<22; j++){
00227       fVAmap[i][j]=0.0;
00228     }
00229   }
00230   return;
00231 }
00232 
00233 void AlgAltDeMuxBase::SetConstants(const VldContext* vldc){
00234   
00235   SimFlag::SimFlag_t simflag = vldc->GetSimFlag( );   
00236 
00237   if(simflag==SimFlag::kMC||simflag==SimFlag::kReroot ){
00238     // velocities of light in m/ns from refractive indices
00239     fClearFibreC   = 0.30/fClearFibreNMC;
00240     fWLSFibreC     = 0.30/fWLSFibreNMC;
00241     fScintillatorC = 0.30/fScintillatorNMC;
00242     // Timing resolution in ns
00243     fSigmaT        = fSigmaTMC;
00244     MSG("AltDeMux", Msg::kDebug) 
00245       << "IT IS Monte Carlo Set Constants " << endl;
00246   }else{
00247     // velocities of light in m/ns from refractive indices
00248     fClearFibreC   = 0.30/fClearFibreN;
00249     fWLSFibreC     = 0.30/fWLSFibreN;
00250     fScintillatorC = 0.30/fScintillatorN;
00251     // Timing resolution in ns
00252     fSigmaT        = fSigmaTData;
00253   }
00254 
00255   // resolution on strip number from timing 
00256   fSigmaStripFromTiming = fSigmaT*fScintillatorC/1.4142/0.041666;
00257   MSG("AltDeMux", Msg::kDebug)  
00258     << "AlgAltDeMuxBase::SetContants Sigma from Timing : " 
00259     << fSigmaStripFromTiming << " strip" << endl;
00260 
00261   // Tell the Calculator which constants to use 
00262 
00263   pCalculator->SetClearFibreC(fClearFibreC);
00264   pCalculator->SetWLSFibreC(fWLSFibreC);
00265   pCalculator->SetScintillatorC(fScintillatorC);
00266   pCalculator->SetNumberOfStrips(fNumberOfStrips);
00267   pCalculator->SetUgli(pUgh);
00268 
00269 }
00270 
00271 
00272 
00273 void AlgAltDeMuxBase::TidyUp() 
00274 {    
00275   //fList->Delete();
00276 }
00277 
00278 //______________________________________________________________________
00279 
00280 
00281 //-----------------------------------------------------------------------
00282 // Default implementation of the demuxing - does nothing
00283 void AlgAltDeMuxBase::RunAlg(AlgConfig & /* acd */, CandHandle & /* ch */, 
00284                              CandContext & /*cx */)
00285 {
00286 
00287   return;
00288 }
00289 
00290 
00291 AlgAltDeMuxBase::~AlgAltDeMuxBase()
00292 {
00293 
00294 }
00295 
00296 
00297 void AlgAltDeMuxBase::Trace(const char * /* c */) const
00298 {
00299 }
00300 
00301 void AlgAltDeMuxBase::CreateDiagnosticCanvas()
00302 {
00303 
00304   // If requested AlgAltDeMuxBase has a built-in diagnositic/debugging canvas
00305   // which provides a visual display of the DeMuxing as the algorithm
00306   // progresses through its various steps.
00307 
00308   if(diagnosticCanvas)return;
00309 
00310   diagnosticCanvas = true;
00311   string title  = "AlgAltDeMuxBase(";
00312   title = title + diagnosticCanvastitle;
00313   title = title + ") Diagnostics screen";
00314 
00315   fCanvas = new TCanvas(title.c_str(),diagnosticCanvastitle.c_str(),600,600);
00316 
00317   fUview  = NULL;
00318   fVview  = NULL;
00319   fUTime  = NULL;
00320   fVTime  = NULL;
00321   fUMask  = NULL;
00322   fVMask  = NULL;
00323   fHoughU = NULL;
00324   fHoughV = NULL;
00325   fHoughProjU = NULL;
00326   fHoughProjV = NULL;
00327   fHoughSliceU = NULL;
00328   fHoughSliceV = NULL;
00329   fUZFitS = NULL;
00330   fVZFitS = NULL;
00331   fUZFitT = NULL;
00332   fVZFitT = NULL;
00333   fUZFitSSM1 = NULL;
00334   fUZFitSSM2 = NULL;
00335   fUZFitQSSM1 = NULL;
00336   fUZFitQSSM2 = NULL;
00337   fUZFitTSM1 = NULL;
00338   fUZFitTSM2 = NULL;
00339   fVZFitSSM1 = NULL;
00340   fVZFitSSM2 = NULL;
00341   fVZFitTSM1 = NULL;
00342   fVZFitTSM2 = NULL;
00343   fVZFitQSSM1 = NULL;
00344   fVZFitQSSM2 = NULL;
00345 
00346 
00347 
00348 // Create the pads;  Pad takes xlo, ylo, xhi, yhi in NC
00349   fUpad  = new TPad("upad","U pad",0.010,0.505,0.990,0.990);
00350   fVpad  = new TPad("vpad","V pad",0.010,0.010,0.990,0.495);
00351 
00352     // white background
00353   fUpad->SetFillColor(10);
00354   fVpad->SetFillColor(10);
00355     
00356     // tweak the margins to maximize histogram use of pads
00357   fUpad->SetLeftMargin(0.05);
00358   fUpad->SetRightMargin(0.0001);
00359   fUpad->SetTopMargin(0.0001);
00360   fUpad->SetBottomMargin(0.055);
00361   fVpad->SetLeftMargin(0.05);
00362   fVpad->SetRightMargin(0.0001);
00363   fVpad->SetTopMargin(0.0001);
00364   fVpad->SetBottomMargin(0.055);
00365   fUpad->Draw();
00366   fVpad->Draw();
00367     
00368   fCanvas->Draw();
00369 }
00370 
00371 
00372 void AlgAltDeMuxBase::ClearDiagnosticHistos()
00373 {
00374 
00375   // Clear the diagnostic histograms - only called if fDiagnosticPlots==true
00376 
00377   if(!fDiagnosticPlots)return;
00378   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::ClearDiagnosticHistos()" << endl;
00379 
00380   if(fUpad)fUpad->Clear("");
00381   if(fVpad)fVpad->Clear("");
00382   
00383 // remove old histograms if they exists
00384   if ( fUview ) { delete fUview; fUview=0; }
00385   if ( fVview ) { delete fVview; fVview=0; }
00386   if ( fUTime ) { delete fUTime; fUTime=0; }
00387   if ( fVTime ) { delete fVTime; fVTime=0; }
00388   if ( fUMask ) { delete fUMask; fUMask=0; }
00389   if ( fVMask ) { delete fVMask; fVMask=0; }
00390   if ( fHoughU) { delete fHoughU; fHoughU=0; }
00391   if ( fHoughV) { delete fHoughV; fHoughV=0; }
00392   if ( fHoughProjU) { delete fHoughProjU; fHoughProjU=0; }
00393   if ( fHoughProjV) { delete fHoughProjV; fHoughProjV=0; }
00394   if ( fHoughSliceU) { delete fHoughSliceU; fHoughSliceU=0; }
00395   if ( fHoughSliceV) { delete fHoughSliceV; fHoughSliceV=0; }
00396   if(fUZFitS){delete fUZFitS; fUZFitS=0;}
00397   if(fVZFitS){delete fVZFitS; fVZFitS=0;}
00398   if(fUZFitT){delete fUZFitT; fUZFitT=0;}
00399   if(fVZFitT){delete fVZFitT; fVZFitT=0;}
00400   if(fUZFitSSM1){delete fUZFitSSM1; fUZFitSSM1=0;}
00401   if(fUZFitSSM2){delete fUZFitSSM2; fUZFitSSM2=0;}
00402   if(fUZFitQSSM1){delete fUZFitQSSM1; fUZFitQSSM1=0;}
00403   if(fUZFitQSSM2){delete fUZFitQSSM2; fUZFitQSSM2=0;}
00404   if(fVZFitQSSM1){delete fVZFitQSSM1; fVZFitQSSM1=0;}
00405   if(fVZFitQSSM2){delete fVZFitQSSM2; fVZFitQSSM2=0;}
00406   if(fUZFitTSM1){delete fUZFitTSM1; fUZFitTSM1=0;}
00407   if(fUZFitTSM2){delete fUZFitTSM2; fUZFitTSM2=0;}
00408   if(fVZFitSSM1){delete fVZFitSSM1; fVZFitSSM1=0;}
00409   if(fVZFitSSM2){delete fVZFitSSM2; fVZFitSSM2=0;}
00410   if(fVZFitTSM1){delete fVZFitTSM1; fVZFitTSM1=0;}
00411   if(fVZFitTSM2){delete fVZFitTSM2; fVZFitTSM2=0;}
00412 
00413   // create histograms that we'll use for World Coordinates
00414   // create histograms that we'll use for World Coordinates
00415   fUview = new TH2F("Uview","U view",501,-0.5,500.5,1,0.,193.);
00416   fVview = new TH2F("Vview","V view",501,-0.5,500.5,1,0.,193.);
00417   fUTime = new TH2F("UTime","U time view",501,-0.5,500.5,193,0.,193.);
00418   fVTime = new TH2F("VTime","V time view",501,-0.5,500.5,193,0.,193.);
00419   fUMask = new TH2F("UMask","U view mask",501,-0.5,500.5,193,0.,193.);
00420   fVMask = new TH2F("VMask","V view mask",501,-0.5,500.5,193,0.,193.);
00421   fHoughU = new TH2F("houghSpaceU", "U Hough Space", 400, -3., 1., 500, -250., 250.);
00422   fHoughV = new TH2F("houghSpaceV", "V Hough Space", 400, -3., 1., 500, -250., 250.);
00423 
00424   fHoughProjU = new TH1F("houghSpaceProjU", "U HoughX Space", 400, -3., 1.);
00425   fHoughProjV = new TH1F("houghSpaceProjV", "V HoughX Space", 400, -3., 1.);
00426 
00427   fHoughSliceU = new TH1F("houghSpaceSliceU", "U Hough c", 500, -250., 250.);
00428   fHoughSliceV = new TH1F("houghSpaceSliceV", "V Hough c", 500, -250., 250.);
00429 
00430     
00431   // don't draw the Stats box
00432   fUview->SetStats(kFALSE);
00433   fVview->SetStats(kFALSE);
00434   
00435   fUTime->SetStats(kFALSE);
00436   fVTime->SetStats(kFALSE);
00437   
00438   fUMask->SetStats(kFALSE);
00439   fVMask->SetStats(kFALSE);
00440 
00441   fHoughU->SetStats(kFALSE);
00442   fHoughV->SetStats(kFALSE);
00443 
00444   fHoughProjU->SetStats(kFALSE);
00445   fHoughProjV->SetStats(kFALSE);
00446 
00447   fHoughSliceU->SetStats(kFALSE);
00448   fHoughSliceV->SetStats(kFALSE);
00449     
00450   // take away any association with a "directory" for these histograms
00451   fUview->SetDirectory(0);
00452   fVview->SetDirectory(0);
00453 
00454   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::ClearDiagnosticHistos() DONE" << endl;
00455 
00456   return;
00457 }
00458 
00459 void AlgAltDeMuxBase::ClearArrays()
00460 {
00461 
00462   // Zero internal arrays/vectors used to DeMux event
00463 
00464   fEventType = UNKNOWN;
00465 
00466   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::ClearArrays()" << endl;
00467 
00468   // Timelist will contain an ordered list of hit times.
00469   fTimeList.erase(fTimeList.begin(),fTimeList.end());
00470 
00471   // Reset the timing masks 
00472   ResetTimingMask();
00473 
00474   // Reset the DeMuxed group ID counter
00475   fUniqueDeMuxedGroupID=0;
00476 
00477   // Clear vector of DeMuxed strip end EW pairs
00478 
00479   // loop over planes/ends
00480   for(Int_t iplane=0; iplane<MAX_NUMBER_OF_PLANES;iplane++){
00481     fUVMap[iplane]=PlaneView::kUnknown;
00482     for(Int_t istrip=0; istrip<MAX_NUMBER_OF_STRIPS;istrip++){
00483       fTimingMask[iplane][istrip] = false;
00484     }
00485     fDeMuxedPairs[iplane].erase(fDeMuxedPairs[iplane].begin(),fDeMuxedPairs[iplane].end());
00486     fDeMuxedSingles[iplane].erase(fDeMuxedSingles[iplane].begin(),fDeMuxedSingles[iplane].end());
00487     NdemuxedHitsU[iplane] = 0;
00488     NdemuxedHitsV[iplane] = 0;
00489     for(Int_t iew=0; iew<=1;iew++){
00490       // Clear the arrays of vectors of AltLists
00491       fPlanesAltLists[iplane][iew].erase(fPlanesAltLists[iplane][iew].begin(),fPlanesAltLists[iplane][iew].end());
00492       fDeMuxedPlanesAltLists[iplane][iew].erase(fDeMuxedPlanesAltLists[iplane][iew].begin(),fDeMuxedPlanesAltLists[iplane][iew].end());
00493       fNoisePlanesAltLists[iplane][iew].erase(fNoisePlanesAltLists[iplane][iew].begin(),fNoisePlanesAltLists[iplane][iew].end());
00494       fXTalkPlanesAltLists[iplane][iew].erase(fXTalkPlanesAltLists[iplane][iew].begin(),fXTalkPlanesAltLists[iplane][iew].end());
00495     }
00496     // zero counters
00497     fPlaneHit[iplane] = 0;
00498     fPlanePair[iplane] = 0;
00499     fGoldPlaneHit[iplane] = 0;
00500     fQTotE[iplane] = 0;
00501     fQTotW[iplane] = 0;
00502     fQMaxE[iplane] = 0;
00503     fQMaxW[iplane] = 0;
00504   }
00505   _nDeMuxedPlanesU=0;
00506   _nDeMuxedPlanesV=0;
00507   _nHitPlanesU=0;
00508   _nHitPlanesV=0;
00509 
00510 
00511   // Zero PMT maps (for previously PMT with hits from previous event)
00512   for(int i=0; i<MAX_NUMBER_OF_PMTS; i++){
00513     if(fPMTtot[i]>0){
00514       fPMTtot[i]=0.0;
00515       for(int j=0; j<16; j++){
00516         fPMTmap[i][j]=0.0;
00517         fXTalkmap[i][j]=0.0;
00518       }
00519       for(int j=0; j<22; j++){
00520         fVAmap[i][j]=0.0;
00521       }
00522     }
00523   }
00524 
00525   // reset range of planes to DeMux 
00526   fLowestDeMuxedPairPlane = MAX_NUMBER_OF_PLANES-1;
00527   fHighestDeMuxedPairPlane = 0;
00528 
00529   fUseHoughSlope         = false;      
00530   fUseFitSlopeTime       = false;   
00531   fUseFitSlopeHits       = false;   
00532   fUseInterpolation      = false;      
00533   fUseSafeExtrapolationF = false; 
00534   fUseSafeExtrapolationB = false; 
00535   fUseLevelStripF        = false;         
00536   fUseLevelStripB        = false;         
00537   //************************************
00538   fUseExtrapolationF     = true;     
00539   fUseExtrapolationB     = true;     
00540   fUseSameStrip          = true;          
00541   //************************************
00542 
00543   // say goodbye
00544   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::ClearArrays() DONE" << endl;
00545 }
00546 
00547 
00548 void AlgAltDeMuxBase::MakeAltListMap(CandDigitListHandle& cdlh)
00549 {
00550   
00551   // Fill the arrays of {vectors of AltLists} which are to navigate through
00552   // the UNDEMUXed hits. Could have used Navigator instead but familiarity
00553   // won out. Arrays of vectors also provide a fast efficient method of
00554   // iterating over the data
00555 
00556   PlexSEIdAltL* paltlist;
00557 
00558   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::MakeAltListMap" << endl;
00559   
00560   int ndigits = 0;
00561   fAbsTime = cdlh.GetAbsTime()*1.0E9;
00562   pCalculator->SetAbsTime(fAbsTime);
00563 
00564   CandDigitHandleItr cdhItr(cdlh.GetDaughterIterator());
00565   
00566   while ( CandDigitHandle *cdh = cdhItr() ) {
00567     // for each digit
00568     paltlist = &(cdh->GetPlexSEIdAltLWritable());
00569     int iplane = paltlist->GetPlane();
00570     if(!paltlist->IsVetoShield()){
00571       if(iplane>0&&iplane<MAX_NUMBER_OF_PLANES){
00572         if(paltlist->GetEnd()==StripEnd::kEast){
00573           fPlanesAltLists[iplane][ALG_EAST].push_back(paltlist);
00574         }else{
00575           fPlanesAltLists[iplane][ALG_WEST].push_back(paltlist);
00576         }
00577         fTimeList.push_back(paltlist->GetCurrentItem().GetTime()*1.0E9);
00578         fUVMap[iplane] = paltlist->GetPlaneView(); 
00579         ndigits++;
00580       }else{
00581         MSG("AltDeMux", Msg::kWarning) << "AlgAltDeMuxBase::MakeAltListMap => Plane out of array bounds : " << iplane << " - would give overflow (ignoring it)!" << endl;
00582       }
00583     }else{
00584       // MSG("AltDeMux", Msg::kVerbose) << "AlgAltDeMuxBase::MakeAltListMap => Veto Shield Plane : " << iplane << " - IGNORE IT !" << endl;
00585     }
00586   }
00587 
00588   return;
00589 }
00590 
00591 void  AlgAltDeMuxBase::MakePixelMap(CandDigitListHandle& cdlh)
00592 {
00593   
00594   // Build up a map of charge deposits for each PMT pixel - for use in
00595   // crosstalk rejection. NOTE PMTmuxID is an internal number scheme
00596   // for FarDet PMTs
00597 
00598   PlexSEIdAltL* paltlist;
00599   
00600   CandDigitHandleItr cdhItr(cdlh.GetDaughterIterator());
00601   
00602   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::MakePixelMap" << endl;
00603 
00604   while ( CandDigitHandle *cdh = cdhItr() ) {
00605     // for each digit
00606     paltlist = &(cdh->GetPlexSEIdAltLWritable());
00607     int iplane = paltlist->GetPlane();
00608     paltlist->SetFirst();
00609     
00610     if(!paltlist->IsVetoShield()){
00611       if(iplane>0&&iplane<MAX_NUMBER_OF_PLANES){
00612 
00613         PlexPixelSpotId pixelID = (paltlist->GetCurrentItem()).GetPixelSpotId(); 
00614         Int_t pixel  = pixelID.GetPixel();
00615         Int_t vaChannel = _pixelToVaChannel[pixel];
00616         Int_t PMTmuxID = pixelID.GetTube();
00617         PMTmuxID      += 3*pixelID.GetInRack();
00618         PMTmuxID      += 24*pixelID.GetRackBay();
00619         Char_t level = pixelID.GetRackLevel(); 
00620         Char_t ew = pixelID.GetEastWest(); 
00621         if(level=='U'){
00622           PMTmuxID += 450;
00623         }
00624         if(ew =='E'){
00625           PMTmuxID += 900;
00626         }
00627         //      Int_t uid = pixelID.GetUniquePmtEncodedValue();    
00628 
00629         if(PMTmuxID<MAX_NUMBER_OF_PMTS){
00630           Float_t q  = paltlist->GetCurrentItem().GetPE();
00631           Float_t qc = paltlist->GetCurrentItem().GetSigCorr()/60.;
00632           if(qc/q<0.1 || qc/q > 10.0){
00633             MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::MakePixelMap Large/small SigCor/SigPE ratio : " <<qc/q << " for Plane : " << iplane << endl;
00634             qc=q;
00635           }
00636           fPMTmap[PMTmuxID][pixel] += qc; 
00637           fVAmap[PMTmuxID][vaChannel] += qc; 
00638           fPMTtot[PMTmuxID]        += qc; 
00639         }else{
00640           MSG("AltDeMux", Msg::kError) << "AlgAltDeMuxBase::MakePixelMap => PMT out of array bounds : " << PMTmuxID << " ignoring it !" << endl;
00641         }
00642       }
00643     }
00644   }
00645 
00646   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::MakePixelMap DONE" << endl;
00647 
00648   return;
00649 }
00650 
00651 
00652 
00653 void  AlgAltDeMuxBase::StripNoise()
00654 {
00655   
00656   // Attempt to identify and remove probably out-of-time noise hits. 
00657 
00658   Int_t nNoiseHits=0;
00659   bool ok;
00660 
00661   if(fTimeList.size()==0){
00662     return;
00663   }
00664 
00665   sort(fTimeList.begin(),fTimeList.end());
00666   Int_t median = static_cast<Int_t>(fTimeList.size()*0.5);
00667   Float_t medianTime = fTimeList[median];
00668 
00669 
00670   MSG("AltDeMux", Msg::kVerbose) << "AlgAltDeMuxBase::StripNoiseHits - Median hit time : " << medianTime << endl;
00671 
00672   vector <PlexSEIdAltL*>::iterator literA;
00673 
00674   // Identify noise hits and store in fNoisePlanesAltLists 
00675 
00676   for(int iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
00677     for(int iew = 0; iew<=1; iew++){
00678       if(fPlanesAltLists[iplane][iew].size()>0){
00679         literA = fPlanesAltLists[iplane][iew].begin();
00680         while (literA != fPlanesAltLists[iplane][iew].end()){
00681           if( (*literA)->GetCurrentItem().GetPE()<1.5){
00682             if(fabs(  (*literA)->GetCurrentItem().GetTime()*1E9-medianTime)>fNoiseTimeWindow){
00683               MSG("AltDeMux", Msg::kVerbose) << "AlgAltDeMuxBase::StripNoiseHits - Noise Hit in plane : " << iplane << " q : " << (*literA)->GetCurrentItem().GetPE() << " time : " << (*literA)->GetCurrentItem().GetTime()*1E9 << endl; 
00684               fNoisePlanesAltLists[iplane][iew].push_back(*literA);
00685               nNoiseHits++;
00686             }
00687           }
00688           *literA++;
00689         }
00690       }
00691     }
00692   }
00693 
00694 
00695   // Remove noise hits from fPlanesAltLists 
00696 
00697   for(int iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
00698     for(int iew = 0; iew<=1; iew++){
00699       if(fNoisePlanesAltLists[iplane][iew].size()>0){
00700         literA = fNoisePlanesAltLists[iplane][iew].begin();
00701         while (literA != fNoisePlanesAltLists[iplane][iew].end()){
00702           ok = RemoveFromPlanesList(iplane,iew,*literA);
00703           if(!ok)MSG("AltDeMux", Msg::kError) << "AlgAltDeMuxBase::StripNoiseHits - hit not found !" << endl;
00704           *literA++;
00705         }
00706       }
00707     }
00708   }
00709 
00710   return;
00711 }
00712 
00713 bool AlgAltDeMuxBase::RemoveFromPlanesList(Int_t iplane, Int_t iew, PlexSEIdAltL* paltlist)
00714 {
00715 
00716   // Find and remove an PlexSEIdAltL* from the fPlanesAltList array
00717   // which stores undemuxed hits.
00718 
00719   vector <PlexSEIdAltL*>::iterator literA;
00720 
00721 
00722   literA = fPlanesAltLists[iplane][iew].begin();
00723   while (literA != fPlanesAltLists[iplane][iew].end()){
00724     if( (*literA)==paltlist ){
00725       fPlanesAltLists[iplane][iew].erase(literA);
00726       return true;
00727     }
00728     literA++;
00729   }
00730 
00731   return false;
00732   
00733 }
00734 
00735 bool AlgAltDeMuxBase::RemoveSingle(Int_t iplane, PlexSEIdAltL* paltlist)
00736 {
00737 
00738   // Find and remove an PlexSEIdAltL* from the fDeMuxedSingles array
00739   // which stores undemuxed hits.
00740 
00741   vector <DeMuxedSingle>::iterator literA;
00742  
00743   literA = fDeMuxedSingles[iplane].begin();
00744   while (literA != fDeMuxedSingles[iplane].end()){
00745     if( (*literA).altList==paltlist ){
00746       fDeMuxedSingles[iplane].erase(literA);
00747       return true;
00748     }
00749     literA++;
00750   }
00751 
00752   return false;
00753   
00754 }
00755 
00756 
00757 void  AlgAltDeMuxBase::StripCrossTalk(CandDeMuxDigitListHandle& cdlh)
00758 {
00759 
00760   // Loop over all hits (stored in fPlanesAltList array) and use PMT
00761   // map to decide whether hit is likely to be cross-talk. If a hit
00762   //
00763 
00764   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::StripCrossTalk" << endl;
00765 
00766   Int_t nXTalkHits=0;
00767   vector <PlexSEIdAltL*>::iterator literA;
00768 
00769   for(int iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
00770     for(int iew = ALG_EAST; iew<=ALG_WEST; iew++){
00771       if(fPlanesAltLists[iplane][iew].size()>0){
00772         literA = fPlanesAltLists[iplane][iew].begin();
00773         while (literA != fPlanesAltLists[iplane][iew].end()){
00774           if(IsXTalk(*literA)){
00775             fXTalkPlanesAltLists[iplane][iew].push_back(*literA);
00776             MSG("AltDeMux", Msg::kVerbose) << "AlgAltDeMuxBase::StripCrossTalk - remove hit" << endl;
00777             nXTalkHits++;
00778           }
00779           literA++;
00780         }
00781       }
00782     }
00783   }
00784 
00785 
00786   // Remove cross talk hits from fPlanesAltLists 
00787 
00788   for(int iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
00789     for(int iew = ALG_EAST; iew<=ALG_WEST; iew++){
00790       if(fXTalkPlanesAltLists[iplane][iew].size()>0){
00791         literA = fXTalkPlanesAltLists[iplane][iew].begin();
00792         while (literA != fXTalkPlanesAltLists[iplane][iew].end()){
00793           bool ok = RemoveFromPlanesList(iplane,iew,*literA);
00794           if(!ok)MSG("AltDeMux", Msg::kError) << "AlgAltDeMuxBase::StripCrossTalk - hit not found !" << endl;
00795           *literA++;
00796         }
00797       }
00798     }
00799   }
00800 
00801   this->TagCrossTalk(cdlh);
00802 
00803   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::StripCrossTalk DONE" << endl;
00804 
00805   return;
00806 
00807 }
00808 
00809 
00810 
00811 void  AlgAltDeMuxBase::ReTagCrossTalk(CandDeMuxDigitListHandle& cdlh)
00812 {
00813 
00814 
00815   CandDeMuxDigitHandleItr cdhItr(cdlh.GetDaughterIterator());
00816   
00817   while ( CandDeMuxDigitHandle *digit = cdhItr() ) {
00818     // for each digit
00819     PlexSEIdAltL* paltlist = &(digit->GetPlexSEIdAltLWritable());
00820     amShowing = false;
00821     paltlist->GetBestItem();
00822     if(!paltlist->IsValid())paltlist->SetFirst();
00823     if(paltlist->IsValid()){
00824       Int_t dmxXTalk = digit->GetDeMuxDigitFlagWord();
00825       if(dmxXTalk==0){
00826         if(IsXTalk(paltlist)){
00827           digit->SetDeMuxDigitFlagBit(CandDeMuxDigit::kXTalk);  
00828         }
00829       }else{
00830       }
00831     }else{
00832       //cout << "INVALID ALTLIST ! " << endl;
00833     }
00834     amShowing = false;
00835   }
00836 
00837   return;
00838 
00839 }
00840 
00841 
00842 
00843 void  AlgAltDeMuxBase::FinalReTagCrossTalk(CandDeMuxDigitListHandle& cdlh)
00844 {
00845 
00846   CandDeMuxDigitHandleItr cdhItr(cdlh.GetDaughterIterator());
00847   
00848   while ( CandDeMuxDigitHandle *digit = cdhItr() ) {
00849     // for each digit
00850     PlexSEIdAltL* paltlist = &(digit->GetPlexSEIdAltLWritable());
00851     if(paltlist->GetSize()==0){
00852       // pixel spot does not correspond to valid strip - tag as xtalk 
00853       digit->SetDeMuxDigitFlagBit(CandDeMuxDigit::kXTalk);  
00854       return;
00855     }
00856     amShowing = false;
00857     paltlist->GetBestItem();
00858     if(!paltlist->IsValid())paltlist->SetFirst();
00859     if(paltlist->IsValid()){
00860       Int_t dmxXTalk = digit->GetDeMuxDigitFlagWord();
00861       if(dmxXTalk==0){
00862         if(IsXTalk(paltlist)){
00863           digit->SetDeMuxDigitFlagBit(CandDeMuxDigit::kXTalk);  
00864         }else{
00865           digit->UnSetDeMuxDigitFlagBit(CandDeMuxDigit::kXTalk);
00866         }
00867       }
00868       float Q     = paltlist->GetBestItem().GetSigCorr()/60.; 
00869       float qspot = PredictedSpotQ(paltlist);
00870       float dist = DistanceToNearestInPlane(paltlist);
00871       if(dmxXTalk!=0){
00872         if(dist==0){
00873           digit->UnSetDeMuxDigitFlagBit(CandDeMuxDigit::kXTalk);
00874           //      cout << "****************************UNSET XTALK FLAG !!!! " << Q << endl; 
00875         }
00876         if(dist==1){
00877           if(Q>3)digit->UnSetDeMuxDigitFlagBit(CandDeMuxDigit::kXTalk);
00878           //cout << "****************************UNSET XTALK FLAG !!!! " << Q << endl; 
00879         }
00880         if(dist==2){
00881           if(Q>5)digit->UnSetDeMuxDigitFlagBit(CandDeMuxDigit::kXTalk);
00882           //cout << "****************************UNSET XTALK FLAG !!!! " << Q << endl; 
00883         }
00884       }else{
00885         if(dist>8){
00886           if(qspot/Q>0.001&&Q<4)digit->SetDeMuxDigitFlagBit(CandDeMuxDigit::kXTalk);
00887         }
00888       }
00889     }else{
00890       //cout << "INVALID ALTLIST ! " << endl;
00891     }
00892     amShowing = false;
00893   }
00894 
00895   return;
00896 
00897 }
00898 
00899 
00900 Float_t AlgAltDeMuxBase::DistanceToNearestInPlane(PlexSEIdAltL* paltlist)
00901 {
00902 
00903   Float_t dmin=999;
00904   PlexStripEndId  seid;
00905   PlexStripEndId dseid;
00906   
00907   int iplane = paltlist->GetPlane();
00908   seid = paltlist->GetBestSEId();
00909   int strip = seid.GetStrip();
00910 
00911   if(iplane>MAX_NUMBER_OF_PLANES)return dmin;
00912 
00913   for(int iew = ALG_EAST; iew<=ALG_WEST; iew++){
00914     for(unsigned int i=0;i<fDeMuxedPlanesAltLists[iplane][iew].size();i++){
00915       if(fDeMuxedPlanesAltLists[iplane][iew][i]!=paltlist){
00916         dseid = fDeMuxedPlanesAltLists[iplane][iew][i]->GetBestSEId();
00917         int dstrip = dseid.GetStrip();
00918         int d = abs(dstrip-strip);
00919         if(d<dmin)dmin=d;
00920       }
00921     }
00922   }
00923 
00924   return dmin;
00925 }
00926 
00927 
00928 Float_t AlgAltDeMuxBase::PredictedSpotQ(PlexSEIdAltL* paltlist)
00929 { 
00930   
00931   PlexPixelSpotId pixelID = (paltlist->GetBestItem()).GetPixelSpotId(); 
00932   Int_t pixel  = pixelID.GetPixel();
00933   Int_t PMTmuxID = pixelID.GetTube();
00934   PMTmuxID      += 3*pixelID.GetInRack();
00935   PMTmuxID      += 24*pixelID.GetRackBay();
00936   Char_t level = pixelID.GetRackLevel(); 
00937   Char_t ew = pixelID.GetEastWest(); 
00938   if(level=='U')PMTmuxID += 450;
00939   if(ew =='E')PMTmuxID += 900;
00940 
00941   return fXTalkmap[PMTmuxID][pixel];
00942 
00943 } 
00944 
00945 void  AlgAltDeMuxBase::TagCrossTalk(CandDeMuxDigitListHandle& cdlh)
00946 {
00947   
00948   PlexSEIdAltL* paltlist;
00949   vector <PlexSEIdAltL*>::iterator literA;
00950   
00951   CandDeMuxDigitHandleItr cdhItr(cdlh.GetDaughterIterator());
00952   
00953   MSG("AltDeMux", Msg::kVerbose) << "AlgAltDeMuxBase::MakePixelMap" << endl;
00954 
00955   while ( CandDeMuxDigitHandle *digit = cdhItr() ) {
00956     // for each digit
00957     paltlist = &(digit->GetPlexSEIdAltLWritable());
00958     int iplane = paltlist->GetPlane();
00959     for(int iew = ALG_EAST; iew<=ALG_WEST; iew++){
00960       if(fXTalkPlanesAltLists[iplane][iew].size()>0){
00961         literA = fXTalkPlanesAltLists[iplane][iew].begin();
00962         while (literA != fXTalkPlanesAltLists[iplane][iew].end()){
00963           if(*literA==paltlist){
00964             digit->SetDeMuxDigitFlagBit(CandDeMuxDigit::kXTalk);  
00965           }
00966           *literA++;
00967         }
00968       }
00969     }
00970   }
00971 
00972   return;
00973 }
00974 
00975 
00976 void  AlgAltDeMuxBase::AddBackCrossTalk()
00977 {
00978 
00979   vector <PlexSEIdAltL*>::iterator literA;
00980 
00981   for(int iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
00982     for(int iew = ALG_EAST; iew<=ALG_WEST; iew++){
00983       if(fXTalkPlanesAltLists[iplane][iew].size()>0){
00984         literA = fXTalkPlanesAltLists[iplane][iew].begin();
00985         while (literA != fXTalkPlanesAltLists[iplane][iew].end()){
00986           fPlanesAltLists[iplane][iew].push_back(*literA);
00987           literA++;
00988         }
00989         fXTalkPlanesAltLists[iplane][iew].erase(fXTalkPlanesAltLists[iplane][iew].begin(),fXTalkPlanesAltLists[iplane][iew].end());
00990       }
00991 
00992     }
00993   }
00994 
00995   return;
00996 
00997 }
00998 
00999 
01000 
01001 
01002 
01003 void  AlgAltDeMuxBase::AddBackNoise()
01004 {
01005   vector <PlexSEIdAltL*>::iterator literA;
01006 
01007   for(int iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
01008     for(int iew = ALG_EAST; iew<=ALG_WEST; iew++){
01009       if(fNoisePlanesAltLists[iplane][iew].size()>0){
01010         literA = fNoisePlanesAltLists[iplane][iew].begin();
01011         while (literA != fNoisePlanesAltLists[iplane][iew].end()){
01012           fPlanesAltLists[iplane][iew].push_back(*literA);
01013           literA++;
01014         }
01015         fNoisePlanesAltLists[iplane][iew].erase(fNoisePlanesAltLists[iplane][iew].begin(),fNoisePlanesAltLists[iplane][iew].end());
01016       }
01017 
01018     }
01019   }
01020 
01021   return;
01022 
01023 }
01024 
01025 
01026 
01027 
01028 void  AlgAltDeMuxBase::FillLowestHighest()
01029 {
01030 
01031   bool first=true;
01032   bool last =true;
01033   fLowestPlane = 0;
01034   fHighestPlane = MAX_NUMBER_OF_PLANES-1;
01035 
01036   for(Int_t iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
01037     if(fPlanesAltLists[iplane][ALG_EAST].size()>0||fPlanesAltLists[iplane][ALG_WEST].size()>0){
01038       if(first){
01039         Int_t nextPlane=999;
01040         bool carryOn = true;
01041         for(Int_t j = iplane+1; carryOn && j < MAX_NUMBER_OF_PLANES; j++){
01042           if(fPlanesAltLists[j][ALG_EAST].size()>0||
01043              fPlanesAltLists[j][ALG_WEST].size()>0){
01044             nextPlane = j;
01045             carryOn = false;
01046           }
01047         }
01048         if((nextPlane-iplane)<10){
01049           first = false;
01050           fLowestPlane = iplane;
01051         }
01052       }
01053     }
01054   }
01055 
01056 
01057   for(Int_t iplane=MAX_NUMBER_OF_PLANES-1; iplane>0; iplane--){
01058     if(fPlanesAltLists[iplane][ALG_EAST].size()>0||fPlanesAltLists[iplane][ALG_WEST].size()>0){
01059       if(last){
01060         Int_t nextPlane=-999;
01061         bool carryOn = true;
01062 
01063         for(Int_t j = iplane-1; carryOn && j >= 0; j--){
01064           if(fPlanesAltLists[j][ALG_EAST].size()>0||
01065              fPlanesAltLists[j][ALG_WEST].size()>0){
01066             nextPlane = j;
01067             carryOn = false;
01068           }
01069         }
01070         if((iplane-nextPlane)<10){
01071           last = false;
01072           fHighestPlane = iplane;
01073         }
01074       }
01075     }
01076   }
01077 
01078   return;
01079 
01080 }
01081 
01082 
01083 void AlgAltDeMuxBase::Setup() 
01084 {
01085   pMaster = new AltDeMuxPatternMaster();
01086   for(int i=0;i<MAX_NUMBER_OF_PMTS;i++){
01087     fPMTtot[i] = 0;
01088   }
01089   amPSing   = false;
01090   amHisting   = false;
01091 
01092   return;
01093 
01094 }
01095 
01096 
01097 void AlgAltDeMuxBase::GetFibreLengths()
01098 {
01099   // Store the fibre lengths for strips in this event.  
01100 
01101   UgliStripHandle ush;
01102   vector <PlexSEIdAltL*>::iterator literA;
01103 
01104   MSG("AltDeMux", Msg::kVerbose) << "AlgAltDeMuxBase::GetFibreLengths " << endl;
01105  
01106   for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
01107     for(Int_t iew = ALG_EAST; iew <= ALG_WEST; iew++){
01108       if(fPlanesAltLists[iplane][iew].size()>0){
01109         literA = fPlanesAltLists[iplane][iew].begin();
01110         while (literA != fPlanesAltLists[iplane][iew].end()){
01111           (*literA)->SetFirst();
01112           while( (*literA)->IsValid() ){
01113             ush = pUgh->GetStripHandle((*literA)->GetCurrentSEId());
01114             if(!ush.IsValid())MSG("AltDeMux", Msg::kFatal) << "AlgAltDeMuxBase::GetFibreLengths => UgliStripHandle NOT VALID : plane " << iplane << " (Carry on regardless)" <<  endl;
01115             if(iew==ALG_EAST)pCalculator->SetFibreLengthE(iplane,*literA);
01116             if(iew==ALG_WEST)pCalculator->SetFibreLengthW(iplane,*literA);
01117             (*literA)->Next();
01118           }
01119           *literA++;
01120         }
01121       }
01122     }
01123   }
01124   return;
01125 
01126 }
01127 
01128 void AlgAltDeMuxBase::MakeTimingMask(bool useMask){
01129   
01130   vector <PlexSEIdAltL*>::iterator literE;
01131   vector <PlexSEIdAltL*>::iterator literW;
01132 
01133   // if diagnostic/debug
01134   if(fDiagnosticPlots){
01135     if ( fUTime ) { delete fUTime; fUTime=0; }
01136     if ( fVTime ) { delete fVTime; fVTime=0; }
01137     fUTime = new TH2F("UTime","U time view",501,-0.5,500.5,193,0.,193.);
01138     fVTime = new TH2F("VTime","V time view",501,-0.5,500.5,193,0.,193.);
01139     fUTime->SetStats(kFALSE);
01140     fVTime->SetStats(kFALSE);
01141   }
01142 
01143   for(int iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
01144     fMaskGroup[iplane].erase(fMaskGroup[iplane].begin(),fMaskGroup[iplane].end());
01145     fInMask[iplane] =  0;
01146     if(fPlanesAltLists[iplane][ALG_EAST].size()>0||fPlanesAltLists[iplane][ALG_WEST].size()>0){
01147       // Reset timing mask strip targets and target groups for this palne 
01148       for(int istrip=0;istrip<=MAX_NUMBER_OF_STRIPS;istrip++){
01149         fTimingMask[iplane][istrip] = false;
01150       }
01151     }
01152 
01153     if(fPlanesAltLists[iplane][ALG_EAST].size()>0&&fPlanesAltLists[iplane][ALG_WEST].size()>0){
01154       literE = fPlanesAltLists[iplane][ALG_EAST].begin();
01155       PlaneView::PlaneView_t kView = (*literE)->GetPlaneView();
01156       pCalculator->SetPlane(iplane);
01157       pCalculator->SetView(kView);
01158       while (literE != fPlanesAltLists[iplane][ALG_EAST].end()){
01159         literW = fPlanesAltLists[iplane][ALG_WEST].begin();
01160         while ( literW != fPlanesAltLists[iplane][ALG_WEST].end()){
01161           (*literE)->SetFirst();
01162           while( (*literE)->IsValid() ){
01163             Int_t  iStripE = (*literE)->GetCurrentSEId().GetStrip();
01164             pCalculator->SetEast(*literE,iStripE);
01165             bool goodComb = true;
01166             if(useMask && fUVmask[iplane][iStripE]==false)goodComb = false; 
01167             if(goodComb){             
01168               (*literW)->SetFirst();
01169               while( (*literW)->IsValid() ){
01170                 Int_t  iStripW = (*literW)->GetCurrentSEId().GetStrip();
01171                 if(iStripE==iStripW){
01172                   // In here we can check for a possibility
01173                   pCalculator->SetWest(*literW,iStripW);
01174                   pCalculator->CalcEastWest();
01175                   if(fabs(pCalculator->SigmaDQ())<4.0){
01176                     Int_t isaim = pCalculator->StripAim();
01177                     fInMask[iplane]++;
01178                     fTimingMask[iplane][isaim] = true;
01179                     if(fDiagnosticPlots){
01180                       if(kView==PlaneView::kV)fUTime->Fill(iplane,isaim,1.);
01181                       if(kView==PlaneView::kU)fVTime->Fill(iplane,isaim,1.);
01182                     }
01183                   }
01184                 }
01185                 (*literW)->Next();
01186               }
01187             }
01188             (*literE)->Next();
01189           }
01190           literW++;
01191         }
01192         literE++;
01193       }
01194     }
01195   }
01196 
01197   if(fDiagnosticPlots)this->DrawDiagnosticPlots(-2);
01198 
01199   this->MakeMaskGroups();
01200 
01201   for(int iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
01202     if(fPlanesAltLists[iplane][ALG_EAST].size()>0||fPlanesAltLists[iplane][ALG_WEST].size()>0){
01203       bool found = false;
01204       if(iplane==0){
01205         int ip = 1;
01206         int ipp = 3; 
01207         found = found || MaskExtrapolateBack(iplane,ip,ipp);
01208       }else{
01209         // For planes with hits : check surrounding planes
01210         int im=iplane-1;
01211         int ip=iplane+1;
01212         found = found || MaskInterpolate(iplane,im,ip);
01213         if(!found){
01214           int imm = iplane-3;
01215           int ipp = iplane+3;
01216           if(imm>=0)found = found || MaskInterpolate(iplane,imm,ip);
01217           if(ipp<499)found = MaskInterpolate(iplane,im,ipp) || found;
01218           if(!found){
01219             if(imm>=0)found = found || MaskExtrapolateForwards(iplane,imm,im);
01220             if(ipp<499)found = MaskExtrapolateBack(iplane,ip,ipp) || found;
01221           }
01222         }
01223       }
01224       if(!found)for(int istrip=0;istrip<fNumberOfStrips;istrip++)this->SetMask(iplane,istrip);
01225     }
01226   }  
01227 
01228   if(fDiagnosticPlots)this->DrawDiagnosticPlots(-1);
01229 
01230   return;
01231   
01232 } 
01233 
01234 
01235 
01236 
01237 
01238 
01239 void AlgAltDeMuxBase::ReMakeTimingMask(bool useMask){
01240   
01241   vector <PlexSEIdAltL*>::iterator literE;
01242   vector <PlexSEIdAltL*>::iterator literW;
01243 
01244   // if diagnostic/debug
01245   if(fDiagnosticPlots){
01246     if ( fUTime ) { delete fUTime; fUTime=0; }
01247     if ( fVTime ) { delete fVTime; fVTime=0; }
01248     fUTime = new TH2F("UTime","U time view",501,-0.5,500.5,193,0.,193.);
01249     fVTime = new TH2F("VTime","V time view",501,-0.5,500.5,193,0.,193.);
01250     fUTime->SetStats(kFALSE);
01251     fVTime->SetStats(kFALSE);
01252   }
01253 
01254   for(int iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
01255     fMaskGroup[iplane].erase(fMaskGroup[iplane].begin(),fMaskGroup[iplane].end());
01256     fInMask[iplane] =  0;
01257     if(fDeMuxedPlanesAltLists[iplane][ALG_EAST].size()>0||fDeMuxedPlanesAltLists[iplane][ALG_WEST].size()>0){
01258       // Reset timing mask strip targets and target groups for this palne 
01259       for(int istrip=0;istrip<=MAX_NUMBER_OF_STRIPS;istrip++){
01260         fTimingMask[iplane][istrip] = false;
01261       }
01262     }
01263 
01264     if(fDeMuxedPlanesAltLists[iplane][ALG_EAST].size()>0&&fDeMuxedPlanesAltLists[iplane][ALG_WEST].size()>0){
01265       literE = fDeMuxedPlanesAltLists[iplane][ALG_EAST].begin();
01266       PlaneView::PlaneView_t kView = (*literE)->GetPlaneView();
01267       pCalculator->SetPlane(iplane);
01268       pCalculator->SetView(kView);
01269       while (literE != fDeMuxedPlanesAltLists[iplane][ALG_EAST].end()){
01270         literW = fDeMuxedPlanesAltLists[iplane][ALG_WEST].begin();
01271         while ( literW != fDeMuxedPlanesAltLists[iplane][ALG_WEST].end()){
01272           (*literE)->SetFirst();
01273           while( (*literE)->IsValid() ){
01274             Int_t  iStripE = (*literE)->GetCurrentSEId().GetStrip();
01275             pCalculator->SetEast(*literE,iStripE);
01276             bool goodComb = true;
01277             if(useMask && fUVmask[iplane][iStripE]==false)goodComb = false; 
01278             if(goodComb){             
01279               (*literW)->SetFirst();
01280               while( (*literW)->IsValid() ){
01281                 Int_t  iStripW = (*literW)->GetCurrentSEId().GetStrip();
01282                 pCalculator->SetWest(*literW,iStripW);
01283                 // In here we can check for a possibility
01284                 if(iStripE==iStripW){
01285                   pCalculator->CalcEastWest();
01286                   if(fabs(pCalculator->SigmaDQ())<3.0){
01287                     Int_t isaim = pCalculator->StripAim();
01288                     fInMask[iplane]++;
01289                     fTimingMask[iplane][isaim] = true;
01290                     if(fDiagnosticPlots){
01291                       if(kView==PlaneView::kV)fUTime->Fill(iplane,isaim,1.);
01292                       if(kView==PlaneView::kU)fVTime->Fill(iplane,isaim,1.);
01293                     }
01294                   }
01295                 }
01296                 (*literW)->Next();
01297               }
01298             }
01299             (*literE)->Next();
01300           }
01301           literW++;
01302         }
01303         literE++;
01304       }
01305     }
01306   }
01307 
01308   if(fDiagnosticPlots)this->DrawDiagnosticPlots(-2);
01309 
01310   this->MakeMaskGroups();
01311 
01312   for(int iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
01313     if(fDeMuxedPlanesAltLists[iplane][ALG_EAST].size()>0||fDeMuxedPlanesAltLists[iplane][ALG_WEST].size()>0){
01314       bool found = false;
01315       if(iplane==0){
01316         int ip = 1;
01317         int ipp = 3; 
01318         found = found || MaskExtrapolateBack(iplane,ip,ipp);
01319       }else{
01320         // For planes with hits : check surrounding planes
01321         int im=iplane-1;
01322         int ip=iplane+1;
01323         found = found || MaskInterpolate(iplane,im,ip);
01324         if(!found){
01325           int imm = iplane-3;
01326           int ipp = iplane+3;
01327           if(imm>=0)found = found || MaskInterpolate(iplane,imm,ip);
01328           if(ipp<499)found = found || MaskInterpolate(iplane,im,ipp);
01329           if(!found){
01330             if(imm>=0)found = found || MaskExtrapolateForwards(iplane,imm,im);
01331             if(ipp<499)found = found || MaskExtrapolateBack(iplane,ip,ipp);
01332           }
01333         }
01334       }
01335       if(!found)for(int istrip=0;istrip<fNumberOfStrips;istrip++)this->SetMask(iplane,istrip);
01336     }
01337   }  
01338 
01339   if(fDiagnosticPlots)this->DrawDiagnosticPlots(-1);
01340   if(fDiagnosticPlots)this->DrawDiagnosticPlots(1);
01341 
01342   return;
01343   
01344 } 
01345 
01346 
01347 
01348 
01349 
01350 
01351 
01352 
01353 bool AlgAltDeMuxBase::MaskInterpolate(int i, int im, int ip)
01354 {
01355   bool found = false;
01356   if(fMaskGroup[im].size()>0&&fMaskGroup[ip].size()>0){
01357     found = true;
01358     int lm = i-im;
01359     int lp = ip-i;
01360     int lt = lp+lm;
01361     for(unsigned int jm = 0; jm < fMaskGroup[im].size();jm++){
01362       for(int km = fMaskGroup[im][jm].groupStart; km<= fMaskGroup[im][jm].groupEnd;km++)this->SetMask(i,km);
01363       for(unsigned int jp = 0; jp < fMaskGroup[ip].size();jp++){
01364         for(int kp = fMaskGroup[ip][jp].groupStart; kp<= fMaskGroup[ip][jp].groupEnd;kp++)this->SetMask(i,kp);
01365         for(int k = (fMaskGroup[im][jm].groupStart*lp+fMaskGroup[ip][jp].groupStart*lm)/lt; k<= (fMaskGroup[im][jm].groupEnd*lp+fMaskGroup[ip][jp].groupEnd*lm)/lt;k++){
01366           this->SetMask(i,k);
01367         }
01368       } 
01369     }  
01370   }
01371   return found;
01372 }
01373 
01374 
01375 bool AlgAltDeMuxBase::MaskExtrapolateBack(int i, int ip, int ipp)
01376 {
01377   bool found = false;
01378   if(fMaskGroup[ip].size()>0&&fMaskGroup[ipp].size()>0){
01379     found = true;
01380     int lp  = ip-i;
01381     int lpp = ipp-i;
01382     int lt  = lpp-lp;
01383     for(unsigned int jp = 0; jp < fMaskGroup[ip].size();jp++){
01384       for(int kp = fMaskGroup[ip][jp].groupStart; kp<= fMaskGroup[ip][jp].groupEnd;kp++)this->SetMask(i,kp);
01385       for(unsigned int jpp = 0; jpp < fMaskGroup[ipp].size();jpp++){
01386         int ilow = (lpp*fMaskGroup[ip][jp].groupStart-lp*fMaskGroup[ipp][jpp].groupEnd)/lt;
01387         if(ilow<0)ilow=0;
01388         int ihigh = (lpp*fMaskGroup[ip][jp].groupEnd-lp*fMaskGroup[ipp][jpp].groupStart)/lt;
01389         if(ihigh>=MAX_NUMBER_OF_PLANES)ihigh=MAX_NUMBER_OF_PLANES-1;
01390         for(int kp = ilow; kp<=ihigh ;kp++)this->SetMask(i,kp);
01391       } 
01392     }  
01393   }
01394   return found;
01395 }
01396 
01397 bool AlgAltDeMuxBase::MaskExtrapolateForwards(int i, int imm, int im)
01398 {
01399   bool found = false;
01400   if(fMaskGroup[im].size()>0&&fMaskGroup[imm].size()>0){
01401     found = true;
01402     int lm  = im-i;
01403     int lmm = imm-i;
01404     int lt  = lmm-lm;
01405     for(unsigned int jm = 0; jm < fMaskGroup[im].size();jm++){
01406       for(int km = fMaskGroup[im][jm].groupStart; km<= fMaskGroup[im][jm].groupEnd;km++)this->SetMask(i,km);
01407       for(unsigned int jmm = 0; jmm < fMaskGroup[imm].size();jmm++){
01408         int ilow = (lmm*fMaskGroup[im][jm].groupStart-lm*fMaskGroup[imm][jmm].groupEnd)/lt;
01409         int ihigh = (lmm*fMaskGroup[im][jm].groupEnd-lm*fMaskGroup[imm][jmm].groupStart)/lt;
01410         if(ilow<0)ilow=0;
01411         if(ihigh>192)ihigh=192;
01412         for(int km =ilow ; km<=ihigh ;km++)this->SetMask(i,km);
01413       } 
01414     }  
01415   }
01416   return found;
01417 }
01418 
01419 
01420 
01421 void AlgAltDeMuxBase::SetMask(int ip, int is)
01422 {
01423   
01424   fUVmask[ip][is] = true;
01425   Int_t iuv = 0;
01426   
01427   if(fDiagnosticPlots){
01428     if(ip<249)iuv = (ip%2)+1;
01429     if(ip>249)iuv  = ((ip+1)%2)+1;
01430     if(iuv==1)fUMask->Fill(ip,is,1.0);
01431     if(iuv==2)fVMask->Fill(ip,is,1.0);
01432   }
01433   return;
01434 }
01435 
01436 
01437 
01438 void AlgAltDeMuxBase::ResetTimingMask()
01439 {
01440   
01441   for(int iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
01442     for(int istrip=0;istrip<MAX_NUMBER_OF_STRIPS;istrip++){
01443       fUVmask[iplane][istrip] = false;
01444     }
01445   }
01446 
01447   if(fDiagnosticPlots){
01448     if ( fUMask ) { delete fUMask; fUMask=0; }
01449     if ( fVMask ) { delete fVMask; fVMask=0; }
01450     fUMask = new TH2F("UMask","U view mask",501,-0.5,500.5,193,0.,193.);
01451     fVMask = new TH2F("VMask","V view mask",501,-0.5,500.5,193,0.,193.);
01452     fUMask->SetStats(kFALSE);
01453     fVMask->SetStats(kFALSE);
01454   }
01455 
01456 }
01457 
01458 void AlgAltDeMuxBase::MakeMaskGroups()
01459 {
01460    
01461   ResetTimingMask();
01462   fTimingMaskWindow = static_cast<Int_t>(2.5*fSigmaStripFromTiming);
01463 
01464   for(int i=0;i<MAX_NUMBER_OF_PLANES;i++){
01465     if(fInMask[i]>0){
01466       DeMuxMaskGroup gm;
01467       bool inGroup = false;
01468       int groupS = -999;
01469       int groupE   = +999;
01470       for(int j=0;j<fNumberOfStrips;j++){
01471         if(inGroup){
01472           if(j>groupE+fTimingMaskWindow){
01473             inGroup = false;
01474             gm.groupStart = groupS;
01475             gm.groupEnd = groupE;
01476             fMaskGroup[i].push_back(gm);
01477           }
01478         }
01479         if(fTimingMask[i][j]){
01480           if(inGroup){
01481             groupE = j + fTimingMaskWindow;
01482             if(groupE>=fNumberOfStrips)groupE=fNumberOfStrips-1;
01483           }else{
01484             inGroup = true;
01485             groupS = j - fTimingMaskWindow;
01486             groupE = j + fTimingMaskWindow;
01487             if(groupS<0)groupS=0;
01488             if(groupE>=fNumberOfStrips)groupE=fNumberOfStrips-1;
01489           }
01490         }
01491       }
01492       if(inGroup){
01493         groupE = fNumberOfStrips-1;
01494         gm.groupStart = groupS;
01495         gm.groupEnd = groupE;
01496         fMaskGroup[i].push_back(gm);
01497       }
01498     }
01499   }
01500   return;
01501 }
01502 
01503 
01504 
01505 
01506 
01507 
01508 
01509 void AlgAltDeMuxBase::PrintMap(Int_t ne, Int_t nw){
01510   
01511 
01512   cout << "Print Map " << ne << " : " << nw << endl;
01513   for(Int_t ie=0;ie<=ne;ie++){
01514     for(Int_t iw=0;iw<=nw;iw++){
01515       cout << fAmap[ie][iw];
01516     }
01517     cout << endl;
01518   }
01519 
01520   return;
01521 } 
01522 
01523 void AlgAltDeMuxBase::ResetMap(Int_t ne, Int_t nw){
01524   
01525   for(Int_t ie=0;ie<=ne;ie++){
01526     for(Int_t iw=0;iw<=nw;iw++){
01527       fAmap[ie][iw] = false;
01528     }
01529   }
01530 
01531   return;
01532 } 
01533 
01534 bool AlgAltDeMuxBase::IsXTalk(PlexSEIdAltL* paltlist, bool useBest)
01535 { 
01536 
01537   Float_t crossTalk=0.0;
01538   Float_t diagCrossTalk=0.0;
01539   bool result = false;
01540 
01541   PlexPixelSpotId pixelID;
01542   if(!useBest)pixelID = (paltlist->GetCurrentItem()).GetPixelSpotId(); 
01543   if(useBest)pixelID = (paltlist->GetBestItem()).GetPixelSpotId(); 
01544   Int_t pixel  = pixelID.GetPixel();
01545   Int_t PMTmuxID = pixelID.GetTube();
01546   PMTmuxID      += 3*pixelID.GetInRack();
01547   PMTmuxID      += 24*pixelID.GetRackBay();
01548   Char_t level = pixelID.GetRackLevel(); 
01549   Char_t ew = pixelID.GetEastWest(); 
01550   if(level=='U')PMTmuxID += 450;
01551   if(ew =='E')PMTmuxID += 900;
01552 
01553   if(PMTmuxID>=MAX_NUMBER_OF_PMTS){
01554     MSG("AltDeMux", Msg::kError) << "AlgAltDeMuxBase::IsXTalk => PMT out of array bounds : " <<    PMTmuxID << " would give array overflow!" << endl;
01555     return false;
01556   }
01557 
01558   Float_t q  = paltlist->GetCurrentItem().GetPE();
01559   Float_t qc = paltlist->GetCurrentItem().GetSigCorr()/60.;
01560   
01561   if(qc/q<0.1 || qc/q > 10.0){
01562     //cout << " BUGGERED " << qc << ":" << q << endl;
01563     qc=q;
01564   }
01565 
01566 
01567   switch(pixel){
01568   case 0:
01569     crossTalk = fPMTmap[PMTmuxID][1] + 
01570       fPMTmap[PMTmuxID][4];
01571     diagCrossTalk = fPMTmap[PMTmuxID][5];
01572     break;
01573   case 1:
01574     crossTalk = fPMTmap[PMTmuxID][0] + 
01575       fPMTmap[PMTmuxID][2] +
01576       fPMTmap[PMTmuxID][5];
01577     diagCrossTalk = fPMTmap[PMTmuxID][4]+
01578       fPMTmap[PMTmuxID][6];
01579     break;
01580   case 2:
01581     crossTalk = fPMTmap[PMTmuxID][1] + 
01582       fPMTmap[PMTmuxID][3] +
01583       fPMTmap[PMTmuxID][6];
01584     diagCrossTalk = fPMTmap[PMTmuxID][5]+
01585       fPMTmap[PMTmuxID][7];
01586     break;
01587   case 3:
01588     crossTalk = fPMTmap[PMTmuxID][2] + 
01589       fPMTmap[PMTmuxID][7];
01590     diagCrossTalk = fPMTmap[PMTmuxID][6];
01591     break;
01592   case 4:
01593     crossTalk = fPMTmap[PMTmuxID][0] + 
01594       fPMTmap[PMTmuxID][5] +
01595       fPMTmap[PMTmuxID][8];
01596     diagCrossTalk = fPMTmap[PMTmuxID][1]+
01597       fPMTmap[PMTmuxID][9];
01598     break;
01599   case 5:
01600     crossTalk = fPMTmap[PMTmuxID][1] + 
01601       fPMTmap[PMTmuxID][4] +
01602       fPMTmap[PMTmuxID][6] +
01603       fPMTmap[PMTmuxID][9];
01604     diagCrossTalk = fPMTmap[PMTmuxID][0]+
01605       fPMTmap[PMTmuxID][2] +
01606       fPMTmap[PMTmuxID][8] +
01607       fPMTmap[PMTmuxID][10];
01608     break;
01609   case 6:
01610     crossTalk = fPMTmap[PMTmuxID][2] + 
01611       fPMTmap[PMTmuxID][5] +
01612       fPMTmap[PMTmuxID][7] +
01613       fPMTmap[PMTmuxID][10];
01614     diagCrossTalk = fPMTmap[PMTmuxID][1]+
01615       fPMTmap[PMTmuxID][3] +
01616       fPMTmap[PMTmuxID][9] +
01617       fPMTmap[PMTmuxID][11];
01618     break;
01619   case 7:
01620     crossTalk = fPMTmap[PMTmuxID][3] + 
01621       fPMTmap[PMTmuxID][6] +
01622       fPMTmap[PMTmuxID][11];
01623     diagCrossTalk = fPMTmap[PMTmuxID][2]+
01624       fPMTmap[PMTmuxID][10];
01625     break;
01626   case 8:
01627     crossTalk = fPMTmap[PMTmuxID][4] + 
01628       fPMTmap[PMTmuxID][9] +
01629       fPMTmap[PMTmuxID][12];
01630     diagCrossTalk = fPMTmap[PMTmuxID][5]+
01631       fPMTmap[PMTmuxID][13];
01632     break;
01633   case 9:
01634     crossTalk = fPMTmap[PMTmuxID][5] + 
01635       fPMTmap[PMTmuxID][8] +
01636       fPMTmap[PMTmuxID][10] +
01637       fPMTmap[PMTmuxID][13];
01638     diagCrossTalk = fPMTmap[PMTmuxID][4]+
01639       fPMTmap[PMTmuxID][6] +
01640       fPMTmap[PMTmuxID][12] +
01641       fPMTmap[PMTmuxID][14];
01642     break;
01643   case 10:
01644     crossTalk = fPMTmap[PMTmuxID][6] + 
01645       fPMTmap[PMTmuxID][9] +
01646       fPMTmap[PMTmuxID][11] +
01647       fPMTmap[PMTmuxID][14];
01648     diagCrossTalk = fPMTmap[PMTmuxID][5]+
01649       fPMTmap[PMTmuxID][7] +
01650       fPMTmap[PMTmuxID][13] +
01651       fPMTmap[PMTmuxID][15];
01652     break;
01653   case 11:
01654     crossTalk = fPMTmap[PMTmuxID][7] + 
01655       fPMTmap[PMTmuxID][10] +
01656       fPMTmap[PMTmuxID][15];
01657     diagCrossTalk = fPMTmap[PMTmuxID][6]+
01658       fPMTmap[PMTmuxID][14];
01659     break;
01660   case 12:
01661     crossTalk = fPMTmap[PMTmuxID][8] + 
01662       fPMTmap[PMTmuxID][13];
01663     diagCrossTalk = fPMTmap[PMTmuxID][9];
01664     break;
01665   case 13:
01666     crossTalk = fPMTmap[PMTmuxID][9] + 
01667       fPMTmap[PMTmuxID][12]+
01668       fPMTmap[PMTmuxID][14];
01669     diagCrossTalk = fPMTmap[PMTmuxID][8]+
01670       fPMTmap[PMTmuxID][10];
01671     break;
01672   case 14:
01673     crossTalk = fPMTmap[PMTmuxID][10] + 
01674       fPMTmap[PMTmuxID][13]+
01675       fPMTmap[PMTmuxID][15];
01676     diagCrossTalk = fPMTmap[PMTmuxID][9]+
01677       fPMTmap[PMTmuxID][11];
01678     break;
01679   case 15:
01680     crossTalk = fPMTmap[PMTmuxID][11]+ 
01681       fPMTmap[PMTmuxID][14];
01682     diagCrossTalk = fPMTmap[PMTmuxID][10];
01683     break;
01684   default:
01685     crossTalk = 0;
01686     diagCrossTalk = 0;
01687     break;
01688   }
01689 
01690   if(amShowing){
01691     int i = PMTmuxID;
01692     cout << " IsXTalk " << paltlist->GetPlane() << " : " << pixel << " q " << q << " qc " << qc << " t " << paltlist->GetCurrentItem().GetTime()*1.0E9-pCalculator->GetAbsTime() << endl;
01693     cout << "PLANE HITS " << fPlaneHit[paltlist->GetPlane()] << endl;
01694 
01695     cout  << fPMTmap[i][0]  << ":" << fPMTmap[i][1]  << 
01696       ":" << fPMTmap[i][2]  << ":" << fPMTmap[i][3]  << endl;
01697     cout  << fPMTmap[i][4]  << ":" << fPMTmap[i][5]  << 
01698       ":" << fPMTmap[i][6]  << ":" << fPMTmap[i][7]  << endl;
01699     cout  << fPMTmap[i][8]  << ":" << fPMTmap[i][9]  << 
01700       ":" << fPMTmap[i][10] << ":" << fPMTmap[i][11] << endl;
01701     cout  << fPMTmap[i][12] << ":" << fPMTmap[i][13] << 
01702       ":" << fPMTmap[i][14] << ":" << fPMTmap[i][15] << endl;
01703 
01704     cout << "----------------" << i << endl;
01705 
01706     cout  << fXTalkmap[i][0]  << ":" << fXTalkmap[i][1]  << 
01707       ":" << fXTalkmap[i][2]  << ":" << fXTalkmap[i][3]  << endl;
01708     cout  << fXTalkmap[i][4]  << ":" << fXTalkmap[i][5]  << 
01709       ":" << fXTalkmap[i][6]  << ":" << fXTalkmap[i][7]  << endl;
01710     cout  << fXTalkmap[i][8]  << ":" << fXTalkmap[i][9]  << 
01711       ":" << fXTalkmap[i][10] << ":" << fXTalkmap[i][11] << endl;
01712     cout  << fXTalkmap[i][12] << ":" << fXTalkmap[i][13] << 
01713       ":" << fXTalkmap[i][14] << ":" << fXTalkmap[i][15] << endl;
01714 
01715     cout << "----------------" << endl;
01716 
01717     cout << fVAmap[i][2] << endl;
01718     cout << fVAmap[i][3] << endl;
01719     cout << fVAmap[i][4] << endl;
01720     cout << fVAmap[i][5] << endl;
01721     cout << fVAmap[i][6] << endl;
01722     cout << fVAmap[i][7] << endl;
01723     cout << fVAmap[i][8] << endl;
01724     cout << fVAmap[i][9] << endl;
01725     cout << fVAmap[i][10] << endl;
01726     cout << fVAmap[i][11] << endl;
01727     cout << fVAmap[i][12] << endl;
01728     cout << fVAmap[i][13] << endl;
01729     cout << fVAmap[i][14] << endl;
01730     cout << fVAmap[i][15] << endl;
01731     cout << fVAmap[i][16] << endl;
01732     cout << fVAmap[i][17] << endl;
01733   }
01734 
01735   if(useBest)q=qc;
01736   Float_t XTalkFraction=1.0;
01737   crossTalk+= 0.5*diagCrossTalk;
01738   if(crossTalk>0)XTalkFraction = q/crossTalk;
01739   if(XTalkFraction<fXTalkFraction)result=true;
01740   if(q<1.5&&XTalkFraction<fXTalk1PEFraction)result=true;
01741   if(q<2.5&&XTalkFraction<fXTalk2PEFraction)result=true;
01742   if(q<5.0&&XTalkFraction<fXTalk5PEFraction)result=true;
01743 
01744   if(q<1.5 && q<0.05*fPMTtot[PMTmuxID])result=true;
01745   
01746   if(amShowing)cout << "NORMAL : " << q << ":" <<  XTalkFraction << ":" << result << endl;
01747 
01748   if(result){
01749     MSG("AltDeMux", Msg::kVerbose) << "AlgAltDeMuxBase::IsXTalk (tagged by Standard Algorithm) PMT " << PMTmuxID << " pixel : " << pixel << " charge : " << qc << endl;
01750     return result; 
01751   }
01752 
01753   if(fXTalkmap[PMTmuxID][pixel]>0.0001){
01754     XTalkFraction = q/fXTalkmap[PMTmuxID][pixel];
01755     if(q<1.0&&XTalkFraction<100.)result=true;
01756     if(q<2.0&&XTalkFraction<50.)result=true;
01757     if(q<3.0&&XTalkFraction<30.)result=true;
01758     if(q<5.0&&XTalkFraction<20.)result=true;
01759     if(amShowing)cout << "SPOT   : " << q << ":" <<  XTalkFraction << ":" << result << endl;
01760 
01761     if(result){
01762       MSG("AltDeMux", Msg::kVerbose) << "AlgAltDeMuxBase::IsXTalk (Tagged by Spot Algorithm) : PMT " << PMTmuxID << " pixel : " << pixel << " charge : " << qc << " pixel map " << fXTalkmap[PMTmuxID][pixel] << endl;
01763       return result; 
01764     }
01765   }
01766 
01767   Int_t vaChannel = _pixelToVaChannel[pixel];
01768 
01769   if((fVAmap[PMTmuxID][vaChannel+1]+fVAmap[PMTmuxID][vaChannel-1])>0){
01770     XTalkFraction = q/(fVAmap[PMTmuxID][vaChannel+1]+fVAmap[PMTmuxID][vaChannel-1]);
01771     if(q<1.5&&XTalkFraction<0.1)result=true;
01772     if(amShowing)cout << "VA     : " << q << ":" <<  XTalkFraction << ":" << result << endl;
01773 
01774     if(result){
01775       MSG("AltDeMux", Msg::kVerbose) << "AlgAltDeMuxBase::IsXTalk (VA Algorithm) : PMT " << PMTmuxID << " pixel : " << pixel << " charge : " << qc << "VA map  : " << fVAmap[PMTmuxID][vaChannel-1] << "," << fVAmap[PMTmuxID][vaChannel-1] << endl;
01776       return result; 
01777     }
01778   }
01779 
01780   return result;
01781 } 
01782 
01783 
01784 
01785 
01786 
01787 
01788 
01789 
01790 Float_t AlgAltDeMuxBase::XTalkCharge(PlexSEIdAltL* paltlist, Int_t istrip)
01791 { 
01792 
01793   Float_t crossTalk=-999;
01794   
01795   paltlist->SetFirst();
01796   bool notFound = true;
01797   while(notFound&&paltlist->IsValid()){
01798     if(paltlist->GetCurrentSEId().GetStrip()==istrip)notFound=false;
01799     if(notFound)paltlist->Next();
01800   }
01801 
01802 
01803   PlexPixelSpotId pixelID = (paltlist->GetCurrentItem()).GetPixelSpotId(); 
01804   Int_t pixel  = pixelID.GetPixel();
01805   Int_t PMTmuxID = pixelID.GetTube();
01806   PMTmuxID      += 3*pixelID.GetInRack();
01807   PMTmuxID      += 24*pixelID.GetRackBay();
01808   Char_t level = pixelID.GetRackLevel(); 
01809   Char_t ew = pixelID.GetEastWest(); 
01810   if(level=='U')PMTmuxID += 450;
01811   if(ew =='E')PMTmuxID += 900;
01812   if(PMTmuxID>=MAX_NUMBER_OF_PMTS){
01813     MSG("AltDeMux", Msg::kError) << "AlgAltDeMuxBase::IsXTalk => PMT out of array bounds : " <<    PMTmuxID << " woul give array overflow!" << endl;
01814     return 0.0;
01815   }
01816   Float_t q  = paltlist->GetCurrentItem().GetPE();
01817   Float_t qc = paltlist->GetCurrentItem().GetSigCorr()/60.;
01818   if(qc/q<0.1 || qc/q > 10.0){
01819     qc=q;
01820   }
01821 
01822   switch(pixel){
01823   case 0:
01824     crossTalk = fPMTmap[PMTmuxID][1] + 
01825       fPMTmap[PMTmuxID][4];
01826     break;
01827   case 1:
01828     crossTalk = fPMTmap[PMTmuxID][0] + 
01829       fPMTmap[PMTmuxID][2] +
01830       fPMTmap[PMTmuxID][5];
01831       break;
01832   case 2:
01833     crossTalk = fPMTmap[PMTmuxID][1] + 
01834       fPMTmap[PMTmuxID][3] +
01835       fPMTmap[PMTmuxID][6];
01836     break;
01837   case 3:
01838     crossTalk = fPMTmap[PMTmuxID][2] + 
01839       fPMTmap[PMTmuxID][7];
01840     break;
01841   case 4:
01842     crossTalk = fPMTmap[PMTmuxID][0] + 
01843       fPMTmap[PMTmuxID][5] +
01844       fPMTmap[PMTmuxID][8];
01845     break;
01846   case 5:
01847     crossTalk = fPMTmap[PMTmuxID][1] + 
01848       fPMTmap[PMTmuxID][4] +
01849       fPMTmap[PMTmuxID][6] +
01850       fPMTmap[PMTmuxID][9];
01851     break;
01852   case 6:
01853     crossTalk = fPMTmap[PMTmuxID][2] + 
01854       fPMTmap[PMTmuxID][5] +
01855       fPMTmap[PMTmuxID][7] +
01856       fPMTmap[PMTmuxID][10];
01857     break;
01858   case 7:
01859     crossTalk = fPMTmap[PMTmuxID][3] + 
01860       fPMTmap[PMTmuxID][6] +
01861       fPMTmap[PMTmuxID][11];
01862     break;
01863   case 8:
01864     crossTalk = fPMTmap[PMTmuxID][4] + 
01865       fPMTmap[PMTmuxID][9] +
01866       fPMTmap[PMTmuxID][12];
01867     break;
01868   case 9:
01869     crossTalk = fPMTmap[PMTmuxID][5] + 
01870       fPMTmap[PMTmuxID][8] +
01871       fPMTmap[PMTmuxID][10] +
01872       fPMTmap[PMTmuxID][13];
01873     break;
01874   case 10:
01875     crossTalk = fPMTmap[PMTmuxID][6] + 
01876       fPMTmap[PMTmuxID][9] +
01877       fPMTmap[PMTmuxID][11] +
01878       fPMTmap[PMTmuxID][14];
01879     break;
01880   case 11:
01881     crossTalk = fPMTmap[PMTmuxID][7] + 
01882       fPMTmap[PMTmuxID][10] +
01883       fPMTmap[PMTmuxID][15];
01884     break;
01885   case 12:
01886     crossTalk = fPMTmap[PMTmuxID][8] + 
01887       fPMTmap[PMTmuxID][13];
01888     break;
01889   case 13:
01890     crossTalk = fPMTmap[PMTmuxID][9] + 
01891       fPMTmap[PMTmuxID][12]+
01892       fPMTmap[PMTmuxID][14];
01893     break;
01894   case 14:
01895     crossTalk = fPMTmap[PMTmuxID][10] + 
01896       fPMTmap[PMTmuxID][13]+
01897       fPMTmap[PMTmuxID][15];
01898     break;
01899   case 15:
01900     crossTalk = fPMTmap[PMTmuxID][11]+ 
01901       fPMTmap[PMTmuxID][14];
01902     break;
01903   default:
01904     crossTalk = 0;
01905     break;
01906   }
01907 
01908   return crossTalk;
01909 } 
01910 
01911 
01912 
01913 
01914 
01915 
01916 Float_t AlgAltDeMuxBase::XTalkPixelMap(PlexSEIdAltL* paltlist)
01917 { 
01918 
01919   Float_t crossTalk=-999;
01920   
01921   PlexPixelSpotId pixelID = (paltlist->GetBestItem()).GetPixelSpotId(); 
01922   Int_t pixel  = pixelID.GetPixel();
01923   Int_t PMTmuxID = pixelID.GetTube();
01924   PMTmuxID      += 3*pixelID.GetInRack();
01925   PMTmuxID      += 24*pixelID.GetRackBay();
01926   Char_t level = pixelID.GetRackLevel(); 
01927   Char_t ew = pixelID.GetEastWest(); 
01928   if(level=='U')PMTmuxID += 450;
01929   if(ew =='E')PMTmuxID += 900;
01930   if(PMTmuxID>=MAX_NUMBER_OF_PMTS){
01931     MSG("AltDeMux", Msg::kError) << "AlgAltDeMuxBase::IsXTalk => PMT out of array bounds : " <<    PMTmuxID << " woul give array overflow!" << endl;
01932     return 0.0;
01933   }
01934   Float_t q  = paltlist->GetBestItem().GetPE();
01935   Float_t qc = paltlist->GetBestItem().GetSigCorr()/60.;
01936   if(qc/q<0.1 || qc/q > 10.0){
01937     qc=q;
01938   }
01939 
01940   cout << " PMTmuxID PIXEL : " << PMTmuxID << "," << pixel << "  : " << qc << endl;
01941   Int_t i=PMTmuxID;
01942   cout  << fPMTmap[i][0]  << ":" << fPMTmap[i][1]  << 
01943     ":" << fPMTmap[i][2]  << ":" << fPMTmap[i][3]  << endl;
01944   cout  << fPMTmap[i][4]  << ":" << fPMTmap[i][5]  << 
01945     ":" << fPMTmap[i][6]  << ":" << fPMTmap[i][7]  << endl;
01946   cout  << fPMTmap[i][8]  << ":" << fPMTmap[i][9]  << 
01947     ":" << fPMTmap[i][10] << ":" << fPMTmap[i][11] << endl;
01948   cout  << fPMTmap[i][12] << ":" << fPMTmap[i][13] << 
01949     ":" << fPMTmap[i][14] << ":" << fPMTmap[i][15] << endl;
01950 
01951   cout  << fXTalkmap[i][0]  << ":" << fXTalkmap[i][1]  << 
01952     ":" << fXTalkmap[i][2]  << ":" << fXTalkmap[i][3]  << endl;
01953   cout  << fXTalkmap[i][4]  << ":" << fXTalkmap[i][5]  << 
01954     ":" << fXTalkmap[i][6]  << ":" << fXTalkmap[i][7]  << endl;
01955   cout  << fXTalkmap[i][8]  << ":" << fXTalkmap[i][9]  << 
01956     ":" << fXTalkmap[i][10] << ":" << fXTalkmap[i][11] << endl;
01957   cout  << fXTalkmap[i][12] << ":" << fXTalkmap[i][13] << 
01958     ":" << fXTalkmap[i][14] << ":" << fXTalkmap[i][15] << endl;
01959 
01960 
01961   
01962   switch(pixel){
01963   case 0:
01964     crossTalk = fPMTmap[PMTmuxID][1] + 
01965       fPMTmap[PMTmuxID][4];
01966     break;
01967   case 1:
01968     crossTalk = fPMTmap[PMTmuxID][0] + 
01969       fPMTmap[PMTmuxID][2] +
01970       fPMTmap[PMTmuxID][5];
01971       break;
01972   case 2:
01973     crossTalk = fPMTmap[PMTmuxID][1] + 
01974       fPMTmap[PMTmuxID][3] +
01975       fPMTmap[PMTmuxID][6];
01976     break;
01977   case 3:
01978     crossTalk = fPMTmap[PMTmuxID][2] + 
01979       fPMTmap[PMTmuxID][7];
01980     break;
01981   case 4:
01982     crossTalk = fPMTmap[PMTmuxID][0] + 
01983       fPMTmap[PMTmuxID][5] +
01984       fPMTmap[PMTmuxID][8];
01985     break;
01986   case 5:
01987     crossTalk = fPMTmap[PMTmuxID][1] + 
01988       fPMTmap[PMTmuxID][4] +
01989       fPMTmap[PMTmuxID][6] +
01990       fPMTmap[PMTmuxID][9];
01991     break;
01992   case 6:
01993     crossTalk = fPMTmap[PMTmuxID][2] + 
01994       fPMTmap[PMTmuxID][5] +
01995       fPMTmap[PMTmuxID][7] +
01996       fPMTmap[PMTmuxID][10];
01997     break;
01998   case 7:
01999     crossTalk = fPMTmap[PMTmuxID][3] + 
02000       fPMTmap[PMTmuxID][6] +
02001       fPMTmap[PMTmuxID][11];
02002     break;
02003   case 8:
02004     crossTalk = fPMTmap[PMTmuxID][4] + 
02005       fPMTmap[PMTmuxID][9] +
02006       fPMTmap[PMTmuxID][12];
02007     break;
02008   case 9:
02009     crossTalk = fPMTmap[PMTmuxID][5] + 
02010       fPMTmap[PMTmuxID][8] +
02011       fPMTmap[PMTmuxID][10] +
02012       fPMTmap[PMTmuxID][13];
02013     break;
02014   case 10:
02015     crossTalk = fPMTmap[PMTmuxID][6] + 
02016       fPMTmap[PMTmuxID][9] +
02017       fPMTmap[PMTmuxID][11] +
02018       fPMTmap[PMTmuxID][14];
02019     break;
02020   case 11:
02021     crossTalk = fPMTmap[PMTmuxID][7] + 
02022       fPMTmap[PMTmuxID][10] +
02023       fPMTmap[PMTmuxID][15];
02024     break;
02025   case 12:
02026     crossTalk = fPMTmap[PMTmuxID][8] + 
02027       fPMTmap[PMTmuxID][13];
02028     break;
02029   case 13:
02030     crossTalk = fPMTmap[PMTmuxID][9] + 
02031       fPMTmap[PMTmuxID][12]+
02032       fPMTmap[PMTmuxID][14];
02033     break;
02034   case 14:
02035     crossTalk = fPMTmap[PMTmuxID][10] + 
02036       fPMTmap[PMTmuxID][13]+
02037       fPMTmap[PMTmuxID][15];
02038     break;
02039   case 15:
02040     crossTalk = fPMTmap[PMTmuxID][11]+ 
02041       fPMTmap[PMTmuxID][14];
02042     break;
02043   default:
02044     crossTalk = 0;
02045     break;
02046   }
02047 
02048   return crossTalk;
02049 } 
02050 
02051 
02052 
02053 
02054 
02055 
02056 
02057 
02058 
02059 
02060 
02061 
02062 void  AlgAltDeMuxBase::DisplayPixelMap()
02063 {
02064 
02065   MSG("AltDeMux", Msg::kVerbose) << "AlgAltDeMuxBase::DisplayPixelMap : " << endl;
02066   for(int i=0; i<MAX_NUMBER_OF_PMTS; i++){
02067     if(fPMTtot[i]>0){
02068       MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::DisplayPixelMap PMT : " << i << endl;
02069       MSG("AltDeMux", Msg::kDebug) << fPMTmap[i][0]  << ":" << fPMTmap[i][1]  << 
02070         ":" << fPMTmap[i][2]  << ":" << fPMTmap[i][3]  << endl;
02071       MSG("AltDeMux", Msg::kDebug) << fPMTmap[i][4]  << ":" << fPMTmap[i][5]  << 
02072         ":" << fPMTmap[i][6]  << ":" << fPMTmap[i][7]  << endl;
02073       MSG("AltDeMux", Msg::kDebug) << fPMTmap[i][8]  << ":" << fPMTmap[i][9]  << 
02074         ":" << fPMTmap[i][10] << ":" << fPMTmap[i][11] << endl;
02075       MSG("AltDeMux", Msg::kDebug) << fPMTmap[i][12] << ":" << fPMTmap[i][13] << 
02076         ":" << fPMTmap[i][14] << ":" << fPMTmap[i][15] << endl;
02077 
02078     }
02079   }
02080   
02081   return;
02082 
02083 }
02084 
02085 
02086 
02087 void AlgAltDeMuxBase::DrawDiagnosticPlots(Int_t ipass) 
02088 {  
02089   if(!fDiagnosticPlots)return;
02090   TPolyMarker* pTPU1;
02091   TPolyMarker* pTPV1;
02092   TPolyMarker* pTPU2;
02093   TPolyMarker* pTPV2;
02094   TPolyMarker* pTPU3;
02095   TPolyMarker* pTPV3;
02096   TPolyMarker* pTPU4;
02097   TPolyMarker* pTPV4;
02098   TPolyMarker* pTPU5;
02099   TPolyMarker* pTPV5;
02100   float xU1[1000];
02101   float yU1[1000];
02102   float xU2[1000];
02103   float yU2[1000];
02104   float xU3[1000];
02105   float yU3[1000];
02106   float xU4[1000];
02107   float yU4[1000];
02108   float xU5[1000];
02109   float yU5[1000];
02110   int nU1=0;
02111   int nU2=0;
02112   int nU3=0;
02113   int nU4=0;
02114   int nU5=0;
02115   float xV1[1000];
02116   float yV1[1000];
02117   float xV2[1000];
02118   float yV2[1000];
02119   float xV3[1000];
02120   float yV3[1000];
02121   float xV4[1000];
02122   float yV4[1000];
02123   float xV5[1000];
02124   float yV5[1000];
02125   int nV1=0;
02126   int nV2=0;
02127   int nV3=0;
02128   int nV4=0;
02129   int nV5=0;
02130 
02131   Float_t markerSize = 1.0;
02132   if(fEventType==MULTIPLE_MUON)markerSize =0.75;
02133 
02134   for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
02135     for(Int_t i=0;i<NdemuxedHitsU[iplane];i++){
02136       for(Int_t j=i+1;j<NdemuxedHitsU[iplane];j++){
02137         if(demuxedHitStripU[iplane][i]==demuxedHitStripU[iplane][j]){
02138           demuxedHitQU[iplane][i] +=demuxedHitQU[iplane][j];
02139           demuxedHitQU[iplane][j] = 0;
02140         }
02141       }
02142     }
02143 
02144     for(Int_t i=0;i<NdemuxedHitsU[iplane];i++){
02145       if(demuxedHitQU[iplane][i]>0 && demuxedHitQU[iplane][i]<=3){
02146         xU1[nU1] = iplane;
02147         yU1[nU1] = demuxedHitStripU[iplane][i];
02148         nU1++;
02149       }
02150       if(demuxedHitQU[iplane][i]>=3 && demuxedHitQU[iplane][i]<=10){
02151         xU2[nU2] = iplane;
02152         yU2[nU2] = demuxedHitStripU[iplane][i];
02153         nU2++;
02154       }
02155       if(demuxedHitQU[iplane][i]>=10 && demuxedHitQU[iplane][i]<=25){
02156         xU3[nU3] = iplane;
02157         yU3[nU3] = demuxedHitStripU[iplane][i];
02158         nU3++;
02159       }
02160       if(demuxedHitQU[iplane][i]>=25 && demuxedHitQU[iplane][i]<=100){
02161         xU4[nU4] = iplane;
02162         yU4[nU4] = demuxedHitStripU[iplane][i];
02163         nU4++;
02164       }
02165       if(demuxedHitQU[iplane][i]>=100){
02166         xU5[nU5] = iplane;
02167         yU5[nU5] = demuxedHitStripU[iplane][i];
02168         nU5++;
02169       }
02170     }
02171   }
02172 
02173 
02174   for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
02175     for(Int_t i=0;i<NdemuxedHitsV[iplane];i++){
02176       for(Int_t j=i+1;j<NdemuxedHitsV[iplane];j++){
02177         if(demuxedHitStripV[iplane][i]==demuxedHitStripV[iplane][j]){
02178           demuxedHitQV[iplane][i] +=demuxedHitQV[iplane][j];
02179           demuxedHitQV[iplane][j] = 0;
02180         }
02181       }
02182     }
02183     
02184     for(int i=0;i<NdemuxedHitsV[iplane];i++){
02185       if(demuxedHitQV[iplane][i]>=0 && demuxedHitQV[iplane][i]<=3){
02186         xV1[nV1] = iplane;
02187         yV1[nV1] = demuxedHitStripV[iplane][i];
02188         nV1++;
02189       }
02190       if(demuxedHitQV[iplane][i]>=3 && demuxedHitQV[iplane][i]<=10){
02191         xV2[nV2] = iplane;
02192         yV2[nV2] = demuxedHitStripV[iplane][i];
02193         nV2++;
02194       }
02195       if(demuxedHitQV[iplane][i]>=10 && demuxedHitQV[iplane][i]<=25){
02196         xV3[nV3] = iplane;
02197         yV3[nV3] = demuxedHitStripV[iplane][i];
02198         nV3++;
02199       }
02200       if(demuxedHitQV[iplane][i]>=25 && demuxedHitQV[iplane][i]<=100){
02201         xV4[nV4] = iplane;
02202         yV4[nV4] = demuxedHitStripV[iplane][i];
02203         nV4++;
02204       }
02205       if(demuxedHitQV[iplane][i]>=100){
02206         xV5[nV5] = iplane;
02207         yV5[nV5] = demuxedHitStripV[iplane][i];
02208         nV5++;
02209       }
02210     }
02211   }
02212 
02213   pTPU1 = new TPolyMarker(nU1,xU1,yU1);
02214   pTPU1->SetMarkerStyle(20);
02215   pTPU1->SetMarkerColor(kYellow);
02216   pTPU1->SetMarkerSize(markerSize);
02217 
02218   pTPU2 = new TPolyMarker(nU2,xU2,yU2);
02219   pTPU2->SetMarkerStyle(20);
02220   pTPU2->SetMarkerColor(kCyan);
02221   pTPU2->SetMarkerSize(markerSize);
02222 
02223   pTPU3 = new TPolyMarker(nU3,xU3,yU3);
02224   pTPU3->SetMarkerStyle(20);
02225   pTPU3->SetMarkerColor(kBlue);
02226   pTPU3->SetMarkerSize(markerSize);
02227 
02228   pTPU4 = new TPolyMarker(nU4,xU4,yU4);
02229   pTPU4->SetMarkerStyle(20);
02230   pTPU4->SetMarkerColor(kBlack);
02231   pTPU4->SetMarkerSize(markerSize);
02232 
02233   pTPU5 = new TPolyMarker(nU5,xU5,yU5);
02234   pTPU5->SetMarkerStyle(20);
02235   pTPU5->SetMarkerColor(kRed);
02236   pTPU5->SetMarkerSize(markerSize);
02237 
02238   pTPV1 = new TPolyMarker(nV1,xV1,yV1);
02239   pTPV1->SetMarkerStyle(20);
02240   pTPV1->SetMarkerColor(kYellow);
02241   pTPV1->SetMarkerSize(markerSize);
02242 
02243   pTPV2 = new TPolyMarker(nV2,xV2,yV2);
02244   pTPV2->SetMarkerStyle(20);
02245   pTPV2->SetMarkerColor(kCyan);
02246   pTPV2->SetMarkerSize(markerSize);
02247 
02248   pTPV3 = new TPolyMarker(nV3,xV3,yV3);
02249   pTPV3->SetMarkerStyle(20);
02250   pTPV3->SetMarkerColor(kBlue);
02251   pTPV3->SetMarkerSize(markerSize);
02252 
02253   pTPV4 = new TPolyMarker(nV4,xV4,yV4);
02254   pTPV4->SetMarkerStyle(20);
02255   pTPV4->SetMarkerColor(kBlack);
02256   pTPV4->SetMarkerSize(markerSize);
02257 
02258   pTPV5 = new TPolyMarker(nV5,xV5,yV5);
02259   pTPV5->SetMarkerStyle(20);
02260   pTPV5->SetMarkerColor(kRed);
02261   pTPV5->SetMarkerSize(markerSize);
02262 
02263   // Keep track of the TPolyMarkers - delete them later
02264 
02265   fList->Add(pTPV1);
02266   fList->Add(pTPV2);
02267   fList->Add(pTPV3);
02268   fList->Add(pTPV4);
02269   fList->Add(pTPV5);
02270   fList->Add(pTPU1);
02271   fList->Add(pTPU2);
02272   fList->Add(pTPU3);
02273   fList->Add(pTPU4);
02274   fList->Add(pTPU5);
02275 
02276   fUpad->cd();
02277 
02278   if(ipass==-2&&fUTime){
02279     fUTime->GetXaxis()->SetRangeUser(fLowestPlane,fHighestPlane); 
02280     fUTime->SetMaximum(0.1);
02281     fUTime->SetLineColor(kRed);
02282     fUTime->SetFillColor(kRed);
02283     fUTime->Draw("BOX");
02284   }
02285   if(ipass==-1&&fUMask){
02286     fUMask->GetXaxis()->SetRangeUser(fLowestPlane,fHighestPlane); 
02287     if(fUTime)fUMask->Add(fUTime,1.);
02288     fUMask->SetLineColor(kGreen);
02289     fUMask->SetFillColor(kGreen);
02290     fUMask->SetMaximum(1.);
02291     if(fUMask)fUMask->Draw("BOX");
02292   }
02293 
02294   if(ipass>=0){
02295     if (fUview){
02296       fUview->GetXaxis()->SetRangeUser(fLowestPlane,fHighestPlane);
02297       fUview->Draw(); 
02298     }
02299     if (fUTime){
02300       fUTime->SetMaximum(1.);
02301       fUTime->Draw();
02302     }
02303     if (fUMask){
02304       fUMask->GetXaxis()->SetRangeUser(fLowestPlane,fHighestPlane);
02305       fUMask->Add(fUTime,1.);
02306       fUMask->SetLineColor(kGreen); 
02307       fUMask->SetFillColor(kGreen);
02308       fUMask->SetMaximum(1.);
02309       fUMask->Draw("BOX");
02310     }
02311     pTPU1->Draw();
02312     pTPU2->Draw();
02313     pTPU3->Draw();
02314     pTPU4->Draw();
02315     pTPU5->Draw();
02316   }
02317 
02318   if(fUZFitS)fUZFitS->Draw();
02319   if(fUZFitT)fUZFitT->Draw();
02320   if(fUZFitSSM1)fUZFitSSM1->Draw();
02321   if(fUZFitQSSM2)fUZFitQSSM2->Draw();
02322   if(fUZFitQSSM1)fUZFitQSSM1->Draw();
02323   if(fUZFitSSM2)fUZFitSSM2->Draw();
02324   if(fUZFitTSM1)fUZFitTSM1->Draw();
02325   if(fUZFitTSM2)fUZFitTSM2->Draw();
02326   if(fEventType==MULTIPLE_MUON){
02327     DeMuxFitResult_t resultU;
02328     // initialize unused struct members
02329     resultU.nUsed = 0;
02330     resultU.nData = 0;
02331     resultU.a1 = 0;
02332     resultU.a2 = 0;
02333     resultU.a3 = 0;
02334     resultU.a4 = 0;
02335     resultU.chi2 = 0;
02336     resultU.chi2pdf = 0;
02337     // set the values
02338     resultU.a0 = fHoughSlopeU;
02339     resultU.status = true;
02340     for(UInt_t i = 0; i< multipleMuonInterceptsU.size();i++){
02341       resultU.a1 = fHoughSlopeU;
02342       resultU.a0 = multipleMuonInterceptsU[i];
02343       TPolyLine* tP1 = NULL;
02344       TPolyLine* tP2 = NULL;
02345       this->MakeFitPolyLines(resultU, tP1, tP2, 1, 1);
02346       tP1->Draw();
02347       tP2->Draw();
02348     }
02349   }
02350 
02351 
02352   fVpad->cd();
02353 
02354   if(ipass==-2&&fVTime){
02355     fVTime->GetXaxis()->SetRangeUser(fLowestPlane,fHighestPlane); 
02356     fVTime->SetMaximum(0.1);
02357     fVTime->SetLineColor(kRed);
02358     fVTime->SetFillColor(kRed);
02359     if(fVTime)fVTime->Draw("BOX");
02360   }
02361   if(ipass==-1&&fVMask){
02362     fVMask->GetXaxis()->SetRangeUser(fLowestPlane,fHighestPlane); 
02363     if(fVTime)fVMask->Add(fVTime,1.);
02364     fVMask->SetLineColor(kGreen);
02365     fVMask->SetFillColor(kGreen);
02366     fVMask->SetMaximum(1.);
02367     fVMask->Draw("BOX");
02368   }
02369 
02370   if(ipass>=0){
02371     if (fVview){
02372       fVview->GetXaxis()->SetRangeUser(fLowestPlane,fHighestPlane);
02373       fVview->Draw();
02374     }
02375     if (fVTime){
02376       fVTime->SetMaximum(1.);
02377       fVTime->Draw();
02378     }
02379     if (fVMask){
02380       fVMask->GetXaxis()->SetRangeUser(fLowestPlane,fHighestPlane);
02381       fVMask->Add(fVTime,1.);
02382       fVMask->SetLineColor(kGreen);
02383       fVMask->SetFillColor(kGreen);
02384       fVMask->SetMaximum(1.);
02385       fVMask->Draw("BOX");
02386     }
02387     pTPV1->Draw();    
02388     pTPV2->Draw();
02389     pTPV3->Draw();
02390     pTPV4->Draw();
02391     pTPV5->Draw();
02392   }
02393 
02394   if(fVZFitT)fVZFitT->Draw();
02395   if(fVZFitS)fVZFitS->Draw();
02396   if(fVZFitSSM1)fVZFitSSM1->Draw();
02397   if(fVZFitSSM2)fVZFitSSM2->Draw();
02398   if(fVZFitQSSM1)fVZFitQSSM1->Draw();
02399   if(fVZFitQSSM2)fVZFitQSSM2->Draw();
02400   if(fVZFitTSM1)fVZFitTSM1->Draw();
02401   if(fVZFitTSM2)fVZFitTSM2->Draw();
02402 
02403   if(fEventType==MULTIPLE_MUON){
02404     DeMuxFitResult_t resultV;
02405     // initialize unused struct members
02406     resultV.nUsed = 0;
02407     resultV.nData = 0;
02408     resultV.a1 = 0;
02409     resultV.a2 = 0;
02410     resultV.a3 = 0;
02411     resultV.a4 = 0;
02412     resultV.chi2 = 0;
02413     resultV.chi2pdf = 0;
02414     // set the values
02415     for(UInt_t i = 0; i< multipleMuonInterceptsV.size();i++){
02416       resultV.a1 = fHoughSlopeV;
02417       resultV.a0 = multipleMuonInterceptsV[i];
02418       resultV.status = true;
02419       TPolyLine* tP1 = NULL;
02420       TPolyLine* tP2 = NULL;
02421       this->MakeFitPolyLines(resultV, tP1, tP2, 1, 1);
02422       tP1->Draw();
02423       tP2->Draw();
02424     }
02425 
02426 
02427   }
02428 
02429 
02430   fCanvas->Update();
02431   return;
02432   
02433 }
02434 
02435 
02436 
02437 
02438 bool AlgAltDeMuxBase::ValidatePlane(Int_t iplane, bool useTimeMask){
02439 
02440   bool fitStatusT = false;
02441   bool fitStatusH = false;
02442 
02443 
02444   if(fPlaneHit[iplane]==0)return false;
02445 
02446   if(fEventType==MULTIPLE_MUON){
02447     MSG("AltDeMux", Msg::kWarning) << "AlgAltDeMuxBase::ValidatePlane doesn't yet handle Multiple Muons " << endl; 
02448     return false;
02449   }
02450 
02451   Int_t easthits = fDeMuxedPlanesAltLists[iplane][ALG_EAST].size()+
02452     fPlanesAltLists[iplane][ALG_EAST].size();
02453   Int_t westhits = fDeMuxedPlanesAltLists[iplane][ALG_WEST].size()+
02454     fPlanesAltLists[iplane][ALG_WEST].size();
02455 
02456   if(amWriting){
02457     if(amWriting)cout << "*****************************************************************  PLANE : " << iplane << endl;
02458     if(amWriting)cout << "ew : " << easthits << ":" << westhits << endl;
02459   }
02460 
02461   bool oneSided = false;
02462   if(easthits==0||westhits==0){
02463     if(easthits>0||westhits>0)oneSided = true;
02464   }
02465 
02466 
02467   Int_t istripH;
02468   Int_t istripT;
02469 
02470   Int_t jplane = iplane;
02471   if(jplane>249)jplane+=20;
02472   if( fUVMap[iplane]==PlaneView::kU){
02473     fitStatusH = fFitQHitU.status;
02474     istripH = static_cast<Int_t>(jplane*fFitQHitU.a1+fFitQHitU.a0);
02475     if(!fFitQHitU.status){
02476       istripH = static_cast<Int_t>(jplane*fFitHitU.a1+fFitHitU.a0);
02477       fitStatusH = fFitHitU.status;
02478     }
02479     fitStatusT = fFitTimeU.status;
02480     istripT = static_cast<Int_t>(jplane*fFitTimeU.a1+fFitTimeU.a0);
02481     if(amWriting){
02482       cout << " fit status : " << fitStatusH << " " << fitStatusT << endl;
02483       cout << "U HIT  STRIP AIM : " << istripH <<" "<< fFitQHitV.a0 << " : " << fFitQHitV.a1 << endl;
02484       cout << "U TIME STRIP AIM : " << istripT <<" "<< fFitTimeV.a0 << " : " << fFitTimeV.a1 << endl;
02485     }
02486   }
02487 
02488   if( fUVMap[iplane]==PlaneView::kV){
02489     fitStatusH = fFitQHitV.status;
02490     istripH = static_cast<Int_t>(jplane*fFitQHitV.a1+fFitQHitV.a0);
02491     if(!fitStatusH){
02492       fitStatusH = fFitHitV.status;
02493       istripH = static_cast<Int_t>(jplane*fFitHitV.a1+fFitHitV.a0);
02494     }
02495     fitStatusT = fFitTimeV.status;
02496     istripT = static_cast<Int_t>(jplane*fFitTimeV.a1+fFitTimeV.a0);
02497     if(amWriting){
02498       cout << "V HIT  STRIP AIM : " << istripH <<" "<< fFitQHitV.a0 << " : " << fFitQHitV.a1 << endl;
02499       cout << "V TIME STRIP AIM : " << istripT <<" "<< fFitTimeV.a0 << " : " << fFitTimeV.a1 << endl;
02500     }
02501   }
02502 
02503   if(istripH>=MAX_NUMBER_OF_STRIPS)istripH=MAX_NUMBER_OF_STRIPS; 
02504   if(istripT>=MAX_NUMBER_OF_STRIPS)istripT=MAX_NUMBER_OF_STRIPS; 
02505   if(istripH<0)istripH=0;
02506   if(istripT<0)istripT=0;
02507   
02508   bool returnFlag = false;
02509   bool found = false;
02510   bool useOldResult = false;
02511 
02512   PlaneValidity_t stripResult;
02513   PlaneValidity_t timeMaskResult;
02514   PlaneValidity_t oldResult;
02515   PlaneValidity_t hitResult;
02516   PlaneValidity_t timeResult;
02517 
02518   vector<Int_t>oldPattern;
02519   for(Int_t iHitStrip=1; iHitStrip<=fPlaneHit[iplane];iHitStrip++){
02520     oldPattern.push_back(fHitMap[iplane][iHitStrip]);
02521   }
02522   if(!oneSided)oldResult = this->ValidatePlaneForPattern(iplane, oldPattern);
02523   if( oneSided)oldResult = this->ValidateOneSidedPlaneForPattern(iplane, oldPattern);
02524 
02525   for(UInt_t i = 0; i<oldResult.strips.size(); i++){
02526     bool found = false;
02527     for(UInt_t ipair=0;ipair<fDeMuxedPairs[iplane].size();ipair++){
02528       Int_t istrip = fDeMuxedPairs[iplane][ipair].altListE->GetBestSEId().GetStrip();
02529       if(oldResult.strips[i]==istrip)found=true;
02530     }
02531     if(found==false){
02532       useOldResult=true;
02533       //cout << "USE OLD RESULT IS SET !!!!!!" << endl;
02534       //getchar();
02535     }
02536   }
02537 
02538 
02539   stripResult.largestContigGroup = -1;
02540   Int_t bestStrip;
02541   for(Int_t iHitStrip=1; iHitStrip<=fPlaneHit[iplane];iHitStrip++){
02542     vector<Int_t>pattern;
02543     pattern.push_back(fHitMap[iplane][iHitStrip]);
02544     PlaneValidity_t thisStripResult;
02545     if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
02546     if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
02547     if(thisStripResult.largestContigGroup>stripResult.largestContigGroup){
02548       stripResult = thisStripResult;
02549       bestStrip = fHitMap[iplane][iHitStrip];
02550     }
02551     if(thisStripResult.largestContigGroup==stripResult.largestContigGroup){
02552       if( fabs(thisStripResult.chi2DQ-stripResult.chi2DQ)>10){
02553         if(thisStripResult.chi2DQ+10.<stripResult.chi2DQ){
02554           stripResult = thisStripResult;
02555           bestStrip = fHitMap[iplane][iHitStrip];
02556         }
02557       }else{
02558         if(fitStatusH && fabs(thisStripResult.centroid-istripH)<fabs(stripResult.centroid-istripH)){
02559           stripResult = thisStripResult;
02560           bestStrip = fHitMap[iplane][iHitStrip];
02561         }
02562       }
02563     }
02564   }
02565 
02566   hitResult.largestContigGroup = 0;
02567   vector<Int_t>patternH;
02568   if(fitStatusH){
02569     patternH.push_back(istripH);
02570     if(!oneSided)hitResult =  this->ValidatePlaneForPattern(iplane, patternH);
02571     if( oneSided)hitResult =  this->ValidateOneSidedPlaneForPattern(iplane, patternH);
02572   }
02573 
02574 
02575   Int_t bestMaskStrip=-1;
02576   timeMaskResult.largestContigGroup = -1;
02577   if(useTimeMask){
02578     for(Int_t iStrip=0; iStrip<=MAX_NUMBER_OF_STRIPS;iStrip++){
02579       if(fUVmask[iplane][iStrip]==true){
02580         vector<Int_t>pattern;
02581         pattern.push_back(iStrip);
02582         PlaneValidity_t thisStripResult;
02583         if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
02584         if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
02585         if(thisStripResult.largestContigGroup>timeMaskResult.largestContigGroup){
02586           timeMaskResult = thisStripResult;
02587           bestMaskStrip = iStrip;
02588         }
02589         if(thisStripResult.largestContigGroup==timeMaskResult.largestContigGroup){
02590           if(oneSided){
02591             if(thisStripResult.stripSpan<=timeMaskResult.stripSpan){
02592               bestMaskStrip = iStrip;
02593               timeMaskResult = thisStripResult;
02594             }
02595           }else{
02596             if((timeMaskResult.fractionQE<0.25||timeMaskResult.fractionQW<0.25)||(thisStripResult.fractionQE>0.5&&thisStripResult.fractionQW>0.5)){
02597               if(thisStripResult.chi2DQ<timeMaskResult.chi2DQ+5.){
02598                 bestMaskStrip = iStrip;
02599                 timeMaskResult = thisStripResult;
02600               }
02601             }
02602           }
02603         }
02604         if(thisStripResult.largestContigGroup>=hitResult.largestContigGroup){
02605           if(amWriting)cout << "TIMING MASK : " << iStrip << endl;
02606           if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
02607           if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
02608         }
02609       }
02610     }
02611   }
02612       
02613 
02614 
02615   timeResult.largestContigGroup = 0;
02616   vector<Int_t>patternT;
02617   if(fitStatusT){
02618     patternT.push_back(istripT);
02619     if(!oneSided)timeResult =  this->ValidatePlaneForPattern(iplane, patternT);
02620     if( oneSided)timeResult =  this->ValidateOneSidedPlaneForPattern(iplane, patternT);
02621   }
02622 
02623   bool useTimeFit   = false;
02624   bool useHitFit    = false;
02625   bool useBestStrip = false;
02626   bool useTimeMaskHit  = false;
02627 
02628   if(useTimeMask&&!oneSided){
02629     if(timeMaskResult.fractionQE>0.25 && timeMaskResult.fractionQW>0.25)useTimeMaskHit = true;
02630     if(timeMaskResult.chi2DQ>oldResult.chi2DQ+20.)useTimeMaskHit = false;
02631   }
02632 
02633   if(fitStatusT){
02634     if(timeResult.largestContigGroup>oldResult.largestContigGroup){
02635       if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25||(timeResult.fractionQE>0.5&&timeResult.fractionQW>0.5))useTimeFit = true;
02636     } 
02637     if(timeResult.largestContigGroup==oldResult.largestContigGroup){
02638       if(timeResult.chi2DQ+10.<oldResult.chi2DQ){
02639         if(oldResult.fractionQE+oldResult.fractionQW<timeResult.fractionQE+timeResult.fractionQW>0.5)useTimeFit = true;
02640       }
02641     } 
02642     if(timeResult.fractionQE<0.25||timeResult.fractionQW<0.25)useTimeFit = false;
02643     if(timeResult.chi2DQ>oldResult.chi2DQ+20.)useTimeFit = false;
02644   }
02645 
02646   if(fitStatusH){
02647     if(hitResult.largestContigGroup>oldResult.largestContigGroup){
02648       if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25||(hitResult.fractionQE>0.5&&hitResult.fractionQW>0.5))useHitFit = true;
02649     } 
02650     if(hitResult.largestContigGroup>=oldResult.largestContigGroup){
02651       if(hitResult.fractionQE>0.75&&hitResult.fractionQW>0.75&&(hitResult.chi2DQ+20.0<oldResult.chi2DQ))useHitFit = true;
02652     }
02653 
02654 
02655 
02656     if(hitResult.fractionQE<0.25||hitResult.fractionQW<0.25)useHitFit = false;
02657     if(hitResult.chi2DQ>oldResult.chi2DQ+20.)useHitFit = false;
02658     if(hitResult.largestContigGroup>oldResult.largestContigGroup){
02659       if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25&&(hitResult.fractionQE>0.5&&hitResult.fractionQW>0.5))useHitFit = true;
02660     } 
02661   }
02662 
02663   if(stripResult.largestContigGroup>oldResult.largestContigGroup){
02664     if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25||(stripResult.fractionQE>0.5&&stripResult.fractionQW>0.5))useBestStrip = true;
02665     if(stripResult.chi2DQ>oldResult.chi2DQ+20.)useBestStrip = false;
02666   } 
02667 
02668   if(oneSided){
02669     if(fitStatusT)useTimeFit = true;
02670     if(fitStatusH)useHitFit = true;
02671     useBestStrip= true;
02672   }
02673  
02674 
02675   if(useHitFit){
02676     //amWriting = true;
02677     //    if(!found)this->ValidatePlaneForPattern(iplane, oldPattern);
02678     found = true;
02679     if(amWriting)cout  << " ALERT **HITS** " << endl; 
02680     //this->ValidatePlaneForPattern(iplane, patternH);
02681     found = true;
02682     if(hitResult.largestContigGroup>=timeResult.largestContigGroup&&
02683        hitResult.largestContigGroup>=stripResult.largestContigGroup){
02684       if(!oneSided)this->ReMuxPlane(iplane, patternH);
02685       if( oneSided)this->ReMuxSingleSidedPlane(iplane, patternH);
02686     }
02687   }
02688 
02689   if(useBestStrip){
02690     //amWriting = true;
02691     //if(!found)this->ValidatePlaneForPattern(iplane, oldPattern);
02692     found = true;
02693     if(amWriting)cout  << " ALERT **BEST** " << bestStrip << endl; 
02694     vector<Int_t>pattern;
02695     pattern.push_back(bestStrip);
02696     //this->ValidatePlaneForPattern(iplane, pattern);
02697     found = true;
02698     if(stripResult.largestContigGroup>=timeResult.largestContigGroup&&
02699        stripResult.largestContigGroup>hitResult.largestContigGroup){
02700       if(!oneSided)this->ReMuxPlane(iplane, pattern);
02701       if( oneSided)this->ReMuxSingleSidedPlane(iplane, pattern);
02702     }
02703   }
02704 
02705   if(useTimeFit){
02706     //amWriting = true;
02707     //if(!found)this->ValidatePlaneForPattern(iplane, oldPattern);
02708     found = true;
02709     if(amWriting)cout  << " ALERT **TIME** " << endl; 
02710     //this->ValidatePlaneForPattern(iplane, patternT);
02711     found = true;
02712     if(timeResult.largestContigGroup>hitResult.largestContigGroup&&
02713        timeResult.largestContigGroup>stripResult.largestContigGroup){
02714       if(!oneSided)this->ReMuxPlane(iplane, patternT);
02715       if( oneSided)this->ReMuxSingleSidedPlane(iplane, patternT);
02716     }
02717   }
02718 
02719 
02720 
02721   if(useTimeMaskHit){
02722     //amWriting = true;
02723     //if(!found)this->ValidatePlaneForPattern(iplane, oldPattern);
02724     if(amWriting)cout  << " ALERT ** TIME MASK !!!!!! ** " << bestMaskStrip << endl; 
02725     vector<Int_t>pattern;
02726     pattern.push_back(bestMaskStrip);
02727     found = true;
02728     if(amWriting)cout << "TM : " << timeMaskResult.largestContigGroup << "   H : " << hitResult.largestContigGroup << endl;
02729     if(timeMaskResult.largestContigGroup>hitResult.largestContigGroup){
02730       if(!oneSided)this->ReMuxPlane(iplane, pattern);
02731       if( oneSided){
02732         cout << "1 Sided Time Mask ReMux : " << timeMaskResult.largestContigGroup << endl;
02733         if(timeMaskResult.largestContigGroup>1){
02734           this->ReMuxSingleSidedPlane(iplane, pattern);
02735         }
02736       }
02737     }
02738     if(timeMaskResult.largestContigGroup==oldResult.largestContigGroup){
02739       if(!oneSided){
02740         if((timeMaskResult.fractionQE+timeMaskResult.fractionQW>
02741             oldResult.fractionQE+oldResult.fractionQW)  ||
02742            (timeMaskResult.chi2DQ+5.0<oldResult.chi2DQ))this->ReMuxPlane(iplane, pattern);
02743       }
02744       if(oneSided){
02745         if(timeMaskResult.largestContigGroup>1){
02746           this->ReMuxSingleSidedPlane(iplane, pattern);
02747             if(amWriting)cout << "One Sided Time Mask ReMux : " << timeMaskResult.largestContigGroup << endl;
02748         }
02749       }
02750     }
02751   }  
02752 
02753   returnFlag = found;
02754 
02755   return returnFlag;
02756 }
02757 
02758 
02759 
02760 
02761 
02762 
02763 
02764 
02765 
02766 
02767 bool AlgAltDeMuxBase::DumpValidateBeamPlane(Int_t iplane, bool useTimeMask){
02768 
02769   bool fitStatusT = false;
02770   bool fitStatusH = false;
02771 
02772 
02773   if(fPlaneHit[iplane]==0)return false;
02774 
02775   if(fEventType==MULTIPLE_MUON){
02776     MSG("AltDeMux", Msg::kWarning) << "AlgAltDeMuxBase::ValidateBeamPlane doesn't yet Multiple Muons " << endl; 
02777     return false;
02778   }
02779   amWriting = false;
02780 
02781 
02782   Int_t easthits = fDeMuxedPlanesAltLists[iplane][ALG_EAST].size()+
02783     fPlanesAltLists[iplane][ALG_EAST].size();
02784   Int_t westhits = fDeMuxedPlanesAltLists[iplane][ALG_WEST].size()+
02785     fPlanesAltLists[iplane][ALG_WEST].size();
02786 
02787   if(amWriting){
02788     if(amWriting)cout << "*****************************************************************  PLANE : " << iplane << endl;
02789     if(amWriting)cout << "ew : " << easthits << ":" << westhits << endl;
02790   }
02791 
02792   bool oneSided = false;
02793   if(easthits==0||westhits==0){
02794     if(easthits>0||westhits>0)oneSided = true;
02795   }
02796 
02797   Int_t istripH;
02798   Int_t istripT;
02799 
02800   Int_t jplane = iplane;
02801   if(jplane>249)jplane+=20;
02802   if( fUVMap[iplane]==PlaneView::kU){
02803     fitStatusH = fFitQHitU.status;
02804     istripH = static_cast<Int_t>(jplane*fFitQHitU.a1+fFitQHitU.a0);
02805     if(!fFitQHitU.status){
02806       istripH = static_cast<Int_t>(jplane*fFitHitU.a1+fFitHitU.a0);
02807       fitStatusH = fFitHitU.status;
02808     }
02809     fitStatusT = fFitTimeU.status;
02810     istripT = static_cast<Int_t>(jplane*fFitTimeU.a1+fFitTimeU.a0);
02811     if(amWriting){
02812       cout << " fit status : " << fitStatusH << " " << fitStatusT << endl;
02813       cout << "U HIT  STRIP AIM : " << istripH <<" "<< fFitQHitV.a0 << " : " << fFitQHitV.a1 << endl;
02814       cout << "U TIME STRIP AIM : " << istripT <<" "<< fFitTimeV.a0 << " : " << fFitTimeV.a1 << endl;
02815     }
02816   }
02817   if( fUVMap[iplane]==PlaneView::kV){
02818     fitStatusH = fFitQHitV.status;
02819     istripH = static_cast<Int_t>(jplane*fFitQHitV.a1+fFitQHitV.a0);
02820     if(!fitStatusH){
02821       fitStatusH = fFitHitV.status;
02822       istripH = static_cast<Int_t>(jplane*fFitHitV.a1+fFitHitV.a0);
02823     }
02824     fitStatusT = fFitTimeV.status;
02825     istripT = static_cast<Int_t>(jplane*fFitTimeV.a1+fFitTimeV.a0);
02826     if(amWriting){
02827       cout << "V HIT  STRIP AIM : " << istripH <<" "<< fFitQHitV.a0 << " : " << fFitQHitV.a1 << endl;
02828       cout << "V TIME STRIP AIM : " << istripT <<" "<< fFitTimeV.a0 << " : " << fFitTimeV.a1 << endl;
02829     }
02830   }
02831 
02832   if(istripH>=MAX_NUMBER_OF_STRIPS)istripH=MAX_NUMBER_OF_STRIPS; 
02833   if(istripT>=MAX_NUMBER_OF_STRIPS)istripT=MAX_NUMBER_OF_STRIPS; 
02834   if(istripH<0)istripH=0;
02835   if(istripT<0)istripT=0;
02836 
02837   
02838   bool returnFlag = false;
02839   bool found = false;
02840   bool useOldResult = false;
02841 
02842   PlaneValidity_t stripResult;
02843   PlaneValidity_t timeMaskResult;
02844   PlaneValidity_t oldResult;
02845   PlaneValidity_t hitResult;
02846   PlaneValidity_t timeResult;
02847 
02848 
02849   // Determine pattern for current result
02850   vector<Int_t>oldPattern;
02851   for(Int_t iHitStrip=1; iHitStrip<=fPlaneHit[iplane];iHitStrip++){
02852     oldPattern.push_back(fHitMap[iplane][iHitStrip]);
02853   }
02854   if(!oneSided)oldResult = this->ValidatePlaneForPattern(iplane, oldPattern);
02855   if( oneSided)oldResult = this->ValidateOneSidedPlaneForPattern(iplane, oldPattern);
02856 
02857   for(UInt_t i = 0; i<oldResult.strips.size(); i++){
02858     bool found = false;
02859     for(UInt_t ipair=0;ipair<fDeMuxedPairs[iplane].size();ipair++){
02860       Int_t istrip = fDeMuxedPairs[iplane][ipair].altListE->GetBestSEId().GetStrip();
02861       if(oldResult.strips[i]==istrip)found=true;
02862     }
02863     if(found==false){
02864       useOldResult=true;
02865       //cout << "USE OLD RESULT IS SET !!!!!!" << endl;
02866       //getchar();
02867     }
02868   }
02869 
02870 
02871 
02872   // Look at patterns centred on the hit strips
02873   stripResult.largestContigGroup = -1;
02874   Int_t bestStrip;
02875   for(Int_t iHitStrip=1; iHitStrip<=fPlaneHit[iplane];iHitStrip++){
02876     vector<Int_t>pattern;
02877     pattern.push_back(fHitMap[iplane][iHitStrip]);
02878     PlaneValidity_t thisStripResult;
02879     if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
02880     if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
02881     if(this->ValidityComp(stripResult,thisStripResult,istripH,istripT,oneSided)){
02882       stripResult = thisStripResult;
02883       bestStrip = fHitMap[iplane][iHitStrip];
02884     }
02885   }
02886 
02887 
02888   hitResult.largestContigGroup = 0;
02889   vector<Int_t>patternH;
02890   if(fitStatusH){
02891     patternH.push_back(istripH);
02892     if(!oneSided)hitResult =  this->ValidatePlaneForPattern(iplane, patternH);
02893     if( oneSided)hitResult =  this->ValidateOneSidedPlaneForPattern(iplane, patternH);
02894   }
02895 
02896 
02897   Int_t bestMaskStrip=-1;
02898   timeMaskResult.largestContigGroup = -1;
02899   if(useTimeMask){
02900     for(Int_t iStrip=0; iStrip<=MAX_NUMBER_OF_STRIPS;iStrip++){
02901       if(fUVmask[iplane][iStrip]==true){
02902         vector<Int_t>pattern;
02903         pattern.push_back(iStrip);
02904         PlaneValidity_t thisStripResult;
02905         if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
02906         if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
02907         if(this->ValidityComp(timeMaskResult,thisStripResult,istripH,istripT,oneSided)){
02908           timeMaskResult = thisStripResult;
02909           bestMaskStrip = iStrip;
02910         }else{
02911           if(oneSided && thisStripResult.largestContigGroup==timeMaskResult.largestContigGroup){
02912             if(thisStripResult.stripSpan<=timeMaskResult.stripSpan){
02913               bestMaskStrip = iStrip;
02914               timeMaskResult = thisStripResult;
02915             }
02916           }     
02917         }
02918       }
02919     }
02920   }
02921       
02922   timeResult.largestContigGroup = 0;
02923   vector<Int_t>patternT;
02924   if(fitStatusT){
02925     patternT.push_back(istripT);
02926     if(!oneSided)timeResult =  this->ValidatePlaneForPattern(iplane, patternT);
02927     if( oneSided)timeResult =  this->ValidateOneSidedPlaneForPattern(iplane, patternT);
02928   }
02929 
02930   bool useTimeFit   = false;
02931   bool useHitFit    = false;
02932   bool useBestStrip = false;
02933   bool useTimeMaskHit  = false;
02934 
02935   if(useTimeMask){
02936     if(oneSided){
02937     }else{
02938       if(timeMaskResult.fractionQE>0.25 && timeMaskResult.fractionQW>0.25)useTimeMaskHit = true;
02939       if(timeMaskResult.chi2DQ>oldResult.chi2DQ+20.)useTimeMaskHit = false;
02940     }
02941   }
02942 
02943   if(fitStatusT){
02944     if(timeResult.largestContigGroup>oldResult.largestContigGroup){
02945       if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25||(timeResult.fractionQE>0.5&&timeResult.fractionQW>0.5))useTimeFit = true;
02946     } 
02947     if(timeResult.fractionQE<0.25||timeResult.fractionQW<0.25)useTimeFit = false;
02948     if(timeResult.chi2DQ>oldResult.chi2DQ+20.)useTimeFit = false;
02949   }
02950 
02951   if(fitStatusH){
02952     if(hitResult.largestContigGroup>oldResult.largestContigGroup){
02953       if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25||(hitResult.fractionQE>0.5&&hitResult.fractionQW>0.5))useHitFit = true;
02954     } 
02955     if(hitResult.largestContigGroup>=oldResult.largestContigGroup){
02956       if(hitResult.fractionQE>0.75&&hitResult.fractionQW>0.75&&(hitResult.chi2DQ+20.0<oldResult.chi2DQ))useHitFit = true;
02957     }
02958 
02959     if(hitResult.fractionQE<0.25||hitResult.fractionQW<0.25)useHitFit = false;
02960     if(hitResult.chi2DQ>oldResult.chi2DQ+20.)useHitFit = false;
02961     if(hitResult.largestContigGroup>oldResult.largestContigGroup){
02962       if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25&&(hitResult.fractionQE>0.5&&hitResult.fractionQW>0.5))useHitFit = true;
02963     } 
02964   }
02965 
02966   if(stripResult.largestContigGroup>oldResult.largestContigGroup){
02967     if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25||(stripResult.fractionQE>0.5&&stripResult.fractionQW>0.5))useBestStrip = true;
02968     if(stripResult.chi2DQ>oldResult.chi2DQ+20.)useBestStrip = false;
02969   } 
02970 
02971   if(oneSided){
02972     if(fitStatusT)useTimeFit = true;
02973     if(fitStatusH)useHitFit = true;
02974     useBestStrip= true;
02975   }
02976  
02977 
02978   if(useHitFit){
02979     //amWriting = true;
02980     //    if(!found)this->ValidatePlaneForPattern(iplane, oldPattern);
02981     found = true;
02982     if(amWriting)cout  << " ALERT **HITS** " << endl; 
02983     //this->ValidatePlaneForPattern(iplane, patternH);
02984     found = true;
02985     if(hitResult.largestContigGroup>=timeResult.largestContigGroup&&
02986        hitResult.largestContigGroup>=stripResult.largestContigGroup){
02987       //if(!oneSided)this->ReMuxPlane(iplane, patternH);
02988       //if( oneSided)this->ReMuxSingleSidedPlane(iplane, patternH);
02989     }
02990   }
02991 
02992   if(useBestStrip){
02993     found = true;
02994     if(amWriting)cout  << " ALERT **BEST** " << bestStrip << endl; 
02995     vector<Int_t>pattern;
02996     pattern.push_back(bestStrip);
02997     //this->ValidatePlaneForPattern(iplane, pattern);
02998     found = true;
02999     if(stripResult.largestContigGroup>=timeResult.largestContigGroup&&
03000        stripResult.largestContigGroup>hitResult.largestContigGroup){
03001       //if(!oneSided)this->ReMuxPlane(iplane, pattern);
03002       //if( oneSided)this->ReMuxSingleSidedPlane(iplane, pattern);
03003     }
03004   }
03005 
03006   if(useTimeFit){
03007     found = true;
03008     if(amWriting)cout  << " ALERT **TIME** " << endl; 
03009     found = true;
03010     if(timeResult.largestContigGroup>hitResult.largestContigGroup&&
03011        timeResult.largestContigGroup>stripResult.largestContigGroup){
03012       //if(!oneSided)this->ReMuxPlane(iplane, patternT);
03013       //if( oneSided)this->ReMuxSingleSidedPlane(iplane, patternT);
03014     }
03015   }
03016 
03017 
03018 
03019   if(useTimeMaskHit){
03020     if(amWriting)cout  << " ALERT ** TIME MASK !!!!!! ** " << bestMaskStrip << endl; 
03021     vector<Int_t>pattern;
03022     pattern.push_back(bestMaskStrip);
03023     found = true;
03024     if(amWriting)cout << "TM : " << timeMaskResult.largestContigGroup << "   H : " << hitResult.largestContigGroup << endl;
03025     if(timeMaskResult.largestContigGroup>hitResult.largestContigGroup){
03026       if(!oneSided)this->ReMuxPlane(iplane, pattern);
03027       if( oneSided){
03028         cout << "1 Sided Time Mask ReMux : " << timeMaskResult.largestContigGroup << endl;
03029         if(timeMaskResult.largestContigGroup>1){
03030           //  this->ReMuxSingleSidedPlane(iplane, pattern);
03031         }
03032       }
03033     }
03034     if(timeMaskResult.largestContigGroup==oldResult.largestContigGroup){
03035       if(!oneSided){
03036         //      if((timeMaskResult.fractionQE+timeMaskResult.fractionQW>oldResult.fractionQE+oldResult.fractionQW)  ||(timeMaskResult.chi2DQ+5.0<oldResult.chi2DQ))this->ReMuxPlane(iplane, pattern);
03037       }
03038       if(oneSided){
03039         if(timeMaskResult.largestContigGroup>1){
03040           //this->ReMuxSingleSidedPlane(iplane, pattern);
03041             if(amWriting)cout << "One Sided Time Mask ReMux : " << timeMaskResult.largestContigGroup << endl;
03042         }
03043       }
03044     }
03045   }  
03046 
03047   returnFlag = found;
03048 
03049   amWriting = false;
03050   return returnFlag;
03051 }
03052 
03053 
03054 
03055 
03056 
03057 
03058 
03059 bool AlgAltDeMuxBase::ValidateBeamPlane(Int_t iplane, bool useTimeMask){
03060 
03061   bool fitStatusT = false;
03062   bool fitStatusH = false;
03063 
03064 
03065   if(fPlaneHit[iplane]==0)return false;
03066 
03067   if(fEventType==MULTIPLE_MUON){
03068     MSG("AltDeMux", Msg::kWarning) << "AlgAltDeMuxBase::ValidateBeamPlane doesn't yet Multiple Muons " << endl; 
03069     return false;
03070   }
03071   amWriting = false;
03072 
03073 
03074   Int_t easthits = fDeMuxedPlanesAltLists[iplane][ALG_EAST].size()+
03075     fPlanesAltLists[iplane][ALG_EAST].size();
03076   Int_t westhits = fDeMuxedPlanesAltLists[iplane][ALG_WEST].size()+
03077     fPlanesAltLists[iplane][ALG_WEST].size();
03078 
03079   if(amWriting){
03080     if(amWriting)cout << "*****************************************************************  PLANE : " << iplane << endl;
03081     if(amWriting)cout << "ew : " << easthits << ":" << westhits << endl;
03082   }
03083 
03084   bool oneSided = false;
03085   if(easthits==0||westhits==0){
03086     if(easthits>0||westhits>0)oneSided = true;
03087   }
03088 
03089 
03090   Int_t istripH;
03091   Int_t istripT;
03092 
03093   Int_t jplane = iplane;
03094   if(jplane>249)jplane+=20;
03095   if( fUVMap[iplane]==PlaneView::kU){
03096     fitStatusH = fFitQHitU.status;
03097     istripH = static_cast<Int_t>(jplane*fFitQHitU.a1+fFitQHitU.a0);
03098     if(!fFitQHitU.status){
03099       istripH = static_cast<Int_t>(jplane*fFitHitU.a1+fFitHitU.a0);
03100       fitStatusH = fFitHitU.status;
03101     }
03102     fitStatusT = fFitTimeU.status;
03103     istripT = static_cast<Int_t>(jplane*fFitTimeU.a1+fFitTimeU.a0);
03104     if(amWriting){
03105       cout << " fit status : " << fitStatusH << " " << fitStatusT << endl;
03106       cout << "U HIT  STRIP AIM : " << istripH <<" "<< fFitQHitV.a0 << " : " << fFitQHitV.a1 << endl;
03107       cout << "U TIME STRIP AIM : " << istripT <<" "<< fFitTimeV.a0 << " : " << fFitTimeV.a1 << endl;
03108     }
03109   }
03110   if( fUVMap[iplane]==PlaneView::kV){
03111     fitStatusH = fFitQHitV.status;
03112     istripH = static_cast<Int_t>(jplane*fFitQHitV.a1+fFitQHitV.a0);
03113     if(!fitStatusH){
03114       fitStatusH = fFitHitV.status;
03115       istripH = static_cast<Int_t>(jplane*fFitHitV.a1+fFitHitV.a0);
03116     }
03117     fitStatusT = fFitTimeV.status;
03118     istripT = static_cast<Int_t>(jplane*fFitTimeV.a1+fFitTimeV.a0);
03119     if(amWriting){
03120       cout << "V HIT  STRIP AIM : " << istripH <<" "<< fFitQHitV.a0 << " : " << fFitQHitV.a1 << endl;
03121       cout << "V TIME STRIP AIM : " << istripT <<" "<< fFitTimeV.a0 << " : " << fFitTimeV.a1 << endl;
03122     }
03123   }
03124 
03125   if(istripH>=MAX_NUMBER_OF_STRIPS)istripH=MAX_NUMBER_OF_STRIPS; 
03126   if(istripT>=MAX_NUMBER_OF_STRIPS)istripT=MAX_NUMBER_OF_STRIPS; 
03127   if(istripH<0)istripH=0;
03128   if(istripT<0)istripT=0;
03129 
03130   
03131   bool returnFlag = false;
03132   bool found = false;
03133   bool useOldResult = false;
03134 
03135   PlaneValidity_t stripResult;
03136   PlaneValidity_t timeMaskResult;
03137   PlaneValidity_t oldResult;
03138   PlaneValidity_t hitResult;
03139   PlaneValidity_t timeResult;
03140 
03141 
03142   vector<Int_t>oldPattern;
03143   for(Int_t iHitStrip=1; iHitStrip<=fPlaneHit[iplane];iHitStrip++){
03144     oldPattern.push_back(fHitMap[iplane][iHitStrip]);
03145   }
03146   if(!oneSided)oldResult = this->ValidatePlaneForPattern(iplane, oldPattern);
03147   if( oneSided)oldResult = this->ValidateOneSidedPlaneForPattern(iplane, oldPattern);
03148 
03149   for(UInt_t i = 0; i<oldResult.strips.size(); i++){
03150     bool found = false;
03151     for(UInt_t ipair=0;ipair<fDeMuxedPairs[iplane].size();ipair++){
03152       Int_t istrip = fDeMuxedPairs[iplane][ipair].altListE->GetBestSEId().GetStrip();
03153       if(oldResult.strips[i]==istrip)found=true;
03154     }
03155     if(found==false){
03156       useOldResult=true;
03157       //cout << "USE OLD RESULT IS SET !!!!!!" << endl;
03158       //getchar();
03159     }
03160   }
03161 
03162 
03163   stripResult.largestContigGroup = 0;
03164   Int_t bestStrip;
03165   for(Int_t iHitStrip=1; iHitStrip<=fPlaneHit[iplane];iHitStrip++){
03166     vector<Int_t>pattern;
03167     pattern.push_back(fHitMap[iplane][iHitStrip]);
03168     PlaneValidity_t thisStripResult;
03169     if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
03170     if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
03171     if(this->ValidityComp(oldResult,thisStripResult,istripH,istripT,oneSided)){
03172       stripResult = thisStripResult;
03173       bestStrip = fHitMap[iplane][iHitStrip];
03174     }
03175   }
03176 
03177   hitResult.largestContigGroup = 0;
03178   vector<Int_t>patternH;
03179   if(fitStatusH){
03180     patternH.push_back(istripH);
03181     if(!oneSided)hitResult =  this->ValidatePlaneForPattern(iplane, patternH);
03182     if( oneSided)hitResult =  this->ValidateOneSidedPlaneForPattern(iplane, patternH);
03183   }
03184 
03185 
03186   Int_t bestMaskStrip=-1;
03187   timeMaskResult.largestContigGroup = -1;
03188   if(useTimeMask){
03189     for(Int_t iStrip=0; iStrip<=MAX_NUMBER_OF_STRIPS;iStrip++){
03190       if(fUVmask[iplane][iStrip]==true){
03191         vector<Int_t>pattern;
03192         pattern.push_back(iStrip);
03193         PlaneValidity_t thisStripResult;
03194         if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
03195         if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
03196         if(this->ValidityComp(timeMaskResult,thisStripResult,istripH,istripT,oneSided)){
03197           timeMaskResult = thisStripResult;
03198           bestMaskStrip = iStrip;
03199         }else{
03200           if(oneSided && thisStripResult.largestContigGroup==timeMaskResult.largestContigGroup){
03201             if(thisStripResult.stripSpan<=timeMaskResult.stripSpan){
03202               bestMaskStrip = iStrip;
03203               timeMaskResult = thisStripResult;
03204             }
03205           }     
03206         }
03207       }
03208     }
03209   }
03210       
03211   timeResult.largestContigGroup = 0;
03212   vector<Int_t>patternT;
03213   if(fitStatusT){
03214     patternT.push_back(istripT);
03215     if(!oneSided)timeResult =  this->ValidatePlaneForPattern(iplane, patternT);
03216     if( oneSided)timeResult =  this->ValidateOneSidedPlaneForPattern(iplane, patternT);
03217   }
03218 
03219   bool useTimeFit   = false;
03220   bool useHitFit    = false;
03221   bool useBestStrip = false;
03222   bool useTimeMaskHit  = false;
03223 
03224   if(useTimeMask){
03225     if(oneSided){
03226     }else{
03227       if(timeMaskResult.fractionQE>0.25 && timeMaskResult.fractionQW>0.25)useTimeMaskHit = true;
03228       if(timeMaskResult.chi2DQ>oldResult.chi2DQ+20.)useTimeMaskHit = false;
03229     }
03230   }
03231 
03232   if(fitStatusT){
03233     if(timeResult.largestContigGroup>oldResult.largestContigGroup){
03234       if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25||(timeResult.fractionQE>0.5&&timeResult.fractionQW>0.5))useTimeFit = true;
03235     } 
03236     if(timeResult.fractionQE<0.25||timeResult.fractionQW<0.25)useTimeFit = false;
03237     if(timeResult.chi2DQ>oldResult.chi2DQ+20.)useTimeFit = false;
03238     if(timeResult.largestContigGroup==oldResult.largestContigGroup){
03239 
03240     }
03241   }
03242 
03243   if(fitStatusH){
03244     if(hitResult.largestContigGroup>oldResult.largestContigGroup){
03245       if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25||(hitResult.fractionQE>0.5&&hitResult.fractionQW>0.5))useHitFit = true;
03246     } 
03247     if(hitResult.largestContigGroup>=oldResult.largestContigGroup){
03248       if(hitResult.fractionQE>0.75&&hitResult.fractionQW>0.75&&(hitResult.chi2DQ+20.0<oldResult.chi2DQ))useHitFit = true;
03249     }
03250 
03251     if(hitResult.fractionQE<0.25||hitResult.fractionQW<0.25)useHitFit = false;
03252     if(hitResult.chi2DQ>oldResult.chi2DQ+20.)useHitFit = false;
03253     if(hitResult.largestContigGroup>oldResult.largestContigGroup){
03254       if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25&&(hitResult.fractionQE>0.5&&hitResult.fractionQW>0.5))useHitFit = true;
03255     } 
03256   }
03257 
03258   if(stripResult.largestContigGroup>oldResult.largestContigGroup){
03259     if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25||(stripResult.fractionQE>0.5&&stripResult.fractionQW>0.5))useBestStrip = true;
03260     if(stripResult.chi2DQ>oldResult.chi2DQ+20.)useBestStrip = false;
03261   } 
03262 
03263   if(oneSided){
03264     if(fitStatusT)useTimeFit = true;
03265     if(fitStatusH)useHitFit = true;
03266     useBestStrip= true;
03267   }
03268  
03269   // NOW HAVE ALL VALIDATE PATTERNS and BEST in each TYPE
03270   // Decide which to use
03271 
03272 
03273   if(useHitFit){
03274     //amWriting = true;
03275     //    if(!found)this->ValidatePlaneForPattern(iplane, oldPattern);
03276     found = true;
03277     if(amWriting)cout  << " ALERT **HITS** " << endl; 
03278     //this->ValidatePlaneForPattern(iplane, patternH);
03279     found = true;
03280     if(hitResult.largestContigGroup>=timeResult.largestContigGroup&&
03281        hitResult.largestContigGroup>=stripResult.largestContigGroup){
03282       if(!oneSided)this->ReMuxPlane(iplane, patternH);
03283       if( oneSided)this->ReMuxSingleSidedPlane(iplane, patternH);
03284     }
03285   }
03286 
03287   if(useBestStrip){
03288     //amWriting = true;
03289     //if(!found)this->ValidatePlaneForPattern(iplane, oldPattern);
03290     found = true;
03291     if(amWriting)cout  << " ALERT **BEST** " << bestStrip << endl; 
03292     vector<Int_t>pattern;
03293     pattern.push_back(bestStrip);
03294     //this->ValidatePlaneForPattern(iplane, pattern);
03295     found = true;
03296     if(stripResult.largestContigGroup>=timeResult.largestContigGroup&&
03297        stripResult.largestContigGroup>hitResult.largestContigGroup){
03298       if(!oneSided)this->ReMuxPlane(iplane, pattern);
03299       if( oneSided)this->ReMuxSingleSidedPlane(iplane, pattern);
03300     }
03301   }
03302 
03303   if(useTimeFit){
03304     //amWriting = true;
03305     //if(!found)this->ValidatePlaneForPattern(iplane, oldPattern);
03306     found = true;
03307     if(amWriting)cout  << " ALERT **TIME** " << endl; 
03308     //this->ValidatePlaneForPattern(iplane, patternT);
03309     found = true;
03310     if(timeResult.largestContigGroup>hitResult.largestContigGroup&&
03311        timeResult.largestContigGroup>stripResult.largestContigGroup){
03312       if(!oneSided)this->ReMuxPlane(iplane, patternT);
03313       if( oneSided)this->ReMuxSingleSidedPlane(iplane, patternT);
03314     }
03315   }
03316 
03317 
03318 
03319   if(useTimeMaskHit){
03320     //amWriting = true;
03321     //if(!found)this->ValidatePlaneForPattern(iplane, oldPattern);
03322     if(amWriting)cout  << " ALERT ** TIME MASK !!!!!! ** " << bestMaskStrip << endl; 
03323     vector<Int_t>pattern;
03324     pattern.push_back(bestMaskStrip);
03325     found = true;
03326     if(amWriting)cout << "TM : " << timeMaskResult.largestContigGroup << "   H : " << hitResult.largestContigGroup << endl;
03327     if(timeMaskResult.largestContigGroup>hitResult.largestContigGroup){
03328       if(!oneSided)this->ReMuxPlane(iplane, pattern);
03329       if( oneSided){
03330         cout << "1 Sided Time Mask ReMux : " << timeMaskResult.largestContigGroup << endl;
03331         if(timeMaskResult.largestContigGroup>1){
03332           this->ReMuxSingleSidedPlane(iplane, pattern);
03333         }
03334       }
03335     }
03336     if(timeMaskResult.largestContigGroup==oldResult.largestContigGroup){
03337       if(!oneSided){
03338         if((timeMaskResult.fractionQE+timeMaskResult.fractionQW>
03339             oldResult.fractionQE+oldResult.fractionQW)  ||
03340            (timeMaskResult.chi2DQ+5.0<oldResult.chi2DQ))this->ReMuxPlane(iplane, pattern);
03341       }
03342       if(oneSided){
03343         if(timeMaskResult.largestContigGroup>1){
03344           this->ReMuxSingleSidedPlane(iplane, pattern);
03345             if(amWriting)cout << "One Sided Time Mask ReMux : " << timeMaskResult.largestContigGroup << endl;
03346         }
03347       }
03348     }
03349   }  
03350 
03351   returnFlag = found;
03352 
03353   amWriting = false;
03354   return returnFlag;
03355 }
03356 
03357 
03358 
03359 
03360 bool AlgAltDeMuxBase::ValidityComp(PlaneValidity_t currentValidity, PlaneValidity_t newValidity, int istripH, int istripT, bool onesided){
03361 
03362   bool spoton=false;
03363   if(istripH==istripT)spoton=true;
03364   if(onesided)spoton=false;
03365 
03366   if(newValidity.largestContigGroup>currentValidity.largestContigGroup)return true;
03367 
03368   if(newValidity.largestContigGroup==currentValidity.largestContigGroup){
03369     if((currentValidity.fractionQE<0.25||currentValidity.fractionQW<0.25)&&(newValidity.fractionQE>0.5&&newValidity.fractionQW>0.5))return true;
03370     if(currentValidity.chi2DQ-newValidity.chi2DQ>10)return true;
03371     if(fFitQHitU.status){
03372       if(fabs(newValidity.centroid-istripH)<fabs(currentValidity.centroid-istripH))return true;
03373     }
03374   }  
03375   
03376   return false;
03377 }
03378 
03379 
03380 
03381 bool AlgAltDeMuxBase::BestGuessForPlane(Int_t iplane, bool doSingleSided){
03382 
03383   if(fPlaneHit[iplane]!=0)return false;
03384 
03385   Int_t easthits = fDeMuxedPlanesAltLists[iplane][ALG_EAST].size()+
03386     fPlanesAltLists[iplane][ALG_EAST].size();
03387   Int_t westhits = fDeMuxedPlanesAltLists[iplane][ALG_WEST].size()+
03388     fPlanesAltLists[iplane][ALG_WEST].size();
03389 
03390   if(fDiagnosticPlots){
03391     if(amWriting)cout << "*****************************************************************  PLANE : " << iplane << endl;
03392     if(amWriting)cout << "ew : " << easthits << ":" << westhits << endl;
03393   }
03394 
03395   bool oneSided = false;
03396   if(easthits==0||westhits==0){
03397     if(easthits>0||westhits>0)oneSided = true;
03398   }
03399 
03400   if(oneSided && !doSingleSided)return false;
03401 
03402   bool returnFlag = false;
03403   bool found = false;
03404 
03405   PlaneValidity_t timeMaskResult;
03406   timeMaskResult.largestContigGroup = -1;
03407   timeMaskResult.stripSpan          = 0;
03408   timeMaskResult.centroid           = 0.;
03409   timeMaskResult.chi2DQ             = 99999.;
03410   timeMaskResult.fractionQE = 0.;
03411   timeMaskResult.fractionQW = 0.;
03412 
03413   Int_t bestMaskStrip=-1;
03414 
03415   for(Int_t iStrip=0; iStrip<=MAX_NUMBER_OF_STRIPS;iStrip++){
03416     if(fUVmask[iplane][iStrip]==true){
03417       vector<Int_t>pattern;
03418       if(amWriting)cout << "TIMING MASK : " << iStrip << endl;
03419       pattern.push_back(iStrip);
03420       PlaneValidity_t thisStripResult;
03421       if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
03422       if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
03423       if(thisStripResult.largestContigGroup>timeMaskResult.largestContigGroup){
03424         timeMaskResult = thisStripResult;
03425         bestMaskStrip = iStrip;
03426       }
03427       if(thisStripResult.largestContigGroup==timeMaskResult.largestContigGroup){
03428         if(oneSided){
03429           if(thisStripResult.stripSpan<=timeMaskResult.stripSpan){
03430             bestMaskStrip = iStrip;
03431             timeMaskResult = thisStripResult;
03432           }
03433         }else{
03434           if( (thisStripResult.fractionQE+thisStripResult.fractionQW)>
03435               (timeMaskResult.fractionQE+timeMaskResult.fractionQW) ){
03436             if(thisStripResult.chi2DQ<timeMaskResult.chi2DQ+10.){
03437               bestMaskStrip = iStrip;
03438               timeMaskResult = thisStripResult;
03439             }
03440           }
03441         }
03442       }
03443     }
03444   }
03445 
03446 
03447   if(timeMaskResult.largestContigGroup>0){
03448     vector<Int_t>pattern;
03449     pattern.push_back(bestMaskStrip);
03450     if(!oneSided)this->ReMuxPlane(iplane, pattern);
03451     if( oneSided){
03452       if(timeMaskResult.largestContigGroup>1){
03453         this->ReMuxSingleSidedPlane(iplane, pattern);
03454       }
03455     }
03456     return true;
03457   }
03458   
03459       
03460   for(Int_t iStrip=0; iStrip<=MAX_NUMBER_OF_STRIPS;iStrip++){
03461     vector<Int_t>pattern;
03462     pattern.push_back(iStrip);
03463     PlaneValidity_t thisStripResult;
03464     if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
03465     if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
03466     if(thisStripResult.largestContigGroup>timeMaskResult.largestContigGroup){
03467       timeMaskResult = thisStripResult;
03468       bestMaskStrip = iStrip;
03469     }
03470     if(thisStripResult.largestContigGroup==timeMaskResult.largestContigGroup){
03471       if(oneSided){
03472         if(thisStripResult.stripSpan<=timeMaskResult.stripSpan){
03473           bestMaskStrip = iStrip;
03474           timeMaskResult = thisStripResult;
03475         }
03476       }else{
03477         if( (thisStripResult.fractionQE+thisStripResult.fractionQW)>
03478             (timeMaskResult.fractionQE+timeMaskResult.fractionQW) ){
03479           if(thisStripResult.chi2DQ<timeMaskResult.chi2DQ+10.){
03480             bestMaskStrip = iStrip;
03481             timeMaskResult = thisStripResult;
03482           }
03483         }
03484       }
03485     }
03486   }
03487       
03488   returnFlag = found;
03489 
03490   if(timeMaskResult.largestContigGroup>0){
03491     vector<Int_t>pattern;
03492     pattern.push_back(bestMaskStrip);
03493     if(!oneSided)this->ReMuxPlane(iplane, pattern);
03494     if( oneSided){
03495       if(timeMaskResult.largestContigGroup>1){
03496         this->ReMuxSingleSidedPlane(iplane, pattern);
03497       }
03498     }
03499   }
03500   
03501   return returnFlag;
03502 }
03503 
03504 
03505 
03506 
03507 
03508 
03509 bool AlgAltDeMuxBase::BestGuessForSingleSidedHits(Int_t iplane){
03510 
03511   vector <PlexSEIdAltL*>::iterator literA;
03512 
03513   //  if(fPlaneHit[iplane]!=0)return false;
03514   
03515   Int_t Nm =0;
03516   Int_t Np =0;
03517   Float_t wm = 0.0;
03518   Float_t wp = 0.0;
03519      
03520   for(Int_t iStrip=0; iStrip<=MAX_NUMBER_OF_STRIPS;iStrip++){
03521     if(iplane>1){
03522       if(fTimingMask[iplane-1][iStrip]){
03523         wm+= iStrip;
03524         Nm++;
03525       }
03526     }
03527     if(iplane<MAX_NUMBER_OF_PLANES-2){
03528       if(fTimingMask[iplane+1][iStrip]){
03529         wp+= iStrip;
03530         Np++;
03531       }
03532     }
03533   }
03534   
03535   Float_t target = 0.;
03536   if(Nm==0&&Np==0){
03537     for(Int_t jplane=iplane;jplane<500 && jplane<iplane+11;jplane+=2){
03538       Int_t easthits = fDeMuxedPlanesAltLists[jplane][ALG_EAST].size();
03539       Int_t westhits = fDeMuxedPlanesAltLists[jplane][ALG_WEST].size();
03540       for(Int_t iE=0;iE<easthits;iE++){
03541         wp += fDeMuxedPlanesAltLists[jplane][ALG_EAST][iE]->GetBestSEId().GetStrip();
03542         Np++;
03543       }
03544       for(Int_t iW=0;iW<westhits;iW++){
03545         wp += fDeMuxedPlanesAltLists[jplane][ALG_WEST][iW]->GetBestSEId().GetStrip();
03546         Np++;
03547       }
03548     }
03549 
03550     for(Int_t jplane=iplane-2;jplane>0 && jplane >iplane-11;jplane-=2){
03551       Int_t easthits = fDeMuxedPlanesAltLists[jplane][ALG_EAST].size();
03552       Int_t westhits = fDeMuxedPlanesAltLists[jplane][ALG_WEST].size();
03553       for(Int_t iE=0;iE<easthits;iE++){
03554         wm += fDeMuxedPlanesAltLists[jplane][ALG_EAST][iE]->GetBestSEId().GetStrip();
03555         Nm++;
03556       }
03557       for(Int_t iW=0;iW<westhits;iW++){
03558         wm += fDeMuxedPlanesAltLists[jplane][ALG_WEST][iW]->GetBestSEId().GetStrip();
03559         Nm++;
03560       }
03561     }
03562 
03563 
03564   }
03565   if(Nm==0&&Np==0)return false;
03566 
03567   if(Nm==0&&Np>0)target =  wp/static_cast<Float_t>(Np);
03568   if(Np==0&&Nm>0)target =  wm/static_cast<Float_t>(Nm);
03569   if(Np>0&&Nm>0)target =  (wm/static_cast<Float_t>(Nm) + wp/static_cast<Float_t>(Np))/2.0;
03570 
03571   for(Int_t iew=ALG_EAST;iew<=ALG_WEST;iew++){
03572     if(fPlanesAltLists[iplane][iew].size()>0){
03573       while (fPlanesAltLists[iplane][iew].size()>0){
03574         Int_t sbest =0;
03575         Float_t closeness = 999;
03576         literA = fPlanesAltLists[iplane][iew].begin();
03577         (*literA)->SetFirst();
03578         while( (*literA)->IsValid() ){
03579           Int_t s = (*literA)->GetCurrentSEId().GetStrip();
03580           if(fabs(target-s)<closeness){
03581             closeness = fabs(target-s);
03582             sbest = s;
03583           }                     
03584           (*literA)->Next();
03585         }
03586         if(closeness<999){
03587           if(iew==ALG_EAST)this->DeMuxSingleHitE(iplane,*literA, sbest);
03588           if(iew==ALG_WEST)this->DeMuxSingleHitW(iplane,*literA, sbest);
03589         }
03590       }
03591     }
03592   }
03593   
03594   return true;
03595 }
03596 
03597 
03598 
03599 
03600 
03601 
03602 
03603 bool AlgAltDeMuxBase::ValidateContainedCandidateEndPlane(Int_t iplane){
03604   if(fPlaneHit[iplane]==0)return false;
03605   bool useTimeMask = true;
03606   Int_t iLowHit = 999;
03607 
03608   if(fEventType==MULTIPLE_MUON){
03609     MSG("AltDeMux", Msg::kWarning) << "AlgAltDeMuxBase::ValidateContainedCandidateEndPlane does nothandle Multiple Muons" << endl; 
03610     return false;
03611   }
03612 
03613   Int_t easthits = fDeMuxedPlanesAltLists[iplane][ALG_EAST].size()+
03614     fPlanesAltLists[iplane][ALG_EAST].size();
03615   Int_t westhits = fDeMuxedPlanesAltLists[iplane][ALG_WEST].size()+
03616     fPlanesAltLists[iplane][ALG_WEST].size();
03617 
03618   if(fDiagnosticPlots){
03619     if(amWriting)cout << "*****************************************************************  PLANE : " << iplane << endl;
03620     if(amWriting)cout << "ew : " << easthits << ":" << westhits << endl;
03621   }
03622 
03623   bool oneSided = false;
03624   if(easthits==0||westhits==0){
03625     if(easthits>0||westhits>0)oneSided = true;
03626   }
03627 
03628   PlaneValidity_t timeMaskResult;
03629   timeMaskResult.largestContigGroup = -1;
03630   timeMaskResult.stripSpan          = 0;
03631   timeMaskResult.centroid           = 0.;
03632   timeMaskResult.chi2DQ             = 99999.;
03633   timeMaskResult.fractionQE = 0.;
03634   timeMaskResult.fractionQW = 0.;
03635 
03636   PlaneValidity_t oldResult;
03637 
03638   vector<Int_t>oldPattern;
03639   for(Int_t iHitStrip=1; iHitStrip<=fPlaneHit[iplane];iHitStrip++){
03640     if(fHitMap[iplane][iHitStrip]<iLowHit)iLowHit = fHitMap[iplane][iHitStrip]; 
03641     oldPattern.push_back(fHitMap[iplane][iHitStrip]);
03642   }
03643   if(!oneSided)oldResult = this->ValidatePlaneForPattern(iplane, oldPattern);
03644   if( oneSided)oldResult = this->ValidateOneSidedPlaneForPattern(iplane, oldPattern);
03645 
03646   Int_t bestMaskStrip=-1;
03647   if(useTimeMask){
03648     for(Int_t iStrip=iLowHit; iStrip<=MAX_NUMBER_OF_STRIPS;iStrip++){
03649       if(fUVmask[iplane][iStrip]==true){
03650         vector<Int_t>pattern;
03651         pattern.push_back(iStrip);
03652         PlaneValidity_t thisStripResult;
03653         if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
03654         if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
03655         if(thisStripResult.largestContigGroup>timeMaskResult.largestContigGroup){
03656           timeMaskResult = thisStripResult;
03657           bestMaskStrip = iStrip;
03658         }
03659         if(thisStripResult.largestContigGroup==timeMaskResult.largestContigGroup){
03660           if(oneSided){
03661             if(thisStripResult.stripSpan<=timeMaskResult.stripSpan){
03662               bestMaskStrip = iStrip;
03663               timeMaskResult = thisStripResult;
03664             }
03665           }else{
03666             if((timeMaskResult.fractionQE<0.25||timeMaskResult.fractionQW<0.25)&&(thisStripResult.fractionQE>0.5&&thisStripResult.fractionQW>0.5)){
03667               if(thisStripResult.chi2DQ<timeMaskResult.chi2DQ+10.){
03668                 bestMaskStrip = iStrip;
03669                 timeMaskResult = thisStripResult;
03670               }
03671             }
03672             if((timeMaskResult.fractionQE<0.25||timeMaskResult.fractionQW<0.25)&&(thisStripResult.fractionQE>0.5||thisStripResult.fractionQW>0.5)){
03673               if(thisStripResult.chi2DQ<timeMaskResult.chi2DQ+5.){
03674                 bestMaskStrip = iStrip;
03675                 timeMaskResult = thisStripResult;
03676               }
03677             }
03678 
03679           }
03680         }
03681         if(thisStripResult.largestContigGroup>=oldResult.largestContigGroup){
03682           if(amWriting)cout << "TIMING MASK : " << iStrip << endl;
03683           if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
03684           if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
03685         }
03686       }
03687     }
03688   }
03689       
03690   bool useTimeMaskHit  = false;
03691 
03692   if(useTimeMask){
03693     if(oneSided){
03694     }else{
03695       if(timeMaskResult.fractionQE>0.25 && timeMaskResult.fractionQW>0.25)useTimeMaskHit = true;
03696     }
03697   }
03698 
03699   bool found = false;
03700 
03701   if(useTimeMaskHit){
03702     //amWriting = true;
03703     //if(!found)this->ValidatePlaneForPattern(iplane, oldPattern);
03704     if(amWriting)cout  << " ALERT ** TIME MASK !!!!!! ** " << bestMaskStrip << endl; 
03705     vector<Int_t>pattern;
03706     pattern.push_back(bestMaskStrip);
03707     found = true;
03708     if(amWriting)cout << "TM : " << timeMaskResult.largestContigGroup << "   H : " << oldResult.largestContigGroup << endl;
03709     if(timeMaskResult.largestContigGroup>oldResult.largestContigGroup){
03710       if(!oneSided)this->ReMuxPlane(iplane, pattern);
03711       if( oneSided){
03712         cout << "1 Sided Time Mask ReMux : " << timeMaskResult.largestContigGroup << endl;
03713         if(timeMaskResult.largestContigGroup>1){
03714           this->ReMuxSingleSidedPlane(iplane, pattern);
03715         }
03716       }
03717     }
03718     if(timeMaskResult.largestContigGroup==oldResult.largestContigGroup){
03719       if(!oneSided){
03720         if((timeMaskResult.fractionQE+timeMaskResult.fractionQW>
03721             oldResult.fractionQE+oldResult.fractionQW)  ||
03722            (timeMaskResult.chi2DQ+5.0<oldResult.chi2DQ))this->ReMuxPlane(iplane, pattern);
03723       }
03724       if(oneSided){
03725         if(timeMaskResult.largestContigGroup>1){
03726           this->ReMuxSingleSidedPlane(iplane, pattern);
03727           if(amWriting)cout << "One Sided Time Mask ReMux : " << timeMaskResult.largestContigGroup << endl;
03728         }
03729       }
03730     }
03731   }  
03732 
03733   bool returnFlag = found;
03734 
03735   return returnFlag;
03736 }
03737 
03738 
03739 
03740 
03741 bool AlgAltDeMuxBase::ValidatePlaneAgainstTarget(Int_t iplane, Int_t targetStrip){
03742 
03743 
03744   vector <PlexSEIdAltL*>::iterator literA;
03745 
03746   bool returnFlag = false;
03747 
03748   if(fPlaneHit[iplane]==0)return false;
03749 
03750   if(fEventType==MULTIPLE_MUON){
03751     MSG("AltDeMux", Msg::kWarning) << "AlgAltDeMuxBase::ValidateContainedCandidateEndPlane does nothandle Multiple Muons" << endl; 
03752     return false;
03753   }
03754 
03755   Int_t easthits = fDeMuxedPlanesAltLists[iplane][ALG_EAST].size()+
03756     fPlanesAltLists[iplane][ALG_EAST].size();
03757 
03758   Int_t westhits = fDeMuxedPlanesAltLists[iplane][ALG_WEST].size()+
03759     fPlanesAltLists[iplane][ALG_WEST].size();
03760 
03761   bool oneSided = false;
03762   if(easthits==0||westhits==0){
03763     if(easthits>0||westhits>0)oneSided = true;
03764   }
03765 
03766   if(oneSided)return false;
03767 
03768   PlaneValidity_t oldResult;
03769   vector<Int_t>oldPattern;
03770   for(Int_t iHitStrip=1; iHitStrip<=fPlaneHit[iplane];iHitStrip++){
03771     oldPattern.push_back(fHitMap[iplane][iHitStrip]);
03772   }
03773 
03774   PlaneValidity_t targetResult;
03775   vector<Int_t>pattern;
03776   pattern.push_back(targetStrip);
03777   PlaneValidity_t thisStripResult;
03778 
03779   if(!oneSided){
03780     oldResult = this->ValidatePlaneForPattern(iplane, oldPattern);
03781     targetResult = this->ValidatePlaneForPattern(iplane, pattern);
03782   }else{
03783     oldResult = this->ValidateOneSidedPlaneForPattern(iplane, oldPattern);
03784     targetResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
03785   }
03786 
03787   bool remux = false;
03788   if(targetResult.largestContigGroup>oldResult.largestContigGroup){
03789     if(targetResult.chi2DQ<oldResult.chi2DQ+10)remux=true;
03790     if(targetResult.chi2DQ<oldResult.chi2DQ+20&&targetResult.fractionQE>oldResult.fractionQE&&targetResult.fractionQW>oldResult.fractionQW )remux=true;
03791   }
03792 
03793   if(targetResult.largestContigGroup==oldResult.largestContigGroup){
03794     int excold = 0;
03795     int excnew = 0;
03796     int oldnew = 0;
03797     for(unsigned int i=0;i<targetResult.strips.size();i++){
03798       bool found=false;
03799       for(unsigned int j=0;j<oldResult.strips.size();j++){
03800         if(targetResult.strips[i]==oldResult.strips[j])found= true;
03801       }
03802       if(found)oldnew++;
03803       if(!found)excnew++;
03804     }
03805     for(unsigned int i=0;i<oldResult.strips.size();i++){
03806       bool found=false;
03807       for(unsigned int j=0;j<targetResult.strips.size();j++){
03808         if(oldResult.strips[i]==targetResult.strips[j])found= true;
03809       }
03810       if(!found)excold++;
03811     }
03812 
03813     if(excold>0||excnew>0){
03814       if(excnew>0&&excold==0)remux=true;
03815       if(excnew>0&&excold>0){
03816         float points = 0;
03817         points+= (targetResult.fractionQE-oldResult.fractionQE)/0.1;
03818         points+= (targetResult.fractionQW-oldResult.fractionQW)/0.1;
03819         points-= (targetResult.stripSpan-oldResult.stripSpan)/5.;
03820         points-= (targetResult.chi2DQ-oldResult.chi2DQ)/5.;
03821         if(points>2)remux=true;
03822       }
03823     }
03824   }
03825 
03826   if(remux){
03827     this->ReMuxPlane(iplane, pattern);
03828     for(Int_t iew=ALG_EAST;iew<=ALG_WEST;iew++){
03829       while (fPlanesAltLists[iplane][iew].size()>0){
03830         int sbest =0;
03831         int closeness = 999;
03832         literA = fPlanesAltLists[iplane][iew].begin();
03833         (*literA)->SetFirst();
03834         while( (*literA)->IsValid() ){
03835           int s = (*literA)->GetCurrentSEId().GetStrip();
03836           for(unsigned int t=0;t<pattern.size();t++){
03837             if(abs(pattern[t]-s)<closeness){
03838               closeness = abs(pattern[t]-s);
03839               sbest = s;                        
03840             }
03841           }
03842           (*literA)->Next();
03843         }
03844         if(closeness<999){
03845           if(iew==ALG_EAST)this->DeMuxSingleHitE(iplane,*literA, sbest);
03846           if(iew==ALG_WEST)this->DeMuxSingleHitW(iplane,*literA, sbest);
03847         }
03848       }
03849     }
03850   }
03851 
03852   if(remux)returnFlag=true;
03853 
03854   return returnFlag;
03855 }
03856 
03857 
03858 
03859 bool AlgAltDeMuxBase::ValidateContainedCandidateEndPlanes(){
03860 
03861   bool changed = false;
03862 
03863   Int_t doWhat[MAX_NUMBER_OF_PLANES];
03864   const Int_t DO_NOTHING=0;
03865   const Int_t DO_LOOK_ABOVE=1;
03866   //  const Int_t DO_LOOK_BELOW=2;
03867 
03868   for(Int_t i=0; i<MAX_NUMBER_OF_PLANES;i++){
03869     doWhat[i]=DO_NOTHING;
03870   } 
03871   
03872 
03873   if(amWriting){
03874     cout << " Low/High " << fLowestPlane << ":" << fHighestPlane << endl;
03875     cout << " HighCC   " << fCCHighestPlane << endl;
03876     cout << " NearCC   " << fCCNearestPlane << endl;
03877   }
03878 
03879   Int_t eventLowPlane  = fCCHighestPlane;
03880   Int_t eventHighPlane = fCCHighestPlane;
03881   Int_t nGap = 0;
03882   bool  done = false;
03883   for(Int_t iplane=fCCHighestPlane; !done && iplane<MAX_NUMBER_OF_PLANES; iplane++){
03884     if(fPlaneHit[iplane]>0){
03885       eventHighPlane = iplane;
03886       nGap = 0;
03887     }
03888     if(fPlaneHit[iplane]==0)nGap++;
03889     if(nGap>=3)done=true;
03890   }
03891   nGap = 0;
03892   done = false;
03893   for(Int_t iplane=fCCHighestPlane; !done && iplane>=0; iplane--){
03894     if(fPlaneHit[iplane]>0){
03895       eventLowPlane = iplane;
03896       nGap = 0;
03897     }
03898     if(fPlaneHit[iplane]==0)nGap++;
03899     if(nGap>=3)done=true;
03900   }
03901 
03902   if(amWriting){
03903     cout << " HighEvent " << eventHighPlane << endl;
03904     cout << " LowEvent  " << eventLowPlane << endl;
03905   }
03906 
03907   bool foundU = false;
03908   bool foundV = false;
03909   if( abs(eventHighPlane-fCCHighestPlane)<abs(eventLowPlane-fCCHighestPlane)){
03910     for(Int_t iplane=fCCHighestPlane+5; iplane>=fCCHighestPlane-5;iplane--){
03911       if(fUVMap[iplane]==PlaneView::kU){
03912         if(!foundU && (fPlaneHit[iplane]>0) ){
03913           doWhat[iplane] = DO_LOOK_ABOVE;
03914           if(fDeMuxedPairs[iplane].size()>0)foundU=true;
03915           if(amWriting)cout << "Need to check U plane : " << iplane << endl;
03916         } 
03917       }
03918       if(fUVMap[iplane]==PlaneView::kV){
03919         if(!foundV && (fPlaneHit[iplane]>0)){
03920           doWhat[iplane] = DO_LOOK_ABOVE;
03921           if(fDeMuxedPairs[iplane].size()>0)foundV=true;
03922           if(amWriting)cout << "Need to check V plane : " << iplane << endl;
03923         } 
03924       }
03925     }
03926   }else{
03927     for(Int_t iplane=fCCHighestPlane-5; iplane<=fCCHighestPlane+5;iplane++){
03928       if(fUVMap[iplane]==PlaneView::kU){
03929         if(!foundU && (fPlaneHit[iplane]>0) ){
03930           doWhat[iplane] = DO_LOOK_ABOVE;
03931           if(fDeMuxedPairs[iplane].size()>0)foundU=true;
03932           if(amWriting)cout << "Need to check U plane : " << iplane << endl;
03933         } 
03934       }
03935       if(fUVMap[iplane]==PlaneView::kV){
03936         if(!foundV && (fPlaneHit[iplane]>0)){
03937           doWhat[iplane] = DO_LOOK_ABOVE;
03938           if(fDeMuxedPairs[iplane].size()>0)foundV=true;
03939           if(amWriting)cout << "Need to check V plane : " << iplane << endl;
03940         } 
03941       }
03942     }
03943   }
03944 
03945   changed = false;
03946   for(Int_t i=0; i<MAX_NUMBER_OF_PLANES;i++){
03947     if(doWhat[i]!=DO_NOTHING){
03948       //      cout << " Validating Plane : " << i << endl;
03949       bool thisPlaneChanged = ValidateContainedCandidateEndPlane(i);
03950       changed = changed || thisPlaneChanged;
03951     }
03952   }
03953 
03954   return changed;
03955 }
03956 
03957 
03958 void AlgAltDeMuxBase::MakeMultipleTargets(Int_t iplane){
03959 
03960   fTargetStrips.erase(fTargetStrips.begin(),fTargetStrips.end());
03961 
03962   Int_t jplane = iplane;
03963   if(iplane>248)jplane+=20;
03964   if(fUVMap[iplane]==PlaneView::kU){
03965     for(UInt_t iline=0; iline<multipleMuonInterceptsU.size();iline++){
03966       Float_t rtarget = fHoughSlopeU*jplane + multipleMuonInterceptsU[iline];
03967       Int_t itarget = static_cast<Int_t>(rtarget);
03968       if(itarget<198&&itarget>-10){
03969         if(itarget>190)itarget=191;
03970         if(itarget<0)itarget=0;
03971         fTargetStrips.push_back(itarget);
03972       }
03973     }
03974   }
03975   if(fUVMap[iplane]==PlaneView::kV){
03976     for(UInt_t iline=0; iline<multipleMuonInterceptsV.size();iline++){
03977       Float_t rtarget = fHoughSlopeV*jplane + multipleMuonInterceptsV[iline];
03978       Int_t itarget = static_cast<Int_t>(rtarget);
03979       if(itarget<198&&itarget>-10){
03980         if(itarget>190)itarget=191;
03981         if(itarget<0)itarget=0;
03982         fTargetStrips.push_back(itarget);
03983       }
03984     }
03985   }
03986 
03987   return;
03988 }
03989 
03990 
03991 
03992 
03993 bool AlgAltDeMuxBase::ValidateCCEndPlanes(){
03994 
03995 
03996   //amWriting=true;
03997   bool changed = false;
03998 
03999   Int_t doWhat[MAX_NUMBER_OF_PLANES];
04000   const Int_t DO_NOTHING=0;
04001   const Int_t DO_LOOK_ABOVE=1;
04002   //  const Int_t DO_LOOK_BELOW=2;
04003 
04004   for(Int_t i=0; i<MAX_NUMBER_OF_PLANES;i++){
04005     doWhat[i]=DO_NOTHING;
04006   } 
04007   
04008 
04009   if(amWriting){
04010     cout << " Low/High " << fLowestPlane << ":" << fHighestPlane << endl;
04011     cout << " HighCC   " << fCCHighestPlane << endl;
04012     cout << " NearCC   " << fCCNearestPlane << endl;
04013   }
04014 
04015   Int_t eventLowPlane  = fCCHighestPlane;
04016   Int_t eventHighPlane = fCCHighestPlane;
04017   Int_t nGap = 0;
04018   bool  done = false;
04019   for(Int_t iplane=fCCHighestPlane; !done && iplane<MAX_NUMBER_OF_PLANES; iplane++){
04020     if(fPlaneHit[iplane]>0){
04021       eventHighPlane = iplane;
04022       nGap = 0;
04023     }
04024     if(fPlaneHit[iplane]==0)nGap++;
04025     if(nGap>=3)done=true;
04026   }
04027   nGap = 0;
04028   done = false;
04029   for(Int_t iplane=fCCHighestPlane; !done && iplane>=0; iplane--){
04030     if(fPlaneHit[iplane]>0){
04031       eventLowPlane = iplane;
04032       nGap = 0;
04033     }
04034     if(fPlaneHit[iplane]==0)nGap++;
04035     if(nGap>=3)done=true;
04036   }
04037 
04038   if(amWriting){
04039     cout << " HighEvent " << eventHighPlane << endl;
04040     cout << " LowEvent  " << eventLowPlane << endl;
04041   }
04042 
04043   bool foundU = false;
04044   bool foundV = false;
04045   if( abs(eventHighPlane-fCCHighestPlane)<abs(eventLowPlane-fCCHighestPlane)){
04046     for(Int_t iplane=fCCHighestPlane+5; iplane>=fCCHighestPlane-5;iplane--){
04047       if(fUVMap[iplane]==PlaneView::kU){
04048         if(!foundU && (fPlaneHit[iplane]>0) ){
04049           doWhat[iplane] = DO_LOOK_ABOVE;
04050           if(fPlaneHit[iplane-2]>0)doWhat[iplane-2] = DO_LOOK_ABOVE;
04051           if(fDeMuxedPairs[iplane].size()>0)foundU=true;
04052           if(amWriting)cout << "Need to check U plane : " << iplane << endl;
04053         } 
04054       }
04055       if(fUVMap[iplane]==PlaneView::kV){
04056         if(!foundV && (fPlaneHit[iplane]>0)){
04057           doWhat[iplane] = DO_LOOK_ABOVE;
04058           if(fPlaneHit[iplane-2]>0)doWhat[iplane-2] = DO_LOOK_ABOVE;
04059           if(fDeMuxedPairs[iplane].size()>0)foundV=true;
04060           if(amWriting)cout << "Need to check V plane : " << iplane << endl;
04061         } 
04062       }
04063     }
04064   }else{
04065     for(Int_t iplane=fCCHighestPlane-5; iplane<=fCCHighestPlane+5;iplane++){
04066       if(fUVMap[iplane]==PlaneView::kU){
04067         if(!foundU && (fPlaneHit[iplane]>0) ){
04068           doWhat[iplane] = DO_LOOK_ABOVE;
04069           if(fPlaneHit[iplane+2]>0)doWhat[iplane+2] = DO_LOOK_ABOVE;
04070           if(fDeMuxedPairs[iplane].size()>0)foundU=true;
04071           if(amWriting)cout << "Need to check U plane : " << iplane << endl;
04072         } 
04073       }
04074       if(fUVMap[iplane]==PlaneView::kV){
04075         if(!foundV && (fPlaneHit[iplane]>0)){
04076           doWhat[iplane] = DO_LOOK_ABOVE;
04077           if(fPlaneHit[iplane+2]>0)doWhat[iplane+2] = DO_LOOK_ABOVE;
04078           if(fDeMuxedPairs[iplane].size()>0)foundV=true;
04079           if(amWriting)cout << "Need to check V plane : " << iplane << endl;
04080         } 
04081       }
04082     }
04083   }
04084 
04085   changed = false;
04086   for(Int_t i=0; i<MAX_NUMBER_OF_PLANES;i++){
04087     if(doWhat[i]!=DO_NOTHING){
04088 
04089       if(fFitTimeU.status){
04090         int istripT;
04091         int istripH;
04092         int istrip;
04093         int j = i;
04094         if(j>249)j=i+20;
04095         if(fUVMap[i]==PlaneView::kU){
04096           istripT = static_cast<Int_t>(j*fFitTimeU.a1+fFitTimeU.a0);
04097           istripH = static_cast<Int_t>(j*fFitHitU.a1+fFitHitU.a0);
04098         }else{
04099           istripT = static_cast<Int_t>(j*fFitTimeV.a1+fFitTimeV.a0);
04100           istripH = static_cast<Int_t>(j*fFitHitV.a1+fFitHitV.a0);
04101         }
04102         istrip = max(istripT,istripH);
04103         if(istrip>192&&istrip<212)istrip=192;
04104         if(istrip<=MAX_NUMBER_OF_PLANES){
04105           if(amWriting)cout << " FINAL Validating Plane : " << i << " vs " << istrip << endl;
04106           bool remux = ValidatePlaneAgainstTarget(i,istrip);
04107           if(remux&&amWriting)cout << " REMUXED !!!!!!!!!!!!! " << endl;
04108         }
04109       }
04110     }
04111   }
04112 
04113   //  amWriting=false;
04114   return changed;
04115 }
04116 
04117 
04118 
04119 
04120 PlaneValidity_t AlgAltDeMuxBase::ValidatePlaneForPattern(Int_t iplane, vector<Int_t> stripPattern)
04121 { 
04122   vector <PlexSEIdAltL*>::iterator literE;
04123   vector <PlexSEIdAltL*>::iterator literW;
04124   PlexSEIdAltL* stripE[MAX_NUMBER_OF_STRIPS+1];
04125   PlexSEIdAltL* stripW[MAX_NUMBER_OF_STRIPS+1];
04126 
04127   Float_t Q = 0;
04128   PlaneValidity_t returnValidity;
04129   returnValidity.strips.erase(returnValidity.strips.begin(),returnValidity.strips.end());
04130 
04131   pCalculator->SetPlane(iplane);
04132 
04133   Float_t QTotE = 0;
04134   Float_t QTotW = 0;
04135   if(fDiagnosticPlots){
04136     if(amWriting)cout << "******HITSTIP ";
04137     for(UInt_t i=0;i<stripPattern.size();i++){
04138       if(amWriting)cout << ":" << stripPattern[i];
04139     }
04140     if(amWriting)cout << endl;
04141   }
04142   for(Int_t i=0; i<MAX_NUMBER_OF_STRIPS; i++){
04143     stripE[i] = NULL;
04144     stripW[i] = NULL;
04145   }
04146   literE = fDeMuxedPlanesAltLists[iplane][ALG_EAST].begin();
04147   while (literE != fDeMuxedPlanesAltLists[iplane][ALG_EAST].end()){
04148     Int_t delta = 999;
04149     Int_t ibest = 999;
04150     (*literE)->SetFirst();
04151     while( (*literE)->IsValid() ){
04152       Int_t iStripE = (*literE)->GetCurrentSEId().GetStrip();
04153       for(UInt_t i = 0; i<stripPattern.size(); i++){
04154         Int_t d =abs(iStripE-stripPattern[i]);
04155         if(d<delta){
04156           delta = d;
04157           ibest = iStripE;
04158           Q = pCalculator->CurrentQ(*literE);
04159         }
04160       }
04161       (*literE)->Next();
04162     }
04163     if(ibest<=MAX_NUMBER_OF_STRIPS)stripE[ibest] =  *literE;
04164     literE++;
04165     QTotE+= Q;
04166   }
04167   
04168   literE = fPlanesAltLists[iplane][ALG_EAST].begin();
04169   while (literE != fPlanesAltLists[iplane][ALG_EAST].end()){
04170     Int_t delta = 999;
04171     Int_t ibest = 999;
04172     (*literE)->SetFirst();
04173     while( (*literE)->IsValid() ){
04174       Int_t iStripE = (*literE)->GetCurrentSEId().GetStrip();
04175       for(UInt_t i = 0; i<stripPattern.size(); i++){
04176         Int_t d =abs(iStripE-stripPattern[i]);
04177         if(d<delta){
04178           delta = d;
04179           ibest = iStripE;
04180           Q = pCalculator->CurrentQ(*literE);
04181         }
04182       }
04183       (*literE)->Next();
04184     }
04185     QTotE+= Q;
04186     if(ibest<=MAX_NUMBER_OF_STRIPS)stripE[ibest] =  *literE;
04187     literE++;
04188   }
04189   
04190   literW = fDeMuxedPlanesAltLists[iplane][ALG_WEST].begin();
04191   while (literW != fDeMuxedPlanesAltLists[iplane][ALG_WEST].end()){
04192     Int_t delta = 999;
04193     Int_t ibest = 999;
04194     (*literW)->SetFirst();
04195     while( (*literW)->IsValid() ){
04196       Int_t iStripW = (*literW)->GetCurrentSEId().GetStrip();
04197       for(UInt_t i = 0; i<stripPattern.size(); i++){
04198         Int_t d =abs(iStripW-stripPattern[i]);
04199         if(d<delta){
04200           delta = d;
04201           ibest = iStripW;
04202           Q     = pCalculator->CurrentQ(*literW);
04203         }
04204       }
04205       (*literW)->Next();
04206     }
04207     if(ibest<=MAX_NUMBER_OF_STRIPS)stripW[ibest] =  *literW;
04208     literW++;
04209     QTotW+=Q;
04210   }
04211   
04212   literW = fPlanesAltLists[iplane][ALG_WEST].begin();
04213   while (literW != fPlanesAltLists[iplane][ALG_WEST].end()){
04214     Int_t delta = 999;
04215     Int_t ibest = 999;
04216     (*literW)->SetFirst();
04217     while( (*literW)->IsValid() ){
04218       Int_t iStripW = (*literW)->GetCurrentSEId().GetStrip();
04219       for(UInt_t i = 0; i<stripPattern.size(); i++){
04220         Int_t d =abs(iStripW-stripPattern[i]);
04221         if(d<delta){
04222           delta = d;
04223           ibest = iStripW;
04224           Q= pCalculator->CurrentQ(*literW);
04225         }
04226       }
04227       (*literW)->Next();
04228     }
04229     QTotW+=Q;
04230     if(ibest<=MAX_NUMBER_OF_STRIPS)stripW[ibest] =  *literW;
04231     literW++;
04232   }
04233   // Have mathched E/W : now check consistency
04234   
04235   Float_t QMatchedE=0;
04236   Float_t QMatchedW=0;
04237   Float_t chi2 =0;
04238   Int_t   lowStrip =999;
04239   Int_t   highStrip =0;
04240   Int_t   contigLow =999;
04241   Int_t   contigHigh =0;
04242   bool    contig = false;
04243   Int_t   nContigGroup = 0;
04244   Int_t   contigGroup = 0;
04245   Int_t   nInGroup = 0;
04246   Int_t   contigLast = 0;
04247 
04248   for(Int_t i = 0;i<MAX_NUMBER_OF_STRIPS; i++){
04249     if(stripE[i]!=NULL&&stripW[i]!=NULL){
04250       returnValidity.strips.push_back(i);
04251       if(i<lowStrip)lowStrip=i;
04252       highStrip=i;
04253       if(contig){
04254         if( (i-contigLast)<=2){
04255           contigLast = i;
04256           nInGroup++;
04257         }else{
04258           contig = false;
04259           contigHigh = contigLast;
04260           if(contigHigh+1-contigLow>contigGroup)contigGroup =contigHigh+1-contigLow; 
04261           if(nInGroup>nContigGroup)nContigGroup = nInGroup;
04262         }
04263       }
04264 
04265       if(!contig){
04266         nInGroup = 1;
04267         contigLow = i;
04268         contigLast = i;
04269         contig = true;
04270       }      
04271 
04272       PlaneView::PlaneView_t kView = stripE[i]->GetPlaneView();
04273       pCalculator->SetPlane(iplane);
04274       pCalculator->SetView(kView);
04275       pCalculator->SetEastToStrip(stripE[i],i);
04276       pCalculator->SetWestToStrip(stripW[i],i);
04277       pCalculator->CalcEastWest();
04278       QMatchedE += pCalculator->QSigCorE();
04279       QMatchedW += pCalculator->QSigCorW();
04280       Float_t sigmaQ = pCalculator->SigmaDQ();
04281       chi2+= sigmaQ*sigmaQ;
04282       if(amWriting)cout << " Match : " << i << " QE/W : " << pCalculator->QSigCorE() << ":"          << pCalculator->QSigCorW() << " SDQ : " << sigmaQ << endl;
04283     }
04284   }
04285   if(contig){
04286     contigHigh = contigLast;
04287     if(contigHigh+1-contigLow>contigGroup)contigGroup =contigHigh+1-contigLow; 
04288     if(nInGroup>nContigGroup)nContigGroup = nInGroup;
04289   }
04290 
04291   Float_t fracE = 0.0;
04292   if(QTotE>0.0)fracE = QMatchedE/QTotE;
04293   Float_t fracW = 0.0;
04294   if(QTotW>0.0)fracW = QMatchedW/QTotW;
04295   if(amWriting)cout << " Frac : " << fracE << "/" << fracW << " chi2 : " << chi2 <<endl;
04296 
04297   returnValidity.fractionQE = fracE;
04298   returnValidity.fractionQW = fracW;
04299   returnValidity.chi2DQ = chi2;
04300   returnValidity.largestContigGroup = nContigGroup;
04301   returnValidity.stripSpan          = highStrip-lowStrip+1;
04302   returnValidity.centroid           = (highStrip+lowStrip)/2.0;
04303 
04304   if(amWriting){
04305     cout << " SPAN          : " << returnValidity.stripSpan  << endl;
04306     cout << " Contig GROUP  : " << returnValidity.largestContigGroup  << endl;
04307     cout << " NContig GROUP : " << nContigGroup  << endl;
04308   }
04309 
04310   return returnValidity;
04311 }
04312 
04313 
04314 
04315 
04316 
04317 
04318 
04319 
04320 PlaneValidity_t AlgAltDeMuxBase::ValidateOneSidedPlaneForPattern(Int_t iplane, vector<Int_t> stripPattern)
04321 { 
04322   vector <PlexSEIdAltL*>::iterator literE;
04323   vector <PlexSEIdAltL*>::iterator literW;
04324   PlexSEIdAltL* stripE[MAX_NUMBER_OF_STRIPS];
04325   PlexSEIdAltL* stripW[MAX_NUMBER_OF_STRIPS];
04326 
04327   Float_t Q;
04328 
04329     pCalculator->SetPlane(iplane);
04330 
04331   Float_t QTotE = 0;
04332   Float_t QTotW = 0;
04333   if(amWriting){
04334     cout << "******HITSTIP ";
04335     for(UInt_t i=0;i<stripPattern.size();i++)cout << ":" << stripPattern[i];
04336     cout << endl;
04337   }
04338   for(Int_t i=0; i<MAX_NUMBER_OF_STRIPS; i++){
04339     stripE[i] = NULL;
04340     stripW[i] = NULL;
04341   }
04342 
04343 
04344   literE = fDeMuxedPlanesAltLists[iplane][ALG_EAST].begin();
04345   while (literE != fDeMuxedPlanesAltLists[iplane][ALG_EAST].end()){
04346     Int_t delta = 999;
04347     Int_t ibest = 999;
04348     (*literE)->SetFirst();
04349     while( (*literE)->IsValid() ){
04350       Int_t iStripE = (*literE)->GetCurrentSEId().GetStrip();
04351       for(UInt_t i = 0; i<stripPattern.size(); i++){
04352         Int_t d =abs(iStripE-stripPattern[i]);
04353         if(d<delta){
04354           delta = d;
04355           ibest = iStripE;
04356           Q = pCalculator->CurrentQ(*literE);
04357         }
04358       }
04359       (*literE)->Next();
04360     }
04361     stripE[ibest] =  *literE;
04362     literE++;
04363     QTotE+= Q;
04364   }
04365   
04366   literE = fPlanesAltLists[iplane][ALG_EAST].begin();
04367   while (literE != fPlanesAltLists[iplane][ALG_EAST].end()){
04368     Int_t delta = 999;
04369     Int_t ibest = 999;
04370     (*literE)->SetFirst();
04371     while( (*literE)->IsValid() ){
04372       Int_t iStripE = (*literE)->GetCurrentSEId().GetStrip();
04373       for(UInt_t i = 0; i<stripPattern.size(); i++){
04374         Int_t d =abs(iStripE-stripPattern[i]);
04375         if(d<delta){
04376           delta = d;
04377           ibest = iStripE;
04378           Q = pCalculator->CurrentQ(*literE);
04379         }
04380       }
04381       (*literE)->Next();
04382     }
04383     QTotE+= Q;
04384     stripE[ibest] =  *literE;
04385     literE++;
04386   }
04387   
04388   literW = fDeMuxedPlanesAltLists[iplane][ALG_WEST].begin();
04389   while (literW != fDeMuxedPlanesAltLists[iplane][ALG_WEST].end()){
04390     Int_t delta = 999;
04391     Int_t ibest = 999;
04392     (*literW)->SetFirst();
04393     while( (*literW)->IsValid() ){
04394       Int_t iStripW = (*literW)->GetCurrentSEId().GetStrip();
04395       for(UInt_t i = 0; i<stripPattern.size(); i++){
04396         Int_t d =abs(iStripW-stripPattern[i]);
04397         if(d<delta){
04398           delta = d;
04399           ibest = iStripW;
04400           Q     = pCalculator->CurrentQ(*literW);
04401         }
04402       }
04403       (*literW)->Next();
04404     }
04405     stripW[ibest] =  *literW;
04406     literW++;
04407     QTotW+=Q;
04408   }
04409   
04410   literW = fPlanesAltLists[iplane][ALG_WEST].begin();
04411   while (literW != fPlanesAltLists[iplane][ALG_WEST].end()){
04412     Int_t delta = 999;
04413     Int_t ibest = 999;
04414     (*literW)->SetFirst();
04415     while( (*literW)->IsValid() ){
04416       Int_t iStripW = (*literW)->GetCurrentSEId().GetStrip();
04417       for(UInt_t i = 0; i<stripPattern.size(); i++){
04418         Int_t d =abs(iStripW-stripPattern[i]);
04419         if(d<delta){
04420           delta = d;
04421           ibest = iStripW;
04422           Q= pCalculator->CurrentQ(*literW);
04423         }
04424       }
04425       (*literW)->Next();
04426     }
04427     QTotW+=Q;
04428     stripW[ibest] =  *literW;
04429     literW++;
04430   }
04431   // Have mathched E/W : now check consistency
04432   
04433   // Float_t QMatchedE=0;
04434   // Float_t QMatchedW=0;
04435   // Float_t chi2 =0;
04436   Int_t   lowStrip =999;
04437   Int_t   highStrip =0;
04438   Int_t   contigLow =999;
04439   Int_t   contigHigh =0;
04440   bool    contig = false;
04441   Int_t   nContigGroup = 0;
04442   Int_t   contigGroup = 0;
04443   Int_t   nInGroup = 0;
04444   Int_t   contigLast = 0;
04445 
04446   for(Int_t i = 0;i<MAX_NUMBER_OF_STRIPS; i++){
04447     if(stripE[i]!=NULL||stripW[i]!=NULL){
04448       if(i<lowStrip)lowStrip=i;
04449       highStrip=i;
04450       if(contig){
04451         if( (i-contigLast)<=2){
04452           contigLast = i;
04453           nInGroup++;
04454         }else{
04455           contig = false;
04456           contigHigh = contigLast;
04457           if(contigHigh+1-contigLow>contigGroup)contigGroup =contigHigh+1-contigLow; 
04458           if(nInGroup>nContigGroup)nContigGroup = nInGroup;
04459         }
04460       }
04461 
04462       if(!contig){
04463         nInGroup = 1;
04464         contigLow = i;
04465         contigLast = i;
04466         contig = true;
04467       }      
04468       if(amWriting)cout << " Match : " << i << endl;
04469     }
04470   }
04471   if(contig){
04472     contigHigh = contigLast;
04473     if(contigHigh+1-contigLow>contigGroup)contigGroup =contigHigh+1-contigLow; 
04474     if(nInGroup>nContigGroup)nContigGroup = nInGroup;
04475   }
04476   PlaneValidity_t returnValidity;
04477   returnValidity.largestContigGroup = nContigGroup;
04478   returnValidity.stripSpan          = highStrip-lowStrip+1;
04479   returnValidity.centroid           = (highStrip+lowStrip)/2.0;
04480   returnValidity.chi2DQ             = 0.;
04481   returnValidity.fractionQE = 0.;
04482   returnValidity.fractionQW = 0.;
04483 
04484 
04485   if(amWriting){
04486     cout << " SPAN          : " << returnValidity.stripSpan  << endl;
04487     cout << " Contig GROUP  : " << returnValidity.largestContigGroup  << endl;
04488     cout << " NContig GROUP : " << nContigGroup  << endl;
04489   }
04490 
04491   return returnValidity;
04492 }
04493 
04494 
04495 
04496 
04497 
04498 void AlgAltDeMuxBase::ReMuxPlane(Int_t iplane, vector<Int_t> stripPattern)
04499 { 
04500   vector <PlexSEIdAltL*>::iterator literE;
04501   vector <PlexSEIdAltL*>::iterator literW;
04502   PlexSEIdAltL* stripE[MAX_NUMBER_OF_STRIPS];
04503   PlexSEIdAltL* stripW[MAX_NUMBER_OF_STRIPS];
04504 
04505   Int_t nE=0;
04506   Int_t nW=0;
04507 
04508 
04509   for(Int_t i=0; i<MAX_NUMBER_OF_STRIPS; i++){
04510     stripE[i] = NULL;
04511     stripW[i] = NULL;
04512   }
04513   literE = fDeMuxedPlanesAltLists[iplane][ALG_EAST].begin();
04514   while (literE != fDeMuxedPlanesAltLists[iplane][ALG_EAST].end()){
04515     nE++;
04516     Int_t delta = 999;
04517     Int_t ibest = 999;
04518     (*literE)->SetFirst();
04519     while( (*literE)->IsValid() ){
04520       Int_t iStripE = (*literE)->GetCurrentSEId().GetStrip();
04521       for(UInt_t i = 0; i<stripPattern.size(); i++){
04522         Int_t d =abs(iStripE-stripPattern[i]);
04523         if(d<delta){
04524           delta = d;
04525           ibest = iStripE;
04526         }
04527       }
04528       (*literE)->Next();
04529     }
04530     stripE[ibest] =  *literE;
04531     literE++;
04532   }
04533   
04534   literE = fPlanesAltLists[iplane][ALG_EAST].begin();
04535   while (literE != fPlanesAltLists[iplane][ALG_EAST].end()){
04536     nE++;
04537     Int_t delta = 999;
04538     Int_t ibest = 999;
04539     (*literE)->SetFirst();
04540     while( (*literE)->IsValid() ){
04541       Int_t iStripE = (*literE)->GetCurrentSEId().GetStrip();
04542       for(UInt_t i = 0; i<stripPattern.size(); i++){
04543         Int_t d =abs(iStripE-stripPattern[i]);
04544         if(d<delta){
04545           delta = d;
04546           ibest = iStripE;
04547         }
04548       }
04549       (*literE)->Next();
04550     }
04551     stripE[ibest] =  *literE;
04552     literE++;
04553   }
04554   
04555   literW = fDeMuxedPlanesAltLists[iplane][ALG_WEST].begin();
04556   while (literW != fDeMuxedPlanesAltLists[iplane][ALG_WEST].end()){
04557     nW++;
04558     Int_t delta = 999;
04559     Int_t ibest = 999;
04560     (*literW)->SetFirst();
04561     while( (*literW)->IsValid() ){
04562       Int_t iStripW = (*literW)->GetCurrentSEId().GetStrip();
04563       for(UInt_t i = 0; i<stripPattern.size(); i++){
04564         Int_t d =abs(iStripW-stripPattern[i]);
04565         if(d<delta){
04566           delta = d;
04567           ibest = iStripW;
04568         }
04569       }
04570       (*literW)->Next();
04571     }
04572     stripW[ibest] =  *literW;
04573     literW++;
04574   }
04575   
04576   literW = fPlanesAltLists[iplane][ALG_WEST].begin();
04577   while (literW != fPlanesAltLists[iplane][ALG_WEST].end()){
04578     nW++;
04579     Int_t delta = 999;
04580     Int_t ibest = 999;
04581     (*literW)->SetFirst();
04582     while( (*literW)->IsValid() ){
04583       Int_t iStripW = (*literW)->GetCurrentSEId().GetStrip();
04584       for(UInt_t i = 0; i<stripPattern.size(); i++){
04585         Int_t d =abs(iStripW-stripPattern[i]);
04586         if(d<delta){
04587           delta = d;
04588           ibest = iStripW;
04589         }
04590       }
04591       (*literW)->Next();
04592     }
04593     stripW[ibest] =  *literW;
04594     literW++;
04595   }
04596   // Have matched E/W : now use pattern remux plane
04597 
04598   this->ReMuxPlane(iplane);
04599 
04600   for(Int_t i = 0;i<MAX_NUMBER_OF_STRIPS; i++){
04601     if(stripE[i]!=NULL&&stripW[i]!=NULL){
04602       this->DeMuxHits(iplane, stripE[i], stripW[i], i);
04603     }
04604   }
04605 
04606   return;
04607 }
04608 
04609 void AlgAltDeMuxBase::ReMuxSingleSidedPlane(Int_t iplane, vector<Int_t> stripPattern)
04610 { 
04611   vector <PlexSEIdAltL*>::iterator literE;
04612   vector <PlexSEIdAltL*>::iterator literW;
04613   PlexSEIdAltL* stripE[MAX_NUMBER_OF_STRIPS];
04614   PlexSEIdAltL* stripW[MAX_NUMBER_OF_STRIPS];
04615 
04616   if(amWriting)cout << " DO REMUX SINGLE HIT " << endl;
04617 
04618   for(Int_t i=0; i<MAX_NUMBER_OF_STRIPS; i++){
04619     stripE[i] = NULL;
04620     stripW[i] = NULL;
04621   }
04622   literE = fDeMuxedPlanesAltLists[iplane][ALG_EAST].begin();
04623   while (literE != fDeMuxedPlanesAltLists[iplane][ALG_EAST].end()){
04624     Int_t delta = 999;
04625     Int_t ibest = 999;
04626     (*literE)->SetFirst();
04627     while( (*literE)->IsValid() ){
04628       Int_t iStripE = (*literE)->GetCurrentSEId().GetStrip();
04629       for(UInt_t i = 0; i<stripPattern.size(); i++){
04630         Int_t d =abs(iStripE-stripPattern[i]);
04631         if(d<delta){
04632           delta = d;
04633           ibest = iStripE;
04634         }
04635       }
04636       (*literE)->Next();
04637     }
04638     stripE[ibest] =  *literE;
04639     literE++;
04640   }
04641   
04642   literE = fPlanesAltLists[iplane][ALG_EAST].begin();
04643   while (literE != fPlanesAltLists[iplane][ALG_EAST].end()){
04644     Int_t delta = 999;
04645     Int_t ibest = 999;
04646     (*literE)->SetFirst();
04647     while( (*literE)->IsValid() ){
04648       Int_t iStripE = (*literE)->GetCurrentSEId().GetStrip();
04649       for(UInt_t i = 0; i<stripPattern.size(); i++){
04650         Int_t d =abs(iStripE-stripPattern[i]);
04651         if(d<delta){
04652           delta = d;
04653           ibest = iStripE;
04654         }
04655       }
04656       (*literE)->Next();
04657     }
04658     stripE[ibest] =  *literE;
04659     literE++;
04660   }
04661   
04662   literW = fDeMuxedPlanesAltLists[iplane][ALG_WEST].begin();
04663   while (literW != fDeMuxedPlanesAltLists[iplane][ALG_WEST].end()){
04664     Int_t delta = 999;
04665     Int_t ibest = 999;
04666     (*literW)->SetFirst();
04667     while( (*literW)->IsValid() ){
04668       Int_t iStripW = (*literW)->GetCurrentSEId().GetStrip();
04669       for(UInt_t i = 0; i<stripPattern.size(); i++){
04670         Int_t d =abs(iStripW-stripPattern[i]);
04671         if(d<delta){
04672           delta = d;
04673           ibest = iStripW;
04674         }
04675       }
04676       (*literW)->Next();
04677     }
04678     stripW[ibest] =  *literW;
04679     literW++;
04680   }
04681   
04682   literW = fPlanesAltLists[iplane][ALG_WEST].begin();
04683   while (literW != fPlanesAltLists[iplane][ALG_WEST].end()){
04684     Int_t delta = 999;
04685     Int_t ibest = 999;
04686     (*literW)->SetFirst();
04687     while( (*literW)->IsValid() ){
04688       Int_t iStripW = (*literW)->GetCurrentSEId().GetStrip();
04689       for(UInt_t i = 0; i<stripPattern.size(); i++){
04690         Int_t d =abs(iStripW-stripPattern[i]);
04691         if(d<delta){
04692           delta = d;
04693           ibest = iStripW;
04694         }
04695       }
04696       (*literW)->Next();
04697     }
04698     stripW[ibest] =  *literW;
04699     literW++;
04700   }
04701   // Have matched E/W : now use pattern remux plane
04702 
04703   this->ReMuxPlane(iplane);
04704 
04705   for(Int_t i = 0;i<MAX_NUMBER_OF_STRIPS; i++){
04706     if(stripE[i]!=NULL)this->DeMuxSingleHitE(iplane, stripE[i], i);
04707     if(stripW[i]!=NULL)this->DeMuxSingleHitW(iplane, stripW[i], i);
04708   }
04709 
04710   return;
04711 }
04712 
04713 
04714 
04715 
04716 void AlgAltDeMuxBase::ReMuxPlane(Int_t iplane){
04717 
04718   vector <PlexSEIdAltL*>::iterator literA;
04719 
04720   for(Int_t iew=ALG_EAST; iew<=ALG_WEST;iew++){
04721     if(fDeMuxedPlanesAltLists[iplane][iew].size()>0){
04722       literA = fDeMuxedPlanesAltLists[iplane][iew].begin();
04723       while( literA != fDeMuxedPlanesAltLists[iplane][iew].end()){
04724         (*literA)->ClearWeights();
04725         fPlanesAltLists[iplane][iew].push_back(*literA);
04726         literA++;
04727       }
04728     }
04729   }
04730 
04731   fDeMuxedPairs[iplane].erase(fDeMuxedPairs[iplane].begin(),fDeMuxedPairs[iplane].end());
04732   fDeMuxedSingles[iplane].erase(fDeMuxedSingles[iplane].begin(),fDeMuxedSingles[iplane].end());
04733 
04734   for(Int_t iew=0; iew<=1;iew++){
04735     // Clear the arrays of vectors of AltLists
04736     fDeMuxedPlanesAltLists[iplane][iew].erase(fDeMuxedPlanesAltLists[iplane][iew].begin(),fDeMuxedPlanesAltLists[iplane][iew].end());
04737   }
04738   // zero counters
04739   fPlaneHit[iplane] = 0;
04740   fPlanePair[iplane] = 0;
04741   NdemuxedHitsU[iplane] = 0;
04742   NdemuxedHitsV[iplane] = 0;
04743 
04744   return;
04745 }
04746 
04747 void AlgAltDeMuxBase::DeMuxPass(Int_t ipass){
04748 
04749   vector <DeMuxSearchTactic>::iterator literS;
04750 
04751   amShowing = false;
04752   fCutUseMultipleLines = false;
04753 
04754   switch(ipass){
04755   case 0:
04756     fCutRawPE            = 0.0;
04757     fCutCorPE            = 1.0;
04758     fCutSigmaQ           = 3.5;
04759     fCutUseTimingMask    = true;
04760     fCutUseTargetStrips  = false;
04761     fCutGuessing         = false;
04762     fStripWindow         = 5;
04763 
04764     for(int iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
04765       if(fPlanesAltLists[iplane][ALG_EAST].size()&&fPlanesAltLists[iplane][ALG_WEST].size()){
04766 
04767         if(amWriting)MSG("AltDeMux", Msg::kDebug) << "DeMuxPass0 : " << iplane << " : " << fPlanesAltLists[iplane][ALG_EAST].size() << " : " << fPlanesAltLists[iplane][ALG_WEST].size() << endl;
04768         this->ResetMap(fPlanesAltLists[iplane][ALG_EAST].size(),fPlanesAltLists[iplane][ALG_WEST].size());
04769         this->MakePlaneMap(iplane);
04770         //  this->PrintPlaneMap();
04771         this->GroupHits();
04772         this->SelectHits(iplane,true);
04773       }
04774     }
04775 
04776     MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::DeMuxPass Finished DeMuxPass 0" << endl;
04777     break;
04778   case 1:
04779     fCutRawPE            = 0.5;
04780     fCutCorPE            = 2.0;
04781     fCutSigmaQ           = 3.0;
04782     fCutUseTimingMask    = true;
04783     fCutUseTargetStrips  = false;
04784     fCutGuessing         = false;
04785     fStripWindow         = 5;
04786     for(Int_t iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
04787       NdemuxedHitsU[iplane]=0;
04788       NdemuxedHitsV[iplane]=0;
04789       if(fPlanesAltLists[iplane][ALG_EAST].size()&&fPlanesAltLists[iplane][ALG_WEST].size()){
04790         this->ResetMap(fPlanesAltLists[iplane][ALG_EAST].size(),fPlanesAltLists[iplane][ALG_WEST].size());
04791         this->MakePlaneMap(iplane);
04792         this->GroupHits();
04793         this->SelectHits(iplane,false,true);
04794       }
04795     }
04796     MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::DeMuxPass Finished DeMuxPass 1" << endl;
04797     if(fDiagnosticPlots){
04798       this->DrawDiagnosticPlots(1);
04799     }
04800     break;
04801 
04802 
04803   case 12:
04804     fCutRawPE            = 0.0;
04805     fCutCorPE            = 0.0;
04806     fCutSigmaQ           = 5.0;
04807     fCutUseTimingMask    = false;
04808     fCutUseTargetStrips  = false;
04809     fCutGuessing         = false;
04810     fCutUseMultipleLines = false;
04811     fStripWindow         = 5;
04812     for(Int_t iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
04813       if(fPlanesAltLists[iplane][ALG_EAST].size()&&fPlanesAltLists[iplane][ALG_WEST].size()){
04814         this->ResetMap(fPlanesAltLists[iplane][ALG_EAST].size(),fPlanesAltLists[iplane][ALG_WEST].size());
04815         this->MakeMultipleTargets(iplane);
04816         this->MakePlaneMap(iplane);
04817         this->GroupHits();
04818         this->SelectHits(iplane,false,true);
04819       }
04820     }
04821     MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::DeMuxPass Finished DeMuxPass 1" << endl;
04822     if(fDiagnosticPlots){
04823       this->DrawDiagnosticPlots(1);
04824     }
04825     break;
04826 
04827 
04828   case 11:
04829     fCutRawPE            = 0.5;
04830     fCutCorPE            = 0.5;
04831     fCutSigmaQ           = 5.0;
04832     fCutUseTimingMask    = true;
04833     fCutUseTargetStrips  = true;
04834     fCutGuessing         = false;
04835     fCutUseMultipleLines = true;
04836     fStripWindow         = 12;
04837     for(Int_t iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
04838       if(fPlanesAltLists[iplane][ALG_EAST].size()&&fPlanesAltLists[iplane][ALG_WEST].size()){
04839         this->ResetMap(fPlanesAltLists[iplane][ALG_EAST].size(),fPlanesAltLists[iplane][ALG_WEST].size());
04840         this->MakeMultipleTargets(iplane);
04841         this->MakePlaneMap(iplane);
04842         this->GroupHits();
04843         this->SelectHits(iplane,false,true);
04844       }
04845     }
04846     MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::DeMuxPass Finished DeMuxPass 1" << endl;
04847     if(fDiagnosticPlots){
04848       this->DrawDiagnosticPlots(1);
04849     }
04850     break;
04851 
04852   case 22:
04853     fCutRawPE            = 0.0;
04854     fCutCorPE            = 0.5;
04855     fCutSigmaQ           = 4.0;
04856     fCutUseTimingMask    = true;
04857     fCutUseTargetStrips  = true;
04858     fCutGuessing         = false;
04859     fTrackingLowPECut    = 1.5;
04860     fStripWindow         = 5;
04861 
04862     this->MakeSearchTactics();
04863 
04864     for(unsigned int i=0; i<fSearchTactics.size(); i++){
04865       int iplane = fSearchTactics[i].iplane;
04866       if(fSearchTactics[i].goodTactic){
04867         this->ResetMap(fPlanesAltLists[iplane][ALG_EAST].size(),fPlanesAltLists[iplane][ALG_WEST].size());
04868         this->MakePlaneMap(fSearchTactics[i]);
04869         this->GroupHits();
04870         if(this->SelectHits(iplane,false)){
04871           this->NewTactic(fSearchTactics[i]);
04872         }else{
04873           this->NewTactic(fSearchTactics[i]);
04874         }
04875       }else{
04876         this->NewTactic(fSearchTactics[i]);
04877       }
04878     }
04879     MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::DeMuxPass Finished DeMuxPass 2" << endl;
04880     if(fDiagnosticPlots){
04881       this->DrawDiagnosticPlots(2);
04882     }
04883     break;
04884 
04885   case 2:
04886     fCutRawPE            = 0.0;
04887     fCutCorPE            = 1.5;
04888     fCutSigmaQ           = 3.0;
04889     fCutUseTimingMask    = false;
04890     fCutUseTargetStrips  = true;
04891     fCutGuessing         = false;
04892     fTrackingLowPECut    = 2.5;
04893     fStripWindow         = 100;
04894 
04895     this->MakeSearchTactics();
04896 
04897     for(unsigned int i=0; i<fSearchTactics.size(); i++){
04898       int iplane = fSearchTactics[i].iplane;
04899       if(fSearchTactics[i].goodTactic){
04900         this->ResetMap(fPlanesAltLists[iplane][ALG_EAST].size(),fPlanesAltLists[iplane][ALG_WEST].size());
04901         this->MakePlaneMap(fSearchTactics[i]);
04902         this->GroupHits();
04903         if(this->SelectHits(iplane,false)){
04904           this->NewTactic(fSearchTactics[i]);
04905         }else{
04906           this->NewTactic(fSearchTactics[i]);
04907         }
04908       }else{
04909         this->NewTactic(fSearchTactics[i]);
04910       }
04911     }
04912     MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::DeMuxPass Finished DeMuxPass 2" << endl;
04913     if(fDiagnosticPlots){
04914       this->DrawDiagnosticPlots(2);
04915     }
04916     break;
04917 
04918   case 3:
04919     fCutRawPE            = 0.0;
04920     fCutCorPE            = 0.0;
04921     fCutSigmaQ           = 4.0;
04922     fCutUseTimingMask    = false;
04923     fCutUseTargetStrips  = true;
04924     fCutGuessing         = false;
04925     fTrackingLowPECut    = 2.5;
04926     fStripWindow         = 100;
04927 
04928     this->MakeSearchTacticsX();
04929     if(fDiagnosticPlots)DrawDiagnosticPlots(3);
04930     for(unsigned int i=0; i<fSearchTactics.size(); i++){
04931       int iplane = fSearchTactics[i].iplane;
04932       if(fSearchTactics[i].goodTactic){
04933         this->ResetMap(fPlanesAltLists[iplane][ALG_EAST].size(),fPlanesAltLists[iplane][ALG_WEST].size());
04934         this->MakePlaneMap(fSearchTactics[i]);
04935         this->GroupHits();
04936         if(this->SelectHits(iplane,false)){
04937           this->NewTactic(fSearchTactics[i]);
04938         }else{
04939           this->NewTactic(fSearchTactics[i]);
04940         }
04941       }else{
04942         this->NewTactic(fSearchTactics[i]);
04943       }
04944     }
04945     MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::DeMuxPass Finished DeMuxPass 3" << endl;
04946     if(fDiagnosticPlots){
04947       this->DrawDiagnosticPlots(3);
04948     }
04949     break;
04950 
04951 
04952   case 33:
04953     fCutRawPE            = 0.0;
04954     fCutCorPE            = 0.0;
04955     fCutSigmaQ           = 5.0;
04956     fCutUseTimingMask    = true;
04957     fCutUseTargetStrips  = false;
04958     fCutGuessing         = false;
04959     fTrackingLowPECut    = 2.5;
04960     fStripWindow         = 5;
04961 
04962     this->MakeSearchTacticsX();
04963 
04964     for(Int_t iplane = 0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
04965       if(fPlanesAltLists[iplane][ALG_EAST].size()>0 && fPlanesAltLists[iplane][ALG_WEST].size()>0){
04966         this->ResetMap(fPlanesAltLists[iplane][ALG_EAST].size(),fPlanesAltLists[iplane][ALG_WEST].size());
04967         this->MakePlaneMap(iplane);
04968         this->GroupHits();
04969         this->SelectHits(iplane,false,true);
04970       }
04971     }
04972     MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::DeMuxPass Finished DeMuxPass 33" << endl;
04973     if(fDiagnosticPlots){
04974       this->DrawDiagnosticPlots(3);
04975     }
04976     break;
04977   case 4:
04978     //amShowing = true;
04979   case 5:
04980     fCutRawPE            = 0.0;
04981     fCutCorPE            = 0.0;
04982     fCutSigmaQ           = 0.0;
04983     fCutUseTimingMask    = false;
04984     fCutUseTargetStrips  = true;
04985     fCutGuessing         = false;
04986     fTrackingLowPECut    = 2.5;
04987     fStripWindow         = 100;
04988     this->MakeSearchTacticsY();
04989     literS = fSearchTactics.begin();
04990     while(literS!=fSearchTactics.end()){
04991       if((*literS).goodTactic){
04992         this->DeMuxSingles((*literS));
04993       }
04994       literS++;
04995     }
04996     MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::DeMuxPass Finished DeMuxPass " << ipass << endl;
04997     if(fDiagnosticPlots)this->DrawDiagnosticPlots(4);
04998     amShowing = false;
04999     break;
05000 
05001   default:
05002     MSG("AltDeMux", Msg::kError) << "AlgAltDeMuxBase::DeMuxPass - try to access undefined pass " << ipass << endl;
05003     break;
05004   }
05005   
05006   return;
05007   
05008 }
05009 
05010 
05011 
05012 
05013 void AlgAltDeMuxBase::DeMuxWhatsLeft(){
05014 
05015   fCutRawPE            = 0.0;
05016   fCutCorPE            = 0.0;
05017   fCutSigmaQ           = 10.0;
05018   fCutUseTimingMask    = false;
05019   fCutUseTargetStrips  = false;
05020   fCutGuessing         = false;
05021   fCutUseMultipleLines = false;
05022   fStripWindow         = 5;
05023   for(Int_t iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
05024     if(fPlanesAltLists[iplane][ALG_EAST].size()>0&&fPlanesAltLists[iplane][ALG_WEST].size()>0){
05025       this->ResetMap(fPlanesAltLists[iplane][ALG_EAST].size(),fPlanesAltLists[iplane][ALG_WEST].size());
05026       this->MakePlaneMap(iplane);
05027       this->GroupHits();
05028       this->SelectHits(iplane,false);
05029     }
05030   }
05031 
05032   
05033 
05034   // Next try demux groups which are golden with timing mask
05035 
05036   fCutRawPE            = 0.0;
05037   fCutCorPE            = 0.0;
05038   fCutSigmaQ           = 10.0;
05039   fCutUseTimingMask    = true;
05040   fCutUseTargetStrips  = false;
05041   fCutGuessing         = false;
05042   fCutUseMultipleLines = false;
05043   fStripWindow         = 5;
05044   for(Int_t iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
05045     if(fPlanesAltLists[iplane][ALG_EAST].size()>0&&fPlanesAltLists[iplane][ALG_WEST].size()>0){
05046       //cout << "*********************************WHATS LEFT : PASS 1 like " << iplane << endl;
05047       this->ResetMap(fPlanesAltLists[iplane][ALG_EAST].size(),fPlanesAltLists[iplane][ALG_WEST].size());
05048       this->MakePlaneMap(iplane);
05049       this->GroupHits();
05050       this->SelectHits(iplane,false);
05051     }
05052   }
05053   
05054 
05055   // Demux remaining pairs - using validate plane and the timing mask as a seed
05056   for(Int_t iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
05057     if(fPlanesAltLists[iplane][ALG_EAST].size()>0&&fPlanesAltLists[iplane][ALG_WEST].size()>0){
05058       //      cout << "*********************************WHATS LEFT : VALIDATE PLANE " << iplane << fPlanesAltLists[iplane][ALG_EAST].size() << " : " << fPlanesAltLists[iplane][ALG_EAST].size() << endl;
05059       //BestGuessForPlane(iplane);
05060     }
05061   }
05062   
05063   // Should only have singles left now.....
05064   DeMuxPass(4);
05065   for(Int_t iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
05066     if(fPlanesAltLists[iplane][ALG_EAST].size()>0||fPlanesAltLists[iplane][ALG_WEST].size()>0){
05067       //  cout << "*********************************WHATS LEFT : SINGLES " << iplane << endl;
05068       this->BestGuessForSingleSidedHits(iplane);
05069     }
05070   }
05071 
05072   return;
05073   
05074 }
05075 
05076 
05077 
05078 
05079 
05080 
05081 void AlgAltDeMuxBase::MakePlaneMap(Int_t iplane,bool useTargets)
05082 {
05083 
05084   if(useTargets); // obsolete but keep backward compatibility
05085   // Look for stripend pairs which satisfy the some set of cuts 
05086 
05087   vector <PlexSEIdAltL*>::iterator literE;
05088   vector <PlexSEIdAltL*>::iterator literW;
05089 
05090   literE = fPlanesAltLists[iplane][ALG_EAST].begin();
05091   fECount = -1;
05092   PlaneView::PlaneView_t kView = (*literE)->GetPlaneView();
05093   pCalculator->SetPlane(iplane);
05094   pCalculator->SetView(kView);
05095   if(fPlanesAltLists[iplane][ALG_EAST].size()>static_cast<UInt_t>(MAX_HITS_PLANE))MSG("AltDeMux", Msg::kError) << "AlgAltDeMuxBase::MakePlaneMap => Too many WEST hits in plane " << iplane << endl;
05096   if(fPlanesAltLists[iplane][ALG_WEST].size()>static_cast<UInt_t>(MAX_HITS_PLANE))MSG("AltDeMux", Msg::kError) << "AlgAltDeMuxBase::MakePlaneMap => Too many EAST hits in plane " << iplane << endl;
05097   while (literE != fPlanesAltLists[iplane][ALG_EAST].end()){
05098     fECount++;
05099     if(fECount<MAX_HITS_PLANE){
05100       pPlaneAltMapE[fECount] = (*literE);
05101       literW = fPlanesAltLists[iplane][ALG_WEST].begin();
05102       fWCount = -1;
05103       while ( literW != fPlanesAltLists[iplane][ALG_WEST].end()){
05104         fWCount++;
05105         if(fWCount<MAX_HITS_PLANE){
05106           pPlaneAltMapW[fWCount] = (*literW);
05107           (*literE)->SetFirst();
05108           while( (*literE)->IsValid() ){
05109             Int_t iStripE = (*literE)->GetCurrentSEId().GetStrip();
05110             pCalculator->SetEast(*literE,iStripE);
05111             (*literW)->SetFirst();
05112             while( (*literW)->IsValid() ){
05113               Int_t iStripW = (*literW)->GetCurrentSEId().GetStrip();
05114               pCalculator->SetWest(*literW,iStripW);
05115               // In here we can check for a possibility
05116               if(iStripE==iStripW){
05117                 Int_t iStrip = iStripE;
05118                 bool goodComb = true;
05119                 pCalculator->CalcEastWest();
05120                 // If desired require the strip is in the road defined by timing
05121                 if(fCutUseTimingMask && fUVmask[iplane][iStrip]==false)goodComb = false; 
05122                 // Apply charge cuts on this EAST-WEST strip possibility
05123                 if(goodComb){
05124                   if(pCalculator->QRawE() < fCutRawPE || 
05125                      pCalculator->QRawW() < fCutRawPE)goodComb = false;
05126                   if(pCalculator->QSigCorE() < fCutCorPE || 
05127                      pCalculator->QSigCorW() < fCutCorPE)goodComb = false;
05128                 }
05129                 
05130                 if(goodComb)goodComb = (fabs(pCalculator->SigmaDQ())<fCutSigmaQ);
05131 
05132                 // goodComb = goodComb && (abs(pCalculator->SigmaDQ())<fCutSigmaQ);
05133                 
05134                 // If we have defined a set of target strips can insist
05135                 // strip is near one of the target positions 
05136                 if(goodComb&&fCutUseTargetStrips){
05137                   bool found = false;
05138                   for(unsigned int t=0;t<fTargetStrips.size()&&found==false;t++){
05139                     if(abs(fTargetStrips[t]-iStrip)<12){
05140                       found = true;
05141                     }
05142                   } 
05143                   goodComb = found;
05144                 }
05145                 if(amWriting){
05146                   if(goodComb)MSG("AltDeMux", Msg::kDebug) << "MakePlane(" <<iplane << ") " << pCalculator->QSigCorE() << ":" << pCalculator->QSigCorW()<<  "::" << pCalculator->QAttCorE() << ":" << pCalculator->QAttCorW() << "::" << " : " << pCalculator->SigmaDQ() << " : " << iStripE << "*" << endl;
05147                   if(!goodComb)MSG("AltDeMux", Msg::kDebug) << "MakePlane(" << iplane << ") " << pCalculator->QSigCorE() << ":" << pCalculator->QSigCorW()<<  "::" << pCalculator->QAttCorE() << ":" << pCalculator->QAttCorW() << "::" << " : " << pCalculator->SigmaDQ() << " : " << iStripE << endl;
05148                 }
05149                 if(goodComb)fAmap[fECount][fWCount] = true;
05150                 fSmap[fECount][fWCount] = iStripE;
05151               }
05152               (*literW)->Next();
05153             }
05154             (*literE)->Next();
05155           }
05156         }
05157         literW++;
05158       }
05159     }
05160     literE++;
05161   }
05162 
05163   return;
05164 }
05165 
05166 
05167 void AlgAltDeMuxBase::GroupHits(){
05168 
05169   for(Int_t iw=0;iw<=fWCount; iw++){
05170     for(Int_t iwp=0;iwp<=fWCount; iwp++){
05171       fBmap[iw][iwp] = false;
05172     }
05173   }
05174 
05175   for(Int_t ie =0; ie<=fECount; ie++){
05176     for(Int_t iw=0; iw<=fWCount; iw++){
05177       if(fAmap[ie][iw]){
05178         for(Int_t iwp =0;iwp<=fWCount; iwp++){
05179           if(fAmap[ie][iwp]){
05180             fBmap[iw][iwp] = true;
05181             fBmap[iwp][iw] = true;
05182           }
05183         }
05184       }
05185     }
05186   }
05187 
05188   for(Int_t iw=0;iw<=fWCount; iw++){
05189     fBmap[iw][iw] = true;
05190     for(Int_t iwp=0;iwp<=fWCount; iwp++){
05191       if(fBmap[iw][iwp]==false){
05192         for(Int_t k=0;k<=fWCount; k++)fBmap[iw][iwp] |= fBmap[iw][k] && fBmap[k][iwp];
05193       }
05194     }
05195   }
05196 
05197 
05198   fNGroups = 0;
05199   for(Int_t iw=0;iw<=fWCount; iw++){fWFound[iw]=false;}
05200   for(Int_t ie=0;ie<=fECount; ie++){fEFound[ie]=false;}
05201 
05202   for(Int_t iw=0;iw<=fWCount; iw++){
05203     if(fWFound[iw]==false){
05204       fNGroups++;
05205       fNInGroupW[fNGroups]=0;
05206       for(int iwp=0;iwp<=fWCount; iwp++){
05207         if(fBmap[iw][iwp]){
05208           fNInGroupW[fNGroups]++;
05209           fWGroup[fNGroups][fNInGroupW[fNGroups]]=iwp;
05210           fWFound[iwp]=true;
05211         }
05212       }
05213     }
05214   }
05215       
05216   if(fNGroups>0){
05217     for(int ig=1;ig<=fNGroups;ig++){
05218       fNInGroupE[ig]=0;
05219       for(int iw=1;iw<=fNInGroupW[ig];iw++){
05220         for(int ie=0;ie<=fECount;ie++){
05221           if(fEFound[ie]==false && fAmap[ie][(fWGroup[ig][iw])]){
05222             fNInGroupE[ig]++;
05223             fEGroup[ig][fNInGroupE[ig]]=ie;
05224             fEFound[ie] = true;
05225           }
05226         }
05227       }
05228     }
05229   }
05230 
05231   return;
05232 }
05233 
05234 
05235 bool AlgAltDeMuxBase::SelectHits(Int_t iPlane, bool gold, bool useGold) 
05236 {
05237   bool success = false;
05238 
05239   for(int ig=1;ig<=fNGroups;ig++){
05240     AltDeMuxPattern* pP;
05241     AltDeMuxPattern* pBest;
05242     PatternPair wibble;
05243     Int_t smin=999;
05244     Int_t smax=0;
05245     Int_t srange;
05246     Int_t srange1;
05247     Int_t srange2;
05248     Int_t count;
05249     pBest = NULL;
05250     count  =0;
05251     srange1 = 1000;
05252     srange2 = 1000; 
05253     if(pMaster->SelectPattern(fNInGroupE[ig],fNInGroupW[ig])){
05254       while( (pP = pMaster->Next())!=NULL ){
05255         count++;
05256         bool patok = true;
05257         smin =999;
05258         smax =0;
05259         for(int i=0; i< pP->Size(); i++){
05260           wibble = pP->GetI(i);
05261           if(patok)patok = fAmap[(fEGroup[ig][wibble.eEntry])][(fWGroup[ig][wibble.wEntry])];
05262           if(patok){
05263             Int_t s = fSmap[(fEGroup[ig][wibble.eEntry])][(fWGroup[ig][wibble.wEntry])];
05264             if(s<smin)smin=s;
05265             if(s>smax)smax=s;
05266           }
05267         }
05268         if(patok){
05269           srange = smax-smin;
05270           if(srange<=srange1){
05271             srange2 = srange1;
05272             srange1 = srange;
05273             pBest = pP;
05274           }else{
05275             if(srange<=srange2)srange2=srange;
05276           }
05277         }
05278       }
05279 
05280       // if no golden pattern found return false
05281       if(pBest==NULL)return false;
05282 
05283 
05284       // have found a golden combination so now do something with it
05285 
05286       if(srange1 < pBest->Size()+fStripWindow && srange1+pBest->Size()<srange2){
05287         success = true;
05288         if(!gold)fUniqueDeMuxedGroupID++;
05289         // have found a golden combination - iterate over it and demux hits
05290         for(int i=0; i< pBest->Size(); i++){
05291           wibble = pBest->GetI(i);
05292           
05293           Int_t iStrip = fSmap[(fEGroup[ig][wibble.eEntry])][(fWGroup[ig][wibble.wEntry])];
05294 
05295           if(amWriting)MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBass::SelectHits using combination " << iStrip << endl;
05296           if(gold)this->GoldHits(iPlane,iStrip);
05297           if(!gold){
05298             bool found = false;
05299             if(useGold){
05300               for(int i=1;!found && i<=fGoldPlaneHit[iPlane];i++){
05301                 if(iStrip==fGoldHitMap[iPlane][i])found=true;
05302               }
05303             }
05304             if(!useGold || fCutGuessing || found )this->DeMuxHits(iPlane,fEGroup[ig][wibble.eEntry],fWGroup[ig][wibble.wEntry],iStrip);
05305           }
05306         }
05307       }
05308     }else{
05309       // Pattern Master says no ! too big ? 
05310       if( (fNInGroupE[ig]>3) && (fNInGroupW[ig]>3) ){
05311         int nfound  = this->DeMuxBigGroup(iPlane,ig,gold);
05312         if(nfound==1)success=true;
05313       }
05314     }
05315   }  // end of loop over groups 
05316   return success; 
05317 }
05318 
05319 
05320 
05321 Int_t AlgAltDeMuxBase::DeMuxBigGroup(Int_t iplane, Int_t ig, bool gold) 
05322 { 
05323   bool success = false;
05324 
05325   vector<BigGroup>theGroups;
05326 
05327   int strips[192];
05328   int estrips[192];
05329   int wstrips[192];
05330   for(int i=0;i<192;i++)strips[i]=0;
05331   for(int ie=1;ie<=fNInGroupE[ig];ie++){
05332     for(int iw=1;iw<=fNInGroupW[ig];iw++){
05333       if(fAmap[(fEGroup[ig][ie])][(fWGroup[ig][iw])]){
05334         int s = fSmap[(fEGroup[ig][ie])][(fWGroup[ig][iw])];
05335         strips[s]++;
05336         estrips[s] = ie;
05337         wstrips[s] = iw;
05338       }
05339     }
05340   }
05341   int istartStrip = 0;
05342   int iendStrip = 0;
05343   int ngroups = 0;
05344   int ilast=0;
05345 
05346   for(int i=0;i<=192;i++){
05347     _smask[i] = false;
05348   }
05349 
05350   int ming = fNInGroupE[ig];
05351   if(fNInGroupW[ig]<ming)ming = fNInGroupW[ig];
05352 
05353   int best = ming-3;
05354   if(ming<12)best = ming-2;
05355   if(ming<7)best = ming-1;
05356   best = ming -1;
05357 
05358   int icount;
05359   for(int is=0; is<192-ming; is++){
05360     if(strips[is]==1){
05361       icount = 1;
05362       int iend = is+ming+5;
05363       int ie;
05364       if(iend>191)iend=192;
05365       for(ie=is+1; ie<iend && icount != ming; ie++){
05366         if(strips[ie]>0){
05367           ilast = ie;
05368           icount++;
05369         }
05370       }
05371       
05372       if(icount>=best){
05373         BigGroup aBigGroup;
05374         aBigGroup.groupStart = is;
05375         aBigGroup.groupEnd = ilast;
05376         aBigGroup.groupCount = icount;
05377         theGroups.push_back(aBigGroup);
05378         best = icount;
05379         if(amWriting)cout << "Found a (small ?) group : " << is << ":" << ilast << " : " << icount << endl;
05380       }
05381       
05382 
05383       if(icount==ming){
05384         ngroups++;
05385         istartStrip = is;
05386         iendStrip   = ie-1;
05387         if(amWriting)cout << "Found a group : " << is << ":" << ie-1 << endl;
05388         for(int i=is;i<=ie;i++){
05389           _smask[i] = true;
05390         }
05391       }
05392     }
05393   }
05394   if(amWriting)cout << "Found " << ngroups << " groups " << endl;
05395 
05396 
05397   ngroups = 0;
05398   for(unsigned int igroup =0; igroup<theGroups.size();igroup++){
05399     if(theGroups[igroup].groupCount==best){
05400       ngroups++;
05401       istartStrip = theGroups[igroup].groupStart;
05402       iendStrip = theGroups[igroup].groupEnd;
05403       if(amWriting)cout << " A good group " << theGroups[igroup].groupStart << " " << theGroups[igroup].groupEnd << " "<< theGroups[igroup].groupCount << endl;
05404       for(int i=theGroups[igroup].groupStart;i<=theGroups[igroup].groupEnd;i++){
05405         _smask[i] = true;
05406       }   
05407     }
05408   }
05409 
05410   // if one and only one group is found then demux it
05411   if(ngroups==1){
05412     success = true;
05413     // fUniqueDeMuxedGroupID is an ugly cludge to tag each group of gold hits 
05414     fUniqueDeMuxedGroupID++;
05415     Int_t ie;
05416     Int_t iw;
05417     for(Int_t is=istartStrip; is<=iendStrip;is++){
05418       if(strips[is]==1){
05419         ie = estrips[is];
05420         iw = wstrips[is];
05421         if(amWriting)cout << " Strip : " << is << " ew " << ie << ":" << iw << endl;
05422         // if the flag gold is 
05423         if(gold)this->GoldHits(iplane,is);
05424         if(!gold)this->DeMuxHits(iplane,fEGroup[ig][ie],fWGroup[ig][iw],is);
05425       }     
05426     }
05427   } 
05428 
05429   if(ngroups>1){
05430     for(int ie=1;ie<=fNInGroupE[ig];ie++){
05431       PlexSEIdAltL* pAltL;
05432       pAltL = pPlaneAltMapE[(fEGroup[ig][ie])]; 
05433       pAltL->SetFirst();
05434       while(pAltL->IsValid()){
05435         int is = pAltL->GetCurrentSEId().GetStrip();
05436         if(!_smask[is])pAltL->SetCurrentWeight(-999.);
05437         pAltL->Next();
05438       }
05439     }
05440     for(int iw=1;iw<=fNInGroupW[ig];iw++){
05441       PlexSEIdAltL* pAltL;
05442       pAltL = pPlaneAltMapW[(fWGroup[ig][iw])]; 
05443       pAltL->SetFirst();
05444       while(pAltL->IsValid()){
05445         int is = pAltL->GetCurrentSEId().GetStrip();
05446         if(!_smask[is])pAltL->SetCurrentWeight(-999.);
05447         pAltL->Next();
05448       }
05449     }
05450   }
05451 
05452   return ngroups;
05453 }
05454 
05455 void AlgAltDeMuxBase::GoldHits(Int_t iplane, Int_t istrip){ 
05456 
05457   fGoldPlaneHit[iplane] += 1;
05458   fGoldHitMap[iplane][fGoldPlaneHit[iplane]] = istrip;
05459 
05460   return;
05461 
05462 }
05463 
05464 void AlgAltDeMuxBase::DeMuxHits(Int_t iplane, Int_t ie, Int_t iw, Int_t istrip ){ 
05465   this->DeMuxHits(iplane, pPlaneAltMapE[ie], pPlaneAltMapW[iw], istrip );
05466 
05467   if(amWriting)cout << "DEMUXED STRIPs : " << ie << ":" << iw << " -> " << istrip << endl;
05468   
05469   return;
05470 }
05471 
05472 void AlgAltDeMuxBase::DeMuxHits(Int_t iplane, PlexSEIdAltL* pAltE, PlexSEIdAltL* pAltW, Int_t istrip )
05473 { 
05474   
05475   this->DeMuxHitE(iplane,pAltE,istrip);
05476   this->DeMuxHitW(iplane,pAltW,istrip);
05477 
05478   if(amWriting)cout << "DEMUX THIS HIT ! " << iplane << ":" << istrip << endl;
05479 
05480   DeMuxedPair thisPair;
05481   thisPair.altListE = pAltE;
05482   thisPair.altListW = pAltW;
05483   thisPair.status   = true;
05484   if(iplane<fLowestDeMuxedPairPlane)fLowestDeMuxedPairPlane = iplane;
05485   if(iplane>fHighestDeMuxedPairPlane)fHighestDeMuxedPairPlane = iplane;
05486 
05487 
05488   PlaneView::PlaneView_t kView = pAltE->GetPlaneView();
05489   pCalculator->SetPlane(iplane);
05490   pCalculator->SetView(kView);
05491   pCalculator->SetEast(pAltE,istrip);
05492   pCalculator->SetWest(pAltW,istrip);
05493   pCalculator->CalcBestEastWest();
05494 
05495   thisPair.orthogonalStripFromTiming = pCalculator->StripAim();
05496   thisPair.uniqueGroupID = fUniqueDeMuxedGroupID;
05497   thisPair.weightQ = 1.0;
05498   thisPair.pairQCor = pCalculator->PairQCor();
05499 
05500   fDeMuxedPairs[iplane].push_back(thisPair);
05501 
05502   if(kView==PlaneView::kU){
05503     if(NdemuxedHitsU[iplane]<MAX_DISPLAYED_HITS){
05504       demuxedHitStripU[iplane][NdemuxedHitsU[iplane]] = istrip;
05505       demuxedHitQU[iplane][NdemuxedHitsU[iplane]]     = pCalculator->PairQCor();
05506       NdemuxedHitsU[iplane]++;
05507     }
05508   }
05509   if(kView==PlaneView::kV){
05510     if(NdemuxedHitsV[iplane]<MAX_DISPLAYED_HITS){
05511       demuxedHitStripV[iplane][NdemuxedHitsV[iplane]] = istrip;
05512       demuxedHitQV[iplane][NdemuxedHitsV[iplane]]     = pCalculator->PairQCor();
05513       NdemuxedHitsV[iplane]++;
05514     }
05515   }
05516 
05517   
05518   if(fPlaneHit[iplane]==0){
05519     if(kView==PlaneView::kU)_nDeMuxedPlanesU++;
05520     if(kView==PlaneView::kV)_nDeMuxedPlanesV++; 
05521   } 
05522   fPlaneHit[iplane]++;
05523   fPlanePair[iplane]++;
05524   fHitMap[iplane][fPlaneHit[iplane]]  = istrip;
05525   fQHitMapE[iplane][fPlaneHit[iplane]] = pCalculator->QSigCorE();
05526   fQHitMapW[iplane][fPlaneHit[iplane]] = pCalculator->QSigCorW();
05527 
05528   return;
05529 
05530 }
05531 
05532 
05533 void AlgAltDeMuxBase::DeMuxHitE(Int_t iplane, Int_t ie, Int_t is){ 
05534 
05535   PlexSEIdAltL* pAltL;
05536 
05537   pAltL = pPlaneAltMapE[ie]; 
05538   this->DeMuxHitE(iplane,pAltL,is);
05539   return;
05540 }
05541 
05542 
05543 void AlgAltDeMuxBase::DeMuxHitW(Int_t iplane, Int_t iw, Int_t is){ 
05544 
05545   PlexSEIdAltL* pAltL;
05546   pAltL = pPlaneAltMapW[iw]; 
05547   this->DeMuxHitW(iplane,pAltL,is);  
05548 
05549   return;
05550 }
05551 
05552 void AlgAltDeMuxBase::DeMuxSingleHitE(Int_t iplane, PlexSEIdAltL* pAltL, Int_t istrip){ 
05553 
05554   PlaneView::PlaneView_t kView = pAltL->GetPlaneView();
05555   pCalculator->SetPlane(iplane);
05556   pCalculator->SetView(kView);
05557   pCalculator->SetEast(pAltL,istrip);
05558   pCalculator->CalcBestEast();
05559 
05560   DeMuxedSingle thisSingle;
05561   thisSingle.altList = pAltL;
05562   thisSingle.status  =  true;
05563   thisSingle.Qcor    = pCalculator->QSigCorE();
05564   fDeMuxedSingles[iplane].push_back(thisSingle);
05565 
05566   if(fDiagnosticPlots){
05567     if(kView==PlaneView::kU){
05568       if(NdemuxedHitsU[iplane]<MAX_DISPLAYED_HITS){
05569         demuxedHitStripU[iplane][NdemuxedHitsU[iplane]] = istrip;
05570         demuxedHitQU[iplane][NdemuxedHitsU[iplane]]     = pCalculator->QSigCorE();
05571         NdemuxedHitsU[iplane]++;
05572       }
05573     }
05574     if(kView==PlaneView::kV){
05575       if(NdemuxedHitsV[iplane]<MAX_DISPLAYED_HITS){
05576         demuxedHitStripV[iplane][NdemuxedHitsV[iplane]] = istrip;
05577         demuxedHitQV[iplane][NdemuxedHitsV[iplane]]     = pCalculator->QSigCorE();
05578         NdemuxedHitsV[iplane]++;
05579       }
05580     }
05581   }
05582   
05583   fPlaneHit[iplane]++;
05584   fHitMap[iplane][fPlaneHit[iplane]]  = istrip;
05585   fQHitMapE[iplane][fPlaneHit[iplane]] = pCalculator->QSigCorE();
05586 
05587   //  cout << "DEMUXING SINGLE E : " << iplane << ":" << istrip  << " : " << pCalculator->QSigCorE() << ":" << this->XTalkCharge(pAltL,istrip) << endl;
05588 
05589   this->DeMuxHitE(iplane,pAltL,istrip);
05590 
05591   return;
05592 }
05593 
05594 
05595 
05596 void AlgAltDeMuxBase::DeMuxSingleHitW(Int_t iplane, PlexSEIdAltL* pAltL, Int_t istrip){ 
05597 
05598   PlaneView::PlaneView_t kView = pAltL->GetPlaneView();
05599   pCalculator->SetPlane(iplane);
05600   pCalculator->SetView(kView);
05601   pCalculator->SetWest(pAltL,istrip);
05602   pCalculator->CalcBestWest();
05603 
05604 
05605   DeMuxedSingle thisSingle;
05606   thisSingle.altList = pAltL;
05607   thisSingle.status  = true;
05608   thisSingle.Qcor    = pCalculator->QSigCorW();
05609   fDeMuxedSingles[iplane].push_back(thisSingle);
05610 
05611   if(fDiagnosticPlots){
05612     if(kView==PlaneView::kU){
05613       if(NdemuxedHitsU[iplane]<MAX_DISPLAYED_HITS){
05614         demuxedHitStripU[iplane][NdemuxedHitsU[iplane]] = istrip;
05615         demuxedHitQU[iplane][NdemuxedHitsU[iplane]]     = pCalculator->QSigCorW();
05616         NdemuxedHitsU[iplane]++;
05617       }
05618     }
05619     if(kView==PlaneView::kV){
05620       if(NdemuxedHitsV[iplane]<MAX_DISPLAYED_HITS){
05621         demuxedHitStripV[iplane][NdemuxedHitsV[iplane]] = istrip;
05622         demuxedHitQV[iplane][NdemuxedHitsV[iplane]]     = pCalculator->QSigCorW();
05623         NdemuxedHitsV[iplane]++;
05624       }
05625     }
05626   }
05627   
05628   fPlaneHit[iplane]++;
05629   fHitMap[iplane][fPlaneHit[iplane]]  = istrip;
05630   fQHitMapW[iplane][fPlaneHit[iplane]] = pCalculator->QSigCorW();
05631   this->DeMuxHitW(iplane,pAltL,istrip);
05632 
05633   return;
05634 }
05635 
05636 
05637 
05638 void AlgAltDeMuxBase::DeMuxHitE(Int_t iplane, PlexSEIdAltL* pAltL, Int_t is){ 
05639 
05640   vector <PlexSEIdAltL*>::iterator literA;
05641   bool notFound;
05642   float q;
05643 
05644   pAltL->SetFirst();
05645 
05646   q = pAltL->GetCurrentItem().GetPE();
05647   notFound = true;
05648   while(pAltL->IsValid()){
05649     if(pAltL->GetCurrentSEId().GetStrip()==is){
05650       pAltL->SetCurrentWeight(1.);
05651     }else{
05652       pAltL->SetCurrentWeight(0.);
05653     }
05654     pAltL->Next();
05655   }
05656 
05657   literA = fPlanesAltLists[iplane][ALG_EAST].begin();
05658   notFound = true;
05659   while (notFound && literA != fPlanesAltLists[iplane][ALG_EAST].end()){
05660     if(*literA==pAltL){
05661       fPlanesAltLists[iplane][ALG_EAST].erase(literA);
05662       notFound = false;
05663     }
05664     literA++;
05665   }
05666   fDeMuxedPlanesAltLists[iplane][ALG_EAST].push_back(pAltL);
05667 
05668   this->UpdateXTalkMap(pAltL);
05669 
05670   return;
05671 }
05672 
05673 
05674 void AlgAltDeMuxBase::VetoHitE(Int_t iplane, PlexSEIdAltL* pAltL){ 
05675 
05676   bool notFound;
05677   vector <PlexSEIdAltL*>::iterator literA;
05678 
05679   literA = fPlanesAltLists[iplane][ALG_EAST].begin();
05680   notFound = true;
05681   while (notFound && literA != fPlanesAltLists[iplane][ALG_EAST].end()){
05682     if(*literA==pAltL){
05683       fPlanesAltLists[iplane][ALG_EAST].erase(literA);
05684       notFound = false;
05685     }
05686     literA++;
05687   }
05688 
05689   return;
05690 }
05691 
05692 void AlgAltDeMuxBase::VetoHitW(Int_t iplane, PlexSEIdAltL* pAltL){ 
05693 
05694   bool notFound;
05695   vector <PlexSEIdAltL*>::iterator literA;
05696 
05697   literA = fPlanesAltLists[iplane][ALG_WEST].begin();
05698   notFound = true;
05699   while (notFound && literA != fPlanesAltLists[iplane][ALG_WEST].end()){
05700     if(*literA==pAltL){
05701       fPlanesAltLists[iplane][ALG_WEST].erase(literA);
05702       notFound = false;
05703     }
05704     literA++;
05705   }
05706 
05707   return;
05708 }
05709 
05710 
05711 void AlgAltDeMuxBase::DeMuxHitW(Int_t iplane, PlexSEIdAltL* pAltL, Int_t is){ 
05712 
05713 
05714   vector <PlexSEIdAltL*>::iterator literA;
05715   bool notFound;
05716   float q;
05717 
05718 
05719   pAltL->SetFirst();
05720 
05721   notFound = true;
05722   q = pAltL->GetCurrentItem().GetPE();
05723   while(pAltL->IsValid()){
05724     if(pAltL->GetCurrentSEId().GetStrip()==is){
05725       pAltL->SetCurrentWeight(1.);
05726     }else{
05727       pAltL->SetCurrentWeight(0.);
05728     }
05729     pAltL->Next();
05730   }
05731   
05732   literA = fPlanesAltLists[iplane][ALG_WEST].begin();
05733   notFound = true;
05734   while (notFound && literA != fPlanesAltLists[iplane][ALG_WEST].end()){
05735     if(*literA==pAltL){
05736       fPlanesAltLists[iplane][ALG_WEST].erase(literA);
05737       notFound = false;
05738     }
05739     literA++;
05740   }
05741 
05742   fDeMuxedPlanesAltLists[iplane][ALG_WEST].push_back(pAltL);
05743   this->UpdateXTalkMap(pAltL);
05744 
05745   return;
05746 }
05747  
05748 
05749 DeMuxSearchTactic AlgAltDeMuxBase::MakeSearchTactics(Int_t iplane)
05750 {
05751 
05752   bool foundH = false;
05753   bool foundL = false;
05754 
05755   DeMuxSearchTactic tactic;
05756   tactic.iplane = iplane;
05757 
05758   Int_t imax = iplane+12;
05759   if(imax>MAX_NUMBER_OF_PLANES-2)imax=MAX_NUMBER_OF_PLANES-3;
05760   for(int i=iplane+2; i<imax &&!foundH ; i+=2){
05761     if( fUVMap[i]==fUVMap[iplane]){
05762       foundH = true;
05763       tactic.highplane  = i;
05764     }
05765   }
05766   Int_t imin = iplane - 12;
05767   if(imin<2)imin=1;
05768   for(int i=iplane-2; i>imin &&!foundL ; i-=2){
05769     if( fUVMap[i]==fUVMap[iplane]){
05770       foundL = true;
05771       tactic.lowplane  = i;
05772     }
05773   }
05774   if(foundL||foundH)tactic.goodTactic = true;
05775 
05776   return tactic;
05777 }
05778 
05779 void AlgAltDeMuxBase::MakeSearchTactics()
05780 {
05781 
05782   bool ifirstU=false;
05783   bool ifirstV=false;
05784   int firstUplane = 0;
05785   int firstVplane = 0;
05786   int lastUplane = 0;
05787   int lastVplane = 0;
05788   int foundPlane = 0;
05789 
05790 
05791   fSearchTactics.erase(fSearchTactics.begin(),fSearchTactics.end());
05792 
05793   for(int i=0; i<MAX_NUMBER_OF_PLANES; i++){
05794     fSearched[i] = false;
05795     if(fPlaneHit[i]>0){
05796       if(ifirstU==false){
05797         if( fUVMap[i]==PlaneView::kU){
05798           ifirstU = true;
05799           firstUplane = i;
05800         }
05801       }
05802       if(ifirstV==false){
05803         if( fUVMap[i]==PlaneView::kV){
05804           ifirstV = true;
05805           firstVplane = i;
05806         }
05807       }
05808 
05809 
05810 
05811       if(fUVMap[i]==PlaneView::kU)lastUplane =i;
05812       if(fUVMap[i]==PlaneView::kV)lastVplane =i;
05813 
05814       int inext = i+2;
05815       if(inext==249)inext=250;
05816       if(inext==250)inext=251;
05817 
05818       if(fPlaneHit[inext]==0){
05819         int j = inext+1;
05820         bool found = false;
05821         while(found==false&&j-inext <=24 && j<MAX_NUMBER_OF_PLANES-2){
05822           j++;
05823           if(fUVMap[j]==fUVMap[i]&&fPlaneHit[j]>0)found=true;
05824         }
05825         if(found){
05826           bool lfound = false;
05827           // Step forward in gap
05828           for(int k=i+2; k<=j-2; k++){
05829             if(fUVMap[k]==fUVMap[i]){
05830               if(!lfound && fPlanesAltLists[k][ALG_EAST].size()&&fPlanesAltLists[k][ALG_WEST].size()){
05831                 lfound = true;
05832                 DeMuxSearchTactic tactic;
05833                 foundPlane = k;
05834                 tactic.iplane = k;
05835                 tactic.searchType = SEARCH_GAP_F;
05836                 tactic.lowplane  = i;
05837                 tactic.highplane = j;
05838                 tactic.goodTactic = true;
05839                 fSearchTactics.push_back(tactic);
05840                 fSearched[k] = true;
05841                 if(tactic.highplane>=MAX_NUMBER_OF_PLANES)MSG("AltDeMux", Msg::kFatal) << "AlgAltDeMuxBase::MakeSearchTactics highplane out of range : " << tactic.highplane << " :" << i << ":" << j << ":" << k << endl;
05842               }
05843             }
05844           }
05845           // Step backwards in gap
05846           if(lfound){
05847             bool found = false;
05848             for(int k=j-2; k>=foundPlane+2; k--){
05849               if(fUVMap[k]==fUVMap[i]){
05850                 if(!found &&fPlanesAltLists[k][ALG_EAST].size()&&fPlanesAltLists[k][ALG_WEST].size()){
05851                   found = true;
05852                   DeMuxSearchTactic tactic;
05853                   tactic.iplane = k;
05854                   tactic.searchType = SEARCH_GAP_B;
05855                   tactic.lowplane  = i;
05856                   tactic.highplane = j;
05857                   tactic.goodTactic = true;
05858                   fSearchTactics.push_back(tactic);
05859                   fSearched[k] = true;
05860                 }
05861               }
05862             }
05863           } 
05864         }       
05865       }
05866     }
05867   }
05868 
05869   if(ifirstU){
05870     DeMuxSearchTactic tactic;
05871     tactic.iplane = firstUplane;
05872     tactic.lowplane = firstUplane;
05873     tactic.highplane = firstUplane;
05874     tactic.searchType = SEARCH_BACKWARDS;
05875     tactic.goodTactic = false;
05876     fSearchTactics.push_back(tactic);
05877 
05878 
05879     tactic.iplane = lastUplane;
05880     tactic.lowplane = lastUplane;
05881     tactic.highplane = lastUplane;
05882     tactic.searchType = SEARCH_FORWARDS;
05883     tactic.goodTactic = false;
05884     fSearchTactics.push_back(tactic);
05885   }
05886 
05887   if(ifirstV){
05888     DeMuxSearchTactic tactic;
05889     tactic.iplane = firstVplane;
05890     tactic.lowplane = firstVplane;
05891     tactic.highplane = firstVplane;
05892     tactic.searchType = SEARCH_BACKWARDS;
05893     tactic.goodTactic = false;
05894     fSearchTactics.push_back(tactic);
05895 
05896     tactic.iplane = lastVplane;
05897     tactic.lowplane = lastVplane;
05898     tactic.highplane = lastVplane;
05899     tactic.searchType = SEARCH_FORWARDS;
05900     tactic.goodTactic = false;
05901     fSearchTactics.push_back(tactic);
05902   }
05903     
05904   return;
05905 }
05906 
05907 
05908 void AlgAltDeMuxBase::MakePlaneMap(DeMuxSearchTactic tactic)
05909 {
05910 
05911   Int_t i = tactic.iplane;
05912   Int_t j = tactic.lowplane;
05913   Int_t k = tactic.highplane;
05914 
05915   Float_t target = 0;
05916   Int_t itarget;
05917   Int_t it;
05918 
05919 
05920   if(j<0&&j>-100)MSG("AltDeMux", Msg::kFatal) << "AlgAltDeMuxBase::MakePlaneMap lowplane out of range : " << j << endl;
05921   if(k>=MAX_NUMBER_OF_PLANES)MSG("AltDeMux", Msg::kFatal) << "AlgAltDeMuxBase::MakePlaneMap highplane out of range : " << k << endl;
05922 
05923   fTargetStrips.erase(fTargetStrips.begin(),fTargetStrips.end());
05924   if(fEventType==MULTIPLE_MUON)MakeMultipleTargets(i);
05925 
05926   bool useHoughSlope         = fUseHoughSlope;
05927   bool useFitSlopeTime       = fUseFitSlopeTime;
05928   bool useFitSlopeHits       = fUseFitSlopeHits;
05929   bool useInterpolation      = false;
05930   // bool useSafeExtrapolationF = false;
05931   // bool useSafeExtrapolationB = false;
05932   bool useExtrapolationF     = false;
05933   bool useExtrapolationB     = false;
05934   bool useSameStrip          = false;
05935   bool useLevelStripF        = false;
05936   bool useLevelStripB        = false;
05937 
05938 
05939   bool treatAsUNKNOWN        = false;
05940   if(fEventType==UNKNOWN)treatAsUNKNOWN = true;
05941   if(fEventType==SINGLE_MUON)useFitSlopeHits = true;
05942   if(fEventType==THROUGH_GOING_MUON)useFitSlopeHits = true;
05943   if(fEventType==STRAIGHT_THROUGH_GOING_MUON)useFitSlopeHits = true;
05944 
05945   if(fEventType==MULTIPLE_MUON){
05946     if( (fHoughStatus==true)&&(j>0||k>0))useHoughSlope = true;
05947     if( (fHoughStatus==false)||(j==0&&k==0))treatAsUNKNOWN = true;
05948   }
05949 
05950   if(treatAsUNKNOWN){
05951     useInterpolation  = true;
05952     if(tactic.searchType != SEARCH_FORWARDS && 
05953        tactic.searchType != SEARCH_GAP_F)useLevelStripB = fUseLevelStripB;
05954     if(tactic.searchType != SEARCH_BACKWARDS && 
05955        tactic.searchType != SEARCH_GAP_B)useLevelStripF = fUseLevelStripF;
05956     useExtrapolationF = fUseExtrapolationF;
05957     useExtrapolationB = fUseExtrapolationB;
05958     useSameStrip      = fUseSameStrip;
05959   }
05960 
05961   for(Int_t index = 0; index<3; index++){
05962     Float_t slopeU = 0.;
05963     Float_t slopeV = 0.;
05964     bool    useSlope = false;
05965     if(index==0){
05966       useSlope = useFitSlopeHits;
05967       if(!fFitQHitU.status)slopeU  = fFitHitU.a1;
05968       if(!fFitQHitV.status)slopeV  = fFitHitV.a1;
05969       if(fFitQHitU.status)slopeU  = fFitQHitU.a1;
05970       if(fFitQHitV.status)slopeV  = fFitQHitV.a1;
05971     }
05972     if(index==1){
05973       useSlope = useFitSlopeTime;
05974       slopeU  = fFitTimeU.a1;
05975       slopeV  = fFitTimeU.a1;
05976     }
05977     if(index==2){
05978       useSlope = useHoughSlope;
05979       slopeU  = fHoughSlopeU;
05980       slopeV  = fHoughSlopeV;
05981     }
05982 
05983     if(useSlope){
05984       if(j>0){
05985         for(int jj=1;jj<=fPlanePair[j];jj++){
05986           Int_t je = j;
05987           if(i>249&&j<249)je-=20;
05988           if(fUVMap[i]==PlaneView::kU)target = fHitMap[j][jj] + slopeU*(i-je);
05989           if(fUVMap[i]==PlaneView::kV)target = fHitMap[j][jj] + slopeV*(i-je);
05990           itarget = static_cast<int>(target);
05991           fTargetStrips.push_back(itarget);
05992         }
05993       }
05994       if(k>0 && k<MAX_NUMBER_OF_PLANES){
05995         for(int kk=1;kk<=fPlanePair[k];kk++){
05996           Int_t ke = k;
05997           if(i<249&&k>249)ke+=20;
05998           if(fUVMap[i]==PlaneView::kU)target = fHitMap[k][kk] + slopeU*(i-ke);
05999           if(fUVMap[i]==PlaneView::kV)target = fHitMap[k][kk] + slopeV*(i-ke);
06000           itarget = static_cast<int>(target);
06001           fTargetStrips.push_back(itarget);
06002         }
06003       }
06004     }
06005   }
06006 
06007   if(useSameStrip&&fPlanePair[i]>0){
06008     for(int ii=1;ii<=fPlanePair[i];ii++){
06009       itarget = fHitMap[i][ii];
06010       fTargetStrips.push_back(itarget);
06011     }
06012   }
06013 
06014   if(fPlanePair[i]==0){
06015     if(j>0 && useLevelStripB){
06016       for(int jj=1;jj<=fPlanePair[j];jj++){
06017         itarget = fHitMap[j][jj];
06018         fTargetStrips.push_back(itarget);
06019       }
06020     }
06021     if(k>0 && k<MAX_NUMBER_OF_PLANES  && useLevelStripF){
06022       for(int kk=1;kk<=fPlaneHit[k];kk++){
06023         itarget = fHitMap[k][kk];
06024         fTargetStrips.push_back(itarget);
06025       }
06026     }
06027   }
06028   
06029   
06030   if(j>0 && k>0 && k<MAX_NUMBER_OF_PLANES && useInterpolation){
06031     for(int jj=1;jj<=fPlanePair[j];jj++){
06032       if(fQHitMapE[j][jj]>fTrackingLowPECut && fQHitMapW[j][jj]>fTrackingLowPECut){
06033         for(int kk=1;kk<=fPlanePair[k];kk++){
06034           if(fQHitMapE[k][kk]>fTrackingLowPECut && fQHitMapW[k][kk]>fTrackingLowPECut){
06035             it =fHitMap[j][jj] + (fHitMap[k][kk]-fHitMap[j][jj])*(i-j)/(k-j);
06036             fTargetStrips.push_back(it);  
06037           }
06038         }
06039       }
06040     }
06041   }
06042 
06043   this->MakePlaneMap(i,true);
06044 
06045   return;
06046 }
06047 
06048 
06049 
06050 void AlgAltDeMuxBase::NewTactic(DeMuxSearchTactic oldTactic){
06051   
06052 
06053   bool foundh;
06054   bool foundl;
06055   bool found;
06056   DeMuxSearchTactic newTactic;
06057 
06058   switch(oldTactic.searchType){
06059   case SEARCH_GAP:
06060 
06061     break;
06062   case SEARCH_GAP_B:
06063     found = false;
06064     for(int i=oldTactic.iplane-2;i>=oldTactic.lowplane+2&&found==false;i-=2){
06065       if(!fSearched[i]&&fPlanesAltLists[i][ALG_EAST].size()&&fPlanesAltLists[i][ALG_WEST].size()){
06066         found = true;
06067         newTactic.iplane = i;
06068         newTactic.goodTactic = true;
06069         newTactic.lowplane = oldTactic.lowplane;
06070         if(fPlaneHit[oldTactic.iplane]>0){ 
06071           newTactic.highplane = oldTactic.iplane;
06072         }else{
06073           newTactic.highplane = oldTactic.highplane;
06074         }
06075         newTactic.searchType = SEARCH_GAP_B;
06076       }
06077     }
06078     if(found){
06079       fSearchTactics.push_back(newTactic);
06080       fSearched[newTactic.iplane] = true;
06081     }
06082     break;
06083   case SEARCH_GAP_F:
06084     found = false;
06085     for(int i=oldTactic.iplane+2;i<=oldTactic.highplane-2&&found==false;i+=2){
06086       if(!fSearched[i]&&fPlanesAltLists[i][ALG_EAST].size()&&fPlanesAltLists[i][ALG_WEST].size()){
06087         found = true;
06088         newTactic.iplane = i;
06089         newTactic.goodTactic = true;
06090         if(fPlaneHit[oldTactic.iplane]>0){ 
06091           newTactic.lowplane = oldTactic.iplane;
06092         }else{
06093           newTactic.lowplane = oldTactic.lowplane;
06094         }
06095         newTactic.highplane = oldTactic.highplane;
06096         newTactic.searchType = SEARCH_GAP_F;
06097       }
06098     }
06099     if(found){
06100       fSearchTactics.push_back(newTactic);
06101       fSearched[newTactic.iplane] = true;
06102     }
06103     break;
06104   case SEARCH_FORWARDS:
06105     foundh = false;
06106     foundl = false;
06107     if(oldTactic.goodTactic){
06108       for(int i=oldTactic.iplane+2;i<MAX_NUMBER_OF_PLANES-2&&foundh==false;i+=2){
06109         if(fPlanesAltLists[i][ALG_EAST].size()&&fPlanesAltLists[i][ALG_WEST].size()){
06110           foundh = true;
06111           newTactic.iplane = i;
06112           newTactic.goodTactic = true;
06113           newTactic.highplane = oldTactic.iplane;
06114           newTactic.lowplane = oldTactic.highplane;
06115           newTactic.searchType = SEARCH_FORWARDS;
06116         }
06117       }
06118     }else{
06119       for(int i=oldTactic.iplane+2;i<MAX_NUMBER_OF_PLANES-2&&foundh==false;i+=2){
06120         if(fPlanesAltLists[i][ALG_EAST].size()&&fPlanesAltLists[i][ALG_WEST].size()){
06121           foundh = true;
06122           newTactic.highplane = oldTactic.iplane;
06123           newTactic.iplane = i; 
06124           newTactic.goodTactic = true;
06125           newTactic.lowplane = -100;
06126           newTactic.searchType = SEARCH_FORWARDS;
06127         }
06128       }
06129       for(int i=oldTactic.iplane-2;i>oldTactic.iplane-12&&foundl==false;i-=2){
06130         if(fPlaneHit[i]>0){
06131           foundl = true;
06132           newTactic.lowplane = i;
06133         }
06134       }
06135     }
06136     if(foundh){
06137       fSearchTactics.push_back(newTactic);
06138     }
06139     break;
06140   case SEARCH_BACKWARDS:
06141     foundh = false;
06142     foundl = false;
06143     if(oldTactic.goodTactic){
06144       for(int i=oldTactic.iplane-2;i>0&&foundl==false;i-=2){
06145         if(fPlanesAltLists[i][ALG_EAST].size()&&fPlanesAltLists[i][ALG_WEST].size()){
06146           foundl = true;
06147           newTactic.iplane = i;
06148           newTactic.lowplane = oldTactic.iplane;
06149           newTactic.goodTactic = true;
06150           newTactic.highplane = oldTactic.lowplane;
06151           newTactic.searchType = SEARCH_BACKWARDS;
06152         }
06153       }
06154     }else{
06155       for(int i=oldTactic.iplane-2;i>0&&foundl==false;i-=2){
06156         if(fPlanesAltLists[i][ALG_EAST].size()&&fPlanesAltLists[i][ALG_WEST].size()){
06157           foundl = true;
06158           newTactic.lowplane = oldTactic.iplane;
06159           newTactic.iplane = i; 
06160           newTactic.goodTactic = true;
06161           newTactic.highplane = -100;
06162           newTactic.searchType = SEARCH_BACKWARDS;
06163         }
06164       }
06165       for(int i=oldTactic.iplane+2;i<oldTactic.iplane+12&&foundh==false;i+=2){
06166         if(fPlaneHit[i]>0){
06167           foundh = true;
06168           newTactic.highplane = i;
06169         }
06170       }
06171     }
06172     if(foundl){
06173       fSearchTactics.push_back(newTactic);
06174     }
06175     break;
06176   default:
06177     break;
06178   }
06179   
06180   return;
06181 } 
06182 
06183 void AlgAltDeMuxBase::MakeSearchTacticsX()
06184 {
06185 
06186   fSearchTactics.erase(fSearchTactics.begin(),fSearchTactics.end());
06187   bool found;
06188 
06189   for(int i=0; i<MAX_NUMBER_OF_PLANES; i++){
06190     if(fPlaneHit[i]>=0){
06191       if(fPlanesAltLists[i][ALG_EAST].size()&&fPlanesAltLists[i][ALG_WEST].size()){
06192         int j = -100;
06193         int k = -100;
06194         if(i>1){
06195           int jj = i-2;
06196           if(jj==248 || jj==249)jj--;
06197           found = false;
06198           while(found==false){
06199             if(fPlaneHit[jj]){
06200               j=jj;
06201               found = true;
06202             }
06203             jj-=2;
06204             if(jj==248 || jj==249)jj--;
06205             if(jj<0||jj<i-24)found =true;
06206           }
06207         }
06208         if(i<MAX_NUMBER_OF_PLANES-2){
06209           int kk = i+2;
06210           if(kk==249 || kk==250)kk++;
06211           found = false;
06212           while(found==false){
06213             if(fPlaneHit[kk]){
06214               k=kk;
06215               found = true;
06216             }
06217             kk+=2;
06218             if(kk==249 || kk==250)kk++;
06219             if(kk>MAX_NUMBER_OF_PLANES-2||kk>i+24)found =true;
06220           }
06221         }
06222         DeMuxSearchTactic tactic;
06223         tactic.iplane = i;
06224         tactic.searchType = SEARCH_GAP;
06225         tactic.lowplane  = j;
06226         tactic.highplane = k;
06227         tactic.goodTactic = true;
06228         fSearchTactics.push_back(tactic);
06229       }
06230     }
06231   }    
06232   return;
06233 }
06234 
06235 
06236 void AlgAltDeMuxBase::MakeSearchTacticsY()
06237 {
06238 
06239   fSearchTactics.erase(fSearchTactics.begin(),fSearchTactics.end());
06240   bool found;
06241 
06242   for(int i=0; i<MAX_NUMBER_OF_PLANES; i++){
06243     if(fPlanesAltLists[i][ALG_EAST].size()||fPlanesAltLists[i][ALG_WEST].size()){
06244       int j = -100;
06245       int k = -100;
06246       if(i>1){
06247         int jj = i-2;
06248         if(jj==248 || jj==249)jj--;
06249         found = false;
06250         while(found==false){
06251           if(fPlaneHit[jj]){
06252             j=jj;
06253             found = true;
06254           }
06255           jj-=2;
06256           if(jj==248 || jj==249)jj--;
06257           if(jj<0||jj<i-24
06258 
06259 )found =true;
06260         }
06261       }
06262       if(i<MAX_NUMBER_OF_PLANES-2){
06263         int kk = i+2;
06264         if(kk==249 || kk==250)kk++;
06265         found = false;
06266         while(found==false){
06267           if(fPlaneHit[kk]){
06268             k=kk;
06269             found = true;
06270           }
06271           kk+=2;
06272           if(kk==249 || kk==250)kk++;
06273           if(kk>MAX_NUMBER_OF_PLANES-2||kk>i+24)found =true;
06274         }
06275       }
06276       DeMuxSearchTactic tactic;
06277       tactic.iplane = i;
06278       tactic.searchType = SEARCH_SINGLES;
06279       tactic.lowplane  = j;
06280       tactic.highplane = k;
06281       tactic.goodTactic = true;
06282       fSearchTactics.push_back(tactic);
06283     }
06284   }    
06285   return;
06286 }
06287 
06288 
06289 
06290 void AlgAltDeMuxBase::DeMuxSingles(DeMuxSearchTactic tactic)
06291 {
06292   vector <PlexSEIdAltL*>::iterator literA;
06293 
06294   int i = tactic.iplane;
06295   int j = tactic.lowplane;
06296   int k = tactic.highplane;
06297   Float_t target = 0.;
06298   int itarget;
06299   int it;
06300   int s;
06301   int sbest;
06302   int closeness; 
06303 
06304   int sbest1;
06305   int closeness1;
06306   int sbest2;
06307   int closeness2;
06308 
06309   fTargetStrips.erase(fTargetStrips.begin(),fTargetStrips.end());
06310   if(fEventType==MULTIPLE_MUON)MakeMultipleTargets(i);
06311   
06312   bool useHoughSlope         = fUseHoughSlope;
06313   bool useFitSlopeTime       = fUseFitSlopeTime;
06314   bool useFitSlopeHits       = fUseFitSlopeHits;
06315   bool useInterpolation      = false;
06316   // bool useSafeExtrapolationF = false;
06317   // bool useSafeExtrapolationB = false;
06318   bool useExtrapolationF     = false;
06319   bool useExtrapolationB     = false;
06320   bool useSameStrip          = fUseSameStrip;
06321   bool useLevelStripF        = false;
06322   bool useLevelStripB        = false;
06323   bool treatAsUNKNOWN        = false;
06324 
06325   if(fEventType==UNKNOWN)treatAsUNKNOWN = true;
06326   if(fEventType==SINGLE_MUON)useFitSlopeHits=true;
06327   if(fEventType==THROUGH_GOING_MUON)useFitSlopeHits=true;
06328   if(fEventType==STRAIGHT_THROUGH_GOING_MUON)useFitSlopeHits=true;
06329   if(fEventType==MULTIPLE_MUON){
06330     useSameStrip = false;
06331     if( (fHoughStatus==true)&&(j>0||k>0))useHoughSlope = true;
06332     if( (fHoughStatus==false)||(j==0&&k==0))treatAsUNKNOWN = true;
06333   }
06334 
06335   if(treatAsUNKNOWN){
06336     if(fPlaneHit[i]==0)useInterpolation  = fUseInterpolation;
06337     // if(fPlaneHit[i]==0)useExtrapolationF = fUseExtrapolationF;
06338     //if(fPlaneHit[i]==0)useExtrapolationB = fUseExtrapolationB;
06339     if(i>=247&&i<=251 ){
06340       useInterpolation   = false;
06341       if(i>249){
06342         useExtrapolationF = fUseExtrapolationF;
06343         useExtrapolationB = false;
06344       }else{
06345         useExtrapolationB = fUseExtrapolationB;
06346         useExtrapolationF = false;
06347       }
06348     }
06349     useSameStrip      = fUseSameStrip;
06350   }
06351 
06352 
06353 
06354   for(Int_t index = 0; index<3; index++){
06355     Float_t slopeU = 0.;
06356     Float_t slopeV = 0.;
06357     bool    useSlope = false;
06358     if(index==0){
06359       useSlope = useFitSlopeHits;
06360       if(!fFitQHitU.status)slopeU  = fFitHitU.a1;
06361       if(!fFitQHitV.status)slopeV  = fFitHitV.a1;
06362       if(fFitQHitU.status)slopeU  = fFitQHitU.a1;
06363       if(fFitQHitV.status)slopeV  = fFitQHitV.a1;
06364     }
06365     if(index==1){
06366       useSlope = useFitSlopeTime;
06367       slopeU  = fFitTimeU.a1;
06368       slopeV  = fFitTimeU.a1;
06369     }
06370     if(index==2){
06371       useSlope = useHoughSlope;
06372       slopeU  = fHoughSlopeU;
06373       slopeV  = fHoughSlopeV;
06374     }
06375 
06376     if(useSlope){
06377       if(j>0){
06378         for(int jj=1;jj<=fPlanePair[j];jj++){
06379           Int_t je = j;
06380           if(i>249&&j<249)je-=20;
06381           if(fUVMap[i]==PlaneView::kU)target = fHitMap[j][jj] + slopeU*(i-je);
06382           if(fUVMap[i]==PlaneView::kV)target = fHitMap[j][jj] + slopeV*(i-je);
06383           itarget = static_cast<int>(target);
06384           if(itarget>-24&&itarget<216)fTargetStrips.push_back(itarget);
06385           if(amWriting)cout << "Slope Target j : " << itarget << endl;
06386         }
06387       }
06388       if(k>0){
06389         for(int kk=1;kk<=fPlanePair[k];kk++){
06390           Int_t ke = k;
06391           if(i<249&&k>249)ke+=20;
06392           if(fUVMap[i]==PlaneView::kU)target = fHitMap[k][kk] + slopeU*(i-ke);
06393           if(fUVMap[i]==PlaneView::kV)target = fHitMap[k][kk] + slopeV*(i-ke);
06394           itarget = static_cast<int>(target);
06395           if(itarget>-24&&itarget<216)fTargetStrips.push_back(itarget);
06396           if(amWriting)cout << "Slope Target k : " << itarget << endl;
06397         }
06398       }
06399     }
06400   }
06401 
06402   if(useSameStrip&&fPlanePair[i]>0){
06403     for(int ii=1;ii<=fPlanePair[i];ii++){
06404       itarget = fHitMap[i][ii];
06405       fTargetStrips.push_back(itarget);
06406       if(amWriting)cout << "USE SAME STRIP : " << itarget << endl;
06407     }
06408   }
06409 
06410   if(useInterpolation && j>0 && k>0){
06411     for(int jj=1;jj<=fPlanePair[j];jj++){
06412       if(fQHitMapE[j][jj]>fTrackingLowPECut && fQHitMapW[j][jj]>fTrackingLowPECut){
06413         for(int kk=1;kk<=fPlaneHit[k];kk++){
06414           if(fQHitMapE[k][kk]>fTrackingLowPECut && fQHitMapW[k][kk]>fTrackingLowPECut){
06415             it =fHitMap[j][jj] + (fHitMap[k][kk]-fHitMap[j][jj])*(i-j)/(k-j);
06416             // Interpolate accross SM boundart 
06417             if(j<249 && i>249)it =fHitMap[j][jj] + (fHitMap[k][kk]-fHitMap[j][jj])*(i-j+15)/(k-j+20);
06418             if(i<249 && k>249)it =fHitMap[j][jj] + (fHitMap[k][kk]-fHitMap[j][jj])*(i-j)/(k+20-j);
06419             fTargetStrips.push_back(it);  
06420             if(amWriting)cout << "INTERPOLATE : " << it << endl;
06421           }
06422         }
06423       }
06424     }
06425   }
06426   
06427   if(useExtrapolationF){
06428     if(k>0 && k<MAX_NUMBER_OF_PLANES-2){
06429       int n = (k-i)/2;
06430       for(int kk=1;kk<=fPlanePair[k];kk++){
06431         int kp = k+2;
06432         if(k>249||kp<249){
06433           for (int kkp=1;kkp<=fPlanePair[kp];kkp++){
06434             itarget = (n+1)*fHitMap[k][kk] - n*fHitMap[kp][kkp];
06435             fTargetStrips.push_back(itarget);
06436             if(amWriting)cout << "EXTRAPOLATEF : " << itarget << endl;
06437           }
06438         }
06439       }
06440     }
06441   }
06442 
06443   if(useExtrapolationB){
06444     if(j>=2){
06445       int n = (i-j)/2;
06446       for(int jj=1;jj<=fPlanePair[j];jj++){
06447         int jm = j-2;
06448         if(jm>249||j<249){
06449           for(int jjm=1;jjm<=fPlanePair[jm];jjm++){
06450             itarget = (n+1)*fHitMap[j][jj] - n*fHitMap[jm][jjm];
06451             fTargetStrips.push_back(itarget);
06452             if(amWriting)cout << "EXTRAPOLATEB : " << itarget << endl;
06453           }
06454         }
06455       }
06456     }
06457   }
06458 
06459   useLevelStripF = false;
06460   useLevelStripB = false;
06461 
06462   if(fTargetStrips.size()==0)useLevelStripF = true;
06463   if(fTargetStrips.size()==0)useLevelStripB = true;
06464  
06465   if(j>0 && useLevelStripB){
06466     if(j!=247&&j!=248){
06467       for(int jj=1;jj<=fPlanePair[j];jj++){      
06468         itarget = fHitMap[j][jj];
06469         fTargetStrips.push_back(itarget);
06470         if(amWriting)cout << "LEVEL B       : " << itarget << endl;
06471       }
06472     }
06473   }
06474   if(k>0 && useLevelStripF){
06475     if(k!=247&&k!=248){
06476       for(int kk=1;kk<=fPlanePair[k];kk++){
06477         itarget = fHitMap[k][kk];
06478         fTargetStrips.push_back(itarget);
06479         if(amWriting)cout << "LEVEL F       : " << itarget << endl;
06480       }
06481     }
06482   }  
06483 
06484   
06485   if(fTargetStrips.size()<1)return;  
06486 
06487   Int_t currentPlane = i;  
06488   PlaneView::PlaneView_t kView;
06489 
06490   for(Int_t iew=ALG_EAST;iew<=ALG_WEST;iew++){
06491     if(fPlanesAltLists[i][iew].size()>0){
06492       while (fPlanesAltLists[i][iew].size()>0){
06493         sbest =0;
06494         closeness = 999;
06495         sbest1 =0;
06496         closeness1 = 999;
06497         sbest2 =0;
06498         closeness2 = 999;
06499         literA = fPlanesAltLists[i][iew].begin();
06500         (*literA)->SetFirst();
06501         kView = (*literA)->GetPlaneView();
06502         while( (*literA)->IsValid() ){
06503           s = (*literA)->GetCurrentSEId().GetStrip();
06504           bool found = false;
06505           if(fCutUseTimingMask==false || fUVmask[i][s]){  
06506             if((*literA)->GetCurrentWeight()>-1.){
06507               for(unsigned int t=0;t<fTargetStrips.size()&&found==false;t++){
06508                 if(abs(fTargetStrips[t]-s)<closeness){
06509                   closeness = abs(fTargetStrips[t]-s);
06510                   sbest = s;                    
06511                   if(closeness==0)found = true;
06512                 }
06513               }
06514             }else{
06515               for(unsigned int t=0;t<fTargetStrips.size()&&found==false;t++){
06516                 if(abs(fTargetStrips[t]-s)<closeness1){
06517                   closeness1 = abs(fTargetStrips[t]-s);
06518                   sbest1 = s;                   
06519                   if(closeness1==0)found = true;
06520                 }
06521               }
06522             }
06523           }else{
06524             for(unsigned int t=0;t<fTargetStrips.size()&&found==false;t++){
06525               if(abs(fTargetStrips[t]-s)<closeness2){
06526                 closeness2 = abs(fTargetStrips[t]-s);
06527                 sbest2 = s;                     
06528               }
06529             }
06530           }
06531           (*literA)->Next();
06532         }
06533         if(closeness>=999|| (closeness>5 && closeness1<closeness)  ){
06534           sbest=sbest1;
06535           closeness=closeness1;
06536         }
06537         if(closeness>=999&&closeness1>=999){
06538           sbest=sbest2;
06539           closeness=closeness2;
06540         }
06541         if(closeness<999){
06542           if(amShowing){
06543             bool foundit = false;
06544             for(int ix=1;ix<=fPlaneHit[currentPlane];ix++){
06545               if(abs(sbest-fHitMap[currentPlane][ix])<2.5)foundit=true;
06546             }
06547             if(foundit==false){
06548               (*literA)->SetFirst();
06549               IsXTalk(*literA);
06550             }
06551           }
06552           if(iew==ALG_EAST)this->DeMuxSingleHitE(currentPlane,*literA, sbest);
06553           if(iew==ALG_WEST)this->DeMuxSingleHitW(currentPlane,*literA, sbest);
06554         }else{
06555           if(iew==ALG_EAST)this->VetoHitE(currentPlane,*literA);
06556           if(iew==ALG_WEST)this->VetoHitW(currentPlane,*literA);                }
06557       }
06558     }
06559   }
06560   
06561   return;
06562 }
06563 
06564 void AlgAltDeMuxBase::StripCrossTalkSingles(CandDeMuxDigitListHandle& cdlh)
06565 {
06566   
06567   PlexSEIdAltL* paltlist;
06568   vector <PlexSEIdAltL*>::iterator literA;
06569   
06570   CandDeMuxDigitHandleItr cdhItr(cdlh.GetDaughterIterator());
06571   
06572   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::MakePixelMap" << endl;
06573   while ( CandDeMuxDigitHandle *digit = cdhItr() ) {
06574     // for each digit
06575     paltlist = &(digit->GetPlexSEIdAltLWritable());
06576     Int_t iplane = paltlist->GetPlane();
06577     if(!paltlist->IsVetoShield()){
06578       if(iplane>0&&iplane<MAX_NUMBER_OF_PLANES){
06579         for(Int_t iew=ALG_EAST;iew<=ALG_WEST;iew++){
06580           if(fPlanesAltLists[iplane][iew].size()>0){
06581             literA = fPlanesAltLists[iplane][iew].begin();
06582             while (literA != fPlanesAltLists[iplane][iew].end()){
06583               if((*literA)==paltlist){
06584                 (*literA)->SetFirst();
06585                 if(IsXTalk(paltlist)){
06586                   digit->SetDeMuxDigitFlagBit(CandDeMuxDigit::kXTalk);  
06587                   fXTalkPlanesAltLists[iplane][iew].push_back(*literA);
06588                 }
06589               }
06590               *literA++;
06591             }
06592           }
06593         }
06594       }else{
06595         MSG("AltDeMux", Msg::kWarning) << "AlgAltDeMuxBase::StripCrossTalkSingles - CandDigit with invalid plane  : " << iplane << endl;
06596       }
06597     }
06598   }
06599 
06600   // Remove cross talk hits from fPlanesAltLists 
06601 
06602   for(int iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
06603     for(int iew = ALG_EAST; iew<=ALG_WEST; iew++){
06604       if(fXTalkPlanesAltLists[iplane][iew].size()>0){
06605         literA = fXTalkPlanesAltLists[iplane][iew].begin();
06606         while (literA != fXTalkPlanesAltLists[iplane][iew].end()){
06607           RemoveFromPlanesList(iplane,iew,*literA);
06608           *literA++;
06609         }
06610       }
06611     }
06612   }
06613 
06614   return;
06615 }
06616 
06617 void AlgAltDeMuxBase::PrintWhatRemains()
06618 {
06619   vector <PlexSEIdAltL*>::iterator literE;
06620   vector <PlexSEIdAltL*>::iterator literW;
06621 
06622   for(int i=0; i<MAX_NUMBER_OF_PLANES; i++){
06623     if(fPlanesAltLists[i][ALG_EAST].size()||fPlanesAltLists[i][ALG_WEST].size()){
06624       MSG("AltDeMux",Msg::kVerbose) << "AlgAltDeMuxBase::PrintWhatRemains() PLANE : " << i << "has " << fPlaneHit[i] <<  " DeMuxed Hits, Left With   E : " << fPlanesAltLists[i][ALG_EAST].size() << ", W : " << fPlanesAltLists[i][ALG_WEST].size() << endl;
06625     }
06626 
06627     if(fPlanesAltLists[i][ALG_EAST].size()&&fPlanesAltLists[i][ALG_WEST].size()){
06628       literE = fPlanesAltLists[i][ALG_EAST].begin();
06629       while (literE != fPlanesAltLists[i][ALG_EAST].end()){
06630         literW = fPlanesAltLists[i][ALG_WEST].begin();
06631         while ( literW != fPlanesAltLists[i][ALG_WEST].end()){
06632           (*literE)->SetFirst();
06633           while( (*literE)->IsValid() ){
06634             (*literW)->SetFirst();
06635             while( (*literW)->IsValid() ){
06636               if((*literE)->GetCurrentSEId().GetStrip()==(*literW)->GetCurrentSEId().GetStrip()){
06637                 MSG("AltDeMux",Msg::kVerbose) << "AlgAltDeMuxBase::PrintWhatRemains() Poss " << i << " : " << (*literE)->GetCurrentItem().GetPE() << " : " << (*literW)->GetCurrentItem().GetPE() << " : " << (*literE)->GetCurrentSEId().GetStrip() << endl;
06638               }
06639               (*literW)->Next();
06640             }
06641             (*literE)->Next();
06642           }
06643           literW++;
06644         }
06645         literE++;
06646       }
06647     }
06648     if(fPlanesAltLists[i][ALG_EAST].size()){
06649       literE = fPlanesAltLists[i][ALG_EAST].begin();
06650       while (literE != fPlanesAltLists[i][ALG_EAST].end()){
06651         (*literE)->SetFirst();
06652         while( (*literE)->IsValid() ){
06653           MSG("AltDeMux",Msg::kVerbose) << "AlgAltDeMuxBase::PrintWhatRemains() Single possibilility : " << i << " : " << (*literE)->GetCurrentItem().GetPE() << " : " << (*literE)->GetCurrentSEId().GetStrip() << endl;
06654           (*literE)->Next();
06655         }
06656         literE++;
06657       }
06658     }
06659     if(fPlanesAltLists[i][ALG_WEST].size()){
06660       literW = fPlanesAltLists[i][ALG_WEST].begin();
06661       while (literW != fPlanesAltLists[i][ALG_WEST].end()){
06662         (*literW)->SetFirst();
06663         while( (*literW)->IsValid() ){
06664           MSG("AltDeMux",Msg::kVerbose) << "AlgAltDeMuxBase::PrintWhatRemains() Single possibilility : " << i << " : " << (*literW)->GetCurrentItem().GetPE() << " : " << (*literW)->GetCurrentSEId().GetStrip() << endl;
06665           (*literW)->Next();
06666         }
06667         literW++;
06668       }
06669     }
06670   }
06671   
06672   return;
06673 }
06674 
06675 
06676 
06677 void AlgAltDeMuxBase::PrintXTalk()
06678 {
06679   vector <PlexSEIdAltL*>::iterator literE;
06680   vector <PlexSEIdAltL*>::iterator literW;
06681   MSG("AltDeMux",Msg::kDebug) << "AlgAltDeMuxBase::PrintXTalk" << endl;
06682   for(int i=0; i<MAX_NUMBER_OF_PLANES; i++){
06683     if(fXTalkPlanesAltLists[i][ALG_EAST].size()||fXTalkPlanesAltLists[i][ALG_WEST].size()){
06684       if(amWriting)cout << " PLANE : " << i << "has " << fPlaneHit[i] <<  " DeMuxed Hits, Left With   E : " << fXTalkPlanesAltLists[i][ALG_EAST].size() << ", W : " << fXTalkPlanesAltLists[i][ALG_WEST].size() << endl;
06685     }
06686 
06687     if(fXTalkPlanesAltLists[i][ALG_EAST].size()&&fXTalkPlanesAltLists[i][ALG_WEST].size()){
06688       literE = fXTalkPlanesAltLists[i][ALG_EAST].begin();
06689       while (literE != fXTalkPlanesAltLists[i][ALG_EAST].end()){
06690         literW = fXTalkPlanesAltLists[i][ALG_WEST].begin();
06691         while ( literW != fXTalkPlanesAltLists[i][ALG_WEST].end()){
06692           (*literE)->SetFirst();
06693           while( (*literE)->IsValid() ){
06694             (*literW)->SetFirst();
06695             while( (*literW)->IsValid() ){
06696               if((*literE)->GetCurrentSEId().GetStrip()==(*literW)->GetCurrentSEId().GetStrip()){
06697                 if(amWriting)cout << " Poss " << i << " : " << (*literE)->GetCurrentItem().GetPE() << " : " << (*literW)->GetCurrentItem().GetPE() << " : " << (*literE)->GetCurrentSEId().GetStrip() << endl;
06698               }
06699               (*literW)->Next();
06700             }
06701             (*literE)->Next();
06702           }
06703           literW++;
06704         }
06705         literE++;
06706       }
06707     }
06708     if(fXTalkPlanesAltLists[i][ALG_EAST].size()){
06709       literE = fXTalkPlanesAltLists[i][ALG_EAST].begin();
06710       while (literE != fXTalkPlanesAltLists[i][ALG_EAST].end()){
06711         (*literE)->SetFirst();
06712         while( (*literE)->IsValid() ){
06713           if(amWriting)cout << " Single possibilility : " << i << " : " << (*literE)->GetCurrentItem().GetPE() << " : " << (*literE)->GetCurrentSEId().GetStrip() << endl;
06714           (*literE)->Next();
06715         }
06716         literE++;
06717       }
06718     }
06719     if(fXTalkPlanesAltLists[i][ALG_WEST].size()){
06720       literW = fXTalkPlanesAltLists[i][ALG_WEST].begin();
06721       while (literW != fXTalkPlanesAltLists[i][ALG_WEST].end()){
06722         (*literW)->SetFirst();
06723         while( (*literW)->IsValid() ){
06724           if(amWriting)cout << " Single possibilility : " << i << " : " << (*literW)->GetCurrentItem().GetPE() << " : " << (*literW)->GetCurrentSEId().GetStrip() << endl;
06725           (*literW)->Next();
06726         }
06727         literW++;
06728       }
06729     }
06730   }
06731   
06732   return;
06733 }
06734 
06735 
06736 
06737 
06738 void AlgAltDeMuxBase::PrintNoise()
06739 {
06740   vector <PlexSEIdAltL*>::iterator literE;
06741   vector <PlexSEIdAltL*>::iterator literW;
06742 
06743   for(int i=0; i<MAX_NUMBER_OF_PLANES; i++){
06744     if(fNoisePlanesAltLists[i][ALG_EAST].size()||fNoisePlanesAltLists[i][ALG_WEST].size()){
06745       cout << " PLANE : " << i << "has " << fPlaneHit[i] <<  " DeMuxed Hits, Left With   E : " << fNoisePlanesAltLists[i][ALG_EAST].size() << ", W : " << fNoisePlanesAltLists[i][ALG_WEST].size() << endl;
06746     }
06747 
06748     if(fNoisePlanesAltLists[i][ALG_EAST].size()&&fNoisePlanesAltLists[i][ALG_WEST].size()){
06749       literE = fNoisePlanesAltLists[i][ALG_EAST].begin();
06750       while (literE != fNoisePlanesAltLists[i][ALG_EAST].end()){
06751         literW = fNoisePlanesAltLists[i][ALG_WEST].begin();
06752         while ( literW != fNoisePlanesAltLists[i][ALG_WEST].end()){
06753           (*literE)->SetFirst();
06754           while( (*literE)->IsValid() ){
06755             (*literW)->SetFirst();
06756             while( (*literW)->IsValid() ){
06757               if((*literE)->GetCurrentSEId().GetStrip()==(*literW)->GetCurrentSEId().GetStrip()){
06758                 if(amWriting)cout << " Poss " << i << " : " << (*literE)->GetCurrentItem().GetPE() << " : " << (*literW)->GetCurrentItem().GetPE() << " : " << (*literE)->GetCurrentSEId().GetStrip() << endl;
06759               }
06760               (*literW)->Next();
06761             }
06762             (*literE)->Next();
06763           }
06764           literW++;
06765         }
06766         literE++;
06767       }
06768     }
06769     if(fNoisePlanesAltLists[i][ALG_EAST].size()){
06770       literE = fNoisePlanesAltLists[i][ALG_EAST].begin();
06771       while (literE != fNoisePlanesAltLists[i][ALG_EAST].end()){
06772         (*literE)->SetFirst();
06773         while( (*literE)->IsValid() ){
06774           if(amWriting)cout << " Single possibilility : " << i << " : " << (*literE)->GetCurrentItem().GetPE() << " : " << (*literE)->GetCurrentSEId().GetStrip() << endl;
06775           (*literE)->Next();
06776         }
06777         literE++;
06778       }
06779     }
06780     if(fNoisePlanesAltLists[i][ALG_WEST].size()){
06781       literW = fNoisePlanesAltLists[i][ALG_WEST].begin();
06782       while (literW != fNoisePlanesAltLists[i][ALG_WEST].end()){
06783         (*literW)->SetFirst();
06784         while( (*literW)->IsValid() ){
06785           if(amWriting)cout << " Single possibilility : " << i << " : " << (*literW)->GetCurrentItem().GetPE() << " : " << (*literW)->GetCurrentSEId().GetStrip() << endl;
06786           (*literW)->Next();
06787         }
06788         literW++;
06789       }
06790     }
06791   }
06792   
06793   return;
06794 }
06795 
06796 
06797 
06798 
06799 void AlgAltDeMuxBase::FitAsCosmic(bool useSingles)
06800 {
06801   Float_t weightedStrip[MAX_NUMBER_OF_PLANES];
06802   Float_t Qtotal[MAX_NUMBER_OF_PLANES];
06803 
06804   vector<DeMuxFitData_t>HitsU;
06805   vector<DeMuxFitData_t>HitsV;
06806   vector<DeMuxFitData_t>QHitsU;
06807   vector<DeMuxFitData_t>QHitsV;
06808   vector<DeMuxFitData_t>TimesU;
06809   vector<DeMuxFitData_t>TimesV;
06810  
06811   Int_t lowestUplane=999;
06812   Int_t lowestVplane=999;
06813   Int_t highestUplane=-999;
06814   Int_t highestVplane=-999;
06815 
06816   if(fEventType==MULTIPLE_MUON)return;
06817 
06818   for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
06819     Qtotal[iplane] = 0.0;
06820     Float_t Qw = 0.0;
06821     Float_t Q  = 0.0;
06822     for(UInt_t ipair=0;ipair<fDeMuxedPairs[iplane].size();ipair++){
06823       Int_t istrip = fDeMuxedPairs[iplane][ipair].altListE->GetBestSEId().GetStrip();
06824       Q += fDeMuxedPairs[iplane][ipair].pairQCor;      
06825       Qw+= istrip*fDeMuxedPairs[iplane][ipair].pairQCor;
06826       PlaneView::PlaneView_t kView = fDeMuxedPairs[iplane][ipair].altListE->GetPlaneView();
06827       if(kView==PlaneView::kU){
06828         if(iplane<lowestUplane)lowestUplane=iplane;
06829         if(iplane>highestUplane)highestUplane=iplane;
06830       }
06831       if(kView==PlaneView::kV){
06832         if(iplane<lowestVplane)lowestVplane=iplane;
06833         if(iplane>highestVplane)highestVplane=iplane;
06834       }
06835     }
06836     if(useSingles){
06837       for(UInt_t isingle=0;isingle<fDeMuxedSingles[iplane].size();isingle++){
06838         Int_t istrip = fDeMuxedSingles[iplane][isingle].altList->GetBestSEId().GetStrip();
06839         Q  += fDeMuxedSingles[iplane][isingle].Qcor;      
06840         Qw += istrip*fDeMuxedSingles[iplane][isingle].Qcor;
06841         PlaneView::PlaneView_t kView = fDeMuxedSingles[iplane][isingle].altList->GetPlaneView();
06842         if(kView==PlaneView::kU){
06843           if(iplane<lowestUplane)lowestUplane=iplane;
06844           if(iplane>highestUplane)highestUplane=iplane;
06845         }
06846         if(kView==PlaneView::kV){
06847           if(iplane<lowestVplane)lowestVplane=iplane;
06848           if(iplane>highestVplane)highestVplane=iplane;
06849         }
06850       }
06851     }
06852     if(Q>0)weightedStrip[iplane] = Qw/Q;
06853     if(Q>0)Qtotal[iplane] = Q;
06854     //if(Q>0)cout << " Weighted : " << iplane << ":" << Qw/Q << " using : " << Q << endl;
06855   }
06856   // Decide on appropriate level of Q cut for weighted plane fit
06857 
06858   Float_t Ntotal = 0;
06859   Float_t Nabove1=0;
06860   Float_t Nabove2=0;
06861   Float_t Nabove3=0;
06862   for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
06863     if(Qtotal[iplane]>0){
06864       Ntotal++;
06865       if(Qtotal[iplane]>3)Nabove1++;
06866       if(Qtotal[iplane]>5)Nabove2++;
06867       if(Qtotal[iplane]>10)Nabove3++;
06868     }
06869   }
06870   Float_t Qcut = 3.0;
06871   if(Ntotal>0.0){
06872     if(amWriting){
06873       cout << "fraction above 3 pe  " << Nabove1/Ntotal << endl;
06874       cout << "fraction above 5 pe  " << Nabove2/Ntotal << endl;
06875       cout << "fraction above 10 pe " << Nabove3/Ntotal << endl;
06876     }
06877     if(Nabove2/Ntotal > 0.8)Qcut= 5.0;
06878     if(Nabove3/Ntotal > 0.8)Qcut=10.0;
06879   }
06880 
06881 
06882 
06883   // Deal with the pairs
06884 
06885   for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
06886     for(UInt_t ipair=0;ipair<fDeMuxedPairs[iplane].size();ipair++){
06887       PlaneView::PlaneView_t kView = fDeMuxedPairs[iplane][ipair].altListE->GetPlaneView();
06888       Int_t istrip = fDeMuxedPairs[iplane][ipair].altListE->GetBestSEId().GetStrip();
06889       Int_t isaim  = fDeMuxedPairs[iplane][ipair].orthogonalStripFromTiming;
06890       Int_t jplane = iplane;
06891       if(jplane>249)jplane+=20;
06892       DeMuxFitData_t hit;
06893       DeMuxFitData_t time;
06894       hit.x = jplane;
06895       hit.y = istrip;
06896       hit.status = true;
06897       time.x = jplane;
06898       time.y = isaim;
06899       time.status = true;
06900       if(kView==PlaneView::kV){
06901         if(iplane>=lowestUplane-1&&iplane<=highestUplane+1){
06902           HitsV.push_back(hit);
06903           TimesU.push_back(time);
06904         }
06905       }
06906       if(kView==PlaneView::kU){
06907         if(iplane>=lowestVplane-1&&iplane<=highestVplane+1){
06908           HitsU.push_back(hit);
06909           TimesV.push_back(time);
06910         }
06911       }
06912     }
06913   }
06914 
06915 
06916   if(useSingles){
06917     for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
06918       for(UInt_t isingle=0;isingle<fDeMuxedSingles[iplane].size();isingle++){
06919         PlaneView::PlaneView_t kView = fDeMuxedSingles[iplane][isingle].altList->GetPlaneView();
06920         Int_t istrip = fDeMuxedSingles[iplane][isingle].altList->GetBestSEId().GetStrip();
06921         Int_t jplane = iplane;
06922         if(jplane>249)jplane+=20;
06923         DeMuxFitData_t hit;
06924         hit.x = jplane;
06925         hit.y = istrip;
06926         hit.status = true;
06927         if(kView==PlaneView::kV){
06928           if(iplane>=lowestUplane-1&&iplane<=highestUplane+1)HitsV.push_back(hit);
06929         }
06930         if(kView==PlaneView::kU){
06931           if(iplane>=lowestVplane-1&&iplane<=highestVplane+1)HitsU.push_back(hit);
06932         }
06933       }
06934     }
06935   }
06936 
06937   for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
06938     Int_t usedHits = fDeMuxedPairs[iplane].size();
06939     if(useSingles)usedHits+=fDeMuxedSingles[iplane].size();
06940     if(usedHits>0 && Qtotal[iplane]>Qcut){
06941       PlaneView::PlaneView_t kView = fUVMap[iplane];
06942       Int_t jplane = iplane;
06943       if(jplane>249)jplane+=20;
06944       DeMuxFitData_t hit;
06945       hit.x = jplane;
06946       hit.y = weightedStrip[iplane];
06947       hit.status = true;
06948       if(kView==PlaneView::kV){
06949         if(iplane>=lowestUplane-1&&iplane<=highestUplane+1)QHitsV.push_back(hit);
06950       }
06951       if(kView==PlaneView::kU){
06952         if(iplane>=lowestVplane-1&&iplane<=highestVplane+1)QHitsU.push_back(hit);
06953       }
06954     }
06955   }
06956 
06957   fFitHitU  = LinearFit(HitsU, 15.0);
06958   fFitHitV  = LinearFit(HitsV, 15.0);
06959   fFitQHitU = LinearFit(QHitsU, 15.0);
06960   fFitQHitV = LinearFit(QHitsV, 15.0);
06961   fFitTimeU = LinearFit(TimesU);
06962   fFitTimeV = LinearFit(TimesV);
06963 
06964   if(fDiagnosticPlots){
06965     MakeFitPolyLines(fFitQHitU,fUZFitQSSM1,fUZFitQSSM2,2,1);
06966     MakeFitPolyLines(fFitQHitV,fVZFitQSSM1,fVZFitQSSM2,2,1);
06967     MakeFitPolyLines(fFitHitU,fUZFitSSM1,fUZFitSSM2);
06968     MakeFitPolyLines(fFitHitV,fVZFitSSM1,fVZFitSSM2);
06969     MakeFitPolyLines(fFitTimeU,fUZFitTSM1,fUZFitTSM2,4,2);
06970     MakeFitPolyLines(fFitTimeV,fVZFitTSM1,fVZFitTSM2,4,2);
06971   }
06972 
06973 
06974   if(fDiagnosticPlots)this->DrawDiagnosticPlots(5);
06975 
06976   MSG("AltDeMux", Msg::kDebug) << "AlgDeMuxBase::FitAsCosmic() chi2 U HitsQ" << fFitQHitU.chi2 << " ndof = " << fFitQHitU.nUsed-2 << endl;
06977   MSG("AltDeMux", Msg::kDebug) << "AlgDeMuxBase::FitAsCosmic() chi2 V HitsQ" << fFitQHitV.chi2 << " ndof = " << fFitQHitV.nUsed-2 << endl;
06978   MSG("AltDeMux", Msg::kDebug) << "AlgDeMuxBase::FitAsCosmic() chi2 U Hits " << fFitHitU.chi2 << " ndof = " << fFitHitU.nUsed-2 << endl;
06979   MSG("AltDeMux", Msg::kDebug) << "AlgDeMuxBase::FitAsCosmic() chi2 V Hits" << fFitHitV.chi2 << " ndof = " << fFitHitV.nUsed-2 << endl;
06980   MSG("AltDeMux", Msg::kDebug) << "AlgDeMuxBase::FitAsCosmic() c2U  U Time " << fFitTimeU.chi2<< " ndof = " << fFitTimeU.nUsed-2 << endl;
06981   MSG("AltDeMux", Msg::kDebug) << "AlgDeMuxBase::FitAsComsic() c2V  V Time " << fFitTimeV.chi2<< " ndof = " << fFitTimeV.nUsed-2 << endl;
06982 
06983   
06984   bool doReMux = false;
06985   if(fFitQHitU.nUsed>4&&fFitQHitV.nUsed>4){
06986     if(fFitQHitU.chi2pdf<5.0&&fFitQHitV.chi2pdf<5.0){
06987       if(fEventType==UNKNOWN){
06988         MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::FitAsCosmic - Event Identified as Single Muon : " << fFitQHitV.nUsed << "," << fFitQHitU.nUsed << ":" << fFitQHitU.chi2 << "," << fFitQHitV.chi2 <<endl; 
06989         fEventType = SINGLE_MUON;
06990       }
06991       if(fEventType==SINGLE_MUON||fEventType==THROUGH_GOING_MUON||fEventType==STRAIGHT_THROUGH_GOING_MUON)doReMux = true;
06992     }
06993   }
06994   if(fDiagnosticPlots)this->DrawDiagnosticPlots(5);
06995 
06996   if(doReMux){
06997     for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
06998       bool carryOn =true;
06999       for(UInt_t ipair=0; carryOn && ipair<fDeMuxedPairs[iplane].size(); ipair++){
07000         PlaneView::PlaneView_t kView = fDeMuxedPairs[iplane][0].altListE->GetPlaneView();
07001         Int_t jplane = iplane;
07002         if(jplane>249)jplane+=20;
07003         Int_t istrip = fDeMuxedPairs[iplane][ipair].altListE->GetBestSEId().GetStrip();
07004         Double_t yFromFit = 0;
07005         if(kView==PlaneView::kU)yFromFit = fFitQHitU.a0 + fFitQHitU.a1*jplane;
07006         if(kView==PlaneView::kV)yFromFit = fFitQHitV.a0 + fFitQHitV.a1*jplane;
07007         Double_t delta = fabs(istrip-yFromFit);
07008         if(delta>12){
07009           this->ReMuxPlane(iplane);
07010           carryOn = false;
07011         }
07012       }
07013       if(carryOn&&useSingles){
07014         for(UInt_t isingle=0; carryOn && isingle<fDeMuxedSingles[iplane].size(); isingle++){
07015           PlaneView::PlaneView_t kView = fDeMuxedSingles[iplane][isingle].altList->GetPlaneView();
07016           Int_t jplane = iplane;
07017           if(jplane>249)jplane+=20;
07018           Int_t istrip = fDeMuxedSingles[iplane][isingle].altList->GetBestSEId().GetStrip();
07019           Double_t yFromFit = 0.;
07020           if(kView==PlaneView::kU)yFromFit = fFitQHitU.a0 + fFitQHitU.a1*jplane;
07021           if(kView==PlaneView::kV)yFromFit = fFitQHitV.a0 + fFitQHitV.a1*jplane;
07022           Double_t delta = fabs(istrip-yFromFit);
07023           if(delta>12){
07024             this->ReMuxPlane(iplane);
07025             carryOn = false;
07026           }
07027         }
07028       }
07029     }
07030     if(fDiagnosticPlots)this->DrawDiagnosticPlots(5);
07031   }
07032 }
07033 
07034 
07035 
07036 
07037 void AlgAltDeMuxBase::CleanMultiple()
07038 {
07039 
07040 
07041   if(fDiagnosticPlots)DrawDiagnosticPlots(5);
07042 
07043   if(fEventType!=MULTIPLE_MUON){
07044     return;
07045   }
07046 
07047   // Deal with the pairs
07048 
07049   for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
07050     bool needReMux = false;
07051     for(UInt_t ipair=0;!needReMux&&ipair<fDeMuxedPairs[iplane].size();ipair++){
07052       PlaneView::PlaneView_t kView = fDeMuxedPairs[iplane][ipair].altListE->GetPlaneView();
07053       Int_t istrip = fDeMuxedPairs[iplane][ipair].altListE->GetBestSEId().GetStrip();
07054       Int_t jplane = iplane;
07055       if(jplane>249)jplane+=20;
07056       bool hitIsGood = false;
07057       if(kView==PlaneView::kU){
07058         for(UInt_t iline=0; !hitIsGood&&iline<multipleMuonInterceptsU.size();iline++){
07059           Float_t delta = fabs(fHoughSlopeU*jplane + multipleMuonInterceptsU[iline] -istrip);
07060 
07061           if(delta<13)hitIsGood=true; 
07062         }
07063       }
07064       if(kView==PlaneView::kV){
07065         for(UInt_t iline=0; !hitIsGood&&iline<multipleMuonInterceptsV.size();iline++){
07066           Float_t delta = fabs(fHoughSlopeV*jplane + multipleMuonInterceptsV[iline] -istrip);
07067           if(delta<13)hitIsGood=true; 
07068         }
07069       }
07070       if(!hitIsGood)needReMux=true;
07071     }
07072     for(UInt_t isingle=0;isingle<fDeMuxedSingles[iplane].size();isingle++){
07073       PlaneView::PlaneView_t kView = fDeMuxedSingles[iplane][isingle].altList->GetPlaneView();
07074       Int_t istrip = fDeMuxedSingles[iplane][isingle].altList->GetBestSEId().GetStrip();
07075       Int_t jplane = iplane;
07076       if(jplane>249)jplane+=20;
07077       bool hitIsGood = false;
07078       if(kView==PlaneView::kU){
07079         for(UInt_t iline=0; !hitIsGood&&iline<multipleMuonInterceptsU.size();iline++){
07080           Float_t delta = fabs(fHoughSlopeU*jplane + multipleMuonInterceptsU[iline] -istrip);
07081 
07082           if(delta<13)hitIsGood=true; 
07083         }
07084       }
07085       if(kView==PlaneView::kV){
07086         for(UInt_t iline=0; !hitIsGood&&iline<multipleMuonInterceptsV.size();iline++){
07087           Float_t delta = fabs(fHoughSlopeV*jplane + multipleMuonInterceptsV[iline] -istrip);
07088           if(delta<13)hitIsGood=true; 
07089         }
07090       }
07091       if(!hitIsGood)needReMux=true;
07092     }
07093     if(needReMux)MSG("AltDeMux",Msg::kVerbose) << "AlgAltDeMuxBase::CleanMultiple Will ReMux Plane : " << iplane << endl;
07094     if(needReMux)ReMuxPlane(iplane);
07095   }
07096 
07097   if(fDiagnosticPlots)DrawDiagnosticPlots(5);
07098 }
07099 
07100 
07101 
07102 void AlgAltDeMuxBase::Hough()
07103 {
07104   
07105   const Int_t MAX_NUMBER_OF_GROUPS=10000; 
07106 
07107   Float_t groupQ[MAX_NUMBER_OF_GROUPS];
07108   Float_t NU=0;
07109   Float_t NV=0;
07110   Float_t xU=0;
07111   Float_t xV=0;
07112   Float_t yU=0;
07113   Float_t yV=0;
07114   Float_t yUT=0;
07115   Float_t yVT=0;
07116   Int_t   icMinU=499;
07117   Int_t   icMaxU=0;
07118   Int_t   icMinV=499;
07119   Int_t   icMaxV=0;
07120   Float_t HU[400];
07121   Float_t HV[400];
07122   Float_t HSU[400][MAX_NUMBER_OF_PLANES];
07123   Float_t HSV[400][MAX_NUMBER_OF_PLANES];
07124   for(Int_t i=0; i<MAX_NUMBER_OF_GROUPS;i++)groupQ[i]=0;
07125 
07126   for(Int_t i=0; i<400;i++){
07127     HU[i] = 0;
07128     HV[i] = 0;
07129     for(Int_t j=0; j<MAX_NUMBER_OF_PLANES;j++){
07130       HSU[i][j] = 0;
07131       HSV[i][j] = 0;
07132     }
07133   }
07134 
07135   MSG("AltDeMux",Msg::kDebug) << "AlgAltDeMuxBase::Hough  performing new Hough transform" << endl;
07136   for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
07137     for(UInt_t ipair=0;ipair<fDeMuxedPairs[iplane].size();ipair++){
07138       if(fDeMuxedPairs[iplane][ipair].uniqueGroupID>=MAX_NUMBER_OF_GROUPS)MSG("AltDeMux",Msg::kFatal) << "AlgAltDeMuxBase::Hough  uniqueGroupID too large" << endl;
07139       groupQ[fDeMuxedPairs[iplane][ipair].uniqueGroupID] += fDeMuxedPairs[iplane][ipair].pairQCor;
07140     }
07141   }
07142   for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
07143     for(UInt_t ipair=0;ipair<fDeMuxedPairs[iplane].size();ipair++){
07144       fDeMuxedPairs[iplane][ipair].weightQ =  fDeMuxedPairs[iplane][ipair].pairQCor/groupQ[fDeMuxedPairs[iplane][ipair].uniqueGroupID];
07145     }
07146   }
07147 
07148   for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
07149     for(UInt_t ipair=0;ipair<fDeMuxedPairs[iplane].size();ipair++){
07150       PlaneView::PlaneView_t kView = fDeMuxedPairs[iplane][ipair].altListE->GetPlaneView();
07151       Int_t istrip = fDeMuxedPairs[iplane][ipair].altListE->GetBestSEId().GetStrip();
07152       if(kView==PlaneView::kU){
07153         NU  += 1.;
07154         xU  = iplane-(fHighestDeMuxedPairPlane+fLowestDeMuxedPairPlane)/2.;
07155         if(iplane>249)xU=xU+20.;
07156         yU  = istrip-96.;
07157         yUT = fDeMuxedPairs[iplane][ipair].orthogonalStripFromTiming;
07158         for(Int_t im=0;im<200;im++){
07159           Float_t m = (im/100.)-0.995;
07160           Float_t c = yU-m*xU;
07161           Int_t ic = 250+static_cast<Int_t>(c); 
07162           if(fDiagnosticPlots)fHoughU->Fill(m,c,fDeMuxedPairs[iplane][ipair].weightQ);
07163           if(ic>0&&ic<MAX_NUMBER_OF_PLANES){
07164             HSU[im+200][ic]+=fDeMuxedPairs[iplane][ipair].weightQ;
07165           }
07166           c = xU-m*yU;
07167           ic = 250+static_cast<Int_t>(c); 
07168           m = -2.-m;
07169           if(fDiagnosticPlots)fHoughU->Fill(m,c,fDeMuxedPairs[iplane][ipair].weightQ);
07170           if(ic>0&&ic<MAX_NUMBER_OF_PLANES){
07171             HSU[199-im][ic]+=fDeMuxedPairs[iplane][ipair].weightQ;
07172             if(ic>icMaxU)icMaxU=ic;
07173             if(ic<icMinU)icMinU=ic;
07174           }
07175         }
07176       }
07177       
07178       
07179 
07180       if(kView==PlaneView::kV){
07181         NV  += 1.;
07182         xV  = iplane-(fHighestDeMuxedPairPlane+fLowestDeMuxedPairPlane)/2.;
07183         if(iplane>249)xV=xV+20.;
07184         yV  = istrip-96.;
07185         yVT = fDeMuxedPairs[iplane][ipair].orthogonalStripFromTiming;
07186         for(Int_t im=0;im<200;im++){
07187           Float_t m = (im/100.)-0.995;
07188           Float_t c = yV-m*xV;
07189           Int_t ic = 250+static_cast<Int_t>(c); 
07190           if(fDiagnosticPlots)fHoughV->Fill(m,c,fDeMuxedPairs[iplane][ipair].weightQ);
07191           if(ic>0&&ic<MAX_NUMBER_OF_PLANES){
07192             HSV[im+200][ic]+=fDeMuxedPairs[iplane][ipair].weightQ;
07193           }
07194           c = xV-m*yV;
07195           ic = 250+static_cast<Int_t>(c); 
07196           m = -2.-m;
07197           if(fDiagnosticPlots)fHoughV->Fill(m,c,fDeMuxedPairs[iplane][ipair].weightQ);
07198           if(ic>0&&ic<MAX_NUMBER_OF_PLANES){
07199           HSV[199-im][ic]+=fDeMuxedPairs[iplane][ipair].weightQ;
07200           if(ic>icMaxV)icMaxV=ic;
07201           if(ic<icMinV)icMinV=ic;
07202           }
07203         }
07204       }
07205     }
07206   }  
07207   // 10 ms/event upto here.
07208   // 11 ms/event with icMaxV...
07209   if(fDiagnosticPlots){
07210     fUpad->cd();
07211     fHoughU->Draw();
07212     fVpad->cd();
07213     fHoughV->Draw();
07214     fCanvas->Update();
07215   }
07216 
07217 
07218   Int_t   imU = 0;
07219   Int_t   imV = 0;
07220   Float_t umax=-999.;
07221   Float_t vmax=-999.;
07222 
07223   for(Int_t i=0; i<400;i++){
07224     Float_t m = (static_cast<Float_t>(i))/100.0-2.995;
07225     for(Int_t j=icMinU; j<icMaxU;j++){
07226       if(HSU[i][j]>0)HU[i] += HSU[i][j]*HSU[i][j];
07227     }
07228     for(Int_t j=icMinV; j<icMaxV;j++){
07229       if(HSV[i][j]>0)HV[i] += HSV[i][j]*HSV[i][j];
07230     }
07231     if(fDiagnosticPlots){
07232       fHoughProjU->Fill(m,HU[i]);
07233       fHoughProjV->Fill(m,HV[i]);
07234     }
07235     if(HU[i]>umax){
07236       umax=HU[i];
07237       imU = i;
07238     }
07239     if(HV[i]>vmax){
07240       vmax=HV[i];
07241       imV = i;
07242     }
07243   }
07244   // 20 ms/event upto here.
07245   // 15 ms/event with icMax
07246 
07247   // Look at width of peaks in Hough space
07248   Int_t   imUm=999;
07249   Int_t   imVm=999;
07250   Int_t   imUp=0;
07251   Int_t   imVp=0;
07252 
07253   bool foundU = false;
07254   bool foundV = false;
07255   for(Int_t i=0; i<400;i++){
07256     if(!foundU && HU[i]>umax/2.0){
07257       imUm = i;
07258       foundU = true;
07259     }
07260     if(!foundV && HV[i]>vmax/2.0){
07261       imVm = i;
07262       foundV = true;
07263     }
07264   }
07265 
07266   foundU = false;
07267   foundV = false;
07268   for(Int_t i=400; i>0;i--){
07269     if(!foundU && HU[i]>umax/2.0){
07270       imUp = i;
07271       foundU = true;
07272     }
07273     if(!foundV && HV[i]>vmax/2.0){
07274       imVp = i;
07275       foundV = true;
07276     }
07277   }
07278 
07279   Float_t houghUwidth = static_cast<Float_t>(imUp-imUm);
07280   Float_t houghVwidth = static_cast<Float_t>(imVp-imVm);
07281 
07282   fHoughSlopeU = (static_cast<Float_t>(imU))/100.0-2.995;
07283   if(fHoughSlopeU<-1.)fHoughSlopeU = 1.0/(-2.0-fHoughSlopeU);
07284   fHoughSlopeV = (static_cast<Float_t>(imV))/100.0-2.995;
07285   if(fHoughSlopeV<-1.)fHoughSlopeV = 1.0/(-2.0-fHoughSlopeV);
07286 
07287   Int_t nUTracks = 0;
07288   Int_t nVTracks = 0;
07289 
07290 
07291   MSG("AltDeMux",Msg::kDebug) << "AlgAltDeMuxBase::Hough Gradient from U Hough Space : " << fHoughSlopeU << endl;
07292   MSG("AltDeMux",Msg::kDebug) << "AlgAltDeMuxBase::Hough Gradient from V Hough Space : " << fHoughSlopeV << endl;
07293 
07294   if(fDiagnosticPlots){
07295     fUpad->cd();
07296     fHoughProjU->Draw();
07297     fVpad->cd();
07298     fHoughProjV->Draw();
07299     fCanvas->Update();
07300     for(Int_t i=0; i<MAX_NUMBER_OF_PLANES;i++){
07301       Float_t c = static_cast<Float_t>(i)-250.;
07302       fHoughSliceU->Fill(c,HSU[imU][i]);
07303       fHoughSliceV->Fill(c,HSV[imV][i]);
07304     }
07305     fUpad->cd();
07306     fHoughSliceU->Draw();
07307     fVpad->cd();
07308     fHoughSliceV->Draw();
07309     fCanvas->Update();
07310   }
07311 
07312   Float_t fTrackCut = 2.5;
07313   Float_t fHCTrackCut = 6.0;
07314   Float_t fTrackCutS = 2.5;
07315   if(houghUwidth>20||houghVwidth>20)fTrackCutS = 3.5;
07316   if(houghUwidth>20&&houghVwidth>20)fTrackCutS = 4.5;
07317   if(fEventType==MULTIPLE_MUON)fTrackCut = 1.5;
07318 
07319 
07320   multipleMuonInterceptsU.erase(multipleMuonInterceptsU.begin(),multipleMuonInterceptsU.end());
07321   multipleMuonInterceptsV.erase(multipleMuonInterceptsV.begin(),multipleMuonInterceptsV.end());
07322 
07323   Int_t NUTR = 0;
07324   Int_t NVTR = 0;
07325 
07326   Int_t NHighConfidenceUTR = 0;
07327   Int_t NHighConfidenceVTR = 0;
07328 
07329   
07330   for(Int_t i=1; i<499;i++){
07331     if( (HSU[imU][i]>HSU[imU][i-1])&&(HSU[imU][i]>=HSU[imU][i+1])){
07332       if(HSU[imU][i]>fTrackCut){
07333         // found local maximum - but is it the best in the group
07334         Float_t maxInGroup = 0.;
07335         bool found = false; 
07336         for(Int_t j=i; !found && j<499;j++){
07337           if(HSU[imU][j]>maxInGroup)maxInGroup=HSU[imU][j];
07338           if(HSU[imU][j]<0.25)found=true;
07339         }
07340         found = false;
07341         for(Int_t j=i; !found && j>1;j--){
07342           if(HSU[imU][j]>maxInGroup)maxInGroup=HSU[imU][j];
07343           if(HSU[imU][j]<0.25)found=true;
07344         }
07345         if(HSU[imU][i]>maxInGroup/2.0 && HSU[imU][i]>fTrackCutS){
07346           NUTR++;
07347           if(HSU[imU][i]>fHCTrackCut && houghUwidth<10)NHighConfidenceUTR++;
07348         }
07349         nUTracks++;
07350         if(imU>=200){
07351           Float_t c = 96.0 - 250.0 + i - fHoughSlopeU*(fHighestDeMuxedPairPlane+fLowestDeMuxedPairPlane)/2.;
07352           if(amWriting)cout << " shallow U intercept : " << i << " -> " << c << endl;
07353           multipleMuonInterceptsU.push_back(c);
07354         }
07355         if(imU<200 ){
07356           Float_t c = 96. - ((fHighestDeMuxedPairPlane+fLowestDeMuxedPairPlane)/2. +i-250)*fHoughSlopeU;
07357           if(amWriting)cout << " steep   U intercept : " << i << " -> " << c << endl;
07358           multipleMuonInterceptsU.push_back(c);
07359         }
07360       }
07361     }
07362   }
07363 
07364   for(Int_t i=1; i<499;i++){
07365     if((HSV[imV][i]>HSV[imV][i-1])&&(HSV[imV][i]>=HSV[imV][i+1])){
07366       if(HSV[imV][i]>fTrackCut){
07367 
07368         Float_t maxInGroup = 0.;
07369         bool found = false; 
07370         for(Int_t j=i; !found && j<499;j++){
07371           if(HSV[imV][j]>maxInGroup)maxInGroup=HSV[imV][j];
07372           if(HSV[imV][j]<0.25)found=true;
07373         }
07374         found = false;
07375         for(Int_t j=i; !found && j>1;j--){
07376           if(HSV[imV][j]>maxInGroup)maxInGroup=HSV[imV][j];
07377           if(HSV[imV][j]<0.25)found=true;
07378         }
07379 
07380 
07381         if(HSV[imV][i]>maxInGroup/2.0 && HSV[imV][i]>fTrackCutS){
07382           NVTR++;
07383           if(HSV[imV][i]>fHCTrackCut && houghVwidth<10)NHighConfidenceVTR++;
07384         }
07385         nVTracks++;
07386         if(imV>=200){
07387           Float_t c = 96.0 - 250.0 + i-fHoughSlopeV*(fHighestDeMuxedPairPlane+fLowestDeMuxedPairPlane)/2.;
07388           if(amWriting)cout << " shallow V intercept : " << i << " -> " << c << endl;
07389           multipleMuonInterceptsV.push_back(c);
07390         }
07391         if(imV<200 ){
07392           Float_t c = 96 - ( (fHighestDeMuxedPairPlane+fLowestDeMuxedPairPlane)/2. +i-250)*fHoughSlopeV;
07393           if(amWriting)cout << " steep   V intercept : " << i << " -> " << c << endl;
07394           multipleMuonInterceptsV.push_back(c);
07395         }
07396       }
07397     }
07398   }
07399 
07400   MSG("AltDeMux",Msg::kDebug) << "AlgAltDeMuxBase::Hough Hough multiplicity : " << nUTracks << "," << NUTR << endl; 
07401   MSG("AltDeMux",Msg::kDebug) << "AlgAltDeMuxBase::Hough Hough multiplicity : " << nUTracks << "," << NVTR << endl; 
07402   // 15ms/event
07403   fHoughStatus = true;
07404   if(fabs(fHoughSlopeU)>50.||fabs(fHoughSlopeV)>50.){
07405     MSG("AltDeMux", Msg::kWarning) << "AlgAltDeMuxBase::Hough - Gradient too steep  : " << fHoughSlopeU << "," << fHoughSlopeV << endl;
07406     fHoughStatus = false;
07407   }
07408 
07409   if(fHoughStatus==true){
07410     if(nUTracks>=2&&nVTracks>=2 && NUTR>=2&&NVTR>=2){
07411       // looks like a multiple muon
07412       // but check to see if it is coming from FNAL
07413       // before tagging it as such
07414       float cosfnal=0.;
07415       float mx = 0.4914*(fHoughSlopeU-fHoughSlopeV);
07416       float my = 0.4914*(fHoughSlopeU+fHoughSlopeV);
07417       float mz = 1.0;
07418       float norm = sqrt(1.0+mx*mx+my*my);
07419       cosfnal = 0.058*my/norm+0.9983*mz/norm;
07420 
07421       MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::Hough - Event Identified as Multiple Muon, multiplicity : " << nUTracks << "," << nVTracks << endl; 
07422       MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::Hough - Event Identified as Multiple Muon, multiplicity : " << NUTR << "," << NVTR << endl; 
07423       
07424       if(amWriting){
07425         cout << " h widths  " << houghUwidth << "," <<  houghVwidth << endl;
07426         cout << " HC counts " << NHighConfidenceUTR << "," << NHighConfidenceVTR << endl;    
07427         cout << " cosfnal : " << cosfnal << endl;
07428       }
07429       if(cosfnal>0.85){
07430         MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::Hough() - Event Identified as Multiple Muon, BUT coming from FNAL" << endl;
07431 //      cout << " MULTIPLE FROM FNAL " << endl;
07432         //getchar();
07433       }else{
07434         MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::Hough - Event Identified as Multiple Muon, multiplicity : " << nUTracks << "," << nVTracks << endl; 
07435         MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::Hough - Event Identified as Multiple Muon, multiplicity : " << NUTR << "," << NVTR << endl; 
07436         fEventType = MULTIPLE_MUON;
07437         if(amWriting){
07438           cout << " **** U ---> " << houghUwidth << endl;
07439           cout << " **** V ---> " << houghVwidth << endl;
07440         }
07441         if(fDiagnosticPlots){
07442           fUpad->cd();
07443           fHoughProjU->Draw();
07444           fVpad->cd();
07445           fHoughProjV->Draw();
07446           fCanvas->Update();
07447         }
07448       }
07449     }
07450   }
07451   
07452   return;
07453 
07454 }
07455 
07456 
07457 void AlgAltDeMuxBase::ReBuildXTalkMap(){
07458   
07459   for(int i=0; i<MAX_NUMBER_OF_PMTS; i++){
07460     if(fPMTtot[i]>0){
07461       for(int j=0; j<16; j++){
07462         fXTalkmap[i][j]=0.0;
07463         fPMTmap[i][j]=0.0;
07464       }
07465       fPMTtot[i]=0;
07466     }
07467   }
07468 
07469   for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
07470     for(UInt_t ipair=0;ipair<fDeMuxedPairs[iplane].size();ipair++){
07471       this->UpdateXTalkMap(fDeMuxedPairs[iplane][ipair].altListE);
07472       this->UpdateXTalkMap(fDeMuxedPairs[iplane][ipair].altListW);
07473     }
07474     for(UInt_t isingle=0;isingle<fDeMuxedSingles[iplane].size();isingle++){
07475       this->UpdateXTalkMap(fDeMuxedSingles[iplane][isingle].altList);
07476     }
07477   }
07478 
07479   return;
07480 }
07481 
07482 void AlgAltDeMuxBase::CleanIsolatedHits(){
07483  
07484   Int_t easthits;
07485   Int_t westhits;
07486   Int_t ilow;
07487   Int_t ihigh;
07488   Int_t nlow;
07489   Int_t nhigh = 0;
07490   Int_t ilower;
07491   Int_t ihigher;
07492   Int_t nlower;
07493   Int_t nhigher;
07494   Int_t sl;
07495   Int_t sh;
07496   Int_t sll;
07497   Int_t shh;
07498 
07499   Int_t bestdm;
07500   vector<int> stripE;
07501   vector<int> stripW;
07502   PlexSEIdAltL* stripMapE[MAX_NUMBER_OF_STRIPS];
07503   PlexSEIdAltL* stripMapW[MAX_NUMBER_OF_STRIPS];
07504 
07505   int increment = 1;
07506   for(Int_t iplane=0; iplane<MAX_NUMBER_OF_PLANES;iplane+=increment){
07507     bool found = false;
07508     for(unsigned int i = 0;!found && i<fDeMuxedSingles[iplane].size();i++){
07509       for(unsigned int j = i+1;!found && j<fDeMuxedSingles[iplane].size();j++){
07510         PlexSEIdAltL* paltListi = fDeMuxedSingles[iplane][i].altList;
07511         PlexSEIdAltL* paltListj = fDeMuxedSingles[iplane][j].altList;
07512         int si = paltListi->GetBestSEId().GetStrip();
07513         int sj = paltListj->GetBestSEId().GetStrip();
07514         if(si==sj){
07515           if(paltListi->GetEnd()==StripEnd::kEast&&
07516              paltListj->GetEnd()==StripEnd::kWest){
07517             found = true;
07518             this->RemoveSingle(iplane, paltListi);
07519             this->RemoveSingle(iplane, paltListj);
07520             this->DeMuxHits(iplane, paltListi, paltListj, si);
07521           }
07522           if(paltListi->GetEnd()==StripEnd::kWest&&
07523              paltListj->GetEnd()==StripEnd::kEast){
07524             found = true;
07525             this->RemoveSingle(iplane, paltListi);
07526             this->RemoveSingle(iplane, paltListj);
07527             this->DeMuxHits(iplane, paltListj, paltListi, si);
07528           }
07529         }
07530       }
07531     }
07532     // loop over plane again if hits removed
07533     increment = 1;
07534     if(found)increment=0;
07535   }
07536   
07537   for(Int_t iplane=0; iplane<MAX_NUMBER_OF_PLANES;iplane++){
07538 
07539     easthits = fDeMuxedPlanesAltLists[iplane][ALG_EAST].size();
07540     //     +fPlanesAltLists[iplane][ALG_EAST].size();
07541     westhits = fDeMuxedPlanesAltLists[iplane][ALG_WEST].size();
07542     // +fPlanesAltLists[iplane][ALG_WEST].size();
07543 
07544     if(iplane==248||iplane==250)easthits=0;
07545     if(iplane==248||iplane==250)westhits=0;
07546 
07547 
07548     bool found;
07549     bool possibleDeMuxError=false;
07550     set<int>strips;
07551     Int_t s;
07552 
07553     if(easthits+westhits>0){
07554       stripE.clear();
07555       stripW.clear();
07556       ilow = iplane-2;
07557       ihigh = iplane+2;
07558       nlow = 0;
07559       if(ilow>=0)nlow = fDeMuxedPairs[ilow].size();
07560       if(ihigh<500)nhigh = fDeMuxedPairs[ihigh].size();
07561 
07562       int ntarget=0;
07563       float sumtarget=0;
07564       float sumsqtarget=0;
07565       for(int alg_ew=ALG_EAST;alg_ew<=ALG_WEST;alg_ew++){
07566         for(UInt_t iEW=0;iEW<fDeMuxedPlanesAltLists[iplane][alg_ew].size();iEW++){
07567           s = fDeMuxedPlanesAltLists[iplane][alg_ew][iEW]->GetBestSEId().GetStrip();
07568           Float_t diff = 999.;
07569           Float_t diffdm = 999.;
07570           found = false;
07571           if(nlow>0&&nhigh>0){
07572             for(Int_t ilpair=0;!found&&ilpair<nlow;ilpair++){
07573               sl = fDeMuxedPairs[ilow][ilpair].altListE->GetBestSEId().GetStrip();
07574               for(Int_t ihpair=0;!found&&ihpair<nhigh;ihpair++){
07575                 sh = fDeMuxedPairs[ihigh][ihpair].altListE->GetBestSEId().GetStrip();
07576                 Float_t target = (sl+sh)/2.0;
07577                 sumtarget+=target;
07578                 sumsqtarget+=target*target;
07579                 ntarget++;
07580                 Float_t delta = fabs(target-s);
07581                 if(delta<diff)diff=delta;
07582                 Float_t deltadm = fmod(delta+23.5,23.5);
07583                 if(deltadm>50)deltadm=0;
07584                 if(diff<5)found = true;
07585                 if(!found&&deltadm<diffdm){
07586                   fDeMuxedPlanesAltLists[iplane][alg_ew][iEW]->SetFirst();
07587                   Float_t del=999; 
07588                   while (fDeMuxedPlanesAltLists[iplane][alg_ew][iEW]->IsValid()){
07589                     Int_t sc = fDeMuxedPlanesAltLists[iplane][alg_ew][iEW]->GetCurrentSEId().GetStrip();
07590                     if(fabs(sc-target)<del){
07591                       if(abs(sc-sl)<5&&abs(sc-sh)<5){
07592                         diffdm = fabs(sc-target);
07593                         del    = diffdm;
07594                         bestdm = sc;
07595                       }
07596                     }
07597                     fDeMuxedPlanesAltLists[iplane][alg_ew][iEW]->Next();
07598                   }
07599                 }
07600               }
07601             }
07602           }
07603           if(nlow>0&&nhigh==0){
07604             ilower = iplane-4;
07605             nlower = 0;
07606             if(ilower>=0)nlower = fDeMuxedPairs[ilower].size();
07607             if(nlower>0){
07608               for(Int_t ilpair=0;!found&&ilpair<nlow;ilpair++){
07609                 sl = fDeMuxedPairs[ilow][ilpair].altListE->GetBestSEId().GetStrip();
07610                 for(Int_t illpair=0;!found&&illpair<nlower;illpair++){
07611                   sll = fDeMuxedPairs[ilower][illpair].altListE->GetBestSEId().GetStrip();
07612                   Float_t target = 2*sl-sll;
07613                   sumtarget+=target;
07614                   sumsqtarget+=target*target;
07615                   ntarget++;
07616                   Float_t delta = fabs(target-s);
07617                   if(delta<diff)diff=delta;
07618                   Float_t deltadm = fmod(delta+23.5,23.5);
07619                   if(deltadm>50)deltadm=0;
07620                   if(diff<5)found = true;
07621                   if(!found&&deltadm<diffdm){
07622                     fDeMuxedPlanesAltLists[iplane][alg_ew][iEW]->SetFirst();
07623                     Float_t del=999; 
07624                     while (fDeMuxedPlanesAltLists[iplane][alg_ew][iEW]->IsValid()){
07625                       Int_t sc = fDeMuxedPlanesAltLists[iplane][alg_ew][iEW]->GetCurrentSEId().GetStrip();
07626                       if(fabs(sc-target)<del){
07627                         if(abs(sc-sl)<4&&abs(sc-sll)<8){
07628                           diffdm = fabs(sc-target);
07629                           del    = diffdm;
07630                           bestdm = sc;
07631                         }
07632                       }
07633                       fDeMuxedPlanesAltLists[iplane][alg_ew][iEW]->Next();
07634                     }
07635                   }
07636                 }
07637               }
07638             }
07639           }
07640           if(nhigh>0&&nlow==0){
07641             ihigher = iplane+4;
07642             nhigher = 0;
07643             if(ihigher<=500)nhigher = fDeMuxedPairs[ihigher].size();
07644             if(nhigher>0){
07645               for(Int_t ihpair=0;!found&&ihpair<nhigh;ihpair++){
07646                 sh = fDeMuxedPairs[ihigh][ihpair].altListE->GetBestSEId().GetStrip();
07647                 for(Int_t ihhpair=0;!found&&ihhpair<nhigher;ihhpair++){
07648                   shh = fDeMuxedPairs[ihigher][ihhpair].altListE->GetBestSEId().GetStrip();
07649                   Float_t target = 2*sh-shh;
07650                   sumtarget+=target;
07651                   sumsqtarget+=target*target;
07652                   ntarget++;
07653                   Float_t delta = fabs(target-s);
07654                   if(delta<diff)diff=delta;
07655                   Float_t deltadm = fmod(delta+23.5,23.5);
07656                   if(deltadm>50)deltadm=0;
07657                   if(diff<5)found = true;
07658                   if(!found&&deltadm<diffdm){
07659                     fDeMuxedPlanesAltLists[iplane][alg_ew][iEW]->SetFirst();
07660                     Float_t del=999; 
07661                     while (fDeMuxedPlanesAltLists[iplane][alg_ew][iEW]->IsValid()){
07662                       Int_t sc = fDeMuxedPlanesAltLists[iplane][alg_ew][iEW]->GetCurrentSEId().GetStrip();
07663                       if(fabs(sc-target)<del){
07664                         if(abs(sc-shh)<8&&abs(sc-sh)<4){
07665                           diffdm = fabs(sc-target);
07666                           del    = diffdm;
07667                           bestdm = sc;
07668                         }
07669                       }
07670                       fDeMuxedPlanesAltLists[iplane][alg_ew][iEW]->Next();
07671                     }
07672                   }
07673                 }
07674               }
07675             }
07676           }
07677           if(!found&&diffdm<2.25){
07678             possibleDeMuxError  =true;
07679             if(alg_ew==ALG_EAST)stripE.push_back(bestdm);
07680             if(alg_ew==ALG_WEST)stripW.push_back(bestdm);
07681           }else{
07682             if(alg_ew==ALG_EAST)stripE.push_back(s);
07683             if(alg_ew==ALG_WEST)stripW.push_back(s);
07684           }
07685         }
07686       }
07687 
07688 
07689 
07690 
07691 
07692       if(possibleDeMuxError){
07693         for(int i=0;i<MAX_NUMBER_OF_STRIPS;i++){
07694           stripMapE[i]=NULL;
07695           stripMapW[i]=NULL;
07696         }
07697         for(int i=0;i<easthits;i++){
07698           stripMapE[stripE[i]] = fDeMuxedPlanesAltLists[iplane][ALG_EAST][i];
07699         }
07700         for(int i=0;i<westhits;i++){
07701           stripMapW[stripW[i]] = fDeMuxedPlanesAltLists[iplane][ALG_WEST][i];
07702         }
07703         this->ReMuxPlane(iplane);
07704         for(int i=0;i<MAX_NUMBER_OF_STRIPS;i++){
07705           
07706           if(stripMapW[i]!=NULL&&stripMapE[i]!=NULL){
07707             this->DeMuxHits(iplane, stripMapE[i], stripMapW[i], i);
07708           }else{
07709             if(stripMapE[i]!=NULL)this->DeMuxSingleHitE(iplane, stripMapE[i], i);
07710             if(stripMapW[i]!=NULL)this->DeMuxSingleHitW(iplane, stripMapW[i], i);
07711           }
07712         }
07713       }
07714       if(ntarget>0){
07715         float mean = sumtarget/ntarget;
07716         int istrip = static_cast<int>(mean+0.5);
07717         ValidatePlaneAgainstTarget(iplane,istrip);
07718         //      float rms = sumsqtarget/ntarget-mean*mean;
07719       }
07720     }
07721   }
07722 
07723   return;
07724 }
07725 
07726 
07727 
07728 
07729 
07730 
07731 
07732 
07733 
07734 void AlgAltDeMuxBase::UpdateXTalkMap(PlexSEIdAltL* paltlist){
07735 
07736   PlexPixelSpotId pixelID = (paltlist->GetBestItem()).GetPixelSpotId(); 
07737   Int_t pixel  = pixelID.GetPixel();
07738   Int_t PMTmuxID = pixelID.GetTube();
07739   PMTmuxID      += 3*pixelID.GetInRack();
07740   PMTmuxID      += 24*pixelID.GetRackBay();
07741   Char_t level = pixelID.GetRackLevel(); 
07742   Char_t ew = pixelID.GetEastWest(); 
07743   if(level=='U')PMTmuxID += 450;
07744   if(ew =='E')PMTmuxID += 900;
07745   if(PMTmuxID<MAX_NUMBER_OF_PMTS){
07746     Float_t q  = paltlist->GetBestItem().GetPE();
07747     Float_t qc = paltlist->GetBestItem().GetSigCorr()/60.;
07748     if(qc/q<0.1 || qc/q > 10.0){
07749       qc=q;
07750     }
07751     Int_t pixelSpot = pixelID.GetSpot();
07752     fPMTmap[PMTmuxID][pixel]+=qc;
07753     fPMTtot[PMTmuxID]+=qc;
07754         
07755     switch(pixel){
07756     case 0:
07757       fXTalkmap[PMTmuxID][1] += qc*_pixelSpotXTalkMap[pixelSpot][5]; 
07758       fXTalkmap[PMTmuxID][4] += qc*_pixelSpotXTalkMap[pixelSpot][7];
07759       fXTalkmap[PMTmuxID][5] += qc*_pixelSpotXTalkMap[pixelSpot][8];
07760       break;
07761     case 1:
07762       fXTalkmap[PMTmuxID][0] += qc*_pixelSpotXTalkMap[pixelSpot][3]; 
07763       fXTalkmap[PMTmuxID][2] += qc*_pixelSpotXTalkMap[pixelSpot][5];
07764       fXTalkmap[PMTmuxID][4] += qc*_pixelSpotXTalkMap[pixelSpot][6];
07765       fXTalkmap[PMTmuxID][5] += qc*_pixelSpotXTalkMap[pixelSpot][7];
07766       fXTalkmap[PMTmuxID][6] += qc*_pixelSpotXTalkMap[pixelSpot][8];
07767       break;
07768     case 2:
07769       fXTalkmap[PMTmuxID][1] += qc*_pixelSpotXTalkMap[pixelSpot][3]; 
07770       fXTalkmap[PMTmuxID][3] += qc*_pixelSpotXTalkMap[pixelSpot][5];
07771       fXTalkmap[PMTmuxID][5] += qc*_pixelSpotXTalkMap[pixelSpot][6];
07772       fXTalkmap[PMTmuxID][6] += qc*_pixelSpotXTalkMap[pixelSpot][7];
07773       fXTalkmap[PMTmuxID][7] += qc*_pixelSpotXTalkMap[pixelSpot][8];
07774       break;
07775     case 3:
07776       fXTalkmap[PMTmuxID][2] += qc*_pixelSpotXTalkMap[pixelSpot][3]; 
07777       fXTalkmap[PMTmuxID][6] += qc*_pixelSpotXTalkMap[pixelSpot][6];
07778       fXTalkmap[PMTmuxID][7] += qc*_pixelSpotXTalkMap[pixelSpot][7];
07779       break;
07780     case 4:
07781       fXTalkmap[PMTmuxID][0] += qc*_pixelSpotXTalkMap[pixelSpot][1]; 
07782       fXTalkmap[PMTmuxID][1] += qc*_pixelSpotXTalkMap[pixelSpot][2];
07783       fXTalkmap[PMTmuxID][5] += qc*_pixelSpotXTalkMap[pixelSpot][5];
07784       fXTalkmap[PMTmuxID][8] += qc*_pixelSpotXTalkMap[pixelSpot][7];
07785       fXTalkmap[PMTmuxID][9] += qc*_pixelSpotXTalkMap[pixelSpot][8];
07786       break;
07787     case 5:
07788       fXTalkmap[PMTmuxID][0] += qc*_pixelSpotXTalkMap[pixelSpot][0]; 
07789       fXTalkmap[PMTmuxID][1] += qc*_pixelSpotXTalkMap[pixelSpot][1];
07790       fXTalkmap[PMTmuxID][2] += qc*_pixelSpotXTalkMap[pixelSpot][2];
07791       fXTalkmap[PMTmuxID][4] += qc*_pixelSpotXTalkMap[pixelSpot][3];
07792       fXTalkmap[PMTmuxID][6] += qc*_pixelSpotXTalkMap[pixelSpot][5];
07793       fXTalkmap[PMTmuxID][8] += qc*_pixelSpotXTalkMap[pixelSpot][6];
07794       fXTalkmap[PMTmuxID][9] += qc*_pixelSpotXTalkMap[pixelSpot][7];
07795       fXTalkmap[PMTmuxID][10]+= qc*_pixelSpotXTalkMap[pixelSpot][8];
07796       break;
07797     case 6:
07798       fXTalkmap[PMTmuxID][1] += qc*_pixelSpotXTalkMap[pixelSpot][0]; 
07799       fXTalkmap[PMTmuxID][2] += qc*_pixelSpotXTalkMap[pixelSpot][1];
07800       fXTalkmap[PMTmuxID][3] += qc*_pixelSpotXTalkMap[pixelSpot][2];
07801       fXTalkmap[PMTmuxID][5] += qc*_pixelSpotXTalkMap[pixelSpot][3];
07802       fXTalkmap[PMTmuxID][7] += qc*_pixelSpotXTalkMap[pixelSpot][5];
07803       fXTalkmap[PMTmuxID][9] += qc*_pixelSpotXTalkMap[pixelSpot][6];
07804       fXTalkmap[PMTmuxID][10]+= qc*_pixelSpotXTalkMap[pixelSpot][7];
07805       fXTalkmap[PMTmuxID][11]+= qc*_pixelSpotXTalkMap[pixelSpot][8];
07806       break;
07807     case 7:
07808       fXTalkmap[PMTmuxID][2] += qc*_pixelSpotXTalkMap[pixelSpot][0]; 
07809       fXTalkmap[PMTmuxID][3] += qc*_pixelSpotXTalkMap[pixelSpot][1];
07810       fXTalkmap[PMTmuxID][6] += qc*_pixelSpotXTalkMap[pixelSpot][3];
07811       fXTalkmap[PMTmuxID][10]+= qc*_pixelSpotXTalkMap[pixelSpot][6];
07812       fXTalkmap[PMTmuxID][11]+= qc*_pixelSpotXTalkMap[pixelSpot][7];
07813       break;
07814     case 8:
07815       fXTalkmap[PMTmuxID][4]  += qc*_pixelSpotXTalkMap[pixelSpot][1]; 
07816       fXTalkmap[PMTmuxID][5]  += qc*_pixelSpotXTalkMap[pixelSpot][2];
07817       fXTalkmap[PMTmuxID][9]  += qc*_pixelSpotXTalkMap[pixelSpot][5];
07818       fXTalkmap[PMTmuxID][12] += qc*_pixelSpotXTalkMap[pixelSpot][7];
07819       fXTalkmap[PMTmuxID][13] += qc*_pixelSpotXTalkMap[pixelSpot][8];
07820       break;
07821     case 9:
07822       fXTalkmap[PMTmuxID][4] += qc*_pixelSpotXTalkMap[pixelSpot][0]; 
07823       fXTalkmap[PMTmuxID][5] += qc*_pixelSpotXTalkMap[pixelSpot][1];
07824       fXTalkmap[PMTmuxID][6] += qc*_pixelSpotXTalkMap[pixelSpot][2];
07825       fXTalkmap[PMTmuxID][8] += qc*_pixelSpotXTalkMap[pixelSpot][3];
07826       fXTalkmap[PMTmuxID][10]+= qc*_pixelSpotXTalkMap[pixelSpot][5];
07827       fXTalkmap[PMTmuxID][12]+= qc*_pixelSpotXTalkMap[pixelSpot][6];
07828       fXTalkmap[PMTmuxID][13]+= qc*_pixelSpotXTalkMap[pixelSpot][7];
07829       fXTalkmap[PMTmuxID][14]+= qc*_pixelSpotXTalkMap[pixelSpot][8];
07830       break;
07831     case 10:
07832       fXTalkmap[PMTmuxID][5] += qc*_pixelSpotXTalkMap[pixelSpot][0]; 
07833       fXTalkmap[PMTmuxID][6] += qc*_pixelSpotXTalkMap[pixelSpot][1];
07834       fXTalkmap[PMTmuxID][7] += qc*_pixelSpotXTalkMap[pixelSpot][2];
07835       fXTalkmap[PMTmuxID][9] += qc*_pixelSpotXTalkMap[pixelSpot][3];
07836       fXTalkmap[PMTmuxID][11]+= qc*_pixelSpotXTalkMap[pixelSpot][5];
07837       fXTalkmap[PMTmuxID][13]+= qc*_pixelSpotXTalkMap[pixelSpot][6];
07838       fXTalkmap[PMTmuxID][14]+= qc*_pixelSpotXTalkMap[pixelSpot][7];
07839       fXTalkmap[PMTmuxID][15]+= qc*_pixelSpotXTalkMap[pixelSpot][8];
07840       break;
07841     case 11:
07842       fXTalkmap[PMTmuxID][6] += qc*_pixelSpotXTalkMap[pixelSpot][0]; 
07843       fXTalkmap[PMTmuxID][7] += qc*_pixelSpotXTalkMap[pixelSpot][1];
07844       fXTalkmap[PMTmuxID][10]+= qc*_pixelSpotXTalkMap[pixelSpot][3];
07845       fXTalkmap[PMTmuxID][14]+= qc*_pixelSpotXTalkMap[pixelSpot][6];
07846       fXTalkmap[PMTmuxID][15]+= qc*_pixelSpotXTalkMap[pixelSpot][7];
07847       break;
07848     case 12:
07849       fXTalkmap[PMTmuxID][8] += qc*_pixelSpotXTalkMap[pixelSpot][1]; 
07850       fXTalkmap[PMTmuxID][9] += qc*_pixelSpotXTalkMap[pixelSpot][2];
07851       fXTalkmap[PMTmuxID][13]+= qc*_pixelSpotXTalkMap[pixelSpot][5];
07852       break;
07853     case 13:
07854       fXTalkmap[PMTmuxID][8] += qc*_pixelSpotXTalkMap[pixelSpot][0]; 
07855       fXTalkmap[PMTmuxID][9] += qc*_pixelSpotXTalkMap[pixelSpot][1];
07856       fXTalkmap[PMTmuxID][10]+= qc*_pixelSpotXTalkMap[pixelSpot][2];
07857       fXTalkmap[PMTmuxID][12]+= qc*_pixelSpotXTalkMap[pixelSpot][3];
07858       fXTalkmap[PMTmuxID][14]+= qc*_pixelSpotXTalkMap[pixelSpot][5];
07859       break;
07860     case 14:
07861       fXTalkmap[PMTmuxID][9] += qc*_pixelSpotXTalkMap[pixelSpot][0]; 
07862       fXTalkmap[PMTmuxID][10]+= qc*_pixelSpotXTalkMap[pixelSpot][1];
07863       fXTalkmap[PMTmuxID][11]+= qc*_pixelSpotXTalkMap[pixelSpot][2];
07864       fXTalkmap[PMTmuxID][13]+= qc*_pixelSpotXTalkMap[pixelSpot][3];
07865       fXTalkmap[PMTmuxID][15]+= qc*_pixelSpotXTalkMap[pixelSpot][5];
07866       break;
07867     case 15:
07868       fXTalkmap[PMTmuxID][10]+= qc*_pixelSpotXTalkMap[pixelSpot][0]; 
07869       fXTalkmap[PMTmuxID][11]+= qc*_pixelSpotXTalkMap[pixelSpot][1];
07870       fXTalkmap[PMTmuxID][14]+= qc*_pixelSpotXTalkMap[pixelSpot][3];
07871       break;
07872     default:
07873       break;
07874     }
07875   }else{
07876     MSG("AltDeMux", Msg::kError) << "AlgAltDeMuxBase::UpdateXTalkMap => PMT out of array bounds : " << PMTmuxID << " ignoring it !" << endl;
07877   }
07878 }
07879 
07880 
07881 void AlgAltDeMuxBase::ReMakeMask()
07882 {
07883   
07884   // if diagnostic/debug
07885   if(fDiagnosticPlots){
07886     if ( fUTime ) { delete fUTime; fUTime=0; }
07887     if ( fVTime ) { delete fVTime; fVTime=0; }
07888     fUTime = new TH2F("UTime","U time view",501,-0.5,500.5,193,0.,193.);
07889     fVTime = new TH2F("VTime","V time view",501,-0.5,500.5,193,0.,193.);
07890     fUTime->SetStats(kFALSE);
07891     fVTime->SetStats(kFALSE);
07892   }
07893   
07894   // Use a 2.5 sigma timing window
07895   fTimingMaskWindow     = static_cast<Int_t>(fSigmasForTimingWindow*fSigmaStripFromTiming);
07896 
07897   for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
07898     if(fDeMuxedPlanesAltLists[iplane][ALG_EAST].size()>0||fDeMuxedPlanesAltLists[iplane][ALG_WEST].size()>0){
07899       fMaskGroup[iplane].erase(fMaskGroup[iplane].begin(),fMaskGroup[iplane].end());
07900       fInMask[iplane] =  0;
07901       // Reset timing mask strip targets and target groups for this palne 
07902       for(Int_t istrip=0;istrip<MAX_NUMBER_OF_STRIPS;istrip++){
07903         fTimingMask[iplane][istrip] = false;
07904       }
07905     }else{
07906       if(fDiagnosticPlots){
07907         for(Int_t isaim = 0;isaim <MAX_NUMBER_OF_STRIPS; isaim++){
07908           if(fTimingMask[iplane][isaim]){
07909             if(fUVMap[iplane]==PlaneView::kV)fUTime->Fill(iplane,isaim,1.);
07910             if(fUVMap[iplane]==PlaneView::kU)fVTime->Fill(iplane,isaim,1.);
07911           }
07912         }
07913       }
07914     }
07915   }
07916 
07917   PlaneView::PlaneView_t kView;
07918   for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
07919     for(unsigned int ipair=0;ipair<fDeMuxedPairs[iplane].size();ipair++){
07920       kView = fDeMuxedPairs[iplane][ipair].altListE->GetPlaneView();
07921       Int_t isaim = fDeMuxedPairs[iplane][ipair].orthogonalStripFromTiming;
07922       if(fDiagnosticPlots){
07923         if(kView==PlaneView::kV)fUTime->Fill(iplane,isaim,1.);
07924         if(kView==PlaneView::kU)fVTime->Fill(iplane,isaim,1.);
07925       }
07926       if(kView==PlaneView::kV){
07927         fInMask[iplane]++;
07928         fTimingMask[iplane][isaim] = true;
07929       }     
07930       if(kView==PlaneView::kU){
07931         fInMask[iplane]++;
07932         fTimingMask[iplane][isaim] = true;
07933       }
07934     }
07935   }
07936   this->MakeMaskGroups();
07937 
07938   for(int iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
07939     if(fPlanesAltLists[iplane][ALG_EAST].size()>0||
07940        fPlanesAltLists[iplane][ALG_WEST].size()>0||
07941        fDeMuxedPlanesAltLists[iplane][ALG_EAST].size()>0||
07942        fDeMuxedPlanesAltLists[iplane][ALG_WEST].size()>0){
07943       bool found = false;
07944       if(iplane==0){
07945         int ip = 1;
07946         int ipp = 3; 
07947         found = found || MaskExtrapolateBack(iplane,ip,ipp);
07948       }else{
07949         // For planes with hits : check surrounding planes
07950         int im=iplane-1;
07951         int ip=iplane+1;
07952         found = found || MaskInterpolate(iplane,im,ip);
07953         if(!found){
07954           int imm = iplane-3;
07955           int ipp = iplane+3;
07956           if(imm>=0)found = found || MaskInterpolate(iplane,imm,ip);
07957           if(ipp<MAX_NUMBER_OF_PLANES-1)found = found || MaskInterpolate(iplane,im,ipp);
07958           if(!found){
07959             if(imm>=0)found = found || MaskExtrapolateForwards(iplane,imm,im);
07960             if(ipp<MAX_NUMBER_OF_PLANES-1)found = found || MaskExtrapolateBack(iplane,ip,ipp);
07961           }
07962         }
07963       }
07964       if(!found)for(int istrip=0;istrip<fNumberOfStrips;istrip++)this->SetMask(iplane,istrip);
07965     }
07966   }
07967   
07968   if(fDiagnosticPlots)this->DrawDiagnosticPlots(-2);
07969   if(fDiagnosticPlots)this->DrawDiagnosticPlots(5);
07970   
07971   return;
07972   
07973 } 
07974 
07975 void AlgAltDeMuxBase::MakeFitPolyLines(DeMuxFitResult_t result, TPolyLine* &pPolyLine1, 
07976 TPolyLine* &pPolyLine2, Int_t color, Int_t style){
07977   
07978   Float_t xp[2];
07979   Float_t yp[2];
07980 
07981   if(result.status){
07982     xp[0] = 0;
07983     xp[1] = 249.;
07984     yp[0] = result.a0;
07985     yp[1] = result.a1*249.+result.a0;
07986     if(pPolyLine1)delete pPolyLine1;
07987     pPolyLine1 = new TPolyLine(2,xp,yp);
07988     pPolyLine1->SetLineColor(color);
07989     pPolyLine1->SetLineStyle(style);
07990     pPolyLine1->SetLineWidth(2);
07991     xp[0] = 249;
07992     xp[1] = 500.;
07993     yp[0] = result.a1*269.+result.a0;
07994     yp[1] = result.a1*520.+result.a0;
07995     if(pPolyLine2)delete pPolyLine2;
07996     pPolyLine2 = new TPolyLine(2,xp,yp);
07997     pPolyLine2->SetLineColor(color);
07998     pPolyLine2->SetLineStyle(style);
07999     pPolyLine2->SetLineWidth(2);
08000   }
08001 
08002   return;
08003 
08004 }
08005 
08006 
08007 
08008 
08009 DeMuxEventType_t AlgAltDeMuxBase::EventID() 
08010 {  
08011   Float_t d;
08012   Int_t iedge;
08013   Float_t QFiducial[12];
08014   Float_t QPlane[MAX_NUMBER_OF_PLANES];
08015   Float_t QSPlane[MAX_NUMBER_OF_PLANES];
08016   Float_t U;
08017   Float_t V;
08018   Float_t x;
08019   Float_t y;
08020   Float_t Qhighest = 0.;
08021 
08022 
08023   for(Int_t i=0;i<12;i++)QFiducial[i]=0.0;
08024 
08025   for(Int_t i=0;i<MAX_NUMBER_OF_PLANES;i++){
08026     QPlane[i]=0.0;
08027     QSPlane[i]=0.0;
08028   }
08029 
08030   for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
08031     for(Int_t i=0;i<NdemuxedHitsU[iplane];i++){
08032       QPlane[iplane] += demuxedHitQU[iplane][i];
08033       QSPlane[iplane] += demuxedHitQU[iplane][i]*demuxedHitStripU[iplane][i];
08034     }
08035     for(Int_t i=0;i<NdemuxedHitsV[iplane];i++){
08036       QPlane[iplane] += demuxedHitQV[iplane][i];
08037       QSPlane[iplane] += demuxedHitQV[iplane][i]*demuxedHitStripV[iplane][i];
08038     }
08039   }
08040 
08041   Float_t dmin = 999.0;
08042   Float_t ymax = -999.0;
08043   Int_t nearestPlane = -1;
08044   Int_t highestPlane = -1;
08045   for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
08046     for(Int_t i=0;i<NdemuxedHitsU[iplane];i++){
08047       Int_t iU = iplane;
08048       U = demuxedHitStripU[iplane][i];
08049       bool ok =false;
08050       if(iU>0&&iU<MAX_NUMBER_OF_PLANES-1){
08051         if(QPlane[iU-1]>0 && QPlane[iU+1]>0){
08052           Float_t sm = QSPlane[iU-1]/QPlane[iU-1];
08053           Float_t sp = QSPlane[iU+1]/QPlane[iU+1];
08054           V = (sm+sp)/2.0;
08055           ok = true;
08056         }
08057       }
08058       if(!ok&&iU>3){
08059         if(QPlane[iU-3]>0 && QPlane[iU-1]>0){
08060           Float_t smm = QSPlane[iU-3]/QPlane[iU-3];
08061           Float_t sm  = QSPlane[iU-1]/QPlane[iU-1];
08062           V = (3*sm-smm)/2.0;
08063           ok = true;
08064         }
08065       }
08066       if(!ok&&iU<MAX_NUMBER_OF_PLANES-3){
08067         if(QPlane[iU+3]>0 && QPlane[iU+1]>0){
08068           Float_t spp = QSPlane[iU+3]/QPlane[iU+3];
08069           Float_t sp  = QSPlane[iU+1]/QPlane[iU+1];
08070           V = (3*sp-spp)/2.0;
08071           ok = true;
08072         }
08073       }
08074       if(ok){
08075         x = ((U-V)*0.0417)/1.4142;
08076         y = ((U+V)*0.0417-8.0)/1.4142;
08077         pCalculator->FindNearestEdge(x,y,iedge,d);
08078         if(iplane<4)iedge=0;
08079         if(iplane>244&&iplane<249)iedge=9;
08080         if(iplane>249&&iplane<254)iedge=10;
08081         if(iplane>481)iedge=11;
08082         if(d<0.5||iedge==0||iedge>=9)QFiducial[iedge]+=demuxedHitQU[iplane][i];
08083         if(d<dmin){
08084           dmin = d;
08085           nearestPlane = iplane;
08086         }
08087         if(y>ymax){
08088           ymax = y;
08089           highestPlane = iplane;
08090           Qhighest = 0.;
08091           if(d<0.5||iedge==0||iedge>=9)Qhighest = demuxedHitQU[iplane][i];
08092         }
08093       }
08094     }
08095     for(Int_t i=0;i<NdemuxedHitsV[iplane];i++){
08096       Int_t iV = iplane;
08097       V = demuxedHitStripV[iplane][i];
08098       bool ok =false;
08099       if(iV>0&&iV<MAX_NUMBER_OF_PLANES-1){
08100         if(QPlane[iV-1]>0 && QPlane[iV+1]>0){
08101           Float_t sm = QSPlane[iV-1]/QPlane[iV-1];
08102           Float_t sp = QSPlane[iV+1]/QPlane[iV+1];
08103           U = (sm+sp)/2.0;
08104           ok = true;
08105         }
08106       }
08107       if(!ok&&iV>3){
08108         if(QPlane[iV-3]>0 && QPlane[iV-1]>0){
08109           Float_t smm = QSPlane[iV-3]/QPlane[iV-3];
08110           Float_t sm  = QSPlane[iV-1]/QPlane[iV-1];
08111           U = (3*sm-smm)/2.0;
08112           ok = true;
08113         }
08114       }
08115       if(!ok&&iV<MAX_NUMBER_OF_PLANES-3){
08116         if(QPlane[iV+3]>0 && QPlane[iV+1]>0){
08117           Float_t spp = QSPlane[iV+3]/QPlane[iV+3];
08118           Float_t sp  = QSPlane[iV+1]/QPlane[iV+1];
08119           U = (3*sp-spp)/2.0;
08120           ok = true;
08121         }
08122       }
08123       if(ok){
08124         x = ((U-V)*0.0417)/1.4142;
08125         y = ((U+V)*0.0417-8.0)/1.4142;
08126         pCalculator->FindNearestEdge(x,y,iedge,d);
08127         if(iplane<4)iedge=0;
08128         if(iplane>244&&iplane<249)iedge=9;
08129         if(iplane>249&&iplane<254)iedge=10;
08130         if(iplane>481)iedge=11;
08131         if(d<0.5||iedge==0||iedge>=9)QFiducial[iedge]+=demuxedHitQV[iplane][i]; 
08132         if(d<dmin){
08133           dmin = d;
08134           nearestPlane = iplane;
08135         }
08136         if(y>ymax){
08137           ymax = y;
08138           highestPlane = iplane;
08139           Qhighest = 0.;
08140           if(d<0.5||iedge==0||iedge>=9)Qhighest = demuxedHitQV[iplane][i]; 
08141         }
08142       }
08143     }
08144   }
08145 
08146 
08147   Int_t icount=0;
08148   for(int i=0;i<12;i++){
08149     if(amWriting)cout << " Edge " << i << " : " << QFiducial[i] << endl; 
08150     if(QFiducial[i]>2.0)icount++;
08151   }
08152   DeMuxEventType_t eventType = fEventType;
08153   if(fEventType!=MULTIPLE_MUON){
08154     if(icount==0)eventType =  CONTAINED_EVENT;
08155     if(icount==1){
08156       eventType = STOPPING_MUON;
08157       if(Qhighest<0.01)eventType = PARTIALLY_CONTAINED_EVENT;
08158     }
08159     if(icount>=2){
08160       if(fEventType==SINGLE_MUON||fEventType==STRAIGHT_THROUGH_GOING_MUON){
08161         eventType = STRAIGHT_THROUGH_GOING_MUON;
08162       }else{
08163         eventType = THROUGH_GOING_MUON;
08164       }
08165     }
08166   }
08167 
08168   
08169   if(eventType==CONTAINED_EVENT || eventType==PARTIALLY_CONTAINED_EVENT){
08170     fCCNearestPlane=nearestPlane;
08171     fCCHighestPlane=highestPlane;
08172   }
08173 
08174   return eventType;
08175 }
08176 
08177 
08178 
08179 DeMuxFitResult_t AlgAltDeMuxBase::LinearFit(vector<DeMuxFitData_t>& data, Float_t refitDistance){
08180 
08181   Double_t N=0.0;
08182   Double_t sumX=0.0;
08183   Double_t sumY=0.0;
08184   Double_t sumXY=0.0;
08185   Double_t sumXX=0.0;
08186   Double_t sumYY=0.0;
08187   Double_t det;
08188   DeMuxFitResult_t result;
08189   result.status = false;
08190   result.a0 = 0.;
08191   result.a1 = 0.;
08192   result.a2 = 0.;
08193   result.a3 = 0.;
08194   result.a4 = 0.;
08195   result.chi2    = 999999.;
08196   result.chi2pdf = 999999.;
08197   result.nUsed = 0;
08198   result.nData = 0;
08199 
08200   for(UInt_t i=0; i<data.size(); i++){
08201     N += 1.; 
08202     sumX += data[i].x;
08203     sumY += data[i].y;
08204     sumXX += data[i].x*data[i].x;
08205     sumXY += data[i].x*data[i].y;
08206     sumYY += data[i].y*data[i].y;
08207   }
08208   
08209   det = sumXX*N-sumX*sumX;
08210   if(det>0){
08211     result.status = true;
08212     result.a0     = (-sumX*sumXY + sumXX*sumY)/det;
08213     result.a1     = (N*sumXY - sumX*sumY)/det;
08214     if(refitDistance>0){
08215       for(UInt_t i=0; i<data.size(); i++){
08216         Double_t yFromFit = result.a0 + result.a1*data[i].x;
08217         Double_t delta = fabs(data[i].y-yFromFit);
08218         if(delta>refitDistance){
08219           data[i].status = false;
08220           N -= 1.; 
08221           sumX  -= data[i].x;
08222           sumY  -= data[i].y;
08223           sumXX -= data[i].x*data[i].x;
08224           sumXY -= data[i].x*data[i].y;
08225           sumYY -= data[i].y*data[i].y;
08226         }
08227       }
08228     } 
08229   }
08230 
08231   Double_t chi2=0.;
08232   det = sumXX*N-sumX*sumX;
08233   result.status = false;
08234   result.a0     = 0.;
08235   result.a1     = 0.;
08236   
08237   if(det>0){
08238     result.status = true;
08239     result.a0     = (-sumX*sumXY + sumXX*sumY)/det;
08240     result.a1     = (N*sumXY - sumX*sumY)/det;
08241     for(UInt_t i=0; i<data.size(); i++){
08242       if(data[i].status){
08243         Double_t yFromFit = result.a0 + result.a1*data[i].x;
08244         Double_t delta = (data[i].y-yFromFit);
08245         chi2+=delta*delta;
08246       }
08247     }
08248     result.nUsed = static_cast<Int_t>(N);
08249     result.nData = data.size();
08250     result.chi2  = chi2;
08251     if(result.nUsed>2)result.chi2pdf  = chi2/(result.nUsed-2);
08252   }
08253 
08254   return result;
08255 }
08256 
08257 
08258 void AlgAltDeMuxBase::SearchAndDestroy(){
08259   
08260   Float_t Qtotal[MAX_NUMBER_OF_PLANES];
08261   Float_t Qpairs[MAX_NUMBER_OF_PLANES];
08262   
08263   if(fEventType==MULTIPLE_MUON)return;
08264   
08265   for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
08266     Qtotal[iplane] = 0.;
08267     Qpairs[iplane] = 0.;
08268     
08269     for(UInt_t ipair=0;ipair<fDeMuxedPairs[iplane].size();ipair++){
08270       Qtotal[iplane]  += fDeMuxedPairs[iplane][ipair].pairQCor;      
08271       Qpairs[iplane] += fDeMuxedPairs[iplane][ipair].pairQCor;      
08272     }
08273   
08274     for(UInt_t isingle=0;isingle<fDeMuxedSingles[iplane].size();isingle++){
08275       Qtotal[iplane]  += fDeMuxedSingles[iplane][isingle].Qcor;      
08276     }
08277     if(Qtotal[iplane]>0){
08278       if(amWriting)cout << "Fraction " << iplane << " : " << Qpairs[iplane] << "," <<  
08279         Qtotal[iplane] << "-->" << Qpairs[iplane]/Qtotal[iplane] << endl;
08280       if(Qpairs[iplane]/Qtotal[iplane]<10.0){ 
08281         if(amWriting)cout << "ValidatePlane : " << iplane << endl;
08282         bool useTimeMask = false;
08283         this->ValidatePlane(iplane,useTimeMask);
08284       }
08285     }
08286   }
08287 
08288   return;
08289 
08290 }
08291 
08292 bool AlgAltDeMuxBase::BestGuessForView(PlaneView::PlaneView_t kView){
08293 
08294   for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
08295     if(fUVMap[iplane]==kView){
08296       if(fPlanesAltLists[iplane][ALG_EAST].size()>0&&fPlanesAltLists[iplane][ALG_WEST].size()>0){
08297         this->BestGuessForPlane(iplane, false);
08298       }
08299     }
08300   }
08301   return true;
08302 }

Generated on Sat Mar 14 22:38:45 2009 for loon by doxygen 1.3.5