Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

AlgAltDeMuxBase.cxx

Go to the documentation of this file.
00001 
00002 // $Id: AlgAltDeMuxBase.cxx,v 1.11.4.1 2005/07/29 19:46:12 boehm 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 <algorithm>
00013 #include <vector>
00014 #include "Candidate/CandContext.h"
00015 #include "Candidate/CandHandle.h"
00016 #include "CandDigit/CandDeMuxDigitHandle.h"
00017 #include "CandDigit/CandDeMuxDigitListHandle.h"
00018 #include "MessageService/MsgService.h"
00019 #include "Algorithm/AlgConfig.h"
00020 #include "Algorithm/AlgFactory.h"
00021 #include "Algorithm/AlgHandle.h"
00022 #include "TObjArray.h"
00023 #include "TH1.h"
00024 #include "TFolder.h"
00025 #include "TROOT.h"
00026 #include "TPolyMarker.h"
00027 #include "CandData/CandRecord.h"           // DigitList handling
00028 #include "CandDigit/CandDigitListHandle.h" // "                "
00029 #include "CandDigit/CandDigitHandle.h"     // "                "
00030 #include "UgliGeometry/UgliGeomHandle.h"
00031 #include "UgliGeometry/UgliPlnNode.h"
00032 #include "Validity/VldContext.h"
00033 #include "Plex/PlexPlaneId.h"
00034 #include "AltDeMuxPatternMaster.h"
00035 #include "AlgAltDeMuxBase.h"
00036 
00037 ClassImp(AlgAltDeMuxBase)
00038   
00039 
00040 //-----------------------------------------------------------------------
00041 
00042 CVSID("$Id: AlgAltDeMuxBase.cxx,v 1.11.4.1 2005/07/29 19:46:12 boehm Exp $");
00043 
00044 //-----------------------------------------------------------------------
00045 
00046 AlgAltDeMuxBase::AlgAltDeMuxBase()
00047 {
00048   //default constructor
00049   MSG("AltDeMux", Msg::kInfo) << "AlgAltDeMuxBase() Constructor" << endl;
00050 
00051   this->Initialize("");
00052   
00053   MSG("AltDeMux", Msg::kInfo) << "AlgAltDeMuxBase Leaving Constructor" << endl;
00054 }
00055 
00056 AlgAltDeMuxBase::AlgAltDeMuxBase(const char* name)
00057 {
00058   //default constructor
00059   MSG("AltDeMux", Msg::kInfo) << "AlgAltDeMuxBase(name) Constructor" << endl;
00060 
00061   this->Initialize(name);
00062   
00063   MSG("AltDeMux", Msg::kInfo) << "AlgAltDeMuxBase Leaving Constructor" << endl;
00064   
00065 }
00066 
00067 void AlgAltDeMuxBase::Initialize(const char* name)
00068 {
00069   
00070   fList = new TList();
00071   fXTalkFraction        = 0.05;
00072   fXTalk1PEFraction     = 0.25;
00073   fXTalk2PEFraction     = 0.15;
00074   fXTalk5PEFraction     = 0.10;
00075   fNoiseTimeWindow      = 100.;
00076   fSigmasForTimingWindow = 2.5;
00077 
00078   // Far Detector Monte Calro
00079 
00080   fScintillatorNMC = 1.75;  
00081   fWLSFibreNMC     = 1.75; 
00082   fClearFibreNMC   = 1.75;  
00083   fSigmaTMC        = 2.5; //(ns)
00084 
00085   // Far Detector DATA
00086 
00087   fScintillatorN = 1.77;  
00088   fWLSFibreN     = 1.77; 
00089   fClearFibreN   = 1.77;  
00090   fSigmaTData    = 2.5; //(ns)
00091                            
00092   fNumberOfStrips = 192;
00093   fEventType = UNKNOWN;
00094   fDiagnosticPlots = false;
00095   //  amWriting = false;
00096   amShowing = false;
00097   pCalculator = new AltDeMuxCalc();
00098   this->Setup();
00099   
00100   diagnosticCanvastitle = name;
00101   diagnosticCanvas = false;
00102 
00103   _pixelToVaChannel[0]  = 3;
00104   _pixelToVaChannel[1]  = 5;
00105   _pixelToVaChannel[2]  = 14;
00106   _pixelToVaChannel[3]  = 16;
00107   _pixelToVaChannel[4]  = 7;
00108   _pixelToVaChannel[5]  = 9;
00109   _pixelToVaChannel[6]  = 10;
00110   _pixelToVaChannel[7]  = 12;
00111   _pixelToVaChannel[8]  = 11;
00112   _pixelToVaChannel[9]  = 13;
00113   _pixelToVaChannel[10] = 6;
00114   _pixelToVaChannel[11] = 8;
00115   _pixelToVaChannel[12] = 17;
00116   _pixelToVaChannel[13] = 15;
00117   _pixelToVaChannel[14] = 2;
00118   _pixelToVaChannel[15] = 4;
00119 
00120   for(int i = 0; i<8; i++){
00121     for(int j = 0; j<9; j++){
00122       _pixelSpotXTalkMap[i][j]=0.0;
00123     }
00124   }
00125   
00126   // spot 0
00127 
00128   _pixelSpotXTalkMap[3][0] = 0.007; 
00129   _pixelSpotXTalkMap[3][1] = 0.025;
00130   _pixelSpotXTalkMap[3][2] = 0.002;
00131   _pixelSpotXTalkMap[3][3] = 0.025;
00132   _pixelSpotXTalkMap[3][5] = 0.003;
00133   _pixelSpotXTalkMap[3][6] = 0.001;
00134   _pixelSpotXTalkMap[3][7] = 0.003;
00135   _pixelSpotXTalkMap[3][8] = 0.002;
00136   
00137   // spot 1
00138 
00139   _pixelSpotXTalkMap[2][0] = 0.003; 
00140   _pixelSpotXTalkMap[2][1] = 0.025;
00141   _pixelSpotXTalkMap[2][2] = 0.003;
00142   _pixelSpotXTalkMap[2][3] = 0.006;
00143   _pixelSpotXTalkMap[2][5] = 0.006;
00144   _pixelSpotXTalkMap[2][6] = 0.001;
00145   _pixelSpotXTalkMap[2][7] = 0.004;
00146   _pixelSpotXTalkMap[2][8] = 0.001;
00147   
00148 
00149   // spot 2
00150 
00151   _pixelSpotXTalkMap[1][0] = 0.002; 
00152   _pixelSpotXTalkMap[1][1] = 0.025;
00153   _pixelSpotXTalkMap[1][2] = 0.007;
00154   _pixelSpotXTalkMap[1][3] = 0.003;
00155   _pixelSpotXTalkMap[1][5] = 0.025;
00156   _pixelSpotXTalkMap[1][6] = 0.001;
00157   _pixelSpotXTalkMap[1][7] = 0.003;
00158   _pixelSpotXTalkMap[1][8] = 0.002;
00159   
00160   // spot 3
00161 
00162   _pixelSpotXTalkMap[5][0] = 0.002; 
00163   _pixelSpotXTalkMap[5][1] = 0.008;
00164   _pixelSpotXTalkMap[5][2] = 0.001;
00165   _pixelSpotXTalkMap[5][3] = 0.011;
00166   _pixelSpotXTalkMap[5][5] = 0.004;
00167   _pixelSpotXTalkMap[5][6] = 0.002;
00168   _pixelSpotXTalkMap[5][7] = 0.008;
00169   _pixelSpotXTalkMap[5][8] = 0.001;
00170   
00171 
00172   // spot 4
00173 
00174   _pixelSpotXTalkMap[4][0] = 0.001; 
00175   _pixelSpotXTalkMap[4][1] = 0.008;
00176   _pixelSpotXTalkMap[4][2] = 0.002;
00177   _pixelSpotXTalkMap[4][3] = 0.004;
00178   _pixelSpotXTalkMap[4][5] = 0.011;
00179   _pixelSpotXTalkMap[4][6] = 0.001;
00180   _pixelSpotXTalkMap[4][7] = 0.008;
00181   _pixelSpotXTalkMap[4][8] = 0.002;
00182   
00183 
00184   // spot 5
00185 
00186   _pixelSpotXTalkMap[8][0] = 0.002; 
00187   _pixelSpotXTalkMap[8][1] = 0.003;
00188   _pixelSpotXTalkMap[8][2] = 0.001;
00189   _pixelSpotXTalkMap[8][3] = 0.025;
00190   _pixelSpotXTalkMap[8][5] = 0.003;
00191   _pixelSpotXTalkMap[8][6] = 0.007;
00192   _pixelSpotXTalkMap[8][7] = 0.025;
00193   _pixelSpotXTalkMap[8][8] = 0.002;
00194   
00195 
00196   // spot 6
00197 
00198   _pixelSpotXTalkMap[7][0] = 0.001; 
00199   _pixelSpotXTalkMap[7][1] = 0.004;
00200   _pixelSpotXTalkMap[7][2] = 0.001;
00201   _pixelSpotXTalkMap[7][3] = 0.006;
00202   _pixelSpotXTalkMap[7][5] = 0.006;
00203   _pixelSpotXTalkMap[7][6] = 0.003;
00204   _pixelSpotXTalkMap[7][7] = 0.025;
00205   _pixelSpotXTalkMap[7][8] = 0.003;
00206   
00207 
00208   // spot 7
00209 
00210   _pixelSpotXTalkMap[6][0] = 0.001; 
00211   _pixelSpotXTalkMap[6][1] = 0.003;
00212   _pixelSpotXTalkMap[6][2] = 0.002;
00213   _pixelSpotXTalkMap[6][3] = 0.003;
00214   _pixelSpotXTalkMap[6][5] = 0.025;
00215   _pixelSpotXTalkMap[6][6] = 0.002;
00216   _pixelSpotXTalkMap[6][7] = 0.025;
00217   _pixelSpotXTalkMap[6][8] = 0.007;
00218 
00219   for(Int_t i=0; i<MAX_NUMBER_OF_PMTS; i++){
00220     fPMTtot[i]=0.0;
00221     for(int j=0; j<16; j++){
00222       fPMTmap[i][j]=0.0;
00223       fXTalkmap[i][j]=0.0;
00224     }
00225     for(int j=0; j<22; j++){
00226       fVAmap[i][j]=0.0;
00227     }
00228   }
00229   return;
00230 }
00231 
00232 void AlgAltDeMuxBase::SetConstants(const VldContext* vldc){
00233   
00234   SimFlag::SimFlag_t simflag = vldc->GetSimFlag( );   
00235 
00236   if(simflag==SimFlag::kMC||simflag==SimFlag::kReroot ){
00237     // velocities of light in m/ns from refractive indices
00238     fClearFibreC   = 0.30/fClearFibreNMC;
00239     fWLSFibreC     = 0.30/fWLSFibreNMC;
00240     fScintillatorC = 0.30/fScintillatorNMC;
00241     // Timing resolution in ns
00242     fSigmaT        = fSigmaTMC;
00243     cout << "IT IS Monte Carlo Set Constants " << endl;
00244   }else{
00245     // velocities of light in m/ns from refractive indices
00246     fClearFibreC   = 0.30/fClearFibreN;
00247     fWLSFibreC     = 0.30/fWLSFibreN;
00248     fScintillatorC = 0.30/fScintillatorN;
00249     // Timing resolution in ns
00250     fSigmaT        = fSigmaTData;
00251   }
00252 
00253   // resolution on strip number from timing 
00254   fSigmaStripFromTiming = fSigmaT*fScintillatorC/1.4142/0.041666;
00255   MSG("AltDeMux", Msg::kWarning)  << "AlgAltDeMuxBase::SetContants Sigma from Timing : " << fSigmaStripFromTiming << " strip" << endl;
00256 
00257   // Tell the Calculator which constants to use 
00258 
00259   pCalculator->SetClearFibreC(fClearFibreC);
00260   pCalculator->SetWLSFibreC(fWLSFibreC);
00261   pCalculator->SetScintillatorC(fScintillatorC);
00262   pCalculator->SetNumberOfStrips(fNumberOfStrips);
00263   pCalculator->SetUgli(pUgh);
00264 
00265 }
00266 
00267 
00268 
00269 void AlgAltDeMuxBase::TidyUp() 
00270 {    
00271   //fList->Delete();
00272 }
00273 
00274 //______________________________________________________________________
00275 
00276 
00277 //-----------------------------------------------------------------------
00278 // Default implementation of the demuxing - does nothing
00279 void AlgAltDeMuxBase::RunAlg(AlgConfig & /* acd */, CandHandle & /* ch */, 
00280                              CandContext & /*cx */)
00281 {
00282 
00283   return;
00284 }
00285 
00286 
00287 AlgAltDeMuxBase::~AlgAltDeMuxBase()
00288 {
00289 
00290 }
00291 
00292 
00293 void AlgAltDeMuxBase::Trace(const char * /* c */) const
00294 {
00295 }
00296 
00297 void AlgAltDeMuxBase::CreateDiagnosticCanvas()
00298 {
00299 
00300   // If requested AlgAltDeMuxBase has a built-in diagnositic/debugging canvas
00301   // which provides a visual display of the DeMuxing as the algorithm
00302   // progresses through its various steps.
00303 
00304   if(diagnosticCanvas)return;
00305 
00306   diagnosticCanvas = true;
00307   string title  = "AlgAltDeMuxBase(";
00308   title = title + diagnosticCanvastitle;
00309   title = title + ") Diagnostics screen";
00310 
00311   fCanvas = new TCanvas(title.c_str(),diagnosticCanvastitle.c_str(),600,600);
00312 
00313   fUview  = NULL;
00314   fVview  = NULL;
00315   fUTime  = NULL;
00316   fVTime  = NULL;
00317   fUMask  = NULL;
00318   fVMask  = NULL;
00319   fHoughU = NULL;
00320   fHoughV = NULL;
00321   fHoughProjU = NULL;
00322   fHoughProjV = NULL;
00323   fHoughSliceU = NULL;
00324   fHoughSliceV = NULL;
00325   fUZFitS = NULL;
00326   fVZFitS = NULL;
00327   fUZFitT = NULL;
00328   fVZFitT = NULL;
00329   fUZFitSSM1 = NULL;
00330   fUZFitSSM2 = NULL;
00331   fUZFitQSSM1 = NULL;
00332   fUZFitQSSM2 = NULL;
00333   fUZFitTSM1 = NULL;
00334   fUZFitTSM2 = NULL;
00335   fVZFitSSM1 = NULL;
00336   fVZFitSSM2 = NULL;
00337   fVZFitTSM1 = NULL;
00338   fVZFitTSM2 = NULL;
00339   fVZFitQSSM1 = NULL;
00340   fVZFitQSSM2 = NULL;
00341 
00342 
00343 
00344 // Create the pads;  Pad takes xlo, ylo, xhi, yhi in NC
00345   fUpad  = new TPad("upad","U pad",0.010,0.505,0.990,0.990);
00346   fVpad  = new TPad("vpad","V pad",0.010,0.010,0.990,0.495);
00347 
00348     // white background
00349   fUpad->SetFillColor(10);
00350   fVpad->SetFillColor(10);
00351     
00352     // tweak the margins to maximize histogram use of pads
00353   fUpad->SetLeftMargin(0.05);
00354   fUpad->SetRightMargin(0.0001);
00355   fUpad->SetTopMargin(0.0001);
00356   fUpad->SetBottomMargin(0.055);
00357   fVpad->SetLeftMargin(0.05);
00358   fVpad->SetRightMargin(0.0001);
00359   fVpad->SetTopMargin(0.0001);
00360   fVpad->SetBottomMargin(0.055);
00361   fUpad->Draw();
00362   fVpad->Draw();
00363     
00364   fCanvas->Draw();
00365 }
00366 
00367 
00368 void AlgAltDeMuxBase::ClearDiagnosticHistos()
00369 {
00370 
00371   // Clear the diagnostic histograms - only called if fDiagnosticPlots==true
00372 
00373   if(!fDiagnosticPlots)return;
00374   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::ClearDiagnosticHistos()" << endl;
00375 
00376   if(fUpad)fUpad->Clear("");
00377   if(fVpad)fVpad->Clear("");
00378   
00379 // remove old histograms if they exists
00380   if ( fUview ) { delete fUview; fUview=0; }
00381   if ( fVview ) { delete fVview; fVview=0; }
00382   if ( fUTime ) { delete fUTime; fUTime=0; }
00383   if ( fVTime ) { delete fVTime; fVTime=0; }
00384   if ( fUMask ) { delete fUMask; fUMask=0; }
00385   if ( fVMask ) { delete fVMask; fVMask=0; }
00386   if ( fHoughU) { delete fHoughU; fHoughU=0; }
00387   if ( fHoughV) { delete fHoughV; fHoughV=0; }
00388   if ( fHoughProjU) { delete fHoughProjU; fHoughProjU=0; }
00389   if ( fHoughProjV) { delete fHoughProjV; fHoughProjV=0; }
00390   if ( fHoughSliceU) { delete fHoughSliceU; fHoughSliceU=0; }
00391   if ( fHoughSliceV) { delete fHoughSliceV; fHoughSliceV=0; }
00392   if(fUZFitS){delete fUZFitS; fUZFitS=0;}
00393   if(fVZFitS){delete fVZFitS; fVZFitS=0;}
00394   if(fUZFitT){delete fUZFitT; fUZFitT=0;}
00395   if(fVZFitT){delete fVZFitT; fVZFitT=0;}
00396   if(fUZFitSSM1){delete fUZFitSSM1; fUZFitSSM1=0;}
00397   if(fUZFitSSM2){delete fUZFitSSM2; fUZFitSSM2=0;}
00398   if(fUZFitQSSM1){delete fUZFitQSSM1; fUZFitQSSM1=0;}
00399   if(fUZFitQSSM2){delete fUZFitQSSM2; fUZFitQSSM2=0;}
00400   if(fVZFitQSSM1){delete fVZFitQSSM1; fVZFitQSSM1=0;}
00401   if(fVZFitQSSM2){delete fVZFitQSSM2; fVZFitQSSM2=0;}
00402   if(fUZFitTSM1){delete fUZFitTSM1; fUZFitTSM1=0;}
00403   if(fUZFitTSM2){delete fUZFitTSM2; fUZFitTSM2=0;}
00404   if(fVZFitSSM1){delete fVZFitSSM1; fVZFitSSM1=0;}
00405   if(fVZFitSSM2){delete fVZFitSSM2; fVZFitSSM2=0;}
00406   if(fVZFitTSM1){delete fVZFitTSM1; fVZFitTSM1=0;}
00407   if(fVZFitTSM2){delete fVZFitTSM2; fVZFitTSM2=0;}
00408 
00409   // create histograms that we'll use for World Coordinates
00410   // create histograms that we'll use for World Coordinates
00411   fUview = new TH2F("Uview","U view",501,-0.5,500.5,1,0.,193.);
00412   fVview = new TH2F("Vview","V view",501,-0.5,500.5,1,0.,193.);
00413   fUTime = new TH2F("UTime","U time view",501,-0.5,500.5,193,0.,193.);
00414   fVTime = new TH2F("VTime","V time view",501,-0.5,500.5,193,0.,193.);
00415   fUMask = new TH2F("UMask","U view mask",501,-0.5,500.5,193,0.,193.);
00416   fVMask = new TH2F("VMask","V view mask",501,-0.5,500.5,193,0.,193.);
00417   fHoughU = new TH2F("houghSpaceU", "U Hough Space", 400, -3., 1., 500, -250., 250.);
00418   fHoughV = new TH2F("houghSpaceV", "V Hough Space", 400, -3., 1., 500, -250., 250.);
00419 
00420   fHoughProjU = new TH1F("houghSpaceProjU", "U HoughX Space", 400, -3., 1.);
00421   fHoughProjV = new TH1F("houghSpaceProjV", "V HoughX Space", 400, -3., 1.);
00422 
00423   fHoughSliceU = new TH1F("houghSpaceSliceU", "U Hough c", 500, -250., 250.);
00424   fHoughSliceV = new TH1F("houghSpaceSliceV", "V Hough c", 500, -250., 250.);
00425 
00426     
00427   // don't draw the Stats box
00428   fUview->SetStats(kFALSE);
00429   fVview->SetStats(kFALSE);
00430   
00431   fUTime->SetStats(kFALSE);
00432   fVTime->SetStats(kFALSE);
00433   
00434   fUMask->SetStats(kFALSE);
00435   fVMask->SetStats(kFALSE);
00436 
00437   fHoughU->SetStats(kFALSE);
00438   fHoughV->SetStats(kFALSE);
00439 
00440   fHoughProjU->SetStats(kFALSE);
00441   fHoughProjV->SetStats(kFALSE);
00442 
00443   fHoughSliceU->SetStats(kFALSE);
00444   fHoughSliceV->SetStats(kFALSE);
00445     
00446   // take away any association with a "directory" for these histograms
00447   fUview->SetDirectory(0);
00448   fVview->SetDirectory(0);
00449 
00450   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::ClearDiagnosticHistos() DONE" << endl;
00451 
00452   return;
00453 }
00454 
00455 void AlgAltDeMuxBase::ClearArrays()
00456 {
00457 
00458   // Zero internal arrays/vectors used to DeMux event
00459 
00460   fEventType = UNKNOWN;
00461 
00462   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::ClearArrays()" << endl;
00463 
00464   // Timelist will contain an ordered list of hit times.
00465   fTimeList.erase(fTimeList.begin(),fTimeList.end());
00466 
00467   // Reset the timing masks 
00468   ResetTimingMask();
00469 
00470   // Reset the DeMuxed group ID counter
00471   fUniqueDeMuxedGroupID=0;
00472 
00473   // Clear vector of DeMuxed strip end EW pairs
00474 
00475   // loop over planes/ends
00476   for(Int_t iplane=0; iplane<MAX_NUMBER_OF_PLANES;iplane++){
00477     fUVMap[iplane]=PlaneView::kUnknown;
00478     for(Int_t istrip=0; istrip<MAX_NUMBER_OF_STRIPS;istrip++){
00479       fTimingMask[iplane][istrip] = false;
00480     }
00481     fDeMuxedPairs[iplane].erase(fDeMuxedPairs[iplane].begin(),fDeMuxedPairs[iplane].end());
00482     fDeMuxedSingles[iplane].erase(fDeMuxedSingles[iplane].begin(),fDeMuxedSingles[iplane].end());
00483     NdemuxedHitsU[iplane] = 0;
00484     NdemuxedHitsV[iplane] = 0;
00485     for(Int_t iew=0; iew<=1;iew++){
00486       // Clear the arrays of vectors of AltLists
00487       fPlanesAltLists[iplane][iew].erase(fPlanesAltLists[iplane][iew].begin(),fPlanesAltLists[iplane][iew].end());
00488       fDeMuxedPlanesAltLists[iplane][iew].erase(fDeMuxedPlanesAltLists[iplane][iew].begin(),fDeMuxedPlanesAltLists[iplane][iew].end());
00489       fNoisePlanesAltLists[iplane][iew].erase(fNoisePlanesAltLists[iplane][iew].begin(),fNoisePlanesAltLists[iplane][iew].end());
00490       fXTalkPlanesAltLists[iplane][iew].erase(fXTalkPlanesAltLists[iplane][iew].begin(),fXTalkPlanesAltLists[iplane][iew].end());
00491     }
00492     // zero counters
00493     fPlaneHit[iplane] = 0;
00494     fPlanePair[iplane] = 0;
00495     fGoldPlaneHit[iplane] = 0;
00496     fQTotE[iplane] = 0;
00497     fQTotW[iplane] = 0;
00498     fQMaxE[iplane] = 0;
00499     fQMaxW[iplane] = 0;
00500   }
00501   _nDeMuxedPlanesU=0;
00502   _nDeMuxedPlanesV=0;
00503   _nHitPlanesU=0;
00504   _nHitPlanesV=0;
00505 
00506 
00507   // Zero PMT maps (for previously PMT with hits from previous event)
00508   for(int i=0; i<MAX_NUMBER_OF_PMTS; i++){
00509     if(fPMTtot[i]>0){
00510       fPMTtot[i]=0.0;
00511       for(int j=0; j<16; j++){
00512         fPMTmap[i][j]=0.0;
00513         fXTalkmap[i][j]=0.0;
00514       }
00515       for(int j=0; j<22; j++){
00516         fVAmap[i][j]=0.0;
00517       }
00518     }
00519   }
00520 
00521   // reset range of planes to DeMux 
00522   fLowestDeMuxedPairPlane = MAX_NUMBER_OF_PLANES-1;
00523   fHighestDeMuxedPairPlane = 0;
00524 
00525   fUseHoughSlope         = false;      
00526   fUseFitSlopeTime       = false;   
00527   fUseFitSlopeHits       = false;   
00528   fUseInterpolation      = false;      
00529   fUseSafeExtrapolationF = false; 
00530   fUseSafeExtrapolationB = false; 
00531   fUseLevelStripF        = false;         
00532   fUseLevelStripB        = false;         
00533   //************************************
00534   fUseExtrapolationF     = true;     
00535   fUseExtrapolationB     = true;     
00536   fUseSameStrip          = true;          
00537   //************************************
00538 
00539   // say goodbye
00540   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::ClearArrays() DONE" << endl;
00541 }
00542 
00543 
00544 void AlgAltDeMuxBase::MakeAltListMap(CandDigitListHandle& cdlh)
00545 {
00546   
00547   // Fill the arrays of {vectors of AltLists} which are to navigate through
00548   // the UNDEMUXed hits. Could have used Navigator instead but familiarity
00549   // won out. Arrays of vectors also provide a fast efficient method of
00550   // iterating over the data
00551 
00552   PlexSEIdAltL* paltlist;
00553 
00554   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::MakeAltListMap" << endl;
00555   
00556   int ndigits = 0;
00557   fAbsTime = cdlh.GetAbsTime()*1.0E9;
00558   pCalculator->SetAbsTime(fAbsTime);
00559 
00560   CandDigitHandleItr cdhItr(cdlh.GetDaughterIterator());
00561   
00562   while ( CandDigitHandle *cdh = cdhItr() ) {
00563     // for each digit
00564     paltlist = &(cdh->GetPlexSEIdAltLWritable());
00565     int iplane = paltlist->GetPlane();
00566     if(!paltlist->IsVetoShield()){
00567       if(iplane>0&&iplane<MAX_NUMBER_OF_PLANES){
00568         if(paltlist->GetEnd()==StripEnd::kEast){
00569           fPlanesAltLists[iplane][ALG_EAST].push_back(paltlist);
00570         }else{
00571           fPlanesAltLists[iplane][ALG_WEST].push_back(paltlist);
00572         }
00573         fTimeList.push_back(paltlist->GetCurrentItem().GetTime()*1.0E9);
00574         fUVMap[iplane] = paltlist->GetPlaneView(); 
00575         ndigits++;
00576       }else{
00577         MSG("AltDeMux", Msg::kWarning) << "AlgAltDeMuxBase::MakeAltListMap => Plane out of array bounds : " << iplane << " - would give overflow (ignoring it)!" << endl;
00578       }
00579     }else{
00580       // MSG("AltDeMux", Msg::kVerbose) << "AlgAltDeMuxBase::MakeAltListMap => Veto Shield Plane : " << iplane << " - IGNORE IT !" << endl;
00581     }
00582   }
00583 
00584   return;
00585 }
00586 
00587 void  AlgAltDeMuxBase::MakePixelMap(CandDigitListHandle& cdlh)
00588 {
00589   
00590   // Build up a map of charge deposits for each PMT pixel - for use in
00591   // crosstalk rejection. NOTE PMTmuxID is an internal number scheme
00592   // for FarDet PMTs
00593 
00594   PlexSEIdAltL* paltlist;
00595   
00596   CandDigitHandleItr cdhItr(cdlh.GetDaughterIterator());
00597   
00598   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::MakePixelMap" << endl;
00599 
00600   while ( CandDigitHandle *cdh = cdhItr() ) {
00601     // for each digit
00602     paltlist = &(cdh->GetPlexSEIdAltLWritable());
00603     int iplane = paltlist->GetPlane();
00604     paltlist->SetFirst();
00605     
00606     if(!paltlist->IsVetoShield()){
00607       if(iplane>0&&iplane<MAX_NUMBER_OF_PLANES){
00608 
00609         PlexPixelSpotId pixelID = (paltlist->GetCurrentItem()).GetPixelSpotId(); 
00610         Int_t pixel  = pixelID.GetPixel();
00611         Int_t vaChannel = _pixelToVaChannel[pixel];
00612         Int_t PMTmuxID = pixelID.GetTube();
00613         PMTmuxID      += 3*pixelID.GetInRack();
00614         PMTmuxID      += 24*pixelID.GetRackBay();
00615         Char_t level = pixelID.GetRackLevel(); 
00616         Char_t ew = pixelID.GetEastWest(); 
00617         if(level=='U'){
00618           PMTmuxID += 450;
00619         }
00620         if(ew =='E'){
00621           PMTmuxID += 900;
00622         }
00623         //      Int_t uid = pixelID.GetUniquePmtEncodedValue();    
00624 
00625         if(PMTmuxID<MAX_NUMBER_OF_PMTS){
00626           Float_t q  = paltlist->GetCurrentItem().GetPE();
00627           Float_t qc = paltlist->GetCurrentItem().GetSigCorr()/60.;
00628           if(qc/q<0.1 || qc/q > 10.0){
00629             MSG("AltDeMux", Msg::kWarning) << "AlgAltDeMuxBase::MakePixelMap Large/small SigCor/SigPE ratio : " <<qc/q << " for Plane : " << iplane << endl;
00630             qc=q;
00631           }
00632           fPMTmap[PMTmuxID][pixel] += qc; 
00633           fVAmap[PMTmuxID][vaChannel] += qc; 
00634           fPMTtot[PMTmuxID]        += qc; 
00635         }else{
00636           MSG("AltDeMux", Msg::kError) << "AlgAltDeMuxBase::MakePixelMap => PMT out of array bounds : " << PMTmuxID << " ignoring it !" << endl;
00637         }
00638       }
00639     }
00640   }
00641 
00642   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::MakePixelMap DONE" << endl;
00643 
00644   return;
00645 }
00646 
00647 
00648 
00649 void  AlgAltDeMuxBase::StripNoise()
00650 {
00651   
00652   // Attempt to identify and remove probably out-of-time noise hits. 
00653 
00654   Int_t nNoiseHits=0;
00655   bool ok;
00656 
00657   if(fTimeList.size()==0){
00658     return;
00659   }
00660 
00661   sort(fTimeList.begin(),fTimeList.end());
00662   Int_t median = static_cast<Int_t>(fTimeList.size()*0.5);
00663   Float_t medianTime = fTimeList[median];
00664 
00665 
00666   MSG("AltDeMux", Msg::kVerbose) << "AlgAltDeMuxBase::StripNoiseHits - Median hit time : " << medianTime << endl;
00667 
00668   vector <PlexSEIdAltL*>::iterator literA;
00669 
00670   // Identify noise hits and store in fNoisePlanesAltLists 
00671 
00672   for(int iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
00673     for(int iew = 0; iew<=1; iew++){
00674       if(fPlanesAltLists[iplane][iew].size()>0){
00675         literA = fPlanesAltLists[iplane][iew].begin();
00676         while (literA != fPlanesAltLists[iplane][iew].end()){
00677           if( (*literA)->GetCurrentItem().GetPE()<1.5){
00678             if(fabs(  (*literA)->GetCurrentItem().GetTime()*1E9-medianTime)>fNoiseTimeWindow){
00679               MSG("AltDeMux", Msg::kVerbose) << "AlgAltDeMuxBase::StripNoiseHits - Noise Hit in plane : " << iplane << " q : " << (*literA)->GetCurrentItem().GetPE() << " time : " << (*literA)->GetCurrentItem().GetTime()*1E9 << endl; 
00680               fNoisePlanesAltLists[iplane][iew].push_back(*literA);
00681               nNoiseHits++;
00682             }
00683           }
00684           *literA++;
00685         }
00686       }
00687     }
00688   }
00689 
00690 
00691   // Remove noise hits from fPlanesAltLists 
00692 
00693   for(int iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
00694     for(int iew = 0; iew<=1; iew++){
00695       if(fNoisePlanesAltLists[iplane][iew].size()>0){
00696         literA = fNoisePlanesAltLists[iplane][iew].begin();
00697         while (literA != fNoisePlanesAltLists[iplane][iew].end()){
00698           ok = RemoveFromPlanesList(iplane,iew,*literA);
00699           if(!ok)MSG("AltDeMux", Msg::kError) << "AlgAltDeMuxBase::StripNoiseHits - hit not found !" << endl;
00700           *literA++;
00701         }
00702       }
00703     }
00704   }
00705 
00706   return;
00707 }
00708 
00709 bool AlgAltDeMuxBase::RemoveFromPlanesList(Int_t iplane, Int_t iew, PlexSEIdAltL* paltlist)
00710 {
00711 
00712   // Find and remove an PlexSEIdAltL* from the fPlanesAltList array
00713   // which stores undemuxed hits.
00714 
00715   vector <PlexSEIdAltL*>::iterator literA;
00716 
00717 
00718   literA = fPlanesAltLists[iplane][iew].begin();
00719   while (literA != fPlanesAltLists[iplane][iew].end()){
00720     if( (*literA)==paltlist ){
00721       fPlanesAltLists[iplane][iew].erase(literA);
00722       return true;
00723     }
00724     literA++;
00725   }
00726 
00727   return false;
00728   
00729 }
00730 
00731 bool AlgAltDeMuxBase::RemoveSingle(Int_t iplane, PlexSEIdAltL* paltlist)
00732 {
00733 
00734   // Find and remove an PlexSEIdAltL* from the fDeMuxedSingles array
00735   // which stores undemuxed hits.
00736 
00737   vector <DeMuxedSingle>::iterator literA;
00738  
00739   literA = fDeMuxedSingles[iplane].begin();
00740   while (literA != fDeMuxedSingles[iplane].end()){
00741     if( (*literA).altList==paltlist ){
00742       fDeMuxedSingles[iplane].erase(literA);
00743       return true;
00744     }
00745     literA++;
00746   }
00747 
00748   return false;
00749   
00750 }
00751 
00752 
00753 void  AlgAltDeMuxBase::StripCrossTalk(CandDeMuxDigitListHandle& cdlh)
00754 {
00755 
00756   // Loop over all hits (stored in fPlanesAltList array) and use PMT
00757   // map to decide whether hit is likely to be cross-talk. If a hit
00758   //
00759 
00760   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::StripCrossTalk" << endl;
00761 
00762   Int_t nXTalkHits=0;
00763   vector <PlexSEIdAltL*>::iterator literA;
00764 
00765   for(int iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
00766     for(int iew = ALG_EAST; iew<=ALG_WEST; iew++){
00767       if(fPlanesAltLists[iplane][iew].size()>0){
00768         literA = fPlanesAltLists[iplane][iew].begin();
00769         while (literA != fPlanesAltLists[iplane][iew].end()){
00770           if(IsXTalk(*literA)){
00771             fXTalkPlanesAltLists[iplane][iew].push_back(*literA);
00772             MSG("AltDeMux", Msg::kVerbose) << "AlgAltDeMuxBase::StripCrossTalk - remove hit" << endl;
00773             nXTalkHits++;
00774           }
00775           literA++;
00776         }
00777       }
00778     }
00779   }
00780 
00781 
00782   // Remove cross talk hits from fPlanesAltLists 
00783 
00784   for(int iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
00785     for(int iew = ALG_EAST; iew<=ALG_WEST; iew++){
00786       if(fXTalkPlanesAltLists[iplane][iew].size()>0){
00787         literA = fXTalkPlanesAltLists[iplane][iew].begin();
00788         while (literA != fXTalkPlanesAltLists[iplane][iew].end()){
00789           bool ok = RemoveFromPlanesList(iplane,iew,*literA);
00790           if(!ok)MSG("AltDeMux", Msg::kError) << "AlgAltDeMuxBase::StripCrossTalk - hit not found !" << endl;
00791           *literA++;
00792         }
00793       }
00794     }
00795   }
00796 
00797   this->TagCrossTalk(cdlh);
00798 
00799   MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::StripCrossTalk DONE" << endl;
00800 
00801   return;
00802 
00803 }
00804 
00805 
00806 
00807 void  AlgAltDeMuxBase::ReTagCrossTalk(CandDeMuxDigitListHandle& cdlh)
00808 {
00809 
00810 
00811   CandDeMuxDigitHandleItr cdhItr(cdlh.GetDaughterIterator());
00812   
00813   while ( CandDeMuxDigitHandle *digit = cdhItr() ) {
00814     // for each digit
00815     PlexSEIdAltL* paltlist = &(digit->GetPlexSEIdAltLWritable());
00816     amShowing = false;
00817     paltlist->GetBestItem();
00818     if(!paltlist->IsValid())paltlist->SetFirst();
00819     if(paltlist->IsValid()){
00820       Int_t dmxXTalk = digit->GetDeMuxDigitFlagWord();
00821       if(dmxXTalk==0){
00822         if(IsXTalk(paltlist)){
00823           digit->SetDeMuxDigitFlagBit(CandDeMuxDigit::kXTalk);  
00824         }
00825       }else{
00826       }
00827     }else{
00828       //cout << "INVALID ALTLIST ! " << endl;
00829     }
00830     amShowing = false;
00831   }
00832 
00833   return;
00834 
00835 }
00836 
00837 
00838 
00839 void  AlgAltDeMuxBase::FinalReTagCrossTalk(CandDeMuxDigitListHandle& cdlh)
00840 {
00841 
00842   CandDeMuxDigitHandleItr cdhItr(cdlh.GetDaughterIterator());
00843   
00844   while ( CandDeMuxDigitHandle *digit = cdhItr() ) {
00845     // for each digit
00846     PlexSEIdAltL* paltlist = &(digit->GetPlexSEIdAltLWritable());
00847     if(paltlist->GetSize()==0){
00848       // pixel spot does not correspond to valid strip - tag as xtalk 
00849       digit->SetDeMuxDigitFlagBit(CandDeMuxDigit::kXTalk);  
00850       return;
00851     }
00852     amShowing = false;
00853     paltlist->GetBestItem();
00854     if(!paltlist->IsValid())paltlist->SetFirst();
00855     if(paltlist->IsValid()){
00856       Int_t dmxXTalk = digit->GetDeMuxDigitFlagWord();
00857       if(dmxXTalk==0){
00858         if(IsXTalk(paltlist)){
00859           digit->SetDeMuxDigitFlagBit(CandDeMuxDigit::kXTalk);  
00860         }else{
00861           digit->UnSetDeMuxDigitFlagBit(CandDeMuxDigit::kXTalk);
00862         }
00863       }
00864       float Q     = paltlist->GetBestItem().GetSigCorr()/60.; 
00865       float qspot = PredictedSpotQ(paltlist);
00866       float dist = DistanceToNearestInPlane(paltlist);
00867       if(dmxXTalk!=0){
00868         if(dist==0){
00869           digit->UnSetDeMuxDigitFlagBit(CandDeMuxDigit::kXTalk);
00870           //      cout << "****************************UNSET XTALK FLAG !!!! " << Q << endl; 
00871         }
00872         if(dist==1){
00873           if(Q>3)digit->UnSetDeMuxDigitFlagBit(CandDeMuxDigit::kXTalk);
00874           //cout << "****************************UNSET XTALK FLAG !!!! " << Q << endl; 
00875         }
00876         if(dist==2){
00877           if(Q>5)digit->UnSetDeMuxDigitFlagBit(CandDeMuxDigit::kXTalk);
00878           //cout << "****************************UNSET XTALK FLAG !!!! " << Q << endl; 
00879         }
00880       }else{
00881         if(dist>8){
00882           if(qspot/Q>0.001&&Q<4)digit->SetDeMuxDigitFlagBit(CandDeMuxDigit::kXTalk);
00883         }
00884       }
00885     }else{
00886       //cout << "INVALID ALTLIST ! " << endl;
00887     }
00888     amShowing = false;
00889   }
00890 
00891   return;
00892 
00893 }
00894 
00895 
00896 Float_t AlgAltDeMuxBase::DistanceToNearestInPlane(PlexSEIdAltL* paltlist)
00897 {
00898 
00899   Float_t dmin=999;
00900   PlexStripEndId  seid;
00901   PlexStripEndId dseid;
00902   
00903   int iplane = paltlist->GetPlane();
00904   seid = paltlist->GetBestSEId();
00905   int strip = seid.GetStrip();
00906 
00907   if(iplane>MAX_NUMBER_OF_PLANES)return dmin;
00908 
00909   for(int iew = ALG_EAST; iew<=ALG_WEST; iew++){
00910     for(uint i=0;i<fDeMuxedPlanesAltLists[iplane][iew].size();i++){
00911       if(fDeMuxedPlanesAltLists[iplane][iew][i]!=paltlist){
00912         dseid = fDeMuxedPlanesAltLists[iplane][iew][i]->GetBestSEId();
00913         int dstrip = dseid.GetStrip();
00914         int d = abs(dstrip-strip);
00915         if(d<dmin)dmin=d;
00916       }
00917     }
00918   }
00919 
00920   return dmin;
00921 }
00922 
00923 
00924 Float_t AlgAltDeMuxBase::PredictedSpotQ(PlexSEIdAltL* paltlist)
00925 { 
00926   
00927   PlexPixelSpotId pixelID = (paltlist->GetBestItem()).GetPixelSpotId(); 
00928   Int_t pixel  = pixelID.GetPixel();
00929   Int_t PMTmuxID = pixelID.GetTube();
00930   PMTmuxID      += 3*pixelID.GetInRack();
00931   PMTmuxID      += 24*pixelID.GetRackBay();
00932   Char_t level = pixelID.GetRackLevel(); 
00933   Char_t ew = pixelID.GetEastWest(); 
00934   if(level=='U')PMTmuxID += 450;
00935   if(ew =='E')PMTmuxID += 900;
00936 
00937   return fXTalkmap[PMTmuxID][pixel];
00938 
00939 } 
00940 
00941 void  AlgAltDeMuxBase::TagCrossTalk(CandDeMuxDigitListHandle& cdlh)
00942 {
00943   
00944   PlexSEIdAltL* paltlist;
00945   vector <PlexSEIdAltL*>::iterator literA;
00946   
00947   CandDeMuxDigitHandleItr cdhItr(cdlh.GetDaughterIterator());
00948   
00949   MSG("AltDeMux", Msg::kVerbose) << "AlgAltDeMuxBase::MakePixelMap" << endl;
00950 
00951   while ( CandDeMuxDigitHandle *digit = cdhItr() ) {
00952     // for each digit
00953     paltlist = &(digit->GetPlexSEIdAltLWritable());
00954     int iplane = paltlist->GetPlane();
00955     for(int iew = ALG_EAST; iew<=ALG_WEST; iew++){
00956       if(fXTalkPlanesAltLists[iplane][iew].size()>0){
00957         literA = fXTalkPlanesAltLists[iplane][iew].begin();
00958         while (literA != fXTalkPlanesAltLists[iplane][iew].end()){
00959           if(*literA==paltlist){
00960             digit->SetDeMuxDigitFlagBit(CandDeMuxDigit::kXTalk);  
00961           }
00962           *literA++;
00963         }
00964       }
00965     }
00966   }
00967 
00968   return;
00969 }
00970 
00971 
00972 void  AlgAltDeMuxBase::AddBackCrossTalk()
00973 {
00974 
00975   vector <PlexSEIdAltL*>::iterator literA;
00976 
00977   for(int iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
00978     for(int iew = ALG_EAST; iew<=ALG_WEST; iew++){
00979       if(fXTalkPlanesAltLists[iplane][iew].size()>0){
00980         literA = fXTalkPlanesAltLists[iplane][iew].begin();
00981         while (literA != fXTalkPlanesAltLists[iplane][iew].end()){
00982           fPlanesAltLists[iplane][iew].push_back(*literA);
00983           literA++;
00984         }
00985         fXTalkPlanesAltLists[iplane][iew].erase(fXTalkPlanesAltLists[iplane][iew].begin(),fXTalkPlanesAltLists[iplane][iew].end());
00986       }
00987 
00988     }
00989   }
00990 
00991   return;
00992 
00993 }
00994 
00995 
00996 
00997 
00998 
00999 void  AlgAltDeMuxBase::AddBackNoise()
01000 {
01001   vector <PlexSEIdAltL*>::iterator literA;
01002 
01003   for(int iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
01004     for(int iew = ALG_EAST; iew<=ALG_WEST; iew++){
01005       if(fNoisePlanesAltLists[iplane][iew].size()>0){
01006         literA = fNoisePlanesAltLists[iplane][iew].begin();
01007         while (literA != fNoisePlanesAltLists[iplane][iew].end()){
01008           fPlanesAltLists[iplane][iew].push_back(*literA);
01009           literA++;
01010         }
01011         fNoisePlanesAltLists[iplane][iew].erase(fNoisePlanesAltLists[iplane][iew].begin(),fNoisePlanesAltLists[iplane][iew].end());
01012       }
01013 
01014     }
01015   }
01016 
01017   return;
01018 
01019 }
01020 
01021 
01022 
01023 
01024 void  AlgAltDeMuxBase::FillLowestHighest()
01025 {
01026 
01027   bool first=true;
01028   bool last =true;
01029   fLowestPlane = 0;
01030   fHighestPlane = MAX_NUMBER_OF_PLANES-1;
01031 
01032   for(Int_t iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
01033     if(fPlanesAltLists[iplane][ALG_EAST].size()>0||fPlanesAltLists[iplane][ALG_WEST].size()>0){
01034       if(first){
01035         Int_t nextPlane=999;
01036         bool carryOn = true;
01037         for(Int_t j = iplane+1; carryOn && j < MAX_NUMBER_OF_PLANES; j++){
01038           if(fPlanesAltLists[j][ALG_EAST].size()>0||
01039              fPlanesAltLists[j][ALG_WEST].size()>0){
01040             nextPlane = j;
01041             carryOn = false;
01042           }
01043         }
01044         if((nextPlane-iplane)<10){
01045           first = false;
01046           fLowestPlane = iplane;
01047         }
01048       }
01049     }
01050   }
01051 
01052 
01053   for(Int_t iplane=MAX_NUMBER_OF_PLANES-1; iplane>0; iplane--){
01054     if(fPlanesAltLists[iplane][ALG_EAST].size()>0||fPlanesAltLists[iplane][ALG_WEST].size()>0){
01055       if(last){
01056         Int_t nextPlane=-999;
01057         bool carryOn = true;
01058 
01059         for(Int_t j = iplane-1; carryOn && j >= 0; j--){
01060           if(fPlanesAltLists[j][ALG_EAST].size()>0||
01061              fPlanesAltLists[j][ALG_WEST].size()>0){
01062             nextPlane = j;
01063             carryOn = false;
01064           }
01065         }
01066         if((iplane-nextPlane)<10){
01067           last = false;
01068           fHighestPlane = iplane;
01069         }
01070       }
01071     }
01072   }
01073 
01074   return;
01075 
01076 }
01077 
01078 
01079 void AlgAltDeMuxBase::Setup() 
01080 {
01081   pMaster = new AltDeMuxPatternMaster();
01082   for(int i=0;i<MAX_NUMBER_OF_PMTS;i++){
01083     fPMTtot[i] = 0;
01084   }
01085   amPSing   = false;
01086   amHisting   = false;
01087 
01088   return;
01089 
01090 }
01091 
01092 
01093 void AlgAltDeMuxBase::GetFibreLengths()
01094 {
01095   // Store the fibre lengths for strips in this event.  
01096 
01097   UgliStripHandle ush;
01098   vector <PlexSEIdAltL*>::iterator literA;
01099 
01100   MSG("AltDeMux", Msg::kVerbose) << "AlgAltDeMuxBase::GetFibreLengths " << endl;
01101  
01102   for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
01103     for(Int_t iew = ALG_EAST; iew <= ALG_WEST; iew++){
01104       if(fPlanesAltLists[iplane][iew].size()>0){
01105         literA = fPlanesAltLists[iplane][iew].begin();
01106         while (literA != fPlanesAltLists[iplane][iew].end()){
01107           (*literA)->SetFirst();
01108           while( (*literA)->IsValid() ){
01109             ush = pUgh->GetStripHandle((*literA)->GetCurrentSEId());
01110             if(!ush.IsValid())MSG("AltDeMux", Msg::kFatal) << "AlgAltDeMuxBase::GetFibreLengths => UgliStripHandle NOT VALID : plane " << iplane << " (Carry on regardless)" <<  endl;
01111             if(iew==ALG_EAST)pCalculator->SetFibreLengthE(iplane,*literA);
01112             if(iew==ALG_WEST)pCalculator->SetFibreLengthW(iplane,*literA);
01113             (*literA)->Next();
01114           }
01115           *literA++;
01116         }
01117       }
01118     }
01119   }
01120   return;
01121 
01122 }
01123 
01124 void AlgAltDeMuxBase::MakeTimingMask(bool useMask){
01125   
01126   vector <PlexSEIdAltL*>::iterator literE;
01127   vector <PlexSEIdAltL*>::iterator literW;
01128 
01129   // if diagnostic/debug
01130   if(fDiagnosticPlots){
01131     if ( fUTime ) { delete fUTime; fUTime=0; }
01132     if ( fVTime ) { delete fVTime; fVTime=0; }
01133     fUTime = new TH2F("UTime","U time view",501,-0.5,500.5,193,0.,193.);
01134     fVTime = new TH2F("VTime","V time view",501,-0.5,500.5,193,0.,193.);
01135     fUTime->SetStats(kFALSE);
01136     fVTime->SetStats(kFALSE);
01137   }
01138 
01139   for(int iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
01140     fMaskGroup[iplane].erase(fMaskGroup[iplane].begin(),fMaskGroup[iplane].end());
01141     fInMask[iplane] =  0;
01142     if(fPlanesAltLists[iplane][ALG_EAST].size()>0||fPlanesAltLists[iplane][ALG_WEST].size()>0){
01143       // Reset timing mask strip targets and target groups for this palne 
01144       for(int istrip=0;istrip<=MAX_NUMBER_OF_STRIPS;istrip++){
01145         fTimingMask[iplane][istrip] = false;
01146       }
01147     }
01148 
01149     if(fPlanesAltLists[iplane][ALG_EAST].size()>0&&fPlanesAltLists[iplane][ALG_WEST].size()>0){
01150       literE = fPlanesAltLists[iplane][ALG_EAST].begin();
01151       PlaneView::PlaneView_t kView = (*literE)->GetPlaneView();
01152       pCalculator->SetPlane(iplane);
01153       pCalculator->SetView(kView);
01154       while (literE != fPlanesAltLists[iplane][ALG_EAST].end()){
01155         literW = fPlanesAltLists[iplane][ALG_WEST].begin();
01156         while ( literW != fPlanesAltLists[iplane][ALG_WEST].end()){
01157           (*literE)->SetFirst();
01158           while( (*literE)->IsValid() ){
01159             Int_t  iStripE = (*literE)->GetCurrentSEId().GetStrip();
01160             pCalculator->SetEast(*literE,iStripE);
01161             bool goodComb = true;
01162             if(useMask && fUVmask[iplane][iStripE]==false)goodComb = false; 
01163             if(goodComb){             
01164               (*literW)->SetFirst();
01165               while( (*literW)->IsValid() ){
01166                 Int_t  iStripW = (*literW)->GetCurrentSEId().GetStrip();
01167                 if(iStripE==iStripW){
01168                   // In here we can check for a possibility
01169                   pCalculator->SetWest(*literW,iStripW);
01170                   pCalculator->CalcEastWest();
01171                   if(fabs(pCalculator->SigmaDQ())<4.0){
01172                     Int_t isaim = pCalculator->StripAim();
01173                     fInMask[iplane]++;
01174                     fTimingMask[iplane][isaim] = true;
01175                     if(fDiagnosticPlots){
01176                       if(kView==PlaneView::kV)fUTime->Fill(iplane,isaim,1.);
01177                       if(kView==PlaneView::kU)fVTime->Fill(iplane,isaim,1.);
01178                     }
01179                   }
01180                 }
01181                 (*literW)->Next();
01182               }
01183             }
01184             (*literE)->Next();
01185           }
01186           literW++;
01187         }
01188         literE++;
01189       }
01190     }
01191   }
01192 
01193   if(fDiagnosticPlots)this->DrawDiagnosticPlots(-2);
01194 
01195   this->MakeMaskGroups();
01196 
01197   for(int iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
01198     if(fPlanesAltLists[iplane][ALG_EAST].size()>0||fPlanesAltLists[iplane][ALG_WEST].size()>0){
01199       bool found = false;
01200       if(iplane==0){
01201         int ip = 1;
01202         int ipp = 3; 
01203         found = found || MaskExtrapolateBack(iplane,ip,ipp);
01204       }else{
01205         // For planes with hits : check surrounding planes
01206         int im=iplane-1;
01207         int ip=iplane+1;
01208         found = found || MaskInterpolate(iplane,im,ip);
01209         if(!found){
01210           int imm = iplane-3;
01211           int ipp = iplane+3;
01212           if(imm>=0)found = found || MaskInterpolate(iplane,imm,ip);
01213           if(ipp<499)found = MaskInterpolate(iplane,im,ipp) || found;
01214           if(!found){
01215             if(imm>=0)found = found || MaskExtrapolateForwards(iplane,imm,im);
01216             if(ipp<499)found = MaskExtrapolateBack(iplane,ip,ipp) || found;
01217           }
01218         }
01219       }
01220       if(!found)for(int istrip=0;istrip<fNumberOfStrips;istrip++)this->SetMask(iplane,istrip);
01221     }
01222   }  
01223 
01224   if(fDiagnosticPlots)this->DrawDiagnosticPlots(-1);
01225 
01226   return;
01227   
01228 } 
01229 
01230 
01231 
01232 
01233 
01234 
01235 void AlgAltDeMuxBase::ReMakeTimingMask(bool useMask){
01236   
01237   vector <PlexSEIdAltL*>::iterator literE;
01238   vector <PlexSEIdAltL*>::iterator literW;
01239 
01240   // if diagnostic/debug
01241   if(fDiagnosticPlots){
01242     if ( fUTime ) { delete fUTime; fUTime=0; }
01243     if ( fVTime ) { delete fVTime; fVTime=0; }
01244     fUTime = new TH2F("UTime","U time view",501,-0.5,500.5,193,0.,193.);
01245     fVTime = new TH2F("VTime","V time view",501,-0.5,500.5,193,0.,193.);
01246     fUTime->SetStats(kFALSE);
01247     fVTime->SetStats(kFALSE);
01248   }
01249 
01250   for(int iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
01251     fMaskGroup[iplane].erase(fMaskGroup[iplane].begin(),fMaskGroup[iplane].end());
01252     fInMask[iplane] =  0;
01253     if(fDeMuxedPlanesAltLists[iplane][ALG_EAST].size()>0||fDeMuxedPlanesAltLists[iplane][ALG_WEST].size()>0){
01254       // Reset timing mask strip targets and target groups for this palne 
01255       for(int istrip=0;istrip<=MAX_NUMBER_OF_STRIPS;istrip++){
01256         fTimingMask[iplane][istrip] = false;
01257       }
01258     }
01259 
01260     if(fDeMuxedPlanesAltLists[iplane][ALG_EAST].size()>0&&fDeMuxedPlanesAltLists[iplane][ALG_WEST].size()>0){
01261       literE = fDeMuxedPlanesAltLists[iplane][ALG_EAST].begin();
01262       PlaneView::PlaneView_t kView = (*literE)->GetPlaneView();
01263       pCalculator->SetPlane(iplane);
01264       pCalculator->SetView(kView);
01265       while (literE != fDeMuxedPlanesAltLists[iplane][ALG_EAST].end()){
01266         literW = fDeMuxedPlanesAltLists[iplane][ALG_WEST].begin();
01267         while ( literW != fDeMuxedPlanesAltLists[iplane][ALG_WEST].end()){
01268           (*literE)->SetFirst();
01269           while( (*literE)->IsValid() ){
01270             Int_t  iStripE = (*literE)->GetCurrentSEId().GetStrip();
01271             pCalculator->SetEast(*literE,iStripE);
01272             bool goodComb = true;
01273             if(useMask && fUVmask[iplane][iStripE]==false)goodComb = false; 
01274             if(goodComb){             
01275               (*literW)->SetFirst();
01276               while( (*literW)->IsValid() ){
01277                 Int_t  iStripW = (*literW)->GetCurrentSEId().GetStrip();
01278                 pCalculator->SetWest(*literW,iStripW);
01279                 // In here we can check for a possibility
01280                 if(iStripE==iStripW){
01281                   pCalculator->CalcEastWest();
01282                   if(fabs(pCalculator->SigmaDQ())<3.0){
01283                     Int_t isaim = pCalculator->StripAim();
01284                     fInMask[iplane]++;
01285                     fTimingMask[iplane][isaim] = true;
01286                     if(fDiagnosticPlots){
01287                       if(kView==PlaneView::kV)fUTime->Fill(iplane,isaim,1.);
01288                       if(kView==PlaneView::kU)fVTime->Fill(iplane,isaim,1.);
01289                     }
01290                   }
01291                 }
01292                 (*literW)->Next();
01293               }
01294             }
01295             (*literE)->Next();
01296           }
01297           literW++;
01298         }
01299         literE++;
01300       }
01301     }
01302   }
01303 
01304   if(fDiagnosticPlots)this->DrawDiagnosticPlots(-2);
01305 
01306   this->MakeMaskGroups();
01307 
01308   for(int iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
01309     if(fDeMuxedPlanesAltLists[iplane][ALG_EAST].size()>0||fDeMuxedPlanesAltLists[iplane][ALG_WEST].size()>0){
01310       bool found = false;
01311       if(iplane==0){
01312         int ip = 1;
01313         int ipp = 3; 
01314         found = found || MaskExtrapolateBack(iplane,ip,ipp);
01315       }else{
01316         // For planes with hits : check surrounding planes
01317         int im=iplane-1;
01318         int ip=iplane+1;
01319         found = found || MaskInterpolate(iplane,im,ip);
01320         if(!found){
01321           int imm = iplane-3;
01322           int ipp = iplane+3;
01323           if(imm>=0)found = found || MaskInterpolate(iplane,imm,ip);
01324           if(ipp<499)found = found || MaskInterpolate(iplane,im,ipp);
01325           if(!found){
01326             if(imm>=0)found = found || MaskExtrapolateForwards(iplane,imm,im);
01327             if(ipp<499)found = found || MaskExtrapolateBack(iplane,ip,ipp);
01328           }
01329         }
01330       }
01331       if(!found)for(int istrip=0;istrip<fNumberOfStrips;istrip++)this->SetMask(iplane,istrip);
01332     }
01333   }  
01334 
01335   if(fDiagnosticPlots)this->DrawDiagnosticPlots(-1);
01336   if(fDiagnosticPlots)this->DrawDiagnosticPlots(1);
01337 
01338   return;
01339   
01340 } 
01341 
01342 
01343 
01344 
01345 
01346 
01347 
01348 
01349 bool AlgAltDeMuxBase::MaskInterpolate(int i, int im, int ip)
01350 {
01351   bool found = false;
01352   if(fMaskGroup[im].size()>0&&fMaskGroup[ip].size()>0){
01353     found = true;
01354     int lm = i-im;
01355     int lp = ip-i;
01356     int lt = lp+lm;
01357     for(unsigned int jm = 0; jm < fMaskGroup[im].size();jm++){
01358       for(int km = fMaskGroup[im][jm].groupStart; km<= fMaskGroup[im][jm].groupEnd;km++)this->SetMask(i,km);
01359       for(unsigned int jp = 0; jp < fMaskGroup[ip].size();jp++){
01360         for(int kp = fMaskGroup[ip][jp].groupStart; kp<= fMaskGroup[ip][jp].groupEnd;kp++)this->SetMask(i,kp);
01361         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++){
01362           this->SetMask(i,k);
01363         }
01364       } 
01365     }  
01366   }
01367   return found;
01368 }
01369 
01370 
01371 bool AlgAltDeMuxBase::MaskExtrapolateBack(int i, int ip, int ipp)
01372 {
01373   bool found = false;
01374   if(fMaskGroup[ip].size()>0&&fMaskGroup[ipp].size()>0){
01375     found = true;
01376     int lp  = ip-i;
01377     int lpp = ipp-i;
01378     int lt  = lpp-lp;
01379     for(unsigned int jp = 0; jp < fMaskGroup[ip].size();jp++){
01380       for(int kp = fMaskGroup[ip][jp].groupStart; kp<= fMaskGroup[ip][jp].groupEnd;kp++)this->SetMask(i,kp);
01381       for(unsigned int jpp = 0; jpp < fMaskGroup[ipp].size();jpp++){
01382         int ilow = (lpp*fMaskGroup[ip][jp].groupStart-lp*fMaskGroup[ipp][jpp].groupEnd)/lt;
01383         if(ilow<0)ilow=0;
01384         int ihigh = (lpp*fMaskGroup[ip][jp].groupEnd-lp*fMaskGroup[ipp][jpp].groupStart)/lt;
01385         if(ihigh>=MAX_NUMBER_OF_PLANES)ihigh=MAX_NUMBER_OF_PLANES-1;
01386         for(int kp = ilow; kp<=ihigh ;kp++)this->SetMask(i,kp);
01387       } 
01388     }  
01389   }
01390   return found;
01391 }
01392 
01393 bool AlgAltDeMuxBase::MaskExtrapolateForwards(int i, int imm, int im)
01394 {
01395   bool found = false;
01396   if(fMaskGroup[im].size()>0&&fMaskGroup[imm].size()>0){
01397     found = true;
01398     int lm  = im-i;
01399     int lmm = imm-i;
01400     int lt  = lmm-lm;
01401     for(unsigned int jm = 0; jm < fMaskGroup[im].size();jm++){
01402       for(int km = fMaskGroup[im][jm].groupStart; km<= fMaskGroup[im][jm].groupEnd;km++)this->SetMask(i,km);
01403       for(unsigned int jmm = 0; jmm < fMaskGroup[imm].size();jmm++){
01404         int ilow = (lmm*fMaskGroup[im][jm].groupStart-lm*fMaskGroup[imm][jmm].groupEnd)/lt;
01405         int ihigh = (lmm*fMaskGroup[im][jm].groupEnd-lm*fMaskGroup[imm][jmm].groupStart)/lt;
01406         if(ilow<0)ilow=0;
01407         if(ihigh>192)ihigh=192;
01408         for(int km =ilow ; km<=ihigh ;km++)this->SetMask(i,km);
01409       } 
01410     }  
01411   }
01412   return found;
01413 }
01414 
01415 
01416 
01417 void AlgAltDeMuxBase::SetMask(int ip, int is)
01418 {
01419   
01420   fUVmask[ip][is] = true;
01421   Int_t iuv;
01422   
01423   if(fDiagnosticPlots){
01424     if(ip<249)iuv = (ip%2)+1;
01425     if(ip>249)iuv  = ((ip+1)%2)+1;
01426     if(iuv==1)fUMask->Fill(ip,is,1.0);
01427     if(iuv==2)fVMask->Fill(ip,is,1.0);
01428   }
01429   return;
01430 }
01431 
01432 
01433 
01434 void AlgAltDeMuxBase::ResetTimingMask()
01435 {
01436   
01437   for(int iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
01438     if(fPlanesAltLists[iplane][ALG_EAST].size()>0||fPlanesAltLists[iplane][ALG_WEST].size()>0){
01439       for(int istrip=0;istrip<MAX_NUMBER_OF_STRIPS;istrip++){
01440         fUVmask[iplane][istrip] = false;
01441       }
01442     }
01443   }
01444 
01445   if(fDiagnosticPlots){
01446     if ( fUMask ) { delete fUMask; fUMask=0; }
01447     if ( fVMask ) { delete fVMask; fVMask=0; }
01448     fUMask = new TH2F("UMask","U view mask",501,-0.5,500.5,193,0.,193.);
01449     fVMask = new TH2F("VMask","V view mask",501,-0.5,500.5,193,0.,193.);
01450     fUMask->SetStats(kFALSE);
01451     fVMask->SetStats(kFALSE);
01452   }
01453 
01454 }
01455 
01456 void AlgAltDeMuxBase::MakeMaskGroups()
01457 {
01458    
01459   ResetTimingMask();
01460   fTimingMaskWindow = static_cast<Int_t>(2.5*fSigmaStripFromTiming);
01461 
01462   for(int i=0;i<MAX_NUMBER_OF_PLANES;i++){
01463     if(fInMask[i]>0){
01464       DeMuxMaskGroup gm;
01465       bool inGroup = false;
01466       int groupS = -999;
01467       int groupE   = +999;
01468       for(int j=0;j<fNumberOfStrips;j++){
01469         if(inGroup){
01470           if(j>groupE+fTimingMaskWindow){
01471             inGroup = false;
01472             gm.groupStart = groupS;
01473             gm.groupEnd = groupE;
01474             fMaskGroup[i].push_back(gm);
01475           }
01476         }
01477         if(fTimingMask[i][j]){
01478           if(inGroup){
01479             groupE = j + fTimingMaskWindow;
01480             if(groupE>=fNumberOfStrips)groupE=fNumberOfStrips-1;
01481           }else{
01482             inGroup = true;
01483             groupS = j - fTimingMaskWindow;
01484             groupE = j + fTimingMaskWindow;
01485             if(groupS<0)groupS=0;
01486             if(groupE>=fNumberOfStrips)groupE=fNumberOfStrips-1;
01487           }
01488         }
01489       }
01490       if(inGroup){
01491         groupE = fNumberOfStrips-1;
01492         gm.groupStart = groupS;
01493         gm.groupEnd = groupE;
01494         fMaskGroup[i].push_back(gm);
01495       }
01496     }
01497   }
01498   return;
01499 }
01500 
01501 
01502 
01503 
01504 
01505 
01506 
01507 void AlgAltDeMuxBase::PrintMap(Int_t ne, Int_t nw){
01508   
01509 
01510   cout << "Print Map " << ne << " : " << nw << endl;
01511   for(Int_t ie=0;ie<=ne;ie++){
01512     for(Int_t iw=0;iw<=nw;iw++){
01513       cout << fAmap[ie][iw];
01514     }
01515     cout << endl;
01516   }
01517 
01518   return;
01519 } 
01520 
01521 void AlgAltDeMuxBase::ResetMap(Int_t ne, Int_t nw){
01522   
01523   for(Int_t ie=0;ie<=ne;ie++){
01524     for(Int_t iw=0;iw<=nw;iw++){
01525       fAmap[ie][iw] = false;
01526     }
01527   }
01528 
01529   return;
01530 } 
01531 
01532 bool AlgAltDeMuxBase::IsXTalk(PlexSEIdAltL* paltlist, bool useBest)
01533 { 
01534 
01535   Float_t crossTalk=0.0;
01536   Float_t diagCrossTalk=0.0;
01537   bool result = false;
01538 
01539   PlexPixelSpotId pixelID;
01540   if(!useBest)pixelID = (paltlist->GetCurrentItem()).GetPixelSpotId(); 
01541   if(useBest)pixelID = (paltlist->GetBestItem()).GetPixelSpotId(); 
01542   Int_t pixel  = pixelID.GetPixel();
01543   Int_t PMTmuxID = pixelID.GetTube();
01544   PMTmuxID      += 3*pixelID.GetInRack();
01545   PMTmuxID      += 24*pixelID.GetRackBay();
01546   Char_t level = pixelID.GetRackLevel(); 
01547   Char_t ew = pixelID.GetEastWest(); 
01548   if(level=='U')PMTmuxID += 450;
01549   if(ew =='E')PMTmuxID += 900;
01550 
01551   if(PMTmuxID>=MAX_NUMBER_OF_PMTS){
01552     MSG("AltDeMux", Msg::kError) << "AlgAltDeMuxBase::IsXTalk => PMT out of array bounds : " <<    PMTmuxID << " would give array overflow!" << endl;
01553     return false;
01554   }
01555 
01556   Float_t q  = paltlist->GetCurrentItem().GetPE();
01557   Float_t qc = paltlist->GetCurrentItem().GetSigCorr()/60.;
01558   
01559   if(qc/q<0.1 || qc/q > 10.0){
01560     //cout << " BUGGERED " << qc << ":" << q << endl;
01561     qc=q;
01562   }
01563 
01564 
01565   switch(pixel){
01566   case 0:
01567     crossTalk = fPMTmap[PMTmuxID][1] + 
01568       fPMTmap[PMTmuxID][4];
01569     diagCrossTalk = fPMTmap[PMTmuxID][5];
01570     break;
01571   case 1:
01572     crossTalk = fPMTmap[PMTmuxID][0] + 
01573       fPMTmap[PMTmuxID][2] +
01574       fPMTmap[PMTmuxID][5];
01575     diagCrossTalk = fPMTmap[PMTmuxID][4]+
01576       fPMTmap[PMTmuxID][6];
01577     break;
01578   case 2:
01579     crossTalk = fPMTmap[PMTmuxID][1] + 
01580       fPMTmap[PMTmuxID][3] +
01581       fPMTmap[PMTmuxID][6];
01582     diagCrossTalk = fPMTmap[PMTmuxID][5]+
01583       fPMTmap[PMTmuxID][7];
01584     break;
01585   case 3:
01586     crossTalk = fPMTmap[PMTmuxID][2] + 
01587       fPMTmap[PMTmuxID][7];
01588     diagCrossTalk = fPMTmap[PMTmuxID][6];
01589     break;
01590   case 4:
01591     crossTalk = fPMTmap[PMTmuxID][0] + 
01592       fPMTmap[PMTmuxID][5] +
01593       fPMTmap[PMTmuxID][8];
01594     diagCrossTalk = fPMTmap[PMTmuxID][1]+
01595       fPMTmap[PMTmuxID][9];
01596     break;
01597   case 5:
01598     crossTalk = fPMTmap[PMTmuxID][1] + 
01599       fPMTmap[PMTmuxID][4] +
01600       fPMTmap[PMTmuxID][6] +
01601       fPMTmap[PMTmuxID][9];
01602     diagCrossTalk = fPMTmap[PMTmuxID][0]+
01603       fPMTmap[PMTmuxID][2] +
01604       fPMTmap[PMTmuxID][8] +
01605       fPMTmap[PMTmuxID][10];
01606     break;
01607   case 6:
01608     crossTalk = fPMTmap[PMTmuxID][2] + 
01609       fPMTmap[PMTmuxID][5] +
01610       fPMTmap[PMTmuxID][7] +
01611       fPMTmap[PMTmuxID][10];
01612     diagCrossTalk = fPMTmap[PMTmuxID][1]+
01613       fPMTmap[PMTmuxID][3] +
01614       fPMTmap[PMTmuxID][9] +
01615       fPMTmap[PMTmuxID][11];
01616     break;
01617   case 7:
01618     crossTalk = fPMTmap[PMTmuxID][3] + 
01619       fPMTmap[PMTmuxID][6] +
01620       fPMTmap[PMTmuxID][11];
01621     diagCrossTalk = fPMTmap[PMTmuxID][2]+
01622       fPMTmap[PMTmuxID][10];
01623     break;
01624   case 8:
01625     crossTalk = fPMTmap[PMTmuxID][4] + 
01626       fPMTmap[PMTmuxID][9] +
01627       fPMTmap[PMTmuxID][12];
01628     diagCrossTalk = fPMTmap[PMTmuxID][5]+
01629       fPMTmap[PMTmuxID][13];
01630     break;
01631   case 9:
01632     crossTalk = fPMTmap[PMTmuxID][5] + 
01633       fPMTmap[PMTmuxID][8] +
01634       fPMTmap[PMTmuxID][10] +
01635       fPMTmap[PMTmuxID][13];
01636     diagCrossTalk = fPMTmap[PMTmuxID][4]+
01637       fPMTmap[PMTmuxID][6] +
01638       fPMTmap[PMTmuxID][12] +
01639       fPMTmap[PMTmuxID][14];
01640     break;
01641   case 10:
01642     crossTalk = fPMTmap[PMTmuxID][6] + 
01643       fPMTmap[PMTmuxID][9] +
01644       fPMTmap[PMTmuxID][11] +
01645       fPMTmap[PMTmuxID][14];
01646     diagCrossTalk = fPMTmap[PMTmuxID][5]+
01647       fPMTmap[PMTmuxID][7] +
01648       fPMTmap[PMTmuxID][13] +
01649       fPMTmap[PMTmuxID][15];
01650     break;
01651   case 11:
01652     crossTalk = fPMTmap[PMTmuxID][7] + 
01653       fPMTmap[PMTmuxID][10] +
01654       fPMTmap[PMTmuxID][15];
01655     diagCrossTalk = fPMTmap[PMTmuxID][6]+
01656       fPMTmap[PMTmuxID][14];
01657     break;
01658   case 12:
01659     crossTalk = fPMTmap[PMTmuxID][8] + 
01660       fPMTmap[PMTmuxID][13];
01661     diagCrossTalk = fPMTmap[PMTmuxID][9];
01662     break;
01663   case 13:
01664     crossTalk = fPMTmap[PMTmuxID][9] + 
01665       fPMTmap[PMTmuxID][12]+
01666       fPMTmap[PMTmuxID][14];
01667     diagCrossTalk = fPMTmap[PMTmuxID][8]+
01668       fPMTmap[PMTmuxID][10];
01669     break;
01670   case 14:
01671     crossTalk = fPMTmap[PMTmuxID][10] + 
01672       fPMTmap[PMTmuxID][13]+
01673       fPMTmap[PMTmuxID][15];
01674     diagCrossTalk = fPMTmap[PMTmuxID][9]+
01675       fPMTmap[PMTmuxID][11];
01676     break;
01677   case 15:
01678     crossTalk = fPMTmap[PMTmuxID][11]+ 
01679       fPMTmap[PMTmuxID][14];
01680     diagCrossTalk = fPMTmap[PMTmuxID][10];
01681     break;
01682   default:
01683     crossTalk = 0;
01684     diagCrossTalk = 0;
01685     break;
01686   }
01687 
01688   if(amShowing){
01689     int i = PMTmuxID;
01690     cout << " IsXTalk " << paltlist->GetPlane() << " : " << pixel << " q " << q << " qc " << qc << " t " << paltlist->GetCurrentItem().GetTime()*1.0E9-pCalculator->GetAbsTime() << endl;
01691     cout << "PLANE HITS " << fPlaneHit[paltlist->GetPlane()] << endl;
01692 
01693     cout  << fPMTmap[i][0]  << ":" << fPMTmap[i][1]  << 
01694       ":" << fPMTmap[i][2]  << ":" << fPMTmap[i][3]  << endl;
01695     cout  << fPMTmap[i][4]  << ":" << fPMTmap[i][5]  << 
01696       ":" << fPMTmap[i][6]  << ":" << fPMTmap[i][7]  << endl;
01697     cout  << fPMTmap[i][8]  << ":" << fPMTmap[i][9]  << 
01698       ":" << fPMTmap[i][10] << ":" << fPMTmap[i][11] << endl;
01699     cout  << fPMTmap[i][12] << ":" << fPMTmap[i][13] << 
01700       ":" << fPMTmap[i][14] << ":" << fPMTmap[i][15] << endl;
01701 
01702     cout << "----------------" << i << endl;
01703 
01704     cout  << fXTalkmap[i][0]  << ":" << fXTalkmap[i][1]  << 
01705       ":" << fXTalkmap[i][2]  << ":" << fXTalkmap[i][3]  << endl;
01706     cout  << fXTalkmap[i][4]  << ":" << fXTalkmap[i][5]  << 
01707       ":" << fXTalkmap[i][6]  << ":" << fXTalkmap[i][7]  << endl;
01708     cout  << fXTalkmap[i][8]  << ":" << fXTalkmap[i][9]  << 
01709       ":" << fXTalkmap[i][10] << ":" << fXTalkmap[i][11] << endl;
01710     cout  << fXTalkmap[i][12] << ":" << fXTalkmap[i][13] << 
01711       ":" << fXTalkmap[i][14] << ":" << fXTalkmap[i][15] << endl;
01712 
01713     cout << "----------------" << endl;
01714 
01715     cout << fVAmap[i][2] << endl;
01716     cout << fVAmap[i][3] << endl;
01717     cout << fVAmap[i][4] << endl;
01718     cout << fVAmap[i][5] << endl;
01719     cout << fVAmap[i][6] << endl;
01720     cout << fVAmap[i][7] << endl;
01721     cout << fVAmap[i][8] << endl;
01722     cout << fVAmap[i][9] << endl;
01723     cout << fVAmap[i][10] << endl;
01724     cout << fVAmap[i][11] << endl;
01725     cout << fVAmap[i][12] << endl;
01726     cout << fVAmap[i][13] << endl;
01727     cout << fVAmap[i][14] << endl;
01728     cout << fVAmap[i][15] << endl;
01729     cout << fVAmap[i][16] << endl;
01730     cout << fVAmap[i][17] << endl;
01731   }
01732 
01733   if(useBest)q=qc;
01734   Float_t XTalkFraction=1.0;
01735   crossTalk+= 0.5*diagCrossTalk;
01736   if(crossTalk>0)XTalkFraction = q/crossTalk;
01737   if(XTalkFraction<fXTalkFraction)result=true;
01738   if(q<1.5&&XTalkFraction<fXTalk1PEFraction)result=true;
01739   if(q<2.5&&XTalkFraction<fXTalk2PEFraction)result=true;
01740   if(q<5.0&&XTalkFraction<fXTalk5PEFraction)result=true;
01741 
01742   if(q<1.5 && q<0.05*fPMTtot[PMTmuxID])result=true;
01743   
01744   if(amShowing)cout << "NORMAL : " << q << ":" <<  XTalkFraction << ":" << result << endl;
01745 
01746   if(result){
01747     MSG("AltDeMux", Msg::kVerbose) << "AlgAltDeMuxBase::IsXTalk (tagged by Standard Algorithm) PMT " << PMTmuxID << " pixel : " << pixel << " charge : " << qc << endl;
01748     return result; 
01749   }
01750 
01751   if(fXTalkmap[PMTmuxID][pixel]>0.0001){
01752     XTalkFraction = q/fXTalkmap[PMTmuxID][pixel];
01753     if(q<1.0&&XTalkFraction<100.)result=true;
01754     if(q<2.0&&XTalkFraction<50.)result=true;
01755     if(q<3.0&&XTalkFraction<30.)result=true;
01756     if(q<5.0&&XTalkFraction<20.)result=true;
01757     if(amShowing)cout << "SPOT   : " << q << ":" <<  XTalkFraction << ":" << result << endl;
01758 
01759     if(result){
01760       MSG("AltDeMux", Msg::kVerbose) << "AlgAltDeMuxBase::IsXTalk (Tagged by Spot Algorithm) : PMT " << PMTmuxID << " pixel : " << pixel << " charge : " << qc << " pixel map " << fXTalkmap[PMTmuxID][pixel] << endl;
01761       return result; 
01762     }
01763   }
01764 
01765   Int_t vaChannel = _pixelToVaChannel[pixel];
01766 
01767   if((fVAmap[PMTmuxID][vaChannel+1]+fVAmap[PMTmuxID][vaChannel-1])>0){
01768     XTalkFraction = q/(fVAmap[PMTmuxID][vaChannel+1]+fVAmap[PMTmuxID][vaChannel-1]);
01769     if(q<1.5&&XTalkFraction<0.1)result=true;
01770     if(amShowing)cout << "VA     : " << q << ":" <<  XTalkFraction << ":" << result << endl;
01771 
01772     if(result){
01773       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;
01774       return result; 
01775     }
01776   }
01777 
01778   return result;
01779 } 
01780 
01781 
01782 
01783 
01784 
01785 
01786 
01787 
01788 Float_t AlgAltDeMuxBase::XTalkCharge(PlexSEIdAltL* paltlist, Int_t istrip)
01789 { 
01790 
01791   Float_t crossTalk=-999;
01792   
01793   paltlist->SetFirst();
01794   bool notFound = true;
01795   while(notFound&&paltlist->IsValid()){
01796     if(paltlist->GetCurrentSEId().GetStrip()==istrip)notFound=false;
01797     if(notFound)paltlist->Next();
01798   }
01799 
01800 
01801   PlexPixelSpotId pixelID = (paltlist->GetCurrentItem()).GetPixelSpotId(); 
01802   Int_t pixel  = pixelID.GetPixel();
01803   Int_t PMTmuxID = pixelID.GetTube();
01804   PMTmuxID      += 3*pixelID.GetInRack();
01805   PMTmuxID      += 24*pixelID.GetRackBay();
01806   Char_t level = pixelID.GetRackLevel(); 
01807   Char_t ew = pixelID.GetEastWest(); 
01808   if(level=='U')PMTmuxID += 450;
01809   if(ew =='E')PMTmuxID += 900;
01810   if(PMTmuxID>=MAX_NUMBER_OF_PMTS){
01811     MSG("AltDeMux", Msg::kError) << "AlgAltDeMuxBase::IsXTalk => PMT out of array bounds : " <<    PMTmuxID << " woul give array overflow!" << endl;
01812     return 0.0;
01813   }
01814   Float_t q  = paltlist->GetCurrentItem().GetPE();
01815   Float_t qc = paltlist->GetCurrentItem().GetSigCorr()/60.;
01816   if(qc/q<0.1 || qc/q > 10.0){
01817     qc=q;
01818   }
01819 
01820   switch(pixel){
01821   case 0:
01822     crossTalk = fPMTmap[PMTmuxID][1] + 
01823       fPMTmap[PMTmuxID][4];
01824     break;
01825   case 1:
01826     crossTalk = fPMTmap[PMTmuxID][0] + 
01827       fPMTmap[PMTmuxID][2] +
01828       fPMTmap[PMTmuxID][5];
01829       break;
01830   case 2:
01831     crossTalk = fPMTmap[PMTmuxID][1] + 
01832       fPMTmap[PMTmuxID][3] +
01833       fPMTmap[PMTmuxID][6];
01834     break;
01835   case 3:
01836     crossTalk = fPMTmap[PMTmuxID][2] + 
01837       fPMTmap[PMTmuxID][7];
01838     break;
01839   case 4:
01840     crossTalk = fPMTmap[PMTmuxID][0] + 
01841       fPMTmap[PMTmuxID][5] +
01842       fPMTmap[PMTmuxID][8];
01843     break;
01844   case 5:
01845     crossTalk = fPMTmap[PMTmuxID][1] + 
01846       fPMTmap[PMTmuxID][4] +
01847       fPMTmap[PMTmuxID][6] +
01848       fPMTmap[PMTmuxID][9];
01849     break;
01850   case 6:
01851     crossTalk = fPMTmap[PMTmuxID][2] + 
01852       fPMTmap[PMTmuxID][5] +
01853       fPMTmap[PMTmuxID][7] +
01854       fPMTmap[PMTmuxID][10];
01855     break;
01856   case 7:
01857     crossTalk = fPMTmap[PMTmuxID][3] + 
01858       fPMTmap[PMTmuxID][6] +
01859       fPMTmap[PMTmuxID][11];
01860     break;
01861   case 8:
01862     crossTalk = fPMTmap[PMTmuxID][4] + 
01863       fPMTmap[PMTmuxID][9] +
01864       fPMTmap[PMTmuxID][12];
01865     break;
01866   case 9:
01867     crossTalk = fPMTmap[PMTmuxID][5] + 
01868       fPMTmap[PMTmuxID][8] +
01869       fPMTmap[PMTmuxID][10] +
01870       fPMTmap[PMTmuxID][13];
01871     break;
01872   case 10:
01873     crossTalk = fPMTmap[PMTmuxID][6] + 
01874       fPMTmap[PMTmuxID][9] +
01875       fPMTmap[PMTmuxID][11] +
01876       fPMTmap[PMTmuxID][14];
01877     break;
01878   case 11:
01879     crossTalk = fPMTmap[PMTmuxID][7] + 
01880       fPMTmap[PMTmuxID][10] +
01881       fPMTmap[PMTmuxID][15];
01882     break;
01883   case 12:
01884     crossTalk = fPMTmap[PMTmuxID][8] + 
01885       fPMTmap[PMTmuxID][13];
01886     break;
01887   case 13:
01888     crossTalk = fPMTmap[PMTmuxID][9] + 
01889       fPMTmap[PMTmuxID][12]+
01890       fPMTmap[PMTmuxID][14];
01891     break;
01892   case 14:
01893     crossTalk = fPMTmap[PMTmuxID][10] + 
01894       fPMTmap[PMTmuxID][13]+
01895       fPMTmap[PMTmuxID][15];
01896     break;
01897   case 15:
01898     crossTalk = fPMTmap[PMTmuxID][11]+ 
01899       fPMTmap[PMTmuxID][14];
01900     break;
01901   default:
01902     crossTalk = 0;
01903     break;
01904   }
01905 
01906   return crossTalk;
01907 } 
01908 
01909 
01910 
01911 
01912 
01913 
01914 Float_t AlgAltDeMuxBase::XTalkPixelMap(PlexSEIdAltL* paltlist)
01915 { 
01916 
01917   Float_t crossTalk=-999;
01918   
01919   PlexPixelSpotId pixelID = (paltlist->GetBestItem()).GetPixelSpotId(); 
01920   Int_t pixel  = pixelID.GetPixel();
01921   Int_t PMTmuxID = pixelID.GetTube();
01922   PMTmuxID      += 3*pixelID.GetInRack();
01923   PMTmuxID      += 24*pixelID.GetRackBay();
01924   Char_t level = pixelID.GetRackLevel(); 
01925   Char_t ew = pixelID.GetEastWest(); 
01926   if(level=='U')PMTmuxID += 450;
01927   if(ew =='E')PMTmuxID += 900;
01928   if(PMTmuxID>=MAX_NUMBER_OF_PMTS){
01929     MSG("AltDeMux", Msg::kError) << "AlgAltDeMuxBase::IsXTalk => PMT out of array bounds : " <<    PMTmuxID << " woul give array overflow!" << endl;
01930     return 0.0;
01931   }
01932   Float_t q  = paltlist->GetBestItem().GetPE();
01933   Float_t qc = paltlist->GetBestItem().GetSigCorr()/60.;
01934   if(qc/q<0.1 || qc/q > 10.0){
01935     qc=q;
01936   }
01937 
01938   cout << " PMTmuxID PIXEL : " << PMTmuxID << "," << pixel << "  : " << qc << endl;
01939   Int_t i=PMTmuxID;
01940   cout  << fPMTmap[i][0]  << ":" << fPMTmap[i][1]  << 
01941     ":" << fPMTmap[i][2]  << ":" << fPMTmap[i][3]  << endl;
01942   cout  << fPMTmap[i][4]  << ":" << fPMTmap[i][5]  << 
01943     ":" << fPMTmap[i][6]  << ":" << fPMTmap[i][7]  << endl;
01944   cout  << fPMTmap[i][8]  << ":" << fPMTmap[i][9]  << 
01945     ":" << fPMTmap[i][10] << ":" << fPMTmap[i][11] << endl;
01946   cout  << fPMTmap[i][12] << ":" << fPMTmap[i][13] << 
01947     ":" << fPMTmap[i][14] << ":" << fPMTmap[i][15] << endl;
01948 
01949   cout  << fXTalkmap[i][0]  << ":" << fXTalkmap[i][1]  << 
01950     ":" << fXTalkmap[i][2]  << ":" << fXTalkmap[i][3]  << endl;
01951   cout  << fXTalkmap[i][4]  << ":" << fXTalkmap[i][5]  << 
01952     ":" << fXTalkmap[i][6]  << ":" << fXTalkmap[i][7]  << endl;
01953   cout  << fXTalkmap[i][8]  << ":" << fXTalkmap[i][9]  << 
01954     ":" << fXTalkmap[i][10] << ":" << fXTalkmap[i][11] << endl;
01955   cout  << fXTalkmap[i][12] << ":" << fXTalkmap[i][13] << 
01956     ":" << fXTalkmap[i][14] << ":" << fXTalkmap[i][15] << endl;
01957 
01958 
01959   
01960   switch(pixel){
01961   case 0:
01962     crossTalk = fPMTmap[PMTmuxID][1] + 
01963       fPMTmap[PMTmuxID][4];
01964     break;
01965   case 1:
01966     crossTalk = fPMTmap[PMTmuxID][0] + 
01967       fPMTmap[PMTmuxID][2] +
01968       fPMTmap[PMTmuxID][5];
01969       break;
01970   case 2:
01971     crossTalk = fPMTmap[PMTmuxID][1] + 
01972       fPMTmap[PMTmuxID][3] +
01973       fPMTmap[PMTmuxID][6];
01974     break;
01975   case 3:
01976     crossTalk = fPMTmap[PMTmuxID][2] + 
01977       fPMTmap[PMTmuxID][7];
01978     break;
01979   case 4:
01980     crossTalk = fPMTmap[PMTmuxID][0] + 
01981       fPMTmap[PMTmuxID][5] +
01982       fPMTmap[PMTmuxID][8];
01983     break;
01984   case 5:
01985     crossTalk = fPMTmap[PMTmuxID][1] + 
01986       fPMTmap[PMTmuxID][4] +
01987       fPMTmap[PMTmuxID][6] +
01988       fPMTmap[PMTmuxID][9];
01989     break;
01990   case 6:
01991     crossTalk = fPMTmap[PMTmuxID][2] + 
01992       fPMTmap[PMTmuxID][5] +
01993       fPMTmap[PMTmuxID][7] +
01994       fPMTmap[PMTmuxID][10];
01995     break;
01996   case 7:
01997     crossTalk = fPMTmap[PMTmuxID][3] + 
01998       fPMTmap[PMTmuxID][6] +
01999       fPMTmap[PMTmuxID][11];
02000     break;
02001   case 8:
02002     crossTalk = fPMTmap[PMTmuxID][4] + 
02003       fPMTmap[PMTmuxID][9] +
02004       fPMTmap[PMTmuxID][12];
02005     break;
02006   case 9:
02007     crossTalk = fPMTmap[PMTmuxID][5] + 
02008       fPMTmap[PMTmuxID][8] +
02009       fPMTmap[PMTmuxID][10] +
02010       fPMTmap[PMTmuxID][13];
02011     break;
02012   case 10:
02013     crossTalk = fPMTmap[PMTmuxID][6] + 
02014       fPMTmap[PMTmuxID][9] +
02015       fPMTmap[PMTmuxID][11] +
02016       fPMTmap[PMTmuxID][14];
02017     break;
02018   case 11:
02019     crossTalk = fPMTmap[PMTmuxID][7] + 
02020       fPMTmap[PMTmuxID][10] +
02021       fPMTmap[PMTmuxID][15];
02022     break;
02023   case 12:
02024     crossTalk = fPMTmap[PMTmuxID][8] + 
02025       fPMTmap[PMTmuxID][13];
02026     break;
02027   case 13:
02028     crossTalk = fPMTmap[PMTmuxID][9] + 
02029       fPMTmap[PMTmuxID][12]+
02030       fPMTmap[PMTmuxID][14];
02031     break;
02032   case 14:
02033     crossTalk = fPMTmap[PMTmuxID][10] + 
02034       fPMTmap[PMTmuxID][13]+
02035       fPMTmap[PMTmuxID][15];
02036     break;
02037   case 15:
02038     crossTalk = fPMTmap[PMTmuxID][11]+ 
02039       fPMTmap[PMTmuxID][14];
02040     break;
02041   default:
02042     crossTalk = 0;
02043     break;
02044   }
02045 
02046   return crossTalk;
02047 } 
02048 
02049 
02050 
02051 
02052 
02053 
02054 
02055 
02056 
02057 
02058 
02059 
02060 void  AlgAltDeMuxBase::DisplayPixelMap()
02061 {
02062 
02063   MSG("AltDeMux", Msg::kVerbose) << "AlgAltDeMuxBase::DisplayPixelMap : " << endl;
02064   for(int i=0; i<MAX_NUMBER_OF_PMTS; i++){
02065     if(fPMTtot[i]>0){
02066       MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBase::DisplayPixelMap PMT : " << i << endl;
02067       MSG("AltDeMux", Msg::kDebug) << fPMTmap[i][0]  << ":" << fPMTmap[i][1]  << 
02068         ":" << fPMTmap[i][2]  << ":" << fPMTmap[i][3]  << endl;
02069       MSG("AltDeMux", Msg::kDebug) << fPMTmap[i][4]  << ":" << fPMTmap[i][5]  << 
02070         ":" << fPMTmap[i][6]  << ":" << fPMTmap[i][7]  << endl;
02071       MSG("AltDeMux", Msg::kDebug) << fPMTmap[i][8]  << ":" << fPMTmap[i][9]  << 
02072         ":" << fPMTmap[i][10] << ":" << fPMTmap[i][11] << endl;
02073       MSG("AltDeMux", Msg::kDebug) << fPMTmap[i][12] << ":" << fPMTmap[i][13] << 
02074         ":" << fPMTmap[i][14] << ":" << fPMTmap[i][15] << endl;
02075 
02076     }
02077   }
02078   
02079   return;
02080 
02081 }
02082 
02083 
02084 
02085 void AlgAltDeMuxBase::DrawDiagnosticPlots(Int_t ipass) 
02086 {  
02087   if(!fDiagnosticPlots)return;
02088   TPolyMarker* pTPU1;
02089   TPolyMarker* pTPV1;
02090   TPolyMarker* pTPU2;
02091   TPolyMarker* pTPV2;
02092   TPolyMarker* pTPU3;
02093   TPolyMarker* pTPV3;
02094   TPolyMarker* pTPU4;
02095   TPolyMarker* pTPV4;
02096   TPolyMarker* pTPU5;
02097   TPolyMarker* pTPV5;
02098   float xU1[1000];
02099   float yU1[1000];
02100   float xU2[1000];
02101   float yU2[1000];
02102   float xU3[1000];
02103   float yU3[1000];
02104   float xU4[1000];
02105   float yU4[1000];
02106   float xU5[1000];
02107   float yU5[1000];
02108   int nU1=0;
02109   int nU2=0;
02110   int nU3=0;
02111   int nU4=0;
02112   int nU5=0;
02113   float xV1[1000];
02114   float yV1[1000];
02115   float xV2[1000];
02116   float yV2[1000];
02117   float xV3[1000];
02118   float yV3[1000];
02119   float xV4[1000];
02120   float yV4[1000];
02121   float xV5[1000];
02122   float yV5[1000];
02123   int nV1=0;
02124   int nV2=0;
02125   int nV3=0;
02126   int nV4=0;
02127   int nV5=0;
02128 
02129   Float_t markerSize = 1.0;
02130   if(fEventType==MULTIPLE_MUON)markerSize =0.75;
02131 
02132   for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
02133     for(Int_t i=0;i<NdemuxedHitsU[iplane];i++){
02134       for(Int_t j=i+1;j<NdemuxedHitsU[iplane];j++){
02135         if(demuxedHitStripU[iplane][i]==demuxedHitStripU[iplane][j]){
02136           demuxedHitQU[iplane][i] +=demuxedHitQU[iplane][j];
02137           demuxedHitQU[iplane][j] = 0;
02138         }
02139       }
02140     }
02141 
02142     for(Int_t i=0;i<NdemuxedHitsU[iplane];i++){
02143       if(demuxedHitQU[iplane][i]>0 && demuxedHitQU[iplane][i]<=3){
02144         xU1[nU1] = iplane;
02145         yU1[nU1] = demuxedHitStripU[iplane][i];
02146         nU1++;
02147       }
02148       if(demuxedHitQU[iplane][i]>=3 && demuxedHitQU[iplane][i]<=10){
02149         xU2[nU2] = iplane;
02150         yU2[nU2] = demuxedHitStripU[iplane][i];
02151         nU2++;
02152       }
02153       if(demuxedHitQU[iplane][i]>=10 && demuxedHitQU[iplane][i]<=25){
02154         xU3[nU3] = iplane;
02155         yU3[nU3] = demuxedHitStripU[iplane][i];
02156         nU3++;
02157       }
02158       if(demuxedHitQU[iplane][i]>=25 && demuxedHitQU[iplane][i]<=100){
02159         xU4[nU4] = iplane;
02160         yU4[nU4] = demuxedHitStripU[iplane][i];
02161         nU4++;
02162       }
02163       if(demuxedHitQU[iplane][i]>=100){
02164         xU5[nU5] = iplane;
02165         yU5[nU5] = demuxedHitStripU[iplane][i];
02166         nU5++;
02167       }
02168     }
02169   }
02170 
02171 
02172   for(Int_t iplane=0;iplane<MAX_NUMBER_OF_PLANES;iplane++){
02173     for(Int_t i=0;i<NdemuxedHitsV[iplane];i++){
02174       for(Int_t j=i+1;j<NdemuxedHitsV[iplane];j++){
02175         if(demuxedHitStripV[iplane][i]==demuxedHitStripV[iplane][j]){
02176           demuxedHitQV[iplane][i] +=demuxedHitQV[iplane][j];
02177           demuxedHitQV[iplane][j] = 0;
02178         }
02179       }
02180     }
02181     
02182     for(int i=0;i<NdemuxedHitsV[iplane];i++){
02183       if(demuxedHitQV[iplane][i]>=0 && demuxedHitQV[iplane][i]<=3){
02184         xV1[nV1] = iplane;
02185         yV1[nV1] = demuxedHitStripV[iplane][i];
02186         nV1++;
02187       }
02188       if(demuxedHitQV[iplane][i]>=3 && demuxedHitQV[iplane][i]<=10){
02189         xV2[nV2] = iplane;
02190         yV2[nV2] = demuxedHitStripV[iplane][i];
02191         nV2++;
02192       }
02193       if(demuxedHitQV[iplane][i]>=10 && demuxedHitQV[iplane][i]<=25){
02194         xV3[nV3] = iplane;
02195         yV3[nV3] = demuxedHitStripV[iplane][i];
02196         nV3++;
02197       }
02198       if(demuxedHitQV[iplane][i]>=25 && demuxedHitQV[iplane][i]<=100){
02199         xV4[nV4] = iplane;
02200         yV4[nV4] = demuxedHitStripV[iplane][i];
02201         nV4++;
02202       }
02203       if(demuxedHitQV[iplane][i]>=100){
02204         xV5[nV5] = iplane;
02205         yV5[nV5] = demuxedHitStripV[iplane][i];
02206         nV5++;
02207       }
02208     }
02209   }
02210 
02211   pTPU1 = new TPolyMarker(nU1,xU1,yU1);
02212   pTPU1->SetMarkerStyle(20);
02213   pTPU1->SetMarkerColor(kYellow);
02214   pTPU1->SetMarkerSize(markerSize);
02215 
02216   pTPU2 = new TPolyMarker(nU2,xU2,yU2);
02217   pTPU2->SetMarkerStyle(20);
02218   pTPU2->SetMarkerColor(kCyan);
02219   pTPU2->SetMarkerSize(markerSize);
02220 
02221   pTPU3 = new TPolyMarker(nU3,xU3,yU3);
02222   pTPU3->SetMarkerStyle(20);
02223   pTPU3->SetMarkerColor(kBlue);
02224   pTPU3->SetMarkerSize(markerSize);
02225 
02226   pTPU4 = new TPolyMarker(nU4,xU4,yU4);
02227   pTPU4->SetMarkerStyle(20);
02228   pTPU4->SetMarkerColor(kBlack);
02229   pTPU4->SetMarkerSize(markerSize);
02230 
02231   pTPU5 = new TPolyMarker(nU5,xU5,yU5);
02232   pTPU5->SetMarkerStyle(20);
02233   pTPU5->SetMarkerColor(kRed);
02234   pTPU5->SetMarkerSize(markerSize);
02235 
02236   pTPV1 = new TPolyMarker(nV1,xV1,yV1);
02237   pTPV1->SetMarkerStyle(20);
02238   pTPV1->SetMarkerColor(kYellow);
02239   pTPV1->SetMarkerSize(markerSize);
02240 
02241   pTPV2 = new TPolyMarker(nV2,xV2,yV2);
02242   pTPV2->SetMarkerStyle(20);
02243   pTPV2->SetMarkerColor(kCyan);
02244   pTPV2->SetMarkerSize(markerSize);
02245 
02246   pTPV3 = new TPolyMarker(nV3,xV3,yV3);
02247   pTPV3->SetMarkerStyle(20);
02248   pTPV3->SetMarkerColor(kBlue);
02249   pTPV3->SetMarkerSize(markerSize);
02250 
02251   pTPV4 = new TPolyMarker(nV4,xV4,yV4);
02252   pTPV4->SetMarkerStyle(20);
02253   pTPV4->SetMarkerColor(kBlack);
02254   pTPV4->SetMarkerSize(markerSize);
02255 
02256   pTPV5 = new TPolyMarker(nV5,xV5,yV5);
02257   pTPV5->SetMarkerStyle(20);
02258   pTPV5->SetMarkerColor(kRed);
02259   pTPV5->SetMarkerSize(markerSize);
02260 
02261   // Keep track of the TPolyMarkers - delete them later
02262 
02263   fList->Add(pTPV1);
02264   fList->Add(pTPV2);
02265   fList->Add(pTPV3);
02266   fList->Add(pTPV4);
02267   fList->Add(pTPV5);
02268   fList->Add(pTPU1);
02269   fList->Add(pTPU2);
02270   fList->Add(pTPU3);
02271   fList->Add(pTPU4);
02272   fList->Add(pTPU5);
02273 
02274   fUpad->cd();
02275 
02276   if(ipass==-2&&fUTime){
02277     fUTime->GetXaxis()->SetRangeUser(fLowestPlane,fHighestPlane); 
02278     fUTime->SetMaximum(0.1);
02279     fUTime->SetLineColor(kRed);
02280     fUTime->SetFillColor(kRed);
02281     fUTime->Draw("BOX");
02282   }
02283   if(ipass==-1&&fUMask){
02284     fUMask->GetXaxis()->SetRangeUser(fLowestPlane,fHighestPlane); 
02285     if(fUTime)fUMask->Add(fUTime,1.);
02286     fUMask->SetLineColor(kGreen);
02287     fUMask->SetFillColor(kGreen);
02288     fUMask->SetMaximum(1.);
02289     if(fUMask)fUMask->Draw("BOX");
02290   }
02291 
02292   if(ipass>=0){
02293     if (fUview){
02294       fUview->GetXaxis()->SetRangeUser(fLowestPlane,fHighestPlane);
02295       fUview->Draw(); 
02296     }
02297     if (fUTime){
02298       fUTime->SetMaximum(1.);
02299       fUTime->Draw();
02300     }
02301     if (fUMask){
02302       fUMask->GetXaxis()->SetRangeUser(fLowestPlane,fHighestPlane);
02303       fUMask->Add(fUTime,1.);
02304       fUMask->SetLineColor(kGreen); 
02305       fUMask->SetFillColor(kGreen);
02306       fUMask->SetMaximum(1.);
02307       fUMask->Draw("BOX");
02308     }
02309     pTPU1->Draw();
02310     pTPU2->Draw();
02311     pTPU3->Draw();
02312     pTPU4->Draw();
02313     pTPU5->Draw();
02314   }
02315 
02316   if(fUZFitS)fUZFitS->Draw();
02317   if(fUZFitT)fUZFitT->Draw();
02318   if(fUZFitSSM1)fUZFitSSM1->Draw();
02319   if(fUZFitQSSM2)fUZFitQSSM2->Draw();
02320   if(fUZFitQSSM1)fUZFitQSSM1->Draw();
02321   if(fUZFitSSM2)fUZFitSSM2->Draw();
02322   if(fUZFitTSM1)fUZFitTSM1->Draw();
02323   if(fUZFitTSM2)fUZFitTSM2->Draw();
02324   if(fEventType==MULTIPLE_MUON){
02325     DeMuxFitResult_t resultU;
02326     resultU.a0 = fHoughSlopeU;
02327     resultU.status = true;
02328     for(UInt_t i = 0; i< multipleMuonInterceptsU.size();i++){
02329       resultU.a1 = fHoughSlopeU;
02330       resultU.a0 = multipleMuonInterceptsU[i];
02331       TPolyLine* tP1 = NULL;
02332       TPolyLine* tP2 = NULL;
02333       this->MakeFitPolyLines(resultU, tP1, tP2, 1, 1);
02334       tP1->Draw();
02335       tP2->Draw();
02336     }
02337   }
02338 
02339 
02340   fVpad->cd();
02341 
02342   if(ipass==-2&&fVTime){
02343     fVTime->GetXaxis()->SetRangeUser(fLowestPlane,fHighestPlane); 
02344     fVTime->SetMaximum(0.1);
02345     fVTime->SetLineColor(kRed);
02346     fVTime->SetFillColor(kRed);
02347     if(fVTime)fVTime->Draw("BOX");
02348   }
02349   if(ipass==-1&&fVMask){
02350     fVMask->GetXaxis()->SetRangeUser(fLowestPlane,fHighestPlane); 
02351     if(fVTime)fVMask->Add(fVTime,1.);
02352     fVMask->SetLineColor(kGreen);
02353     fVMask->SetFillColor(kGreen);
02354     fVMask->SetMaximum(1.);
02355     fVMask->Draw("BOX");
02356   }
02357 
02358   if(ipass>=0){
02359     if (fVview){
02360       fVview->GetXaxis()->SetRangeUser(fLowestPlane,fHighestPlane);
02361       fVview->Draw();
02362     }
02363     if (fVTime){
02364       fVTime->SetMaximum(1.);
02365       fVTime->Draw();
02366     }
02367     if (fVMask){
02368       fVMask->GetXaxis()->SetRangeUser(fLowestPlane,fHighestPlane);
02369       fVMask->Add(fVTime,1.);
02370       fVMask->SetLineColor(kGreen);
02371       fVMask->SetFillColor(kGreen);
02372       fVMask->SetMaximum(1.);
02373       fVMask->Draw("BOX");
02374     }
02375     pTPV1->Draw();    
02376     pTPV2->Draw();
02377     pTPV3->Draw();
02378     pTPV4->Draw();
02379     pTPV5->Draw();
02380   }
02381 
02382   if(fVZFitT)fVZFitT->Draw();
02383   if(fVZFitS)fVZFitS->Draw();
02384   if(fVZFitSSM1)fVZFitSSM1->Draw();
02385   if(fVZFitSSM2)fVZFitSSM2->Draw();
02386   if(fVZFitQSSM1)fVZFitQSSM1->Draw();
02387   if(fVZFitQSSM2)fVZFitQSSM2->Draw();
02388   if(fVZFitTSM1)fVZFitTSM1->Draw();
02389   if(fVZFitTSM2)fVZFitTSM2->Draw();
02390 
02391   if(fEventType==MULTIPLE_MUON){
02392     DeMuxFitResult_t resultV;
02393     for(UInt_t i = 0; i< multipleMuonInterceptsV.size();i++){
02394       resultV.a1 = fHoughSlopeV;
02395       resultV.a0 = multipleMuonInterceptsV[i];
02396       resultV.status = true;
02397       TPolyLine* tP1 = NULL;
02398       TPolyLine* tP2 = NULL;
02399       this->MakeFitPolyLines(resultV, tP1, tP2, 1, 1);
02400       tP1->Draw();
02401       tP2->Draw();
02402     }
02403 
02404 
02405   }
02406 
02407 
02408   fCanvas->Update();
02409   return;
02410   
02411 }
02412 
02413 
02414 
02415 
02416 bool AlgAltDeMuxBase::ValidatePlane(Int_t iplane, bool useTimeMask){
02417 
02418   bool fitStatusT;
02419   bool fitStatusH;
02420 
02421 
02422   if(fPlaneHit[iplane]==0)return false;
02423 
02424   if(fEventType==MULTIPLE_MUON){
02425     MSG("AltDeMux", Msg::kWarning) << "AlgAltDeMuxBase::ValidatePlane doesn't yet handle Multiple Muons " << endl; 
02426     return false;
02427   }
02428 
02429   Int_t easthits = fDeMuxedPlanesAltLists[iplane][ALG_EAST].size()+
02430     fPlanesAltLists[iplane][ALG_EAST].size();
02431   Int_t westhits = fDeMuxedPlanesAltLists[iplane][ALG_WEST].size()+
02432     fPlanesAltLists[iplane][ALG_WEST].size();
02433 
02434   if(amWriting){
02435     if(amWriting)cout << "*****************************************************************  PLANE : " << iplane << endl;
02436     if(amWriting)cout << "ew : " << easthits << ":" << westhits << endl;
02437   }
02438 
02439   bool oneSided = false;
02440   if(easthits==0||westhits==0){
02441     if(easthits>0||westhits>0)oneSided = true;
02442   }
02443 
02444 
02445   Int_t istripH;
02446   Int_t istripT;
02447 
02448   Int_t jplane = iplane;
02449   if(jplane>249)jplane+=20;
02450   if( fUVMap[iplane]==PlaneView::kU){
02451     fitStatusH = fFitQHitU.status;
02452     istripH = static_cast<Int_t>(jplane*fFitQHitU.a1+fFitQHitU.a0);
02453     if(!fFitQHitU.status){
02454       istripH = static_cast<Int_t>(jplane*fFitHitU.a1+fFitHitU.a0);
02455       fitStatusH = fFitHitU.status;
02456     }
02457     fitStatusT = fFitTimeU.status;
02458     istripT = static_cast<Int_t>(jplane*fFitTimeU.a1+fFitTimeU.a0);
02459     if(amWriting){
02460       cout << " fit status : " << fitStatusH << " " << fitStatusT << endl;
02461       cout << "U HIT  STRIP AIM : " << istripH <<" "<< fFitQHitV.a0 << " : " << fFitQHitV.a1 << endl;
02462       cout << "U TIME STRIP AIM : " << istripT <<" "<< fFitTimeV.a0 << " : " << fFitTimeV.a1 << endl;
02463     }
02464   }
02465 
02466   if( fUVMap[iplane]==PlaneView::kV){
02467     fitStatusH = fFitQHitV.status;
02468     istripH = static_cast<Int_t>(jplane*fFitQHitV.a1+fFitQHitV.a0);
02469     if(!fitStatusH){
02470       fitStatusH = fFitHitV.status;
02471       istripH = static_cast<Int_t>(jplane*fFitHitV.a1+fFitHitV.a0);
02472     }
02473     fitStatusT = fFitTimeV.status;
02474     istripT = static_cast<Int_t>(jplane*fFitTimeV.a1+fFitTimeV.a0);
02475     if(amWriting){
02476       cout << "V HIT  STRIP AIM : " << istripH <<" "<< fFitQHitV.a0 << " : " << fFitQHitV.a1 << endl;
02477       cout << "V TIME STRIP AIM : " << istripT <<" "<< fFitTimeV.a0 << " : " << fFitTimeV.a1 << endl;
02478     }
02479   }
02480 
02481   if(istripH>=MAX_NUMBER_OF_STRIPS)istripH=MAX_NUMBER_OF_STRIPS; 
02482   if(istripT>=MAX_NUMBER_OF_STRIPS)istripT=MAX_NUMBER_OF_STRIPS; 
02483   if(istripH<0)istripH=0;
02484   if(istripT<0)istripT=0;
02485   
02486   bool returnFlag = false;
02487   bool found = false;
02488   bool useOldResult = false;
02489 
02490   PlaneValidity_t stripResult;
02491   PlaneValidity_t timeMaskResult;
02492   PlaneValidity_t oldResult;
02493   PlaneValidity_t hitResult;
02494   PlaneValidity_t timeResult;
02495 
02496   vector<Int_t>oldPattern;
02497   for(Int_t iHitStrip=1; iHitStrip<=fPlaneHit[iplane];iHitStrip++){
02498     oldPattern.push_back(fHitMap[iplane][iHitStrip]);
02499   }
02500   if(!oneSided)oldResult = this->ValidatePlaneForPattern(iplane, oldPattern);
02501   if( oneSided)oldResult = this->ValidateOneSidedPlaneForPattern(iplane, oldPattern);
02502 
02503   for(UInt_t i = 0; i<oldResult.strips.size(); i++){
02504     bool found = false;
02505     for(UInt_t ipair=0;ipair<fDeMuxedPairs[iplane].size();ipair++){
02506       Int_t istrip = fDeMuxedPairs[iplane][ipair].altListE->GetBestSEId().GetStrip();
02507       if(oldResult.strips[i]==istrip)found=true;
02508     }
02509     if(found==false){
02510       useOldResult=true;
02511       //cout << "USE OLD RESULT IS SET !!!!!!" << endl;
02512       //getchar();
02513     }
02514   }
02515 
02516 
02517   stripResult.largestContigGroup = -1;
02518   Int_t bestStrip;
02519   for(Int_t iHitStrip=1; iHitStrip<=fPlaneHit[iplane];iHitStrip++){
02520     vector<Int_t>pattern;
02521     pattern.push_back(fHitMap[iplane][iHitStrip]);
02522     PlaneValidity_t thisStripResult;
02523     if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
02524     if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
02525     if(thisStripResult.largestContigGroup>stripResult.largestContigGroup){
02526       stripResult = thisStripResult;
02527       bestStrip = fHitMap[iplane][iHitStrip];
02528     }
02529     if(thisStripResult.largestContigGroup==stripResult.largestContigGroup){
02530       if( fabs(thisStripResult.chi2DQ-stripResult.chi2DQ)>10){
02531         if(thisStripResult.chi2DQ+10.<stripResult.chi2DQ){
02532           stripResult = thisStripResult;
02533           bestStrip = fHitMap[iplane][iHitStrip];
02534         }
02535       }else{
02536         if(fitStatusH && fabs(thisStripResult.centroid-istripH)<fabs(stripResult.centroid-istripH)){
02537           stripResult = thisStripResult;
02538           bestStrip = fHitMap[iplane][iHitStrip];
02539         }
02540       }
02541     }
02542   }
02543 
02544   hitResult.largestContigGroup = 0;
02545   vector<Int_t>patternH;
02546   if(fitStatusH){
02547     patternH.push_back(istripH);
02548     if(!oneSided)hitResult =  this->ValidatePlaneForPattern(iplane, patternH);
02549     if( oneSided)hitResult =  this->ValidateOneSidedPlaneForPattern(iplane, patternH);
02550   }
02551 
02552 
02553   Int_t bestMaskStrip=-1;
02554   timeMaskResult.largestContigGroup = -1;
02555   if(useTimeMask){
02556     for(Int_t iStrip=0; iStrip<=MAX_NUMBER_OF_STRIPS;iStrip++){
02557       if(fUVmask[iplane][iStrip]==true){
02558         vector<Int_t>pattern;
02559         pattern.push_back(iStrip);
02560         PlaneValidity_t thisStripResult;
02561         if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
02562         if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
02563         if(thisStripResult.largestContigGroup>timeMaskResult.largestContigGroup){
02564           timeMaskResult = thisStripResult;
02565           bestMaskStrip = iStrip;
02566         }
02567         if(thisStripResult.largestContigGroup==timeMaskResult.largestContigGroup){
02568           if(oneSided){
02569             if(thisStripResult.stripSpan<=timeMaskResult.stripSpan){
02570               bestMaskStrip = iStrip;
02571               timeMaskResult = thisStripResult;
02572             }
02573           }else{
02574             if((timeMaskResult.fractionQE<0.25||timeMaskResult.fractionQW<0.25)||(thisStripResult.fractionQE>0.5&&thisStripResult.fractionQW>0.5)){
02575               if(thisStripResult.chi2DQ<timeMaskResult.chi2DQ+5.){
02576                 bestMaskStrip = iStrip;
02577                 timeMaskResult = thisStripResult;
02578               }
02579             }
02580           }
02581         }
02582         if(thisStripResult.largestContigGroup>=hitResult.largestContigGroup){
02583           if(amWriting)cout << "TIMING MASK : " << iStrip << endl;
02584           if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
02585           if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
02586         }
02587       }
02588     }
02589   }
02590       
02591 
02592 
02593   timeResult.largestContigGroup = 0;
02594   vector<Int_t>patternT;
02595   if(fitStatusT){
02596     patternT.push_back(istripT);
02597     if(!oneSided)timeResult =  this->ValidatePlaneForPattern(iplane, patternT);
02598     if( oneSided)timeResult =  this->ValidateOneSidedPlaneForPattern(iplane, patternT);
02599   }
02600 
02601   bool useTimeFit   = false;
02602   bool useHitFit    = false;
02603   bool useBestStrip = false;
02604   bool useTimeMaskHit  = false;
02605 
02606   if(useTimeMask&&!oneSided){
02607     if(timeMaskResult.fractionQE>0.25 && timeMaskResult.fractionQW>0.25)useTimeMaskHit = true;
02608     if(timeMaskResult.chi2DQ>oldResult.chi2DQ+20.)useTimeMaskHit = false;
02609   }
02610 
02611   if(fitStatusT){
02612     if(timeResult.largestContigGroup>oldResult.largestContigGroup){
02613       if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25||(timeResult.fractionQE>0.5&&timeResult.fractionQW>0.5))useTimeFit = true;
02614     } 
02615     if(timeResult.largestContigGroup==oldResult.largestContigGroup){
02616       if(timeResult.chi2DQ+10.<oldResult.chi2DQ){
02617         if(oldResult.fractionQE+oldResult.fractionQW<timeResult.fractionQE+timeResult.fractionQW>0.5)useTimeFit = true;
02618       }
02619     } 
02620     if(timeResult.fractionQE<0.25||timeResult.fractionQW<0.25)useTimeFit = false;
02621     if(timeResult.chi2DQ>oldResult.chi2DQ+20.)useTimeFit = false;
02622   }
02623 
02624   if(fitStatusH){
02625     if(hitResult.largestContigGroup>oldResult.largestContigGroup){
02626       if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25||(hitResult.fractionQE>0.5&&hitResult.fractionQW>0.5))useHitFit = true;
02627     } 
02628     if(hitResult.largestContigGroup>=oldResult.largestContigGroup){
02629       if(hitResult.fractionQE>0.75&&hitResult.fractionQW>0.75&&(hitResult.chi2DQ+20.0<oldResult.chi2DQ))useHitFit = true;
02630     }
02631 
02632 
02633 
02634     if(hitResult.fractionQE<0.25||hitResult.fractionQW<0.25)useHitFit = false;
02635     if(hitResult.chi2DQ>oldResult.chi2DQ+20.)useHitFit = false;
02636     if(hitResult.largestContigGroup>oldResult.largestContigGroup){
02637       if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25&&(hitResult.fractionQE>0.5&&hitResult.fractionQW>0.5))useHitFit = true;
02638     } 
02639   }
02640 
02641   if(stripResult.largestContigGroup>oldResult.largestContigGroup){
02642     if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25||(stripResult.fractionQE>0.5&&stripResult.fractionQW>0.5))useBestStrip = true;
02643     if(stripResult.chi2DQ>oldResult.chi2DQ+20.)useBestStrip = false;
02644   } 
02645 
02646   if(oneSided){
02647     if(fitStatusT)useTimeFit = true;
02648     if(fitStatusH)useHitFit = true;
02649     useBestStrip= true;
02650   }
02651  
02652 
02653   if(useHitFit){
02654     //amWriting = true;
02655     //    if(!found)this->ValidatePlaneForPattern(iplane, oldPattern);
02656     found = true;
02657     if(amWriting)cout  << " ALERT **HITS** " << endl; 
02658     //this->ValidatePlaneForPattern(iplane, patternH);
02659     found = true;
02660     if(hitResult.largestContigGroup>=timeResult.largestContigGroup&&
02661        hitResult.largestContigGroup>=stripResult.largestContigGroup){
02662       if(!oneSided)this->ReMuxPlane(iplane, patternH);
02663       if( oneSided)this->ReMuxSingleSidedPlane(iplane, patternH);
02664     }
02665   }
02666 
02667   if(useBestStrip){
02668     //amWriting = true;
02669     //if(!found)this->ValidatePlaneForPattern(iplane, oldPattern);
02670     found = true;
02671     if(amWriting)cout  << " ALERT **BEST** " << bestStrip << endl; 
02672     vector<Int_t>pattern;
02673     pattern.push_back(bestStrip);
02674     //this->ValidatePlaneForPattern(iplane, pattern);
02675     found = true;
02676     if(stripResult.largestContigGroup>=timeResult.largestContigGroup&&
02677        stripResult.largestContigGroup>hitResult.largestContigGroup){
02678       if(!oneSided)this->ReMuxPlane(iplane, pattern);
02679       if( oneSided)this->ReMuxSingleSidedPlane(iplane, pattern);
02680     }
02681   }
02682 
02683   if(useTimeFit){
02684     //amWriting = true;
02685     //if(!found)this->ValidatePlaneForPattern(iplane, oldPattern);
02686     found = true;
02687     if(amWriting)cout  << " ALERT **TIME** " << endl; 
02688     //this->ValidatePlaneForPattern(iplane, patternT);
02689     found = true;
02690     if(timeResult.largestContigGroup>hitResult.largestContigGroup&&
02691        timeResult.largestContigGroup>stripResult.largestContigGroup){
02692       if(!oneSided)this->ReMuxPlane(iplane, patternT);
02693       if( oneSided)this->ReMuxSingleSidedPlane(iplane, patternT);
02694     }
02695   }
02696 
02697 
02698 
02699   if(useTimeMaskHit){
02700     //amWriting = true;
02701     //if(!found)this->ValidatePlaneForPattern(iplane, oldPattern);
02702     if(amWriting)cout  << " ALERT ** TIME MASK !!!!!! ** " << bestMaskStrip << endl; 
02703     vector<Int_t>pattern;
02704     pattern.push_back(bestMaskStrip);
02705     found = true;
02706     if(amWriting)cout << "TM : " << timeMaskResult.largestContigGroup << "   H : " << hitResult.largestContigGroup << endl;
02707     if(timeMaskResult.largestContigGroup>hitResult.largestContigGroup){
02708       if(!oneSided)this->ReMuxPlane(iplane, pattern);
02709       if( oneSided){
02710         cout << "1 Sided Time Mask ReMux : " << timeMaskResult.largestContigGroup << endl;
02711         if(timeMaskResult.largestContigGroup>1){
02712           this->ReMuxSingleSidedPlane(iplane, pattern);
02713         }
02714       }
02715     }
02716     if(timeMaskResult.largestContigGroup==oldResult.largestContigGroup){
02717       if(!oneSided){
02718         if((timeMaskResult.fractionQE+timeMaskResult.fractionQW>
02719             oldResult.fractionQE+oldResult.fractionQW)  ||
02720            (timeMaskResult.chi2DQ+5.0<oldResult.chi2DQ))this->ReMuxPlane(iplane, pattern);
02721       }
02722       if(oneSided){
02723         if(timeMaskResult.largestContigGroup>1){
02724           this->ReMuxSingleSidedPlane(iplane, pattern);
02725             if(amWriting)cout << "One Sided Time Mask ReMux : " << timeMaskResult.largestContigGroup << endl;
02726         }
02727       }
02728     }
02729   }  
02730 
02731   returnFlag = found;
02732 
02733   return returnFlag;
02734 }
02735 
02736 
02737 
02738 
02739 
02740 
02741 
02742 
02743 
02744 
02745 bool AlgAltDeMuxBase::DumpValidateBeamPlane(Int_t iplane, bool useTimeMask){
02746 
02747   bool fitStatusT;
02748   bool fitStatusH;
02749 
02750 
02751   if(fPlaneHit[iplane]==0)return false;
02752 
02753   if(fEventType==MULTIPLE_MUON){
02754     MSG("AltDeMux", Msg::kWarning) << "AlgAltDeMuxBase::ValidateBeamPlane doesn't yet Multiple Muons " << endl; 
02755     return false;
02756   }
02757   amWriting = false;
02758 
02759 
02760   Int_t easthits = fDeMuxedPlanesAltLists[iplane][ALG_EAST].size()+
02761     fPlanesAltLists[iplane][ALG_EAST].size();
02762   Int_t westhits = fDeMuxedPlanesAltLists[iplane][ALG_WEST].size()+
02763     fPlanesAltLists[iplane][ALG_WEST].size();
02764 
02765   if(amWriting){
02766     if(amWriting)cout << "*****************************************************************  PLANE : " << iplane << endl;
02767     if(amWriting)cout << "ew : " << easthits << ":" << westhits << endl;
02768   }
02769 
02770   bool oneSided = false;
02771   if(easthits==0||westhits==0){
02772     if(easthits>0||westhits>0)oneSided = true;
02773   }
02774 
02775   Int_t istripH;
02776   Int_t istripT;
02777 
02778   Int_t jplane = iplane;
02779   if(jplane>249)jplane+=20;
02780   if( fUVMap[iplane]==PlaneView::kU){
02781     fitStatusH = fFitQHitU.status;
02782     istripH = static_cast<Int_t>(jplane*fFitQHitU.a1+fFitQHitU.a0);
02783     if(!fFitQHitU.status){
02784       istripH = static_cast<Int_t>(jplane*fFitHitU.a1+fFitHitU.a0);
02785       fitStatusH = fFitHitU.status;
02786     }
02787     fitStatusT = fFitTimeU.status;
02788     istripT = static_cast<Int_t>(jplane*fFitTimeU.a1+fFitTimeU.a0);
02789     if(amWriting){
02790       cout << " fit status : " << fitStatusH << " " << fitStatusT << endl;
02791       cout << "U HIT  STRIP AIM : " << istripH <<" "<< fFitQHitV.a0 << " : " << fFitQHitV.a1 << endl;
02792       cout << "U TIME STRIP AIM : " << istripT <<" "<< fFitTimeV.a0 << " : " << fFitTimeV.a1 << endl;
02793     }
02794   }
02795   if( fUVMap[iplane]==PlaneView::kV){
02796     fitStatusH = fFitQHitV.status;
02797     istripH = static_cast<Int_t>(jplane*fFitQHitV.a1+fFitQHitV.a0);
02798     if(!fitStatusH){
02799       fitStatusH = fFitHitV.status;
02800       istripH = static_cast<Int_t>(jplane*fFitHitV.a1+fFitHitV.a0);
02801     }
02802     fitStatusT = fFitTimeV.status;
02803     istripT = static_cast<Int_t>(jplane*fFitTimeV.a1+fFitTimeV.a0);
02804     if(amWriting){
02805       cout << "V HIT  STRIP AIM : " << istripH <<" "<< fFitQHitV.a0 << " : " << fFitQHitV.a1 << endl;
02806       cout << "V TIME STRIP AIM : " << istripT <<" "<< fFitTimeV.a0 << " : " << fFitTimeV.a1 << endl;
02807     }
02808   }
02809 
02810   if(istripH>=MAX_NUMBER_OF_STRIPS)istripH=MAX_NUMBER_OF_STRIPS; 
02811   if(istripT>=MAX_NUMBER_OF_STRIPS)istripT=MAX_NUMBER_OF_STRIPS; 
02812   if(istripH<0)istripH=0;
02813   if(istripT<0)istripT=0;
02814 
02815   
02816   bool returnFlag = false;
02817   bool found = false;
02818   bool useOldResult = false;
02819 
02820   PlaneValidity_t stripResult;
02821   PlaneValidity_t timeMaskResult;
02822   PlaneValidity_t oldResult;
02823   PlaneValidity_t hitResult;
02824   PlaneValidity_t timeResult;
02825 
02826 
02827   // Determine pattern for current result
02828   vector<Int_t>oldPattern;
02829   for(Int_t iHitStrip=1; iHitStrip<=fPlaneHit[iplane];iHitStrip++){
02830     oldPattern.push_back(fHitMap[iplane][iHitStrip]);
02831   }
02832   if(!oneSided)oldResult = this->ValidatePlaneForPattern(iplane, oldPattern);
02833   if( oneSided)oldResult = this->ValidateOneSidedPlaneForPattern(iplane, oldPattern);
02834 
02835   for(UInt_t i = 0; i<oldResult.strips.size(); i++){
02836     bool found = false;
02837     for(UInt_t ipair=0;ipair<fDeMuxedPairs[iplane].size();ipair++){
02838       Int_t istrip = fDeMuxedPairs[iplane][ipair].altListE->GetBestSEId().GetStrip();
02839       if(oldResult.strips[i]==istrip)found=true;
02840     }
02841     if(found==false){
02842       useOldResult=true;
02843       //cout << "USE OLD RESULT IS SET !!!!!!" << endl;
02844       //getchar();
02845     }
02846   }
02847 
02848 
02849 
02850   // Look at patterns centred on the hit strips
02851   stripResult.largestContigGroup = -1;
02852   Int_t bestStrip;
02853   for(Int_t iHitStrip=1; iHitStrip<=fPlaneHit[iplane];iHitStrip++){
02854     vector<Int_t>pattern;
02855     pattern.push_back(fHitMap[iplane][iHitStrip]);
02856     PlaneValidity_t thisStripResult;
02857     if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
02858     if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
02859     if(this->ValidityComp(stripResult,thisStripResult,istripH,istripT,oneSided)){
02860       stripResult = thisStripResult;
02861       bestStrip = fHitMap[iplane][iHitStrip];
02862     }
02863   }
02864 
02865 
02866   hitResult.largestContigGroup = 0;
02867   vector<Int_t>patternH;
02868   if(fitStatusH){
02869     patternH.push_back(istripH);
02870     if(!oneSided)hitResult =  this->ValidatePlaneForPattern(iplane, patternH);
02871     if( oneSided)hitResult =  this->ValidateOneSidedPlaneForPattern(iplane, patternH);
02872   }
02873 
02874 
02875   Int_t bestMaskStrip=-1;
02876   timeMaskResult.largestContigGroup = -1;
02877   if(useTimeMask){
02878     for(Int_t iStrip=0; iStrip<=MAX_NUMBER_OF_STRIPS;iStrip++){
02879       if(fUVmask[iplane][iStrip]==true){
02880         vector<Int_t>pattern;
02881         pattern.push_back(iStrip);
02882         PlaneValidity_t thisStripResult;
02883         if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
02884         if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
02885         if(this->ValidityComp(timeMaskResult,thisStripResult,istripH,istripT,oneSided)){
02886           timeMaskResult = thisStripResult;
02887           bestMaskStrip = iStrip;
02888         }else{
02889           if(oneSided && thisStripResult.largestContigGroup==timeMaskResult.largestContigGroup){
02890             if(thisStripResult.stripSpan<=timeMaskResult.stripSpan){
02891               bestMaskStrip = iStrip;
02892               timeMaskResult = thisStripResult;
02893             }
02894           }     
02895         }
02896       }
02897     }
02898   }
02899       
02900   timeResult.largestContigGroup = 0;
02901   vector<Int_t>patternT;
02902   if(fitStatusT){
02903     patternT.push_back(istripT);
02904     if(!oneSided)timeResult =  this->ValidatePlaneForPattern(iplane, patternT);
02905     if( oneSided)timeResult =  this->ValidateOneSidedPlaneForPattern(iplane, patternT);
02906   }
02907 
02908   bool useTimeFit   = false;
02909   bool useHitFit    = false;
02910   bool useBestStrip = false;
02911   bool useTimeMaskHit  = false;
02912 
02913   if(useTimeMask){
02914     if(oneSided){
02915     }else{
02916       if(timeMaskResult.fractionQE>0.25 && timeMaskResult.fractionQW>0.25)useTimeMaskHit = true;
02917       if(timeMaskResult.chi2DQ>oldResult.chi2DQ+20.)useTimeMaskHit = false;
02918     }
02919   }
02920 
02921   if(fitStatusT){
02922     if(timeResult.largestContigGroup>oldResult.largestContigGroup){
02923       if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25||(timeResult.fractionQE>0.5&&timeResult.fractionQW>0.5))useTimeFit = true;
02924     } 
02925     if(timeResult.fractionQE<0.25||timeResult.fractionQW<0.25)useTimeFit = false;
02926     if(timeResult.chi2DQ>oldResult.chi2DQ+20.)useTimeFit = false;
02927   }
02928 
02929   if(fitStatusH){
02930     if(hitResult.largestContigGroup>oldResult.largestContigGroup){
02931       if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25||(hitResult.fractionQE>0.5&&hitResult.fractionQW>0.5))useHitFit = true;
02932     } 
02933     if(hitResult.largestContigGroup>=oldResult.largestContigGroup){
02934       if(hitResult.fractionQE>0.75&&hitResult.fractionQW>0.75&&(hitResult.chi2DQ+20.0<oldResult.chi2DQ))useHitFit = true;
02935     }
02936 
02937     if(hitResult.fractionQE<0.25||hitResult.fractionQW<0.25)useHitFit = false;
02938     if(hitResult.chi2DQ>oldResult.chi2DQ+20.)useHitFit = false;
02939     if(hitResult.largestContigGroup>oldResult.largestContigGroup){
02940       if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25&&(hitResult.fractionQE>0.5&&hitResult.fractionQW>0.5))useHitFit = true;
02941     } 
02942   }
02943 
02944   if(stripResult.largestContigGroup>oldResult.largestContigGroup){
02945     if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25||(stripResult.fractionQE>0.5&&stripResult.fractionQW>0.5))useBestStrip = true;
02946     if(stripResult.chi2DQ>oldResult.chi2DQ+20.)useBestStrip = false;
02947   } 
02948 
02949   if(oneSided){
02950     if(fitStatusT)useTimeFit = true;
02951     if(fitStatusH)useHitFit = true;
02952     useBestStrip= true;
02953   }
02954  
02955 
02956   if(useHitFit){
02957     //amWriting = true;
02958     //    if(!found)this->ValidatePlaneForPattern(iplane, oldPattern);
02959     found = true;
02960     if(amWriting)cout  << " ALERT **HITS** " << endl; 
02961     //this->ValidatePlaneForPattern(iplane, patternH);
02962     found = true;
02963     if(hitResult.largestContigGroup>=timeResult.largestContigGroup&&
02964        hitResult.largestContigGroup>=stripResult.largestContigGroup){
02965       //if(!oneSided)this->ReMuxPlane(iplane, patternH);
02966       //if( oneSided)this->ReMuxSingleSidedPlane(iplane, patternH);
02967     }
02968   }
02969 
02970   if(useBestStrip){
02971     found = true;
02972     if(amWriting)cout  << " ALERT **BEST** " << bestStrip << endl; 
02973     vector<Int_t>pattern;
02974     pattern.push_back(bestStrip);
02975     //this->ValidatePlaneForPattern(iplane, pattern);
02976     found = true;
02977     if(stripResult.largestContigGroup>=timeResult.largestContigGroup&&
02978        stripResult.largestContigGroup>hitResult.largestContigGroup){
02979       //if(!oneSided)this->ReMuxPlane(iplane, pattern);
02980       //if( oneSided)this->ReMuxSingleSidedPlane(iplane, pattern);
02981     }
02982   }
02983 
02984   if(useTimeFit){
02985     found = true;
02986     if(amWriting)cout  << " ALERT **TIME** " << endl; 
02987     found = true;
02988     if(timeResult.largestContigGroup>hitResult.largestContigGroup&&
02989        timeResult.largestContigGroup>stripResult.largestContigGroup){
02990       //if(!oneSided)this->ReMuxPlane(iplane, patternT);
02991       //if( oneSided)this->ReMuxSingleSidedPlane(iplane, patternT);
02992     }
02993   }
02994 
02995 
02996 
02997   if(useTimeMaskHit){
02998     if(amWriting)cout  << " ALERT ** TIME MASK !!!!!! ** " << bestMaskStrip << endl; 
02999     vector<Int_t>pattern;
03000     pattern.push_back(bestMaskStrip);
03001     found = true;
03002     if(amWriting)cout << "TM : " << timeMaskResult.largestContigGroup << "   H : " << hitResult.largestContigGroup << endl;
03003     if(timeMaskResult.largestContigGroup>hitResult.largestContigGroup){
03004       if(!oneSided)this->ReMuxPlane(iplane, pattern);
03005       if( oneSided){
03006         cout << "1 Sided Time Mask ReMux : " << timeMaskResult.largestContigGroup << endl;
03007         if(timeMaskResult.largestContigGroup>1){
03008           //  this->ReMuxSingleSidedPlane(iplane, pattern);
03009         }
03010       }
03011     }
03012     if(timeMaskResult.largestContigGroup==oldResult.largestContigGroup){
03013       if(!oneSided){
03014         //      if((timeMaskResult.fractionQE+timeMaskResult.fractionQW>oldResult.fractionQE+oldResult.fractionQW)  ||(timeMaskResult.chi2DQ+5.0<oldResult.chi2DQ))this->ReMuxPlane(iplane, pattern);
03015       }
03016       if(oneSided){
03017         if(timeMaskResult.largestContigGroup>1){
03018           //this->ReMuxSingleSidedPlane(iplane, pattern);
03019             if(amWriting)cout << "One Sided Time Mask ReMux : " << timeMaskResult.largestContigGroup << endl;
03020         }
03021       }
03022     }
03023   }  
03024 
03025   returnFlag = found;
03026 
03027   amWriting = false;
03028   return returnFlag;
03029 }
03030 
03031 
03032 
03033 
03034 
03035 
03036 
03037 bool AlgAltDeMuxBase::ValidateBeamPlane(Int_t iplane, bool useTimeMask){
03038 
03039   bool fitStatusT;
03040   bool fitStatusH;
03041 
03042 
03043   if(fPlaneHit[iplane]==0)return false;
03044 
03045   if(fEventType==MULTIPLE_MUON){
03046     MSG("AltDeMux", Msg::kWarning) << "AlgAltDeMuxBase::ValidateBeamPlane doesn't yet Multiple Muons " << endl; 
03047     return false;
03048   }
03049   amWriting = false;
03050 
03051 
03052   Int_t easthits = fDeMuxedPlanesAltLists[iplane][ALG_EAST].size()+
03053     fPlanesAltLists[iplane][ALG_EAST].size();
03054   Int_t westhits = fDeMuxedPlanesAltLists[iplane][ALG_WEST].size()+
03055     fPlanesAltLists[iplane][ALG_WEST].size();
03056 
03057   if(amWriting){
03058     if(amWriting)cout << "*****************************************************************  PLANE : " << iplane << endl;
03059     if(amWriting)cout << "ew : " << easthits << ":" << westhits << endl;
03060   }
03061 
03062   bool oneSided = false;
03063   if(easthits==0||westhits==0){
03064     if(easthits>0||westhits>0)oneSided = true;
03065   }
03066 
03067 
03068   Int_t istripH;
03069   Int_t istripT;
03070 
03071   Int_t jplane = iplane;
03072   if(jplane>249)jplane+=20;
03073   if( fUVMap[iplane]==PlaneView::kU){
03074     fitStatusH = fFitQHitU.status;
03075     istripH = static_cast<Int_t>(jplane*fFitQHitU.a1+fFitQHitU.a0);
03076     if(!fFitQHitU.status){
03077       istripH = static_cast<Int_t>(jplane*fFitHitU.a1+fFitHitU.a0);
03078       fitStatusH = fFitHitU.status;
03079     }
03080     fitStatusT = fFitTimeU.status;
03081     istripT = static_cast<Int_t>(jplane*fFitTimeU.a1+fFitTimeU.a0);
03082     if(amWriting){
03083       cout << " fit status : " << fitStatusH << " " << fitStatusT << endl;
03084       cout << "U HIT  STRIP AIM : " << istripH <<" "<< fFitQHitV.a0 << " : " << fFitQHitV.a1 << endl;
03085       cout << "U TIME STRIP AIM : " << istripT <<" "<< fFitTimeV.a0 << " : " << fFitTimeV.a1 << endl;
03086     }
03087   }
03088   if( fUVMap[iplane]==PlaneView::kV){
03089     fitStatusH = fFitQHitV.status;
03090     istripH = static_cast<Int_t>(jplane*fFitQHitV.a1+fFitQHitV.a0);
03091     if(!fitStatusH){
03092       fitStatusH = fFitHitV.status;
03093       istripH = static_cast<Int_t>(jplane*fFitHitV.a1+fFitHitV.a0);
03094     }
03095     fitStatusT = fFitTimeV.status;
03096     istripT = static_cast<Int_t>(jplane*fFitTimeV.a1+fFitTimeV.a0);
03097     if(amWriting){
03098       cout << "V HIT  STRIP AIM : " << istripH <<" "<< fFitQHitV.a0 << " : " << fFitQHitV.a1 << endl;
03099       cout << "V TIME STRIP AIM : " << istripT <<" "<< fFitTimeV.a0 << " : " << fFitTimeV.a1 << endl;
03100     }
03101   }
03102 
03103   if(istripH>=MAX_NUMBER_OF_STRIPS)istripH=MAX_NUMBER_OF_STRIPS; 
03104   if(istripT>=MAX_NUMBER_OF_STRIPS)istripT=MAX_NUMBER_OF_STRIPS; 
03105   if(istripH<0)istripH=0;
03106   if(istripT<0)istripT=0;
03107 
03108   
03109   bool returnFlag = false;
03110   bool found = false;
03111   bool useOldResult = false;
03112 
03113   PlaneValidity_t stripResult;
03114   PlaneValidity_t timeMaskResult;
03115   PlaneValidity_t oldResult;
03116   PlaneValidity_t hitResult;
03117   PlaneValidity_t timeResult;
03118 
03119 
03120   vector<Int_t>oldPattern;
03121   for(Int_t iHitStrip=1; iHitStrip<=fPlaneHit[iplane];iHitStrip++){
03122     oldPattern.push_back(fHitMap[iplane][iHitStrip]);
03123   }
03124   if(!oneSided)oldResult = this->ValidatePlaneForPattern(iplane, oldPattern);
03125   if( oneSided)oldResult = this->ValidateOneSidedPlaneForPattern(iplane, oldPattern);
03126 
03127   for(UInt_t i = 0; i<oldResult.strips.size(); i++){
03128     bool found = false;
03129     for(UInt_t ipair=0;ipair<fDeMuxedPairs[iplane].size();ipair++){
03130       Int_t istrip = fDeMuxedPairs[iplane][ipair].altListE->GetBestSEId().GetStrip();
03131       if(oldResult.strips[i]==istrip)found=true;
03132     }
03133     if(found==false){
03134       useOldResult=true;
03135       //cout << "USE OLD RESULT IS SET !!!!!!" << endl;
03136       //getchar();
03137     }
03138   }
03139 
03140 
03141   stripResult.largestContigGroup = 0;
03142   Int_t bestStrip;
03143   for(Int_t iHitStrip=1; iHitStrip<=fPlaneHit[iplane];iHitStrip++){
03144     vector<Int_t>pattern;
03145     pattern.push_back(fHitMap[iplane][iHitStrip]);
03146     PlaneValidity_t thisStripResult;
03147     if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
03148     if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
03149     if(this->ValidityComp(oldResult,thisStripResult,istripH,istripT,oneSided)){
03150       stripResult = thisStripResult;
03151       bestStrip = fHitMap[iplane][iHitStrip];
03152     }
03153   }
03154 
03155   hitResult.largestContigGroup = 0;
03156   vector<Int_t>patternH;
03157   if(fitStatusH){
03158     patternH.push_back(istripH);
03159     if(!oneSided)hitResult =  this->ValidatePlaneForPattern(iplane, patternH);
03160     if( oneSided)hitResult =  this->ValidateOneSidedPlaneForPattern(iplane, patternH);
03161   }
03162 
03163 
03164   Int_t bestMaskStrip=-1;
03165   timeMaskResult.largestContigGroup = -1;
03166   if(useTimeMask){
03167     for(Int_t iStrip=0; iStrip<=MAX_NUMBER_OF_STRIPS;iStrip++){
03168       if(fUVmask[iplane][iStrip]==true){
03169         vector<Int_t>pattern;
03170         pattern.push_back(iStrip);
03171         PlaneValidity_t thisStripResult;
03172         if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
03173         if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
03174         if(this->ValidityComp(timeMaskResult,thisStripResult,istripH,istripT,oneSided)){
03175           timeMaskResult = thisStripResult;
03176           bestMaskStrip = iStrip;
03177         }else{
03178           if(oneSided && thisStripResult.largestContigGroup==timeMaskResult.largestContigGroup){
03179             if(thisStripResult.stripSpan<=timeMaskResult.stripSpan){
03180               bestMaskStrip = iStrip;
03181               timeMaskResult = thisStripResult;
03182             }
03183           }     
03184         }
03185       }
03186     }
03187   }
03188       
03189   timeResult.largestContigGroup = 0;
03190   vector<Int_t>patternT;
03191   if(fitStatusT){
03192     patternT.push_back(istripT);
03193     if(!oneSided)timeResult =  this->ValidatePlaneForPattern(iplane, patternT);
03194     if( oneSided)timeResult =  this->ValidateOneSidedPlaneForPattern(iplane, patternT);
03195   }
03196 
03197   bool useTimeFit   = false;
03198   bool useHitFit    = false;
03199   bool useBestStrip = false;
03200   bool useTimeMaskHit  = false;
03201 
03202   if(useTimeMask){
03203     if(oneSided){
03204     }else{
03205       if(timeMaskResult.fractionQE>0.25 && timeMaskResult.fractionQW>0.25)useTimeMaskHit = true;
03206       if(timeMaskResult.chi2DQ>oldResult.chi2DQ+20.)useTimeMaskHit = false;
03207     }
03208   }
03209 
03210   if(fitStatusT){
03211     if(timeResult.largestContigGroup>oldResult.largestContigGroup){
03212       if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25||(timeResult.fractionQE>0.5&&timeResult.fractionQW>0.5))useTimeFit = true;
03213     } 
03214     if(timeResult.fractionQE<0.25||timeResult.fractionQW<0.25)useTimeFit = false;
03215     if(timeResult.chi2DQ>oldResult.chi2DQ+20.)useTimeFit = false;
03216     if(timeResult.largestContigGroup==oldResult.largestContigGroup){
03217 
03218     }
03219   }
03220 
03221   if(fitStatusH){
03222     if(hitResult.largestContigGroup>oldResult.largestContigGroup){
03223       if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25||(hitResult.fractionQE>0.5&&hitResult.fractionQW>0.5))useHitFit = true;
03224     } 
03225     if(hitResult.largestContigGroup>=oldResult.largestContigGroup){
03226       if(hitResult.fractionQE>0.75&&hitResult.fractionQW>0.75&&(hitResult.chi2DQ+20.0<oldResult.chi2DQ))useHitFit = true;
03227     }
03228 
03229     if(hitResult.fractionQE<0.25||hitResult.fractionQW<0.25)useHitFit = false;
03230     if(hitResult.chi2DQ>oldResult.chi2DQ+20.)useHitFit = false;
03231     if(hitResult.largestContigGroup>oldResult.largestContigGroup){
03232       if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25&&(hitResult.fractionQE>0.5&&hitResult.fractionQW>0.5))useHitFit = true;
03233     } 
03234   }
03235 
03236   if(stripResult.largestContigGroup>oldResult.largestContigGroup){
03237     if(oldResult.fractionQE<0.25||oldResult.fractionQW<0.25||(stripResult.fractionQE>0.5&&stripResult.fractionQW>0.5))useBestStrip = true;
03238     if(stripResult.chi2DQ>oldResult.chi2DQ+20.)useBestStrip = false;
03239   } 
03240 
03241   if(oneSided){
03242     if(fitStatusT)useTimeFit = true;
03243     if(fitStatusH)useHitFit = true;
03244     useBestStrip= true;
03245   }
03246  
03247   // NOW HAVE ALL VALIDATE PATTERNS and BEST in each TYPE
03248   // Decide which to use
03249 
03250 
03251   if(useHitFit){
03252     //amWriting = true;
03253     //    if(!found)this->ValidatePlaneForPattern(iplane, oldPattern);
03254     found = true;
03255     if(amWriting)cout  << " ALERT **HITS** " << endl; 
03256     //this->ValidatePlaneForPattern(iplane, patternH);
03257     found = true;
03258     if(hitResult.largestContigGroup>=timeResult.largestContigGroup&&
03259        hitResult.largestContigGroup>=stripResult.largestContigGroup){
03260       if(!oneSided)this->ReMuxPlane(iplane, patternH);
03261       if( oneSided)this->ReMuxSingleSidedPlane(iplane, patternH);
03262     }
03263   }
03264 
03265   if(useBestStrip){
03266     //amWriting = true;
03267     //if(!found)this->ValidatePlaneForPattern(iplane, oldPattern);
03268     found = true;
03269     if(amWriting)cout  << " ALERT **BEST** " << bestStrip << endl; 
03270     vector<Int_t>pattern;
03271     pattern.push_back(bestStrip);
03272     //this->ValidatePlaneForPattern(iplane, pattern);
03273     found = true;
03274     if(stripResult.largestContigGroup>=timeResult.largestContigGroup&&
03275        stripResult.largestContigGroup>hitResult.largestContigGroup){
03276       if(!oneSided)this->ReMuxPlane(iplane, pattern);
03277       if( oneSided)this->ReMuxSingleSidedPlane(iplane, pattern);
03278     }
03279   }
03280 
03281   if(useTimeFit){
03282     //amWriting = true;
03283     //if(!found)this->ValidatePlaneForPattern(iplane, oldPattern);
03284     found = true;
03285     if(amWriting)cout  << " ALERT **TIME** " << endl; 
03286     //this->ValidatePlaneForPattern(iplane, patternT);
03287     found = true;
03288     if(timeResult.largestContigGroup>hitResult.largestContigGroup&&
03289        timeResult.largestContigGroup>stripResult.largestContigGroup){
03290       if(!oneSided)this->ReMuxPlane(iplane, patternT);
03291       if( oneSided)this->ReMuxSingleSidedPlane(iplane, patternT);
03292     }
03293   }
03294 
03295 
03296 
03297   if(useTimeMaskHit){
03298     //amWriting = true;
03299     //if(!found)this->ValidatePlaneForPattern(iplane, oldPattern);
03300     if(amWriting)cout  << " ALERT ** TIME MASK !!!!!! ** " << bestMaskStrip << endl; 
03301     vector<Int_t>pattern;
03302     pattern.push_back(bestMaskStrip);
03303     found = true;
03304     if(amWriting)cout << "TM : " << timeMaskResult.largestContigGroup << "   H : " << hitResult.largestContigGroup << endl;
03305     if(timeMaskResult.largestContigGroup>hitResult.largestContigGroup){
03306       if(!oneSided)this->ReMuxPlane(iplane, pattern);
03307       if( oneSided){
03308         cout << "1 Sided Time Mask ReMux : " << timeMaskResult.largestContigGroup << endl;
03309         if(timeMaskResult.largestContigGroup>1){
03310           this->ReMuxSingleSidedPlane(iplane, pattern);
03311         }
03312       }
03313     }
03314     if(timeMaskResult.largestContigGroup==oldResult.largestContigGroup){
03315       if(!oneSided){
03316         if((timeMaskResult.fractionQE+timeMaskResult.fractionQW>
03317             oldResult.fractionQE+oldResult.fractionQW)  ||
03318            (timeMaskResult.chi2DQ+5.0<oldResult.chi2DQ))this->ReMuxPlane(iplane, pattern);
03319       }
03320       if(oneSided){
03321         if(timeMaskResult.largestContigGroup>1){
03322           this->ReMuxSingleSidedPlane(iplane, pattern);
03323             if(amWriting)cout << "One Sided Time Mask ReMux : " << timeMaskResult.largestContigGroup << endl;
03324         }
03325       }
03326     }
03327   }  
03328 
03329   returnFlag = found;
03330 
03331   amWriting = false;
03332   return returnFlag;
03333 }
03334 
03335 
03336 
03337 
03338 bool AlgAltDeMuxBase::ValidityComp(PlaneValidity_t currentValidity, PlaneValidity_t newValidity, int istripH, int istripT, bool onesided){
03339 
03340   bool spoton=false;
03341   if(istripH==istripT)spoton=true;
03342   if(onesided)spoton=false;
03343 
03344   if(newValidity.largestContigGroup>currentValidity.largestContigGroup)return true;
03345 
03346   if(newValidity.largestContigGroup==currentValidity.largestContigGroup){
03347     if((currentValidity.fractionQE<0.25||currentValidity.fractionQW<0.25)&&(newValidity.fractionQE>0.5&&newValidity.fractionQW>0.5))return true;
03348     if(currentValidity.chi2DQ-newValidity.chi2DQ>10)return true;
03349     if(fFitQHitU.status){
03350       if(fabs(newValidity.centroid-istripH)<fabs(currentValidity.centroid-istripH))return true;
03351     }
03352   }  
03353   
03354   return false;
03355 }
03356 
03357 
03358 
03359 bool AlgAltDeMuxBase::BestGuessForPlane(Int_t iplane, bool doSingleSided){
03360 
03361   if(fPlaneHit[iplane]!=0)return false;
03362 
03363   Int_t easthits = fDeMuxedPlanesAltLists[iplane][ALG_EAST].size()+
03364     fPlanesAltLists[iplane][ALG_EAST].size();
03365   Int_t westhits = fDeMuxedPlanesAltLists[iplane][ALG_WEST].size()+
03366     fPlanesAltLists[iplane][ALG_WEST].size();
03367 
03368   if(fDiagnosticPlots){
03369     if(amWriting)cout << "*****************************************************************  PLANE : " << iplane << endl;
03370     if(amWriting)cout << "ew : " << easthits << ":" << westhits << endl;
03371   }
03372 
03373   bool oneSided = false;
03374   if(easthits==0||westhits==0){
03375     if(easthits>0||westhits>0)oneSided = true;
03376   }
03377 
03378   if(oneSided && !doSingleSided)return false;
03379 
03380   bool returnFlag = false;
03381   bool found = false;
03382 
03383   PlaneValidity_t timeMaskResult;
03384 
03385   Int_t bestMaskStrip=-1;
03386   timeMaskResult.largestContigGroup = -1;
03387 
03388   for(Int_t iStrip=0; iStrip<=MAX_NUMBER_OF_STRIPS;iStrip++){
03389     if(fUVmask[iplane][iStrip]==true){
03390       vector<Int_t>pattern;
03391       if(amWriting)cout << "TIMING MASK : " << iStrip << endl;
03392       pattern.push_back(iStrip);
03393       PlaneValidity_t thisStripResult;
03394       if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
03395       if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
03396       if(thisStripResult.largestContigGroup>timeMaskResult.largestContigGroup){
03397         timeMaskResult = thisStripResult;
03398         bestMaskStrip = iStrip;
03399       }
03400       if(thisStripResult.largestContigGroup==timeMaskResult.largestContigGroup){
03401         if(oneSided){
03402           if(thisStripResult.stripSpan<=timeMaskResult.stripSpan){
03403             bestMaskStrip = iStrip;
03404             timeMaskResult = thisStripResult;
03405           }
03406         }else{
03407           if( (thisStripResult.fractionQE+thisStripResult.fractionQW)>
03408               (timeMaskResult.fractionQE+timeMaskResult.fractionQW) ){
03409             if(thisStripResult.chi2DQ<timeMaskResult.chi2DQ+10.){
03410               bestMaskStrip = iStrip;
03411               timeMaskResult = thisStripResult;
03412             }
03413           }
03414         }
03415       }
03416     }
03417   }
03418 
03419 
03420   if(timeMaskResult.largestContigGroup>0){
03421     vector<Int_t>pattern;
03422     pattern.push_back(bestMaskStrip);
03423     if(!oneSided)this->ReMuxPlane(iplane, pattern);
03424     if( oneSided){
03425       if(timeMaskResult.largestContigGroup>1){
03426         this->ReMuxSingleSidedPlane(iplane, pattern);
03427       }
03428     }
03429     return true;
03430   }
03431   
03432       
03433   for(Int_t iStrip=0; iStrip<=MAX_NUMBER_OF_STRIPS;iStrip++){
03434     vector<Int_t>pattern;
03435     pattern.push_back(iStrip);
03436     PlaneValidity_t thisStripResult;
03437     if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
03438     if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
03439     if(thisStripResult.largestContigGroup>timeMaskResult.largestContigGroup){
03440       timeMaskResult = thisStripResult;
03441       bestMaskStrip = iStrip;
03442     }
03443     if(thisStripResult.largestContigGroup==timeMaskResult.largestContigGroup){
03444       if(oneSided){
03445         if(thisStripResult.stripSpan<=timeMaskResult.stripSpan){
03446           bestMaskStrip = iStrip;
03447           timeMaskResult = thisStripResult;
03448         }
03449       }else{
03450         if( (thisStripResult.fractionQE+thisStripResult.fractionQW)>
03451             (timeMaskResult.fractionQE+timeMaskResult.fractionQW) ){
03452           if(thisStripResult.chi2DQ<timeMaskResult.chi2DQ+10.){
03453             bestMaskStrip = iStrip;
03454             timeMaskResult = thisStripResult;
03455           }
03456         }
03457       }
03458     }
03459   }
03460       
03461   returnFlag = found;
03462 
03463   if(timeMaskResult.largestContigGroup>0){
03464     vector<Int_t>pattern;
03465     pattern.push_back(bestMaskStrip);
03466     if(!oneSided)this->ReMuxPlane(iplane, pattern);
03467     if( oneSided){
03468       if(timeMaskResult.largestContigGroup>1){
03469         this->ReMuxSingleSidedPlane(iplane, pattern);
03470       }
03471     }
03472   }
03473   
03474   return returnFlag;
03475 }
03476 
03477 
03478 
03479 
03480 
03481 
03482 bool AlgAltDeMuxBase::BestGuessForSingleSidedHits(Int_t iplane){
03483 
03484   vector <PlexSEIdAltL*>::iterator literA;
03485 
03486   //  if(fPlaneHit[iplane]!=0)return false;
03487   
03488   Int_t Nm =0;
03489   Int_t Np =0;
03490   Float_t wm = 0.0;
03491   Float_t wp = 0.0;
03492      
03493   for(Int_t iStrip=0; iStrip<=MAX_NUMBER_OF_STRIPS;iStrip++){
03494     if(iplane>1){
03495       if(fTimingMask[iplane-1][iStrip]){
03496         wm+= iStrip;
03497         Nm++;
03498       }
03499     }
03500     if(iplane<MAX_NUMBER_OF_PLANES-2){
03501       if(fTimingMask[iplane+1][iStrip]){
03502         wp+= iStrip;
03503         Np++;
03504       }
03505     }
03506   }
03507   
03508   Float_t target;
03509   if(Nm==0&&Np==0){
03510     for(Int_t jplane=iplane;jplane<500 && jplane<iplane+11;jplane+=2){
03511       Int_t easthits = fDeMuxedPlanesAltLists[jplane][ALG_EAST].size();
03512       Int_t westhits = fDeMuxedPlanesAltLists[jplane][ALG_WEST].size();
03513       for(Int_t iE=0;iE<easthits;iE++){
03514         wp += fDeMuxedPlanesAltLists[jplane][ALG_EAST][iE]->GetBestSEId().GetStrip();
03515         Np++;
03516       }
03517       for(Int_t iW=0;iW<westhits;iW++){
03518         wp += fDeMuxedPlanesAltLists[jplane][ALG_WEST][iW]->GetBestSEId().GetStrip();
03519         Np++;
03520       }
03521     }
03522 
03523     for(Int_t jplane=iplane-2;jplane>0 && jplane >iplane-11;jplane-=2){
03524       Int_t easthits = fDeMuxedPlanesAltLists[jplane][ALG_EAST].size();
03525       Int_t westhits = fDeMuxedPlanesAltLists[jplane][ALG_WEST].size();
03526       for(Int_t iE=0;iE<easthits;iE++){
03527         wm += fDeMuxedPlanesAltLists[jplane][ALG_EAST][iE]->GetBestSEId().GetStrip();
03528         Nm++;
03529       }
03530       for(Int_t iW=0;iW<westhits;iW++){
03531         wm += fDeMuxedPlanesAltLists[jplane][ALG_WEST][iW]->GetBestSEId().GetStrip();
03532         Nm++;
03533       }
03534     }
03535 
03536 
03537   }
03538   if(Nm==0&&Np==0)return false;
03539 
03540   if(Nm==0&&Np>0)target =  wp/static_cast<Float_t>(Np);
03541   if(Np==0&&Nm>0)target =  wm/static_cast<Float_t>(Nm);
03542   if(Np>0&&Nm>0)target =  (wm/static_cast<Float_t>(Nm) + wp/static_cast<Float_t>(Np))/2.0;
03543 
03544   for(Int_t iew=ALG_EAST;iew<=ALG_WEST;iew++){
03545     if(fPlanesAltLists[iplane][iew].size()>0){
03546       while (fPlanesAltLists[iplane][iew].size()>0){
03547         Int_t sbest =0;
03548         Float_t closeness = 999;
03549         literA = fPlanesAltLists[iplane][iew].begin();
03550         (*literA)->SetFirst();
03551         while( (*literA)->IsValid() ){
03552           Int_t s = (*literA)->GetCurrentSEId().GetStrip();
03553           if(fabs(target-s)<closeness){
03554             closeness = fabs(target-s);
03555             sbest = s;
03556           }                     
03557           (*literA)->Next();
03558         }
03559         if(closeness<999){
03560           if(iew==ALG_EAST)this->DeMuxSingleHitE(iplane,*literA, sbest);
03561           if(iew==ALG_WEST)this->DeMuxSingleHitW(iplane,*literA, sbest);
03562         }
03563       }
03564     }
03565   }
03566   
03567   return true;
03568 }
03569 
03570 
03571 
03572 
03573 
03574 
03575 
03576 bool AlgAltDeMuxBase::ValidateContainedCandidateEndPlane(Int_t iplane){
03577   if(fPlaneHit[iplane]==0)return false;
03578   bool useTimeMask = true;
03579   Int_t iLowHit = 999;
03580 
03581   if(fEventType==MULTIPLE_MUON){
03582     MSG("AltDeMux", Msg::kWarning) << "AlgAltDeMuxBase::ValidateContainedCandidateEndPlane does nothandle Multiple Muons" << endl; 
03583     return false;
03584   }
03585 
03586   Int_t easthits = fDeMuxedPlanesAltLists[iplane][ALG_EAST].size()+
03587     fPlanesAltLists[iplane][ALG_EAST].size();
03588   Int_t westhits = fDeMuxedPlanesAltLists[iplane][ALG_WEST].size()+
03589     fPlanesAltLists[iplane][ALG_WEST].size();
03590 
03591   if(fDiagnosticPlots){
03592     if(amWriting)cout << "*****************************************************************  PLANE : " << iplane << endl;
03593     if(amWriting)cout << "ew : " << easthits << ":" << westhits << endl;
03594   }
03595 
03596   bool oneSided = false;
03597   if(easthits==0||westhits==0){
03598     if(easthits>0||westhits>0)oneSided = true;
03599   }
03600 
03601   PlaneValidity_t timeMaskResult;
03602   PlaneValidity_t oldResult;
03603 
03604   vector<Int_t>oldPattern;
03605   for(Int_t iHitStrip=1; iHitStrip<=fPlaneHit[iplane];iHitStrip++){
03606     if(fHitMap[iplane][iHitStrip]<iLowHit)iLowHit = fHitMap[iplane][iHitStrip]; 
03607     oldPattern.push_back(fHitMap[iplane][iHitStrip]);
03608   }
03609   if(!oneSided)oldResult = this->ValidatePlaneForPattern(iplane, oldPattern);
03610   if( oneSided)oldResult = this->ValidateOneSidedPlaneForPattern(iplane, oldPattern);
03611 
03612   Int_t bestMaskStrip=-1;
03613   timeMaskResult.largestContigGroup = -1;
03614   if(useTimeMask){
03615     for(Int_t iStrip=iLowHit; iStrip<=MAX_NUMBER_OF_STRIPS;iStrip++){
03616       if(fUVmask[iplane][iStrip]==true){
03617         vector<Int_t>pattern;
03618         pattern.push_back(iStrip);
03619         PlaneValidity_t thisStripResult;
03620         if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
03621         if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
03622         if(thisStripResult.largestContigGroup>timeMaskResult.largestContigGroup){
03623           timeMaskResult = thisStripResult;
03624           bestMaskStrip = iStrip;
03625         }
03626         if(thisStripResult.largestContigGroup==timeMaskResult.largestContigGroup){
03627           if(oneSided){
03628             if(thisStripResult.stripSpan<=timeMaskResult.stripSpan){
03629               bestMaskStrip = iStrip;
03630               timeMaskResult = thisStripResult;
03631             }
03632           }else{
03633             if((timeMaskResult.fractionQE<0.25||timeMaskResult.fractionQW<0.25)&&(thisStripResult.fractionQE>0.5&&thisStripResult.fractionQW>0.5)){
03634               if(thisStripResult.chi2DQ<timeMaskResult.chi2DQ+10.){
03635                 bestMaskStrip = iStrip;
03636                 timeMaskResult = thisStripResult;
03637               }
03638             }
03639             if((timeMaskResult.fractionQE<0.25||timeMaskResult.fractionQW<0.25)&&(thisStripResult.fractionQE>0.5||thisStripResult.fractionQW>0.5)){
03640               if(thisStripResult.chi2DQ<timeMaskResult.chi2DQ+5.){
03641                 bestMaskStrip = iStrip;
03642                 timeMaskResult = thisStripResult;
03643               }
03644             }
03645 
03646           }
03647         }
03648         if(thisStripResult.largestContigGroup>=oldResult.largestContigGroup){
03649           if(amWriting)cout << "TIMING MASK : " << iStrip << endl;
03650           if(!oneSided)thisStripResult = this->ValidatePlaneForPattern(iplane, pattern);
03651           if( oneSided)thisStripResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
03652         }
03653       }
03654     }
03655   }
03656       
03657   bool useTimeMaskHit  = false;
03658 
03659   if(useTimeMask){
03660     if(oneSided){
03661     }else{
03662       if(timeMaskResult.fractionQE>0.25 && timeMaskResult.fractionQW>0.25)useTimeMaskHit = true;
03663     }
03664   }
03665 
03666   bool found;
03667 
03668   if(useTimeMaskHit){
03669     //amWriting = true;
03670     //if(!found)this->ValidatePlaneForPattern(iplane, oldPattern);
03671     if(amWriting)cout  << " ALERT ** TIME MASK !!!!!! ** " << bestMaskStrip << endl; 
03672     vector<Int_t>pattern;
03673     pattern.push_back(bestMaskStrip);
03674     found = true;
03675     if(amWriting)cout << "TM : " << timeMaskResult.largestContigGroup << "   H : " << oldResult.largestContigGroup << endl;
03676     if(timeMaskResult.largestContigGroup>oldResult.largestContigGroup){
03677       if(!oneSided)this->ReMuxPlane(iplane, pattern);
03678       if( oneSided){
03679         cout << "1 Sided Time Mask ReMux : " << timeMaskResult.largestContigGroup << endl;
03680         if(timeMaskResult.largestContigGroup>1){
03681           this->ReMuxSingleSidedPlane(iplane, pattern);
03682         }
03683       }
03684     }
03685     if(timeMaskResult.largestContigGroup==oldResult.largestContigGroup){
03686       if(!oneSided){
03687         if((timeMaskResult.fractionQE+timeMaskResult.fractionQW>
03688             oldResult.fractionQE+oldResult.fractionQW)  ||
03689            (timeMaskResult.chi2DQ+5.0<oldResult.chi2DQ))this->ReMuxPlane(iplane, pattern);
03690       }
03691       if(oneSided){
03692         if(timeMaskResult.largestContigGroup>1){
03693           this->ReMuxSingleSidedPlane(iplane, pattern);
03694           if(amWriting)cout << "One Sided Time Mask ReMux : " << timeMaskResult.largestContigGroup << endl;
03695         }
03696       }
03697     }
03698   }  
03699 
03700   bool returnFlag = found;
03701 
03702   return returnFlag;
03703 }
03704 
03705 
03706 
03707 
03708 bool AlgAltDeMuxBase::ValidatePlaneAgainstTarget(Int_t iplane, Int_t targetStrip){
03709 
03710 
03711   vector <PlexSEIdAltL*>::iterator literA;
03712 
03713   bool returnFlag = false;
03714   
03715   if(fPlaneHit[iplane]==0)return false;
03716 
03717   if(fEventType==MULTIPLE_MUON){
03718     MSG("AltDeMux", Msg::kWarning) << "AlgAltDeMuxBase::ValidateContainedCandidateEndPlane does nothandle Multiple Muons" << endl; 
03719     return false;
03720   }
03721 
03722   Int_t easthits = fDeMuxedPlanesAltLists[iplane][ALG_EAST].size()+
03723     fPlanesAltLists[iplane][ALG_EAST].size();
03724   Int_t westhits = fDeMuxedPlanesAltLists[iplane][ALG_WEST].size()+
03725     fPlanesAltLists[iplane][ALG_WEST].size();
03726 
03727   bool oneSided = false;
03728   if(easthits==0||westhits==0){
03729     if(easthits>0||westhits>0)oneSided = true;
03730   }
03731 
03732   if(oneSided)return false;
03733 
03734   PlaneValidity_t oldResult;
03735   vector<Int_t>oldPattern;
03736   for(Int_t iHitStrip=1; iHitStrip<=fPlaneHit[iplane];iHitStrip++){
03737     oldPattern.push_back(fHitMap[iplane][iHitStrip]);
03738   }
03739 
03740   PlaneValidity_t targetResult;
03741   vector<Int_t>pattern;
03742   pattern.push_back(targetStrip);
03743   PlaneValidity_t thisStripResult;
03744 
03745   if(!oneSided){
03746     oldResult = this->ValidatePlaneForPattern(iplane, oldPattern);
03747     targetResult = this->ValidatePlaneForPattern(iplane, pattern);
03748   }else{
03749     oldResult = this->ValidateOneSidedPlaneForPattern(iplane, oldPattern);
03750     targetResult = this->ValidateOneSidedPlaneForPattern(iplane, pattern);
03751   }
03752 
03753 
03754   bool remux = false;
03755   if(targetResult.largestContigGroup>oldResult.largestContigGroup){
03756     if(targetResult.chi2DQ<oldResult.chi2DQ+10)remux=true;
03757     if(targetResult.chi2DQ<oldResult.chi2DQ+20&&targetResult.fractionQE>oldResult.fractionQE&&targetResult.fractionQW>oldResult.fractionQW )remux=true;
03758   }
03759 
03760   if(targetResult.largestContigGroup==oldResult.largestContigGroup){
03761     int excold = 0;
03762     int excnew = 0;
03763     int oldnew = 0;
03764     for(unsigned int i=0;i<targetResult.strips.size();i++){
03765       bool found=false;
03766       for(unsigned int j=0;j<oldResult.strips.size();j++){
03767         if(targetResult.strips[i]==oldResult.strips[j])found= true;
03768       }
03769       if(found)oldnew++;
03770       if(!found)excnew++;
03771     }
03772     for(unsigned int i=0;i<oldResult.strips.size();i++){
03773       bool found=false;
03774       for(unsigned int j=0;j<targetResult.strips.size();j++){
03775         if(oldResult.strips[i]==targetResult.strips[j])found= true;
03776       }
03777       if(!found)excold++;
03778     }
03779 
03780     if(excold>0||excnew>0){
03781       if(excnew>0&&excold==0)remux=true;
03782       if(excnew>0&&excold>0){
03783         float points = 0;
03784         points+= (targetResult.fractionQE-oldResult.fractionQE)/0.1;
03785         points+= (targetResult.fractionQW-oldResult.fractionQW)/0.1;
03786         points-= (targetResult.stripSpan-oldResult.stripSpan)/5.;
03787         points-= (targetResult.chi2DQ-oldResult.chi2DQ)/5.;
03788         if(points>2)remux=true;
03789       }
03790     }
03791   }
03792 
03793   if(remux){
03794     this->ReMuxPlane(iplane, pattern);
03795     for(Int_t iew=ALG_EAST;iew<=ALG_WEST;iew++){
03796       while (fPlanesAltLists[iplane][iew].size()>0){
03797         int sbest =0;
03798         int closeness = 999;
03799         literA = fPlanesAltLists[iplane][iew].begin();
03800         (*literA)->SetFirst();
03801         while( (*literA)->IsValid() ){
03802           int s = (*literA)->GetCurrentSEId().GetStrip();
03803           for(unsigned int t=0;t<pattern.size();t++){
03804             if(abs(pattern[t]-s)<closeness){
03805               closeness = abs(pattern[t]-s);
03806               sbest = s;                        
03807             }
03808           }
03809           (*literA)->Next();
03810         }
03811         if(closeness<999){
03812           if(iew==ALG_EAST)this->DeMuxSingleHitE(iplane,*literA, sbest);
03813           if(iew==ALG_WEST)this->DeMuxSingleHitW(iplane,*literA, sbest);
03814         }
03815       }
03816     }
03817   }
03818 
03819   if(remux)returnFlag=true;
03820 
03821   return returnFlag;
03822 }
03823 
03824 
03825 
03826 bool AlgAltDeMuxBase::ValidateContainedCandidateEndPlanes(){
03827 
03828   bool changed = false;
03829 
03830   Int_t doWhat[MAX_NUMBER_OF_PLANES];
03831   const Int_t DO_NOTHING=0;
03832   const Int_t DO_LOOK_ABOVE=1;
03833   //  const Int_t DO_LOOK_BELOW=2;
03834 
03835   for(Int_t i=0; i<MAX_NUMBER_OF_PLANES;i++){
03836     doWhat[i]=DO_NOTHING;
03837   } 
03838   
03839 
03840   if(amWriting){
03841     cout << " Low/High " << fLowestPlane << ":" << fHighestPlane << endl;
03842     cout << " HighCC   " << fCCHighestPlane << endl;
03843     cout << " NearCC   " << fCCNearestPlane << endl;
03844   }
03845 
03846   Int_t eventLowPlane  = fCCHighestPlane;
03847   Int_t eventHighPlane = fCCHighestPlane;
03848   Int_t nGap = 0;
03849   bool  done = false;
03850   for(Int_t iplane=fCCHighestPlane; !done && iplane<MAX_NUMBER_OF_PLANES; iplane++){
03851     if(fPlaneHit[iplane]>0){
03852       eventHighPlane = iplane;
03853       nGap = 0;
03854     }
03855     if(fPlaneHit[iplane]==0)nGap++;
03856     if(nGap>=3)done=true;
03857   }
03858   nGap = 0;
03859   done = false;
03860   for(Int_t iplane=fCCHighestPlane; !done && iplane>=0; iplane--){
03861     if(fPlaneHit[iplane]>0){
03862       eventLowPlane = iplane;
03863       nGap = 0;
03864     }
03865     if(fPlaneHit[iplane]==0)nGap++;
03866     if(nGap>=3)done=true;
03867   }
03868 
03869   if(amWriting){
03870     cout << " HighEvent " << eventHighPlane << endl;
03871     cout << " LowEvent  " << eventLowPlane << endl;
03872   }
03873 
03874   bool foundU = false;
03875   bool foundV = false;
03876   if( abs(eventHighPlane-fCCHighestPlane)<abs(eventLowPlane-fCCHighestPlane)){
03877     for(Int_t iplane=fCCHighestPlane+5; iplane>=fCCHighestPlane-5;iplane--){
03878       if(fUVMap[iplane]==PlaneView::kU){
03879         if(!foundU && (fPlaneHit[iplane]>0) ){
03880           doWhat[iplane] = DO_LOOK_ABOVE;
03881           if(fDeMuxedPairs[iplane].size()>0)foundU=true;
03882           if(amWriting)cout << "Need to check U plane : " << iplane << endl;
03883         } 
03884       }
03885       if(fUVMap[iplane]==PlaneView::kV){
03886         if(!foundV && (fPlaneHit[iplane]>0)){
03887           doWhat[iplane] = DO_LOOK_ABOVE;
03888           if(fDeMuxedPairs[iplane].size()>0)foundV=true;
03889           if(amWriting)cout << "Need to check V plane : " << iplane << endl;
03890         } 
03891       }
03892     }
03893   }else{
03894     for(Int_t iplane=fCCHighestPlane-5; iplane<=fCCHighestPlane+5;iplane++){
03895       if(fUVMap[iplane]==PlaneView::kU){
03896         if(!foundU && (fPlaneHit[iplane]>0) ){
03897           doWhat[iplane] = DO_LOOK_ABOVE;
03898           if(fDeMuxedPairs[iplane].size()>0)foundU=true;
03899           if(amWriting)cout << "Need to check U plane : " << iplane << endl;
03900         } 
03901       }
03902       if(fUVMap[iplane]==PlaneView::kV){
03903         if(!foundV && (fPlaneHit[iplane]>0)){
03904           doWhat[iplane] = DO_LOOK_ABOVE;
03905           if(fDeMuxedPairs[iplane].size()>0)foundV=true;
03906           if(amWriting)cout << "Need to check V plane : " << iplane << endl;
03907         } 
03908       }
03909     }
03910   }
03911 
03912   changed = false;
03913   for(Int_t i=0; i<MAX_NUMBER_OF_PLANES;i++){
03914     if(doWhat[i]!=DO_NOTHING){
03915       //      cout << " Validating Plane : " << i << endl;
03916       bool thisPlaneChanged = ValidateContainedCandidateEndPlane(i);
03917       changed = changed || thisPlaneChanged;
03918     }
03919   }
03920 
03921   return changed;
03922 }
03923 
03924 
03925 void AlgAltDeMuxBase::MakeMultipleTargets(Int_t iplane){
03926 
03927   fTargetStrips.erase(fTargetStrips.begin(),fTargetStrips.end());
03928 
03929   Int_t jplane = iplane;
03930   if(iplane>248)jplane+=20;
03931   if(fUVMap[iplane]==PlaneView::kU){
03932     for(UInt_t iline=0; iline<multipleMuonInterceptsU.size();iline++){
03933       Float_t rtarget = fHoughSlopeU*jplane + multipleMuonInterceptsU[iline];
03934       Int_t itarget = static_cast<Int_t>(rtarget);
03935       if(itarget<198&&itarget>-10){
03936         if(itarget>190)itarget=191;
03937         if(itarget<0)itarget=0;
03938         fTargetStrips.push_back(itarget);
03939       }
03940     }
03941   }
03942   if(fUVMap[iplane]==PlaneView::kV){
03943     for(UInt_t iline=0; iline<multipleMuonInterceptsV.size();iline++){
03944       Float_t rtarget = fHoughSlopeV*jplane + multipleMuonInterceptsV[iline];
03945       Int_t itarget = static_cast<Int_t>(rtarget);
03946       if(itarget<198&&itarget>-10){
03947         if(itarget>190)itarget=191;
03948         if(itarget<0)itarget=0;
03949         fTargetStrips.push_back(itarget);
03950       }
03951     }
03952   }
03953 
03954   return;
03955 }
03956 
03957 
03958 
03959 
03960 bool AlgAltDeMuxBase::ValidateCCEndPlanes(){
03961 
03962 
03963   //amWriting=true;
03964   bool changed = false;
03965 
03966   Int_t doWhat[MAX_NUMBER_OF_PLANES];
03967   const Int_t DO_NOTHING=0;
03968   const Int_t DO_LOOK_ABOVE=1;
03969   //  const Int_t DO_LOOK_BELOW=2;
03970 
03971   for(Int_t i=0; i<MAX_NUMBER_OF_PLANES;i++){
03972     doWhat[i]=DO_NOTHING;
03973   } 
03974   
03975 
03976   if(amWriting){
03977     cout << " Low/High " << fLowestPlane << ":" << fHighestPlane << endl;
03978     cout << " HighCC   " << fCCHighestPlane << endl;
03979     cout << " NearCC   " << fCCNearestPlane << endl;
03980   }
03981 
03982   Int_t eventLowPlane  = fCCHighestPlane;
03983   Int_t eventHighPlane = fCCHighestPlane;
03984   Int_t nGap = 0;
03985   bool  done = false;
03986   for(Int_t iplane=fCCHighestPlane; !done && iplane<MAX_NUMBER_OF_PLANES; iplane++){
03987     if(fPlaneHit[iplane]>0){
03988       eventHighPlane = iplane;
03989       nGap = 0;
03990     }
03991     if(fPlaneHit[iplane]==0)nGap++;
03992     if(nGap>=3)done=true;
03993   }
03994   nGap = 0;
03995   done = false;
03996   for(Int_t iplane=fCCHighestPlane; !done && iplane>=0; iplane--){
03997     if(fPlaneHit[iplane]>0){
03998       eventLowPlane = iplane;
03999       nGap = 0;
04000     }
04001     if(fPlaneHit[iplane]==0)nGap++;
04002     if(nGap>=3)done=true;
04003   }
04004 
04005   if(amWriting){
04006     cout << " HighEvent " << eventHighPlane << endl;
04007     cout << " LowEvent  " << eventLowPlane << endl;
04008   }
04009 
04010   bool foundU = false;
04011   bool foundV = false;
04012   if( abs(eventHighPlane-fCCHighestPlane)<abs(eventLowPlane-fCCHighestPlane)){
04013     for(Int_t iplane=fCCHighestPlane+5; iplane>=fCCHighestPlane-5;iplane--){
04014       if(fUVMap[iplane]==PlaneView::kU){
04015         if(!foundU && (fPlaneHit[iplane]>0) ){
04016           doWhat[iplane] = DO_LOOK_ABOVE;
04017           doWhat[iplane-2] = DO_LOOK_ABOVE;
04018           if(fDeMuxedPairs[iplane].size()>0)foundU=true;
04019           if(amWriting)cout << "Need to check U plane : " << iplane << endl;
04020         } 
04021       }
04022       if(fUVMap[iplane]==PlaneView::kV){
04023         if(!foundV && (fPlaneHit[iplane]>0)){
04024           doWhat[iplane] = DO_LOOK_ABOVE;
04025           doWhat[iplane-2] = DO_LOOK_ABOVE;
04026           if(fDeMuxedPairs[iplane].size()>0)foundV=true;
04027           if(amWriting)cout << "Need to check V plane : " << iplane << endl;
04028         } 
04029       }
04030     }
04031   }else{
04032     for(Int_t iplane=fCCHighestPlane-5; iplane<=fCCHighestPlane+5;iplane++){
04033       if(fUVMap[iplane]==PlaneView::kU){
04034         if(!foundU && (fPlaneHit[iplane]>0) ){
04035           doWhat[iplane] = DO_LOOK_ABOVE;
04036           doWhat[iplane+2] = DO_LOOK_ABOVE;
04037           if(fDeMuxedPairs[iplane].size()>0)foundU=true;
04038           if(amWriting)cout << "Need to check U plane : " << iplane << endl;
04039         } 
04040       }
04041       if(fUVMap[iplane]==PlaneView::kV){
04042         if(!foundV && (fPlaneHit[iplane]>0)){
04043           doWhat[iplane] = DO_LOOK_ABOVE;
04044           doWhat[iplane+2] = DO_LOOK_ABOVE;
04045           if(fDeMuxedPairs[iplane].size()>0)foundV=true;
04046           if(amWriting)cout << "Need to check V plane : " << iplane << endl;
04047         } 
04048       }
04049     }
04050   }
04051 
04052   changed = false;
04053   for(Int_t i=0; i<MAX_NUMBER_OF_PLANES;i++){
04054     if(doWhat[i]!=DO_NOTHING){
04055       if(fFitTimeU.status){
04056         int istripT;
04057         int istripH;
04058         int istrip;
04059         int j = i;
04060         if(j>249)j=i+20;
04061         if(fUVMap[i]==PlaneView::kU){
04062           istripT = static_cast<Int_t>(j*fFitTimeU.a1+fFitTimeU.a0);
04063           istripH = static_cast<Int_t>(j*fFitHitU.a1+fFitHitU.a0);
04064         }else{
04065           istripT = static_cast<Int_t>(j*fFitTimeV.a1+fFitTimeV.a0);
04066           istripH = static_cast<Int_t>(j*fFitHitV.a1+fFitHitV.a0);
04067         }
04068         istrip = max(istripT,istripH);
04069         if(istrip>192&&istrip<212)istrip=192;
04070         if(amWriting)cout << " FINAL Validating Plane : " << i << " vs " << istrip << endl;
04071         bool remux = ValidatePlaneAgainstTarget(i,istrip);
04072         if(remux&&amWriting)cout << " REMUXED !!!!!!!!!!!!! " << endl;
04073       }
04074     }
04075   }
04076 
04077   //amWriting=false;
04078   return changed;
04079 }
04080 
04081 
04082 
04083 
04084 PlaneValidity_t AlgAltDeMuxBase::ValidatePlaneForPattern(Int_t iplane, vector<Int_t> stripPattern)
04085 { 
04086   vector <PlexSEIdAltL*>::iterator literE;
04087   vector <PlexSEIdAltL*>::iterator literW;
04088   PlexSEIdAltL* stripE[MAX_NUMBER_OF_STRIPS];
04089   PlexSEIdAltL* stripW[MAX_NUMBER_OF_STRIPS];
04090 
04091   Float_t Q;
04092   PlaneValidity_t returnValidity;
04093   returnValidity.strips.erase(returnValidity.strips.begin(),returnValidity.strips.end());
04094 
04095   pCalculator->SetPlane(iplane);
04096 
04097   Float_t QTotE = 0;
04098   Float_t QTotW = 0;
04099   if(fDiagnosticPlots){
04100     if(amWriting)cout << "******HITSTIP ";
04101     for(UInt_t i=0;i<stripPattern.size();i++){
04102       if(amWriting)cout << ":" << stripPattern[i];
04103     }
04104     if(amWriting)cout << endl;
04105   }
04106   for(Int_t i=0; i<MAX_NUMBER_OF_STRIPS; i++){
04107     stripE[i] = NULL;
04108     stripW[i] = NULL;
04109   }
04110   literE = fDeMuxedPlanesAltLists[iplane][ALG_EAST].begin();
04111   while (literE != fDeMuxedPlanesAltLists[iplane][ALG_EAST].end()){
04112     Int_t delta = 999;
04113     Int_t ibest = 999;
04114     (*literE)->SetFirst();
04115     while( (*literE)->IsValid() ){
04116       Int_t iStripE = (*literE)->GetCurrentSEId().GetStrip();
04117       for(UInt_t i = 0; i<stripPattern.size(); i++){
04118         Int_t d =abs(iStripE-stripPattern[i]);
04119         if(d<delta){
04120           delta = d;
04121           ibest = iStripE;
04122           Q = pCalculator->CurrentQ(*literE);
04123         }
04124       }
04125       (*literE)->Next();
04126     }
04127     stripE[ibest] =  *literE;
04128     literE++;
04129     QTotE+= Q;
04130   }
04131   
04132   literE = fPlanesAltLists[iplane][ALG_EAST].begin();
04133   while (literE != fPlanesAltLists[iplane][ALG_EAST].end()){
04134     Int_t delta = 999;
04135     Int_t ibest = 999;
04136     (*literE)->SetFirst();
04137     while( (*literE)->IsValid() ){
04138       Int_t iStripE = (*literE)->GetCurrentSEId().GetStrip();
04139       for(UInt_t i = 0; i<stripPattern.size(); i++){
04140         Int_t d =abs(iStripE-stripPattern[i]);
04141         if(d<delta){
04142           delta = d;
04143           ibest = iStripE;
04144           Q = pCalculator->CurrentQ(*literE);
04145         }
04146       }
04147       (*literE)->Next();
04148     }
04149     QTotE+= Q;
04150     stripE[ibest] =  *literE;
04151     literE++;
04152   }
04153   
04154   literW = fDeMuxedPlanesAltLists[iplane][ALG_WEST].begin();
04155   while (literW != fDeMuxedPlanesAltLists[iplane][ALG_WEST].end()){
04156     Int_t delta = 999;
04157     Int_t ibest = 999;
04158     (*literW)->SetFirst();
04159     while( (*literW)->IsValid() ){
04160       Int_t iStripW = (*literW)->GetCurrentSEId().GetStrip();
04161       for(UInt_t i = 0; i<stripPattern.size(); i++){
04162         Int_t d =abs(iStripW-stripPattern[i]);
04163         if(d<delta){
04164           delta = d;
04165           ibest = iStripW;
04166           Q     = pCalculator->CurrentQ(*literW);
04167         }
04168       }
04169       (*literW)->Next();
04170     }
04171     stripW[ibest] =  *literW;
04172     literW++;
04173     QTotW+=Q;
04174   }
04175   
04176   literW = fPlanesAltLists[iplane][ALG_WEST].begin();
04177   while (literW != fPlanesAltLists[iplane][ALG_WEST].end()){
04178     Int_t delta = 999;
04179     Int_t ibest = 999;
04180     (*literW)->SetFirst();
04181     while( (*literW)->IsValid() ){
04182       Int_t iStripW = (*literW)->GetCurrentSEId().GetStrip();
04183       for(UInt_t i = 0; i<stripPattern.size(); i++){
04184         Int_t d =abs(iStripW-stripPattern[i]);
04185         if(d<delta){
04186           delta = d;
04187           ibest = iStripW;
04188           Q= pCalculator->CurrentQ(*literW);
04189         }
04190       }
04191       (*literW)->Next();
04192     }
04193     QTotW+=Q;
04194     stripW[ibest] =  *literW;
04195     literW++;
04196   }
04197   // Have mathched E/W : now check consistency
04198   
04199   Float_t QMatchedE=0;
04200   Float_t QMatchedW=0;
04201   Float_t chi2 =0;
04202   Int_t   lowStrip =999;
04203   Int_t   highStrip =0;
04204   Int_t   contigLow =999;
04205   Int_t   contigHigh =0;
04206   bool    contig = false;
04207   Int_t   nContigGroup = 0;
04208   Int_t   contigGroup = 0;
04209   Int_t   nInGroup = 0;
04210   Int_t   contigLast = 0;
04211 
04212   for(Int_t i = 0;i<MAX_NUMBER_OF_STRIPS; i++){
04213     if(stripE[i]!=NULL&&stripW[i]!=NULL){
04214       returnValidity.strips.push_back(i);
04215       if(i<lowStrip)lowStrip=i;
04216       highStrip=i;
04217       if(contig){
04218         if( (i-contigLast)<=2){
04219           contigLast = i;
04220           nInGroup++;
04221         }else{
04222           contig = false;
04223           contigHigh = contigLast;
04224           if(contigHigh+1-contigLow>contigGroup)contigGroup =contigHigh+1-contigLow; 
04225           if(nInGroup>nContigGroup)nContigGroup = nInGroup;
04226         }
04227       }
04228 
04229       if(!contig){
04230         nInGroup = 1;
04231         contigLow = i;
04232         contigLast = i;
04233         contig = true;
04234       }      
04235 
04236       PlaneView::PlaneView_t kView = stripE[i]->GetPlaneView();
04237       pCalculator->SetPlane(iplane);
04238       pCalculator->SetView(kView);
04239       pCalculator->SetEastToStrip(stripE[i],i);
04240       pCalculator->SetWestToStrip(stripW[i],i);
04241       pCalculator->CalcEastWest();
04242       QMatchedE += pCalculator->QSigCorE();
04243       QMatchedW += pCalculator->QSigCorW();
04244       Float_t sigmaQ = pCalculator->SigmaDQ();
04245       chi2+= sigmaQ*sigmaQ;
04246       if(amWriting)cout << " Match : " << i << " QE/W : " << pCalculator->QSigCorE() << ":"          << pCalculator->QSigCorW() << " SDQ : " << sigmaQ << endl;
04247     }
04248   }
04249   if(contig){
04250     contigHigh = contigLast;
04251     if(contigHigh+1-contigLow>contigGroup)contigGroup =contigHigh+1-contigLow; 
04252     if(nInGroup>nContigGroup)nContigGroup = nInGroup;
04253   }
04254 
04255   Float_t fracE = QMatchedE/QTotE;
04256   Float_t fracW = QMatchedW/QTotW;
04257   if(amWriting)cout << " Frac : " << fracE << "/" << fracW << " chi2 : " << chi2 <<endl;
04258 
04259   returnValidity.fractionQE = fracE;
04260   returnValidity.fractionQW = fracW;
04261   returnValidity.chi2DQ = chi2;
04262   returnValidity.largestContigGroup = nContigGroup;
04263   returnValidity.stripSpan          = highStrip-lowStrip+1;
04264   returnValidity.centroid           = (highStrip+lowStrip)/2.0;
04265 
04266   if(amWriting){
04267     cout << " SPAN          : " << returnValidity.stripSpan  << endl;
04268     cout << " Contig GROUP  : " << returnValidity.largestContigGroup  << endl;
04269     cout << " NContig GROUP : " << nContigGroup  << endl;
04270   }
04271 
04272   return returnValidity;
04273 }
04274 
04275 
04276 
04277 
04278 
04279 
04280 
04281 
04282 PlaneValidity_t AlgAltDeMuxBase::ValidateOneSidedPlaneForPattern(Int_t iplane, vector<Int_t> stripPattern)
04283 { 
04284   vector <PlexSEIdAltL*>::iterator literE;
04285   vector <PlexSEIdAltL*>::iterator literW;
04286   PlexSEIdAltL* stripE[MAX_NUMBER_OF_STRIPS];
04287   PlexSEIdAltL* stripW[MAX_NUMBER_OF_STRIPS];
04288 
04289   Float_t Q;
04290 
04291     pCalculator->SetPlane(iplane);
04292 
04293   Float_t QTotE = 0;
04294   Float_t QTotW = 0;
04295   if(amWriting){
04296     cout << "******HITSTIP ";
04297     for(UInt_t i=0;i<stripPattern.size();i++)cout << ":" << stripPattern[i];
04298     cout << endl;
04299   }
04300   for(Int_t i=0; i<MAX_NUMBER_OF_STRIPS; i++){
04301     stripE[i] = NULL;
04302     stripW[i] = NULL;
04303   }
04304 
04305 
04306   literE = fDeMuxedPlanesAltLists[iplane][ALG_EAST].begin();
04307   while (literE != fDeMuxedPlanesAltLists[iplane][ALG_EAST].end()){
04308     Int_t delta = 999;
04309     Int_t ibest = 999;
04310     (*literE)->SetFirst();
04311     while( (*literE)->IsValid() ){
04312       Int_t iStripE = (*literE)->GetCurrentSEId().GetStrip();
04313       for(UInt_t i = 0; i<stripPattern.size(); i++){
04314         Int_t d =abs(iStripE-stripPattern[i]);
04315         if(d<delta){
04316           delta = d;
04317           ibest = iStripE;
04318           Q = pCalculator->CurrentQ(*literE);
04319         }
04320       }
04321       (*literE)->Next();
04322     }
04323     stripE[ibest] =  *literE;
04324     literE++;
04325     QTotE+= Q;
04326   }
04327   
04328   literE = fPlanesAltLists[iplane][ALG_EAST].begin();
04329   while (literE != fPlanesAltLists[iplane][ALG_EAST].end()){
04330     Int_t delta = 999;
04331     Int_t ibest = 999;
04332     (*literE)->SetFirst();
04333     while( (*literE)->IsValid() ){
04334       Int_t iStripE = (*literE)->GetCurrentSEId().GetStrip();
04335       for(UInt_t i = 0; i<stripPattern.size(); i++){
04336         Int_t d =abs(iStripE-stripPattern[i]);
04337         if(d<delta){
04338           delta = d;
04339           ibest = iStripE;
04340           Q = pCalculator->CurrentQ(*literE);
04341         }
04342       }
04343       (*literE)->Next();
04344     }
04345     QTotE+= Q;
04346     stripE[ibest] =  *literE;
04347     literE++;
04348   }
04349   
04350   literW = fDeMuxedPlanesAltLists[iplane][ALG_WEST].begin();
04351   while (literW != fDeMuxedPlanesAltLists[iplane][ALG_WEST].end()){
04352     Int_t delta = 999;
04353     Int_t ibest = 999;
04354     (*literW)->SetFirst();
04355     while( (*literW)->IsValid() ){
04356       Int_t iStripW = (*literW)->GetCurrentSEId().GetStrip();
04357       for(UInt_t i = 0; i<stripPattern.size(); i++){
04358         Int_t d =abs(iStripW-stripPattern[i]);
04359         if(d<delta){
04360           delta = d;
04361           ibest = iStripW;
04362           Q     = pCalculator->CurrentQ(*literW);
04363         }
04364       }
04365       (*literW)->Next();
04366     }
04367     stripW[ibest] =  *literW;
04368     literW++;
04369     QTotW+=Q;
04370   }
04371   
04372   literW = fPlanesAltLists[iplane][ALG_WEST].begin();
04373   while (literW != fPlanesAltLists[iplane][ALG_WEST].end()){
04374     Int_t delta = 999;
04375     Int_t ibest = 999;
04376     (*literW)->SetFirst();
04377     while( (*literW)->IsValid() ){
04378       Int_t iStripW = (*literW)->GetCurrentSEId().GetStrip();
04379       for(UInt_t i = 0; i<stripPattern.size(); i++){
04380         Int_t d =abs(iStripW-stripPattern[i]);
04381         if(d<delta){
04382           delta = d;
04383           ibest = iStripW;
04384           Q= pCalculator->CurrentQ(*literW);
04385         }
04386       }
04387       (*literW)->Next();
04388     }
04389     QTotW+=Q;
04390     stripW[ibest] =  *literW;
04391     literW++;
04392   }
04393   // Have mathched E/W : now check consistency
04394   
04395   // Float_t QMatchedE=0;
04396   // Float_t QMatchedW=0;
04397   // Float_t chi2 =0;
04398   Int_t   lowStrip =999;
04399   Int_t   highStrip =0;
04400   Int_t   contigLow =999;
04401   Int_t   contigHigh =0;
04402   bool    contig = false;
04403   Int_t   nContigGroup = 0;
04404   Int_t   contigGroup = 0;
04405   Int_t   nInGroup = 0;
04406   Int_t   contigLast = 0;
04407 
04408   for(Int_t i = 0;i<MAX_NUMBER_OF_STRIPS; i++){
04409     if(stripE[i]!=NULL||stripW[i]!=NULL){
04410       if(i<lowStrip)lowStrip=i;
04411       highStrip=i;
04412       if(contig){
04413         if( (i-contigLast)<=2){
04414           contigLast = i;
04415           nInGroup++;
04416         }else{
04417           contig = false;
04418           contigHigh = contigLast;
04419           if(contigHigh+1-contigLow>contigGroup)contigGroup =contigHigh+1-contigLow; 
04420           if(nInGroup>nContigGroup)nContigGroup = nInGroup;
04421         }
04422       }
04423 
04424       if(!contig){
04425         nInGroup = 1;
04426         contigLow = i;
04427         contigLast = i;
04428         contig = true;
04429       }      
04430       if(amWriting)cout << " Match : " << i << endl;
04431     }
04432   }
04433   if(contig){
04434     contigHigh = contigLast;
04435     if(contigHigh+1-contigLow>contigGroup)contigGroup =contigHigh+1-contigLow; 
04436     if(nInGroup>nContigGroup)nContigGroup = nInGroup;
04437   }
04438   PlaneValidity_t returnValidity;
04439   returnValidity.largestContigGroup = nContigGroup;
04440   returnValidity.stripSpan          = highStrip-lowStrip+1;
04441   returnValidity.centroid           = (highStrip+lowStrip)/2.0;
04442   returnValidity.chi2DQ             = 0.;
04443   returnValidity.fractionQE = 0.;
04444   returnValidity.fractionQW = 0.;
04445 
04446 
04447   if(amWriting){
04448     cout << " SPAN          : " << returnValidity.stripSpan  << endl;
04449     cout << " Contig GROUP  : " << returnValidity.largestContigGroup  << endl;
04450     cout << " NContig GROUP : " << nContigGroup  << endl;
04451   }
04452 
04453   return returnValidity;
04454 }
04455 
04456 
04457 
04458 
04459 
04460 void AlgAltDeMuxBase::ReMuxPlane(Int_t iplane, vector<Int_t> stripPattern)
04461 { 
04462   vector <PlexSEIdAltL*>::iterator literE;
04463   vector <PlexSEIdAltL*>::iterator literW;
04464   PlexSEIdAltL* stripE[MAX_NUMBER_OF_STRIPS];
04465   PlexSEIdAltL* stripW[MAX_NUMBER_OF_STRIPS];
04466 
04467   Int_t nE=0;
04468   Int_t nW=0;
04469 
04470 
04471   for(Int_t i=0; i<MAX_NUMBER_OF_STRIPS; i++){
04472     stripE[i] = NULL;
04473     stripW[i] = NULL;
04474   }
04475   literE = fDeMuxedPlanesAltLists[iplane][ALG_EAST].begin();
04476   while (literE != fDeMuxedPlanesAltLists[iplane][ALG_EAST].end()){
04477     nE++;
04478     Int_t delta = 999;
04479     Int_t ibest = 999;
04480     (*literE)->SetFirst();
04481     while( (*literE)->IsValid() ){
04482       Int_t iStripE = (*literE)->GetCurrentSEId().GetStrip();
04483       for(UInt_t i = 0; i<stripPattern.size(); i++){
04484         Int_t d =abs(iStripE-stripPattern[i]);
04485         if(d<delta){
04486           delta = d;
04487           ibest = iStripE;
04488         }
04489       }
04490       (*literE)->Next();
04491     }
04492     stripE[ibest] =  *literE;
04493     literE++;
04494   }
04495   
04496   literE = fPlanesAltLists[iplane][ALG_EAST].begin();
04497   while (literE != fPlanesAltLists[iplane][ALG_EAST].end()){
04498     nE++;
04499     Int_t delta = 999;
04500     Int_t ibest = 999;
04501     (*literE)->SetFirst();
04502     while( (*literE)->IsValid() ){
04503       Int_t iStripE = (*literE)->GetCurrentSEId().GetStrip();
04504       for(UInt_t i = 0; i<stripPattern.size(); i++){
04505         Int_t d =abs(iStripE-stripPattern[i]);
04506         if(d<delta){
04507           delta = d;
04508           ibest = iStripE;
04509         }
04510       }
04511       (*literE)->Next();
04512     }
04513     stripE[ibest] =  *literE;
04514     literE++;
04515   }
04516   
04517   literW = fDeMuxedPlanesAltLists[iplane][ALG_WEST].begin();
04518   while (literW != fDeMuxedPlanesAltLists[iplane][ALG_WEST].end()){
04519     nW++;
04520     Int_t delta = 999;
04521     Int_t ibest = 999;
04522     (*literW)->SetFirst();
04523     while( (*literW)->IsValid() ){
04524       Int_t iStripW = (*literW)->GetCurrentSEId().GetStrip();
04525       for(UInt_t i = 0; i<stripPattern.size(); i++){
04526         Int_t d =abs(iStripW-stripPattern[i]);
04527         if(d<delta){
04528           delta = d;
04529           ibest = iStripW;
04530         }
04531       }
04532       (*literW)->Next();
04533     }
04534     stripW[ibest] =  *literW;
04535     literW++;
04536   }
04537   
04538   literW = fPlanesAltLists[iplane][ALG_WEST].begin();
04539   while (literW != fPlanesAltLists[iplane][ALG_WEST].end()){
04540     nW++;
04541     Int_t delta = 999;
04542     Int_t ibest = 999;
04543     (*literW)->SetFirst();
04544     while( (*literW)->IsValid() ){
04545       Int_t iStripW = (*literW)->GetCurrentSEId().GetStrip();
04546       for(UInt_t i = 0; i<stripPattern.size(); i++){
04547         Int_t d =abs(iStripW-stripPattern[i]);
04548         if(d<delta){
04549           delta = d;
04550           ibest = iStripW;
04551         }
04552       }
04553       (*literW)->Next();
04554     }
04555     stripW[ibest] =  *literW;
04556     literW++;
04557   }
04558   // Have matched E/W : now use pattern remux plane
04559 
04560   this->ReMuxPlane(iplane);
04561 
04562   for(Int_t i = 0;i<MAX_NUMBER_OF_STRIPS; i++){
04563     if(stripE[i]!=NULL&&stripW[i]!=NULL){
04564       this->DeMuxHits(iplane, stripE[i], stripW[i], i);
04565     }
04566   }
04567 
04568   return;
04569 }
04570 
04571 void AlgAltDeMuxBase::ReMuxSingleSidedPlane(Int_t iplane, vector<Int_t> stripPattern)
04572 { 
04573   vector <PlexSEIdAltL*>::iterator literE;
04574   vector <PlexSEIdAltL*>::iterator literW;
04575   PlexSEIdAltL* stripE[MAX_NUMBER_OF_STRIPS];
04576   PlexSEIdAltL* stripW[MAX_NUMBER_OF_STRIPS];
04577 
04578   if(amWriting)cout << " DO REMUX SINGLE HIT " << endl;
04579 
04580   for(Int_t i=0; i<MAX_NUMBER_OF_STRIPS; i++){
04581     stripE[i] = NULL;
04582     stripW[i] = NULL;
04583   }
04584   literE = fDeMuxedPlanesAltLists[iplane][ALG_EAST].begin();
04585   while (literE != fDeMuxedPlanesAltLists[iplane][ALG_EAST].end()){
04586     Int_t delta = 999;
04587     Int_t ibest = 999;
04588     (*literE)->SetFirst();
04589     while( (*literE)->IsValid() ){
04590       Int_t iStripE = (*literE)->GetCurrentSEId().GetStrip();
04591       for(UInt_t i = 0; i<stripPattern.size(); i++){
04592         Int_t d =abs(iStripE-stripPattern[i]);
04593         if(d<delta){
04594           delta = d;
04595           ibest = iStripE;
04596         }
04597       }
04598       (*literE)->Next();
04599     }
04600     stripE[ibest] =  *literE;
04601     literE++;
04602   }
04603   
04604   literE = fPlanesAltLists[iplane][ALG_EAST].begin();
04605   while (literE != fPlanesAltLists[iplane][ALG_EAST].end()){
04606     Int_t delta = 999;
04607     Int_t ibest = 999;
04608     (*literE)->SetFirst();
04609     while( (*literE)->IsValid() ){
04610       Int_t iStripE = (*literE)->GetCurrentSEId().GetStrip();
04611       for(UInt_t i = 0; i<stripPattern.size(); i++){
04612         Int_t d =abs(iStripE-stripPattern[i]);
04613         if(d<delta){
04614           delta = d;
04615           ibest = iStripE;
04616         }
04617       }
04618       (*literE)->Next();
04619     }
04620     stripE[ibest] =  *literE;
04621     literE++;
04622   }
04623   
04624   literW = fDeMuxedPlanesAltLists[iplane][ALG_WEST].begin();
04625   while (literW != fDeMuxedPlanesAltLists[iplane][ALG_WEST].end()){
04626     Int_t delta = 999;
04627     Int_t ibest = 999;
04628     (*literW)->SetFirst();
04629     while( (*literW)->IsValid() ){
04630       Int_t iStripW = (*literW)->GetCurrentSEId().GetStrip();
04631       for(UInt_t i = 0; i<stripPattern.size(); i++){
04632         Int_t d =abs(iStripW-stripPattern[i]);
04633         if(d<delta){
04634           delta = d;
04635           ibest = iStripW;
04636         }
04637       }
04638       (*literW)->Next();
04639     }
04640     stripW[ibest] =  *literW;
04641     literW++;
04642   }
04643   
04644   literW = fPlanesAltLists[iplane][ALG_WEST].begin();
04645   while (literW != fPlanesAltLists[iplane][ALG_WEST].end()){
04646     Int_t delta = 999;
04647     Int_t ibest = 999;
04648     (*literW)->SetFirst();
04649     while( (*literW)->IsValid() ){
04650       Int_t iStripW = (*literW)->GetCurrentSEId().GetStrip();
04651       for(UInt_t i = 0; i<stripPattern.size(); i++){
04652         Int_t d =abs(iStripW-stripPattern[i]);
04653         if(d<delta){
04654           delta = d;
04655           ibest = iStripW;
04656         }
04657       }
04658       (*literW)->Next();
04659     }
04660     stripW[ibest] =  *literW;
04661     literW++;
04662   }
04663   // Have matched E/W : now use pattern remux plane
04664 
04665   this->ReMuxPlane(iplane);
04666 
04667   for(Int_t i = 0;i<MAX_NUMBER_OF_STRIPS; i++){
04668     if(stripE[i]!=NULL)this->DeMuxSingleHitE(iplane, stripE[i], i);
04669     if(stripW[i]!=NULL)this->DeMuxSingleHitW(iplane, stripW[i], i);
04670   }
04671 
04672   return;
04673 }
04674 
04675 
04676 
04677 
04678 void AlgAltDeMuxBase::ReMuxPlane(Int_t iplane){
04679 
04680   vector <PlexSEIdAltL*>::iterator literA;
04681 
04682   for(Int_t iew=ALG_EAST; iew<=ALG_WEST;iew++){
04683     if(fDeMuxedPlanesAltLists[iplane][iew].size()>0){
04684       literA = fDeMuxedPlanesAltLists[iplane][iew].begin();
04685       while( literA != fDeMuxedPlanesAltLists[iplane][iew].end()){
04686         (*literA)->ClearWeights();
04687         fPlanesAltLists[iplane][iew].push_back(*literA);
04688         literA++;
04689       }
04690     }
04691   }
04692 
04693   fDeMuxedPairs[iplane].erase(fDeMuxedPairs[iplane].begin(),fDeMuxedPairs[iplane].end());
04694   fDeMuxedSingles[iplane].erase(fDeMuxedSingles[iplane].begin(),fDeMuxedSingles[iplane].end());
04695 
04696   for(Int_t iew=0; iew<=1;iew++){
04697     // Clear the arrays of vectors of AltLists
04698     fDeMuxedPlanesAltLists[iplane][iew].erase(fDeMuxedPlanesAltLists[iplane][iew].begin(),fDeMuxedPlanesAltLists[iplane][iew].end());
04699   }
04700   // zero counters
04701   fPlaneHit[iplane] = 0;
04702   fPlanePair[iplane] = 0;
04703   NdemuxedHitsU[iplane] = 0;
04704   NdemuxedHitsV[iplane] = 0;
04705 
04706   return;
04707 }
04708 
04709 void AlgAltDeMuxBase::DeMuxPass(Int_t ipass){
04710 
04711   vector <DeMuxSearchTactic>::iterator literS;
04712 
04713   amShowing = false;
04714   fCutUseMultipleLines = false;
04715 
04716   switch(ipass){
04717   case 0:
04718     fCutRawPE            = 0.0;
04719     fCutCorPE            = 1.0;
04720     fCutSigmaQ           = 3.5;
04721     fCutUseTimingMask    = true;
04722     fCutUseTargetStrips  = false;
04723     fCutGuessing         = false;
04724     fStripWindow         = 5;
04725 
04726     for(int iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
04727       if(fPlanesAltLists[iplane][ALG_EAST].size()&&fPlanesAltLists[iplane][ALG_WEST].size()){
04728 
04729         if(amWriting)MSG("AltDeMux", Msg::kInfo) << "DeMuxPass0 : " << iplane << " : " << fPlanesAltLists[iplane][ALG_EAST].size() << " : " << fPlanesAltLists[iplane][ALG_WEST].size() << endl;
04730         this->ResetMap(fPlanesAltLists[iplane][ALG_EAST].size(),fPlanesAltLists[iplane][ALG_WEST].size());
04731         this->MakePlaneMap(iplane);
04732         //  this->PrintPlaneMap();
04733         this->GroupHits();
04734         this->SelectHits(iplane,true);
04735       }
04736     }
04737 
04738     MSG("AltDeMux", Msg::kInfo) << "AlgAltDeMuxBase::DeMuxPass Finished DeMuxPass 0" << endl;
04739     break;
04740   case 1:
04741     fCutRawPE            = 0.5;
04742     fCutCorPE            = 2.0;
04743     fCutSigmaQ           = 3.0;
04744     fCutUseTimingMask    = true;
04745     fCutUseTargetStrips  = false;
04746     fCutGuessing         = false;
04747     fStripWindow         = 5;
04748     for(Int_t iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
04749       NdemuxedHitsU[iplane]=0;
04750       NdemuxedHitsV[iplane]=0;
04751       if(fPlanesAltLists[iplane][ALG_EAST].size()&&fPlanesAltLists[iplane][ALG_WEST].size()){
04752         this->ResetMap(fPlanesAltLists[iplane][ALG_EAST].size(),fPlanesAltLists[iplane][ALG_WEST].size());
04753         this->MakePlaneMap(iplane);
04754         this->GroupHits();
04755         this->SelectHits(iplane,false,true);
04756       }
04757     }
04758     MSG("AltDeMux", Msg::kInfo) << "AlgAltDeMuxBase::DeMuxPass Finished DeMuxPass 1" << endl;
04759     if(fDiagnosticPlots){
04760       this->DrawDiagnosticPlots(1);
04761     }
04762     break;
04763 
04764 
04765   case 12:
04766     fCutRawPE            = 0.0;
04767     fCutCorPE            = 0.0;
04768     fCutSigmaQ           = 5.0;
04769     fCutUseTimingMask    = false;
04770     fCutUseTargetStrips  = false;
04771     fCutGuessing         = false;
04772     fCutUseMultipleLines = false;
04773     fStripWindow         = 5;
04774     for(Int_t iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
04775       if(fPlanesAltLists[iplane][ALG_EAST].size()&&fPlanesAltLists[iplane][ALG_WEST].size()){
04776         this->ResetMap(fPlanesAltLists[iplane][ALG_EAST].size(),fPlanesAltLists[iplane][ALG_WEST].size());
04777         this->MakeMultipleTargets(iplane);
04778         this->MakePlaneMap(iplane);
04779         this->GroupHits();
04780         this->SelectHits(iplane,false,true);
04781       }
04782     }
04783     MSG("AltDeMux", Msg::kInfo) << "AlgAltDeMuxBase::DeMuxPass Finished DeMuxPass 1" << endl;
04784     if(fDiagnosticPlots){
04785       this->DrawDiagnosticPlots(1);
04786     }
04787     break;
04788 
04789 
04790   case 11:
04791     fCutRawPE            = 0.5;
04792     fCutCorPE            = 0.5;
04793     fCutSigmaQ           = 5.0;
04794     fCutUseTimingMask    = true;
04795     fCutUseTargetStrips  = true;
04796     fCutGuessing         = false;
04797     fCutUseMultipleLines = true;
04798     fStripWindow         = 12;
04799     for(Int_t iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
04800       if(fPlanesAltLists[iplane][ALG_EAST].size()&&fPlanesAltLists[iplane][ALG_WEST].size()){
04801         this->ResetMap(fPlanesAltLists[iplane][ALG_EAST].size(),fPlanesAltLists[iplane][ALG_WEST].size());
04802         this->MakeMultipleTargets(iplane);
04803         this->MakePlaneMap(iplane);
04804         this->GroupHits();
04805         this->SelectHits(iplane,false,true);
04806       }
04807     }
04808     MSG("AltDeMux", Msg::kInfo) << "AlgAltDeMuxBase::DeMuxPass Finished DeMuxPass 1" << endl;
04809     if(fDiagnosticPlots){
04810       this->DrawDiagnosticPlots(1);
04811     }
04812     break;
04813 
04814   case 22:
04815     fCutRawPE            = 0.0;
04816     fCutCorPE            = 0.5;
04817     fCutSigmaQ           = 4.0;
04818     fCutUseTimingMask    = true;
04819     fCutUseTargetStrips  = true;
04820     fCutGuessing         = false;
04821     fTrackingLowPECut    = 1.5;
04822     fStripWindow         = 5;
04823 
04824     this->MakeSearchTactics();
04825 
04826     for(unsigned int i=0; i<fSearchTactics.size(); i++){
04827       int iplane = fSearchTactics[i].iplane;
04828       if(fSearchTactics[i].goodTactic){
04829         this->ResetMap(fPlanesAltLists[iplane][ALG_EAST].size(),fPlanesAltLists[iplane][ALG_WEST].size());
04830         this->MakePlaneMap(fSearchTactics[i]);
04831         this->GroupHits();
04832         if(this->SelectHits(iplane,false)){
04833           this->NewTactic(fSearchTactics[i]);
04834         }else{
04835           this->NewTactic(fSearchTactics[i]);
04836         }
04837       }else{
04838         this->NewTactic(fSearchTactics[i]);
04839       }
04840     }
04841     MSG("AltDeMux", Msg::kInfo) << "AlgAltDeMuxBase::DeMuxPass Finished DeMuxPass 2" << endl;
04842     if(fDiagnosticPlots){
04843       this->DrawDiagnosticPlots(2);
04844     }
04845     break;
04846 
04847   case 2:
04848     fCutRawPE            = 0.0;
04849     fCutCorPE            = 1.5;
04850     fCutSigmaQ           = 3.0;
04851     fCutUseTimingMask    = false;
04852     fCutUseTargetStrips  = true;
04853     fCutGuessing         = false;
04854     fTrackingLowPECut    = 2.5;
04855     fStripWindow         = 100;
04856 
04857     this->MakeSearchTactics();
04858 
04859     for(unsigned int i=0; i<fSearchTactics.size(); i++){
04860       int iplane = fSearchTactics[i].iplane;
04861       if(fSearchTactics[i].goodTactic){
04862         this->ResetMap(fPlanesAltLists[iplane][ALG_EAST].size(),fPlanesAltLists[iplane][ALG_WEST].size());
04863         this->MakePlaneMap(fSearchTactics[i]);
04864         this->GroupHits();
04865         if(this->SelectHits(iplane,false)){
04866           this->NewTactic(fSearchTactics[i]);
04867         }else{
04868           this->NewTactic(fSearchTactics[i]);
04869         }
04870       }else{
04871         this->NewTactic(fSearchTactics[i]);
04872       }
04873     }
04874     MSG("AltDeMux", Msg::kInfo) << "AlgAltDeMuxBase::DeMuxPass Finished DeMuxPass 2" << endl;
04875     if(fDiagnosticPlots){
04876       this->DrawDiagnosticPlots(2);
04877     }
04878     break;
04879 
04880   case 3:
04881     fCutRawPE            = 0.0;
04882     fCutCorPE            = 0.0;
04883     fCutSigmaQ           = 4.0;
04884     fCutUseTimingMask    = false;
04885     fCutUseTargetStrips  = true;
04886     fCutGuessing         = false;
04887     fTrackingLowPECut    = 2.5;
04888     fStripWindow         = 100;
04889 
04890     this->MakeSearchTacticsX();
04891     if(fDiagnosticPlots)DrawDiagnosticPlots(3);
04892     for(unsigned int i=0; i<fSearchTactics.size(); i++){
04893       int iplane = fSearchTactics[i].iplane;
04894       if(fSearchTactics[i].goodTactic){
04895         this->ResetMap(fPlanesAltLists[iplane][ALG_EAST].size(),fPlanesAltLists[iplane][ALG_WEST].size());
04896         this->MakePlaneMap(fSearchTactics[i]);
04897         this->GroupHits();
04898         if(this->SelectHits(iplane,false)){
04899           this->NewTactic(fSearchTactics[i]);
04900         }else{
04901           this->NewTactic(fSearchTactics[i]);
04902         }
04903       }else{
04904         this->NewTactic(fSearchTactics[i]);
04905       }
04906     }
04907     MSG("AltDeMux", Msg::kInfo) << "AlgAltDeMuxBase::DeMuxPass Finished DeMuxPass 3" << endl;
04908     if(fDiagnosticPlots){
04909       this->DrawDiagnosticPlots(3);
04910     }
04911     break;
04912 
04913 
04914   case 33:
04915     fCutRawPE            = 0.0;
04916     fCutCorPE            = 0.0;
04917     fCutSigmaQ           = 5.0;
04918     fCutUseTimingMask    = true;
04919     fCutUseTargetStrips  = false;
04920     fCutGuessing         = false;
04921     fTrackingLowPECut    = 2.5;
04922     fStripWindow         = 5;
04923 
04924     this->MakeSearchTacticsX();
04925 
04926     for(Int_t iplane = 0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
04927       if(fPlanesAltLists[iplane][ALG_EAST].size()>0 && fPlanesAltLists[iplane][ALG_WEST].size()>0){
04928         this->ResetMap(fPlanesAltLists[iplane][ALG_EAST].size(),fPlanesAltLists[iplane][ALG_WEST].size());
04929         this->MakePlaneMap(iplane);
04930         this->GroupHits();
04931         this->SelectHits(iplane,false,true);
04932       }
04933     }
04934     MSG("AltDeMux", Msg::kInfo) << "AlgAltDeMuxBase::DeMuxPass Finished DeMuxPass 33" << endl;
04935     if(fDiagnosticPlots){
04936       this->DrawDiagnosticPlots(3);
04937     }
04938     break;
04939   case 4:
04940     //amShowing = true;
04941   case 5:
04942     fCutRawPE            = 0.0;
04943     fCutCorPE            = 0.0;
04944     fCutSigmaQ           = 0.0;
04945     fCutUseTimingMask    = false;
04946     fCutUseTargetStrips  = true;
04947     fCutGuessing         = false;
04948     fTrackingLowPECut    = 2.5;
04949     fStripWindow         = 100;
04950     this->MakeSearchTacticsY();
04951     literS = fSearchTactics.begin();
04952     while(literS!=fSearchTactics.end()){
04953       if((*literS).goodTactic){
04954         this->DeMuxSingles((*literS));
04955       }
04956       literS++;
04957     }
04958     MSG("AltDeMux", Msg::kInfo) << "AlgAltDeMuxBase::DeMuxPass Finished DeMuxPass " << ipass << endl;
04959     if(fDiagnosticPlots)this->DrawDiagnosticPlots(4);
04960     amShowing = false;
04961     break;
04962 
04963   default:
04964     MSG("AltDeMux", Msg::kError) << "AlgAltDeMuxBase::DeMuxPass - try to access undefined pass " << ipass << endl;
04965     break;
04966   }
04967   
04968   return;
04969   
04970 }
04971 
04972 
04973 
04974 
04975 void AlgAltDeMuxBase::DeMuxWhatsLeft(){
04976 
04977   fCutRawPE            = 0.0;
04978   fCutCorPE            = 0.0;
04979   fCutSigmaQ           = 10.0;
04980   fCutUseTimingMask    = false;
04981   fCutUseTargetStrips  = false;
04982   fCutGuessing         = false;
04983   fCutUseMultipleLines = false;
04984   fStripWindow         = 5;
04985   for(Int_t iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
04986     if(fPlanesAltLists[iplane][ALG_EAST].size()>0&&fPlanesAltLists[iplane][ALG_WEST].size()>0){
04987       this->ResetMap(fPlanesAltLists[iplane][ALG_EAST].size(),fPlanesAltLists[iplane][ALG_WEST].size());
04988       this->MakePlaneMap(iplane);
04989       this->GroupHits();
04990       this->SelectHits(iplane,false);
04991     }
04992   }
04993 
04994   
04995 
04996   // Next try demux groups which are golden with timing mask
04997 
04998   fCutRawPE            = 0.0;
04999   fCutCorPE            = 0.0;
05000   fCutSigmaQ           = 10.0;
05001   fCutUseTimingMask    = true;
05002   fCutUseTargetStrips  = false;
05003   fCutGuessing         = false;
05004   fCutUseMultipleLines = false;
05005   fStripWindow         = 5;
05006   for(Int_t iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
05007     if(fPlanesAltLists[iplane][ALG_EAST].size()>0&&fPlanesAltLists[iplane][ALG_WEST].size()>0){
05008       //cout << "*********************************WHATS LEFT : PASS 1 like " << iplane << endl;
05009       this->ResetMap(fPlanesAltLists[iplane][ALG_EAST].size(),fPlanesAltLists[iplane][ALG_WEST].size());
05010       this->MakePlaneMap(iplane);
05011       this->GroupHits();
05012       this->SelectHits(iplane,false);
05013     }
05014   }
05015   
05016 
05017   // Demux remaining pairs - using validate plane and the timing mask as a seed
05018   for(Int_t iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
05019     if(fPlanesAltLists[iplane][ALG_EAST].size()>0&&fPlanesAltLists[iplane][ALG_WEST].size()>0){
05020       //      cout << "*********************************WHATS LEFT : VALIDATE PLANE " << iplane << fPlanesAltLists[iplane][ALG_EAST].size() << " : " << fPlanesAltLists[iplane][ALG_EAST].size() << endl;
05021       //BestGuessForPlane(iplane);
05022     }
05023   }
05024   
05025   // Should only have singles left now.....
05026   DeMuxPass(4);
05027   for(Int_t iplane=0; iplane<MAX_NUMBER_OF_PLANES; iplane++){
05028     if(fPlanesAltLists[iplane][ALG_EAST].size()>0||fPlanesAltLists[iplane][ALG_WEST].size()>0){
05029       //  cout << "*********************************WHATS LEFT : SINGLES " << iplane << endl;
05030       this->BestGuessForSingleSidedHits(iplane);
05031     }
05032   }
05033 
05034   return;
05035   
05036 }
05037 
05038 
05039 
05040 
05041 
05042 
05043 void AlgAltDeMuxBase::MakePlaneMap(Int_t iplane,bool useTargets)
05044 {
05045 
05046   if(useTargets); // obsolete but keep backward compatibility
05047   // Look for stripend pairs which satisfy the some set of cuts 
05048 
05049   vector <PlexSEIdAltL*>::iterator literE;
05050   vector <PlexSEIdAltL*>::iterator literW;
05051 
05052   literE = fPlanesAltLists[iplane][ALG_EAST].begin();
05053   fECount = -1;
05054   PlaneView::PlaneView_t kView = (*literE)->GetPlaneView();
05055   pCalculator->SetPlane(iplane);
05056   pCalculator->SetView(kView);
05057   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;
05058   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;
05059   while (literE != fPlanesAltLists[iplane][ALG_EAST].end()){
05060     fECount++;
05061     if(fECount<MAX_HITS_PLANE){
05062       pPlaneAltMapE[fECount] = (*literE);
05063       literW = fPlanesAltLists[iplane][ALG_WEST].begin();
05064       fWCount = -1;
05065       while ( literW != fPlanesAltLists[iplane][ALG_WEST].end()){
05066         fWCount++;
05067         if(fWCount<MAX_HITS_PLANE){
05068           pPlaneAltMapW[fWCount] = (*literW);
05069           (*literE)->SetFirst();
05070           while( (*literE)->IsValid() ){
05071             Int_t iStripE = (*literE)->GetCurrentSEId().GetStrip();
05072             pCalculator->SetEast(*literE,iStripE);
05073             (*literW)->SetFirst();
05074             while( (*literW)->IsValid() ){
05075               Int_t iStripW = (*literW)->GetCurrentSEId().GetStrip();
05076               pCalculator->SetWest(*literW,iStripW);
05077               // In here we can check for a possibility
05078               if(iStripE==iStripW){
05079                 Int_t iStrip = iStripE;
05080                 bool goodComb = true;
05081                 pCalculator->CalcEastWest();
05082                 // If desired require the strip is in the road defined by timing
05083                 if(fCutUseTimingMask && fUVmask[iplane][iStrip]==false)goodComb = false; 
05084                 // Apply charge cuts on this EAST-WEST strip possibility
05085                 if(goodComb){
05086                   if(pCalculator->QRawE() < fCutRawPE || 
05087                      pCalculator->QRawW() < fCutRawPE)goodComb = false;
05088                   if(pCalculator->QSigCorE() < fCutCorPE || 
05089                      pCalculator->QSigCorW() < fCutCorPE)goodComb = false;
05090                 }
05091                 
05092                 if(goodComb)goodComb = (fabs(pCalculator->SigmaDQ())<fCutSigmaQ);
05093 
05094                 // goodComb = goodComb && (abs(pCalculator->SigmaDQ())<fCutSigmaQ);
05095                 
05096                 // If we have defined a set of target strips can insist
05097                 // strip is near one of the target positions 
05098                 if(goodComb&&fCutUseTargetStrips){
05099                   bool found = false;
05100                   for(unsigned int t=0;t<fTargetStrips.size()&&found==false;t++){
05101                     if(abs(fTargetStrips[t]-iStrip)<12){
05102                       found = true;
05103                     }
05104                   } 
05105                   goodComb = found;
05106                 }
05107                 if(amWriting){
05108                   if(goodComb)MSG("AltDeMux", Msg::kDebug) << "MakePlane(" <<iplane << ") " << pCalculator->QSigCorE() << ":" << pCalculator->QSigCorW()<<  "::" << pCalculator->QAttCorE() << ":" << pCalculator->QAttCorW() << "::" << " : " << pCalculator->SigmaDQ() << " : " << iStripE << "*" << endl;
05109                   if(!goodComb)MSG("AltDeMux", Msg::kDebug) << "MakePlane(" << iplane << ") " << pCalculator->QSigCorE() << ":" << pCalculator->QSigCorW()<<  "::" << pCalculator->QAttCorE() << ":" << pCalculator->QAttCorW() << "::" << " : " << pCalculator->SigmaDQ() << " : " << iStripE << endl;
05110                 }
05111                 if(goodComb)fAmap[fECount][fWCount] = true;
05112                 fSmap[fECount][fWCount] = iStripE;
05113               }
05114               (*literW)->Next();
05115             }
05116             (*literE)->Next();
05117           }
05118         }
05119         literW++;
05120       }
05121     }
05122     literE++;
05123   }
05124 
05125   return;
05126 }
05127 
05128 
05129 void AlgAltDeMuxBase::GroupHits(){
05130 
05131   for(Int_t iw=0;iw<=fWCount; iw++){
05132     for(Int_t iwp=0;iwp<=fWCount; iwp++){
05133       fBmap[iw][iwp] = false;
05134     }
05135   }
05136 
05137   for(Int_t ie =0; ie<=fECount; ie++){
05138     for(Int_t iw=0; iw<=fWCount; iw++){
05139       if(fAmap[ie][iw]){
05140         for(Int_t iwp =0;iwp<=fWCount; iwp++){
05141           if(fAmap[ie][iwp]){
05142             fBmap[iw][iwp] = true;
05143             fBmap[iwp][iw] = true;
05144           }
05145         }
05146       }
05147     }
05148   }
05149 
05150   for(Int_t iw=0;iw<=fWCount; iw++){
05151     fBmap[iw][iw] = true;
05152     for(Int_t iwp=0;iwp<=fWCount; iwp++){
05153       if(fBmap[iw][iwp]==false){
05154         for(Int_t k=0;k<=fWCount; k++)fBmap[iw][iwp] |= fBmap[iw][k] && fBmap[k][iwp];
05155       }
05156     }
05157   }
05158 
05159 
05160   fNGroups = 0;
05161   for(Int_t iw=0;iw<=fWCount; iw++){fWFound[iw]=false;}
05162   for(Int_t ie=0;ie<=fECount; ie++){fEFound[ie]=false;}
05163 
05164   for(Int_t iw=0;iw<=fWCount; iw++){
05165     if(fWFound[iw]==false){
05166       fNGroups++;
05167       fNInGroupW[fNGroups]=0;
05168       for(int iwp=0;iwp<=fWCount; iwp++){
05169         if(fBmap[iw][iwp]){
05170           fNInGroupW[fNGroups]++;
05171           fWGroup[fNGroups][fNInGroupW[fNGroups]]=iwp;
05172           fWFound[iwp]=true;
05173         }
05174       }
05175     }
05176   }
05177       
05178   if(fNGroups>0){
05179     for(int ig=1;ig<=fNGroups;ig++){
05180       fNInGroupE[ig]=0;
05181       for(int iw=1;iw<=fNInGroupW[ig];iw++){
05182         for(int ie=0;ie<=fECount;ie++){
05183           if(fEFound[ie]==false && fAmap[ie][(fWGroup[ig][iw])]){
05184             fNInGroupE[ig]++;
05185             fEGroup[ig][fNInGroupE[ig]]=ie;
05186             fEFound[ie] = true;
05187           }
05188         }
05189       }
05190     }
05191   }
05192 
05193   return;
05194 }
05195 
05196 
05197 bool AlgAltDeMuxBase::SelectHits(Int_t iPlane, bool gold, bool useGold) 
05198 {
05199   bool success = false;
05200 
05201   for(int ig=1;ig<=fNGroups;ig++){
05202     AltDeMuxPattern* pP;
05203     AltDeMuxPattern* pBest;
05204     PatternPair wibble;
05205     Int_t smin=999;
05206     Int_t smax=0;
05207     Int_t srange;
05208     Int_t srange1;
05209     Int_t srange2;
05210     Int_t count;
05211     pBest = NULL;
05212     count  =0;
05213     srange1 = 1000;
05214     srange2 = 1000; 
05215     if(pMaster->SelectPattern(fNInGroupE[ig],fNInGroupW[ig])){
05216       while( (pP = pMaster->Next())!=NULL ){
05217         count++;
05218         bool patok = true;
05219         smin =999;
05220         smax =0;
05221         for(int i=0; i< pP->Size(); i++){
05222           wibble = pP->GetI(i);
05223           if(patok)patok = fAmap[(fEGroup[ig][wibble.eEntry])][(fWGroup[ig][wibble.wEntry])];
05224           if(patok){
05225             Int_t s = fSmap[(fEGroup[ig][wibble.eEntry])][(fWGroup[ig][wibble.wEntry])];
05226             if(s<smin)smin=s;
05227             if(s>smax)smax=s;
05228           }
05229         }
05230         if(patok){
05231           srange = smax-smin;
05232           if(srange<=srange1){
05233             srange2 = srange1;
05234             srange1 = srange;
05235             pBest = pP;
05236           }else{
05237             if(srange<=srange2)srange2=srange;
05238           }
05239         }
05240       }
05241 
05242       // if no golden pattern found return false
05243       if(pBest==NULL)return false;
05244 
05245 
05246       // have found a golden combination so now do something with it
05247 
05248       if(srange1 < pBest->Size()+fStripWindow && srange1+pBest->Size()<srange2){
05249         success = true;
05250         if(!gold)fUniqueDeMuxedGroupID++;
05251         // have found a golden combination - iterate over it and demux hits
05252         for(int i=0; i< pBest->Size(); i++){
05253           wibble = pBest->GetI(i);
05254           
05255           Int_t iStrip = fSmap[(fEGroup[ig][wibble.eEntry])][(fWGroup[ig][wibble.wEntry])];
05256 
05257           if(amWriting)MSG("AltDeMux", Msg::kDebug) << "AlgAltDeMuxBass::SelectHits using combination " << iStrip << endl;
05258           if(gold)this->GoldHits(iPlane,iStrip);
05259           if(!gold){
05260             bool found = false;
05261             if(useGold){
05262               for(int i=1;!found && i<=fGoldPlaneHit[iPlane];i++){
05263                 if(iStrip==fGoldHitMap[iPlane][i])found=true;
05264               }
05265             }
05266             if(!useGold || fCutGuessing || found )this->DeMuxHits(iPlane,fEGroup[ig][wibble.eEntry],fWGroup[ig][wibble.wEntry],iStrip);
05267           }
05268         }
05269       }
05270     }else{
05271       // Pattern Master says no ! too big ? 
05272       if( (fNInGroupE[ig]>3) && (fNInGroupW[ig]>3) ){
05273         int nfound  = this->DeMuxBigGroup(iPlane,ig,gold);
05274         if(nfound==1)success=true;
05275       }
05276     }
05277   }  // end of loop over groups 
05278   return success; 
05279 }
05280 
05281 
05282 
05283 Int_t AlgAltDeMuxBase::DeMuxBigGroup(Int_t iplane, Int_t ig, bool gold) 
05284 { 
05285   bool success = false;
05286 
05287   vector<BigGroup>theGroups;
05288 
05289   int strips[192];
05290   int estrips[192];
05291   int wstrips[192];
05292   for(int i=0;i<192;i++)strips[i]=0;
05293   for(int ie=1;ie<=fNInGroupE[ig];ie++){
05294     for(int iw=1;iw<=fNInGroupW[ig];iw++){
05295       if(fAmap[(fEGroup[ig][ie])][(fWGroup[ig][iw])]){
05296         int s = fSmap[(fEGroup[ig][ie])][(fWGroup[ig][iw])];
05297         strips[s]++;
05298         estrips[s] = ie;
05299         wstrips[s] = iw;
05300       }
05301     }
05302   }
05303   int istartStrip;
05304   int iendStrip;
05305   int ngroups = 0;
05306   int ilast=0;
05307 
05308   for(int i=0;i<=192;i++){
05309     _smask[i] = false;
05310   }
05311 
05312   int ming = fNInGroupE[ig];
05313   if(fNInGroupW[ig]<ming)ming = fNInGroupW[ig];
05314 
05315   int best = ming-3;
05316   if(ming<12)best = ming-2;
05317   if(ming<7)best = ming-1;
05318   best = ming -1;
05319 
05320   int icount;
05321   for(int is=0; is<192-ming; is++){
05322     if(strips[is]==1){
05323       icount = 1;
05324       int iend = is+ming+5;
05325       int ie;
05326       if(iend>191)iend=192;
05327       for(ie=is+1; ie<iend && icount != ming; ie++){
05328         if(strips[ie]>0){
05329           ilast = ie;
05330           icount++;
05331         }
05332       }
05333       
05334       if(icount>=best){
05335         BigGroup aBigGroup;
05336         aBigGroup.groupStart = is;
05337         aBigGroup.groupEnd = ilast;
05338         aBigGroup.groupCount = icount;
05339         theGroups.push_back(aBigGroup);
05340         best = icount;
05341         if(amWriting)cout << "Found a (small ?) group : " << is << ":" << ilast << " : " << icount << endl;
05342       }
05343       
05344 
05345       if(icount==ming){
05346         ngroups++;
05347         istartStrip = is;
05348         iendStrip   = ie-1;
05349         if(amWriting)cout << "Found a group : " << is << ":" << ie-1 << endl;
05350         for(int i=is;i<=ie;i++){
05351           _smask[i] = true;
05352         }
05353       }
05354     }
05355   }
05356   if(amWriting)cout << "Found " << ngroups << " groups " << endl;
05357 
05358 
05359   ngroups = 0;
05360   for(unsigned int igroup =0; igroup<theGroups.size();igroup++){
05361     if(theGroups[igroup].groupCount==best){
05362       ngroups++;
05363       istartStrip = theGroups[igroup].groupStart;
05364       iendStrip = theGroups[igroup].groupEnd;
05365       if(amWriting)cout << " A good group " << theGroups[igroup].groupStart << " " << theGroups[igroup].groupEnd << " "<< theGroups[igroup].groupCount << endl;
05366       for(int i=theGroups[igroup].groupStart;i<=theGroups[igroup].groupEnd;i++){
05367         _smask[i] = true;
05368       }   
05369     }
05370   }
05371 
05372   // if one and only one group is found then demux it
05373   if(ngroups==1){
05374     success = true;
05375     // fUniqueDeMuxedGroupID is an ugly cludge to tag each group of gold hits 
05376     fUniqueDeMuxedGroupID++;
05377     Int_t ie;
05378     Int_t iw;
05379     for(Int_t is=istartStrip; is<=iendStrip;is++){
05380       if(strips[is]==1){
05381         ie = estrips[is];
05382         iw = wstrips[is];
05383         if(amWriting)cout << " Strip : " << is << " ew " << ie << ":" << iw << endl;
05384         // if the flag gold is 
05385         if(gold)this->GoldHits(iplane,is);
05386         if(!gold)this->DeMuxHits(iplane,fEGroup[ig][ie],fWGroup[ig][iw],is);
05387       }     
05388     }
05389   } 
05390 
05391   if(ngroups>1){
05392     for(int ie=1;ie<=fNInGroupE[ig];ie++){
05393       PlexSEIdAltL* pAltL;
05394       pAltL = pPlaneAltMapE[(fEGroup[ig][ie])]; 
05395       pAltL->SetFirst();
05396       while(pAltL->IsValid()){
05397         int is = pAltL->GetCurrentSEId().GetStrip();
05398         if(!_smask[is])pAltL->SetCurrentWeight(-999.);
05399         pAltL->Next();
05400       }
05401     }
05402     for(int iw=1;iw<=fNInGroupW[ig];iw++){
05403       PlexSEIdAltL* pAltL;
05404       pAltL = pPlaneAltMapW[(fWGroup[ig][iw])]; 
05405       pAltL->SetFirst();
05406       while(pAltL->IsValid()){
05407         int is = pAltL->GetCurrentSEId().GetStrip();
05408         if(!_smask[is])pAltL->SetCurrentWeight(-999.);
05409         pAltL->Next();
05410       }
05411     }
05412   }
05413 
05414   return ngroups;
05415 }
05416 
05417 void AlgAltDeMuxBase::GoldHits(Int_t iplane, Int_t istrip){ 
05418 
05419   fGoldPlaneHit[iplane] += 1;
05420   fGoldHitMap[iplane][fGoldPlaneHit[iplane]] = istrip;
05421 
05422   return;
05423 
05424 }
05425 
05426 void AlgAltDeMuxBase::DeMuxHits(Int_t iplane, Int_t ie, Int_t iw, Int_t istrip ){ 
05427   this->DeMuxHits(iplane, pPlaneAltMapE[ie], pPlaneAltMapW[iw], istrip );
05428 
05429   if(amWriting)cout << "DEMUXED STRIPs : " << ie << ":" << iw << " -> " << istrip << endl;
05430   
05431   return;
05432 }
05433 
05434 void AlgAltDeMuxBase::DeMuxHits(Int_t iplane, PlexSEIdAltL* pAltE, PlexSEIdAltL* pAltW, Int_t istrip )
05435 { 
05436   
05437   this->DeMuxHitE(iplane,pAltE,istrip);
05438   this->DeMuxHitW(iplane,pAltW,istrip);
05439 
05440   if(amWriting)cout << "DEMUX THIS HIT ! " << iplane << ":" << istrip << endl;
05441 
05442   DeMuxedPair thisPair;
05443   thisPair.altListE = pAltE;
05444   thisPair.altListW = pAltW;
05445   thisPair.status   = true;
05446   if(iplane<fLowestDeMuxedPairPlane)fLowestDeMuxedPairPlane = iplane;
05447   if(iplane>fHighestDeMuxedPairPlane)fHighestDeMuxedPairPlane = iplane;
05448 
05449 
05450   PlaneView::PlaneView_t kView = pAltE->GetPlaneView();
05451   pCalculator->SetPlane(iplane);
05452   pCalculator->SetView(kView);
05453   pCalculator->SetEast(pAltE,istrip);
05454   pCalculator->SetWest(pAltW,istrip);
05455   pCalculator->CalcBestEastWest();
05456 
05457   thisPair.orthogonalStripFromTiming = pCalculator->StripAim();
05458   thisPair.uniqueGroupID = fUniqueDeMuxedGroupID;
05459   thisPair.weightQ = 1.0;
05460   thisPair.pairQCor = pCalculator->PairQCor();
05461 
05462   fDeMuxedPairs[iplane].push_back(thisPair);
05463 
05464   if(kView==PlaneView::kU){
05465     if(NdemuxedHitsU[iplane]<MAX_DISPLAYED_HITS){
05466       demuxedHitStripU[iplane][NdemuxedHitsU[iplane]] = istrip;
05467       demuxedHitQU[iplane][NdemuxedHitsU[iplane]]     = pCalculator->PairQCor();
05468       NdemuxedHitsU[iplane]++;
05469     }
05470   }
05471   if(kView==PlaneView::kV){
05472     if(NdemuxedHitsV[iplane]<MAX_DISPLAYED_HITS){
05473       demuxedHitStripV[iplane][NdemuxedHitsV[iplane]] = istrip;
05474       demuxedHitQV[iplane][NdemuxedHitsV[iplane]]     = pCalculator->PairQCor();
05475       NdemuxedHitsV[iplane]++;
05476     }
05477   }
05478 
05479   
05480   if(fPlaneHit[iplane]==0){
05481     if(kView==PlaneView::kU)_nDeMuxedPlanesU++;
05482     if(kView==PlaneView::kV)_nDeMuxedPlanesV++; 
05483   } 
05484   fPlaneHit[iplane]++;
05485   fPlanePair[iplane]++;
05486   fHitMap[iplane][fPlaneHit[iplane]]  = istrip;
05487   fQHitMapE[iplane][fPlaneHit[iplane]] = pCalculator->QSigCorE();
05488   fQHitMapW[iplane][fPlaneHit[iplane]] = pCalculator->QSigCorW();
05489 
05490   return;
05491 
05492 }
05493 
05494 
05495 void AlgAltDeMuxBase::DeMuxHitE(Int_t iplane, Int_t ie, Int_t is){ 
05496 
05497   PlexSEIdAltL* pAltL;
05498 
05499   pAltL = pPlaneAltMapE[ie]; 
05500   this->DeMuxHitE(iplane,pAltL,is);
05501   return;
05502 }
05503 
05504 
05505 void AlgAltDeMuxBase::DeMuxHitW(Int_t iplane, Int_t iw, Int_t is){ 
05506 
05507   PlexSEIdAltL* pAltL;
05508   pAltL = pPlaneAltMapW[iw]; 
05509   this->DeMuxHitW(iplane,pAltL,is);  
05510 
05511   return;
05512 }
05513 
05514 void AlgAltDeMuxBase::DeMuxSingleHitE(Int_t iplane, PlexSEIdAltL* pAltL, Int_t istrip){ 
05515 
05516   PlaneView::PlaneView_t kView = pAltL->GetPlaneView();
05517   pCalculator->SetPlane(iplane);
05518   pCalculator->SetView(kView);
05519   pCalculator->SetEast(pAltL,istrip);
05520   pCalculator->CalcBestEast();
05521 
05522   DeMuxedSingle thisSingle;
05523   thisSingle.altList = pAltL;
05524   thisSingle.status  =  true;
05525   thisSingle.Qcor    = pCalculator->QSigCorE();
05526   fDeMuxedSingles[iplane].push_back(thisSingle);
05527 
05528   if(fDiagnosticPlots){
05529     if(kView==PlaneView::kU){
05530       if(NdemuxedHitsU[iplane]<MAX_DISPLAYED_HITS){
05531         demuxedHitStripU[iplane][NdemuxedHitsU[iplane]] = istrip;
05532         demuxedHitQU[iplane][NdemuxedHitsU[iplane]]     = pCalculator->QSigCorE();
05533         NdemuxedHitsU[iplane]++;
05534       }
05535     }
05536     if(kView==PlaneView::kV){
05537       if(NdemuxedHitsV[iplane]<MAX_DISPLAYED_HITS){
05538         demuxedHitStripV[iplane][NdemuxedHitsV[iplane]] = istrip;
05539         demuxedHitQV[iplane][NdemuxedHitsV[iplane]]     = pCalculator->QSigCorE();
05540         NdemuxedHitsV[iplane]++;
05541       }
05542     }
05543   }
05544   
05545   fPlaneHit[iplane]++;
05546   fHitMap[iplane][fPlaneHit[iplane]]  = istrip;
05547   fQHitMapE[iplane][fPlaneHit[iplane]] = pCalculator->QSigCorE();
05548 
05549   //  cout << "DEMUXING SINGLE E : " << iplane << ":" << istrip  << " : " << pCalculator->QSigCorE() << ":" << this->XTalkCharge(pAltL,istrip) << endl;
05550 
05551   this->DeMuxHitE(iplane,pAltL,istrip);
05552 
05553   return;
05554 }
05555 
05556 
05557 
05558 void AlgAltDeMuxBase::DeMuxSingleHitW(Int_t iplane, PlexSEIdAltL* pAltL, Int_t istrip){ 
05559 
05560   PlaneView::PlaneView_t kView = pAltL->GetPlaneView();
05561   pCalculator->SetPlane(iplane);
05562   pCalculator->SetView(kView);
05563   pCalculator->SetWest(pAltL,istrip);
05564   pCalculator->CalcBestWest();
05565 
05566 
05567   DeMuxedSingle thisSingle;
05568   thisSingle.altList = pAltL;
05569   thisSingle.status  = true;
05570   thisSingle.Qcor    = pCalculator->QSigCorW();
05571   fDeMuxedSingles[iplane].push_back(thisSingle);
05572 
05573   if(fDiagnosticPlots){
05574     if(kView==PlaneView::kU){
05575       if(NdemuxedHitsU[iplane]<MAX_DISPLAYED_HITS){
05576         demuxedHitStripU[iplane][NdemuxedHitsU[iplane]] = istrip;
05577         demuxedHitQU[iplane][NdemuxedHitsU[iplane]]     = pCalculator->QSigCorW();
05578         NdemuxedHitsU[iplane]++;
05579       }
05580     }
05581     if(kView==PlaneView::kV){
05582       if(NdemuxedHitsV[iplane]<MAX_DISPLAYED_HITS){
05583         demuxedHitStripV[iplane][NdemuxedHitsV[iplane]] = istrip;
05584         demuxedHitQV[iplane][NdemuxedHitsV[iplane]]     = pCalculator->QSigCorW();
05585         NdemuxedHitsV[iplane]++;
05586       }
05587     }
05588   }
05589   
05590   fPlaneHit[iplane]++;
05591   fHitMap[iplane][fPlaneHit[iplane]]  = istrip;
05592   fQHitMapW[iplane][fPlaneHit[iplane]] = pCalculator->QSigCorW();
05593   this->DeMuxHitW(iplane,pAltL,istrip);
05594 
05595   return;
05596 }
05597 
05598 
05599 
05600 void AlgAltDeMuxBase::DeMuxHitE(Int_t iplane, PlexSEIdAltL* pAltL, Int_t is){ 
05601 
05602   vector <PlexSEIdAltL*>::iterator literA;
05603   bool notFound;
05604   float q;
05605 
05606   pAltL->SetFirst();
05607 
05608   q = pAltL->GetCurrentItem().GetPE();
05609   notFound = true;
05610   while(pAltL->IsValid()){
05611     if(pAltL->GetCurrentSEId().GetStrip()==is){
05612       pAltL->SetCurrentWeight(1.);
05613     }else{
05614       pAltL->SetCurrentWeight(0.);
05615     }
05616     pAltL->Next();
05617   }
05618 
05619   literA = fPlanesAltLists[iplane][ALG_EAST].begin();
05620   notFound = true;
05621   while (notFound && literA != fPlanesAltLists[iplane][ALG_EAST].end()){
05622     if(*literA==pAltL){
05623       fPlanesAltLists[iplane][ALG_EAST].erase(literA);
05624       notFound = false;
05625     }
05626     literA++;
05627   }
05628   fDeMuxedPlanesAltLists[iplane][ALG_EAST].push_back(pAltL);
05629 
05630   this->UpdateXTalkMap(pAltL);
05631 
05632   return;
05633 }
05634 
05635 
05636 void AlgAltDeMuxBase::VetoHitE(Int_t iplane, PlexSEIdAltL* pAltL){ 
05637 
05638   bool notFound;
05639   vector <PlexSEIdAltL*>::iterator literA;
05640 
05641   literA = fPlanesAltLists[iplane][ALG_EAST].begin();
05642   notFound = true;
05643   while (notFound && literA != fPlanesAltLists[iplane][ALG_EAST].end()){
05644     if(*literA==pAltL){
05645       fPlanesAltLists[iplane][ALG_EAST].erase(literA);
05646       notFound = false;
05647     }
05648     literA++;
05649   }
05650 
05651   return;
05652 }
05653 
05654 void AlgAltDeMuxBase::VetoHitW(Int_t iplane, PlexSEIdAltL* pAltL){ 
05655 
05656   bool notFound;
05657   vector <PlexSEIdAltL*>::iterator literA;
05658 
05659   literA = fPlanesAltLists[iplane][ALG_WEST].begin();
05660   notFound = true;
05661   while (notFound && literA != fPlanesAltLists[iplane][ALG_WEST].end()){
05662     if(*literA==pAltL){
05663       fPlanesAltLists[iplane][ALG_WEST].erase(literA);
05664       notFound = false;
05665     }
05666     literA++;
05667   }
05668 
05669   return;
05670 }
05671 
05672 
05673 void AlgAltDeMuxBase::DeMuxHitW(Int_t iplane, PlexSEIdAltL* pAltL, Int_t is){ 
05674 
05675 
05676   vector <PlexSEIdAltL*>::iterator literA;
05677   bool notFound;
05678   float q;
05679 
05680 
05681   pAltL->SetFirst();
05682 
05683   notFound = true;
05684   q = pAltL->GetCurrentItem().GetPE();
05685   while(pAltL->IsValid()){
05686     if(pAltL->GetCurrentSEId().GetStrip()==is){
05687       pAltL->SetCurrentWeight(1.);
05688     }else{
05689       pAltL->SetCurrentWeight(0.);
05690     }
05691     pAltL->Next();
05692   }
05693   
05694   literA = fPlanesAltLists[iplane][ALG_WEST].begin();
05695   notFound = true;
05696   while (notFound && literA != fPlanesAltLists[iplane][ALG_WEST].end()){
05697     if(*literA==pAltL){
05698       fPlanesAltLists[iplane][ALG_WEST].erase(literA);
05699       notFound = false;
05700     }
05701     literA++;
05702   }
05703 
05704   fDeMuxedPlanesAltLists[iplane][ALG_WEST].push_back(pAltL);
05705   this->UpdateXTalkMap(pAltL);
05706 
05707   return;
05708 }
05709  
05710 
05711 DeMuxSearchTactic AlgAltDeMuxBase::MakeSearchTactics(Int_t iplane)
05712 {
05713 
05714   bool foundH = false;
05715   bool foundL = false;
05716 
05717   DeMuxSearchTactic tactic;
05718   tactic.iplane = iplane;
05719 
05720   Int_t imax = iplane+12;
05721   if(imax>MAX_NUMBER_OF_PLANES-2)imax=MAX_NUMBER_OF_PLANES-3;
05722   for(int i=iplane+2; i<imax &&!foundH ; i+=2){
05723     if( fUVMap[i]==fUVMap[iplane]){
05724       foundH = true;
05725       tactic.highplane  = i;
05726     }
05727   }
05728   Int_t imin = iplane - 12;
05729   if(imin<2)imin=1;
05730   for(int i=iplane-2; i>imin &&!foundL ; i-=2){
05731     if( fUVMap[i]==fUVMap[iplane]){
05732       foundL = true;
05733       tactic.lowplane  = i;
05734     }
05735   }
05736   if(foundL||foundH)tactic.goodTactic = true;
05737 
05738   return tactic;
05739 }
05740 
05741 void AlgAltDeMuxBase::MakeSearchTactics()
05742 {
05743 
05744   bool ifirstU=false;
05745   bool ifirstV=false;
05746   int firstUplane;
05747   int firstVplane;
05748   int lastUplane;
05749   int lastVplane;
05750   int foundPlane;
05751 
05752 
05753   fSearchTactics.erase(fSearchTactics.begin(),fSearchTactics.end());
05754 
05755   for(int i=0; i<MAX_NUMBER_OF_PLANES; i++){
05756     fSearched[i] = false;
05757     if(fPlaneHit[i]>0){
05758       if(ifirstU==false){
05759         if( fUVMap[i]==PlaneView::kU){
05760           ifirstU = true;
05761           firstUplane = i;
05762         }
05763       }
05764       if(ifirstV==false){
05765         if( fUVMap[i]==PlaneView::kV){
05766           ifirstV = true;
05767           firstVplane = i;
05768         }
05769       }
05770 
05771 
05772 
05773       if(fUVMap[i]==PlaneView::kU)lastUplane =i;
05774       if(fUVMap[i]==PlaneView::kV)lastVplane =i;
05775 
05776       int inext = i+2;
05777       if(inext==249)inext=250;
05778       if(inext==250)inext=251;
05779 
05780       if(fPlaneHit[inext]==0){
05781         int j = inext+1;
05782         bool found = false;
05783         while(found==false&&j-inext <=24 && j<MAX_NUMBER_OF_PLANES-2){
05784           j++;
05785           if(fUVMap[j]==fUVMap[i]&&fPlaneHit[j]>0)found=true;
05786         }
05787         if(found){
05788           bool lfound = false;
05789           // Step forward in gap
05790           for(int k=i+2; k<=j-2; k++){
05791             if(fUVMap[k]==fUVMap[i]){
05792               if(!lfound && fPlanesAltLists[k][ALG_EAST].size()&&fPlanesAltLists[k][ALG_WEST].size()){
05793                 lfound = true;
05794                 DeMuxSearchTactic tactic;
05795                 foundPlane = k;
05796                 tactic.iplane = k;
05797                 tactic.searchType = SEARCH_GAP_F;
05798                 tactic.lowplane  = i;
05799                 tactic.highplane = j;
05800                 tactic.goodTactic = true;
05801                 fSearchTactics.push_back(tactic);
05802                 fSearched[k] = true;
05803                 if(tactic.highplane>=MAX_NUMBER_OF_PLANES)MSG("AltDeMux", Msg::kFatal) << "AlgAltDeMuxBase::MakeSearchTactics highplane out of range : " << tactic.highplane << " :" << i << ":" << j << ":" << k << endl;
05804               }
05805             }
05806           }
05807           // Step backwards in gap
05808           if(lfound){
05809             bool found = false;
05810             for(int k=j-2; k>=foundPlane+2; k--){
05811               if(fUVMap[k]==fUVMap[i]){
05812                 if(!found &&fPlanesAltLists[k][ALG_EAST].size()&&fPlanesAltLists[k][ALG_WEST].size()){
05813                   found = true;
05814                   DeMuxSearchTactic tactic;
05815                   tactic.iplane = k;
05816                   tactic.searchType = SEARCH_GAP_B;
05817                   tactic.lowplane  = i;
05818                   tactic.highplane = j;
05819                   tactic.goodTactic = true;
05820                   fSearchTactics.push_back(tactic);
05821                   fSearched[k] = true;
05822                 }
05823               }
05824             }
05825           } 
05826         }       
05827       }
05828     }
05829   }
05830 
05831   if(ifirstU){
05832     DeMuxSearchTactic tactic;
05833     tactic.iplane = firstUplane;
05834     tactic.lowplane = firstUplane;
05835     tactic.highplane = firstUplane;
05836     tactic.searchType = SEARCH_BACKWARDS;
05837     tactic.goodTactic = false;
05838     fSearchTactics.push_back(tactic);
05839 
05840 
05841     tactic.iplane = lastUplane;
05842     tactic.lowplane = lastUplane;
05843     tactic.highplane = lastUplane;
05844     tactic.searchType = SEARCH_FORWARDS;
05845     tactic.goodTactic = false;
05846     fSearchTactics.push_back(tactic);
05847   }
05848 
05849   if(ifirstV){
05850     DeMuxSearchTactic tactic;
05851     tactic.iplane = firstVplane;
05852     tactic.lowplane = firstVplane;
05853     tactic.highplane = firstVplane;
05854     tactic.searchType = SEARCH_BACKWARDS;
05855     tactic.goodTactic = false;
05856     fSearchTactics.push_back(tactic);
05857 
05858     tactic.iplane = lastVplane;
05859     tactic.lowplane = lastVplane;
05860     tactic.highplane = lastVplane;
05861     tactic.searchType = SEARCH_FORWARDS;
05862     tactic.goodTactic = false;
05863     fSearchTactics.push_back(tactic);
05864   }
05865     
05866   return;
05867 }
05868 
05869 
05870 void AlgAltDeMuxBase::MakePlaneMap(DeMuxSearchTactic tactic)
05871 {
05872 
05873   Int_t i = tactic.iplane;
05874   Int_t j = tactic.lowplane;
05875   Int_t k = tactic.highplane;
05876 
05877   Float_t target;
05878   Int_t itarget;
05879   Int_t it;
05880 
05881 
05882   if(j<0&&j>-100)MSG("AltDeMux", Msg::kFatal) << "AlgAltDeMuxBase::MakePlaneMap lowplane out of range : " << j << endl;
05883   if(k>=MAX_NUMBER_OF_PLANES)MSG("AltDeMux", Msg::kFatal) << "AlgAltDeMuxBase::MakePlaneMap highplane out of range : " << k << endl;
05884 
05885   fTargetStrips.erase(fTargetStrips.begin(),fTargetStrips.end());
05886   if(fEventType==MULTIPLE_MUON)MakeMultipleTargets(i);
05887 
05888   bool useHoughSlope         = fUseHoughSlope;
05889   bool useFitSlopeTime       = fUseFitSlopeTime;
05890   bool useFitSlopeHits       = fUseFitSlopeHits;
05891   bool useInterpolation      = false;
05892   // bool useSafeExtrapolationF = false;
05893   // bool useSafeExtrapolationB = false;
05894   bool useExtrapolationF     = false;
05895   bool useExtrapolationB     = false;
05896   bool useSameStrip          = false;
05897   bool useLevelStripF        = false;
05898   bool useLevelStripB        = false;
05899 
05900 
05901   bool treatAsUNKNOWN        = false;
05902   if(fEventType==UNKNOWN)treatAsUNKNOWN = true;
05903   if(fEventType==SINGLE_MUON)useFitSlopeHits = true;
05904   if(fEventType==THROUGH_GOING_MUON)useFitSlopeHits = true;
05905   if(fEventType==STRAIGHT_THROUGH_GOING_MUON)useFitSlopeHits = true;
05906 
05907   if(fEventType==MULTIPLE_MUON){
05908     if( (fHoughStatus==true)&&(j>0||k>0))useHoughSlope = true;
05909     if( (fHoughStatus==false)||(j==0&&k==0))treatAsUNKNOWN = true;
05910   }
05911 
05912   if(treatAsUNKNOWN){
05913     useInterpolation  = true;
05914     if(tactic.searchType != SEARCH_FORWARDS && 
05915        tactic.searchType != SEARCH_GAP_F)useLevelStripB = fUseLevelStripB;
05916     if(tactic.searchType != SEARCH_BACKWARDS && 
05917        tactic.searchType != SEARCH_GAP_B)useLevelStripF = fUseLevelStripF;
05918     useExtrapolationF = fUseExtrapolationF;
05919     useExtrapolationB = fUseExtrapolationB;
05920     useSameStrip      = fUseSameStrip;
05921   }
05922 
05923   for(Int_t index = 0; index<3; index++){
05924     Float_t slopeU;
05925     Float_t slopeV;
05926     bool    useSlope = false;
05927     if(index==0){
05928       useSlope = useFitSlopeHits;
05929       if(!fFitQHitU.status)slopeU  = fFitHitU.a1;
05930       if(!fFitQHitV.status)slopeV  = fFitHitV.a1;
05931       if(fFitQHitU.status)slopeU  = fFitQHitU.a1;
05932       if(fFitQHitV.status)slopeV  = fFitQHitV.a1;
05933     }
05934     if(index==1){
05935       useSlope = useFitSlopeTime;
05936       slopeU  = fFitTimeU.a1;
05937       slopeV  = fFitTimeU.a1;
05938     }
05939     if(index==2){
05940       useSlope = useHoughSlope;
05941       slopeU  = fHoughSlopeU;
05942       slopeV  = fHoughSlopeV;
05943     }
05944 
05945     if(useSlope){
05946       if(j>0){
05947         for(int jj=1;jj<=fPlanePair[j];jj++){
05948           Int_t je = j;
05949           if(i>249&&j<249)je-=20;
05950           if(fUVMap[i]==PlaneView::kU)target = fHitMap[j][jj] + slopeU*(i-je);
05951           if(fUVMap[i]==PlaneView::kV)target = fHitMap[j][jj] + slopeV*(i-je);
05952           itarget = static_cast<int>(target);
05953           fTargetStrips.push_back(itarget);
05954         }
05955       }
05956       if(k>0 && k<MAX_NUMBER_OF_PLANES){
05957         for(int kk=1;kk<=fPlanePair[k];kk++){
05958           Int_t ke = k;
05959           if(i<249&&k>249)ke+=20;
05960           if(fUVMap[i]==PlaneView::kU)target = fHitMap[k][kk] + slopeU*(i-ke);
05961           if(fUVMap[i]==PlaneView::kV)target = fHitMap[k][kk] + slopeV*(i-ke);
05962           itarget = static_cast<int>(target);
05963           fTargetStrips.push_back(itarget);
05964         }
05965       }
05966     }
05967   }
05968 
05969   if(useSameStrip&&fPlanePair[i]>0){
05970     for(int ii=1;ii<=fPlanePair[i];ii++){
05971       itarget = fHitMap[i][ii];
05972       fTargetStrips.push_back(itarget);
05973     }
05974   }
05975 
05976   if(fPlanePair[i]==0){
05977     if(j>0 && useLevelStripB){
05978       for(int jj=1;jj<=fPlanePair[j];jj++){
05979         itarget = fHitMap[j][jj];
05980         fTargetStrips.push_back(itarget);
05981       }
05982     }
05983     if(k>0 && k<MAX_NUMBER_OF_PLANES  && useLevelStripF){
05984       for(int kk=1;kk<=fPlaneHit[k];kk++){
05985         itarget = fHitMap[k][kk];
05986         fTargetStrips.push_back(itarget);
05987       }
05988     }
05989   }
05990   
05991   
05992   if(j>0 && k>0 && k<MAX_NUMBER_OF_PLANES && useInterpolation){
05993     for(int jj=1;jj<=fPlanePair[j];jj++){
05994       if(fQHitMapE[j][jj]>fTrackingLowPECut && fQHitMapW[j][jj]>fTrackingLowPECut){
05995         for(int kk=1;kk<=fPlanePair[k];kk++){
05996           if(fQHitMapE[k][kk]>fTrackingLowPECut && fQHitMapW[k][kk]>fTrackingLowPECut){
05997             it =fHitMap[j][jj] + (fHitMap[k][kk]-fHitMap[j][jj])*(i-j)/(k-j);
05998             fTargetStrips.push_back(it);  
05999           }
06000         }
06001       }
06002     }
06003   }
06004 
06005   this->MakePlaneMap(i,true);
06006 
06007   return;
06008 }
06009 
06010 
06011 
06012 void AlgAltDeMuxBase::NewTactic(DeMuxSearchTactic oldTactic){
06013   
06014 
06015   bool foundh;
06016   bool foundl;
06017   bool found;
06018   DeMuxSearchTactic newTactic;
06019 
06020   switch(oldTactic.searchType){
06021   case SEARCH_GAP:
06022 
06023     break;
06024   case SEARCH_GAP_B:
06025     found = false;
06026     for(int i=oldTactic.iplane-2;i>=oldTactic.lowplane+2&&found==false;i-=2){
06027       if(!fSearched[i]&&fPlanesAltLists[i][ALG_EAST].size()&&fPlanesAltLists[i][ALG_WEST].size()){
06028         found = true;
06029         newTactic.iplane = i;
06030         newTactic.goodTactic = true;
06031         newTactic.lowplane = oldTactic.lowplane;
06032         if(fPlaneHit[oldTactic.iplane]>0){ 
06033           newTactic.highplane = oldTactic.iplane;
06034         }else{
06035           newTactic.highplane = oldTactic.highplane;
06036         }
06037         newTactic.searchType = SEARCH_GAP_B;
06038       }
06039     }
06040     if(found){
06041       fSearchTactics.push_back(newTactic);
06042       fSearched[newTactic.iplane] = true;
06043     }
06044     break;
06045   case SEARCH_GAP_F:
06046     found = false;
06047     for(int i=oldTactic.iplane+2;i<=oldTactic.highplane-2&&found==false;i+=2){
06048       if(!fSearched[i]&&fPlanesAltLists[i][ALG_EAST].size()&&fPlanesAltLists[i][ALG_WEST].size()){
06049         found = true;
06050         newTactic.iplane = i;
06051         newTactic.goodTactic = true;
06052         if(fPlaneHit[oldTactic.iplane]>0){ 
06053           newTactic.lowplane = oldTactic.iplane;
06054         }else{
06055           newTactic.lowplane = oldTactic.lowplane;
06056         }
06057         newTactic.highplane = oldTactic.highplane;
06058         newTactic.searchType = SEARCH_GAP_F;
06059       }
06060     }
06061     if(found){
06062       fSearchTactics.push_back(newTactic);
06063       fSearched[newTactic.iplane] = true;
06064     }
06065     break;
06066   case SEARCH_FORWARDS:
06067     foundh = false;
06068     foundl = false;
06069     if(oldTactic.goodTactic){
06070       for(int i=oldTactic.iplane+2;i<MAX_NUMBER_OF_PLANES-2&&foundh==false;i+=2){
06071         if(fPlanesAltLists[i][ALG_EAST].size()&&fPlanesAltLists[i][ALG_WEST].size()){
06072           foundh = true;
06073           newTactic.iplane = i;
06074           newTactic.goodTactic = true;
06075           newTactic.highplane = oldTactic.iplane;
06076           newTactic.lowplane = oldTactic.highplane;
06077           newTactic.searchType = SEARCH_FORWARDS;
06078         }
06079       }
06080     }else{
06081       for(int i=oldTactic.iplane+2;i<MAX_NUMBER_OF_PLANES-2&&foundh==false;i+=2){
06082         if(fPlanesAltLists[i][ALG_EAST].size()&&fPlanesAltLists[i][ALG_WEST].size()){
06083           foundh = true;
06084           newTactic.highplane = oldTactic.iplane;
06085           newTactic.iplane = i; 
06086           newTactic.goodTactic = true;
06087           newTactic.lowplane = -100;
06088           newTactic.searchType = SEARCH_FORWARDS;
06089         }
06090       }
06091       for(int i=oldTactic.iplane-2;i>oldTactic.iplane-12&&foundl==false;i-=2){
06092         if(fPlaneHit[i]>0){
06093           foundl = true;
06094           newTactic.lowplane = i;
06095         }
06096       }
06097     }
06098     if(foundh){
06099       fSearchTactics.push_back(newTactic);
06100     }
06101     break;
06102   case SEARCH_BACKWARDS:
06103     foundh = false;
06104     foundl = false;
06105     if(oldTactic.goodTactic){
06106       for(int i=oldTactic.iplane-2;i>0&&foundl==false;i-=2){
06107         if(fPlanesAltLists[i][ALG_EAST].size()&&fPlanesAltLists[i][ALG_WEST].size()){
06108           foundl = true;
06109           newTactic.iplane = i;
06110           newTactic.lowplane = oldTactic.iplane;
06111           newTactic.goodTactic = true;
06112           newTactic.highplane = oldTactic.lowplane;
06113           newTactic.searchType = SEARCH_BACKWARDS;
06114         }
06115       }
06116     }else{
06117       for(int i=oldTactic.iplane-2;i>0&&foundl==false;i-=2){
06118         if(fPlanesAltLists[i][ALG_EAST].size()&&fPlanesAltLists[i][ALG_WEST].size()){
06119           foundl = true;
06120           newTactic.lowplane = oldTactic.iplane;
06121           newTactic.iplane = i; 
06122           newTactic.goodTactic = true;
06123           newTactic.highplane = -100;
06124           newTactic.searchType = SEARCH_BACKWARDS;
06125         }
06126       }
06127       for(int i=oldTactic.iplane+2;i<oldTactic.iplane+12&&foundh==false;i+=2){
06128         if(fPlaneHit[i]>0){
06129           foundh = true;
06130           newTactic.highplane = i;
06131         }
06132       }
06133     }
06134     if(foundl){
06135       fSearchTactics.push_back(newTactic);
06136     }
06137     break;
06138   default:
06139     break;
06140   }
06141   
06142   return;
06143 } 
06144 
06145 void AlgAltDeMuxBase::MakeSearchTacticsX()
06146 {
06147 
06148   fSearchTactics.erase(fSearchTactics.begin(),fSearchTactics.end());
06149   bool found;
06150 
06151   for(int i=0; i<MAX_NUMBER_OF_PLANES; i++){
06152     if(fPlaneHit[i]>=0){
06153       if(fPlanesAltLists[i][ALG_EAST].size()&&fPlanesAltLists[i][ALG_WEST].size()){
06154         int j = -100;
06155         int k = -100;
06156         if(i>1){
06157           int jj = i-2;
06158           if(jj==248 || jj==249)jj--;
06159           found = false;
06160           while(found==false){
06161             if(fPlaneHit[jj]){
06162               j=jj;
06163               found = true;
06164             }
06165             jj-=2;
06166             if(jj==248 || jj==249)jj--;
06167             if(jj<0||jj<i-24)found =true;
06168           }
06169         }
06170         if(i<MAX_NUMBER_OF_PLANES-2){
06171           int kk = i+2;
06172           if(kk==249 || kk==250)kk++;
06173           found = false;
06174           while(found==false){
06175             if(fPlaneHit[kk]){
06176               k=kk;
06177               found = true;
06178             }
06179             kk+=2;
06180             if(kk==249 || kk==250)kk++;
06181             if(kk>MAX_NUMBER_OF_PLANES-2||kk>i+24)found =true;
06182           }
06183         }
06184         DeMuxSearchTactic tactic;
06185         tactic.iplane = i;
06186         tactic.searchType = SEARCH_GAP;
06187         tactic.lowplane  = j;
06188         tactic.highplane = k;
06189         tactic.goodTactic = true;
06190         fSearchTactics.push_back(tactic);
06191       }
06192     }
06193   }    
06194   return;
06195 }
06196 
06197 
06198 void AlgAltDeMuxBase::MakeSearchTacticsY()
06199 {
06200 
06201   fSearchTactics.erase(fSearchTactics.begin(),fSearchTactics.end());
06202   bool found;
06203 
06204   for(int i=0; i<MAX_NUMBER_OF_PLANES; i++){
06205     if(fPlanesAltLists[i][ALG_EAST].size()||fPlanesAltLists[i][ALG_WEST].size()){
06206       int j = -100;
06207       int k = -100;
06208       if(i>1){
06209         int jj = i-2;
06210         if(jj==248 || jj==249)jj--;
06211         found = false;
06212         while(found==false){
06213           if(fPlaneHit[jj]){
06214             j=jj;
06215             found = true;
06216           }
06217           jj-=2;
06218           if(jj==248 || jj==249)jj--;
06219           if(jj<0||jj<i-24
06220 
06221 )found =true;
06222         }
06223       }
06224       if(i<MAX_NUMBER_OF_PLANES-2){
06225         int kk = i+2;
06226         if(kk==249 || kk==250)kk++;
06227         found = false;
06228         while(found==false){
06229           if(fPlaneHit[kk]){
06230             k=kk;
06231             found = true;
06232           }
06233           kk+=2;
06234           if(kk==249 || kk==250)kk++;
06235           if(kk>MAX_NUMBER_OF_PLANES-2||kk&g