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

FillMuonId.cxx

Go to the documentation of this file.
00001 // $Id: FillMuonId.cxx,v 1.25 2009/07/31 16:28:11 jyuko Exp $
00002 
00003 //C++
00004 #include <iostream>
00005 #include <numeric>
00006 #include <sstream>
00007 
00008 //MINOS
00009 #include "Calibrator/Calibrator.h"
00010 #include "Plex/PlexStripEndId.h"
00011 #include "Registry/Registry.h"
00012 #include "UgliGeometry/UgliGeomHandle.h"
00013 #include "Validity/VldContext.h"
00014 
00015 //Local
00016 #include "PhysicsNtuple/Default.h"
00017 #include "PhysicsNtuple/Factory.h"
00018 
00019 //Local
00020 #include "FillMuonId.h"
00021 
00022 REGISTER_ANP_OBJECT(AlgSnarl,FillMuonId)
00023 REGISTER_ANP_OBJECT(AlgEvent,FillMuonId)
00024 
00025 using namespace std;
00026 
00027 //---------------------------------------------------------------------------------------
00028 Anp::FillMuonId::FillMuonId()
00029    :fStripWindow(4),
00030     fMinViewNPlane(5),
00031     fKeyBase(7000),
00032     fKeyPass(-1),
00033     fTimeWindow((2.0*18.83 + 0.1)*1.0e-9),
00034     fMinStripAdc(0.0),
00035     fMinStripMip(0.0),
00036     fADCShiftMuon(-14.0),
00037     fADCShiftMuonSpect(-79.0),
00038     fADCShiftOther(10.0),
00039     fADCShiftOtherSpect(0.0),
00040     fIsStudy(false),
00041     fFillDetec(true),
00042     fFillEvent(true),
00043     fFillShift(false),
00044     fFillShort(false)
00045 {
00046 }
00047 
00048 //------------------------------------------------------------------------------------------
00049 Anp::FillMuonId::~FillMuonId()
00050 {
00051 }
00052 
00053 //---------------------------------------------------------------------------------------
00054 Anp::FillMuonId::PlaneData::PlaneData()
00055    :min_strip(-1),
00056     max_strip(-1),
00057     track_vec(),
00058     other_vec(),
00059     tpos(0.0)
00060 {
00061 }
00062 
00063 //------------------------------------------------------------------------------------------
00064 bool Anp::FillMuonId::Run(Record &record)
00065 {
00066    map<short, const DataMap> track_dmap;
00067 
00068    for(TrackIterator track = record.TrackBegIterator(); track != record.TrackEndIterator(); ++track)
00069    {
00070       //
00071       // Check if KeyPass exists
00072       //
00073       if(fKeyPass > 0 && !(track -> KeyExists(fKeyPass)))
00074       {
00075          continue;
00076       }
00077 
00078       const DataMap dmap = FillMuonId::Run(*track, record);
00079 
00080       for(DataMap::const_iterator it = dmap.begin(); it != dmap.end(); ++it)
00081       {
00082          track -> Add(it -> first, it -> second);
00083       }
00084 
00085       if(!track_dmap.insert(map<short, const DataMap>::value_type(track -> TrackIndex(), dmap)).second)
00086       {
00087          cerr << "FillMuonId::Run - duplicate track index " << track -> TrackIndex() << endl;
00088       }
00089    }
00090 
00091    if(!fFillEvent || track_dmap.empty())
00092    {
00093       return true;
00094    }
00095 
00096    for(EventIterator event = record.EventBegIterator(); event != record.EventEndIterator(); ++event)
00097    {
00098       const TrackIter track = Anp::LongestTrack(*event, record);
00099       if(track == record.TrackEnd())
00100       {
00101          continue;
00102       }
00103 
00104       map<short, const DataMap>::const_iterator dit = track_dmap.find(track -> TrackIndex());
00105       if(dit == track_dmap.end())
00106       {
00107          cerr << "FillMuonId::Run - failed to find track index " << track -> TrackIndex() << endl;
00108          continue;
00109       }
00110       
00111       const DataMap &dmap = dit -> second;
00112 
00113       for(DataMap::const_iterator it = dmap.begin(); it != dmap.end(); ++it)
00114       {
00115          event -> Add(it -> first, it -> second);
00116       }     
00117    } 
00118 
00119    return true;
00120 }
00121 
00122 //----------------------------------------------------------------------
00123 bool Anp::FillMuonId::Run(Event &event, const Record& record, const bool pass)
00124 { 
00125    if(!pass)
00126    {
00127       return true;
00128    }
00129    
00130    const TrackIter track = Anp::LongestTrack(event, record);
00131    if(track == record.TrackEnd())
00132    {
00133       return true;
00134    }
00135 
00136    const DataMap dmap = Run(*track, record);
00137    
00138    for(DataMap::const_iterator it = dmap.begin(); it != dmap.end(); ++it)
00139    {
00140       event.Add(it -> first, it -> second);
00141    }
00142 
00143    return true;
00144 }
00145 
00146 //-----------------------------------------------------------------------------
00147 void Anp::FillMuonId::Config(const Registry &reg)
00148 {
00149    //
00150    // Configure self
00151    //
00152 
00153    int value_int = 0;
00154    if(reg.Get("FillMuonIdStripWindow", value_int) && value_int >= 0)
00155    {
00156       fStripWindow = value_int;
00157    }
00158 
00159    value_int = 0;
00160    if(reg.Get("FillMuonIdMinViewNPlane", value_int) && value_int >= 0)
00161    {
00162       fMinViewNPlane = value_int;
00163    }
00164 
00165    value_int = 0;
00166    if(reg.Get("FillMuonIdKeyBase", value_int) && value_int >= 0)
00167    {
00168       fKeyBase = value_int;
00169    }
00170 
00171    double value_double = 0;
00172    if(reg.Get("FillMuonIdTimeWindow", value_double) && value_double > 0.0)
00173    {
00174       fTimeWindow = value_double;
00175    }
00176 
00177    //
00178    // Configure minimum strip ADC or MIP and ADC shift for tuning
00179    //
00180    reg.Get("FillMuonIdKeyPass",            fKeyPass);
00181    reg.Get("FillMuonIdMinStripAdc",        fMinStripAdc);
00182    reg.Get("FillMuonIdMinStripMip",        fMinStripMip);
00183    reg.Get("FillMuonIdADCShiftMuon",       fADCShiftMuon);
00184    reg.Get("FillMuonIdADCShiftMuonSpect",  fADCShiftMuonSpect);
00185    reg.Get("FillMuonIdADCShiftOther",      fADCShiftOther);
00186    reg.Get("FillMuonIdADCShiftOtherSpect", fADCShiftOtherSpect);
00187 
00188    Anp::Read(reg, "FillMuonIdStudy", fIsStudy);
00189    Anp::Read(reg, "FillMuonIdDetec", fFillDetec);
00190    Anp::Read(reg, "FillMuonIdEvent", fFillEvent);
00191    Anp::Read(reg, "FillMuonIdShift", fFillShift);
00192    Anp::Read(reg, "FillMuonIdShort", fFillShort);
00193 
00194    if(reg.KeyExists("PrintConfig"))
00195    {
00196       cout << "FillMuonId::Config" << endl
00197            << "   StripWindow = "        << fStripWindow << endl
00198            << "   MinViewNPlane = "      << fMinViewNPlane << endl
00199            << "   KeyBase = "            << fKeyBase << endl
00200            << "   KeyPass = "            << fKeyPass << endl
00201            << "   TimeWindow = "         << fTimeWindow << endl
00202            << "   MinStripAdc = "        << fMinStripAdc << endl
00203            << "   MinStripMip = "        << fMinStripMip << endl
00204            << "   ADCShiftMuon = "       << fADCShiftMuon << endl
00205            << "   ADCShiftMuonSpect = "  << fADCShiftMuonSpect << endl
00206            << "   ADCShiftOther = "      << fADCShiftOther << endl
00207            << "   ADCShiftOtherSpect = " << fADCShiftOtherSpect << endl
00208            << "   IsStudy = "            << fIsStudy << endl
00209            << "   FillDetec = "          << fFillDetec << endl
00210            << "   FillEvent = "          << fFillEvent << endl
00211            << "   FillShift = "          << fFillShift << endl
00212            << "   FillShort = "          << fFillShort << endl;
00213    }
00214 }
00215 
00216 //------------------------------------------------------------------------------------------
00217 const Anp::FillMuonId::DataMap Anp::FillMuonId::Run(const Track &track, const Record &record) const
00218 {
00219    // fill variables used for muon identification
00220    // there are 4 variables filled:
00221    // 1) remove first few track planes and compute mean strip sigcor
00222    //    for remaining track strips
00223    // 2) removed first few planes from track, then
00225    //    and then sort these selected strips
00227    //    approximately in half and take ratio of lower half over 
00228    //    upper half
00229    // 3) removed first few planes from track,then for 
00230    //    remaining track strips compute mean strip sigcor
00231    //    for whole track and for last 20% of track
00232    //    take ratio of 20% mean over whole mean
00233    // 4) remove first 30% of track planes, add strips
00234    //    within 4 strip window and 40 ns around track
00235    //    take ratio of track strips' sigcor over all plane's
00236    //     strips' sigcor in window
00237    //
00238    // This function has hard coded key base values
00239    //
00240    
00241 
00242    DataMap dmap;
00243    
00244    //
00245    // Fill truth variable used by training algorithm(s)
00246    //
00247    short track_is_muon = -1;
00248    if(!record.GetHeader().IsData() && record.StdHepBeg() != record.StdHepEnd())
00249    {
00250       StdHepIter stdhep = record.FindStdHep(track);
00251       if(stdhep != record.StdHepEnd())
00252       {
00253          if(stdhep -> IsMuon()) track_is_muon = 1;
00254          else                   track_is_muon = 0;
00255          
00256          if(!dmap.insert(DataMap::value_type(fKeyBase, static_cast<float>(track_is_muon))).second)
00257          {
00258             cerr << "FillMuonId::Run - failed to insert value at " << fKeyBase << " key" << endl;
00259          }
00260       }
00261       else
00262       {
00263          cerr << "FillMuonId::Run - failed to find StdHep record" << endl;
00264          return dmap;
00265       }
00266    }
00267 
00268    //
00269    // Collect strips that we will use to compute variables...
00270    //
00271    const PMap pall = FillMuonId::Select(track, record);
00272    
00273    //
00274    // Track does not pass selection requirement
00275    //
00276    if(pall.empty()) return dmap;
00277 
00278    //
00279    // Fill variables using all of the detector planes
00280    //
00281    if(fFillDetec) FillMuonId::Fill(pall, dmap, 0);
00282 
00283    //
00284    // Fill number of track planes variable (once, using all detector planes)
00285    //
00286    FillMuonId::Fill0(pall.begin(), pall.end(), dmap);
00287    //
00288    // Fill tuned (ADC added or subtracted) variables
00289    //
00290    if(fFillShift)
00291    {      
00292       PMap pnew;
00293       if     (track_is_muon == 1) pnew = AddCharge(pall, fADCShiftMuon,  fADCShiftMuonSpect);
00294       else if(track_is_muon == 0) pnew = AddCharge(pall, fADCShiftOther, fADCShiftOtherSpect);
00295 
00296       if(!pnew.empty()) FillMuonId::Fill(pnew, dmap, 100);
00297    }
00298 
00299    //
00300    // Fill variables using calorimeter only strips
00301    // 
00302    const PMap pcal = FillMuonId::Select(track, record, "calor");
00303    if(!pcal.empty())
00304    {
00305       FillMuonId::Fill(pcal, dmap, 200);
00306    }   
00307 
00308    //
00309    // Fill variables using MIP calibrated strip charge
00310    //
00311    if(fFillDetec)
00312    {
00313       const PMap pmip = FillMuonId::Select(track, record, "mip");
00314       if(!pmip.empty())
00315       {
00316          FillMuonId::Fill(pmip, dmap, 300);
00317       }
00318    }
00319 
00320    //
00321    // Fill variables using MIP calibrated calorimeter strip charge
00322    //
00323    const PMap pmipcal = FillMuonId::Select(track, record, "calor mip");
00324    if(!pmipcal.empty())
00325    {
00326       FillMuonId::Fill(pmipcal, dmap, 400);
00327    }
00328 
00329    return dmap;
00330 }
00331 
00332 //------------------------------------------------------------------------------------------
00333 void Anp::FillMuonId::Fill(const PMap &pmap, DataMap &dmap, const short base) const
00334 
00335 {
00336    // fill variables used for muon identification
00337    // there are 4 variables filled:
00338    // 1) remove first couple track planes and compute mean strip sigcor
00339    //    for remaining track strips
00340    // 2) removed first couple planes from track, then
00342    //    and then sort these selected strips
00344    //    approximately in half and take ratio of lower half over 
00345    //    upper half
00346    // 3) removed first couple planes from track,then for 
00347    //    remaining track strips compute mean strip sigcor
00348    //    for whole track and for last 20% of track
00349    //    take ratio of 20% mean over whole mean
00350    // 4) remove first 30% of track planes, add strips
00351    //    within 4 strip window and 40 ns around track
00352    //    take ratio of track strips' sigcor over all plane's
00353    //     strips' sigcor in window
00354 
00355    PIter end_22_it = pmap.end();
00356    PIter end_24_it = pmap.end();
00357 
00358    if(fFillShort)
00359    {
00360       end_22_it = pmap.begin();
00361       end_24_it = pmap.begin();
00362    }
00363    else
00364    {
00365       short i_frac = 0, pdistance = 0;
00366       for(PIter pit = pmap.begin(); pit != pmap.end(); ++pit)
00367       {
00368          const short frac = (10 * pdistance)/pmap.size();      
00369          
00370          ++pdistance;
00371       
00372          if(pmap.size() > 9 && frac == i_frac)
00373          {
00374             continue;
00375          }
00376          
00377          // !!! hardcoded number !!!
00378          if(i_frac == 2 && end_22_it == pmap.end())
00379          {
00380             end_22_it = pit;
00381       }
00382          
00383          // !!! hardcoded number !!!
00384          if(i_frac == 4 && end_24_it == pmap.end())
00385          {
00386             end_24_it = pit;
00387          }
00388          
00389          ++i_frac;
00390       }
00391    }
00392 
00393    FillMuonId::Fill1(end_22_it, pmap.end(), dmap, base);
00394    FillMuonId::Fill2(end_22_it, pmap.end(), dmap, base);
00395    FillMuonId::Fill3(end_22_it, pmap.end(), dmap, base);
00396    FillMuonId::Fill4(end_24_it, pmap.end(), dmap, base);
00397 }
00398 
00399 //------------------------------------------------------------------------------------------
00400 const Anp::FillMuonId::PMap Anp::FillMuonId::Select(const Track &track,
00401                                                     const Record &record, 
00402                                                     const string &opt) const
00403 {
00404    //
00405    // Select strips matching this track, subject to various cuts. This function 
00406    // returns map: key is plane number and value is PlaneData struct.
00407    //
00408 
00409    PMap pmap;
00410 
00411    short option_detec = 0;
00412    if(opt.find("calor") != string::npos)
00413    {
00414       option_detec = 1;
00415    }
00416    else if(opt.find("spect") != string::npos)
00417    {
00418       option_detec = 2;
00419    }
00420 
00421    short option_view = 0;
00422    if(opt.find("Uview") != string::npos)
00423    {
00424       option_view = 1;
00425    }
00426    else if(opt.find("Vview") != string::npos)
00427    {
00428       option_view = 2;
00429    }
00430 
00431    short option_strip = 0;
00432    if(opt.find("sigmap") != string::npos)
00433    {
00434       option_strip = 1;
00435    }
00436    else if(opt.find("mip") != string::npos)
00437    {
00438       option_strip = 2;
00439    }
00440 
00441    const VldContext vldc = GetVldc(record.GetHeader());
00442    if(option_strip > 0)
00443    { 
00444       Calibrator::Instance().ReInitialise(vldc);
00445    }
00446 
00447    // count number of planes in each view
00448    int nuplane = 0, nvplane = 0;
00449 
00450    //
00451    // First loop: collect all track strips 
00452    //
00453    for(StripIter sit = record.StripBeg(); sit != record.StripEnd(); ++sit)
00454    {
00455       if(!sit -> MatchTrk(track.TrackIndex()))
00456       {
00457          continue;
00458       }
00459 
00460       if(option_detec > 0 && record.GetHeader().IsNear())
00461       {
00462          if(option_detec == 1 && sit -> GetPlane() > 120)
00463          {
00464             continue;
00465          }
00466          if(option_detec == 2 && sit -> GetPlane() < 121)
00467          {
00468             continue;
00469          }
00470       }
00471 
00472       if(option_view > 0)
00473       {
00474          if(option_view == 1 && !sit -> IsUview())
00475          {
00476             continue;
00477          }
00478          if(option_view == 2 && !sit -> IsVview())
00479          {
00480             continue;
00481          }
00482       }
00483 
00484       double strip_charge = -1.0;
00485 
00486       if(option_strip == 0)
00487       {
00488          // use sigcor pulse height
00489          if(!(sit -> SigCor() < fMinStripAdc))
00490          {
00491             strip_charge = sit -> SigCor();
00492          }
00493       }
00494       else
00495       {
00496          Strip::TrackInfoIter info_it = sit -> GetInfo(track.TrackIndex());
00497          if(info_it != sit -> InfoEndIter())
00498          {
00499             const Strip::TrackInfo &info = info_it -> second;   
00500 
00501             if(option_strip == 1)
00502             {
00503                // use sigmap pulse height
00504                if(!(info.sigmap_east + info.sigmap_west < fMinStripAdc))
00505                {
00506                   strip_charge = info.sigmap_east + info.sigmap_west;
00507                }
00508             }
00509             else if(option_strip == 2)
00510             {
00511                // use mip pulse height
00512                if(!(info.mip_east + info.mip_west < fMinStripMip))
00513                {
00514                   strip_charge = info.mip_east + info.mip_west;
00515                }
00516             }
00517             else
00518             {
00519                cerr << "FillMuonId::Select - unknown strip option" << endl;
00520             }
00521          }
00522          else
00523          {
00524             cerr << "FillMuonId::Select - failed to find Strip::TrackInfo" << endl;
00525          }
00526       }
00527 
00528       // strip pulse height did not pass selection cut
00529       if(strip_charge < 0.0)
00530       {
00531          continue;
00532       }
00533 
00534       // find plane data for this plane
00535       // for first call insert new PlaneData object
00536       PMap::iterator plane_it = pmap.find(sit -> GetPlane());
00537       if(plane_it == pmap.end())
00538       { 
00539          // count number of included active planes
00540          if(sit -> IsUview())
00541          {
00542             ++nuplane;
00543          }
00544          else
00545          {
00546             ++nvplane;
00547          }
00548 
00549          plane_it = pmap.insert(PMap::value_type(sit -> GetPlane(), PlaneData())).first;
00550       }
00551 
00552       PlaneData &data = plane_it -> second;
00553       
00554       data.tpos += sit -> TPos();
00555       data.track_vec.push_back(strip_charge);
00556 
00557       if(data.min_strip < 0 || data.min_strip > sit -> GetStrip())
00558       {
00559          data.min_strip = sit -> GetStrip();
00560       }
00561       if(data.max_strip < 0 || data.max_strip < sit -> GetStrip())
00562       {
00563          data.max_strip = sit -> GetStrip();
00564       }
00565    }
00566 
00567    if(option_view == 0)
00568    {      
00569       if(fFillShort)
00570       {  
00571          // check that track has minimum required number of hits in each view
00572          if(nuplane < fMinViewNPlane || nvplane < fMinViewNPlane)
00573          {
00574             pmap.clear();
00575          }
00576 
00577          // require at least 2 hits in each view
00578          if(nuplane < 2 || nvplane < 2)
00579          {
00580             pmap.clear();
00581          }
00582       }
00583       else
00584       {
00585          // check that track has minimum required number of hits in each view
00586          if(nuplane < fMinViewNPlane || nvplane < fMinViewNPlane)
00587          {
00588             pmap.clear();
00589          }
00590       }
00591    }
00592    else
00593    {
00594       if(nuplane < 2*fMinViewNPlane && nvplane < 2*fMinViewNPlane)
00595       {
00596          pmap.clear();
00597       }
00598    }
00599 
00600    if(pmap.empty())
00601    {
00602       return pmap;
00603    }
00604 
00605    if(option_strip > 0)
00606    { 
00607       for(PMap::iterator pit = pmap.begin(); pit != pmap.end(); ++pit)
00608       {
00609          PlaneData &data = pit -> second;
00610          if(data.track_vec.empty())
00611          {
00612             cerr << "FillMuonId::Select - no track strips in plane " << pit -> first << endl;
00613             continue;
00614          }
00615 
00616          data.tpos /= float(data.track_vec.size());
00617       }
00618    }
00619 
00620    const double min_time = track.GetBasic().MinTime() - fTimeWindow;
00621    const double max_time = track.GetBasic().MaxTime() + fTimeWindow;
00622 
00623    //
00624    // Second loop: collect all "nearby" non-track strips 
00625    //
00626    for(StripIter sit = record.StripBeg(); sit != record.StripEnd(); ++sit)
00627    {
00628       PMap::iterator pit = pmap.find(sit -> GetPlane());
00629       if(pit == pmap.end())
00630       {
00631          continue;
00632       }
00633 
00634       if(sit -> MatchTrk(track.TrackIndex()))
00635       {
00636          continue;
00637       }
00638 
00639       const double time = sit -> Time();
00640       if(time < 0.0)
00641       {
00642          cerr << "FillMuonId::Select - negative strip time: " << time << endl;
00643          continue;
00644       }
00645 
00646       if(time < min_time || time > max_time)
00647       {
00648          continue;
00649       }
00650 
00651       PlaneData &data = pit -> second;
00652 
00653       if(sit -> GetStrip() < data.min_strip - fStripWindow ||
00654          sit -> GetStrip() > data.max_strip + fStripWindow)
00655       {
00656          continue;
00657       }
00658 
00659       double strip_charge = -1.0;
00660 
00661       // use sigcor pulse height
00662       if(option_strip == 0)
00663       {
00664          if(!(sit -> SigCor() < fMinStripAdc))
00665          {
00666             strip_charge = sit -> SigCor();
00667          }
00668       }
00669       else
00670       {
00671          const float charge = Get(*sit, vldc, GetLPos(sit -> GetPlane(), pmap), option_strip);
00672          
00673          if(option_strip == 1)
00674          {
00675             // use sigmap pulse height
00676             if(!(charge < fMinStripAdc))
00677             {
00678                strip_charge = charge;
00679             }
00680          }
00681          else if(option_strip == 2)
00682          {
00683             // use mip pulse height
00684             if(!(charge < fMinStripMip))
00685             {
00686                strip_charge = charge;
00687             }
00688          }
00689       }
00690 
00691       // add charge for strips with pulse height above threshold
00692       if(!(strip_charge < 0.0))
00693       {
00694          data.other_vec.push_back(strip_charge);
00695       }
00696    }
00697 
00698    return pmap;
00699 }
00700 
00701 //------------------------------------------------------------------------------------------
00702 const Anp::FillMuonId::PMap Anp::FillMuonId::AddCharge(const PMap &pmap,
00703                                                        const double calor,
00704                                                        const double spect) const
00705 {
00706    //
00707    // Subtract adc values for calorimeter and spectrometer strips
00708    //
00709 
00710    PMap newmap = pmap;
00711    
00712    for(PMap::iterator pit = newmap.begin(); pit != newmap.end(); ++pit)
00713    {
00714       PlaneData &data = pit -> second;
00715       
00716       if(pit -> first > 120)
00717       {
00718          std::for_each(data.track_vec.begin(), data.track_vec.end(), Anp::Fill::AddCharge(spect));
00719          std::for_each(data.other_vec.begin(), data.other_vec.end(), Anp::Fill::AddCharge(spect));
00720       }
00721       else
00722       {
00723          std::for_each(data.track_vec.begin(), data.track_vec.end(), Anp::Fill::AddCharge(calor));
00724          std::for_each(data.other_vec.begin(), data.other_vec.end(), Anp::Fill::AddCharge(calor)); 
00725       }
00726    }
00727 
00728    return newmap;
00729 }
00730 
00731 //------------------------------------------------------------------------------------------
00732 void Anp::FillMuonId::Fill0(PIter beg, PIter end, DataMap &dmap) const
00733 {
00734   // this function computes track length in scintillator planes
00735 
00736    const float nplane_scint = std::distance(beg, end);
00737 
00738    if(nplane_scint < 1.0)
00739    {
00740       cerr << "FillMuonId::Fill0() - zero number of scintillator planes" << endl;
00741    }
00742 
00743    --end;
00744 
00745    const float nplane_steel = end -> first - beg -> first + 1;
00746 
00747    // this function computes track length in scintillator and steel planes
00748    if(!dmap.insert(DataMap::value_type(fKeyBase + 1, nplane_scint)).second)
00749    {
00750       cerr << "FillMuonId::Select() - failed to add data" << endl;
00751    }
00752    if(!dmap.insert(DataMap::value_type(fKeyBase + 2, nplane_steel)).second)
00753    {
00754       cerr << "FillMuonId::Select() - failed to add data" << endl;
00755    }  
00756 }
00757 
00758 //------------------------------------------------------------------------------------------
00759 void Anp::FillMuonId::Fill1(PIter beg, PIter end, DataMap &dmap, const short base) const
00760 {
00761    // this function computes mean strip sigcor per strip
00762    // perhaps should use per plane?
00763 
00764    double sum = 0.0;
00765    unsigned short count = 0;
00766 
00767    for(PIter pit = beg; pit != end; ++pit)
00768    {
00769       const PlaneData &data = pit -> second;
00770 
00771       sum += std::accumulate(data.track_vec.begin(), data.track_vec.end(), 0.0);
00772 
00773       count += data.track_vec.size();
00774    }
00775 
00776    if(count < 1)
00777    {
00778       cerr << "FillMuonId::Fill1() - track has no strips" << endl;
00779       return;
00780    }
00781    
00782    const float par = sum/double(count);
00783 
00784    if(!dmap.insert(DataMap::value_type(fKeyBase + base + 10, par)).second)
00785    {
00786       cerr << "FillMuonId::Fill1() - failed to add data" << endl;
00787    }
00788 }
00789 
00790 //------------------------------------------------------------------------------------------
00791 void Anp::FillMuonId::Fill2(PIter beg, PIter end, DataMap &dmap, const short base) const
00792 {
00793    // this function finds all strips within 4 strip window of track
00794    // these strips are sorted in increasing sigcor values
00795    // sigcor sum of lower ?% of strips is divided by sigcor sum 
00796    // of remaining strips
00797    
00798    ChargeVec svec;
00799    float plane_nstrip = 0.0, other_nstrip = 0.0;
00800    
00801    for(PIter pit = beg; pit != end; ++pit)
00802    {
00803       const PlaneData &data = pit -> second;
00804 
00805       plane_nstrip += data.track_vec.size() + data.track_vec.size();
00806       other_nstrip += data.other_vec.size();
00807 
00808       svec.insert(svec.end(), data.track_vec.begin(), data.track_vec.end());
00809       svec.insert(svec.end(), data.other_vec.begin(), data.other_vec.end());
00810    }
00811    
00812    //
00813    // Sort strip by pulse height
00814    //
00815    std::sort(svec.begin(), svec.end());
00816    
00817    const short size = svec.size();   
00818    if(size < 1)
00819    {
00820       cerr << "FillMuonId::Fill2() - strip vector is too short" << endl;
00821       return;
00822    }
00823    
00824    double lower_charge = 0.0, upper_charge = 0.0;
00825    double lower_nstrip = 0.0, upper_nstrip = 0.0;
00826    
00827    unsigned short count = 0;
00828    for(ChargeVec::const_iterator sit = svec.begin(); sit != svec.end(); ++sit)
00829    {
00830       // !!! hardcoded number !!!
00831       if((10 * count)/size < 4)
00832       {
00833          lower_charge += *sit;
00834          lower_nstrip += 1.0;
00835       }
00836       else
00837       {
00838          upper_charge += *sit;
00839          upper_nstrip += 1.0;
00840       }
00841       
00842       ++count;
00843    }
00844    
00845    if(upper_nstrip < 1.0 || lower_nstrip < 1.0 || short(count) != size)
00846    {
00847       cerr << "FillMuonId::Fill2() - failed to split track" << endl;
00848       return;
00849    }
00850    
00851    const double lower_mean = lower_charge/lower_nstrip;
00852    const double upper_mean = upper_charge/upper_nstrip;
00853    
00854    if(!(upper_mean > 0.0))
00855    {
00856       cerr << "FillMuonId::Fill2() -  upper sum is not positive" << endl;
00857       return;
00858    }
00859   
00860    const float par = lower_mean/upper_mean;
00861 
00862    if(!dmap.insert(DataMap::value_type(fKeyBase + base + 20, par)).second)
00863    {
00864       cerr << "FillMuonId::Fill2() - failed to add data" << endl;
00865    }
00866    
00867    //
00868    // Do not fill special variables when running production
00869    //
00870    if(!fIsStudy) return;
00871 
00872    if(!dmap.insert(DataMap::value_type(fKeyBase + base + 21, lower_mean)).second)
00873    {
00874       cerr << "FillMuonId::Fill2() - failed to add data" << endl;
00875    }
00876    if(!dmap.insert(DataMap::value_type(fKeyBase + base + 22, upper_mean)).second)
00877    {
00878       cerr << "FillMuonId::Fill2() - failed to add data" << endl;
00879    }
00880    if(!dmap.insert(DataMap::value_type(fKeyBase + base + 23, plane_nstrip)).second)
00881    {
00882       cerr << "FillMuonId::Fill4() - failed to add track data" << endl;
00883    }
00884    if(!dmap.insert(DataMap::value_type(fKeyBase + base + 24, other_nstrip)).second)
00885    {
00886       cerr << "FillMuonId::Fill4() - failed to add track data" << endl;
00887    }
00888    if(plane_nstrip > 0.0)
00889    {
00890       if(!dmap.insert(DataMap::value_type(fKeyBase + base + 25, other_nstrip/plane_nstrip)).second)
00891       {
00892          cerr << "FillMuonId::Fill4() - failed to add track data" << endl;
00893       }
00894    }
00895 }
00896 
00897 //------------------------------------------------------------------------------------------
00898 void Anp::FillMuonId::Fill3(PIter beg, PIter end, DataMap &dmap, const short base) const
00899 {
00900    // this function computes mean strip sigcor in last 20% of track
00901    // and total mean strip sigcor
00902    // no strips around a track are included
00903 
00904    const unsigned short psize = std::distance(beg, end);
00905    if(psize < 1)
00906    {
00907       cerr << "FillMuonId::Fill3() - track has no strips" << endl;
00908       return;
00909    }
00910 
00911    double lower_charge = 0.0, upper_charge = 0.0;
00912    double lower_nplane = 0.0, upper_nplane = 0.0;
00913 
00914    unsigned short pcount = 0;
00915    for(PIter pit = beg; pit != end; ++pit)
00916    {
00917       const PlaneData &data = pit -> second;
00918 
00919       const double tcharge = std::accumulate(data.track_vec.begin(), data.track_vec.end(), 0.0);
00920       const double ocharge = std::accumulate(data.other_vec.begin(), data.other_vec.end(), 0.0);
00921 
00922       // !!! hardcoded number !!!
00923       if((10 * pcount)/psize < 8)
00924       {
00925          lower_charge += tcharge;
00926          lower_charge += ocharge;
00927          lower_nplane += 1.0;
00928       }
00929       else
00930       {
00931          upper_charge += tcharge;
00932          upper_charge += ocharge;
00933          upper_nplane += 1.0;
00934       }
00935 
00936       ++pcount;
00937    }
00938 
00939    if(upper_nplane < 1.0 || lower_nplane < 1.0 || pcount != psize)
00940    {
00941       cout << "upper, lower, pcount, psize = "
00942            << upper_nplane << ", "
00943            << lower_nplane << ", "
00944            << pcount << ", "
00945            << psize << endl;
00946       cerr << "FillMuonId::Fill3() - failed to split track" << endl;
00947       return;
00948    }
00949    
00950    const double total_mean = (lower_charge + upper_charge)/double(psize);  
00951    const double upper_mean = upper_charge/upper_nplane;
00952 
00953    if(!(total_mean > 0.0) && !(total_mean < 0.0))
00954    {
00955       cerr << "FillMuonId::Fill3() - mean charge is zero" << endl;
00956       return;
00957    }
00958 
00959    const float ratio = upper_mean/total_mean;
00960 
00961    if(!dmap.insert(DataMap::value_type(fKeyBase + base + 30, ratio)).second)
00962    {
00963       cerr << "FillMuonId::Fill3() - failed to add track data" << endl;
00964    }
00965 
00966    //
00967    // do not fill special variables when running production
00968    //
00969    if(!fIsStudy) return;
00970 
00971    if(!dmap.insert(DataMap::value_type(fKeyBase + base + 31, total_mean)).second)
00972    {
00973       cerr << "FillMuonId::Fill3() - failed to add track data" << endl;
00974    }
00975    if(!dmap.insert(DataMap::value_type(fKeyBase + base + 32, upper_mean)).second)
00976    {
00977       cerr << "FillMuonId::Fill3() - failed to add track data" << endl;
00978    }
00979 }
00980 
00981 //------------------------------------------------------------------------------------------
00982 void Anp::FillMuonId::Fill4(PIter beg, PIter end, DataMap &dmap, const short base) const
00983 {
00984    // this function computes ratio of track sigcor to sigcor of strips near track
00985    // use strips within time and strip window around track
00986 
00987    double track_charge = 0.0, other_charge = 0.0;
00988 
00989    for(PIter pit = beg; pit != end; ++pit)
00990    {
00991       const PlaneData &data = pit -> second;
00992 
00993       track_charge += std::accumulate(data.track_vec.begin(), data.track_vec.end(), 0.0);
00994       other_charge += std::accumulate(data.other_vec.begin(), data.other_vec.end(), 0.0);
00995    }
00996 
00997    const double total_charge = other_charge + track_charge;
00998    if(!(total_charge > 0.0) && !(total_charge < 0.0))
00999    {
01000       cerr << "FillMuonId::Fill4() - total charge is zero" << endl;
01001       return;
01002    }
01003    
01004    const float par = track_charge/total_charge;
01005 
01006    if(!dmap.insert(DataMap::value_type(fKeyBase + base + 40, par)).second)
01007    {
01008       cerr << "FillMuonId::Fill4() - failed to add track data" << endl;
01009    }
01010 
01011    //
01012    // do not fill special variables when running production
01013    //
01014    if(!fIsStudy) return;
01015 
01016    if(!dmap.insert(DataMap::value_type(fKeyBase + base + 41, track_charge)).second)
01017    {
01018       cerr << "FillMuonId::Fill4() - failed to add track data" << endl;
01019    }
01020    if(!dmap.insert(DataMap::value_type(fKeyBase + base + 42, other_charge)).second)
01021    {
01022       cerr << "FillMuonId::Fill4() - failed to add track data" << endl;
01023    }
01024 }
01025 
01026 //------------------------------------------------------------------------------------------
01027 const VldContext Anp::FillMuonId::GetVldc(const Header &header) const
01028 {
01029    const VldTimeStamp time(header.Sec(), header.NSec());
01030    if(header.IsData())
01031    {
01032       if(header.IsNear())
01033       {
01034          return VldContext(Detector::kNear, SimFlag::kData, time);
01035       }
01036       else if(header.IsFar())
01037       {
01038          return VldContext(Detector::kFar, SimFlag::kData, time);
01039       }
01040    }
01041    else
01042    {
01043       if(header.IsNear())
01044       {
01045          return VldContext(Detector::kNear, SimFlag::kMC, time);
01046       }
01047       else if(header.IsFar())
01048       {
01049          return VldContext(Detector::kFar, SimFlag::kMC, time);
01050       }
01051    }
01052 
01053    return VldContext(Detector::kUnknown, SimFlag::kUnknown, time);   
01054 }
01055 
01056 //------------------------------------------------------------------------------------------
01057 float Anp::FillMuonId::GetLPos(const short plane, const PMap &pmap) const
01058 {
01059    // 
01060    // Find longitudinal hit position using nearby planes
01061    //
01062 
01063    map<short, float> fmap;
01064    
01065    for(PMap::const_iterator pit = pmap.begin(); pit != pmap.end(); ++pit)
01066    {
01067       const short diff = plane - pit -> first;
01068 
01069       const PlaneData &data = pit -> second;
01070 
01071       // easiest solution: return tpos in the previous plane
01072       if(diff == -1)
01073       {
01074          return data.tpos;
01075       }
01076 
01077       // skip strips in same plane view
01078       if(std::abs(diff) % 2 == 0)
01079       {
01080          continue;
01081       }
01082 
01083       if(!fmap.insert(map<short, float>::value_type(diff, data.tpos)).second)
01084       {
01085          cerr << "FillMuonId::GetLPos - duplicate plane difference" << endl;
01086       }
01087    }
01088 
01089    if(fmap.empty())
01090    {
01091       cerr << "FillMuonId::GetLPos - no planes in orthogonal view" << endl;
01092       return -100.0;
01093    }
01094 
01095    map<short, float>::iterator dit_pos = fmap.begin();
01096    map<short, float>::iterator dit_neg = fmap.begin();
01097    for(map<short, float>::iterator dit = fmap.begin(); dit != fmap.end(); ++dit)
01098    {
01099       const short diff = dit -> first;
01100       if(diff < 0)
01101       {
01102          if(abs(dit_neg -> first) > abs(diff))
01103          {
01104             dit_neg = dit;
01105          }
01106       }
01107       if(diff > 0)
01108       {
01109          if(abs(dit_pos -> first) > abs(diff))
01110          {
01111             dit_pos = dit;
01112          }
01113       }
01114    }
01115 
01116    return 0.5*(dit_pos -> second + dit_neg -> second);
01117 }
01118 
01119 //------------------------------------------------------------------------------------------
01120 float Anp::FillMuonId::Get(const Strip &strip, const VldContext &vldc,
01121                            const float lpos, const short option) const
01122 {
01123    //
01124    // Calibrate strip pulse height from sigcor to sigmap or from sigmap to mip
01125    //
01126 
01127    float upos = -1.0, vpos = -1.0;
01128    if(strip.IsUview())
01129    {
01130       upos = strip.TPos();
01131       vpos = lpos;
01132    }
01133    else
01134    {
01135       upos = lpos;      
01136       vpos = strip.TPos();
01137    }
01138 
01139    UgliGeomHandle ugh(vldc);
01140    if(!ugh.IsValid())
01141    {
01142       cerr << "FillMuonId::Get - invalid UgliGeomHandle: " << vldc << endl;
01143       return 0.0;
01144    }
01145  
01146    const PlexStripEndId seid(strip.GetEncoded());
01147    const UgliStripHandle ush = ugh.GetStripHandle(seid);
01148   
01149    if(!ush.IsValid())
01150    {
01151       cerr << "FillMuonId::Get - invalid UgliStripHandle: " << seid << endl;
01152       return 0.0;
01153    }
01154 
01155    const TVector3 guvz(upos, vpos, strip.ZPos());
01156    const TVector3 lxyz = ush.GlobalToLocal(guvz, false);
01157    
01158    float sigmap = 0.0, sigmap_east = -1.0, sigmap_west = -1.0;
01159    if(vldc.GetDetector() == Detector::kNear)
01160    {
01161       sigmap = Calibrator::Instance().GetAttenCorrected(strip.SigCor(), lxyz.x(), seid);
01162    }
01163    else if(vldc.GetDetector() == Detector::kFar)
01164    {
01165       PlexStripEndId seid_far(seid);
01166       Calibrator &calibrator = Calibrator::Instance();
01167 
01168       if(strip.SigCorEast() > 0.0)
01169       {
01170          seid_far.SetEnd(StripEnd::kEast);
01171          sigmap_east = calibrator.GetAttenCorrected(strip.SigCorEast(), lxyz.x(), seid_far);
01172          sigmap += sigmap_west;
01173       }
01174 
01175       if(strip.SigCorWest() > 0.0)
01176       {      
01177          seid_far.SetEnd(StripEnd::kWest);
01178          sigmap_east = calibrator.GetAttenCorrected(strip.SigCorWest(), lxyz.x(), seid_far);
01179          sigmap += sigmap_east;
01180       }      
01181    }
01182    else
01183    {
01184       cerr << "FillMuonId::Get - unknown detector" << endl;
01185       return 0.0;
01186    }
01187 
01188    //
01189    // Just want sigmap pulse height
01190    //
01191    if(option == 1) return sigmap;
01192 
01193    float mip = 0.0;
01194    if(vldc.GetDetector() == Detector::kNear)
01195    {
01196       mip = Calibrator::Instance().GetMIP(sigmap, seid);
01197    }
01198    else if(vldc.GetDetector() == Detector::kFar)
01199    {
01200       PlexStripEndId seid_far(seid);
01201 
01202       if(sigmap_east > 0.0)
01203       {
01204          seid_far.SetEnd(StripEnd::kEast);
01205          mip += Calibrator::Instance().GetMIP(sigmap_east, seid_far);
01206       }
01207 
01208       if(sigmap_west > 0.0)
01209       {      
01210          seid_far.SetEnd(StripEnd::kWest);
01211          mip = Calibrator::Instance().GetMIP(sigmap_west, seid_far);
01212       }
01213    }
01214 
01215    return mip;
01216 }

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