//____________________________________________________________________
//
// Atlas muon class
// 
// For details about the muon reconstruction at Atlas see the muon
// working group wiki page at
// BEGIN_HTML
// <a href="https://twiki.cern.ch/twiki/bin/view/AtlasProtected/MuonPerformance">
// https://twiki.cern.ch/twiki/bin/view/AtlasProtected/MuonPerformance</a>
// END_HTML
// or the MuonRecoPedia
// BEGIN_HTML
// <a href="https://twiki.cern.ch/twiki/bin/view/AtlasProtected/MuonRecoPedia">
// https://twiki.cern.ch/twiki/bin/view/AtlasProtected/MuonRecoPedia</a>
// END_HTML
//
//  
// Author: Oliver Maria Kind <mailto: kind@mail.desy.de>
// Update: $Id: AtlMuon.cxx,v 1.29 2016/11/29 18:05:19 kind Exp $
// Copyright: 2008 (C) Oliver Maria Kind
//
#ifndef ATLAS_AtlMuon
#include <AtlMuon.h>
#endif
#include <TSystem.h>
#include <iostream>
#include <iomanip>

using namespace std;

#ifndef __CINT__
ClassImp(AtlMuon);
#endif

const Int_t AtlMuon::fgNAuthors = 21; // NO! There are actually only 19 now!
const char* AtlMuon::fgAuthorNames[] = {
    "Invalid", "HighPt", "LowPt", "MediumPt",
    "MuonBoySP", "MuonBoy", "STACO", "MuTag",
    "Unused", "Unused2", // this should be amended!
    "MOORE", "MuidSA", "MuidCo", "MuGirl",
    "CaloMuonId", "MuGirlLowBeta", "CaloTag",
    "CaloLikelihood", "MuTagIMO", "MuCombRefit", "MuExtrapolateIP"
};
const Int_t AtlMuon::fgNQuality = 4;
const char* AtlMuon::fgQualityNames[] = {
    "Invalid", "Loose", "Medium", "Tight"
};

//____________________________________________________________________

AtlMuon::AtlMuon() {
    //
    // Default constructor
    //
    
    // Initialize Chi2 and No. of degrees of freedom for combined
    // Muons. Values will be set for combined muons during the
    // conversion. For not combined muons, please look for the chi2
    // and NDof from the originally IDTrack if existing
    fMatchingChi2 = 0.;      
    fMatchingNDoF = 0;      
    fIDTrack = new TRef;
    fMETrack = new TRef;
    fTrackRefit = new HepTrackHelix;
}

//____________________________________________________________________

AtlMuon::AtlMuon(Int_t Id, Float_t Px, Float_t Py, Float_t Pz,
		 Float_t E, Bool_t IsMuPlus, Float_t EtCone10,
		 Float_t EtCone20, Float_t EtCone30, Float_t EtCone40, 
		 Int_t NtrkCone10, Int_t NtrkCone20, Int_t NtrkCone30,
		 Int_t NtrkCone40, Float_t PtCone10, Float_t PtCone20,
		 Float_t PtCone30, Float_t PtCone40, EAuthor Author,
		 EQuality Quality, 
		 Float_t MatchingChi2, Int_t MatchingNDoF,
		 Bool_t IsCombinedMuon,
		 TLorentzVector PMuonSpecExtrapol, 
		 Int_t MuonSpecExtrapolCharge) : 
  HepMuon(Id, Px, Py, Pz, E, IsMuPlus), fAuthor(Author), fQuality(Quality),
  fEtCone10(EtCone10), fEtCone20(EtCone20), fEtCone30(EtCone30), fEtCone40(EtCone40),
  fNtrkCone10(NtrkCone10), fNtrkCone20(NtrkCone20), fNtrkCone30(NtrkCone30),
  fNtrkCone40(NtrkCone40), fPtCone10(PtCone10), fPtCone20(PtCone20),
  fPtCone30(PtCone30), fPtCone40(PtCone40), 
  fMatchingChi2(MatchingChi2), fMatchingNDoF(MatchingNDoF),
  fIsCombinedMuon(IsCombinedMuon),
  fPMuonSpecExtrapol(PMuonSpecExtrapol), 
  fMuonSpecExtrapolCharge(MuonSpecExtrapolCharge) { 
  //
  // Normal constructor
  //
  fTrackRefit = new HepTrackHelix;
  fIDTrack = new TRef;
  fMETrack = new TRef;
}

