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

ANtpInfoObjectFiller.cxx

Go to the documentation of this file.
00001 
00002 //$Id: ANtpInfoObjectFiller.cxx,v 1.72 2009/11/16 14:40:56 pittam Exp $
00003 //
00004 //ANtpInfoObjectFiller.cxx
00005 //
00006 //B. Rebel 02/2005
00008 
00009 #include "AnalysisNtuples/Module/ANtpInfoObjectFiller.h"
00010 #include "AnalysisNtuples/Module/ANtpRecoNtpManipulator.h"
00011 #include "AnalysisNtuples/ANtpDefaultValue.h"
00012 #include "MessageService/MsgService.h"
00013 #include "AnalysisNtuples/ANtpEventInfo.h"
00014 #include "AnalysisNtuples/ANtpShowerInfo.h"
00015 #include "AnalysisNtuples/ANtpTrackInfo.h"
00016 #include "AnalysisNtuples/ANtpTruthInfo.h"
00017 #include "AnalysisNtuples/ANtpHeaderInfo.h"
00018 #include "StandardNtuple/NtpStRecord.h"
00019 #include "CandNtupleSR/NtpSRRecord.h"
00020 #include "CandNtupleSR/NtpSREvent.h"
00021 #include "CandNtupleSR/NtpSRCosmicRay.h"
00022 #include "CandNtupleSR/NtpSREventSummary.h"
00023 #include "CandNtupleSR/NtpSRStrip.h"
00024 #include "CandNtupleSR/NtpSRTrack.h"
00025 #include "CandNtupleSR/NtpSRShower.h"
00026 #include "MCNtuple/NtpMCRecord.h"
00027 #include "MCNtuple/NtpMCTruth.h"
00028 #include "MCNtuple/NtpMCStdHep.h"
00029 #include "DatabaseInterface/DbiResultPtr.h"
00030 #include "BField/BfieldCoilCurrent.h"
00031 #include "DcsUser/CoilTools.h"
00032 #include "DcsUser/Dcs_Mag_Near.h"
00033 #include "DcsUser/BfldDbiCoilState.h"
00034 #include "DcsUser/HvStatusFinder.h"
00035 #include "DcsUser/HvStatus.h"
00036 #include "Conventions/Munits.h"
00037 #include "Conventions/Detector.h"
00038 #include "Conventions/ReleaseType.h"
00039 #include "DataUtil/PlaneOutline.h"
00040 #include "DataUtil/DataQualDB.h"
00041 #include "NtupleUtils/LISieve.h"
00042 #include "VertexFinder/NtpVtxFinder/NtpVtxFinder.h"
00043 #include "AstroUtil/Ast.h"
00044 #include "AstroUtil/AstTime.h"
00045 
00046 #include "TString.h"
00047 #include <cassert>
00048 #include <algorithm>
00049 #include <cmath>
00050 
00051 #include <time.h>
00052 static const double kFarSideLength = 1.656854250;    
00053 static const double kInverseSqrt2 = TMath::Power(2., -0.5);
00054 
00055 using namespace AstUtil;
00056 
00057 ClassImp(ANtpInfoObjectFiller)
00058 
00059 CVSID("$Id: ANtpInfoObjectFiller.cxx,v 1.72 2009/11/16 14:40:56 pittam Exp $");
00060 
00061 //-------------------------------------------------------------------
00062 ANtpInfoObjectFiller::ANtpInfoObjectFiller() :
00063   fStripArray(0),
00064   fDetector(Detector::kUnknown),
00065   fRowNum(0)
00066 {
00067     
00068   MSG("ANtpInfoObjectFiller", Msg::kDebug) 
00069     << "ANtpInfoObjectFiller::Constructor" << endl;
00070   
00071 }
00072 
00073 //-------------------------------------------------------------------
00074 ANtpInfoObjectFiller::ANtpInfoObjectFiller(Detector::Detector_t detector) :
00075   fStripArray(0),
00076   fDetector(detector),
00077   fRowNum(0)
00078 {
00079     
00080   MSG("ANtpInfoObjectFiller", Msg::kDebug) 
00081     << "ANtpInfoObjectFiller::Constructor" << endl;
00082   
00083 }
00084 
00085 //-------------------------------------------------------------------
00086 ANtpInfoObjectFiller::ANtpInfoObjectFiller(TClonesArray *strips) :
00087   fStripArray(strips),
00088   fDetector(Detector::kUnknown),
00089   fRowNum(0)
00090 {
00091     
00092   MSG("ANtpInfoObjectFiller", Msg::kDebug) 
00093     << "ANtpInfoObjectFiller::Constructor" << endl;
00094   
00095 }
00096 
00097 //----------------------------------------------------------------------
00098 ANtpInfoObjectFiller::~ANtpInfoObjectFiller()
00099 {
00100   
00101   MSG("ANtpInfoObjectFiller", Msg::kDebug) 
00102     << "ANtpInfoObjectFiller::Destructor" << endl;
00103   
00104 }
00105 
00106 //----------------------------------------------------------------------
00107 void ANtpInfoObjectFiller::SetDetector(Detector::Detector_t detector)
00108 {
00109   fDetector = detector;
00110   return;
00111 }
00112 
00113 //----------------------------------------------------------------------
00114 //this is the method where you fill all variables related to header information
00115 void ANtpInfoObjectFiller::FillHeaderInformation(ANtpRecoNtpManipulator *ntpManip,
00116                                                  Detector::Detector_t det,
00117                                                  SimFlag::SimFlag_t dataType,
00118                                                  ANtpHeaderInfo *headerInfo)
00119 {
00120   const NtpSREventSummary& summary(ntpManip->GetSnarlEventSummary());
00121 
00122   headerInfo->Reset();
00123   
00124   headerInfo->detector = (int)det;
00125   headerInfo->dataType = (int)dataType;
00126   headerInfo->run = ntpManip->GetRun();
00127   headerInfo->subRun = ntpManip->GetSubRun();
00128   headerInfo->snarl = ntpManip->GetSnarl();
00129   //always call it a new snarl because this method is called once per record
00130   //reset the value in the loop over events in the module
00131   headerInfo->newSnarl = 1; 
00132   headerInfo->triggerSource = ntpManip->GetTriggerSource();
00133   headerInfo->spillType = ntpManip->GetSpillType();
00134   headerInfo->events = summary.nevent;
00135   headerInfo->slices = summary.nslice;
00136   headerInfo->year = (int)summary.date.year;
00137   headerInfo->month = (int)summary.date.month;
00138   headerInfo->day = (int)summary.date.day;
00139   headerInfo->hour = (int)summary.date.hour;
00140   headerInfo->minute = (int)summary.date.minute;
00141   headerInfo->utc = summary.date.utc;
00142 
00143 
00144   headerInfo->second = summary.date.sec;
00145   // It sometimes happens in MRCC files that summary.trigtime and
00146   // summary.date.sec are filled with junk. If this is the case,
00147   // refill the second based on the utc value, which is still
00148   // correct. This means we lose the fractional part, but since
00149   // trigtime is wrong, we couldn't have got it anyway
00150   if(headerInfo->second<0 || headerInfo->second>61 || isnan(headerInfo->second)){
00151     MSG("ANtpInfoObjectFiller", Msg::kWarning) 
00152       << "summary.date.sec out of range (" << summary.date.sec << ") " 
00153       << "Resetting from utc" << endl;
00154     // Code shamelessly stolen from VldTimeStamp::GetTime
00155     time_t atime=summary.date.utc;
00156     struct tm* ptm=gmtime(&atime);
00157     headerInfo->second=ptm->tm_sec;
00158   }
00159 
00160 
00161   double longitude = AstUtil::kFarDetLongitude;
00162   if(det == Detector::kNear) longitude = AstUtil::kNearDetLongitude;
00163   double gmst = 0.;
00164   double hour = 1.*headerInfo->hour + 1.*headerInfo->minute/60. + headerInfo->second/3600.;
00165   AstUtil::CalendarToJulian(headerInfo->year, headerInfo->month, 
00166                             headerInfo->day, hour, headerInfo->julianDate);
00167   AstUtil::JulianToGMST(headerInfo->julianDate, gmst);
00168   AstUtil::GSTToLST(gmst, longitude, headerInfo->localSiderealTime);
00169 
00170   headerInfo->snarlPulseHeight = summary.ph.sigcor;     
00171   headerInfo->triggerPMTTime = summary.litime;
00172   // This still won't protect against the case of trigtime being
00173   // filled with junk that is interpreted as a very tiny positive
00174   // number, but it's the best we can do I think
00175   if(summary.trigtime<0 || summary.trigtime>1){
00176     MSG("ANtpInfoObjectFiller", Msg::kWarning) 
00177       << "summary.trigtime out of range (" << summary.trigtime << ") " 
00178       << "Resetting to zero." << endl;
00179     headerInfo->triggerTime=0;
00180   }
00181   else{
00182     headerInfo->triggerTime = summary.trigtime;
00183   }
00184   headerInfo->passedDeMux = 1;
00185   headerInfo->crateMask = ntpManip->GetDataQuality().cratemask;
00186   //headerInfo->isGoodFDData = (int)DataUtil::IsGoodFDData(ntpManip->GetNtpStRecord());
00187   headerInfo->isGoodData = (int)DataUtil::IsGoodData(ntpManip->GetNtpStRecord());
00188 
00189   //......................................................................
00190   //Now fill new data members
00191   headerInfo->snarlPE = summary.ph.pe;
00192   headerInfo->sntpRow = fRowNum++;
00193   headerInfo->isLIold = LISieve::IsLI( *(ntpManip->GetNtpStRecord()) );
00194   headerInfo->isLI = LISieve::IsLIforNC( *(ntpManip->GetNtpStRecord()) );
00195 
00196   //......................................................................
00197   //Fill Release type member
00198   headerInfo->softVersion = ntpManip->GetReleaseMCType();
00199   
00200   //Passed DeMux flag
00201   if(det == Detector::kFar) {
00202     const NtpSRDmxStatus& dmx( ntpManip->GetDmxStatusInfo());
00203     if (dmx.ismultimuon || dmx.validplanesfail) headerInfo->passedDeMux = 0;
00204   }
00205   
00206   //loop over the strips to figure out the 
00207   double ph2pe = 0.;
00208   double ph = 0.;
00209   NtpSRStrip *strip = 0;
00210   for(int i = 0; i < fStripArray->GetLast()+1; ++i){
00211     strip = dynamic_cast<NtpSRStrip *>(fStripArray->At(i));
00212     ph = strip->ph0.pe+strip->ph1.pe;
00213     if(ph > 2.) ph2pe += strip->ph0.sigcor + strip->ph1.sigcor;
00214   }
00215   headerInfo->snarlPulseHeight2PE = ph2pe;
00216     
00217   //figure out the coil status
00218   headerInfo->coilStatus = 0;
00219 
00220   //coil is always on in the MC
00221   if(dataType == SimFlag::kMC){
00222     headerInfo->coilStatus = 1;
00223     return;
00224   }
00225 
00226   //get the appropriate context
00227   VldTimeStamp timeStamp(headerInfo->year, headerInfo->month, 
00228                          headerInfo->day, headerInfo->hour, 
00229                          headerInfo->minute, 
00230                          TMath::Nint(headerInfo->second));
00231   fVldc = VldContext(det, dataType, timeStamp);
00232 
00233   //check out the HV status of the detector - only works for 
00234   //far detector currently
00235   if(det == Detector::kFar){
00236     HvStatus::HvStatus_t hv = HvStatusFinder::Instance().GetHvStatus(fVldc,60,1);
00237     headerInfo->hvStatus = (int)HvStatus::Good(hv);
00238     //   MSG("ANtpInfoObjectFiller", Msg::kInfo) << HvStatus::Good(hv)
00239     //                                    << " " 
00240     //                                    << headerInfo->hvStatus
00241     //                                    << endl;
00242     const BfldDbiCoilState *farstate = CoilTools::Instance().GetCoilState(fVldc);
00243     if(farstate) headerInfo->coilCurrent =  farstate->GetCurrent();
00244   }
00245   else if(det == Detector::kNear){
00246     const Dcs_Mag_Near *nearstate = CoilTools::Instance().GetMagNear(fVldc);
00247     if(nearstate) headerInfo->coilCurrent = nearstate->GetCurrent();
00248   }
00249 
00250   //CoilTools allows for generic access of the database - no 
00251   //detector dependent stuff needed by user
00252   if( CoilTools::IsReverse(fVldc) ) headerInfo->coilStatus = -1;
00253   else headerInfo->coilStatus = 1;
00254   
00255   if( !CoilTools::IsOK(fVldc) ) headerInfo->coilStatus = 0;
00256 
00257   return;
00258 }
00259 
00260 //----------------------------------------------------------------------
00261 //this is the method where you fill all variables related to a track
00262 void ANtpInfoObjectFiller::FillTrackInformation(NtpSRTrack *ntpTrack, 
00263                                                 ANtpTrackInfo *trackInfo)
00264 {
00265   
00266   trackInfo->Reset();
00267   trackInfo->planes = ntpTrack->plane.n;
00268   trackInfo->totalStrips = ntpTrack->nstrip;
00269   trackInfo->pulseHeight = ntpTrack->ph.sigcor;
00270   if(TMath::Abs(ntpTrack->momentum.qp) > 0.) 
00271     trackInfo->fitMomentum = (1./ntpTrack->momentum.qp);
00272   trackInfo->sigmaQoverP = ntpTrack->momentum.eqp;
00273   trackInfo->rangeMomentum = ntpTrack->momentum.range;                            
00274   trackInfo->begPlane = ntpTrack->plane.beg;
00275   trackInfo->endPlane = ntpTrack->plane.end;
00276   trackInfo->begPlaneU = ntpTrack->plane.begu;
00277   trackInfo->endPlaneU = ntpTrack->plane.endu;
00278   trackInfo->begPlaneV = ntpTrack->plane.begv;
00279   trackInfo->endPlaneV = ntpTrack->plane.endv;
00280   trackInfo->length = ntpTrack->ds;
00281   trackInfo->vtxX = ntpTrack->vtx.x; 
00282   trackInfo->vtxY = ntpTrack->vtx.y; 
00283   trackInfo->vtxZ = ntpTrack->vtx.z; 
00284   trackInfo->dcosXVtx = ntpTrack->vtx.dcosx;
00285   trackInfo->dcosYVtx = ntpTrack->vtx.dcosy;
00286   trackInfo->dcosZVtx = ntpTrack->vtx.dcosz;
00287   trackInfo->endX = ntpTrack->end.x; 
00288   trackInfo->endY = ntpTrack->end.y; 
00289   trackInfo->endZ = ntpTrack->end.z; 
00290   trackInfo->dcosXEnd = ntpTrack->end.dcosx;
00291   trackInfo->dcosYEnd = ntpTrack->end.dcosy;
00292   trackInfo->dcosZEnd = ntpTrack->end.dcosz;
00293   trackInfo->passedFit = 0;
00294   if(ntpTrack->fit.pass) trackInfo->passedFit = 1;
00295   trackInfo->reducedChi2 = ntpTrack->fit.chi2;
00296   if(ntpTrack->fit.ndof>0.) 
00297     trackInfo->reducedChi2 /= 1.*ntpTrack->fit.ndof;
00298 
00299   trackInfo->forwardRMS = ntpTrack->time.forwardRMS;
00300   trackInfo->backwardRMS = ntpTrack->time.backwardRMS;
00301 
00302     GetTrackTrace(ntpTrack, trackInfo, -1);
00303   GetTrackTrace(ntpTrack, trackInfo, 1);
00304 
00305   FillFiducialInformation(trackInfo);
00306 
00307   //loop over the strips in the track and record which planes they are on
00308   NtpSRStrip *strip = 0;
00309   for(int i = 0; i < trackInfo->totalStrips; ++i){
00310     if (ntpTrack->stp[i] >=0) strip = dynamic_cast<NtpSRStrip *>
00311                                 (fStripArray->At(ntpTrack->stp[i]));
00312     else continue;
00313     ++trackInfo->stripsPerPlane[strip->plane];
00314   }
00315     
00316   return;
00317 }
00318 
00319 //----------------------------------------------------------------------
00320 //this is the method where you fill all variables related to a shower
00321 void ANtpInfoObjectFiller::FillShowerInformation(NtpSRShower *ntpShower,
00322                                                  ANtpShowerInfo *showerInfo)
00323 {
00324   showerInfo->Reset();
00325   showerInfo->planes = ntpShower->plane.n;
00326   showerInfo->totalStrips = ntpShower->nstrip;
00327   showerInfo->begPlane = ntpShower->plane.beg;
00328   showerInfo->endPlane = ntpShower->plane.end;
00329   showerInfo->vtxX = ntpShower->vtx.x;
00330   showerInfo->vtxY = ntpShower->vtx.y;
00331   showerInfo->vtxZ = ntpShower->vtx.z;
00332   showerInfo->dcosX = ntpShower->vtx.dcosx;
00333   showerInfo->dcosY = ntpShower->vtx.dcosy;
00334   showerInfo->dcosZ = ntpShower->vtx.dcosz;
00335   showerInfo->pulseHeight = ntpShower->ph.sigcor;//used to be sigmap
00336   showerInfo->linearCCGeV = ntpShower->shwph.linCCgev;
00337   showerInfo->linearNCGeV = ntpShower->shwph.linNCgev;
00338   showerInfo->deweightCCGeV = ntpShower->shwph.wtCCgev;
00339   showerInfo->deweightNCGeV = ntpShower->shwph.wtNCgev;
00340 
00341   //loop over the strips in the shower and record which planes they are on
00342   NtpSRStrip *strip = 0;
00343   for(int i = 0; i < showerInfo->totalStrips; ++i){
00344     strip = dynamic_cast<NtpSRStrip *>(fStripArray->At(ntpShower->stp[i]));
00345     ++showerInfo->stripsPerPlane[strip->plane];
00346   }
00347   
00348   return;
00349 }
00350 
00351 //----------------------------------------------------------------------
00352 //this is the method where you fill all variables related to an event
00353 void ANtpInfoObjectFiller::FillEventInformation(ANtpRecoNtpManipulator *ntpManip, 
00354                                                 NtpSREvent *ntpEvent,
00355                                                 ANtpEventInfo *eventInfo)
00356 {
00357 
00358   eventInfo->Reset();
00359   eventInfo->index = static_cast <int> (ntpEvent->index);
00360   eventInfo->pulseHeight = ntpEvent->ph.sigcor;
00361   eventInfo->energyGeV = ntpEvent->ph.gev;
00362   eventInfo->begPlane = ntpEvent->plane.beg;
00363   eventInfo->endPlane = ntpEvent->plane.end;
00364   eventInfo->planes = ntpEvent->plane.n;
00365   
00366   //add up the pulse height in each plane to find the maximum in the event
00367   eventInfo->totalStrips = ntpEvent->nstrip;
00368   
00369   //write your own criterea for whether a strip is good or not
00370   eventInfo->passStrips = ntpEvent->nstrip;
00371   
00372   eventInfo->showers = ntpEvent->nshower;
00373   eventInfo->tracks = ntpEvent->ntrack;
00374 
00375   //Correct cedar vertex bug 
00376   TString reco = ntpManip->GetReleaseMCType();
00377   if(reco.Contains((ReleaseType::AsString(ReleaseType::kCedarData)).c_str()) || 
00378      reco.Contains((ReleaseType::AsString(ReleaseType::kCedarCarrot)).c_str()) ||
00379      reco.Contains((ReleaseType::AsString(ReleaseType::kCedarDaikon)).c_str())){
00380     
00381     NtpVtxFinder::NtpVtxFinder vtxf;
00382     vtxf.SetTargetEvent(static_cast <int> (ntpEvent->index), 
00383                    ntpManip->GetNtpStRecord());
00384     if (vtxf.FindVertex()<0){ //Take existing vertex if fix cannot be used
00385       eventInfo->vtxX = ntpEvent->vtx.x;
00386       eventInfo->vtxY = ntpEvent->vtx.y;
00387       eventInfo->vtxZ = ntpEvent->vtx.z;
00388       eventInfo->vertexTime = ntpEvent->vtx.t;
00389     } else {
00390       eventInfo->vtxX = vtxf.VtxX();
00391       eventInfo->vtxY = vtxf.VtxY();
00392       eventInfo->vtxZ = vtxf.VtxZ();
00393       eventInfo->vertexTime = vtxf.VtxT();
00394     }//if(vtxf.FindVertex())
00395     
00396   } else {
00397     eventInfo->vtxX = ntpEvent->vtx.x;
00398     eventInfo->vtxY = ntpEvent->vtx.y;
00399     eventInfo->vtxZ = ntpEvent->vtx.z;
00400     eventInfo->vertexTime = ntpEvent->vtx.t;
00401   }//if(reco.Contains(...))
00402 
00403   FillFiducialInformation(eventInfo);
00404 
00405   if(!fStripArray) return;
00406 
00407   //loop over the strips in the shower and record which planes they are on
00408   NtpSRStrip *strip = 0;
00409   for(int i = 0; i < eventInfo->totalStrips; ++i){
00410     if (ntpEvent->stp[i] >= 0) strip = dynamic_cast<NtpSRStrip *>
00411                                   (fStripArray->At(ntpEvent->stp[i]));
00412     else continue;
00413     ++eventInfo->stripsPerPlane[strip->plane];
00414   }
00415   
00416   return;
00417 }
00418 
00419 //----------------------------------------------------------------------
00420 //this is the method where you fill all variables related to the MC truth
00421 void ANtpInfoObjectFiller::FillMCTruthInformation(NtpMCTruth *ntpMCTruth,
00422                                                   ANtpTruthInfo *truthInfo)
00423 {
00424   const Float_t muMass = 0.105658357; //mu mass in GeV/c
00425   const Float_t eMass = 0.000510999; //e mass in GeV/c
00426   const Float_t tauMass = 1.777;      //tau mass in GeV/c
00427 
00428   truthInfo->Reset();
00429   truthInfo->nuEnergy = ntpMCTruth->p4neu[3];
00430   truthInfo->nuVtxX = ntpMCTruth->vtxx;
00431   truthInfo->nuVtxY = ntpMCTruth->vtxy;
00432   truthInfo->nuVtxZ = ntpMCTruth->vtxz;
00433   if(TMath::Abs(truthInfo->nuEnergy) > 0.){
00434     truthInfo->nuDCosX = ntpMCTruth->p4neu[0]/TMath::Sqrt(truthInfo->nuEnergy*truthInfo->nuEnergy);
00435     truthInfo->nuDCosY = ntpMCTruth->p4neu[1]/TMath::Sqrt(truthInfo->nuEnergy*truthInfo->nuEnergy);
00436     truthInfo->nuDCosZ = ntpMCTruth->p4neu[2]/TMath::Sqrt(truthInfo->nuEnergy*truthInfo->nuEnergy);             
00437   }
00438   else{
00439     truthInfo->nuDCosX = -10000.;
00440     truthInfo->nuDCosY = -10000.;
00441     truthInfo->nuDCosZ = -10000.;
00442   }
00443   truthInfo->nuFlavor = ntpMCTruth->inu;
00444   truthInfo->interactionType = ntpMCTruth->iaction;
00445   
00446   truthInfo->targetEnergy = ntpMCTruth->p4tgt[3];
00447   truthInfo->targetPX = ntpMCTruth->p4tgt[0];
00448   truthInfo->targetPY = ntpMCTruth->p4tgt[1];
00449   truthInfo->targetPZ = ntpMCTruth->p4tgt[2];
00450   
00451   truthInfo->hadronicY = ntpMCTruth->y;
00452   
00453   truthInfo->showerEnergy = 0.;
00454   float showerMomentumSqr = 0.;
00455   if(ntpMCTruth->p4shw[3]>0. && TMath::Abs(ntpMCTruth->p4shw[0] + 
00456                                            ntpMCTruth->p4shw[1] + 
00457                                            ntpMCTruth->p4shw[2]) > 0.){
00458     truthInfo->showerEnergy = ntpMCTruth->p4shw[3];
00459     showerMomentumSqr = ntpMCTruth->p4shw[0]*ntpMCTruth->p4shw[0];
00460     showerMomentumSqr += ntpMCTruth->p4shw[1]*ntpMCTruth->p4shw[1];
00461     showerMomentumSqr += ntpMCTruth->p4shw[2]*ntpMCTruth->p4shw[2];
00462     truthInfo->showerDCosX = ntpMCTruth->p4shw[0]/TMath::Sqrt(showerMomentumSqr);
00463     truthInfo->showerDCosY = ntpMCTruth->p4shw[1]/TMath::Sqrt(showerMomentumSqr);
00464     truthInfo->showerDCosZ = ntpMCTruth->p4shw[2]/TMath::Sqrt(showerMomentumSqr);
00465   }
00466   else{
00467     truthInfo->showerDCosX = ANtpDefVal::kFloat;
00468     truthInfo->showerDCosY = ANtpDefVal::kFloat;
00469     truthInfo->showerDCosZ = ANtpDefVal::kFloat;
00470   }
00471   
00472   truthInfo->leptonMomentum = 0.;
00473   if(TMath::Abs(ntpMCTruth->p4mu1[3])>muMass){
00474     truthInfo->leptonMomentum = TMath::Sqrt(ntpMCTruth->p4mu1[3]*ntpMCTruth->p4mu1[3] - muMass*muMass);
00475     truthInfo->leptonDCosX = ntpMCTruth->p4mu1[0]/truthInfo->leptonMomentum;
00476     truthInfo->leptonDCosY = ntpMCTruth->p4mu1[1]/truthInfo->leptonMomentum;
00477     truthInfo->leptonDCosZ = ntpMCTruth->p4mu1[2]/truthInfo->leptonMomentum;            
00478     if(ntpMCTruth->p4mu1[3]<0.) truthInfo->leptonMomentum *= -1.;
00479   }
00480   else if(TMath::Abs(ntpMCTruth->p4el1[3])>eMass){
00481     truthInfo->leptonMomentum = TMath::Sqrt(ntpMCTruth->p4el1[3]*ntpMCTruth->p4el1[3] - eMass*eMass);
00482     truthInfo->leptonDCosX = ntpMCTruth->p4el1[0]/truthInfo->leptonMomentum;
00483     truthInfo->leptonDCosY = ntpMCTruth->p4el1[1]/truthInfo->leptonMomentum;
00484     truthInfo->leptonDCosZ = ntpMCTruth->p4el1[2]/truthInfo->leptonMomentum;            
00485     if(ntpMCTruth->p4el1[3]<0.) truthInfo->leptonMomentum *= -1.;
00486   }
00487   else if(TMath::Abs(ntpMCTruth->p4tau[3])>tauMass){
00488     truthInfo->leptonMomentum = TMath::Sqrt(ntpMCTruth->p4tau[3]*ntpMCTruth->p4tau[3] - tauMass*tauMass);
00489     truthInfo->leptonDCosX = ntpMCTruth->p4tau[0]/truthInfo->leptonMomentum;
00490     truthInfo->leptonDCosY = ntpMCTruth->p4tau[1]/truthInfo->leptonMomentum;
00491     truthInfo->leptonDCosZ = ntpMCTruth->p4tau[2]/truthInfo->leptonMomentum;            
00492     if(ntpMCTruth->p4tau[3]<0.) truthInfo->leptonMomentum *= -1.;
00493   }
00494   else{
00495     truthInfo->leptonDCosX = ANtpDefVal::kFloat;
00496     truthInfo->leptonDCosY = ANtpDefVal::kFloat;
00497     truthInfo->leptonDCosZ = ANtpDefVal::kFloat;                
00498   }
00499     
00500   
00501   return;
00502 }
00503 
00504 //----------------------------------------------------------------------
00505 void ANtpInfoObjectFiller::FillFiducialInformation(ANtpTrackInfo *trackInfo)
00506 {
00507   double x = trackInfo->vtxX; 
00508   double y = trackInfo->vtxY;
00509   double z = trackInfo->vtxZ;
00510 
00511   trackInfo->vtxMetersToBeam = MetersToBeam(fDetector, x, y, z); 
00512   trackInfo->vtxMetersToCoil = MetersToCoil(fDetector, x, y); 
00513   trackInfo->vtxMetersToCloseEdge = MetersToCloseEdge(fDetector, x,y, 0);
00514   
00515   x = trackInfo->endX; 
00516   y = trackInfo->endY;
00517   z = trackInfo->endZ;
00518 
00519   trackInfo->endMetersToBeam = MetersToBeam(fDetector, x, y, z);
00520   trackInfo->endMetersToCoil = MetersToCoil(fDetector, x, y);
00521   trackInfo->endMetersToCloseEdge = MetersToCloseEdge(fDetector, x, y, 1);
00522   return;
00523 }
00524 
00525 //----------------------------------------------------------------------
00526 void ANtpInfoObjectFiller::FillFiducialInformation(ANtpEventInfo *eventInfo)
00527 {
00528   double x = eventInfo->vtxX; 
00529   double y = eventInfo->vtxY;
00530   double z = eventInfo->vtxZ;
00531   
00532   eventInfo->vtxMetersToBeam = MetersToBeam(fDetector, x, y, z); 
00533   eventInfo->vtxMetersToCoil = MetersToCoil(fDetector, x, y); 
00534   eventInfo->vtxMetersToCloseEdge = MetersToCloseEdge(fDetector, x, y, 0);
00535 
00536   return;
00537 }
00538 
00539 //----------------------------------------------------------------------
00540 void ANtpInfoObjectFiller::SetStripArray(TClonesArray *strips)
00541 {
00542   fStripArray = strips;
00543   return;
00544 }
00545 
00546 //----------------------------------------------------------------------
00547 double ANtpInfoObjectFiller::Sqr(double x)
00548 {
00549   return x*x;
00550 }
00551 
00552 //----------------------------------------------------------------------
00553 int ANtpInfoObjectFiller::Sqr(int x)
00554 {
00555   return x*x;
00556 }
00557 
00558 //----------------------------------------------------------------------
00559 float ANtpInfoObjectFiller::Sqr(float x)
00560 {
00561   return x*x;
00562 }
00563 
00564 //------------------------------------------------------------------------
00565 void ANtpInfoObjectFiller::GetTrackTrace(NtpSRTrack *ntpTrack, 
00566                                          ANtpTrackInfo *trackInfo,
00567                                          Int_t direction)
00568 {
00569   
00570   //get the trace for the track - this is very far detector centric for now,
00571   //adapted from C. Howcroft's code
00572   
00573   //direction tells you whether to trace back from vertex (-1) or forward from end (1)
00574   
00575   //side is as labeled below
00576   /*
00577              0
00578           --------
00579        7 /        \ 1
00580         /   y|     \
00581      6 |     |      | 2
00582        |     ----   |
00583       5 \      x   / 3
00584          \        /
00585           --------
00586               4
00587   */  
00588   double dcos[3] = {direction*ntpTrack->vtx.dcosx,
00589                     direction*ntpTrack->vtx.dcosy,
00590                     direction*ntpTrack->vtx.dcosz}; 
00591   double dcosUV[3] = {direction*ntpTrack->vtx.dcosu,
00592                       direction*ntpTrack->vtx.dcosv,
00593                       direction*ntpTrack->vtx.dcosz}; 
00594   double endPointXY[3] = {ntpTrack->vtx.x, ntpTrack->vtx.y, ntpTrack->vtx.z};
00595   double endPointUV[3] = {ntpTrack->vtx.u, ntpTrack->vtx.v, ntpTrack->vtx.z};
00596   
00597   if(direction > 0){
00598     endPointXY[0] = ntpTrack->end.x;
00599     endPointXY[1] = ntpTrack->end.y;
00600     endPointXY[2] = ntpTrack->end.z;
00601     endPointUV[0] = ntpTrack->end.u;
00602     endPointUV[1] = ntpTrack->end.v;
00603     endPointUV[2] = ntpTrack->end.z;
00604     dcos[0] = ntpTrack->end.dcosx;
00605     dcos[1] = ntpTrack->end.dcosy;
00606     dcos[2] = ntpTrack->end.dcosz;
00607     dcosUV[0] = ntpTrack->end.dcosu;
00608     dcosUV[1] = ntpTrack->end.dcosv;
00609     dcosUV[2] = ntpTrack->end.dcosz;
00610   }
00611   
00612   int side = -1;
00613   double xzproj[2]={-999., -999.};   
00614   double entry[3] = {0.};
00615   double minpath = 99e99;
00616   double tmppath = 0.;
00617   double maxDetectorY = 4.;
00618   double sidelength = kFarSideLength;
00619   
00620   if(TMath::IsNaN(endPointUV[0]) || TMath::IsNaN(endPointUV[1]) 
00621      || TMath::IsNaN(dcosUV[0]) || TMath::IsNaN(dcosUV[1]) 
00622      || TMath::IsNaN(dcos[2])) return;
00623   
00624   if(TMath::Abs(dcos[1])>1.e-6){ 
00625     // Y - SIDES
00626     //SIDE 0 
00627     xzproj[0] = endPointXY[0] + (dcos[0]/dcos[1])*(maxDetectorY - endPointXY[1]);
00628     xzproj[1] = endPointXY[2] + (dcos[2]/dcos[1])*(maxDetectorY - endPointXY[1]);
00629     if(TMath::Abs(xzproj[0]) < sidelength && ((xzproj[1] -  endPointXY[2])*dcos[2]) > 0.0){
00630       tmppath = Sqr(endPointXY[0] - xzproj[0]) 
00631               + Sqr(endPointXY[1] - maxDetectorY) 
00632               + Sqr(endPointXY[2] - xzproj[1]);
00633       if(TMath::Finite(tmppath)){
00634         tmppath = TMath::Sqrt(tmppath);
00635         if(tmppath < minpath){
00636           minpath  = tmppath;
00637           entry[0] = xzproj[0];
00638           entry[2] = xzproj[1];
00639           entry[1] = maxDetectorY;
00640           side     = 0;
00641         }                       
00642       }      
00643     }//end side 0
00644     //SIDE 4 
00645     xzproj[0] = endPointXY[0] + (dcos[0]/dcos[1])*(-maxDetectorY - endPointXY[1]);
00646     xzproj[1] = endPointXY[2] + (dcos[2]/dcos[1])*(-maxDetectorY - endPointXY[1]);
00647     if(TMath::Abs(xzproj[0]) < sidelength && ((xzproj[1] -  endPointXY[2])*dcos[2]) > 0.0){
00648       tmppath = Sqr(endPointXY[0] - xzproj[0]) 
00649               + Sqr(endPointXY[1] + maxDetectorY) 
00650               + Sqr(endPointXY[2] - xzproj[1]);
00651       if(TMath::Finite(tmppath)){
00652         tmppath = TMath::Sqrt(tmppath);
00653         if(tmppath<minpath){
00654           minpath  = tmppath;
00655           entry[0] = xzproj[0];
00656           entry[2] = xzproj[1];
00657           entry[1] = -maxDetectorY;
00658           side     = 4;
00659         }                       
00660       }      
00661     }//end side 4
00662   }//end Y sides
00663   if(TMath::Abs(dcos[0])>1e-6){  // X - SIDES
00664     //SIDE 2 
00665     xzproj[0] = endPointXY[1] + (dcos[1]/dcos[0])*(maxDetectorY - endPointXY[0]);
00666     xzproj[1] = endPointXY[2] + (dcos[2]/dcos[0])*(maxDetectorY - endPointXY[0]);
00667     if(TMath::Abs(xzproj[0]) < sidelength && ((xzproj[1] -  endPointXY[2])*dcos[2]) > 0.0){
00668       tmppath = (endPointXY[1] - xzproj[0])    * (endPointXY[1] - xzproj[0]) 
00669               + (endPointXY[0] - maxDetectorY) * (endPointXY[0] - maxDetectorY) 
00670               + (endPointXY[2] - xzproj[1])    * (endPointXY[2] - xzproj[1]);
00671       if(TMath::Finite(tmppath)){
00672         tmppath = TMath::Sqrt(tmppath);
00673         if(tmppath<minpath){
00674           minpath  = tmppath;
00675           entry[1] = xzproj[0];
00676           entry[2] = xzproj[1];
00677           entry[0] = maxDetectorY;
00678           side     = 2;
00679         }               
00680       }       
00681     }//end side 2      
00682     //SIDE 6 
00683     xzproj[0] = endPointXY[1] + (dcos[1]/dcos[0])*(-maxDetectorY - endPointXY[0]);
00684     xzproj[1] = endPointXY[2] + (dcos[2]/dcos[0])*(-maxDetectorY - endPointXY[0]);
00685     if(TMath::Abs(xzproj[0]) < sidelength && ((xzproj[1] -  endPointXY[2])*dcos[2]) > 0.0){
00686       tmppath = Sqr(endPointXY[1] - xzproj[0]) 
00687               + Sqr(endPointXY[0] + maxDetectorY) 
00688               + Sqr(endPointXY[2] - xzproj[1]);
00689       if(TMath::Finite(tmppath)){
00690         tmppath = TMath::Sqrt(tmppath);
00691         if(tmppath<minpath){
00692           minpath  = tmppath;
00693           entry[1] = xzproj[0];
00694           entry[2] = xzproj[1];
00695           entry[0] = -maxDetectorY;
00696           side     = 6;
00697         }
00698       }                       
00699     }//end if side 6      
00700   }//end x sides
00701   if(TMath::Abs(dcosUV[0])>1.e-6){  // U - SIDES
00702     //SIDE 1 
00703     xzproj[0] = endPointUV[1] + (dcosUV[1]/dcosUV[0])*(maxDetectorY - endPointUV[0]);
00704     xzproj[1] = endPointXY[2] + (dcos[2]/dcosUV[0])*(maxDetectorY - endPointUV[0]);
00705     if(TMath::Abs(xzproj[0]) < sidelength && ((xzproj[1] -  endPointXY[2])*dcos[2]) > 0.0){
00706       tmppath = Sqr(ntpTrack->vtx.v - xzproj[0]) 
00707               + Sqr(ntpTrack->vtx.u - maxDetectorY) 
00708               + Sqr(endPointXY[2] - xzproj[1]);
00709       if(TMath::Finite(tmppath)){
00710         tmppath = TMath::Sqrt(tmppath);
00711         if(tmppath<minpath){
00712           minpath  = tmppath;
00713           entry[0] = kInverseSqrt2*(maxDetectorY - xzproj[0]) ;
00714           entry[2] = xzproj[1];
00715           entry[1] = kInverseSqrt2*(maxDetectorY + xzproj[0]) ;
00716           side     = 1;
00717         }                       
00718       }      
00719     }//end if side1 
00720     //SIDE 5 
00721     xzproj[0] = endPointUV[1] + (dcosUV[1]/dcosUV[0])*(-maxDetectorY - endPointUV[0]);
00722     xzproj[1] = endPointXY[2] + (dcos[2]/dcosUV[0])*(-maxDetectorY - endPointUV[0]);
00723     if(TMath::Abs(xzproj[0]) < sidelength && ((xzproj[1] -  endPointXY[2])*dcos[2]) > 0.0){
00724       tmppath = Sqr(ntpTrack->vtx.v - xzproj[0]) 
00725               + Sqr(ntpTrack->vtx.u + maxDetectorY) 
00726               + Sqr(endPointXY[2] - xzproj[1]);
00727       if(TMath::Finite(tmppath)){
00728         tmppath = TMath::Sqrt(tmppath);
00729         if(tmppath<minpath){
00730           minpath  = tmppath;
00731           entry[0] = kInverseSqrt2*(-maxDetectorY - xzproj[0]) ;
00732           entry[2] = xzproj[1];
00733           entry[1] = kInverseSqrt2*(-maxDetectorY + xzproj[0]) ;
00734           side     = 5;
00735         }                             
00736       }
00737     }//end if side 5 
00738   }//end u sides
00739   if(TMath::Abs(dcosUV[1])>1.e-6){  // V - SIDES
00740     //SIDE 7
00741     xzproj[0] = endPointUV[0] + (dcosUV[0]/dcosUV[1])*(maxDetectorY - endPointUV[1]);
00742     xzproj[1] = endPointXY[2] + (dcos[2]/dcosUV[1])*(maxDetectorY - endPointUV[1]);
00743     if(TMath::Abs(xzproj[0]) < sidelength && ((xzproj[1] -  endPointXY[2])*dcos[2]) > 0.0){
00744       tmppath =  Sqr(ntpTrack->vtx.u - xzproj[0]) 
00745               + Sqr(ntpTrack->vtx.v - maxDetectorY) 
00746               + Sqr(endPointXY[2] - xzproj[1]);
00747       if(TMath::Finite(tmppath)){
00748         tmppath = TMath::Sqrt ( tmppath);
00749         if(tmppath<minpath){
00750           minpath  = tmppath;
00751           entry[0] = kInverseSqrt2*(xzproj[0]-maxDetectorY) ;
00752           entry[2] = xzproj[1];
00753           entry[1] = kInverseSqrt2*(xzproj[0]+maxDetectorY) ;
00754           side     = 7;
00755         }                       
00756       }      
00757     }//end if side7
00758     //SIDE 3
00759     xzproj[0] = endPointUV[0] + (dcosUV[0]/dcosUV[1])*(-maxDetectorY - endPointUV[1]);
00760     xzproj[1] = endPointXY[2] + (dcos[2]/dcosUV[1])*(-maxDetectorY - endPointUV[1]);
00761     if(TMath::Abs(xzproj[0]) < sidelength && ((xzproj[1] -  endPointXY[2])*dcos[2]) > 0.0){
00762       tmppath = Sqr(ntpTrack->vtx.u - xzproj[0]) 
00763               + Sqr(ntpTrack->vtx.v + maxDetectorY) 
00764               + Sqr(endPointXY[2] - xzproj[1]);
00765       if(TMath::Finite(tmppath)){
00766         tmppath = TMath::Sqrt(tmppath);
00767         if(tmppath<minpath){
00768           minpath  = tmppath;
00769           entry[0] = kInverseSqrt2*(xzproj[0]+maxDetectorY) ;
00770           entry[2] = xzproj[1];
00771           entry[1] = kInverseSqrt2*(xzproj[0]-maxDetectorY) ;
00772           side     = 3;
00773         }                         
00774       }    
00775     }//end if side 3    
00776   }//end v sides
00777   
00778   if(direction < 0){
00779     trackInfo->traceVtx = TMath::Sqrt(Sqr(endPointXY[0]-entry[0]) + Sqr(endPointXY[1]-entry[1])
00780                                       + Sqr(endPointXY[2]-entry[2]));
00781     trackInfo->traceVtxZ = entry[2] - endPointXY[2];
00782     
00783   } 
00784   else if(direction > 0){
00785     trackInfo->traceEnd = TMath::Sqrt(Sqr(ntpTrack->end.x-entry[0]) + Sqr(ntpTrack->end.y-entry[1])
00786                                       + Sqr(ntpTrack->end.z-entry[2]));
00787     trackInfo->traceEndZ = entry[2] - ntpTrack->end.z;
00788     
00789   } 
00790   
00791   return;
00792 }
00793 
00794 //----------------------------------------------------------------------
00795 Float_t ANtpInfoObjectFiller::MetersToBeam(Detector::Detector_t det,
00796                                            Float_t x, Float_t y,
00797                                            Float_t z)
00798 
00799   // Calculate the distance to the beam spot at this Z position
00800   // From my log book:
00801   // Beam is at x = 1.4485m
00802   // Beam dy/dz = -0.0578 (angle = -3.31deg) to the z-axis 
00803   // Beam passes through y = 0 at back of golden region (plane 90)
00804   //  \-> Beam passes through y = 0.3087 @ z = 0  
00805   // Still looking for hard evidence about this.
00806 {
00807   if (det == Detector::kNear) {
00808     const Float_t dydz(-0.0578); 
00809     const Float_t beamCenterX(1.4885 * Munits::m);
00810     const Float_t beamCenterY0(0.3087 * Munits::m);
00811 
00812     x -= beamCenterX;
00813     y -= beamCenterY0 + dydz * z; 
00814     return TMath::Sqrt(x*x + y*y);
00815   }
00816 
00817   else if (det == Detector::kFar){
00818     //Beam center is faintly meaningless for FD cut
00819     return ANtpDefVal::kFloat;
00820   }
00821 
00822   else return ANtpDefVal::kFloat;
00823 }
00824 //----------------------------------------------------------------------
00825 Float_t ANtpInfoObjectFiller::MetersToCoil(Detector::Detector_t det,
00826                                            Float_t x, Float_t y)
00827 {
00828   if (det == Detector::kNear){
00829    // Take coil to be at (0,0) Looks about right...  (?) 
00830     return TMath::Sqrt(x*x + y*y);
00831   }
00832 
00833   else if (det == Detector::kFar){
00834     return TMath::Sqrt(x*x + y*y);    
00835   }
00836 
00837   else return ANtpDefVal::kFloat;
00838 }       
00839                                    
00840 //----------------------------------------------------------------------
00841 Float_t ANtpInfoObjectFiller::MetersToCloseEdge(Detector::Detector_t det,
00842                                                 Float_t x, Float_t y,
00843                                                 Bool_t NDUseFullPlane)
00844 {
00845   // Calculate the distance to the nearest (outside) plane edge
00846   // using the PlaneOutline class. 
00847   // Currently takes distance to nearest edges seperatly for U and V
00848   // views, then takes the average of the two distances.
00849   // It would be better to take a single distance to an average plane
00850   // but this is not yet possible.
00851 
00852   if (det == Detector::kNear || det == Detector::kFar ){
00853     
00854     // Pick a plane coverage
00855     PlaneCoverage::PlaneCoverage_t outline(PlaneCoverage::kComplete);
00856     if (det == Detector::kNear){
00857       if (NDUseFullPlane) outline = PlaneCoverage::kNearFull;
00858       else outline = PlaneCoverage::kNearPartial;
00859     }
00860 
00861     PlaneOutline po;  
00862     
00863     // Calculate distance (to nearest outside edge) in U. 
00864     Float_t distU(0.);
00865     Float_t xedge; Float_t yedge; 
00866     po.DistanceToOuterEdge(x, y, PlaneView::kU, outline,
00867                            distU, xedge, yedge);
00868 
00869     // Calculate distance in V.
00870     Float_t distV(0.);
00871     po.DistanceToOuterEdge(x, y, PlaneView::kV, outline,
00872                            distV, xedge, yedge); 
00873 
00874     // Now work out if the point is inside or outside each outline
00875     // Firstly deal with the coil hole. We consider it inside,
00876     // but the PlaneOutline class calls it outside.
00877     
00878     Bool_t insideU(0.); 
00879     if ( outline != PlaneCoverage::kNearPartial ) {
00880       // circle of radius 1/sqrt(2) will enclose the coilHole, 
00881       // but is itself enclosed by the outer edges
00882       insideU = ( (x*x + y*y) < 0.5 * Munits::m2 );
00883       //cout << "X: " << x << ";   Y: " 
00884       //           << y << ";   inside:" << insideU << endl;
00885     }
00886     
00887     Bool_t insideV(insideU);
00888     if ( !insideU ){ 
00889       insideU = po.IsInside(x, y, PlaneView::kU, outline);
00890       insideV = po.IsInside(x, y, PlaneView::kV, outline);
00891     }
00892     distU *= ( insideU ? 1. : -1. );
00893     distV *= ( insideV ? 1. : -1. );
00894 
00895     //    cout << ">U<: " << insideU << "   " << distU << "\n";
00896     //cout << ">V<: " << insideV << "   " << distV;
00897     
00898     return ( distU + distV ) / 2.;
00899   }  // if ( @ near or far detectors )
00900 
00901   else return ANtpDefVal::kFloat;    
00902 }

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