00001
00002
00003
00004 #include <iostream>
00005 #include <numeric>
00006 #include <sstream>
00007
00008
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
00016 #include "PhysicsNtuple/Default.h"
00017 #include "PhysicsNtuple/Factory.h"
00018
00019
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
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 ®)
00148 {
00149
00150
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
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
00220
00221
00222
00223
00225
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 DataMap dmap;
00243
00244
00245
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
00270
00271 const PMap pall = FillMuonId::Select(track, record);
00272
00273
00274
00275
00276 if(pall.empty()) return dmap;
00277
00278
00279
00280
00281 if(fFillDetec) FillMuonId::Fill(pall, dmap, 0);
00282
00283
00284
00285
00286 FillMuonId::Fill0(pall.begin(), pall.end(), dmap);
00287
00288
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
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
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
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
00337
00338
00339
00340
00342
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
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
00378 if(i_frac == 2 && end_22_it == pmap.end())
00379 {
00380 end_22_it = pit;
00381 }
00382
00383
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
00406
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
00448 int nuplane = 0, nvplane = 0;
00449
00450
00451
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
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
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
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
00529 if(strip_charge < 0.0)
00530 {
00531 continue;
00532 }
00533
00534
00535
00536 PMap::iterator plane_it = pmap.find(sit -> GetPlane());
00537 if(plane_it == pmap.end())
00538 {
00539
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
00572 if(nuplane < fMinViewNPlane || nvplane < fMinViewNPlane)
00573 {
00574 pmap.clear();
00575 }
00576
00577
00578 if(nuplane < 2 || nvplane < 2)
00579 {
00580 pmap.clear();
00581 }
00582 }
00583 else
00584 {
00585
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
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
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
00676 if(!(charge < fMinStripAdc))
00677 {
00678 strip_charge = charge;
00679 }
00680 }
00681 else if(option_strip == 2)
00682 {
00683
00684 if(!(charge < fMinStripMip))
00685 {
00686 strip_charge = charge;
00687 }
00688 }
00689 }
00690
00691
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
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
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
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
00762
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
00794
00795
00796
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
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
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
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
00901
00902
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
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
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
00985
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
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
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
01072 if(diff == -1)
01073 {
01074 return data.tpos;
01075 }
01076
01077
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
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
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 }