//____________________________________________________________________

AtlMuon::~AtlMuon() {
    //
    // Default destructor
    //
    delete fTrackRefit;
    delete fIDTrack; fIDTrack=0;
    delete fMETrack; fMETrack=0;
}

//____________________________________________________________________

void AtlMuon::Clear(Option_t *option) {
    //
    // Clear object
    //
    HepMuon::Clear(option);
    AtlMETWeights::Clear(option);
    AtlTriggerMatch::Clear(option);

    fAuthor = kInvalidAuthor;
    fQuality = kInvalid;
    fEtCone10     = 0.;
    fEtCone20     = 0.;
    fEtCone30     = 0.;
    fEtCone40     = 0.;
    fPtCone10     = 0.;
    fPtCone20     = 0.;
    fPtCone30     = 0.;
    fPtCone40     = 0.;
    fNtrkCone10   = 0;
    fNtrkCone20   = 0;
    fNtrkCone30   = 0;
    fNtrkCone40   = 0;
    fMatchingChi2 = 0.;
    fMatchingNDoF = 0;
    fPMuonSpecExtrapol.SetPxPyPzE(0, 0, 1., 0); // unit-vector in Pz direction
    fMuonSpecExtrapolCharge = 0;
    delete fIDTrack; fIDTrack = 0;    
    delete fMETrack; fMETrack = 0;
    delete fTrackRefit; fTrackRefit = 0;
    fMCTruthClassifier.Clear(option);
}

//_____________________________________________________________

void AtlMuon::Print(Option_t *option) {
    //
    // Print muon information
    //
    // Note that in the standard printout only the main authors are
    // displayed. For a detailed view use the option "author".
    //
    // Options available:
    //   "nohead" - No header containing the variable names is
    //              displayed. Useful when printing a whole
    //              table for a list of muons
    //   "author" - Print the reconstruction algorithm(s) the
    //              muon candidate had been found by
    //
    TString opt = option;
    opt.ToLower();
    
    // Print header
    if ( !opt.Contains("nohead") ) PrintHeader();
    
    // Print
    cout.setf(ios::showpoint | ios::fixed, ios::floatfield);
    cout.precision(3);
    cout.width(4);  cout << fId;
    cout.width(3);  cout << (( IsPositive() ) ? "+" : "-");
    cout.width(10); cout << Pt();
    cout.width(9); cout << E();
    cout.precision(6);
    cout.width(11); cout << M("REC");
    cout.precision(3);
    cout.width(9); cout << Theta()*180/TMath::Pi();
    cout.width(9); cout << Phi()*180/TMath::Pi();
    cout.width(7); cout << Eta();
    cout.width(9); cout << GetEtCone20();
    cout.width(11); cout << GetNtrkCone20();
    cout.precision(1);
    cout.width(5); cout << GetMatchingChi2();
    cout << " /";
    cout.width(2); cout << GetMatchingNDoF();
    cout << "  ";
    if ( HasInvalidQuality() ) {
	cout << "i";
    } else {
	cout << "-";
    }
    if ( IsLoose() ) {
	cout << "l";
    } else {
	cout << "-";
    }
    if ( IsMedium() ) {
	cout << "m";
    } else {
	cout << "-";
    }
    if ( IsTight() ) {
	cout << "t";
    } else {
	cout << "-";
    }
    cout << " ";
    if ( HasInvalidAuthor() ) {
	cout << "i";
    } else {
	cout << "-";
    }
    if ( IsSTACO() ) {
	cout << "s";
    } else {
	cout << "-";
    }
    if ( IsMuidCo() ) {
	cout << "c";
    } else {
	cout << "-";
    }
    if ( IsMuGirl() ) {
	cout << "g";
    } else {
	cout << "-";
    }
    if ( IsMuonBoy() ) {
	cout << "b";
    } else {
	cout << "-";
    }
    if ( IsMuidSA() ) {
	cout << "a";
    } else {
	cout << "-";
    }
    cout << endl;

    // Print author (if wanted)
    if ( opt.Contains("author") ) PrintAuthor();
    
    // Print footer
    if ( !opt.Contains("nohead") ) PrintFooter();
}

