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

DmxDeMuxCosmicsModule.cxx

Go to the documentation of this file.
00001 
00002 //$Id: DmxDeMuxCosmicsModule.cxx,v 1.109 2005/03/26 21:41:48 gmieg Exp $
00003 //
00004 //DmxDeMuxCosmicsModule.cxx
00005 //
00006 //Module for demultiplexing cosmic ray events in the far detector
00007 //
00008 //Author:  B. Rebel 6/2001
00010 
00011 #include "DeMux/DmxDeMuxCosmicsModule.h"
00012 #include "DeMux/DmxChiSqrStat.h"
00013 #include "DeMux/DmxUtilities.h"
00014 #include "JobControl/JobCModuleRegistry.h"
00015 #include "JobControl/JobCommand.h"
00016 #include "MessageService/MsgService.h"
00017 #include "MinosObjectMap/MomNavigator.h"
00018 #include "Algorithm/AlgConfig.h"
00019 #include "CandDigit/CandDeMuxDigitListHandle.h"
00020 #include "CandDigit/CandDigitHandle.h"
00021 #include "CandDigit/CandDeMuxDigitHandle.h"
00022 #include "Algorithm/AlgFactory.h"
00023 #include "Algorithm/AlgHandle.h"
00024 #include "CandData/CandRecord.h"
00025 #include "CandData/CandHeader.h"
00026 #include "Candidate/CandContext.h"
00027 #include "Navigation/NavKey.h"
00028 #include "Navigation/NavSet.h"
00029 #include "Conventions/PlaneView.h"
00030 #include "CandTrackSR/CandTrackSR.h"
00031 #include "Navigation/XxxItr.h"
00032 #include "RecoBase/CandTrackHandle.h"
00033 #include "RecoBase/CandTrackListHandle.h"
00034 #include "DeMux/DmxShowerPlane.h"
00035 #include "DeMux/DmxMuonPlane.h"
00036 #include "DeMux/DmxPlane.h"
00037 #include "DeMux/DmxHypothesis.h"
00038 #include "TH1.h"
00039 #include "TH2.h"
00040 #include "TClonesArray.h"
00041 #include "RawData/RawRecord.h"
00042 #include "RawData/RawDaqSnarlHeader.h"
00043 #include "Validity/VldContext.h"
00044 #include "UgliGeometry/UgliGeomHandle.h"
00045 
00046 #include "TFolder.h"
00047 #include "TObjArray.h"
00048 #include "TROOT.h"
00049 
00050 #include <cassert>
00051 
00052 //define the NavKey to sort the digits by plane
00053 static NavKey KeyFromDigitPlane( const CandDeMuxDigitHandle *cdh){
00054   return cdh->GetPlexSEIdAltL().GetPlane();}
00055 
00056 //define the NavKey to sort the digits by plane
00057 static NavKey KeyFromDigitPlane( const CandDigitHandle *cdh){
00058   return cdh->GetPlexSEIdAltL().GetPlane();}
00059 
00060 //define the NavKey to sort the planes
00061 static NavKey KeyOnPlaneNumber( const TObject *tobj){
00062   const DmxPlane *currentPlane = dynamic_cast<const DmxPlane *>(tobj);
00063   return currentPlane->GetPlaneNumber();
00064 }
00065 
00066 ClassImp(DmxDeMuxCosmicsModule)
00067 
00068 CVSID("$Id: DmxDeMuxCosmicsModule.cxx,v 1.109 2005/03/26 21:41:48 gmieg Exp $");
00069 
00070 // Declare this module to JobControll. Arguments are:
00071 //  (1) The class name 
00072 //  (2) The human-readable name 
00073 //  (3) A short, human-readable description of what the module does
00074 JOBMODULE(DmxDeMuxCosmicsModule, 
00075           "DeMuxCosmicsModule",
00076           "A module used for demultiplexing cosmics in the far detector");
00077 
00078 //......................................................................
00079 DmxDeMuxCosmicsModule::DmxDeMuxCosmicsModule() :
00080   fAverageTimingOffset(-5.),
00081   fCrate(-1),
00082   fDataType(0),
00083   fDeMuxedStrip(-1),
00084   fDeMuxedStripW(-1),
00085   fDigitCharge(-1.),
00086   fDigitChargeW(-1.),
00087   fDigitDeMuxedCorrectly(0),
00088   fDigitsInEvent(0),
00089   fDigitSide(0),
00090   fDirection(0),
00091   fDontUseCandDigitMasks(false),
00092   fEndPlane(-1),
00093   fEventCharge(0.),
00094   fEventDeMuxed(0),
00095   fEventLength(false),
00096   fEventNumber(0),
00097   fFilter(false),
00098   fHistoFileName("demux_cosmics.root"),
00099   fHoughSlope(5.),
00100   fHoughIntercept(10.),
00101   fHoughPeak(0.66),
00102   fHypothesisCoG(-1.),
00103   fHypothesisMatedSignalRatio(-1.),
00104   fHypothesisNumber(-1),
00105   fHypothesisRank(-1),
00106   fHypothesisStat(-1.),
00107   fHypothesisTieBreaker(-1.),
00108   fHypothesisValid(-1),
00109   fMakeTrees(true),
00110   fMated(0),
00111   fMatedSignalForValid(0.5),
00112   fMCDigitChargeE(0.),
00113   fMCDigitChargeW(0.),
00114   fMCVertexPlane(0),
00115   fMCEndPlane(0),
00116   fMultiple(0),
00117   fNonPhysicalFailure(0),
00118   fNonPhysicalPlanes(0),
00119   fNoVertexFailure(0),
00120   fNumberOfPlanesInEvent(0),
00121   fOneSidedUPlanes(0),
00122   fOneSidedVPlanes(0),
00123   fPlane(-1),
00124   fPlaneDeMuxedCoG(-1.),
00125   fPlaneStray(0),
00126   fPlanesInWindow(6),
00127   fPlaneType(-1),
00128   fSignalFractionLimit(0.1),
00129   fSingleModuleDeMux(false),
00130   fSingleModuleCharge(-1.),
00131   fSingleModuleCorrectCharge(-1.),
00132   fSingleModuleDigits(-1.),
00133   fSingleModuleCorrectDigits(-1.),
00134   fStrayDeltaStripLimit(6),
00135   fStrip0(0),
00136   fStrip1(0),
00137   fStrip2(0),
00138   fStrip3(0),
00139   fStrip4(0),
00140   fStrip5(0),
00141   fStrip6(0),
00142   fStrip7(0),
00143   fTime(-1.),
00144   fTruthStripE(-1),
00145   fTruthStripW(-1),
00146   fUStrayPlanes(0),
00147   fUValidPlanes(0),
00148   fVStrayPlanes(0),
00149   fVValidPlanes(0),
00150   fXTalkDigit(1),
00151   fUnsetDigitCheck(false),
00152   fValidPlanesFailure(0),
00153   fVertexPlane(-1),
00154   fWriteHistos(false),
00155   fXTalkSignalRatio(-1.),
00156   fUseStrayPlaneCheck(false),
00157   fStrayPlanesLimit(4),
00158   fDeMuxFile(0),
00159   fDeMuxTree(0),
00160   fDeMuxedDigitTree(0),
00161   fDmxPlaneTree(0),
00162   fSingleModuleTree(0),
00163   fTrackDigitsTree(0),
00164   fUnusedDigitsTree(0),
00165   fMCDeMuxTree(0),
00166   fMCDeMuxDigitTree(0),
00167   fTFolder(0)
00168 {
00169  
00170   // Put DmxStatus object in /Loon/DeMux folder
00171   if (fTFolder==0) {
00172     TFolder *lf = dynamic_cast<TFolder *>
00173                          (gROOT->GetRootFolder()->FindObject("Loon"));
00174     if (lf==0) {
00175       lf = gROOT->GetRootFolder()->AddFolder("Loon", "Loon analysis");
00176       gROOT->GetListOfBrowsables()->Add(lf, "Loon");
00177     }
00178     fTFolder = lf->AddFolder("DeMux", "DeMux analysis");
00179     fTFolder->Add(&fStatus);
00180   }
00181 
00182    AlgFactory &af = AlgFactory::GetInstance();
00183    af.Register("AlgDeMuxCosmics", "default", "libDeMux.so", "AlgConfig");
00184    AlgHandle ah = af.GetAlgHandle("AlgDeMuxCosmics", "default");
00185 
00186    //get the AlgConfig class and set some variables for demuxing
00187    AlgConfig &acd = ah.GetAlgConfig();
00188    acd.UnLockValues();
00189    acd.Set("HoughInterceptRMSLimit",10.);
00190    acd.Set("HoughPeakLimit",0.60);
00191    acd.Set("HoughSlopeRMSLimit",10.);
00192    acd.Set("HypothesisSize",24);
00193    acd.Set("MuonTrackSlopeLimit",192.0);
00194    acd.Set("NumberOfHypotheses",169);
00195    acd.Set("NumberOfStrips", 192);
00196    acd.Set("PlanesInSet",fPlanesInWindow);
00197    acd.Set("RatioMatedSignalForValid",fMatedSignalForValid);
00198    acd.Set("UseCandDigitMask", 1);
00199    acd.Set("XTalkFractionLimit", 0.1);
00200    acd.Set("IgnoreSignalLimit", 1.5);
00201    if(fDataType == 1) acd.Set("AveragePEGainConversion", 60.);
00202    else acd.Set("AveragePEGainConversion", 60.);
00203    acd.Set("StrayDeltaStripLimit",fStrayDeltaStripLimit);
00204    acd.Set("StrayPlanesLimit",10);
00205    acd.Set("UseStrayPlaneCheck", 0);
00206    
00207    if(fUseStrayPlaneCheck){
00208      acd.Set("UseStrayPlaneCheck",(Int_t)fUseStrayPlaneCheck);
00209      //acd.SetStrayPlanesLimit(fStrayPlanesLimit);
00210    }
00211    
00212    if( fDontUseCandDigitMasks ){ acd.Set("UseCandDigitMask",0); }
00213    //MSG("DMX", Msg::kDebug) << fSignalFractionLimit << endl;
00214    if( fSignalFractionLimit > 0.){ acd.Set("XTalkFractionLimit",fSignalFractionLimit);}
00215    
00216    acd.LockValues();
00217    acd.LockKeys();
00218    
00219    MSG("JobC", Msg::kDebug) << "DmxDeMuxCosmicsModule::Constructor" << endl;
00220    //MSG("DMX", Msg::kDebug) << fSignalFractionLimit << endl;
00221    
00222 }
00223 
00224 //----------------------------------------------------------------------
00225 DmxDeMuxCosmicsModule::~DmxDeMuxCosmicsModule()
00226 {
00227   MSG("JobC", Msg::kDebug) << "DmxDeMuxCosmicsModule::Destructor" << endl;
00228   if(fDeMuxFile) delete fDeMuxFile;
00229 }
00230 
00231 //......................................................................
00232 
00233 void DmxDeMuxCosmicsModule::BeginJob()
00234 { 
00235 
00236   if(fMakeTrees && !fDeMuxFile){
00237     // save the current working directory
00238     TDirectory* savedir  = gDirectory;  
00239 
00240     //create the new TFile for demuxing
00241     // this changes the value of gDirectory
00242     fDeMuxFile = new TFile(fHistoFileName,"RECREATE");  
00243     
00244     // create TTree's, these will attach themselves to the current 
00245     //working directory (demux_cosmics.root)
00246    
00247     fDeMuxTree = new TTree("fDeMuxTree", "DeMux Info Tree");
00248     fDeMuxedDigitTree = new TTree("fDeMuxedDigitTree", "DeMuxed Digit Info");
00249     fDmxPlaneTree = new TTree("fDmxPlaneTree", "DeMux Plane Info");
00250     
00251     fDeMuxTree->Branch("Event", &fEventNumber, "fEventNumber/I"); 
00252     fDeMuxTree->Branch("DeMuxed", &fEventDeMuxed, "fEventDeMuxed/I");
00253     fDeMuxTree->Branch("Vertex", &fVertexPlane, "fVertexPlane/I");
00254     fDeMuxTree->Branch("VertexZ", &fVertexPlaneZ, "fVertexPlaneZ/F");
00255     fDeMuxTree->Branch("Direction", &fDirection, "fDirection/I");
00256     fDeMuxTree->Branch("End", &fEndPlane, "fEndPlane/I");
00257     fDeMuxTree->Branch("NumberOfPlanesHit", &fNumberOfPlanesInEvent, "fNumberOfPlanesInEvent/I");
00258     fDeMuxTree->Branch("EventCharge", &fEventCharge, "fEventCharge/F");
00259     fDeMuxTree->Branch("DigitsInEvent", &fDigitsInEvent, "fDigitsInEvent/I");
00260     fDeMuxTree->Branch("Multiple", &fMultiple, "fMultiple/I");
00261     fDeMuxTree->Branch("NonPhysicalPlanes", &fNonPhysicalPlanes, "fNonPhysicalPlanes/I");
00262     fDeMuxTree->Branch("ValidPlanesFailure", &fValidPlanesFailure, "fValidPlanesFailure/I");
00263     fDeMuxTree->Branch("NoVertexFailure", &fNoVertexFailure, "fNoVertexFailure/I");
00264     fDeMuxTree->Branch("NonPhysicalFailure", &fNonPhysicalFailure, "fNonPhysicalFailure/I");
00265     fDeMuxTree->Branch("OneSidedUPlanes", &fOneSidedUPlanes, "fOneSidedUPlanes/I");
00266     fDeMuxTree->Branch("OneSidedVPlanes", &fOneSidedVPlanes, "fOneSidedVPlanes/I");
00267     fDeMuxTree->Branch("SingleModuleCharge", &fSingleModuleCharge, "fSingleModuleCharge/F");
00268     fDeMuxTree->Branch("SingleModuleCorrectCharge", &fSingleModuleCorrectCharge, "fSingleModuleCorrectCharge/F");
00269     fDeMuxTree->Branch("SingleModuleDigits", &fSingleModuleDigits, "fSingleModuleDigits/F");
00270     fDeMuxTree->Branch("SingleModuleCorrectDigits", &fSingleModuleCorrectDigits, "fSingleModuleCorrectDigits/F");
00271     fDeMuxTree->Branch("UStrayPlanes", &fUStrayPlanes, "fUStrayPlanes/I");
00272     fDeMuxTree->Branch("VStrayPlanes", &fVStrayPlanes, "fVStrayPlanes/I");
00273     fDeMuxTree->Branch("UValidPlanes", &fUValidPlanes, "fUValidPlanes/I");
00274     fDeMuxTree->Branch("VValidPlanes", &fVValidPlanes, "fVValidPlanes/I");
00275     fDeMuxTree->Branch("UOverlappingMultiple", &fUOverlap, "fUOverlap/I");
00276     fDeMuxTree->Branch("VOverlappingMultiple", &fVOverlap, "fVOverlap/I");
00277     fDeMuxTree->Branch("AvTimingOffset", &fAverageTimingOffset, "fAverageTimingOffset/F");
00278     //fDeMuxTree->SetAutoSave(10000);
00279     
00280     fDeMuxedDigitTree->Branch("Event", &fEventNumber, "fEventNumber/I");
00281     fDeMuxedDigitTree->Branch("Plane", &fPlane, "fPlane/I");
00282     fDeMuxedDigitTree->Branch("Crate", &fCrate, "fCrate/I");
00283     fDeMuxedDigitTree->Branch("ADC", &fDigitCharge, "fDigitCharge/F");
00284     fDeMuxedDigitTree->Branch("Time", &fTime, "fTime/D");
00285     fDeMuxedDigitTree->Branch("Strip0", &fStrip0, "fStrip0/I");
00286     fDeMuxedDigitTree->Branch("Strip1", &fStrip1, "fStrip1/I");
00287     fDeMuxedDigitTree->Branch("Strip2", &fStrip2, "fStrip2/I");
00288     fDeMuxedDigitTree->Branch("Strip3", &fStrip3, "fStrip3/I");
00289     fDeMuxedDigitTree->Branch("Strip4", &fStrip4, "fStrip4/I");
00290     fDeMuxedDigitTree->Branch("Strip5", &fStrip5, "fStrip5/I");
00291     fDeMuxedDigitTree->Branch("Strip6", &fStrip6, "fStrip6/I");
00292     fDeMuxedDigitTree->Branch("Strip7", &fStrip7, "fStrip7/I");
00293     fDeMuxedDigitTree->Branch("DeMuxedStrip", &fDeMuxedStrip, "fDeMuxedStrip/I");
00294     fDeMuxedDigitTree->Branch("XTalkDigit", &fXTalkDigit, "fXTalkDigit/I");
00295     //fDeMuxedDigitTree->SetAutoSave(100000);
00296     
00297     fDmxPlaneTree->Branch("Event", &fEventNumber, "fEventNumber/I");
00298     fDmxPlaneTree->Branch("Plane", &fPlane, "fPlane/I");
00299     fDmxPlaneTree->Branch("PlaneZ", &fPlaneZ, "fPlaneZ/F");
00300     fDmxPlaneTree->Branch("PlaneType", &fPlaneType, "fPlaneType/I");
00301     fDmxPlaneTree->Branch("PlaneCoG", &fPlaneDeMuxedCoG, "fPlaneDeMuxedCoG/F");
00302     fDmxPlaneTree->Branch("Stray", &fPlaneStray, "fPlaneStray/I");
00303     fDmxPlaneTree->Branch("HypothesisCoG", &fHypothesisCoG, "fHypothesisCoG/F");
00304     fDmxPlaneTree->Branch("HypothesisCoGTPos", &fHypothesisCoGTPos, "fHypothesisCoGTPos/F");
00305     fDmxPlaneTree->Branch("Hypothesis", &fHypothesisNumber, "fHypothesisNumber/I");
00306     fDmxPlaneTree->Branch("MatedSignal", &fHypothesisMatedSignalRatio, "fHypothesisMatedSignalRatio/F");
00307     fDmxPlaneTree->Branch("Statistic", &fHypothesisStat, "fHypothesisStat/F");
00308     fDmxPlaneTree->Branch("TieBreaker", &fHypothesisTieBreaker, "fHypothesisTieBreaker/F");
00309     fDmxPlaneTree->Branch("Rank", &fHypothesisRank, "fHypothesisRank/I");
00310     fDmxPlaneTree->Branch("Valid", &fHypothesisValid, "fHypothesisValid/I");
00311     //fDmxPlaneTree->SetAutoSave(10000);
00312 
00313     fMCDeMuxDigitTree = new TTree("fMCDeMuxDigitTree", "MC DeMux Digit Tree");
00314     fMCDeMuxDigitTree->Branch("Event", &fEventNumber, "fEventNumber/I");
00315     fMCDeMuxDigitTree->Branch("TruthDigitChargeE", &fMCDigitChargeE, "fMCDigitChargeE/F");
00316     fMCDeMuxDigitTree->Branch("TruthDigitChargeW", &fMCDigitChargeW, "fMCDigitChargeW/F");
00317     fMCDeMuxDigitTree->Branch("DigitChargeE", &fDigitCharge, "fDigitCharge/F");
00318     fMCDeMuxDigitTree->Branch("DigitChargeW", &fDigitChargeW, "fDigitChargeW/F");
00319     fMCDeMuxDigitTree->Branch("Plane", &fPlane, "fPlane/I");
00320     fMCDeMuxDigitTree->Branch("Strip", &fDeMuxedStrip, "fDeMuxedStrip/I");
00321     fMCDeMuxDigitTree->Branch("MCStripSpread", &fMCStripSpread, "fMCStripSpread/I");
00322     //fMCDeMuxDigitTree->SetAutoSave(10000);
00323         
00324     fMCDeMuxTree = new TTree("fMCDeMuxTree", "MC DeMux Tree");
00325     fMCDeMuxTree->Branch("Event", &fEventNumber, "fEventNumber/I"); 
00326     fMCDeMuxTree->Branch("Vertex", &fMCVertexPlane, "fVertexPlane/I");
00327     fMCDeMuxTree->Branch("End", &fMCEndPlane, "fEndPlane/I");
00328     fMCDeMuxTree->Branch("ChargeCorrect", &fMCChargeCorrect, "fMCChargeCorrect/F");
00329     fMCDeMuxTree->Branch("ChargeCorrect1Hyp", &fMCChargeCorrect1Hyp, "fMCChargeCorrect1Hyp/F");
00330     fMCDeMuxTree->Branch("TotalCharge", &fMCTotalCharge, "fMCTotalCorrect/F");
00331     fMCDeMuxTree->Branch("TotalCharge1Hyp", &fMCTotalCharge1Hyp, "fMCTotalCharge1Hyp/F");
00332     fMCDeMuxTree->Branch("StripsCorrect", &fMCStripsCorrect, "fMCStripsCorrect/F");
00333     fMCDeMuxTree->Branch("StripSpread24Planes", &fMCStripSpread24Planes, "fMCStripSpread24Planes/I");
00334     fMCDeMuxTree->Branch("ShowerSpread", &fMCShowerSpread, "fMCShowerSpread/I");
00335     
00336     
00337     //fMCDeMuxTree->SetAutoSave(10000);
00338     
00339     // change back to current working directory before leaving constructor
00340     savedir->cd();   
00341   }
00342 
00343   //set up the TTrees for the various tests
00344   if( fSingleModuleDeMux && fMakeTrees){
00345     
00346     // save the current working directory
00347     TDirectory* savedir = gDirectory; 
00348     fDeMuxFile->cd();
00349 
00350     fSingleModuleTree = new TTree("fSingleModuleTree", "SingleModule Test Tree");
00351     fSingleModuleTree->Branch("Event", &fEventNumber, "fEventNumber/I"); 
00352     fSingleModuleTree->Branch("DigitCharge", &fDigitCharge, "fDigitCharge/F");
00353     fSingleModuleTree->Branch("XTalkSignalRatio", &fXTalkSignalRatio, "fXTalkSignalRatio/D");
00354     fSingleModuleTree->Branch("Strip", &fDeMuxedStrip, "fDeMuxedStrip/I");
00355     fSingleModuleTree->Branch("Mated", &fMated, "fMated/I");
00356     fSingleModuleTree->Branch("DigitDeMuxedCorrectly", &fDigitDeMuxedCorrectly, "fDigitDeMuxedCorrectly/I");
00357     
00358     // change back to current working directory
00359     savedir->cd(); 
00360   }
00361   if( fUnsetDigitCheck && fMakeTrees){
00362 
00363     // save the current working directory
00364     TDirectory* savedir = gDirectory; 
00365     fDeMuxFile->cd();
00366 
00367     fUnusedDigitsTree = new TTree("fUnusedDigitsTree", "UnsetDigitCheck Test Tree");
00368     fUnusedDigitsTree->Branch("Event", &fEventNumber, "fEventNumber/I"); 
00369     fUnusedDigitsTree->Branch("DigitCharge", &fDigitCharge, "fDigitCharge/F");
00370     fUnusedDigitsTree->Branch("XTalkSignalRatio", &fXTalkSignalRatio, "fXTalkSignalRatio/D");
00371     fUnusedDigitsTree->Branch("DigitSide", &fDigitSide, "fDigitSide/F");
00372     
00373     // change back to current working directory
00374     savedir->cd(); 
00375   }
00376   
00377   return;
00378 }
00379 
00380 //......................................................................
00381 
00382 JobCResult DmxDeMuxCosmicsModule::Reco(MomNavigator *mom)
00383 {
00384   JobCResult result(JobCResult::kPassed);
00385 
00386   //MSG("JobCDmx", Msg::kDebug) << "DeMuxCosmicsModule::Reco starting" << endl;
00387 
00388   // Check that mom exists.
00389   assert(mom);
00390 
00391   // Find PrimaryCandidateRecord fragment in MOM.
00392   CandRecord *candrec = dynamic_cast<CandRecord *>
00393     (mom->GetFragment("CandRecord", "PrimaryCandidateRecord"));
00394   if (candrec == 0) {
00395     result.SetError().SetFailed();
00396     return result;
00397   }
00398 
00399   //MSG("JobCDmx", Msg::kDebug) << "got cand record" << endl;
00400   //*-* Find Raw Data CandDeMuxDigitList fragment in PrimaryCandidateRecord.
00401   CandDeMuxDigitListHandle *crdlh = dynamic_cast<CandDeMuxDigitListHandle *>
00402     (candrec->FindCandHandle("CandDeMuxDigitListHandle", "canddigitlist"));
00403   if (crdlh == 0) {
00404     result.SetError().SetFailed();
00405     return result;
00406   }
00407     
00408   AlgFactory &af = AlgFactory::GetInstance();
00409   AlgHandle ah = af.GetAlgHandle("AlgDeMuxCosmics", "default");
00410   //AlgHandle ah = af.GetAlgHandle("AlgDeMuxGolden", "default");
00411     
00412   CandContext cx(this, mom);
00413   //cx.SetDataIn(status);
00414   
00415   //MSG("JobCDmx", Msg::kDebug) << "starting demux algorithm " << snarl << endl;
00416   ah.RunAlg(*crdlh, cx);
00417   //MSG("JobCDmx", Msg::kDebug) << "finished demux algorithm " << snarl << endl;
00418   
00419   
00420   //MSG("JobCDmx", Msg::kDebug) << "Event DeMuxed" << endl;
00421   
00422   return result;
00423 }
00424 
00425 //......................................................................
00426 //this method fills various histograms used to test the demuxing algorithm
00427 //efficiency
00428 
00429 JobCResult DmxDeMuxCosmicsModule::Ana(const MomNavigator *mom)
00430 {
00431   JobCResult result(JobCResult::kPassed);
00432   
00433   //MSG("JobCDmx", Msg::kDebug) << "DeMuxCosmicsModule::Ana" << endl;
00434 
00435   DmxStatus *status = dynamic_cast<DmxStatus *>(gROOT->GetRootFolder()->FindObject("Loon/DeMux/DmxStatus"));
00436   if (status == 0) {
00437     MSG("DMX", Msg::kWarning) << "//root/Loon/DeMux/DmxStatus not found." << endl;
00438     
00439     result.SetError().SetFailed();
00440     return result;
00441   }
00442   
00443   //if the event fails demuxing for any reason and filtering is turned on, 
00444   //dont pass the event on
00445   
00446   if(fFilter && fUseStrayPlaneCheck && (status->GetVOverlappingMultiple() || status->GetUOverlappingMultiple())){
00447     result.SetError().SetFailed();
00448     return result;
00449   }
00450   else if( !status->GetEventDeMuxed() && fFilter){
00451     result.SetError().SetFailed();
00452     return result;
00453   }
00454   
00455   //only do stuff in this method if you are making trees - otherwise there 
00456   //is no point to running the method.
00457   if( fMakeTrees ){
00458     
00459           DmxUtilities util;
00460 
00461           // Check that mom exists.
00462           assert(mom);
00463     
00464           // Find PrimaryCandidateRecord fragment in MOM.
00465           CandRecord *candrec = dynamic_cast<CandRecord *>
00466                   (mom->GetFragment("CandRecord", "PrimaryCandidateRecord"));
00467           if(candrec == 0){
00468                   result.SetError().SetFailed();
00469                   return result;
00470           }
00471     
00472     //Find Raw Data CandDeMuxDigitList fragment in PrimaryCandidateRecord.
00473     CandDeMuxDigitListHandle *crdlh = dynamic_cast<CandDeMuxDigitListHandle *>
00474       (candrec->FindCandHandle("CandDeMuxDigitListHandle", "canddigitlist"));
00475     
00476     // Check that crdlh exists.
00477     assert(crdlh);
00478         
00479         //check that there are digits present
00480         //MSG("DeMuxCosmics", Msg::kWarning) << crdlh->GetNDaughters() << " digits present at start of ana" << endl;
00481         
00482     
00483     //get an iterator over the digits and one extra for the single module test
00484     CandDeMuxDigitHandleItr crdhi(crdlh->GetDaughterIterator());
00485     CandDeMuxDigitHandleItr smcrdhi(crdlh->GetDaughterIterator());
00486 
00487     //create the KeyFunc
00488     CandDeMuxDigitHandleKeyFunc *planeKF = crdhi.CreateKeyFunc();
00489     CandDeMuxDigitHandleKeyFunc *smPlaneKF = smcrdhi.CreateKeyFunc();
00490     
00491     //program the KeyFunc with the sort function
00492     planeKF->SetFun(KeyFromDigitPlane);
00493     smPlaneKF->SetFun(KeyFromDigitPlane);
00494     
00495     //get the NavSet from the iterator and pass the KeyFunc to it
00496     crdhi.GetSet()->AdoptSortKeyFunc(planeKF);
00497     smcrdhi.GetSet()->AdoptSortKeyFunc(smPlaneKF);
00498     
00499     //clear the KF pointer because we no longer own the KeyFunc
00500     planeKF = 0;
00501     smPlaneKF = 0;
00502     
00503     crdhi.ResetFirst();
00504     smcrdhi.ResetFirst();
00505 
00506     //get the TObjArray of DmxPlane objects
00507     const TObjArray *planeArray = status->GetPlaneArray();
00508     
00509     //create a TObjectItr
00510     TObjectItr planeItr(planeArray);
00511     
00512     //create a KeyFunc to sort planes by number
00513     TObjectKeyFunc *pnKF = planeItr.CreateKeyFunc();
00514     
00515     //program the KeyFunc with the sort function
00516     pnKF->SetFun(KeyOnPlaneNumber);
00517     
00518     //get the NavSet from the iterator and pass the KeyFunc to it
00519     planeItr.GetSet()->AdoptSortKeyFunc(pnKF);
00520     
00521     //clear the KF pointer because we no longer own the KeyFunc
00522     pnKF = 0;
00523     
00524     fNonPhysicalPlanes = 0;
00525     fHypothesisCoG = -1.;
00526     fPlaneStray = 0;
00527     fPlaneDeMuxedCoG = -1.;
00528     fHypothesisNumber = -1;
00529     fHypothesisStat = -1.;
00530     fHypothesisTieBreaker = -1.;
00531     fHypothesisMatedSignalRatio = -1.;
00532     fHypothesisValid = -1;
00533     fPlaneType = -1;
00534     fCrate = -1;
00535     fPlane = -1;
00536     fDeMuxedStrip = -1;
00537     fOneSidedUPlanes = 0;
00538     fOneSidedVPlanes = 0;
00539     fSingleModuleCharge = -1.;
00540     fSingleModuleDigits = -1.;
00541     fSingleModuleCorrectCharge = -1.;
00542     fSingleModuleCorrectDigits = -1.;
00543     fEventCharge = 0.;
00544     fDigitsInEvent = 0;
00545     fDigitCharge = -1.;
00546     fXTalkSignalRatio = -1.;
00547     fDigitDeMuxedCorrectly = 0;
00548     fDigitSide = 0;
00549     //get generic info for event
00550     fEventNumber = status->GetEventNumber();
00551     fEventDeMuxed = (Int_t)status->GetEventDeMuxed();
00552     fValidPlanesFailure = (Int_t)status->GetValidPlanesFailure();
00553     fNoVertexFailure = (Int_t)status->GetVertexPlaneFailure();
00554     fNonPhysicalFailure = (Int_t)status->GetNonPhysicalFailure();
00555     fUOverlap = (Int_t)status->GetUOverlappingMultiple();
00556     fVOverlap = (Int_t)status->GetVOverlappingMultiple();
00557     fAverageTimingOffset = status->GetAverageTimingOffset();
00558     fUSlope = status->GetUTrackSlope();
00559     fUIntercept = status->GetUTrackIntercept();
00560     fUSlopeRMS = status->GetUSlopeRMS();
00561     fUStrayPlanes = status->GetUStrayPlanes();
00562     fUInterceptRMS = -1.;
00563     fUChiSq = status->GetUTrackChiSq();
00564     fVSlope = status->GetVTrackSlope();
00565     fVIntercept = status->GetVTrackIntercept();
00566     fVSlopeRMS = status->GetVSlopeRMS();
00567     fVStrayPlanes = status->GetVStrayPlanes();
00568     fVInterceptRMS = -1.;
00569     fVChiSq = status->GetVTrackChiSq();
00570     fUValidPlanes = 0;
00571     fVValidPlanes = 0;
00572   
00573     //zero values that need to start over with each event
00574     fVertexPlane = status->GetVertexPlaneNumber();
00575     fVertexPlaneZ = status->GetVertexZPosition();
00576     fDirection = status->GetEventDirection();
00577     fEndPlane = status->GetEndPlaneNumber();
00578     fMultiple = (Int_t)status->GetMultipleMuon();
00579     
00580     if(fMultiple == 0){planeItr.GetSet()->Slice(fVertexPlane, fEndPlane);}
00581     else if(fMultiple == 1){planeItr.GetSet()->Slice(fVertexPlane, 500);}
00582     
00583     //-----------------------------get plane info--------------------------//
00584     
00585     //get the total charge and digits in the event between vertex and end planes
00586     while( planeItr.IsValid() ){
00587       DmxPlane *currentPlane = dynamic_cast<DmxPlane *>(planeItr.Ptr());
00588       fEventCharge += currentPlane->GetPlaneCharge();
00589       fPlane = currentPlane->GetPlaneNumber();
00590       fPlaneZ = currentPlane->GetZPosition();
00591       fPlaneDeMuxedCoG = currentPlane->GetStripCoG(); 
00592       fPlaneStray = (Int_t)currentPlane->IsStray();
00593       if(currentPlane->GetPlaneView() == PlaneView::kU){
00594         if(currentPlane->IsValid()){ ++fUValidPlanes; }
00595       }
00596       else if(currentPlane->GetPlaneView() == PlaneView::kV){
00597         if(currentPlane->IsValid()){ ++fVValidPlanes; }
00598       }
00599       //if(fPlaneFitCoG > 192. || fPlaneFitCoG < 0.){ ++fNonPhysicalPlanes; }
00600       if(TMath::Abs(fPlaneDeMuxedCoG) > 4.){ ++fNonPhysicalPlanes; }
00601       
00602       crdhi.GetSet()->Slice(fPlane);
00603       
00604       //fill the DmxPlane tree
00605       if( currentPlane->IsValid() && currentPlane->GetPlaneType() == DmxPlaneTypes::kShower ){
00606         fPlaneType = 0;
00607         
00608         //loop over the best hypotheses to get their stats
00609         if(dynamic_cast<DmxShowerPlane *>(currentPlane)->GetBestHypothesis()){
00610           fHypothesisNumber = dynamic_cast<DmxShowerPlane *>(currentPlane)->GetBestHypothesis()->GetLowerBound();
00611           fHypothesisRank = 1;
00612           fHypothesisCoG = dynamic_cast<DmxShowerPlane *>(currentPlane)->GetBestHypothesis()->GetCoG();
00613           fHypothesisCoGTPos = dynamic_cast<DmxShowerPlane *>(currentPlane)->GetBestCoG();
00614           fHypothesisStat = dynamic_cast<DmxShowerPlane *>(currentPlane)->GetBestHypothesis()->GetStat();
00615           fHypothesisTieBreaker = dynamic_cast<DmxShowerPlane *>(currentPlane)->GetBestHypothesis()->GetTieBreakerStat();
00616           fHypothesisValid = (Int_t)dynamic_cast<DmxShowerPlane *>(currentPlane)->GetBestHypothesis()->IsValid();
00617           fHypothesisMatedSignalRatio = dynamic_cast<DmxShowerPlane *>(currentPlane)->GetBestHypothesis()->GetMatedSignalRatio();
00618 
00619           if(status->GetEventDeMuxed()){fDmxPlaneTree->Fill();}
00620 
00621         }
00622         if(dynamic_cast<DmxShowerPlane *>(currentPlane)->GetSecondBestHypothesis() ){
00623           fHypothesisNumber = dynamic_cast<DmxShowerPlane *>(currentPlane)->GetSecondBestHypothesis()->GetLowerBound();
00624           fHypothesisRank = 2;
00625           fHypothesisCoG = dynamic_cast<DmxShowerPlane *>(currentPlane)->GetSecondBestHypothesis()->GetCoG();
00626           fHypothesisCoGTPos = dynamic_cast<DmxShowerPlane *>(currentPlane)->GetSecondBestCoG();
00627           fHypothesisStat = dynamic_cast<DmxShowerPlane *>(currentPlane)->GetSecondBestHypothesis()->GetStat();
00628           fHypothesisTieBreaker = dynamic_cast<DmxShowerPlane *>(currentPlane)->GetSecondBestHypothesis()->GetTieBreakerStat();
00629           fHypothesisValid = (Int_t)dynamic_cast<DmxShowerPlane *>(currentPlane)->GetSecondBestHypothesis()->IsValid();
00630           fHypothesisMatedSignalRatio = dynamic_cast<DmxShowerPlane *>(currentPlane)->GetSecondBestHypothesis()->GetMatedSignalRatio();
00631           if(status->GetEventDeMuxed()){fDmxPlaneTree->Fill();}
00632 
00633         }
00634         if(dynamic_cast<DmxShowerPlane *>(currentPlane)->GetThirdBestHypothesis() ){
00635           fHypothesisNumber = dynamic_cast<DmxShowerPlane *>(currentPlane)->GetThirdBestHypothesis()->GetLowerBound();
00636           fHypothesisRank = 3;
00637           fHypothesisCoG = dynamic_cast<DmxShowerPlane *>(currentPlane)->GetThirdBestHypothesis()->GetCoG();
00638           fHypothesisCoGTPos = dynamic_cast<DmxShowerPlane *>(currentPlane)->GetThirdBestCoG();
00639           fHypothesisStat = dynamic_cast<DmxShowerPlane *>(currentPlane)->GetThirdBestHypothesis()->GetStat();
00640           fHypothesisTieBreaker = dynamic_cast<DmxShowerPlane *>(currentPlane)->GetThirdBestHypothesis()->GetTieBreakerStat();
00641           fHypothesisValid = (Int_t)dynamic_cast<DmxShowerPlane *>(currentPlane)->GetThirdBestHypothesis()->IsValid();
00642           fHypothesisMatedSignalRatio = dynamic_cast<DmxShowerPlane *>(currentPlane)->GetThirdBestHypothesis()->GetMatedSignalRatio();
00643           if(status->GetEventDeMuxed()){fDmxPlaneTree->Fill();}
00644         }
00645         
00646         //fDmxPlaneTree->Fill();
00647         fHypothesisStat = -1.;
00648         fHypothesisMatedSignalRatio = -1.;
00649         fHypothesisTieBreaker = -1.;
00650         fHypothesisRank = -1;
00651         fHypothesisValid = -1;
00652         fHypothesisCoG = -1.;
00653       }
00654       else if( currentPlane->IsValid() && currentPlane->GetPlaneType() == DmxPlaneTypes::kMuon ){
00655         fPlaneType = 1;
00656         if((Int_t)currentPlane->GetStripCoG() > 11){
00657           fHypothesisNumber = (Int_t)currentPlane->GetStripCoG() - 11;
00658         }
00659         else{ fHypothesisNumber = 0; }
00660         
00661         fHypothesisTieBreaker = -1;
00662         fHypothesisRank = 1;
00663         fHypothesisCoGTPos = dynamic_cast<DmxMuonPlane *>(currentPlane)->GetInitialCoG();
00664         fHypothesisCoG = dynamic_cast<DmxMuonPlane *>(currentPlane)->GetInitialStripCoG();
00665         fHypothesisMatedSignalRatio = 1.;
00666         fHypothesisValid = (Int_t)currentPlane->IsValid();
00667         if(status->GetEventDeMuxed()){
00668           fDmxPlaneTree->Fill();
00669           if ( fEventNumber%1000 == 0 ) {
00670             // save current working directory
00671             TDirectory* savedir = gDirectory; 
00672             // move to file directory of tree, oddly SaveSelf 
00673             //doesn't work without it
00674             fDeMuxFile->cd();
00675             // save tree to file  
00676             fDmxPlaneTree->AutoSave();
00677             // save file directory containing this tree
00678             fDeMuxFile->SaveSelf();
00679             // change back to working to directory
00680             savedir->cd();  
00681           }
00682         }
00683       }
00684       
00685       //-------------------get digit info----------------------------------//
00686       
00687       fDigitsInEvent += crdhi.SizeSelect();
00688       
00689       //loop over the digits to fill the demuxed digit info
00690       while( crdhi.IsValid() ){
00691         CandDeMuxDigitHandle *digit = crdhi.Ptr();
00692         fStrip0 = 0;
00693         fStrip1 = 0;
00694         fStrip2 = 0;
00695         fStrip3 = 0;
00696         fStrip4 = 0;
00697         fStrip5 = 0;
00698         fStrip6 = 0;
00699         fStrip7 = 0;
00700         fXTalkDigit = 1;
00701         fTime = digit->GetTime();
00702         //get the strip, charge, crate for the digit
00703         if(digit->GetPlexSEIdAltL().GetBestWeight() == 1.){
00704           fDeMuxedStrip = digit->GetPlexSEIdAltL().GetBestSEId().GetStrip();
00705         }
00706         else{ fDeMuxedStrip = -1;}
00707         
00708         //set the alternatives list to the first one
00709         digit->GetPlexSEIdAltL().SetFirst();
00710         
00711         //loop over the strip end alt list
00712         Int_t cnt = 0;
00713         while( digit->GetPlexSEIdAltL().IsValid() ){
00714           if(cnt == 0){ fStrip0 = digit->GetPlexSEIdAltL().GetCurrentSEId().GetStrip();}
00715           else if(cnt == 1){ fStrip1 = digit->GetPlexSEIdAltL().GetCurrentSEId().GetStrip();}
00716           else if(cnt == 2){ fStrip2 = digit->GetPlexSEIdAltL().GetCurrentSEId().GetStrip();}
00717           else if(cnt == 3){ fStrip3 = digit->GetPlexSEIdAltL().GetCurrentSEId().GetStrip();}
00718           else if(cnt == 4){ fStrip4 = digit->GetPlexSEIdAltL().GetCurrentSEId().GetStrip();}
00719           else if(cnt == 5){ fStrip5 = digit->GetPlexSEIdAltL().GetCurrentSEId().GetStrip();}
00720           else if(cnt == 6){ fStrip6 = digit->GetPlexSEIdAltL().GetCurrentSEId().GetStrip();}
00721           else if(cnt == 7){ fStrip7 = digit->GetPlexSEIdAltL().GetCurrentSEId().GetStrip();}
00722           ++cnt;
00723           digit->GetPlexSEIdAltL().Next();
00724         }
00725         
00726         
00727         fDigitCharge = digit->GetCharge();
00728         
00729         //MSG("DMX", Msg::kDebug) << status->GetEventNumber() << "\t" << fPlane << "\t" << fDigitCharge 
00730         //                   << "\t" << neighborSignal << "\t" << neighborSignal*fSignalFractionLimit 
00731         //           << "\t" << fSignalFractionLimit << endl;
00732         
00733         if( digit->GetDeMuxDigitFlagWord() == 0) fXTalkDigit = 0;
00734         
00735         fCrate = digit->GetChannelId().GetCrate();
00736         if(status->GetEventDeMuxed()){
00737           fDeMuxedDigitTree->Fill();
00738           if ( fEventNumber%1000 == 0 ) {
00739             TDirectory* savedir = gDirectory; // save current working directory
00740             fDeMuxFile->cd();  // move to file directory of tree, oddly SaveSelf doesn't work without it
00741             fDeMuxedDigitTree->AutoSave();  // save tree to file
00742             fDeMuxFile->SaveSelf();  // save file directory containing this tree
00743             savedir->cd();  // change back to working to directory
00744           }
00745         }
00746         crdhi.Next();
00747       }
00748       
00749       crdhi.GetSet()->Slice();
00750       crdhi.ResetFirst();
00751       
00752       planeItr.Next();
00753     }
00754     
00755     //if you arent using the cand digit masks to demux, then set them all to true
00756     //if(fDontUseCandDigitMasks){ crdhi.GetSet()->GetMasks().SetAllMasks(kTRUE); }
00757     
00758     planeItr.ResetFirst();
00759     planeItr.GetSet()->Slice();
00760 
00761     Int_t totalPlanes = planeItr.SizeSelect();
00762     fNumberOfPlanesInEvent = totalPlanes;
00763     
00764     //------------------start the efficiency tests----------------------------//
00765     
00766     if( fDataType == 0){
00767       if( fSingleModuleDeMux && status->GetEventDeMuxed() ){
00768         //get information about plane 10's shared tube 
00769         //to do some cross talk analysis later
00770         Float_t west10[16];
00771         Float_t east10[16];
00772         for(Int_t i = 0; i < 16; i++){
00773           west10[i] = 0.;
00774           east10[i] = 0.;
00775         }
00776         
00777         
00778         //slice the digit Itr to get plane 10
00779         crdhi.GetSet()->Slice(10);
00780         
00781         //fill the hit info
00782         util.FillHitPixels(crdhi, 2, east10, west10);
00783         
00784         //reset the itr
00785         crdhi.GetSet()->Slice();
00786         crdhi.ResetFirst();
00787         
00788         //slice digit Itr to get plane 12
00789         crdhi.GetSet()->Slice(12);
00790         crdhi.ResetFirst();
00791         smcrdhi.GetSet()->Slice(12);
00792         smcrdhi.ResetFirst();
00793 
00794         if(crdhi.SizeSelect()>0){
00795           fMated = 0;
00796           fSingleModuleCorrectCharge = 0.;
00797           fSingleModuleCorrectDigits = 0.;
00798           fSingleModuleCharge = 0.;
00799           fSingleModuleDigits = 0.;
00800         }
00801         
00802         //array to keep track of which pixels on which sides were hit for
00803         //the set digits//chip 2 can have xtalk from both planes 12 and 10, so put that into the signal ratio
00804         Float_t westSet1[16];
00805         Float_t eastSet1[16];
00806         Float_t westSet2[16];
00807         Float_t eastSet2[16];
00808         for(Int_t i = 0; i < 16; i++){
00809           westSet1[i] = 0.;
00810           eastSet1[i] = 0.;
00811           westSet2[i] = 0.;
00812           eastSet2[i] = 0.;
00813         }
00814         
00815         util.FillHitPixels(crdhi, 1, eastSet1, westSet1);
00816         util.FillHitPixels(crdhi, 2, eastSet2, westSet2);
00817         
00818         while( crdhi.IsValid() ){
00819           CandDeMuxDigitHandle *digit = crdhi.Ptr();
00820           
00821           //get the strip for the digit and check that it is within module 3 or module 6
00822           Int_t strip = digit->GetPlexSEIdAltL().GetBestSEId().GetStrip();
00823           fDigitCharge = digit->GetCharge()/55.;
00824           
00825           if( crdhi.Ptr()->GetPlexSEIdAltL().GetBestWeight() == 1. 
00826               && crdhi.Ptr()->GetPlexSEIdAltL().GetEnd() == StripEnd::kWest){
00827             
00828               fSingleModuleCharge += fDigitCharge;
00829               fSingleModuleDigits += 1.;
00830               fDeMuxedStrip = strip;
00831               
00832               bool mated = false;
00833               //loop over the smcrdhi to see if there is an east side digit from this strip
00834               smcrdhi.ResetFirst();
00835               while( smcrdhi.IsValid() ){
00836                 if(smcrdhi.Ptr()->GetPlexSEIdAltL().GetBestWeight() == 1. &&
00837                    smcrdhi.Ptr()->GetPlexSEIdAltL().GetBestSEId().GetStrip() == fDeMuxedStrip &&
00838                    smcrdhi.Ptr()->GetPlexSEIdAltL().GetEnd() == StripEnd::kEast)  mated = true;
00839                 smcrdhi.Next();
00840               }
00841               
00842               if( mated ) fMated = 1;
00843 
00844               Int_t chip = digit->GetChannelId().GetVaChip();
00845               Int_t channel = digit->GetChannelId().GetVaChannel();
00846               Int_t pixel = util.GetDigitPixel(channel);
00847               
00848               //get the ratio of this digits charge to the sum of its 4 nearest neighbors
00849               Float_t nearestNeighborSignal = -1.;
00850               if(chip == 1){nearestNeighborSignal = util.CheckForXTalk(pixel, westSet1);}
00851               if(chip == 2){nearestNeighborSignal = util.CheckForXTalk(pixel, westSet2) 
00852                               + util.CheckForXTalk(pixel, west10);}
00853               
00854               if(nearestNeighborSignal > 0.){fXTalkSignalRatio = fDigitCharge / (nearestNeighborSignal/55.);}
00855               
00856               //MSG("DMX12", Msg::kDebug)<< fDigitCharge << "\t" << nearestNeighborSignal/55. 
00857               //                  << "\t" << fXTalkSignalRatio << endl;
00858               
00859               
00860               if( strip >= 56 && strip <= 75 ){
00861                 fSingleModuleCorrectDigits += 1.;
00862                 fSingleModuleCorrectCharge += fDigitCharge;
00863                 fDigitDeMuxedCorrectly = 1;
00864               }
00865               else if( strip >= 116 && strip <= 135 ){
00866                 fSingleModuleCorrectDigits += 1.;
00867                 fSingleModuleCorrectCharge += fDigitCharge;
00868                 fDigitDeMuxedCorrectly = 1;
00869               }
00870               else{
00871                 fDigitDeMuxedCorrectly = 0;
00872                 //MSG("DMX", Msg::kDebug)<<"XTalkSignalRatio = " << fXTalkSignalRatio << "\tNearestNeighborsSignal = "
00873                 //              <<nearestNeighborSignal/55. << "\tDigitCharge = " << fDigitCharge << endl;
00874               } //end reconstructed in wrong module
00875               
00876               //MSG("DMX", Msg::kDebug)<<"SingleModuleCharge = " << fSingleModuleCharge 
00877               //                << "\tSingleModuleCorrectCharge = " <<fSingleModuleCorrectCharge 
00878               //                << "\tSingleModuleDigits = " << fSingleModuleDigits 
00879               //                << "\tSingleModuleCorrectDigits = " << fSingleModuleCorrectDigits 
00880               //                << endl;
00881               
00882               //fill the digit information in the tree
00883               fSingleModuleTree->Fill();
00884               if ( fEventNumber%1000 == 0 ) {
00885                 TDirectory* savedir = gDirectory; // save current working directory
00886                 fDeMuxFile->cd();  // move to file directory of tree, oddly SaveSelf doesn't work without it
00887                 fSingleModuleTree->AutoSave();  // save tree to file
00888                 fDeMuxFile->SaveSelf();  // save file directory containing this tree
00889                 savedir->cd();  // change back to working to directory
00890               }
00891               fXTalkSignalRatio = -1.;
00892               fMated = 0;
00893               fDigitDeMuxedCorrectly = 0;
00894             } //end if from west side and set
00895           crdhi.Next();
00896         } //end loop over digits
00897         
00898         crdhi.GetSet()->Slice();
00899         crdhi.ResetFirst();
00900         smcrdhi.GetSet()->Slice();
00901         smcrdhi.ResetFirst();
00902       }
00903       
00904       if( fUnsetDigitCheck && status->GetEventDeMuxed() ){
00905         
00906         //slice to get planes between the vertex and end
00907         planeItr.GetSet()->Slice(status->GetVertexPlaneNumber(), status->GetEndPlaneNumber());
00908         planeItr.ResetFirst();
00909         
00910         //loop over the planes and print their reconstructions
00911         while( planeItr.IsValid() ){
00912           DmxPlane *plane = dynamic_cast<DmxPlane *>(planeItr.Ptr());
00913           
00914           Int_t planeNumber = plane->GetPlaneNumber();
00915           
00916           //slice the digit iterator to the current plane
00917           crdhi.GetSet()->Slice(planeNumber);
00918           
00919           //array to keep track of which pixels on which planes were hit for
00920           //the set digits
00921           Float_t westSet0[16];
00922           Float_t eastSet0[16];
00923           Float_t westSet1[16];
00924           Float_t eastSet1[16];
00925           Float_t westSet2[16];
00926           Float_t eastSet2[16];
00927           for(Int_t i = 0; i < 16; i++){
00928             westSet0[i] = 0.;
00929             eastSet0[i] = 0.;
00930             westSet1[i] = 0.;
00931             eastSet1[i] = 0.;
00932             westSet2[i] = 0.;
00933             eastSet2[i] = 0.;
00934           }
00935           
00936           util.FillHitPixels(crdhi, 0, eastSet0, westSet0);
00937           crdhi.ResetFirst();
00938           util.FillHitPixels(crdhi, 1, eastSet1, westSet1);
00939           crdhi.ResetFirst();
00940           util.FillHitPixels(crdhi, 2, eastSet2, westSet2);
00941           
00942           crdhi.ResetFirst();
00943           
00944           //loop over the digits and see if they have been set
00945           while( crdhi.IsValid() ){
00946             
00947             //get the digit and it's strip, plane, and side
00948             CandDeMuxDigitHandle *digit = crdhi.Ptr();
00949             fDigitCharge = digit->GetCharge()/55.;
00950             
00951             Int_t chip = digit->GetChannelId().GetVaChip();
00952             Int_t pixel = util.GetDigitPixel(digit->GetChannelId().GetVaChannel());
00953             
00954             //see if the best weight is < 1.0 - if so, the digit had no strip chosen
00955             if(digit->GetPlexSEIdAltL().GetBestWeight() < 1.0){
00956               
00957               Float_t nearestNeighborSignal = -1.;
00958               if(digit->GetPlexSEIdAltL().GetEnd() == StripEnd::kEast){
00959                 if(chip == 0){nearestNeighborSignal = util.CheckForXTalk(pixel, eastSet0);}
00960                 if(chip == 1){nearestNeighborSignal = util.CheckForXTalk(pixel, eastSet1);}
00961                 if(chip == 2){nearestNeighborSignal = util.CheckForXTalk(pixel, eastSet2);}
00962                 fDigitSide = 0;
00963               }
00964               if(digit->GetPlexSEIdAltL().GetEnd() == StripEnd::kWest){
00965                 if(chip == 0){nearestNeighborSignal = util.CheckForXTalk(pixel, westSet0);}
00966                 if(chip == 1){nearestNeighborSignal = util.CheckForXTalk(pixel, westSet1);}
00967                 if(chip == 2){nearestNeighborSignal = util.CheckForXTalk(pixel, westSet2);}
00968                 fDigitSide = 1;
00969               }
00970               
00971               if(nearestNeighborSignal > 0.){fXTalkSignalRatio = fDigitCharge / (nearestNeighborSignal/55.);}
00972               
00973               fUnusedDigitsTree->Fill();
00974               if ( fEventNumber%1000 == 0 ) {
00975                 TDirectory* savedir = gDirectory; // save current working directory
00976                 fDeMuxFile->cd();  // move to file directory of tree, oddly SaveSelf doesn't work without it
00977                 fUnusedDigitsTree->AutoSave();  // save tree to file
00978                 fDeMuxFile->SaveSelf();  // save file directory containing this tree
00979                 savedir->cd();  // change back to working to directory
00980               }
00981 
00982               fXTalkSignalRatio = -1.;
00983             }
00984             crdhi.Next();
00985           }
00986           
00987           //clear the digit slice
00988           crdhi.GetSet()->Slice();
00989           planeItr.Next();
00990         }
00991         
00992         //reset the digit itr
00993         crdhi.GetSet()->Slice();
00994         crdhi.ResetFirst();
00995         
00996         //reset the planeItr
00997         planeItr.GetSet()->Slice();
00998         planeItr.ResetFirst();
00999         
01000       } //end UnsetDigitCheck test
01001       
01002       if( fEventLength ){
01003         
01004         if( status->GetValidPlanesFailure() ){ 
01005           //MSG("DmxDigit", Msg::kDebug) << "Event = " << status->GetEventNumber() << endl;
01006           
01007           while( planeItr.IsValid() ){
01008             
01009             crdhi.GetSet()->Slice(dynamic_cast<DmxPlane *>(planeItr.Ptr())->GetPlaneNumber());
01010             
01011             //declare variables to see if the digits from this plane come from each side
01012             Bool_t westDigits = false;
01013             Bool_t eastDigits = false;
01014             
01015             while( crdhi.IsValid() ){
01016               
01017               if(crdhi.Ptr()->GetPlexSEIdAltL().GetEnd() == StripEnd::kWest ){
01018                 //  MSG("DmxDigit", Msg::kDebug) << "\tPlane = " 
01019                 //                                        << dynamic_cast<DmxPlane *>(planeItr.Ptr())->GetPlaneNumber() 
01020                 //                                        << "\tSide = West\t" << "chip = " 
01021                 //                                        << crdhi.Ptr()->GetChannelId().GetVaChip()
01022                 //                                        << "\tpixel = " 
01023                 //                                        << status->GetDigitPixel(crdhi.Ptr()->GetChannelId().GetVaChannel()) 
01024                 //                                        << "\tcharge = " << crdhi.Ptr()->GetCharge() << endl;
01025                 westDigits = true;
01026               }
01027               if(crdhi.Ptr()->GetPlexSEIdAltL().GetEnd() == StripEnd::kEast ){
01028                 //  MSG("DmxDigit", Msg::kDebug) << "\tPlane = " 
01029                 //                                        << dynamic_cast<DmxPlane *>(planeItr.Ptr())->GetPlaneNumber() 
01030                 //                                        << "\tSide = East\t" << "chip = " 
01031                 //                                        << crdhi.Ptr()->GetChannelId().GetVaChip()
01032                 //                                        << "\tpixel = " 
01033                 //                                        << status->GetDigitPixel(crdhi.Ptr()->GetChannelId().GetVaChannel()) 
01034                 //                                        << "\tcharge = " << crdhi.Ptr()->GetCharge() << endl;
01035                 eastDigits = true;
01036               }
01037               crdhi.Next();
01038               
01039             } //end loop over digits
01040             
01041             crdhi.GetSet()->Slice();
01042             crdhi.ResetFirst();
01043             
01044             
01045             if( dynamic_cast<DmxPlane *>(planeItr.Ptr())->GetPlaneView() == PlaneView::kU){
01046               if( !westDigits || !eastDigits){ fOneSidedUPlanes += 1; }
01047             }
01048             if( dynamic_cast<DmxPlane *>(planeItr.Ptr())->GetPlaneView() == PlaneView::kV){
01049               if( !westDigits || !eastDigits){ fOneSidedVPlanes += 1; }
01050             }
01051             planeItr.Next();
01052             
01053           } //end loop over planes
01054           
01055           planeItr.ResetFirst();
01056           
01057         }//end valid plane failure
01058         else if( status->GetVertexPlaneFailure() ){ 
01059           if( fNumberOfPlanesInEvent > 3 ){
01060             //MSG("DmxVertex", Msg::kDebug) << "Event = " << status->GetEventNumber() << endl;
01061             
01062             bool westSide = false;
01063             bool eastSide = false;
01064             
01065             while( planeItr.IsValid() ){
01066               
01067               crdhi.GetSet()->Slice(dynamic_cast<DmxPlane *>(planeItr.Ptr())->GetPlaneNumber());
01068               
01069               while( crdhi.IsValid() ){
01070                 
01071                 if(crdhi.Ptr()->GetPlexSEIdAltL().GetEnd() == StripEnd::kWest ){
01072                   //  MSG("DmxVertex", Msg::kDebug) << "\tPlane = " 
01073                   //                                         << dynamic_cast<DmxPlane *>(planeItr.Ptr())->GetPlaneNumber() 
01074                   //                                         << "\tIsValid = "
01075                   //                                         << (Int_t)dynamic_cast<DmxPlane *>(planeItr.Ptr())->IsValid() 
01076                   //                                         << "\tSide = West\t" << "chip = " 
01077                   //                                         << crdhi.Ptr()->GetChannelId().GetVaChip()
01078                   //                                         << "\tpixel = " 
01079                   //                                         << status->GetDigitPixel(crdhi.Ptr()->GetChannelId().GetVaChannel()) 
01080                   //                                         << "\tcharge = " << crdhi.Ptr()->GetCharge() << endl;
01081                   westSide = true;
01082                 }
01083                 if(crdhi.Ptr()->GetPlexSEIdAltL().GetEnd() == StripEnd::kEast ){
01084                   //  MSG("DmxVertex", Msg::kDebug) << "\tPlane = " 
01085                   //                                         << dynamic_cast<DmxPlane *>(planeItr.Ptr())->GetPlaneNumber() 
01086                   //                                         << "\tIsValid = "
01087                   //                                         << (Int_t)dynamic_cast<DmxPlane *>(planeItr.Ptr())->IsValid() 
01088                   //                                         << "\tSide = East\t" << "chip = " 
01089                   //                                         << crdhi.Ptr()->GetChannelId().GetVaChip()
01090                   //                                         << "\tpixel = " 
01091                   //                                         << status->GetDigitPixel(crdhi.Ptr()->GetChannelId().GetVaChannel()) 
01092                   //                                         << "\tcharge = " << crdhi.Ptr()->GetCharge() << endl;
01093                   eastSide = true;
01094                 }
01095                 crdhi.Next();
01096                 
01097               } //end loop over digits
01098               
01099               crdhi.GetSet()->Slice();
01100               crdhi.ResetFirst();
01101               
01102               planeItr.Next();
01103               
01104             } //end loop over planes
01105             
01106             planeItr.ResetFirst();
01107           } //if more than 10 planes
01108           
01109         }// end vertex plane failure
01110       }// end if EventLength test
01111       
01112                 //Find Raw Data CandDeMuxDigitList fragment in PrimaryCandidateRecord.
01113                 CandDeMuxDigitListHandle *crdlh1 = dynamic_cast<CandDeMuxDigitListHandle *>
01114                 (candrec->FindCandHandle("CandDeMuxDigitListHandle", "canddigitlist"));
01115                 
01116                 // Check that crdlh exists.
01117                 assert(crdlh1);
01118                 
01119                 //check that there are digits present
01120                 //MSG("DeMuxCosmics", Msg::kWarning) << crdlh1->GetNDaughters() << " digits present at end of real data" << endl;
01121                 
01122                 
01123                 
01124     } //end if FarDetector data
01125     
01126     else if( fDataType == 1 ){
01127 
01128       //MSG("Dmx", Msg::kDebug) << "event " << fEventNumber << endl;
01129       //*-* Find Raw Data CandDigitList fragment in PrimaryCandidateRecord.
01130       CandDigitListHandle *cmdlh = dynamic_cast<CandDigitListHandle *>
01131         (candrec->FindCandHandle("CandDigitListHandle", "candmcdigitlist"));
01132       
01133       // Check that cmdlh exists.
01134       assert(cmdlh);
01135       
01136       // Get CandDigitHandleItr over MC Truth digits.
01137       CandDigitHandleItr cmdhi(cmdlh->GetDaughterIterator());
01138        
01139       //create the KeyFunc
01140       CandDigitHandleKeyFunc *mcplaneKF = cmdhi.CreateKeyFunc();
01141       
01142       //program the KeyFunc with the sort function
01143       mcplaneKF->SetFun(KeyFromDigitPlane);
01144             
01145       //get the NavSet from the iterator and pass the KeyFunc to it
01146       cmdhi.GetSet()->AdoptSortKeyFunc(mcplaneKF);
01147       
01148       //clear the KF pointer because we no longer own the KeyFunc
01149       mcplaneKF = 0;
01150        
01151       //reset the mc and raw digit iterators
01152       cmdhi.ResetFirst();
01153       crdhi.ResetFirst();
01154       
01155       //reset the plane iterator
01156       planeItr.ResetFirst();
01157       
01158 
01159       //make arrays to hold the strip hit information
01160       Float_t reconStripsW[192], reconStripsE[192], mcStripsW[192], mcStripsE[192];
01161       Float_t chargeCorrect = 0., stripsCorrect = 0.;
01162       Float_t totalCharge = 0., totalStrips = 0.;
01163       Float_t totalCharge1Hyp = 0.;//, chargeCorrect1Hyp = 0.;
01164       Float_t mcCoG = 0.;
01165       Float_t mcNum = 0.;
01166       Float_t mcDeNom = 0.;
01167       Int_t firstStrip = 0;
01168       Int_t lastStrip = 0;
01169       fMCStripSpread24Planes = 0;
01170       fMCShowerSpread = 0;
01171       Int_t lowShowerStrip = 192;
01172       Int_t highShowerStrip = -1;
01173       //loop over the planes in the event
01174       while( planeItr.IsValid() ){
01175         DmxPlane *currentPlane = dynamic_cast<DmxPlane *>(planeItr.Ptr());
01176         fPlane = currentPlane->GetPlaneNumber();
01177         mcNum = 0.;
01178         mcDeNom = 0.;
01179         mcCoG = 0.;
01180         firstStrip = 0;
01181         lastStrip = 0;
01182 
01183         //MSG("Dmx", Msg::kDebug) << "event " << fEventNumber << "plane " << fPlane << endl;
01184         //-------------------get digit info----------------------------------//
01185         //zero the arrays
01186         for(Int_t i = 0; i < 192; i++){
01187           reconStripsW[i] = 0;
01188           mcStripsW[i] = 0;
01189           reconStripsE[i] = 0;
01190           mcStripsE[i] = 0;
01191         }
01192       
01193         //slice for the digits in this plane
01194         crdhi.GetSet()->Slice(fPlane);
01195         cmdhi.GetSet()->Slice(fPlane);
01196         
01197         //loop over the digits to fill the demuxed digit info
01198         while( crdhi.IsValid() ){
01199           CandDeMuxDigitHandle *digit = crdhi.Ptr();
01200           //get the strip, charge, crate for the digit
01201           if(digit->GetPlexSEIdAltL().GetEnd() == StripEnd::kWest){
01202             reconStripsW[digit->GetPlexSEIdAltL().GetBestSEId().GetStrip()] += digit->GetCharge();
01203           }
01204           else if(digit->GetPlexSEIdAltL().GetEnd() == StripEnd::kEast){
01205             reconStripsE[digit->GetPlexSEIdAltL().GetBestSEId().GetStrip()] += digit->GetCharge();
01206           }
01207           
01208           crdhi.Next();
01209         }
01210 
01211         //now for the mc digits
01212         while( cmdhi.IsValid() ){
01213           CandDigitHandle *digit = cmdhi.Ptr();
01214           //get the strip, charge, crate for the digit
01215           if(digit->GetPlexSEIdAltL().GetEnd() == StripEnd::kWest){
01216             mcStripsW[digit->GetPlexSEIdAltL().GetBestSEId().GetStrip()] += digit->GetCharge();
01217           }
01218           else if(digit->GetPlexSEIdAltL().GetEnd() == StripEnd::kEast){
01219             mcStripsE[digit->GetPlexSEIdAltL().GetBestSEId().GetStrip()] += digit->GetCharge();
01220           }
01221           mcNum += digit->GetCharge() * digit->GetPlexSEIdAltL().GetBestSEId().GetStrip();
01222           mcDeNom += digit->GetCharge();
01223           
01224           cmdhi.Next();
01225         }
01226 
01227         if(mcDeNom > 0.) mcCoG = mcNum/mcDeNom;
01228 
01229         crdhi.GetSet()->Slice();
01230         crdhi.ResetFirst();
01231         cmdhi.GetSet()->Slice();
01232         cmdhi.ResetFirst();
01233         
01234         for(Int_t ss = 0; ss<192; ss++){
01235           if(mcStripsE[ss]>0. && firstStrip == 0) firstStrip = ss;
01236           else if(mcStripsW[ss]>0. && firstStrip == 0) firstStrip = ss;
01237           if(mcStripsE[ss]>0. || mcStripsW[ss]>0.) lastStrip = ss;
01238 
01239           //fill variables to check and see if the shower extends more than a meter in the detector
01240           if(currentPlane->GetPlaneType()==DmxPlaneTypes::kShower && (mcStripsE[ss]>0.||mcStripsW[ss]>0.)){
01241             if(ss>highShowerStrip) highShowerStrip = ss;
01242             if(ss<lowShowerStrip) lowShowerStrip = ss;
01243           }
01244         }
01245 
01246         fMCStripSpread = lastStrip - firstStrip;
01247 
01248         for(Int_t s = 0; s<192; s++){
01249           fDeMuxedStrip = s;
01250           fDigitCharge = -1.;
01251           fMCDigitChargeE = -1.;
01252           fDigitChargeW = -1.;
01253           fMCDigitChargeW = -1.;
01254           fDigitSide = -1;
01255 
01256           if(mcStripsE[s] != 0.){
01257             fMCDigitChargeE = mcStripsE[s];
01258             totalCharge += mcStripsE[s];
01259             totalStrips += 1.;
01260             if(TMath::Abs(mcCoG-s)<=23) totalCharge1Hyp += mcStripsE[s];
01261           }
01262           if(mcStripsW[s] != 0.){
01263             fMCDigitChargeW = mcStripsW[s];
01264             totalCharge += mcStripsW[s];
01265             totalStrips += 1.;
01266             if(TMath::Abs(mcCoG-s)<=23) totalCharge1Hyp += mcStripsW[s];
01267           }
01268           if(reconStripsE[s] != 0.) fDigitCharge = reconStripsE[s];
01269           if(reconStripsW[s] != 0.) fDigitChargeW = reconStripsW[s];
01270             
01271 
01272           if(reconStripsW[s] == mcStripsW[s] && reconStripsW[s] != 0.){
01273             chargeCorrect += mcStripsW[s];
01274             //if(TMath::Abs(mcCoG-s)<=23) chargeCorrect1Hyp += reconStripsW[s];
01275           }
01276           if(reconStripsE[s] == mcStripsE[s] && reconStripsE[s] != 0.){
01277             chargeCorrect += mcStripsE[s];
01278             //if(TMath::Abs(mcCoG-s)<=23) chargeCorrect1Hyp += reconStripsE[s];
01279           }
01280           if((reconStripsE[s] == mcStripsE[s]) && (reconStripsW[s] == mcStripsW[s])) stripsCorrect += 1.;
01281          
01282           
01283           fMCDeMuxDigitTree->Fill();
01284           if ( fEventNumber%1000 == 0 ) {
01285             TDirectory* savedir = gDirectory; // save current working directory
01286             fDeMuxFile->cd();  // move to file directory of tree, oddly SaveSelf doesn't work without it
01287             fMCDeMuxDigitTree->AutoSave();  // save tree to file
01288             fDeMuxFile->SaveSelf();  // save file directory containing this tree
01289             savedir->cd();  // change back to working to directory
01290           }
01291 
01292         }//end loop to fill digit tree
01293 
01294         if(fMCStripSpread>23) ++fMCStripSpread24Planes;
01295              
01296         planeItr.Next();
01297       } //end loop over planes in event
01298       
01299       fMCChargeCorrect = -1.;
01300       fMCChargeCorrect1Hyp = -1.;
01301       fMCStripsCorrect = -1.;
01302      
01303       if(totalCharge != 0.){
01304         fMCChargeCorrect = chargeCorrect/totalCharge;
01305         fMCTotalCharge = totalCharge;
01306       }
01307       if(totalCharge1Hyp != 0.){
01308         fMCChargeCorrect1Hyp = chargeCorrect/totalCharge1Hyp;
01309         fMCTotalCharge1Hyp = totalCharge1Hyp;
01310       }
01311       if(totalStrips != 0.) fMCStripsCorrect = stripsCorrect/totalStrips;
01312       fMCShowerSpread = highShowerStrip-lowShowerStrip;
01313 
01314       //cout << "filling mc demux tree" << endl;
01315       fMCDeMuxTree->Fill();
01316       if ( fEventNumber%1000 == 0 ) {
01317         TDirectory* savedir = gDirectory; // save current working directory
01318         fDeMuxFile->cd();  // move to file directory of tree, oddly SaveSelf doesn't work without it
01319         fMCDeMuxTree->AutoSave();  // save tree to file
01320         fDeMuxFile->SaveSelf();  // save file directory containing this tree
01321         savedir->cd();  // change back to working to directory
01322       }
01323 
01324     } //end if MonteCarlo data
01325     
01326     //fill the DeMux info Tree
01327 
01328     fDeMuxTree->Fill();
01329     if ( fEventNumber%1000 == 0 ) {
01330       TDirectory* savedir = gDirectory; // save current working directory
01331       fDeMuxFile->cd();  // move to file directory of tree, oddly SaveSelf doesn't work without it
01332       fDeMuxTree->AutoSave();  // save tree to file
01333       fDeMuxFile->SaveSelf();  // save file directory containing this tree
01334       savedir->cd();  // change back to working to directory
01335     }
01336 
01337   }
01338   //MSG("JobCDmx", Msg::kDebug) << "finished ana" << endl;
01339   
01340   // Find PrimaryCandidateRecord fragment in MOM.
01341   CandRecord *candrec = dynamic_cast<CandRecord *>
01342           (mom->GetFragment("CandRecord", "PrimaryCandidateRecord"));
01343   if(candrec == 0){
01344           result.SetError().SetFailed();
01345           return result;
01346   }
01347   
01348   
01349   //Find Raw Data CandDeMuxDigitList fragment in PrimaryCandidateRecord.
01350   CandDeMuxDigitListHandle *crdlh = dynamic_cast<CandDeMuxDigitListHandle *>
01351       (candrec->FindCandHandle("CandDeMuxDigitListHandle", "canddigitlist"));
01352   
01353   // Check that crdlh exists.
01354   assert(crdlh);
01355   
01356   //check that there are digits present
01357   //MSG("DeMuxCosmics", Msg::kWarning) << crdlh->GetNDaughters() << " digits present at end of ana" << endl;
01358   
01359   return result;
01360 }
01361 
01362 //......................................................................
01363 
01364 void DmxDeMuxCosmicsModule::HandleCommand(JobCommand *command) 
01365 {
01366   //
01367   //  Purpose:  Method to interpret module commands.
01368   //
01369   //  Arguments:
01370   //    command   in    Command to interpret.
01371   //
01372   //  Return:   n/a
01373   //
01374   //  Commands implemented:
01375   //    Set TestToMake  Set the test to make to obtain a figure of merit - fraction of
01376   //                    digits within n strips from a track, fraction of mated signal
01377   //                    DigitsAlongTrack, and MatedSignalFraction respectively
01378   //    Set DataType    Set the type of data to test - MonteCarlo or FarDetector
01379   //    Set MatedSignalLimit  Set the lower limit for fraction of signal coming from opposite
01380   //                          sides of the same strip in a plane.
01381   //    Set DeltaStripsFromTrack  Set the number of strips a digit can be off from a track and
01382   //                              still be considered along that track.
01383   //
01384   //  see http://beaker.astro.indiana.edu/brebel/demux_notes/how_to_demux.html for details
01385    MSG("JobC", Msg::kDebug) << "DeMuxCosmicsModule::HandleCommand" << endl;
01386 
01387    TString cmd = command->PopCmd();
01388    if(cmd == "Set"){   
01389      TString opt = command->PopOpt();
01390      if(opt == "DataType"){ fDataType = command->PopIntOpt();}
01391      else if(opt == "TestToMake"){ 
01392        TString testopt = command->PopOpt();
01393        if(testopt == "SingleModuleDeMux"){ fSingleModuleDeMux = true;}
01394        if(testopt == "EventLength"){ fEventLength = true;}
01395        if(testopt == "UnsetDigitCheck"){ fUnsetDigitCheck = true;}
01396      }
01397      else if(opt == "UseStrayPlanesCheck"){ fUseStrayPlaneCheck = true;}
01398      else if(opt == "DontUseCandDigitMasks"){ fDontUseCandDigitMasks = true;}
01399      else if(opt == "WriteHistos"){ fWriteHistos = true;}
01400      else if(opt == "DontMakeTrees"){ fMakeTrees = false;}
01401      else if(opt == "WindowSize"){ fPlanesInWindow = command->PopIntOpt();}
01402      else if(opt == "StrayDeltaStripLimit"){ fStrayDeltaStripLimit = command->PopIntOpt();}
01403      else if(opt == "StrayPlanesLimit"){ fStrayPlanesLimit = command->PopIntOpt();}
01404      else if(opt == "Filter"){ cout << fFilter << endl; fFilter = 1;}
01405      else if(opt == "HistoFileName"){ fHistoFileName = command->PopOpt();}
01406      else {
01407          MSG("JobC", Msg::kWarning)<< "DeMuxCosmicsModule: Unrecognized option " << opt << endl;
01408       }
01409    }
01410    else {
01411      MSG("JobC", Msg::kWarning)<< "DeMuxCosmicsModule: Unrecognized command " << cmd << endl;
01412    }
01413    return;
01414 }
01415 
01416 //......................................................................
01417 
01418 const Registry& DmxDeMuxCosmicsModule::DefaultConfig() const
01419 {
01420   //  Commands implemented:
01421   //    Set TestToMake  Set the test to make to obtain a figure of merit - fraction of
01422   //                    digits within n strips from a track, fraction of mated signal
01423   //                    DigitsAlongTrack, and MatedSignalFraction respectively
01424   //    Set DataType    Set the type of data to test - MonteCarlo or FarDetector
01425   //    Set MatedSignalLimit  Set the lower limit for fraction of signal coming from opposite
01426   //                          sides of the same strip in a plane.
01427   //    Set DeltaStripsFromTrack  Set the number of strips a digit can be off from a track and
01428   //                              still be considered along that track.
01429   //
01430   //  see http://beaker.astro.indiana.edu/brebel/demux_notes/how_to_demux.html for details
01431    int itrue = 1;  // work around for lack of bool in registry
01432    int ifalse = 0; // work around for lack of bool in registry
01433 
01434    MSG("JobC", Msg::kDebug) << "DeMuxCosmicsModule::DefaultConfig" << endl;
01435 
01436    static Registry r;
01437  
01438    r.UnLockValues();
01439 
01440    r.Set("SingleModuleDeMux",ifalse);
01441    r.Set("EventLength",      ifalse);
01442    r.Set("UnsetDigitCheck",  ifalse);
01443    r.Set("DataType",         0);
01444    
01445    r.Set("WriteHistos",          itrue);
01446    r.Set("MakeTrees",            ifalse);
01447    r.Set("HistoFileName",        "demux_cosmics.root");
01448    r.Set("Filter",               ifalse);
01449    r.Set("UseCandDigitMasks",    itrue);
01450    r.Set("WindowSize",           6);
01451    r.Set("StrayDeltaStripLimit", 6);
01452    r.Set("StrayPlaneLimit",      4);
01453    r.Set("UseFigureOfMerit",     ifalse);
01454    r.Set("HoughSlopeRMS",        5.);
01455    r.Set("HoughInterceptRMS",    10.);
01456    r.Set("HoughPeak",            0.66);
01457    r.Set("XTalkFractionLimit",  0.1);
01458    r.Set("RatioMatedSignalForValid",  0.5);
01459    
01460    r.LockValues();
01461       
01462    return r;
01463 }
01464 
01465 //......................................................................
01466 
01467 void DmxDeMuxCosmicsModule::Config(const Registry& r)
01468 {
01469   int         tmpb;  // a temp bool. See comment under DefaultConfig...
01470   int         tmpi;  // a temp int.
01471   double      tmpd;  // a temp double.
01472   const char* tmps;  // a temp string
01473 
01474   if (r.Get("SingleModuleDemux",   tmpb)) fSingleModuleDeMux     =  tmpb;
01475   if (r.Get("EventLength",         tmpb)) fEventLength           =  tmpb;
01476   if (r.Get("UnsetDigitCheck",     tmpb)) fUnsetDigitCheck       =  tmpb;
01477   if (r.Get("UseCandDigitMasks",   tmpb)) fDontUseCandDigitMasks = !tmpb;
01478   if (r.Get("WriteHistos",         tmpb)) fWriteHistos           =  tmpb;
01479   if (r.Get("MakeTrees",           tmpb)) fMakeTrees             =  tmpb;
01480   if (r.Get("HistoFileName",       tmps)) fHistoFileName         =  tmps;
01481   if (r.Get("DataType",            tmpi)) fDataType              =  tmpi;
01482   if (r.Get("WindowSize",          tmpi)) fPlanesInWindow        =  tmpi;
01483   if (r.Get("StrayDeltaStripLimit",tmpi)) fStrayDeltaStripLimit  =  tmpi;
01484   if (r.Get("StrayPlaneLimit",     tmpi)) fStrayPlanesLimit      =  tmpi;
01485   if (r.Get("UseFigureOfMerit",    tmpb)) fUseStrayPlaneCheck    =  tmpb;
01486   if (r.Get("Filter",              tmpb)) fFilter                =  tmpb;
01487   if (r.Get("HoughSlopeRMS",       tmpd)) fHoughSlope            =  tmpd;
01488   if (r.Get("HoughInterceptRMS",   tmpd)) fHoughIntercept        =  tmpd;
01489   if (r.Get("HoughPeak",           tmpd)) fHoughPeak             =  tmpd;
01490   if (r.Get("XTalkFractionLimit",  tmpd)) fSignalFractionLimit   =  tmpd;
01491   if (r.Get("RatioMatedSignalForValid",  tmpd)) fMatedSignalForValid   =  tmpd;
01492  
01493 }
01494 
01495 //----------------------------------------------------------------------------------
01496 void DmxDeMuxCosmicsModule::Help() 
01497 {
01498   MSG("JobC", Msg::kInfo) 
01499     << "DeMuxCosmicsModule::Help\n"
01500     <<"DmxDeMuxCosmicsModule is a module which demultiplexes events "
01501     <<"in the far detector." << endl
01502     << "see http://beaker.astro.indiana.edu/brebel/demux_notes/how_to_demux.html for details"
01503     << endl;
01504 }
01505 
01506 void DmxDeMuxCosmicsModule::EndJob() 
01507 {
01508   //save the trees to a file
01509   if(fMakeTrees && fDeMuxFile){
01510     
01511 //     if(fDataType==1){
01512 //       fMCDeMuxTree->Write();
01513 //       fMCDeMuxDigitTree->Write();
01514 //     }
01515     fDeMuxFile->Write();
01516     fDeMuxFile->Close();
01517   }
01518   return;
01519 }
01520 
01521 void DmxDeMuxCosmicsModule::FindDigitsChiSq(Double_t &uChiSq, Double_t &vChiSq, CandDeMuxDigitHandleItr &digitItr, 
01522                                             Double_t uIntercept, Double_t uSlope, Double_t vIntercept, 
01523                                             Double_t vSlope)
01524 {
01525   uChiSq = 0.;
01526   vChiSq = 0.;
01527   Double_t xi = 0.;
01528   Double_t weight = 0.;
01529   Double_t yi = 0.;
01530   Double_t yxi = 0.;
01531   Double_t quotient = 0.;
01532   Int_t uDigits = -1;
01533   Int_t vDigits = -1;
01534   digitItr.ResetFirst();
01535     
01536   while( digitItr.IsValid() ){
01537 
01538     CandDeMuxDigitHandle *digit = digitItr.Ptr();
01539 
01540     if( digitItr.GetSet()->GetMasks().GetMask(digit) ){
01541       xi = digit->GetPlexSEIdAltL().GetPlane();
01542 
01543       //make the weight the inverse of the charge - that means that digits with more
01544       //charge make a bigger contribution to the chi^2 and you are more interested 
01545       //in getting those right.
01546       weight = 1.; //10000. / digit->GetCharge();
01547       yi = 1. * digit->GetPlexSEIdAltL().GetBestSEId().GetStrip();
01548       
01549       if( digit->GetPlexSEIdAltL().GetPlaneView() == PlaneView::kU ){
01550         ++uDigits;
01551         yxi = uIntercept + (xi * uSlope);
01552         quotient = (yi - yxi) / weight;
01553       
01554         uChiSq += quotient * quotient;
01555       }
01556       else if( digit->GetPlexSEIdAltL().GetPlaneView() == PlaneView::kV ){
01557         ++vDigits;
01558         yxi = vIntercept + (xi * vSlope);
01559         quotient = (yi - yxi) / weight;
01560       
01561         vChiSq += quotient * quotient;
01562       }
01563     }
01564     digitItr.Next();
01565   }  
01566 
01567   digitItr.ResetFirst();
01568   
01569   if(vDigits > 0){ vChiSq /= 1.*vDigits; }
01570   if(uDigits > 0){ uChiSq /= 1.*uDigits; }
01571   return;
01572 }
01573 
01574 void DmxDeMuxCosmicsModule::FindPlanesChiSq(Double_t &uChiSq, Double_t &vChiSq, TObjectItr &planeItr, 
01575                                             Double_t uIntercept, Double_t uSlope, Double_t vIntercept, 
01576                                             Double_t vSlope)
01577 {
01578   uChiSq = 0.;
01579   vChiSq = 0.;
01580   Double_t xi = 0.;
01581   Double_t weight = 0.;
01582   Double_t yi = 0.;
01583   Double_t yxi = 0.;
01584   Double_t quotient = 0.;
01585   Int_t uPlanes = -1;
01586   Int_t vPlanes = -1;
01587   planeItr.ResetFirst();
01588     
01589   while( planeItr.IsValid() ){
01590 
01591     DmxPlane *plane = dynamic_cast<DmxPlane *>(planeItr.Ptr());
01592 
01593     xi = plane->GetPlaneNumber();
01594 
01595     //weight each plane as 1.  this means that the chi^2 is the square of the 
01596     //difference between the fit and actual cog
01597     weight = 1.; 
01598     yi = plane->GetCoG();
01599       
01600     if( plane->GetPlaneView() == PlaneView::kU ){
01601         ++uPlanes;
01602         yxi = uIntercept + (xi * uSlope);
01603         quotient = (yi - yxi) / weight;
01604       
01605         uChiSq += quotient * quotient;
01606     }
01607     else if( plane->GetPlaneView() == PlaneView::kV ){
01608         ++vPlanes;
01609         yxi = vIntercept + (xi * vSlope);
01610         quotient = (yi - yxi) / weight;
01611       
01612         vChiSq += quotient * quotient;
01613     }
01614     
01615     planeItr.Next();
01616   }  
01617 
01618   planeItr.ResetFirst();
01619   
01620   if(vPlanes > 0){ vChiSq /= 1.*vPlanes; }
01621   if(uPlanes > 0){ uChiSq /= 1.*uPlanes; }
01622   return;
01623 }
01624 
01625 
01626 
01627 

Generated on Mon Feb 15 11:06:37 2010 for loon by  doxygen 1.3.9.1