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

MergeEvent.cxx

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 #include <cassert>
00009 
00010 #include "MuonRemoval/MergeEvent.h"
00011 #include "MuonRemoval/RawDigitInfo.h"
00012 #include "MuonRemoval/SelectEvent.h"
00013 #include "MuonRemoval/CandRmMuListHandle.h"
00014 #include "MuonRemoval/CandRmMuHandle.h"
00015 #include "MuonRemoval/AlgRmMu.h"
00016 #include "MessageService/MsgService.h"
00017 #include "MinosObjectMap/MomNavigator.h"
00018 #include "JobControl/JobCModuleRegistry.h" // For JOBMODULE macro
00019 #include "Calibrator/Calibrator.h"
00020 
00021 #include <CandData/CandHeader.h>
00022 #include "CandData/CandRecord.h"
00023 #include "CandDigit/CandDeMuxDigitListHandle.h"
00024 #include <RecoBase/CandTrackListHandle.h>
00025 #include <RecoBase/CandFitTrackHandle.h>
00026 #include <RecoBase/CandTrackHandle.h>
00027 #include <RecoBase/CandShowerHandle.h>
00028 #include <RecoBase/CandShowerListHandle.h>
00029 #include <RecoBase/CandStripHandle.h>
00030 #include <RecoBase/CandStripListHandle.h>
00031 #include <RecoBase/CandEventListHandle.h>
00032 #include <RecoBase/CandEventHandle.h>
00033 
00034 #include "RawData/RawRecord.h"
00035 #include "RawData/RawDigit.h"
00036 #include "RawData/RawHeader.h"
00037 #include "RawData/RawDigitDataBlock.h"
00038 #include "RawData/RawChannelId.h"
00039 #include "RawData/RawDaqSnarlHeader.h"
00040 #include "RawData/RawDaqHeaderBlock.h"
00041 #include "RawData/RawDigitDataBlock.h"
00042 #include "RawData/RawVarcErrorInTfBlock.h"
00043 
00044 #include "Algorithm/AlgConfig.h"
00045 #include "Algorithm/AlgFactory.h"
00046 #include "Algorithm/AlgHandle.h"
00047 
00048 #include "Record/SimSnarlRecord.h"
00049 #include "REROOT_Classes/REROOT_NeuKin.h"
00050 
00051 #include "Candidate/CandContext.h"
00052 
00053 #include "TFile.h"
00054 #include "TTree.h"
00055 #include "TObjArray.h"
00056 #include "TParticle.h"
00057 
00058 #include "Conventions/ReleaseType.h"
00059 #include "DataUtil/EnergyCorrections.h"
00060 
00061 #include <cmath>
00062 
00063 JOBMODULE(MergeEvent, "MergeEvent","");
00064 CVSID("$Id: MergeEvent.cxx,v 1.13 2008/05/09 15:19:40 boehm Exp $");
00065 //......................................................................
00066 MergeEvent::MergeEvent() :
00067   fInputFileName(""), fInputFile(NULL), fInputTree(NULL),
00068   fInputEventNumber(0), fInRawDigits(NULL),
00069   fOutputFileName(""), fOutputFile(NULL), fOutputTree(NULL),
00070   fOutputEventNumber(0), fOutRawDigits(NULL),
00071   fMergeAlg(""), fMergeConfig(""), fMergeListOut(""), fUseTrkForTiming(1)
00072 {
00073   fInputP4[0] = 0; fInputP4[1] = 0; fInputP4[2] = 0; fInputP4[3] = 0;  
00074   fOutputP4[0] = 0; fOutputP4[1] = 0; fOutputP4[2] = 0; fOutputP4[3] = 0;  
00075   for (int i = 0; i<6; i++){
00076     fInputMRM[i] = 0;
00077     fOutputMRM[i] = 0;
00078   }
00079 }
00080 
00081 void MergeEvent::EndJob()
00082 {
00083   if(fOutputEventNumber>0) {
00084     fOutputFile->cd();
00085     fOutputTree->Write();
00086     fOutputFile->Close();
00087     MSG("EvtMrg",Msg::kInfo) << " Wrote digits from "<< fOutputEventNumber 
00088                              << " electron events to summary file: "
00089                              << fOutputFileName.c_str() << endl;
00090   }
00091   if(fInputEventNumber>0) {
00092     fInputFile->Close();
00093     MSG("EvtMrg",Msg::kInfo) << " Merged digits from "<< fInputEventNumber 
00094                              << " electron events from summary file: "
00095                              << fInputFileName.c_str() << endl;
00096   }
00097 }
00098 
00099 MergeEvent::~MergeEvent() 
00100 {
00101   if(fInRawDigits) delete fInRawDigits;
00102   if(fOutRawDigits) delete fOutRawDigits;
00103 }
00104 
00105 //......................................................................
00106 void MergeEvent::OutfileSetUp() 
00107 {
00108   fOutputFile = new TFile(fOutputFileName.c_str(),"RECREATE");  
00109   fOutputTree = new TTree("ElectronTree","Electron Tree");
00110   fOutputTree->Branch("true_p4",&fOutputP4,"true_p4[4]/F",32000);
00111   fOutputTree->Branch("mrminfo",&fOutputMRM,"mrminfo[6]/F",32000);
00112   fOutRawDigits = new TClonesArray("RawDigitInfo",1000);
00113   fOutputTree->Branch("rawdigits","TClonesArray",&fOutRawDigits,8000,1);  
00114   MSG("EvtMrg",Msg::kInfo) << " Opened summary file "<< fOutputFileName
00115                            << " for writing electron events" << endl;
00116 }
00117 
00118 //......................................................................
00119 void MergeEvent::InfileSetUp()
00120 {
00121   TDirectory* current_directory = gDirectory;
00122   fInputFile = TFile::Open(fInputFileName.c_str(),"READ");
00123   if(!fInputFile || !(fInputFile->IsOpen()) ){
00124     MSG("EvtMrg",Msg::kFatal) << " Unable to open: "<< fInputFileName << endl;
00125     return;
00126   }
00127   fInputTree = dynamic_cast<TTree*>(fInputFile->Get("ElectronTree"));
00128   if(!fInputTree){
00129     MSG("EvtMrg",Msg::kFatal) << " Unable to get tree : ElectronTree from  "
00130                               << fInputFileName << endl;
00131     return;
00132   }
00133   fInRawDigits = new TClonesArray("RawDigitInfo",1000);
00134   fInputTree->SetBranchAddress("true_p4",fInputP4);
00135   if (fInputTree->GetBranchStatus("mrminfo")) fInputTree->SetBranchAddress("mrminfo",fInputMRM);
00136   fInputTree->SetBranchAddress("rawdigits",&fInRawDigits);
00137   current_directory->cd();
00138   MSG("EvtMrg",Msg::kDebug) << " Opened input file: " << fInputFileName <<endl;
00139 }
00140 
00141 //......................................................................
00142 JobCResult MergeEvent::Ana(const MomNavigator* mom)
00143 {
00144   //set up output tree if first time:
00145   if(!fOutputTree) this->OutfileSetUp();
00146   
00147   JobCResult result(JobCResult::kPassed);
00148   
00149   // make sure raw record is available
00150   RawRecord *rr = dynamic_cast<RawRecord *>(mom->GetFragment("RawRecord"));
00151   if (rr == 0) {
00152     MSG("EventSR", Msg::kWarning) << "No RawRecord in MOM." << endl;
00153     return result;
00154   }
00155 
00156   const RawDaqSnarlHeader* snarlHdr =
00157     dynamic_cast<const RawDaqSnarlHeader*>(rr->GetRawHeader());
00158   if (snarlHdr) {
00159     if (snarlHdr->GetSnarl()%1000==0) cout<<"Run "<<snarlHdr->GetRun()<<" Snarl "<<snarlHdr->GetSnarl()<<endl;
00160   }
00161   else cout<<"No snarl info"<<endl;  
00162 
00163   //fill raw digit array
00164   fOutRawDigits->Clear();
00165   TClonesArray &rawdigitl = *fOutRawDigits;
00166   const RawDigitDataBlock *rddb=dynamic_cast<const RawDigitDataBlock *>
00167     (rr->FindRawBlock("RawDigitDataBlock"));
00168   Int_t rawDigitCounter = 0;
00169   if (rddb) {
00170     TIter it=rddb->GetDatumIter();
00171     while (TObject *obj=it.Next()) {
00172       RawDigit *rd=dynamic_cast<RawDigit *>(obj);
00173       new(rawdigitl[rawDigitCounter]) RawDigitInfo(rd->GetChannel(),
00174                                                    rd->GetADC(),
00175                                                    rd->GetTDC(),
00176                                                    rd->GetCrateT0());
00177       rawDigitCounter++;
00178     }
00179     rawdigitl.Compress();
00180   }
00181 
00182   //get truth:
00183   SimSnarlRecord* simrec = dynamic_cast<SimSnarlRecord*>
00184     (mom->GetFragment("SimSnarlRecord"));
00185   if ( !simrec ) {
00186     MSG("NtpMC",Msg::kWarning) << "No SimSnarlRecord in Mom" << endl;
00187     result.SetWarning().SetFailed();
00188     return result;
00189   }
00190   const TClonesArray* neukinarray = dynamic_cast<const TClonesArray*>
00191     (simrec->FindComponent("TClonesArray","NeuKinList"));
00192   REROOT_NeuKin* rneukin = dynamic_cast<REROOT_NeuKin*>(neukinarray->At(0));
00193   if (rneukin){
00194     for(int i=0;i<4;i++) fOutputP4[i] = rneukin->P4Shw()[i];
00195   }
00196   else {
00197     const TClonesArray* parts = 
00198       (const TClonesArray*)simrec->FindComponent("TClonesArray","StdHep");
00199     
00200     TIter next(parts);
00201     TObject* obj = 0;
00202     while ( ( obj = next() ) ) {
00203       TParticle* part = (TParticle*)obj;
00204       if (part->GetStatusCode()==1){
00205         fOutputMRM[0] = part->Px();
00206         fOutputMRM[1] = part->Py();
00207         fOutputMRM[2] = part->Pz();
00208         fOutputMRM[3] = part->Energy();
00209       }
00210       if (part->GetStatusCode()==800){
00211         fOutputP4[0] = part->Px();
00212         fOutputP4[1] = part->Py();
00213         fOutputP4[2] = part->Pz();
00214         fOutputP4[3] = part->Energy();
00215         fOutputMRM[4] = part->Vx();
00216         fOutputMRM[5] = part->Vy();
00217         fOutputTree->Fill();
00218         fOutputEventNumber++;
00219         return result;
00220       }
00221     }
00222   }
00223   //fill tree
00224   fOutputTree->Fill();
00225   fOutputEventNumber++;
00226   return result;
00227 }
00228 
00229 //......................................................................
00230 
00231 JobCResult MergeEvent::Reco(MomNavigator* mom)
00232 {
00233   JobCResult result(JobCResult::kPassed);
00234   MSG("EvtMrg", Msg::kDebug) << " Starting RemoveMuon::Reco() " <<endl;
00235   MSG("EvtMrg", Msg::kDebug) << "  Alg        : " << fMergeAlg<< endl;
00236   MSG("EvtMrg", Msg::kDebug) << "  AlgConfig  : " << fMergeConfig<< endl;
00237   MSG("EvtMrg", Msg::kDebug) << "  NameListOut: " << fMergeListOut<< endl;
00238 
00239   //set up input tree if first time:
00240   if(!fInputTree) this->InfileSetUp();
00241   
00242   // Find PrimaryCandidateRecord fragment in MOM.
00243   CandRecord *record = dynamic_cast<CandRecord *>(mom->GetFragment("CandRecord"));
00244   if (record == 0) {
00245     MSG("EvtMrg", Msg::kError) << "No PrimaryCandidateRecord in MOM."<< endl;
00246     result.SetWarning().SetFailed();
00247     return result;
00248   }
00249   const CandHeader* header  = dynamic_cast<const CandHeader*>(record->GetHeader());  
00250   
00251   //Find the raw data in MOM
00252   RawRecord *rawrecord = 
00253     dynamic_cast<RawRecord *>(mom->GetFragment("RawRecord",0,"DaqSnarl"));
00254   assert(rawrecord);
00255   RawDigitDataBlock *input_datablock =  NULL;
00256   if(rawrecord){
00257     TIter rdbit = rawrecord->GetRawBlockIter();
00258     TObject *tob;
00259     while ((tob = rdbit())) {
00260       if (tob->InheritsFrom("RawDigitDataBlock")) {
00261         input_datablock = (RawDigitDataBlock *) tob;
00262       }
00263     }
00264   }
00265 
00266   CandEventListHandle * eventlist = 
00267     dynamic_cast<CandEventListHandle*>(record->FindCandHandle("CandEventListHandle"));
00268   if(eventlist==NULL) { 
00269     MSG("EvtMrg",Msg::kWarning) << " Bailing out of Event eventlist = " << eventlist 
00270                                 << endl; 
00271     result.SetWarning().SetFailed();
00272     return result;
00273   }
00274 
00275   //get muon removed digit list:
00276   CandDigitListHandle* digitlist = dynamic_cast<CandDigitListHandle*>
00277     (record->FindCandHandle("CandDigitListHandle","stripdigitlist"));
00278 
00279   //make a new TClonesArray to hold track time corrected 
00280   //RawDigitInfo objects for whole snarl
00281   TClonesArray *fRawDigits = new TClonesArray("RawDigitInfo",5000);
00282 
00283   //get rmmulist to check that input electrons match with removed muons
00284   CandRmMuListHandle *rmmulist = 
00285     dynamic_cast<CandRmMuListHandle*>(record->FindCandHandle("CandRmMuListHandle"));  
00286 
00287   //map to link MC electron RawDigits to RmMu objects
00288   std::map<Int_t,Int_t> linkRmMuRawDig;
00289 
00290   //Set up calibrator
00291   Calibrator& calibrator = Calibrator::Instance();
00292   calibrator.ReInitialise(*(record->GetVldContext()));
00293 
00294   //loop over removed muons:
00295   Int_t rmmuIndex = 0;
00296   TIter rmmuItr(rmmulist->GetDaughterIterator());
00297   while(CandRmMuHandle* rmmu = dynamic_cast<CandRmMuHandle*>(rmmuItr())){
00298     //read in first electron:
00299     if(fInputTree->GetEntry(fInputEventNumber++)<=0){
00300       MSG("EvtMrg", Msg::kFatal) << "Unable to read input event number: " 
00301                                  << fInputEventNumber-1 <<endl;
00302       result.SetFatal();
00303       return result;
00304     }
00305     MSG("EvtMrg", Msg::kDebug)  << " Cand:" << header->GetRun() << "/" 
00306                                 << header->GetSnarl() << "/" 
00307                                 << rmmu->GetOrigEvtIndex() << endl;
00308     MSG("EvtMrg",Msg::kDebug) << " Read New event P4: " 
00309                               << fInputP4[0] <<", " 
00310                               << fInputP4[1] <<", "
00311                               << fInputP4[2] <<", "
00312                               << fInputP4[3] <<endl;
00313 
00314     //Check that inputs and rmmu values agree
00315     const Float_t emass  = 0.000511; //GeV
00316     const Float_t mumass = 0.105658; //GeV
00317     Float_t etot = 0;
00318     Float_t pelec = 0;
00319     if(rmmu->GetIsCont()==1 || rmmu->GetFitPass()==1){
00320       etot = sqrt(pow(rmmu->GetMomX(),2) + pow(rmmu->GetMomY(),2) +
00321                   pow(rmmu->GetMomZ(),2) + pow(mumass,2));
00322       pelec  = sqrt(etot*etot - emass*emass);
00323     }
00324     else { //use range:
00325       etot = sqrt(pow(rmmu->GetMomRange(),2)+mumass*mumass);
00326       pelec  = sqrt(etot*etot - emass*emass);
00327     }
00328     if(etot > 500) {etot = emass; pelec = 0.0;}
00329     if(fInputP4[3] > 500) {
00330       fInputP4[0] = 0;
00331       fInputP4[1] = 0;
00332       fInputP4[2] = 0;
00333       fInputP4[3] = emass;
00334     } 
00335    float cut = 1e-3;
00336 
00337     if( TMath::Abs(rmmu->GetVtxDCosX()*pelec - fInputP4[0])> cut ||
00338         TMath::Abs(rmmu->GetVtxDCosY()*pelec - fInputP4[1])> cut ||
00339         TMath::Abs(rmmu->GetVtxDCosZ()*pelec - fInputP4[2])> cut ||
00340         TMath::Abs(etot - fInputP4[3])> cut ) {
00341       MSG("EvtMrg", Msg::kInfo) << " Input momentum: " << fInputP4[0] << " "
00342                                 << fInputP4[1] << " " << fInputP4[2] << " " 
00343                                 << fInputP4[3] << endl
00344                                 << " RmMu momentum: " << rmmu->GetVtxDCosX()*pelec 
00345                                 << " " << rmmu->GetVtxDCosY()*pelec << " " 
00346                                 << rmmu->GetVtxDCosZ()*pelec << " " << etot << endl;
00347       MSG("EvtMrg", Msg::kError)
00348         << " Input electron file out of synch with muon removal..." 
00349         << " look for a match nearby." << endl;
00350       
00351       Bool_t gotMatch = false;
00352       for(int ii=1;ii<50;ii++){
00353         for(int jj=-1;jj<=1;jj+=2){       
00354           if(fInputTree->GetEntry(fInputEventNumber+(ii*jj))) {
00355             if( TMath::Abs(rmmu->GetVtxDCosX()*pelec - fInputP4[0])< cut &&
00356                 TMath::Abs(rmmu->GetVtxDCosY()*pelec - fInputP4[1])< cut &&
00357                 TMath::Abs(rmmu->GetVtxDCosZ()*pelec - fInputP4[2])< cut &&
00358                 TMath::Abs(etot - fInputP4[3])<1e-4 ) {
00359               //got a match!
00360               fInputEventNumber+=(ii*jj)+1;
00361               gotMatch = true;
00362               MSG("EvtMrg", Msg::kInfo) 
00363                 << "Found an input momentum match; "
00364                 "ii = " << ii << " jj = " << jj << " "
00365                 << rmmu->GetVtxDCosX()*pelec - fInputP4[0] << " " 
00366                 << rmmu->GetVtxDCosY()*pelec - fInputP4[1] << " " 
00367                 << rmmu->GetVtxDCosZ()*pelec - fInputP4[2] << " " 
00368                 << etot - fInputP4[3] << endl;
00369               break;
00370             }
00371           }       
00372         }
00373         if(gotMatch) break;
00374       }
00375 
00376       if(!gotMatch) {
00377         MSG("EvtMrg", Msg::kError) << "Can't find a match... quitting" << endl;
00378         result.SetWarning().SetFailed();
00379         return result;
00380       }
00381     }
00382 
00383     //We have a rmmu entry and a set of electron hits that match
00384     //check if the MC electron/muon digit list is empty
00385     //This might not be a problem for electrons. But sometimes the muon event has no hits since the MC muon momentum is independent of the original muon momentum and can be very small. TY 11/16/07
00386     if (!fInRawDigits->GetEntries()){
00387       MSG("EvtMrg", Msg::kWarning) << "The lepton has no hits, don't add it to the muon removal event." << endl;
00388       continue;
00389     }
00390     
00391     //save MRM information: pmu, Q2 and Eshw
00392     rmmu->SetMRMX(fInputMRM[0]);
00393     rmmu->SetMRMY(fInputMRM[1]);
00394     rmmu->SetMRMZ(fInputMRM[2]);
00395     rmmu->SetMRMQ2(fInputMRM[4]);
00396     rmmu->SetMRMEshw(fInputMRM[5]);
00397 
00398     //now find original event and track to get the timing offsets
00399     TIter evtItr(eventlist->GetDaughterIterator());
00400     const CandEventHandle *event = NULL;
00401     for(int i=0;i<rmmu->GetOrigEvtIndex()+1;i++) 
00402       event = dynamic_cast<const CandEventHandle*>(evtItr());      
00403     if(!SelectEvent(event)) {
00404       MSG("EvtMrg", Msg::kError) << " This event was selected for muon removal " 
00405                                  << " Now it is not passing... quitting"
00406                                  << endl;
00407       result.SetWarning().SetFailed();
00408       return result;
00409     }
00410     const CandTrackHandle* track = GetRemovableTrack(event);
00411     if(!track) {
00412       MSG("EvtMrg", Msg::kError) << " Cannot find removable track from event" 
00413                                  << " ... quitting"
00414                                  << endl;
00415       result.SetWarning().SetFailed();
00416       return result;
00417     }
00418     //check that track matches rmmu:
00419     if(rmmu->GetVtxPlane()!=track->GetVtxPlane() ||
00420        rmmu->GetNPlane()!= TMath::Abs(track->GetEndPlane()-
00421                                       track->GetVtxPlane())+1) {
00422       MSG("EvtMrg", Msg::kError) << " Removable track properties do not match"
00423                                  << " rmmu properties... quitting"
00424                                  << endl;
00425       result.SetWarning().SetFailed();
00426       return result;
00427     }
00428 
00429     //now calculate mean offsets between track/event and MC electron:
00430     int tracktdc = 0;
00431     int tracktdc_ndigit = 0 ;
00432     int track_offset = -1;
00433     if(fUseTrkForTiming){
00434       MSG("EvtMrg", Msg::kDebug) << " Using Track for timing " << endl;
00435       TIter trkstpIter(track->GetDaughterIterator());
00436       while(const CandStripHandle* strip = 
00437             dynamic_cast<const CandStripHandle*>(trkstpIter())){
00438         TIter trkdigIter(strip->GetDaughterIterator());
00439         if(strip->GetPlane()<track->GetVtxPlane()+10){
00440           while(const CandDigitHandle* digit = 
00441                 dynamic_cast<const CandDigitHandle*>(trkdigIter())){
00442             const RawDigit* raw_digit = input_datablock->At(digit->GetRawDigitIndex());
00443             if(raw_digit){
00444               if(track_offset==-1) track_offset = raw_digit->GetTDC();    
00445               tracktdc += raw_digit->GetTDC() - track_offset;
00446               tracktdc_ndigit++;
00447               MSG("EvtMrg", Msg::kDebug) << " TDC:  " << raw_digit->GetTDC() 
00448                                          << " ADC:  " << raw_digit->GetADC() << endl;
00449             }
00450             else MSG("EvtMrg", Msg::kError) << "Digit with no raw digit"<<endl;   
00451           }
00452         }
00453       }
00454     }
00455     else {
00456       //Use all digts for finding the mean time of the event. 
00457       //  NB: You want to be careful that you dont have outliers screwing it up so 
00458       //      use a 5.0PE cut rather than the usual 3PE cut when doing timing 
00459       //      along tracks. 
00460       TIter digIter(digitlist->GetDaughterIterator());
00461       while(const CandDigitHandle* digit = 
00462             dynamic_cast<const CandDigitHandle*>(digIter())){
00463         if(digit->GetCharge(CalDigitType::kPE)>5.0){
00464           const RawDigit* raw_digit = input_datablock->At(digit->GetRawDigitIndex());   
00465           if(raw_digit){
00466             if(track_offset==-1) track_offset = raw_digit->GetTDC();      
00467             tracktdc+=raw_digit->GetTDC() - track_offset;
00468             tracktdc_ndigit++;
00469             MSG("EvtMrg", Msg::kDebug) << " TDC:  " << raw_digit->GetTDC() 
00470                                        << " ADC:  " << raw_digit->GetADC() << endl;
00471           }
00472           else {
00473             MSG("EvtMrg", Msg::kError) << "Digit with no raw digit"<<endl;
00474           }
00475         }
00476       }    
00477     }
00478 
00479     int meantracktdc = (track_offset!=-1)?((int)(round(((float)tracktdc)/ 
00480                                                        tracktdc_ndigit))+track_offset):0;
00481     MSG("EvtMrg", Msg::kDebug) << " Mean Track TDC:  " << meantracktdc << endl;
00482 
00483     
00484     //Calc mean and mode timing offset for the "MC" events.
00485     int rawtdc = 0;
00486     int rawtdc_ndigit = 0;
00487     TIter rawdigitIter(fInRawDigits);
00488     RawDigitInfo *tmp_digit = 0;
00489     std::map<Int_t,Int_t> freqTDC;
00490     while((tmp_digit = dynamic_cast<RawDigitInfo*>(rawdigitIter()))){
00491       rawtdc_ndigit++;
00492       rawtdc += (int)(tmp_digit->tdc);
00493       if(freqTDC.find(int(tmp_digit->tdc))!=freqTDC.end()) 
00494         freqTDC[int(tmp_digit->tdc)] += 1;
00495       else freqTDC[int(tmp_digit->tdc)] = 1;
00496     }
00497     int moderawtdc = 0;
00498     int maxrawtdc = 0;
00499     std::map<Int_t,Int_t>::iterator begTDC = freqTDC.begin();
00500     std::map<Int_t,Int_t>::iterator endTDC = freqTDC.end();
00501     while(begTDC!=endTDC){
00502       if(begTDC->second>maxrawtdc) {
00503         moderawtdc = begTDC->first;
00504         maxrawtdc = begTDC->second;
00505       }
00506       begTDC++;
00507     }
00508     int meanrawtdc = 0;
00509     if(rawtdc_ndigit>0) meanrawtdc = (int)(round(((float)rawtdc)/rawtdc_ndigit));
00510     MSG("EvtMrg", Msg::kDebug) << "MODE, MAX, MEAN: " << moderawtdc << " " 
00511                                << maxrawtdc << " " << meanrawtdc << endl;
00512 
00513     //remove large outliers which skew the mean:
00514     if(maxrawtdc>4) meanrawtdc = moderawtdc; //trust the mode
00515     rawtdc = rawtdc_ndigit = 0;
00516     rawdigitIter.Reset();
00517     while((tmp_digit = dynamic_cast<RawDigitInfo*>(rawdigitIter()))){   
00518       if(TMath::Abs(tmp_digit->tdc-meanrawtdc)<=5) { //ND: 5 buckets ~ 100ns
00519         rawtdc_ndigit++;
00520         rawtdc += (int)(tmp_digit->tdc);
00521         MSG("EvtMrg", Msg::kDebug) << " TDC:  " << tmp_digit->tdc 
00522                                    << " ADC:  " << tmp_digit->adc << endl;
00523       }
00524     }
00525     if(rawtdc_ndigit>0) meanrawtdc = (int)(round(((float)rawtdc)/rawtdc_ndigit));
00526     MSG("EvtMrg", Msg::kDebug) << " Mean Electron TDC:  " << meanrawtdc << endl;
00527 
00528     MSG("EvtMrg", Msg::kDebug)<< "Delta T muon and electron events: " << meantracktdc
00529                               <<" - "<< meanrawtdc <<" = " 
00530                               << meantracktdc - meanrawtdc <<endl;     
00531     
00532     //Now add RawDigitInfo objects to new TClonesArray for the snarl
00533     //and correct for the average delta time between the muon and electron
00534     rawdigitIter.Reset();
00535     TClonesArray &rawdigitl = *fRawDigits;
00536     Int_t rawDigitCounter = fRawDigits->GetEntries();
00537     tmp_digit = 0;
00538     while((tmp_digit = dynamic_cast<RawDigitInfo*>(rawdigitIter()))) {
00539       Double_t TDC = tmp_digit->tdc - meanrawtdc + meantracktdc;
00540       if(TDC<0) TDC = 0;
00541       linkRmMuRawDig[rawDigitCounter] = rmmuIndex;
00542       new(rawdigitl[rawDigitCounter++]) RawDigitInfo(tmp_digit->rcid,tmp_digit->adc,
00543                                                      TDC,tmp_digit->t0);
00544     }
00545     rmmuIndex += 1;
00546   }
00547   
00548   // Add back in the electrons
00549   MSG("EvtMrg", Msg::kDebug) << " Running Event Merging:  " << fMergeAlg 
00550                              << ":"<< fMergeConfig<< " to produce " 
00551                              << fMergeListOut <<endl;   
00552   
00553   CandContext merge_cx(NULL, mom);
00554   TObjArray merge_input;
00555   merge_input.Add(fRawDigits);
00556   merge_input.Add(digitlist);
00557   merge_input.Add(rawrecord);
00558   merge_cx.SetDataIn(&merge_input);
00559   merge_cx.SetCandRecord(record);
00560   AlgHandle merge_algorithm = 
00561     AlgFactory::GetInstance().GetAlgHandle(fMergeAlg.c_str(), fMergeConfig.c_str());
00562   CandDigitListHandle merge_digitlist = 
00563     CandDigitList::MakeCandidate(merge_algorithm, merge_cx);
00564   merge_digitlist.SetName(fMergeListOut.c_str());
00565   merge_digitlist.SetTitle(fMergeListOut.c_str());
00566   record->SecureCandHandle(merge_digitlist);
00567 
00568   //now need to replace daughters in rmmu objects with those in new digitlist
00569   CandDigitListHandle* mergedlist = dynamic_cast<CandDigitListHandle*>
00570     (record->FindCandHandle("CandDigitListHandle",fMergeListOut.c_str()));
00571   TIter mergedlistIter(mergedlist->GetDaughterIterator());
00572 
00573   rmmuItr.Reset();
00574   while(CandRmMuHandle* rmmu = dynamic_cast<CandRmMuHandle*>(rmmuItr())){
00575     std::vector<CandDigitHandle*> mdigs(rmmu->GetNDaughters());
00576     std::vector<CandDigitHandle*> rmdigs(rmmu->GetNDaughters());
00577     std::vector<Int_t> rfk(rmmu->GetNDaughters());
00578     Int_t rmmuDigCounter = 0;
00579     TIter rmmuDigIter(rmmu->GetDaughterIterator());
00580     while(CandDigitHandle *rmmuDig = dynamic_cast<CandDigitHandle*>(rmmuDigIter())){      
00581       rfk[rmmuDigCounter] = rmmu->ReasonForKeeping(rmmuDig);
00582       mergedlistIter.Reset();
00583       while(CandDigitHandle *mergeDig = dynamic_cast<CandDigitHandle*>(mergedlistIter())){
00584         if( ( mergeDig->GetRawDigitIndex()==rmmuDig->GetRawDigitIndex() ) ){
00585           mdigs[rmmuDigCounter] = mergeDig;
00586           rmdigs[rmmuDigCounter] = rmmuDig;
00587           break;
00588         }
00589       }
00590       rmmuDigCounter += 1;
00591     }
00592     for(int i=0;i<rmmu->GetNDaughters();i++) {
00593       if(rmdigs[i]){
00594         rmmu->RemoveDaughter(rmdigs[i]);
00595         rmmu->AddDaughterLink(*mdigs[i]);
00596         rmmu->SetReasonForKeeping(mdigs[i],rfk[i]);
00597       }
00598     }
00599   }
00600 
00601   //now add electron digits to RmMu objects, and set ReasonForKeeping IsMCElec flag
00602   //loop over new raw digits:
00603   TIter rawDigIter(fRawDigits);
00604   Int_t rawDigitCounter = 0;
00605   RawDigitInfo *tmp_digit = 0;
00606   while((tmp_digit = dynamic_cast<RawDigitInfo*>(rawDigIter()))) {
00607     Bool_t gotDigit = false;
00608     //get rmmu index
00609     Int_t rmmuInd = linkRmMuRawDig[rawDigitCounter];
00610     MSG("EvtMrg", Msg::kDebug) << "RawDigit: " << rawDigitCounter 
00611                                << " rmmu index: " << rmmuInd << endl;
00612     //now loop over merged digit list
00613     mergedlistIter.Reset();
00614     while(CandDigitHandle *mergeDig = dynamic_cast<CandDigitHandle*>(mergedlistIter())){
00615       //look for equivalent channels:
00616       if(tmp_digit->rcid == mergeDig->GetChannelId()) {
00617         MSG("EvtMrg", Msg::kVerbose) << "Got channel match for electron rawdigit " 
00618                                      << rawDigitCounter << endl;
00619         //get raw digit and check that TDC is the same
00620         const RawDigit* raw_digit = input_datablock->At(mergeDig->GetRawDigitIndex());
00621         //also check against digit info since electron-only hits have no associated RawDigit
00622         Double_t rdTime = calibrator.GetTimeFromTDC(int(tmp_digit->tdc), tmp_digit->rcid);
00623         Double_t rdAdc = tmp_digit->adc - 50.;
00624         if( ( raw_digit!=NULL && tmp_digit->tdc==raw_digit->GetTDC() ) || 
00625             ( TMath::Abs(rdTime - mergeDig->GetTime())<1e-9 && 
00626               TMath::Abs(rdAdc  - mergeDig->GetCharge())<1e-6 ) ) {
00627           //found match; 
00628           MSG("EvtMrg", Msg::kDebug) << "Got TDC match for electron rawdigit " 
00629                                      << rawDigitCounter << endl;
00630           MSG("EvtMrg", Msg::kDebug) << "Time: " << rdTime*1e6 << " " 
00631                                      << mergeDig->GetTime()*1e6
00632                                      << " ADC: " << rdAdc << " " << mergeDig->GetCharge()
00633                                      << endl;
00634           rmmuItr.Reset();
00635           Int_t rmmuIndex = 0;
00636           while(CandRmMuHandle* rmmu = dynamic_cast<CandRmMuHandle*>(rmmuItr())){
00637             if(rmmuIndex==rmmuInd) {
00638               MSG("EvtMrg", Msg::kDebug) << "Got RmMu match for electron rawdigit " 
00639                                          << rawDigitCounter << endl;
00640               //got rmmu object, now look for match in rmmu digit list
00641               TIter rmmuDigIter(rmmu->GetDaughterIterator());
00642               while(CandDigitHandle *rmmuDig = dynamic_cast<CandDigitHandle*>(rmmuDigIter())){
00643                 Int_t rfk = rmmu->ReasonForKeeping(rmmuDig);
00644                 if(rmmuDig->IsEquivalent(mergeDig)) {
00645                   MSG("EvtMrg", Msg::kDebug) << "Got RmMu Digit match for electron rawdigit " 
00646                                              << rawDigitCounter << endl;
00647                   //this digit is already in list, set IsMCElec flag
00648                   rfk |= RmMuMask::kRMMU_ISMCELEC_MASK;
00649                   rmmu->SetReasonForKeeping(rmmuDig,rfk);
00650                   gotDigit = true;
00651                   break;
00652                 }
00653               }
00654               if(!gotDigit) {
00655                 //then add the daughter link and set the flag
00656                 MSG("EvtMrg", Msg::kDebug) << "Adding electron digit for electron rawdigit " 
00657                                            << rawDigitCounter << endl;
00658                 Int_t rfk = 0;
00659                 rfk |= RmMuMask::kRMMU_ISMCELEC_MASK;
00660                 rmmu->AddDaughterLink(*mergeDig);
00661                 rmmu->SetReasonForKeeping(mergeDig,rfk);
00662               }
00663             }
00664             if(gotDigit) break;
00665             rmmuIndex++;
00666           } // end of loop over rmmulist
00667         } // found a raw digit match
00668       } // found a channel ID match
00669       if(gotDigit) break;
00670     } // end of loop over new merged digitlist
00671     rawDigitCounter++;
00672   } // end of loop over MC electron raw digits
00673 
00674   fRawDigits->Clear();
00675   delete fRawDigits;
00676   
00677   return JobCResult::kPassed; // kNoDecision, kFailed, etc.
00678 }
00679 
00680 //......................................................................
00681 
00682 const Registry& MergeEvent::DefaultConfig() const
00683 {
00684   // Default configuration for module
00685   static Registry r;
00686   // Set name of config
00687   std::string name = this->GetName();
00688   name += ".config.default";
00689   r.SetName(name.c_str());
00690   // Set values in configuration
00691   r.UnLockValues();
00692   // Config for merging events
00693   r.Set("InputFileName","input_events.root");
00694   r.Set("OutputFileName","output_events.root");
00695   r.Set("MergeAlg","AlgMergeEvent");
00696   r.Set("MergeConfig","default");
00697   r.Set("MergeListOut","mergedigitlist");  
00698   r.Set("UseTrkForTiming",1);
00699   r.LockValues();
00700   return r;
00701 }
00702 
00703 //......................................................................
00704 void MergeEvent::Config(const Registry& r)
00705 {
00706   fInputFileName  = r.GetCharString("InputFileName");
00707   fOutputFileName = r.GetCharString("OutputFileName");
00708   fMergeAlg       = r.GetCharString("MergeAlg");
00709   fMergeConfig    = r.GetCharString("MergeConfig");
00710   fMergeListOut   = r.GetCharString("MergeListOut");
00711   fUseTrkForTiming   = r.GetInt("UseTrkForTiming");
00712   MSG("EvtMrg",Msg::kInfo) << " **** " << fInputFileName << endl;
00713   MSG("EvtMrg",Msg::kInfo) << " **** " << fOutputFileName << endl;
00714   MSG("EvtMrg",Msg::kInfo) << " **** " << fMergeAlg << endl;
00715   MSG("EvtMrg",Msg::kInfo) << " **** " << fMergeConfig << endl;
00716   MSG("EvtMrg",Msg::kInfo) << " **** " << fMergeListOut << endl;
00717   if(fUseTrkForTiming) MSG("EvtMrg",Msg::kInfo) << " **** Using Trk For Timing" << endl;
00718 }
00719 

Generated on Mon Jun 16 14:57:39 2008 for loon by  doxygen 1.3.9.1