//____________________________________________________________________

void AtlMuon::PrintHeader() {
    //
    // Print information header
    //
    cout << "--------------------------------------------------------------------------------------------------------"
	 << endl
	 << " Id  Chg Pt (GeV)  E (GeV) Minv (GeV)    Theta      Phi    Eta EtCone20 NtrkCone20 Chi2/NDoF Qual Author"
	 << endl
	 << "--------------------------------------------------------------------------------------------------------"
	 << endl;
}

//____________________________________________________________________

void AtlMuon::PrintFooter() {
    //
    // Print footer
    //
    cout << "   i=invalid l=loose m=medium t=tight s=staco c=muid-comb g=mu_girl b=mu-boy a=muid-sa"
	 << endl
	 << "--------------------------------------------------------------------------------------------------------"
	 << endl;
}

//____________________________________________________________________

void AtlMuon::PrintAuthor() const {
    //
    // Print names of the reconstruction algorithm(s) used
    //
    cout << endl
	 << "==========================" << endl
	 << " Muon reconstruction" << endl
	 << "--------------------------" << endl;
    for ( Int_t i = 0; i < fgNAuthors; i++ ) {
	if ( i != 8 && i != 9 ) { // these bits are not used
	    Bool_t set = fAuthor & 1<<i; 
	    cout << setw(20) << setiosflags(ios::left)
		 << fgAuthorNames[i] << set << endl;
	}
    }
    cout << "==========================" << endl << endl;
}

//____________________________________________________________________

TString* AtlMuon::NameOfAuthor() {
    //
    // Return name(s) of reconstruction algorithm used. The user is
    // responsible for deleting the returned TString object.
    //
    return NameOfAuthor(fAuthor);
}

//____________________________________________________________________

TString* AtlMuon::NameOfAuthor(AtlMuon::EAuthor author) {
    //
    // Return name(s) of given reconstruction algorithm(s). The user
    // is responsible for deleting the returned TString object.
    //
    TString *author_str = new TString("");
    for ( Int_t i = 0; i < fgNAuthors; i++ ) {
	if ( author & (0x1<<i) ) {
	    if ( author_str->Length() > 0 ) author_str->Append(",");
	    author_str->Append(fgAuthorNames[i]);
	}
    }
    if ( author_str->Length() == 0 ) author_str->Append(" --- ");
    return author_str;
}

//____________________________________________________________________

TString* AtlMuon::NameOfQuality() {
    //
    // Return name(s) of selection used. The user is responsible for
    // deleting the returned TString object.
    //
    return NameOfQuality(fQuality);
}
    
//____________________________________________________________________

TString* AtlMuon::NameOfQuality(AtlMuon::EQuality quality) {
    //
    // Return name(s) of given quality. The user is responsible for
    // deleting the returned TString object.
    //
    TString *quality_str = new TString("");
    for ( Int_t i = 0; i < fgNQuality; i++ ) {
	if ( quality & (0x1<<i) ) {
	    if ( quality_str->Length() > 0 ) quality_str->Append(",");
	    quality_str->Append(fgQualityNames[i]);
	}
    }
    if ( quality_str->Length() == 0 ) quality_str->Append(" --- ");
    return quality_str;
}



 AtlMuon.cxx:1
 AtlMuon.cxx:2
 AtlMuon.cxx:3
 AtlMuon.cxx:4
 AtlMuon.cxx:5
 AtlMuon.cxx:6
 AtlMuon.cxx:7
 AtlMuon.cxx:8
 AtlMuon.cxx:9
 AtlMuon.cxx:10
 AtlMuon.cxx:11
 AtlMuon.cxx:12
 AtlMuon.cxx:13
 AtlMuon.cxx:14
 AtlMuon.cxx:15
 AtlMuon.cxx:16
 AtlMuon.cxx:17
 AtlMuon.cxx:18
 AtlMuon.cxx:19
 AtlMuon.cxx:20
 AtlMuon.cxx:21
 AtlMuon.cxx:22
 AtlMuon.cxx:23
 AtlMuon.cxx:24
 AtlMuon.cxx:25
 AtlMuon.cxx:26
 AtlMuon.cxx:27
 AtlMuon.cxx:28
 AtlMuon.cxx:29
 AtlMuon.cxx:30
 AtlMuon.cxx:31
 AtlMuon.cxx:32
 AtlMuon.cxx:33
 AtlMuon.cxx:34
 AtlMuon.cxx:35
 AtlMuon.cxx:36
 AtlMuon.cxx:37
 AtlMuon.cxx:38
 AtlMuon.cxx:39
 AtlMuon.cxx:40
 AtlMuon.cxx:41
 AtlMuon.cxx:42
 AtlMuon.cxx:43
 AtlMuon.cxx:44
 AtlMuon.cxx:45
 AtlMuon.cxx:46
 AtlMuon.cxx:47
 AtlMuon.cxx:48
 AtlMuon.cxx:49
 AtlMuon.cxx:50
 AtlMuon.cxx:51
 AtlMuon.cxx:52
 AtlMuon.cxx:53
 AtlMuon.cxx:54
 AtlMuon.cxx:55
 AtlMuon.cxx:56
 AtlMuon.cxx:57
 AtlMuon.cxx:58
 AtlMuon.cxx:59
 AtlMuon.cxx:60
 AtlMuon.cxx:61
 AtlMuon.cxx:62
 AtlMuon.cxx:63
 AtlMuon.cxx:64
 AtlMuon.cxx:65
 AtlMuon.cxx:66
 AtlMuon.cxx:67
 AtlMuon.cxx:68
 AtlMuon.cxx:69
 AtlMuon.cxx:70
 AtlMuon.cxx:71
 AtlMuon.cxx:72
 AtlMuon.cxx:73
 AtlMuon.cxx:74
 AtlMuon.cxx:75
 AtlMuon.cxx:76
 AtlMuon.cxx:77
 AtlMuon.cxx:78
 AtlMuon.cxx:79
 AtlMuon.cxx:80
 AtlMuon.cxx:81
 AtlMuon.cxx:82
 AtlMuon.cxx:83
 AtlMuon.cxx:84
 AtlMuon.cxx:85
 AtlMuon.cxx:86
 AtlMuon.cxx:87
 AtlMuon.cxx:88
 AtlMuon.cxx:89
 AtlMuon.cxx:90
 AtlMuon.cxx:91
 AtlMuon.cxx:92
 AtlMuon.cxx:93
 AtlMuon.cxx:94
 AtlMuon.cxx:95
 AtlMuon.cxx:96
 AtlMuon.cxx:97
 AtlMuon.cxx:98
 AtlMuon.cxx:99
 AtlMuon.cxx:100
 AtlMuon.cxx:101
 AtlMuon.cxx:102
 AtlMuon.cxx:103
 AtlMuon.cxx:104
 AtlMuon.cxx:105
 AtlMuon.cxx:106
 AtlMuon.cxx:107
 AtlMuon.cxx:108
 AtlMuon.cxx:109
 AtlMuon.cxx:110
 AtlMuon.cxx:111
 AtlMuon.cxx:112
 AtlMuon.cxx:113
 AtlMuon.cxx:114
 AtlMuon.cxx:115
 AtlMuon.cxx:116
 AtlMuon.cxx:117
 AtlMuon.cxx:118
 AtlMuon.cxx:119
 AtlMuon.cxx:120
 AtlMuon.cxx:121
 AtlMuon.cxx:122
 AtlMuon.cxx:123
 AtlMuon.cxx:124
 AtlMuon.cxx:125
 AtlMuon.cxx:126
 AtlMuon.cxx:127
 AtlMuon.cxx:128
 AtlMuon.cxx:129
 AtlMuon.cxx:130
 AtlMuon.cxx:131
 AtlMuon.cxx:132
 AtlMuon.cxx:133
 AtlMuon.cxx:134
 AtlMuon.cxx:135
 AtlMuon.cxx:136
 AtlMuon.cxx:137
 AtlMuon.cxx:138
 AtlMuon.cxx:139
 AtlMuon.cxx:140
 AtlMuon.cxx:141
 AtlMuon.cxx:142
 AtlMuon.cxx:143
 AtlMuon.cxx:144
 AtlMuon.cxx:145
 AtlMuon.cxx:146
 AtlMuon.cxx:147
 AtlMuon.cxx:148
 AtlMuon.cxx:149
 AtlMuon.cxx:150
 AtlMuon.cxx:151
 AtlMuon.cxx:152
 AtlMuon.cxx:153
 AtlMuon.cxx:154
 AtlMuon.cxx:155
 AtlMuon.cxx:156
 AtlMuon.cxx:157
 AtlMuon.cxx:158
 AtlMuon.cxx:159
 AtlMuon.cxx:160
 AtlMuon.cxx:161
 AtlMuon.cxx:162
 AtlMuon.cxx:163
 AtlMuon.cxx:164
 AtlMuon.cxx:165
 AtlMuon.cxx:166
 AtlMuon.cxx:167
 AtlMuon.cxx:168
 AtlMuon.cxx:169
 AtlMuon.cxx:170
 AtlMuon.cxx:171
 AtlMuon.cxx:172
 AtlMuon.cxx:173
 AtlMuon.cxx:174
 AtlMuon.cxx:175
 AtlMuon.cxx:176
 AtlMuon.cxx:177
 AtlMuon.cxx:178
 AtlMuon.cxx:179
 AtlMuon.cxx:180
 AtlMuon.cxx:181
 AtlMuon.cxx:182
 AtlMuon.cxx:183
 AtlMuon.cxx:184
 AtlMuon.cxx:185
 AtlMuon.cxx:186
 AtlMuon.cxx:187
 AtlMuon.cxx:188
 AtlMuon.cxx:189
 AtlMuon.cxx:190
 AtlMuon.cxx:191
 AtlMuon.cxx:192
 AtlMuon.cxx:193
 AtlMuon.cxx:194
 AtlMuon.cxx:195
 AtlMuon.cxx:196
 AtlMuon.cxx:197
 AtlMuon.cxx:198
 AtlMuon.cxx:199
 AtlMuon.cxx:200
 AtlMuon.cxx:201
 AtlMuon.cxx:202
 AtlMuon.cxx:203
 AtlMuon.cxx:204
 AtlMuon.cxx:205
 AtlMuon.cxx:206
 AtlMuon.cxx:207
 AtlMuon.cxx:208
 AtlMuon.cxx:209
 AtlMuon.cxx:210
 AtlMuon.cxx:211
 AtlMuon.cxx:212
 AtlMuon.cxx:213
 AtlMuon.cxx:214
 AtlMuon.cxx:215
 AtlMuon.cxx:216
 AtlMuon.cxx:217
 AtlMuon.cxx:218
 AtlMuon.cxx:219
 AtlMuon.cxx:220
 AtlMuon.cxx:221
 AtlMuon.cxx:222
 AtlMuon.cxx:223
 AtlMuon.cxx:224
 AtlMuon.cxx:225
 AtlMuon.cxx:226
 AtlMuon.cxx:227
 AtlMuon.cxx:228
 AtlMuon.cxx:229
 AtlMuon.cxx:230
 AtlMuon.cxx:231
 AtlMuon.cxx:232
 AtlMuon.cxx:233
 AtlMuon.cxx:234
 AtlMuon.cxx:235
 AtlMuon.cxx:236
 AtlMuon.cxx:237
 AtlMuon.cxx:238
 AtlMuon.cxx:239
 AtlMuon.cxx:240
 AtlMuon.cxx:241
 AtlMuon.cxx:242
 AtlMuon.cxx:243
 AtlMuon.cxx:244
 AtlMuon.cxx:245
 AtlMuon.cxx:246
 AtlMuon.cxx:247
 AtlMuon.cxx:248
 AtlMuon.cxx:249
 AtlMuon.cxx:250
 AtlMuon.cxx:251
 AtlMuon.cxx:252
 AtlMuon.cxx:253
 AtlMuon.cxx:254
 AtlMuon.cxx:255
 AtlMuon.cxx:256
 AtlMuon.cxx:257
 AtlMuon.cxx:258
 AtlMuon.cxx:259
 AtlMuon.cxx:260
 AtlMuon.cxx:261
 AtlMuon.cxx:262
 AtlMuon.cxx:263
 AtlMuon.cxx:264
 AtlMuon.cxx:265
 AtlMuon.cxx:266
 AtlMuon.cxx:267
 AtlMuon.cxx:268
 AtlMuon.cxx:269
 AtlMuon.cxx:270
 AtlMuon.cxx:271
 AtlMuon.cxx:272
 AtlMuon.cxx:273
 AtlMuon.cxx:274
 AtlMuon.cxx:275
 AtlMuon.cxx:276
 AtlMuon.cxx:277
 AtlMuon.cxx:278
 AtlMuon.cxx:279
 AtlMuon.cxx:280
 AtlMuon.cxx:281
 AtlMuon.cxx:282
 AtlMuon.cxx:283
 AtlMuon.cxx:284
 AtlMuon.cxx:285
 AtlMuon.cxx:286
 AtlMuon.cxx:287
 AtlMuon.cxx:288
 AtlMuon.cxx:289
 AtlMuon.cxx:290
 AtlMuon.cxx:291
 AtlMuon.cxx:292
 AtlMuon.cxx:293
 AtlMuon.cxx:294
 AtlMuon.cxx:295
 AtlMuon.cxx:296
 AtlMuon.cxx:297
 AtlMuon.cxx:298
 AtlMuon.cxx:299
 AtlMuon.cxx:300
 AtlMuon.cxx:301
 AtlMuon.cxx:302
 AtlMuon.cxx:303
 AtlMuon.cxx:304
 AtlMuon.cxx:305
 AtlMuon.cxx:306
 AtlMuon.cxx:307
 AtlMuon.cxx:308
 AtlMuon.cxx:309
 AtlMuon.cxx:310
 AtlMuon.cxx:311
 AtlMuon.cxx:312
 AtlMuon.cxx:313
 AtlMuon.cxx:314
 AtlMuon.cxx:315
 AtlMuon.cxx:316
 AtlMuon.cxx:317
 AtlMuon.cxx:318
 AtlMuon.cxx:319
 AtlMuon.cxx:320
 AtlMuon.cxx:321
 AtlMuon.cxx:322
 AtlMuon.cxx:323
 AtlMuon.cxx:324
 AtlMuon.cxx:325
 AtlMuon.cxx:326
 AtlMuon.cxx:327
 AtlMuon.cxx:328
 AtlMuon.cxx:329
 AtlMuon.cxx:330
 AtlMuon.cxx:331
 AtlMuon.cxx:332
 AtlMuon.cxx:333
 AtlMuon.cxx:334
 AtlMuon.cxx:335
 AtlMuon.cxx:336
 AtlMuon.cxx:337
 AtlMuon.cxx:338
 AtlMuon.cxx:339
 AtlMuon.cxx:340
 AtlMuon.cxx:341
 AtlMuon.cxx:342
 AtlMuon.cxx:343
 AtlMuon.cxx:344
 AtlMuon.cxx:345
 AtlMuon.cxx:346
 AtlMuon.cxx:347