diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..c788190 --- /dev/null +++ b/.clang-format @@ -0,0 +1,236 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AlignConsecutiveAssignments: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: true +AlignConsecutiveBitFields: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: false +AlignConsecutiveDeclarations: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: false +AlignConsecutiveMacros: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: false +AlignConsecutiveShortCaseStatements: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCaseColons: false +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: + Kind: Always + OverEmptyLines: 0 +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortEnumsOnASingleLine: true +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: true +BitFieldColonSpacing: Both +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterExternBlock: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakAfterAttributes: Never +BreakAfterJavaFieldAnnotations: false +BreakArrays: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: Always +BreakBeforeBraces: Attach +BreakBeforeInlineASMColon: OnlyMultiline +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakInheritanceList: BeforeColon +BreakStringLiterals: true +ColumnLimit: 120 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseBlocks: false +IndentCaseLabels: false +IndentExternBlock: AfterExternBlock +IndentGotoLabels: true +IndentPPDirectives: None +IndentRequiresClause: true +IndentWidth: 2 +IndentWrappedFunctionNames: false +InsertBraces: false +InsertNewlineAtEOF: false +InsertTrailingCommas: None +IntegerLiteralSeparator: + Binary: 0 + BinaryMinDigits: 0 + Decimal: 0 + DecimalMinDigits: 0 + Hex: 0 + HexMinDigits: 0 +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +KeepEmptyLinesAtEOF: false +LambdaBodyIndentation: Signature +LineEnding: DeriveLF +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: Inner +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PackConstructorInitializers: BinPack +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyIndentedWhitespace: 0 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Left +PPIndentWidth: -1 +QualifierAlignment: Leave +ReferenceAlignment: Pointer +ReflowComments: true +RemoveBracesLLVM: false +RemoveParentheses: Leave +RemoveSemicolon: false +RequiresClausePosition: OwnLine +RequiresExpressionIndentation: OuterScope +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: LexicographicNumeric +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceAroundPointerQualifiers: Default +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeJsonColon: false +SpaceBeforeParens: ControlStatements +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterForeachMacros: true + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: true + AfterOverloadedOperator: false + AfterRequiresInClause: false + AfterRequiresInExpression: false + BeforeNonEmptyParentheses: false +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: Never +SpacesInContainerLiterals: true +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParens: Never +SpacesInParensOptions: + InCStyleCasts: false + InConditionalStatements: false + InEmptyParentheses: false + Other: false +SpacesInSquareBrackets: false +Standard: Latest +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseTab: Never +VerilogBreakBetweenInstancePorts: true +WhitespaceSensitiveMacros: + - BOOST_PP_STRINGIZE + - CF_SWIFT_NAME + - NS_SWIFT_NAME + - PP_STRINGIZE + - STRINGIZE +... + diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000..787ac06 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,2 @@ +# clang-format +8d83bec53dabca039889042b170a91ae3dd9852a diff --git a/examples/anatrack.C b/examples/anatrack.C index 749cd88..5318616 100644 --- a/examples/anatrack.C +++ b/examples/anatrack.C @@ -1,44 +1,64 @@ -#include -#include -#include "TFile.h" #include "TDirectory.h" +#include "TFile.h" +#include +#include +// plot6hists(TFile* fi, char* title, char* h1,char* h2,char* h3,char* h4, char* h5, char* h6=0){ +plot6hists(TFile* fi, const char* dir, const std::string& fileName, char* title, char* h1, char* h2, char* h3, char* h4, + char* h5, char* h6 = 0) { -//plot6hists(TFile* fi, char* title, char* h1,char* h2,char* h3,char* h4, char* h5, char* h6=0){ -plot6hists(TFile* fi,const char* dir, const std::string& fileName, char* title, char* h1,char* h2,char* h3,char* h4, char* h5, char* h6=0){ - - c1 = new TCanvas(title,title,-5); + c1 = new TCanvas(title, title, -5); c1->Clear(); - c1->Divide(3,2); - - int pad = 1; - - std::string path = std::string("/") + std::string( dir ) + std::string("/" ) ; - // std::string path( "/tracks_mup_50gev/" ) ; - - std::string hName ; - TH1D* hist = 0 ; - - c1->cd(pad++); hName = path + std::string(h1) ; hist = (TH1D*) fi->Get( hName.c_str() ) ; if(hist) hist->Draw() ; - c1->cd(pad++); hName = path + std::string(h2) ; hist = (TH1D*) fi->Get( hName.c_str() ) ; if(hist) hist->Draw() ; - c1->cd(pad++); hName = path + std::string(h3) ; hist = (TH1D*) fi->Get( hName.c_str() ) ; if(hist) hist->Draw() ; - c1->cd(pad++); hName = path + std::string(h4) ; hist = (TH1D*) fi->Get( hName.c_str() ) ; if(hist) hist->Draw() ; - c1->cd(pad++); hName = path + std::string(h5) ; hist = (TH1D*) fi->Get( hName.c_str() ) ; if(hist) hist->Draw() ; + c1->Divide(3, 2); + int pad = 1; - if( h6 != 0 ) { + std::string path = std::string("/") + std::string(dir) + std::string("/"); + // std::string path( "/tracks_mup_50gev/" ) ; - c1->cd(pad++); hName = path + std::string(h6) ; hist = (TH1D*) fi->Get( hName.c_str() ) ; if(hist) hist->Draw() ; + std::string hName; + TH1D* hist = 0; + + c1->cd(pad++); + hName = path + std::string(h1); + hist = (TH1D*)fi->Get(hName.c_str()); + if (hist) + hist->Draw(); + c1->cd(pad++); + hName = path + std::string(h2); + hist = (TH1D*)fi->Get(hName.c_str()); + if (hist) + hist->Draw(); + c1->cd(pad++); + hName = path + std::string(h3); + hist = (TH1D*)fi->Get(hName.c_str()); + if (hist) + hist->Draw(); + c1->cd(pad++); + hName = path + std::string(h4); + hist = (TH1D*)fi->Get(hName.c_str()); + if (hist) + hist->Draw(); + c1->cd(pad++); + hName = path + std::string(h5); + hist = (TH1D*)fi->Get(hName.c_str()); + if (hist) + hist->Draw(); + + if (h6 != 0) { + + c1->cd(pad++); + hName = path + std::string(h6); + hist = (TH1D*)fi->Get(hName.c_str()); + if (hist) + hist->Draw(); } // std::string fileName( title ) ; // fileName += ".pdf" ; - c1->Print( fileName.c_str() ) ; - + c1->Print(fileName.c_str()); } - - void anatrack(const char* FILEN, const char* dirName) { gROOT->Reset(); @@ -50,29 +70,21 @@ void anatrack(const char* FILEN, const char* dirName) { gStyle->SetStatH(.15); // style->SetStatX(0.90); // style->SetStatY(0.90); - gStyle->SetTitleFont(32,"xyz"); - gStyle->SetTitleSize(0.07,"xyz"); - gStyle->SetTitleOffset(1.1,"yz"); - gStyle->SetTitleOffset(1.0,"x"); - + gStyle->SetTitleFont(32, "xyz"); + gStyle->SetTitleSize(0.07, "xyz"); + gStyle->SetTitleOffset(1.1, "yz"); + gStyle->SetTitleOffset(1.0, "x"); - - std::string fN = std::string(dirName) + ".pdf" ; + std::string fN = std::string(dirName) + ".pdf"; - TFile* f = new TFile(FILEN) ; - f->cd( dirName ) ; + TFile* f = new TFile(FILEN); + f->cd(dirName); - const char* dn = dirName ; - - plot6hists( f, dn , fN+"(" ,"track_params", "hphi", "hd0" , "homega" , "hz0", "htanL" , "hpt" ) ; - plot6hists( f, dn , fN ,"track_params_mcp", "hphimcp", "hd0mcp" , "homegamcp" , "hz0mcp", "htanLmcp" , "hptmcp" ) ; - plot6hists( f, dn , fN ,"track_params_error", "hephi", "hed0" , "heomega" , "hez0", "hetanL" , "hept" ) ; - plot6hists( f, dn , fN ,"track_params_delta", "hdphi", "hdd0" , "hdomega" , "hdz0", "hdtanL" , "hdpt" ) ; - plot6hists( f, dn , fN+")" ,"track_params_pulls", "hpphi", "hpd0" , "hpomega" , "hpz0", "hptanL" , "hppt" ) ; + const char* dn = dirName; + plot6hists(f, dn, fN + "(", "track_params", "hphi", "hd0", "homega", "hz0", "htanL", "hpt"); + plot6hists(f, dn, fN, "track_params_mcp", "hphimcp", "hd0mcp", "homegamcp", "hz0mcp", "htanLmcp", "hptmcp"); + plot6hists(f, dn, fN, "track_params_error", "hephi", "hed0", "heomega", "hez0", "hetanL", "hept"); + plot6hists(f, dn, fN, "track_params_delta", "hdphi", "hdd0", "hdomega", "hdz0", "hdtanL", "hdpt"); + plot6hists(f, dn, fN + ")", "track_params_pulls", "hpphi", "hpd0", "hpomega", "hpz0", "hptanL", "hppt"); } - - - - - diff --git a/examples/trkeff.C b/examples/trkeff.C index 05a864b..ef05d2b 100644 --- a/examples/trkeff.C +++ b/examples/trkeff.C @@ -1,26 +1,25 @@ -void trkeff(const char* FILEN ) { +void trkeff(const char* FILEN) { - float minEff = 0.8 ; - float maxEff = 1.01 ; + float minEff = 0.8; + float maxEff = 1.01; - float minpt = 0.2 ; - float maxpt = 500. ; + float minpt = 0.2; + float maxpt = 500.; - float minct = 0.0 ; - float maxct = 1. ; + float minct = 0.0; + float maxct = 1.; - const char* title = "TPC track finding efficiency - WW @ 1000 GeV" ; + const char* title = "TPC track finding efficiency - WW @ 1000 GeV"; // const char* title = "TPC track finding efficiency - tau pairs @ 500 GeV" ; - //const char* title = "TPC track finding efficiency - ttbar @ 500 GeV" ; - //const char* title = "TPC track finding efficiency - tracks from v-zeros (in ttbar @ 500 GeV)" ; + // const char* title = "TPC track finding efficiency - ttbar @ 500 GeV" ; + // const char* title = "TPC track finding efficiency - tracks from v-zeros (in ttbar @ 500 GeV)" ; - char* dirClupa = "clupaeff" ; + char* dirClupa = "clupaeff"; // char* dirTPC = "marlintrkeff" ; - char* dirLDC = "marlintrkeff" ; + char* dirLDC = "marlintrkeff"; - gROOT->Reset(); gROOT->SetStyle("Plain"); // gStyle->SetOptFit(111); @@ -32,161 +31,145 @@ void trkeff(const char* FILEN ) { // style->SetStatX(0.90); // style->SetStatY(0.90); - gStyle->SetTitleFont(32,"xyz"); - gStyle->SetTitleSize(0.07,"xyz"); - gStyle->SetTitleOffset(1.1,"yz"); - gStyle->SetTitleOffset(1.0,"x"); - + gStyle->SetTitleFont(32, "xyz"); + gStyle->SetTitleSize(0.07, "xyz"); + gStyle->SetTitleOffset(1.1, "yz"); + gStyle->SetTitleOffset(1.0, "x"); + // gStyle->SetMarkerStyle( kFullCircle ) ; // gStyle->SetMarkerStyle( kOpenCircle ) ; - gStyle->SetMarkerStyle( kDot ) ; - + gStyle->SetMarkerStyle(kDot); gROOT->ForceStyle(); - - TFile* f = new TFile( FILEN ) ; - + TFile* f = new TFile(FILEN); //---- create some graphs with asymmetric efficiency errors ----------- - f->cd( dirClupa ) ; + f->cd(dirClupa); - TGraphAsymmErrors* gpt_clupa = new TGraphAsymmErrors ; - gpt_clupa->Divide( hpt_f , hpt_t , "v" ) ; - gpt_clupa->SetName("gpt_clupa" ) ; + TGraphAsymmErrors* gpt_clupa = new TGraphAsymmErrors; + gpt_clupa->Divide(hpt_f, hpt_t, "v"); + gpt_clupa->SetName("gpt_clupa"); // TGraphAsymmErrors* gcosth_clupa = new TGraphAsymmErrors ; // gcosth_clupa->Divide( hcosth_f , hcosth_t , "v" ) ; - TGraphAsymmErrors* gacth_clupa = new TGraphAsymmErrors ; - gacth_clupa->Divide( hacth_f , hacth_t , "v" ) ; - gacth_clupa->SetName("gacth_clupa" ) ; - + TGraphAsymmErrors* gacth_clupa = new TGraphAsymmErrors; + gacth_clupa->Divide(hacth_f, hacth_t, "v"); + gacth_clupa->SetName("gacth_clupa"); -// f->cd( dirTPC ) ; -// TGraphAsymmErrors* gpt_tpc = new TGraphAsymmErrors ; -// gpt_tpc->Divide( hpt_f , hpt_t , "v" ) ; + // f->cd( dirTPC ) ; + // TGraphAsymmErrors* gpt_tpc = new TGraphAsymmErrors ; + // gpt_tpc->Divide( hpt_f , hpt_t , "v" ) ; -// // TGraphAsymmErrors* gcosth_tpc = new TGraphAsymmErrors ; -// // gcosth_tpc->Divide( hcosth_f , hcosth_t , "v" ) ; + // // TGraphAsymmErrors* gcosth_tpc = new TGraphAsymmErrors ; + // // gcosth_tpc->Divide( hcosth_f , hcosth_t , "v" ) ; -// TGraphAsymmErrors* gacth_tpc = new TGraphAsymmErrors ; -// gacth_tpc->Divide( hacth_f , hacth_t , "v" ) ; -// gacth_tpc->SetName("gacth_tpc" ) ; + // TGraphAsymmErrors* gacth_tpc = new TGraphAsymmErrors ; + // gacth_tpc->Divide( hacth_f , hacth_t , "v" ) ; + // gacth_tpc->SetName("gacth_tpc" ) ; - - - f->cd( dirLDC ) ; - TGraphAsymmErrors* gpt_ldc = new TGraphAsymmErrors ; - gpt_ldc->Divide( hpt_f , hpt_t , "v" ) ; + f->cd(dirLDC); + TGraphAsymmErrors* gpt_ldc = new TGraphAsymmErrors; + gpt_ldc->Divide(hpt_f, hpt_t, "v"); // TGraphAsymmErrors* gcosth_ldc = new TGraphAsymmErrors ; // gcosth_ldc->Divide( hcosth_f , hcosth_t , "v" ) ; - TGraphAsymmErrors* gacth_ldc = new TGraphAsymmErrors ; - gacth_ldc->Divide( hacth_f , hacth_t , "v" ) ; - gacth_ldc->SetName("gacth_ldc" ) ; - - + TGraphAsymmErrors* gacth_ldc = new TGraphAsymmErrors; + gacth_ldc->Divide(hacth_f, hacth_t, "v"); + gacth_ldc->SetName("gacth_ldc"); // ----------- create histograms that defnie the axis ranges of the plot ---- - hpt_clupa = new TH2F( "hpt_clupa", title ,10, minpt, maxpt, 10, minEff , maxEff ) ; + hpt_clupa = new TH2F("hpt_clupa", title, 10, minpt, maxpt, 10, minEff, maxEff); - hacth_clupa = new TH2F( "hcosth_clupa", "" , 10, minct, maxct, 10, minEff , maxEff ) ; + hacth_clupa = new TH2F("hcosth_clupa", "", 10, minct, maxct, 10, minEff, maxEff); // hpt_clupa = new TH2F("hpt_clupa","track finding efficiency vs. pt",10, minpt, maxpt, 10, minEff , maxEff ) ; - // hacth_clupa = new TH2F("hcosth_clupa","track finding efficiency vs. |cos(theta)|",10, minct, maxct, 10, minEff , maxEff ) ; + // hacth_clupa = new TH2F("hcosth_clupa","track finding efficiency vs. |cos(theta)|",10, minct, maxct, 10, minEff , + // maxEff ) ; - hpt_clupa->GetYaxis()->SetTitle( "#epsilon_{t_find}" ); - hpt_clupa->GetYaxis()->SetTitleSize( 0.04 ) ; - hpt_clupa->GetYaxis()->SetTitleOffset( 0.5 ); + hpt_clupa->GetYaxis()->SetTitle("#epsilon_{t_find}"); + hpt_clupa->GetYaxis()->SetTitleSize(0.04); + hpt_clupa->GetYaxis()->SetTitleOffset(0.5); - hpt_clupa->GetXaxis()->SetTitle( "p_{t}/GeV" ); - hpt_clupa->GetXaxis()->SetTitleSize( 0.04 ) ; - hpt_clupa->GetXaxis()->SetTitleOffset( 1.2 ); + hpt_clupa->GetXaxis()->SetTitle("p_{t}/GeV"); + hpt_clupa->GetXaxis()->SetTitleSize(0.04); + hpt_clupa->GetXaxis()->SetTitleOffset(1.2); - hacth_clupa->GetYaxis()->SetTitle( "#epsilon_{t_find}" ); - hacth_clupa->GetYaxis()->SetTitleSize( 0.04 ) ; - hacth_clupa->GetYaxis()->SetTitleOffset( 0.5 ); + hacth_clupa->GetYaxis()->SetTitle("#epsilon_{t_find}"); + hacth_clupa->GetYaxis()->SetTitleSize(0.04); + hacth_clupa->GetYaxis()->SetTitleOffset(0.5); - hacth_clupa->GetXaxis()->SetTitle( "|cos(#theta)|" ); - hacth_clupa->GetXaxis()->SetTitleSize( 0.05 ) ; - hacth_clupa->GetXaxis()->SetTitleOffset( 1. ); + hacth_clupa->GetXaxis()->SetTitle("|cos(#theta)|"); + hacth_clupa->GetXaxis()->SetTitleSize(0.05); + hacth_clupa->GetXaxis()->SetTitleOffset(1.); //------------------------------ - - - c1 = new TCanvas("c_trkeff", title ,-5); + c1 = new TCanvas("c_trkeff", title, -5); c1->Clear(); - c1->Divide(1,2); - + c1->Divide(1, 2); + int pad = 1; - + //------------------------------------------------------------------------------------- - c1->cd( pad++ ) ; + c1->cd(pad++); - gPad->SetLogx() ; + gPad->SetLogx(); - c1->GetPad(1)->SetTitle("track finding efficiency vs. pt") ; - - hpt_clupa->Draw() ; + c1->GetPad(1)->SetTitle("track finding efficiency vs. pt"); - gpt_clupa->SetMarkerStyle( kOpenCircle) ; - gpt_clupa->SetMarkerColor( kRed) ; - gpt_clupa->SetLineColor( kRed ) ; - gpt_clupa->Draw("P") ; + hpt_clupa->Draw(); -// gpt_tpc->SetMarkerStyle( kOpenTriangleUp ) ; -// gpt_tpc->SetMarkerColor( kBlue) ; -// gpt_tpc->SetLineColor( kBlue ) ; -// gpt_tpc->Draw("P") ; + gpt_clupa->SetMarkerStyle(kOpenCircle); + gpt_clupa->SetMarkerColor(kRed); + gpt_clupa->SetLineColor(kRed); + gpt_clupa->Draw("P"); - gpt_ldc->SetMarkerStyle( kDot) ; - gpt_ldc->SetMarkerColor( kBlack) ; - gpt_ldc->SetLineColor( kBlack ) ; - gpt_ldc->Draw("P") ; + // gpt_tpc->SetMarkerStyle( kOpenTriangleUp ) ; + // gpt_tpc->SetMarkerColor( kBlue) ; + // gpt_tpc->SetLineColor( kBlue ) ; + // gpt_tpc->Draw("P") ; + gpt_ldc->SetMarkerStyle(kDot); + gpt_ldc->SetMarkerColor(kBlack); + gpt_ldc->SetLineColor(kBlack); + gpt_ldc->Draw("P"); //======================================================================================== - c1->cd( pad++ ) ; - - c_trkeff->GetPad(2)->SetTitle("track finding efficiency vs. |cos(theta)|") ; + c1->cd(pad++); - hacth_clupa->Draw() ; - gacth_clupa->SetMarkerStyle( kOpenCircle) ; - gacth_clupa->SetMarkerColor( kRed) ; - gacth_clupa->SetLineColor( kRed ) ; - gacth_clupa->Draw("P") ; + c_trkeff->GetPad(2)->SetTitle("track finding efficiency vs. |cos(theta)|"); -// gacth_tpc->SetMarkerStyle( kOpenTriangleUp ) ; -// gacth_tpc->SetMarkerColor( kBlue) ; -// gacth_tpc->SetLineColor( kBlue ) ; -// gacth_tpc->Draw("P") ; + hacth_clupa->Draw(); + gacth_clupa->SetMarkerStyle(kOpenCircle); + gacth_clupa->SetMarkerColor(kRed); + gacth_clupa->SetLineColor(kRed); + gacth_clupa->Draw("P"); - gacth_ldc->SetMarkerStyle( kDot) ; - gacth_ldc->SetMarkerColor( kBlack) ; - gacth_ldc->SetLineColor( kBlack ) ; - gacth_ldc->Draw("P") ; + // gacth_tpc->SetMarkerStyle( kOpenTriangleUp ) ; + // gacth_tpc->SetMarkerColor( kBlue) ; + // gacth_tpc->SetLineColor( kBlue ) ; + // gacth_tpc->Draw("P") ; + gacth_ldc->SetMarkerStyle(kDot); + gacth_ldc->SetMarkerColor(kBlack); + gacth_ldc->SetLineColor(kBlack); + gacth_ldc->Draw("P"); // TLegend* tl = ((TPad*)c1->GetPad(2))->BuildLegend() ; // tl->Draw() TLegend* leg = new TLegend(0.5, 0.2, .8, .5); - leg->AddEntry( "gacth_clupa" , "Clupatra (TPC only)" , "lep") ; -// leg->AddEntry( "gacth_tpc" , "LEPTracking (TPC only)", "lep") ; -// leg->AddEntry( "gacth_ldc" , "MarlinTrk (incl VTX/SIT,FTD)", "lep") ; + leg->AddEntry("gacth_clupa", "Clupatra (TPC only)", "lep"); + // leg->AddEntry( "gacth_tpc" , "LEPTracking (TPC only)", "lep") ; + // leg->AddEntry( "gacth_ldc" , "MarlinTrk (incl VTX/SIT,FTD)", "lep") ; leg->Draw(); - // --------------- save to pdf file ---------------------------------- - std::string pdfFile( std::string( FILEN ) + std::string( ".pdf" ) ) ; + std::string pdfFile(std::string(FILEN) + std::string(".pdf")); - c1->Print( pdfFile.c_str() ) ; - + c1->Print(pdfFile.c_str()); } - - - diff --git a/include/ClupatraProcessor.h b/include/ClupatraProcessor.h index 6c4cb0a..1d56ba0 100644 --- a/include/ClupatraProcessor.h +++ b/include/ClupatraProcessor.h @@ -1,7 +1,7 @@ #ifndef ClupatraProcessor_h #define ClupatraProcessor_h 1 -//#include "assert.h" +// #include "assert.h" #include "marlin/Processor.h" @@ -11,14 +11,13 @@ #include - // forward declarations -namespace MarlinTrk{ - class IMarlinTrkSystem ; +namespace MarlinTrk { +class IMarlinTrkSystem; } -namespace EVENT{ - class Track ; +namespace EVENT { +class Track; } // namespace DD4hep{ @@ -27,150 +26,152 @@ namespace EVENT{ // } // - -/** ClupatraProcessor : nearest neighbour clustering seeded pattern recognition using a Kalman-Filter for extrapolation and - * hit search. - * +/** ClupatraProcessor : nearest neighbour clustering seeded pattern recognition using a Kalman-Filter for extrapolation + * and hit search. + * * @parameter TPCHitCollection Name of the tpc hit input collections * @parameter OutputCollection Name of the output collection with final TPC tracks * @parameter SegmentCollectionName Name of the output collection that has the individual track segments - * @parameter CreateDebugCollections optionally create some debug collection with intermediate track segments and used and unused hits - * + * @parameter CreateDebugCollections optionally create some debug collection with intermediate track segments and + * used and unused hits + * * @parameter DistanceCut Cut for distance between hits in mm for the seed finding * @parameter Chi2Cut the maximum chi2-distance for which a hit is considered for merging - * @parameter CosAlphaCut Cut for max.angle between hits in consecutive layers for seed finding - NB value should be smaller than 1 - default is 0.9999999 - * @parameter MaxDeltaChi2 the maximum delta Chi2 after filtering for which a hit is added to a track segement - * + * @parameter CosAlphaCut Cut for max.angle between hits in consecutive layers for seed finding - NB + * value should be smaller than 1 - default is 0.9999999 + * @parameter MaxDeltaChi2 the maximum delta Chi2 after filtering for which a hit is added to a track + * segement + * * @parameter DuplicatePadRowFraction allowed fraction of hits in same pad row per track - * @parameter NLoopForSeeding number of seed finding loops - every loop increases the distance cut by DistanceCut/NLoopForSeeding - * @parameter NumberOfZBins number of bins in z over total length of TPC - hits from different z bins are nver merged + * @parameter NLoopForSeeding number of seed finding loops - every loop increases the distance cut by + * DistanceCut/NLoopForSeeding + * @parameter NumberOfZBins number of bins in z over total length of TPC - hits from different z bins are + * nver merged * @parameter PadRowRange number of pad rows used in initial seed clustering - * - * @parameter MaxStepWithoutHit the maximum number of layers without finding a hit before hit search search is stopped - * @parameter MinLayerFractionWithMultiplicity minimum fraction of layers that have a given multiplicity, when forcing a cluster into sub clusters - * @parameter MinLayerNumberWithMultiplicity minimum number of layers that have a given multiplicity, when forcing a cluster into sub clusters + * + * @parameter MaxStepWithoutHit the maximum number of layers without finding a hit before hit search + * search is stopped + * @parameter MinLayerFractionWithMultiplicity minimum fraction of layers that have a given multiplicity, when + * forcing a cluster into sub clusters + * @parameter MinLayerNumberWithMultiplicity minimum number of layers that have a given multiplicity, when forcing + * a cluster into sub clusters * @parameter MinimumClusterSize minimum number of hits per cluster - * - * @parameter TrackEndsOuterCentralDist maximum radial distance [mm] from outer field cage of last hit, such that the track is considered to end at the end - * @parameter TrackEndsOuterForwardDist maximum distance in z [mm] from endplate of last hit, such that the track is considered to end at the end + * + * @parameter TrackEndsOuterCentralDist maximum radial distance [mm] from outer field cage of last hit, such that the + * track is considered to end at the end + * @parameter TrackEndsOuterForwardDist maximum distance in z [mm] from endplate of last hit, such that the track is + * considered to end at the end * @parameter TrackIsCurlerOmega minimum curvature omega of a track segment for being considered a curler - * @parameter TrackStartsInnerDist maximum radial distance [mm] from inner field cage of first hit, such that the track is considered to start at the beginning - * + * @parameter TrackStartsInnerDist maximum radial distance [mm] from inner field cage of first hit, such that the + * track is considered to start at the beginning + * * @parameter EnergyLossOn Use Energy Loss in Fit * @parameter MultipleScatteringOn Use MultipleScattering in Fit * @parameter SmoothOn Smooth All Mesurement Sites in Fit - * + * * @parameter pickUpSiHits try to pick up hits from Si-trackers - * @parameter SITHitCollection name of the SIT hit collections - used to extend TPC tracks if (pickUpSiHits==true) - * @parameter VXDHitCollection name of the VXD hit collections - used to extend TPC tracks if (pickUpSiHits==true) + * @parameter SITHitCollection name of the SIT hit collections - used to extend TPC tracks if + * (pickUpSiHits==true) + * @parameter VXDHitCollection name of the VXD hit collections - used to extend TPC tracks if + * (pickUpSiHits==true) * @parameter SITDetectorName name of the SIT-like inner Si-tracking barrel detector (default: SIT) * @parameter VXDDetectorName name of the VXD-like vertex barrel detector (default: VXD) * - * @parameter Verbosity verbosity level of this processor ("DEBUG0-4,MESSAGE0-4,WARNING0-4,ERROR0-4,SILENT") - * + * @parameter Verbosity verbosity level of this processor + * ("DEBUG0-4,MESSAGE0-4,WARNING0-4,ERROR0-4,SILENT") + * * @author F.Gaede, DESY, 2011/2012 - * + * */ class ClupatraProcessor : public marlin::Processor { - - public: - - virtual Processor* newProcessor() { return new ClupatraProcessor ; } - - ClupatraProcessor(const ClupatraProcessor&) = delete ; - ClupatraProcessor& operator=(const ClupatraProcessor&) = delete ; - - ClupatraProcessor() ; - + +public: + virtual Processor* newProcessor() { return new ClupatraProcessor; } + + ClupatraProcessor(const ClupatraProcessor&) = delete; + ClupatraProcessor& operator=(const ClupatraProcessor&) = delete; + + ClupatraProcessor(); + /** Called at the begin of the job before anything is read. * Use to initialize the processor, e.g. book histograms. */ - virtual void init() ; - + virtual void init(); + /** Called for every run. */ - virtual void processRunHeader( lcio::LCRunHeader* run ) ; - + virtual void processRunHeader(lcio::LCRunHeader* run); + /** Called for every event - the working horse. */ - virtual void processEvent( lcio::LCEvent * evt ) ; + virtual void processEvent(lcio::LCEvent* evt); // void doBLA() ; - - - virtual void check( lcio::LCEvent * evt ) ; - - + + virtual void check(lcio::LCEvent* evt); + /** Called after data processing for clean up. */ - virtual void end() ; - - - protected: + virtual void end(); - /** helper method to compute a few track segment parameters (start and end points, z spread,...) +protected: + /** helper method to compute a few track segment parameters (start and end points, z spread,...) */ - void computeTrackInfo( lcio::Track* lTrk ) ; - + void computeTrackInfo(lcio::Track* lTrk); - void pickUpSiTrackerHits( EVENT::LCCollection* trackCol , LCEvent* evt) ; + void pickUpSiTrackerHits(EVENT::LCCollection* trackCol, LCEvent* evt); /** Input collection name. */ - std::string _colName {}; - std::string _vxdColName {}; - std::string _sitColName {}; - std::string _outColName {}; - std::string _sitDetectorName {}; - std::string _vxdDetectorName {}; - - std::string _segmentsOutColName {}; + std::string _colName{}; + std::string _vxdColName{}; + std::string _sitColName{}; + std::string _outColName{}; + std::string _sitDetectorName{}; + std::string _vxdDetectorName{}; - float _distCut {}; - float _cosAlphaCut {}; + std::string _segmentsOutColName{}; - float _duplicatePadRowFraction {}; - float _bfield {}; - - float _dChi2Max {}; - float _chi2Cut {}; - int _maxStep {}; + float _distCut{}; + float _cosAlphaCut{}; - float _minLayerFractionWithMultiplicity {}; - int _minLayerNumberWithMultiplicity {}; - int _nLoop {}; - - float _trackStartsInnerDist {}; - float _trackEndsOuterCentralDist {}; - float _trackEndsOuterForwardDist {}; - float _trackIsCurlerOmega {}; - - int _minCluSize {}; - int _padRowRange {}; - int _nZBins {}; + float _duplicatePadRowFraction{}; + float _bfield{}; - bool _MSOn {}; - bool _ElossOn {}; - bool _SmoothOn {}; - bool _pickUpSiHits {}; + float _dChi2Max{}; + float _chi2Cut{}; + int _maxStep{}; - bool _createDebugCollections {}; + float _minLayerFractionWithMultiplicity{}; + int _minLayerNumberWithMultiplicity{}; + int _nLoop{}; - int _caloFaceBarrelID {}; - int _caloFaceEndcapID {}; + float _trackStartsInnerDist{}; + float _trackEndsOuterCentralDist{}; + float _trackEndsOuterForwardDist{}; + float _trackIsCurlerOmega{}; + int _minCluSize{}; + int _padRowRange{}; + int _nZBins{}; - int _nRun {}; - int _nEvt {}; + bool _MSOn{}; + bool _ElossOn{}; + bool _SmoothOn{}; + bool _pickUpSiHits{}; - MarlinTrk::IMarlinTrkSystem* _trksystem {}; - std::string _trkSystemName {}; + bool _createDebugCollections{}; - const dd4hep::rec::FixedPadSizeTPCData* _tpc {}; + int _caloFaceBarrelID{}; + int _caloFaceEndcapID{}; -} ; - -#endif + int _nRun{}; + int _nEvt{}; + MarlinTrk::IMarlinTrkSystem* _trksystem{}; + std::string _trkSystemName{}; + const dd4hep::rec::FixedPadSizeTPCData* _tpc{}; +}; +#endif diff --git a/include/DebugDigiProcessor.h b/include/DebugDigiProcessor.h index 7dc1e09..6bc8c64 100644 --- a/include/DebugDigiProcessor.h +++ b/include/DebugDigiProcessor.h @@ -1,77 +1,67 @@ #ifndef DebugDigiProcessor_h #define DebugDigiProcessor_h 1 -#include "marlin/Processor.h" -#include "marlin/EventModifier.h" #include "lcio.h" -#include +#include "marlin/EventModifier.h" +#include "marlin/Processor.h" #include +#include - -using namespace lcio ; -using namespace marlin ; - +using namespace lcio; +using namespace marlin; /** DebugDigiProcessor puts all TrackerHits from the tracks in TrackCollection into one or more TrackerHitCollections. - * The Hits are sorted into the output collections based on CellIDDecoder( LCTrackerCellID::encoding_string() )( t )[ LCTrackerCellID::subdet() ]
- * Pre-existing collections with the names of the TrackerHitCollections are renamed to NAME_OLD - as is the TrackCollection. + * The Hits are sorted into the output collections based on CellIDDecoder( LCTrackerCellID::encoding_string() )( t + * )[ LCTrackerCellID::subdet() ]
Pre-existing collections with the names of the TrackerHitCollections are renamed + * to NAME_OLD - as is the TrackCollection. * * @parameter TrackCollection Name of the input collections with Tracks - * @parameter TrackerHitCollections The tracker hit collection names - needs to run parallel to SubDetectorIDs - * @parameter SubDetectorIDs The IDs of the subdetectors corresponding to the hit collections in TrackerHitCollectionNames - * + * @parameter TrackerHitCollections The tracker hit collection names - needs to run parallel to + * SubDetectorIDs + * @parameter SubDetectorIDs The IDs of the subdetectors corresponding to the hit collections + * in TrackerHitCollectionNames + * * @author F.Gaede, DESY - * @version $Id$ + * @version $Id$ */ class DebugDigiProcessor : public Processor, public EventModifier { - - public: - - virtual Processor* newProcessor() { return new DebugDigiProcessor ; } - - - DebugDigiProcessor() ; - + +public: + virtual Processor* newProcessor() { return new DebugDigiProcessor; } + + DebugDigiProcessor(); + /** Called at the begin of the job before anything is read. * Use to initialize the processor, e.g. book histograms. */ - virtual void init() ; - + virtual void init(); + /** Called for every run. */ - virtual void processRunHeader( LCRunHeader* run ) ; - + virtual void processRunHeader(LCRunHeader* run); + /** Called for every event - the working horse. */ - virtual void processEvent( LCEvent * evt ) ; + virtual void processEvent(LCEvent* evt); + + virtual void modifyEvent(LCEvent* evt); - virtual void modifyEvent( LCEvent * evt ) ; + virtual void check(LCEvent* evt); - - virtual void check( LCEvent * evt ) ; - - /** Called after data processing for clean up. */ - virtual void end() ; - - - virtual const std::string & name() const { return Processor::name() ; } + virtual void end(); + virtual const std::string& name() const { return Processor::name(); } - protected: +protected: + std::string _trkColName{}; - std::string _trkColName {}; + StringVec _hitColNames{}; + IntVec _subDetIDs{}; - StringVec _hitColNames {}; - IntVec _subDetIDs {}; - - int _nRun {}; - int _nEvt {}; - -} ; + int _nRun{}; + int _nEvt{}; +}; #endif - - - diff --git a/include/NNClusterer.h b/include/NNClusterer.h index 4a21370..398bf95 100644 --- a/include/NNClusterer.h +++ b/include/NNClusterer.h @@ -13,424 +13,408 @@ * @version $Id$ */ namespace nnclu { - - /** fast check if integer is in a given range [Min,Max] */ - template - inline bool inRange( int i){ return ( (unsigned int) ( i - Min ) <= (unsigned int) ( Max - Min ) ); } - - /** fast check if integer is not in a given range [Min,Max] */ - template - inline bool notInRange( int i){ return ( (unsigned int) ( i - Min ) > (unsigned int) ( Max - Min ) ); } - - - // forward declaration: - template - class Cluster ; - - - /** Wrapper class for elements that are clustered, holding a pointer to the actual - * object "->first" and a pointer to the cluster this obejct belongs to "->second". - * - * @see Cluster - * @author F.Gaede (DESY) - * @version $Id$ - */ - template - class Element : public std::pair< T*, Cluster* >{ - - typedef T value_type ; - typedef Cluster cluster_type ; - - public: - - /** Default c'tor takes a pointer to the original element type object. The optional index can be used to - * code nearest neighbour bins, e.g. in z-coordinate to speed up the clustering process. - */ - Element(T* element, int index0 = 0 ) : Index0( index0 ) { - Pair::first = element ; - Pair::second = 0 ; - } - - /** C'tor that also takes a pointer to the cluster this element belongs to - in case seed elements/clusters are used. - */ - Element(T* element , Cluster* cl , int index0 = 0) : Index0( index0 ) { - Pair::first = element ; - Pair::second = cl ; - } - - /** Index that can be used to code nearest neighbour bins, e.g. in z-coordinate - * to speed up the clustering process. - */ - int Index0 ; - - protected: - typedef std::pair< T*, Cluster* > Pair ; - /** Don't allow default c'tor w/o element */ - Element() ; - } ; +/** fast check if integer is in a given range [Min,Max] */ +template +inline bool inRange(int i) { + return ((unsigned int)(i - Min) <= (unsigned int)(Max - Min)); +} +/** fast check if integer is not in a given range [Min,Max] */ +template +inline bool notInRange(int i) { + return ((unsigned int)(i - Min) > (unsigned int)(Max - Min)); +} - /** Helper class that creates an Elements for an objects of type T. - */ - template - struct MakeElement{ - Element operator()( T* t) { return new Element( t ) ; } - } ; +// forward declaration: +template +class Cluster; + +/** Wrapper class for elements that are clustered, holding a pointer to the actual + * object "->first" and a pointer to the cluster this obejct belongs to "->second". + * + * @see Cluster + * @author F.Gaede (DESY) + * @version $Id$ + */ +template +class Element : public std::pair*> { + typedef T value_type; + typedef Cluster cluster_type; - /** Extension of std::vector that allows to take ownership of objects pointed to and - * delete these when going out of scope. +public: + /** Default c'tor takes a pointer to the original element type object. The optional index can be used to + * code nearest neighbour bins, e.g. in z-coordinate to speed up the clustering process. */ - template - class PtrVector : public std::vector { - typedef std::vector vec ; - bool _isOwner ; - public: - PtrVector() : _isOwner( false ) {} - ~PtrVector() { - if( _isOwner ) - for( typename vec::iterator i = vec::begin(),end = vec::end(); i != end ; delete *i++ ) ; //++i ) delete *i ; - } - void setOwner( bool val=true ) { _isOwner = val ; } - }; - + Element(T* element, int index0 = 0) : Index0(index0) { + Pair::first = element; + Pair::second = 0; + } - /** Extension of std::list that allows to take ownership of objects pointed to and - * delete these when going out of scope. + /** C'tor that also takes a pointer to the cluster this element belongs to - in case seed elements/clusters are used. */ - template - class PtrList : private std::list { - - bool _isOwner ; - - public: - typedef std::list base ; - typedef typename base::value_type value_type; - typedef typename base::const_iterator const_iterator; - typedef typename base::iterator iterator; - typedef typename base::reverse_iterator reverse_iterator; - typedef typename base::const_reverse_iterator const_reverse_iterator; - typedef typename base::const_reference const_reference; - - PtrList() : _isOwner( false ) {} - ~PtrList() { - if( _isOwner ) - for( typename base::iterator i = base::begin(),end = base::end(); i != end ; delete *i++ ) ; //++i ) delete *i ; - } - void setOwner( bool val=true ) { _isOwner = val ; } - - // make (part of) list interface public - typename base::size_type size() const { return base::size() ; } - const_iterator begin() const { return base::begin() ; } - const_iterator end() const { return base::end() ; } - iterator begin() { return base::begin() ; } - iterator end() { return base::end() ; } - reverse_iterator rbegin() { return base::rbegin() ; } - reverse_iterator rend() { return base::rend() ; } - const_reverse_iterator rbegin() const { return base::rbegin() ; } - const_reverse_iterator rend() const { return base::rend() ; } - template< class Compare > - void sort( Compare comp ) { base::sort( comp ) ; } - const_reference front() const { return base::front() ; } - const_reference back() const { return base::back() ; } - void clear() { base::clear() ; } - bool empty() const { return base::empty() ; }; - iterator erase( iterator pos ) { return base::erase( pos ) ; } - iterator erase( const_iterator pos ) { return base::erase( pos ) ; } - void merge( PtrList& other ) { base::merge( other ) ; } - - void push_back(T* t) { base::push_back(t) ; } - }; - - - - /** Templated class for generic clusters of Elements that are clustered with - * an NN-like clustering algorithm. Effectively this is just a list of elements. - * - * @see Element - * @author F.Gaede (DESY) - * @version $Id$ + Element(T* element, Cluster* cl, int index0 = 0) : Index0(index0) { + Pair::first = element; + Pair::second = cl; + } + + /** Index that can be used to code nearest neighbour bins, e.g. in z-coordinate + * to speed up the clustering process. */ - template - class Cluster : private std::list< Element * >, public lcrtrel::LCRTRelations { - - public : - typedef Element element_type ; - typedef std::list< Element * > base ; - typedef typename base::value_type value_type; - typedef typename base::iterator iterator; - typedef typename base::const_iterator const_iterator; - typedef typename base::reverse_iterator reverse_iterator; - typedef typename base::const_reverse_iterator const_reverse_iterator; - typedef typename base::const_reference const_reference; - - int ID{} ; //DEBUG - - Cluster() : ID(0) {} - - typename base::size_type size() const { return base::size() ; } - const_iterator begin() const { return base::begin() ; } - const_iterator end() const { return base::end() ; } - iterator begin() { return base::begin() ; } - iterator end() { return base::end() ; } - reverse_iterator rbegin() { return base::rbegin() ; } - reverse_iterator rend() { return base::rend() ; } - const_reverse_iterator rbegin() const { return base::rbegin() ; } - const_reverse_iterator rend() const { return base::rend() ; } - template< class Compare > - void sort( Compare comp ) { base::sort( comp ) ; } - const_reference front() const { return base::front() ; } - const_reference back() const { return base::back() ; } - void clear() { base::clear() ; } - bool empty() const { return base::empty() ; }; - iterator erase( iterator pos ) { return base::erase( pos ) ; } - iterator erase( const_iterator pos ) { return base::erase( pos ) ; } - void merge( Cluster& other ) { base::merge( other ) ; } - - /** C'tor that takes the first element */ - Cluster( Element* element) { - static int SID=0 ; //DEBUG - ID = SID++ ; //DEBUG - addElement( element ) ; - } - - /** Add a element to this cluster - updates the element's pointer to cluster */ - void addElement( Element* element ) { - - element->second = this ; - base::push_back( element ) ; - } + int Index0; - // /** Remove all elements from the cluster and reset the cluster association, i.e. elements can be - // * used for another clustering procedure. - // */ - // template - // void takeElements(Out result){ - // typename Cluster::iterator it = this->begin() ; - // while( it != this->end() ){ - // (*it)->second = 0 ; - // result++ = *it ; - // it = this->erase(it) ; - // } - // } - - - /** Free all elements, ie. reset their cluster association - the elements are still in the list !. - */ - void freeElements(){ - - for( typename Cluster::iterator it = this->begin(), end = this->end() ; it != end ; it++ ){ - (*it)->second = 0 ; - } - } - - /** Merges all elements from the other cluster cl into this cluster */ - void mergeClusters( Cluster* cl ) { - - for( typename Cluster::iterator it = cl->begin(), end = cl->end() ; it != end ; it++ ){ - (*it)->second = this ; - } - this->merge( *cl ) ; +protected: + typedef std::pair*> Pair; + + /** Don't allow default c'tor w/o element */ + Element(); +}; + +/** Helper class that creates an Elements for an objects of type T. + */ +template +struct MakeElement { + Element operator()(T* t) { return new Element(t); } +}; + +/** Extension of std::vector that allows to take ownership of objects pointed to and + * delete these when going out of scope. + */ +template +class PtrVector : public std::vector { + typedef std::vector vec; + bool _isOwner; + +public: + PtrVector() : _isOwner(false) {} + ~PtrVector() { + if (_isOwner) + for (typename vec::iterator i = vec::begin(), end = vec::end(); i != end; delete *i++) + ; //++i ) delete *i ; + } + void setOwner(bool val = true) { _isOwner = val; } +}; + +/** Extension of std::list that allows to take ownership of objects pointed to and + * delete these when going out of scope. + */ +template +class PtrList : private std::list { + + bool _isOwner; + +public: + typedef std::list base; + typedef typename base::value_type value_type; + typedef typename base::const_iterator const_iterator; + typedef typename base::iterator iterator; + typedef typename base::reverse_iterator reverse_iterator; + typedef typename base::const_reverse_iterator const_reverse_iterator; + typedef typename base::const_reference const_reference; + + PtrList() : _isOwner(false) {} + ~PtrList() { + if (_isOwner) + for (typename base::iterator i = base::begin(), end = base::end(); i != end; delete *i++) + ; //++i ) delete *i ; + } + void setOwner(bool val = true) { _isOwner = val; } + + // make (part of) list interface public + typename base::size_type size() const { return base::size(); } + const_iterator begin() const { return base::begin(); } + const_iterator end() const { return base::end(); } + iterator begin() { return base::begin(); } + iterator end() { return base::end(); } + reverse_iterator rbegin() { return base::rbegin(); } + reverse_iterator rend() { return base::rend(); } + const_reverse_iterator rbegin() const { return base::rbegin(); } + const_reverse_iterator rend() const { return base::rend(); } + template + void sort(Compare comp) { + base::sort(comp); + } + const_reference front() const { return base::front(); } + const_reference back() const { return base::back(); } + void clear() { base::clear(); } + bool empty() const { return base::empty(); }; + iterator erase(iterator pos) { return base::erase(pos); } + iterator erase(const_iterator pos) { return base::erase(pos); } + void merge(PtrList& other) { base::merge(other); } + + void push_back(T* t) { base::push_back(t); } +}; + +/** Templated class for generic clusters of Elements that are clustered with + * an NN-like clustering algorithm. Effectively this is just a list of elements. + * + * @see Element + * @author F.Gaede (DESY) + * @version $Id$ + */ +template +class Cluster : private std::list*>, public lcrtrel::LCRTRelations { + +public: + typedef Element element_type; + typedef std::list*> base; + typedef typename base::value_type value_type; + typedef typename base::iterator iterator; + typedef typename base::const_iterator const_iterator; + typedef typename base::reverse_iterator reverse_iterator; + typedef typename base::const_reverse_iterator const_reverse_iterator; + typedef typename base::const_reference const_reference; + + int ID{}; // DEBUG + + Cluster() : ID(0) {} + + typename base::size_type size() const { return base::size(); } + const_iterator begin() const { return base::begin(); } + const_iterator end() const { return base::end(); } + iterator begin() { return base::begin(); } + iterator end() { return base::end(); } + reverse_iterator rbegin() { return base::rbegin(); } + reverse_iterator rend() { return base::rend(); } + const_reverse_iterator rbegin() const { return base::rbegin(); } + const_reverse_iterator rend() const { return base::rend(); } + template + void sort(Compare comp) { + base::sort(comp); + } + const_reference front() const { return base::front(); } + const_reference back() const { return base::back(); } + void clear() { base::clear(); } + bool empty() const { return base::empty(); }; + iterator erase(iterator pos) { return base::erase(pos); } + iterator erase(const_iterator pos) { return base::erase(pos); } + void merge(Cluster& other) { base::merge(other); } + + /** C'tor that takes the first element */ + Cluster(Element* element) { + static int SID = 0; // DEBUG + ID = SID++; // DEBUG + addElement(element); + } + + /** Add a element to this cluster - updates the element's pointer to cluster */ + void addElement(Element* element) { + + element->second = this; + base::push_back(element); + } + + // /** Remove all elements from the cluster and reset the cluster association, i.e. elements can be + // * used for another clustering procedure. + // */ + // template + // void takeElements(Out result){ + // typename Cluster::iterator it = this->begin() ; + // while( it != this->end() ){ + // (*it)->second = 0 ; + // result++ = *it ; + // it = this->erase(it) ; + // } + // } + + /** Free all elements, ie. reset their cluster association - the elements are still in the list !. + */ + void freeElements() { + + for (typename Cluster::iterator it = this->begin(), end = this->end(); it != end; it++) { + (*it)->second = 0; } - - /** D'tor frees all remaining elements that still belong to this cluster */ - ~Cluster() { - - // typename Cluster::iterator it = this->begin() ; - // while( it != this->end() ) - - for( typename Cluster::iterator it = this->begin() , end = this->end() ; it != end ; ++it ){ - - typename Cluster::value_type h = *it ; - - if( h != 0 && h->second == this ) - h->second = 0 ; - - } + } + + /** Merges all elements from the other cluster cl into this cluster */ + void mergeClusters(Cluster* cl) { + + for (typename Cluster::iterator it = cl->begin(), end = cl->end(); it != end; it++) { + (*it)->second = this; } - } ; + this->merge(*cl); + } + + /** D'tor frees all remaining elements that still belong to this cluster */ + ~Cluster() { + + // typename Cluster::iterator it = this->begin() ; + // while( it != this->end() ) + + for (typename Cluster::iterator it = this->begin(), end = this->end(); it != end; ++it) { + typename Cluster::value_type h = *it; - template - /** Main class for a nearest neighbour type clustering. - * - * @author F.Gaede (DESY) - * @version $Id$ + if (h != 0 && h->second == this) + h->second = 0; + } + } +}; + +template +/** Main class for a nearest neighbour type clustering. + * + * @author F.Gaede (DESY) + * @version $Id$ + */ +class NNClusterer { + +public: + typedef T value_type; + typedef Cluster cluster_type; + typedef Element element_type; + typedef PtrVector element_vector; + typedef PtrVector cluster_vector; + typedef PtrList element_list; + typedef PtrList cluster_list; + + /** Simple nearest neighbour (NN) clustering algorithm. Users have to provide an input iterator of + * Element objects and an output iterator for the clusters found. The predicate has to have + * a method with the following signature: bool operator()( const Element*, const Element*). + * All pairs of elements for which this method returns 'true' will be merged into one output cluster + * - all other pairs of elements will be in different clusters. */ - class NNClusterer{ - - public: - typedef T value_type ; - typedef Cluster cluster_type ; - typedef Element element_type ; - typedef PtrVector< element_type > element_vector ; - typedef PtrVector< cluster_type > cluster_vector ; - typedef PtrList< element_type > element_list ; - typedef PtrList< cluster_type > cluster_list ; - - /** Simple nearest neighbour (NN) clustering algorithm. Users have to provide an input iterator of - * Element objects and an output iterator for the clusters found. The predicate has to have - * a method with the following signature: bool operator()( const Element*, const Element*). - * All pairs of elements for which this method returns 'true' will be merged into one output cluster - * - all other pairs of elements will be in different clusters. - */ - - template - void cluster( In first, In last, Out result, Pred& pred , const unsigned minSize=1) { - - cluster_vector tmp ; - tmp.reserve( 1024 ) ; - - while( first != last ) { - - for( In other = first+1 ; other != last ; other ++ ) { - - if( pred( (*first) , (*other) ) ) { - - if( (*first)->second == 0 && (*other)->second == 0 ) { // no cluster exists - - cluster_type* cl = new cluster_type( (*first) ) ; - - cl->addElement( (*other) ) ; - - tmp.push_back( cl ) ; - - } - else if( (*first)->second != 0 && (*other)->second != 0 ) { // two clusters - - if( (*first)->second != (*other)->second ) // don't call merge on identical clusters - (*first)->second->mergeClusters( (*other)->second ) ; - - } else { // one cluster exists - - if( (*first)->second != 0 ) { - - (*first)->second->addElement( (*other) ) ; - - } else { - - (*other)->second->addElement( (*first) ) ; - } + + template + void cluster(In first, In last, Out result, Pred& pred, const unsigned minSize = 1) { + + cluster_vector tmp; + tmp.reserve(1024); + + while (first != last) { + + for (In other = first + 1; other != last; other++) { + + if (pred((*first), (*other))) { + + if ((*first)->second == 0 && (*other)->second == 0) { // no cluster exists + + cluster_type* cl = new cluster_type((*first)); + + cl->addElement((*other)); + + tmp.push_back(cl); + + } else if ((*first)->second != 0 && (*other)->second != 0) { // two clusters + + if ((*first)->second != (*other)->second) // don't call merge on identical clusters + (*first)->second->mergeClusters((*other)->second); + + } else { // one cluster exists + + if ((*first)->second != 0) { + + (*first)->second->addElement((*other)); + + } else { + + (*other)->second->addElement((*first)); } - } } - ++first ; } - - // remove empty clusters - for( typename cluster_vector::iterator i = tmp.begin(); i != tmp.end() ; i++ ){ - - if( (*i)->size() > minSize-1 ) { - - result++ = *i ; - } - else { - - delete *i ; - } + ++first; + } + + // remove empty clusters + for (typename cluster_vector::iterator i = tmp.begin(); i != tmp.end(); i++) { + + if ((*i)->size() > minSize - 1) { + + result++ = *i; + } else { + + delete *i; } } + } + /** Same as above - but requires the elements to be sorted in index0 (only compare neighbouring bins in index0). */ - /** Same as above - but requires the elements to be sorted in index0 (only compare neighbouring bins in index0). */ - - template - void cluster_sorted( In first, In last, Out result, Pred& pred , const unsigned minSize=1) { - - - cluster_vector tmp ; - tmp.reserve( 1024 ) ; - - while( first != last ) { - - for( In other = first+1 ; other != last ; other ++ ) { - - // if the elements are sorted we can skip the rest of the inner loop - if( notInRange<-1,1>( (*first)->Index0 - (*other)->Index0 ) ) - break ; - - if( pred( (*first) , (*other) ) ) { - - if( (*first)->second == 0 && (*other)->second == 0 ) { // no cluster exists - - cluster_type* cl = new cluster_type( (*first) ) ; - - cl->addElement( (*other) ) ; - - tmp.push_back( cl ) ; - - } - else if( (*first)->second != 0 && (*other)->second != 0 ) { // two clusters - - if( (*first)->second != (*other)->second ) // don't call merge on identical clusters - (*first)->second->mergeClusters( (*other)->second ) ; - - } else { // one cluster exists - - if( (*first)->second != 0 ) { - - (*first)->second->addElement( (*other) ) ; - - } else { - - (*other)->second->addElement( (*first) ) ; - } + template + void cluster_sorted(In first, In last, Out result, Pred& pred, const unsigned minSize = 1) { + + cluster_vector tmp; + tmp.reserve(1024); + + while (first != last) { + + for (In other = first + 1; other != last; other++) { + + // if the elements are sorted we can skip the rest of the inner loop + if (notInRange<-1, 1>((*first)->Index0 - (*other)->Index0)) + break; + + if (pred((*first), (*other))) { + + if ((*first)->second == 0 && (*other)->second == 0) { // no cluster exists + + cluster_type* cl = new cluster_type((*first)); + + cl->addElement((*other)); + + tmp.push_back(cl); + + } else if ((*first)->second != 0 && (*other)->second != 0) { // two clusters + + if ((*first)->second != (*other)->second) // don't call merge on identical clusters + (*first)->second->mergeClusters((*other)->second); + + } else { // one cluster exists + + if ((*first)->second != 0) { + + (*first)->second->addElement((*other)); + + } else { + + (*other)->second->addElement((*first)); } - } } - ++first ; - } - - // remove empty clusters - for( typename cluster_vector::iterator i = tmp.begin(); i != tmp.end() ; i++ ){ - - if( (*i)->size() > minSize-1 ) { - - result++ = *i ; - } - else { - - delete *i ; - } } + ++first; } - }; - //----------------------------------------------------------------------------------------------------------------------- + // remove empty clusters + for (typename cluster_vector::iterator i = tmp.begin(); i != tmp.end(); i++) { + if ((*i)->size() > minSize - 1) { + result++ = *i; + } else { - /**Splits a list into two based on a predicate. The new list will - * hold all elements for which Pred is true which are in turn removed - * from the original list. - */ - template - void split_list( List& list, Out result, Pred pred) { - - typename List::iterator it = list.begin() ; - - while( it != list.end() ){ - - if( pred( *it ) ){ - - result++ = *it ; - it = list.erase( it ) ; - - } else - ++it ; + delete *i; + } } } - - +}; +//----------------------------------------------------------------------------------------------------------------------- +/**Splits a list into two based on a predicate. The new list will + * hold all elements for which Pred is true which are in turn removed + * from the original list. + */ +template +void split_list(List& list, Out result, Pred pred) { - //----------------------------------------------------------------------------------------------------------------------- + typename List::iterator it = list.begin(); -} // namespace nnclu - -#endif + while (it != list.end()) { + + if (pred(*it)) { + result++ = *it; + it = list.erase(it); + } else + ++it; + } +} + +//----------------------------------------------------------------------------------------------------------------------- + +} // namespace nnclu + +#endif diff --git a/include/TrackCheckMCTruth.h b/include/TrackCheckMCTruth.h index 8a106b5..1b2ce5d 100644 --- a/include/TrackCheckMCTruth.h +++ b/include/TrackCheckMCTruth.h @@ -1,80 +1,69 @@ #ifndef TrackCheckMCTruth_h #define TrackCheckMCTruth_h 1 -#include "marlin/Processor.h" #include "lcio.h" -#include +#include "marlin/Processor.h" #include +#include +using namespace lcio; +using namespace marlin; -using namespace lcio ; -using namespace marlin ; - -class TH1 ; +class TH1; /** Check a track collection based on MCTruth for merged and split tracks. */ class TrackCheckMCTruth : public Processor { - - public: - - virtual Processor* newProcessor() { return new TrackCheckMCTruth ; } - - - TrackCheckMCTruth() ; - + +public: + virtual Processor* newProcessor() { return new TrackCheckMCTruth; } + + TrackCheckMCTruth(); + /** Called at the begin of the job before anything is read. * Use to initialize the processor, e.g. book histograms. */ - virtual void init() ; - + virtual void init(); + /** Called for every run. */ - virtual void processRunHeader( LCRunHeader* run ) ; - + virtual void processRunHeader(LCRunHeader* run); + /** Called for every event - the working horse. */ - virtual void processEvent( LCEvent * evt ) ; + virtual void processEvent(LCEvent* evt); + + virtual void check(LCEvent* evt); - - virtual void check( LCEvent * evt ) ; - - /** Called after data processing for clean up. */ - virtual void end() ; - - - protected: + virtual void end(); +protected: /** Input collection names. */ - std::string _mcpColName {}; + std::string _mcpColName{}; - StringVec _sthColNames {}; + StringVec _sthColNames{}; - std::string _relTrkMCPColName {}; - std::string _relMCPTrkColName {}; - - std::string _trkColName {}; - - std::string _mergedColName {}; - std::string _splitColName {}; + std::string _relTrkMCPColName{}; + std::string _relMCPTrkColName{}; - float _hitFractionSplit {}; - float _hitFractionMerged {}; + std::string _trkColName{}; - FloatVec _ptRange {}; + std::string _mergedColName{}; + std::string _splitColName{}; - std::vector< TH1* > _h1 {}; - - int _nRun {}; - int _nEvt {}; + float _hitFractionSplit{}; + float _hitFractionMerged{}; -} ; - -#endif + FloatVec _ptRange{}; + std::vector _h1{}; + int _nRun{}; + int _nEvt{}; +}; +#endif diff --git a/include/TrackEfficiency.h b/include/TrackEfficiency.h index 0a2fc97..2059313 100644 --- a/include/TrackEfficiency.h +++ b/include/TrackEfficiency.h @@ -1,82 +1,71 @@ #ifndef TrackEfficiency_h #define TrackEfficiency_h 1 -#include "marlin/Processor.h" #include "lcio.h" -#include +#include "marlin/Processor.h" #include +#include +using namespace lcio; +using namespace marlin; -using namespace lcio ; -using namespace marlin ; - -class TH1 ; +class TH1; /** Analysis plots for tracking efficiency. - * + * * @author F.Gaede, DESY - * @version $Id$ + * @version $Id$ */ class TrackEfficiency : public Processor { - - public: - - virtual Processor* newProcessor() { return new TrackEfficiency ; } - - - TrackEfficiency() ; - + +public: + virtual Processor* newProcessor() { return new TrackEfficiency; } + + TrackEfficiency(); + /** Called at the begin of the job before anything is read. * Use to initialize the processor, e.g. book histograms. */ - virtual void init() ; - + virtual void init(); + /** Called for every run. */ - virtual void processRunHeader( LCRunHeader* run ) ; - + virtual void processRunHeader(LCRunHeader* run); + /** Called for every event - the working horse. */ - virtual void processEvent( LCEvent * evt ) ; + virtual void processEvent(LCEvent* evt); + + virtual void check(LCEvent* evt); - - virtual void check( LCEvent * evt ) ; - - /** Called after data processing for clean up. */ - virtual void end() ; - - - protected: + virtual void end(); +protected: /** Input collection names. */ - std::string _mcpColName {}; - std::string _sthColName {}; - std::string _t2mColName {}; - std::string _m2tColName {}; - std::string _trkColName {}; - - std::vector< TH1* > _h1 {}; - - FloatVec _ptRange {}; - - int _nRun {}; - int _nEvt {}; - - bool _physSampleOn {}; - double _pCut {}; - double _ptCut {}; - double _originCut {}; - double _cosTheta {}; - double _minPurity {}; - int _minHits {}; - -} ; + std::string _mcpColName{}; + std::string _sthColName{}; + std::string _t2mColName{}; + std::string _m2tColName{}; + std::string _trkColName{}; -#endif + std::vector _h1{}; + + FloatVec _ptRange{}; + int _nRun{}; + int _nEvt{}; + bool _physSampleOn{}; + double _pCut{}; + double _ptCut{}; + double _originCut{}; + double _cosTheta{}; + double _minPurity{}; + int _minHits{}; +}; +#endif diff --git a/include/clupatra_new.h b/include/clupatra_new.h index 2a7173c..9c0c84c 100644 --- a/include/clupatra_new.h +++ b/include/clupatra_new.h @@ -1,742 +1,694 @@ #ifndef clupatra_new_h #define clupatra_new_h -#include +#include "assert.h" #include -#include +#include #include -#include #include -#include "assert.h" +#include +#include #include "NNClusterer.h" // --- DD4hep --- +#include "DD4hep/DD4hepUnits.h" #include "DD4hep/Detector.h" #include "DDRec/Vector3D.h" -#include "DD4hep/DD4hepUnits.h" -#include "lcio.h" #include "EVENT/TrackerHit.h" #include "IMPL/TrackImpl.h" -#include "UTIL/Operators.h" #include "UTIL/CellIDDecoder.h" #include "UTIL/LCTrackerConf.h" +#include "UTIL/Operators.h" +#include "lcio.h" #include - #include "MarlinTrk/IMarlinTrack.h" #include "MarlinTrk/IMarlinTrkSystem.h" // ----- include for verbosity dependend logging --------- #include "marlin/VerbosityLevels.h" - /** Helper structs that should go to LCIo to make extraction of layer (and subdetector etc easier ) */ -namespace lcio{ - struct ILDDecoder : public CellIDDecoder{ - ILDDecoder() : lcio::CellIDDecoder( LCTrackerCellID::encoding_string() ) {} - } ; - - static const BitField64& ILD_cellID( TrackerHit* th ){ - static ILDDecoder encoder; - return encoder( th ); - } +namespace lcio { +struct ILDDecoder : public CellIDDecoder { + ILDDecoder() : lcio::CellIDDecoder(LCTrackerCellID::encoding_string()) {} +}; + +static const BitField64& ILD_cellID(TrackerHit* th) { + static ILDDecoder encoder; + return encoder(th); +} + +struct ILDTrackTypeBit { + static const int SEGMENT; + static const int COMPOSITE; +}; +} // namespace lcio + +namespace clupatra_new { + +/** Small wrapper extension of the LCIO Hit + */ +struct ClupaHit { + + ClupaHit() : layer(-1), zIndex(-1), phiIndex(-1), lcioHit(0), pos(0., 0., 0.) {} + int layer; + int zIndex; + int phiIndex; + lcio::TrackerHit* lcioHit; + dd4hep::rec::Vector3D pos; +}; + +// inline lcio::TrackerHit* lcioHit( const ClupaHit* h) { return h->lcioHit ; } - struct ILDTrackTypeBit{ - static const int SEGMENT ; - static const int COMPOSITE ; - } ; -} - -namespace clupatra_new{ - - /** Small wrapper extension of the LCIO Hit - */ - struct ClupaHit { - - ClupaHit() :layer(-1), - zIndex(-1), - phiIndex(-1), - lcioHit(0), - pos(0.,0.,0.) {} - int layer ; - int zIndex ; - int phiIndex ; - lcio::TrackerHit* lcioHit ; - dd4hep::rec::Vector3D pos ; - - }; - - // inline lcio::TrackerHit* lcioHit( const ClupaHit* h) { return h->lcioHit ; } - - //------------------ typedefs for elements and clusters --------- - typedef nnclu::NNClusterer< ClupaHit > Clusterer ; - - typedef Clusterer::element_type Hit ; - typedef Clusterer::cluster_type CluTrack ; - - typedef Clusterer::element_vector HitVec ; - typedef Clusterer::cluster_vector CluTrackVec ; - - typedef std::list HitList ; - typedef std::vector< HitList > HitListVector ; - - - // typedef GenericHitVec GHitVec ; - // typedef GenericClusterVec GClusterVec ; - - //------------------------------------------------------------------------------------------ - - struct GHit : lcrtrel::LCExtension {} ; - - //------------------------------------------------------------------------------------------ - - struct MarTrk : lcrtrel::LCExtension {} ; - - //------------------------------------------------------------------------------------------ - - struct DChi2 : lcrtrel::LCFloatExtension {} ; - - //---------------------------------------------------------------- - - /** Simple predicate class for computing an index from N bins of the z-coordinate of LCObjects - * that have a float/double* getPostion() method. - */ - class ZIndex{ - public: - /** C'tor takes zmin and zmax - NB index can be negative and larger than N */ - ZIndex( float zmin , float zmax , int n ) : _zmin( zmin ), _zmax( zmax ) , _N (n) {} - - template - inline int operator() (T* hit) { - - return (int) std::floor( ( hit->getPosition()[2] - _zmin ) / ( _zmax - _zmin ) * _N ) ; - } - - inline int index( double z) { return (int) std::floor( ( z - _zmin ) / ( _zmax - _zmin ) * _N ) ; } - - protected: - ZIndex() {} ; - float _zmin{} ; - float _zmax{} ; - int _N{} ; - } ; - - //------------------------------------------------------------------------------------------ - - struct ZSort { - inline bool operator()( const Hit* l, const Hit* r) { - return ( l->first->pos.z() < r->first->pos.z() ); - } - }; - +typedef nnclu::NNClusterer Clusterer; - //------------------------------------------------------------------------------------------ +typedef Clusterer::element_type Hit; +typedef Clusterer::cluster_type CluTrack; - struct PtSort { // sort tracks wtr to pt - largest first - inline bool operator()( const lcio::LCObject* l, const lcio::LCObject* r) { - return ( std::abs( ( (const lcio::Track*) l )->getOmega() ) < std::abs( ( (const lcio::Track*) r )->getOmega() ) ); // pt ~ 1./omega - } - }; +typedef Clusterer::element_vector HitVec; +typedef Clusterer::cluster_vector CluTrackVec; - //------------------------------------------------------------------------------------------ +typedef std::list HitList; +typedef std::vector HitListVector; +// typedef GenericHitVec GHitVec ; +// typedef GenericClusterVec GClusterVec ; - /** Add the elements (Hits) from (First,Last) to the HitListVector - vector needs to be initialized, e.g. with - * hLV.resize( MAX_LAYER_INDEX ) - */ - template - void addToHitListVector( First first, Last last, HitListVector& hLV ){ - - while( first != last ){ +//------------------------------------------------------------------------------------------ - streamlog_out( DEBUG ) << " add hit << " << *first << " to layer " << (*first)->first->layer << std::endl ; +struct GHit : lcrtrel::LCExtension {}; - hLV[ (*first)->first->layer ].push_back( *first ) ; - ++first ; - } +//------------------------------------------------------------------------------------------ + +struct MarTrk : lcrtrel::LCExtension {}; + +//------------------------------------------------------------------------------------------ + +struct DChi2 : lcrtrel::LCFloatExtension {}; + +//---------------------------------------------------------------- + +/** Simple predicate class for computing an index from N bins of the z-coordinate of LCObjects + * that have a float/double* getPostion() method. + */ +class ZIndex { +public: + /** C'tor takes zmin and zmax - NB index can be negative and larger than N */ + ZIndex(float zmin, float zmax, int n) : _zmin(zmin), _zmax(zmax), _N(n) {} + + template + inline int operator()(T* hit) { + + return (int)std::floor((hit->getPosition()[2] - _zmin) / (_zmax - _zmin) * _N); } - //------------------------------------------------------------------------------------------ + inline int index(double z) { return (int)std::floor((z - _zmin) / (_zmax - _zmin) * _N); } + +protected: + ZIndex() {}; + float _zmin{}; + float _zmax{}; + int _N{}; +}; - /** Predicate class for 'distance' of NN clustering. */ - class HitDistance{ - public: +//------------------------------------------------------------------------------------------ - HitDistance(float dCut, float caCut = -1.0 ) : _dCutSquared( dCut*dCut ) , _caCut( caCut ) {} +struct ZSort { + inline bool operator()(const Hit* l, const Hit* r) { return (l->first->pos.z() < r->first->pos.z()); } +}; - /** Merge condition: true if distance is less than dCut */ - inline bool operator()( Hit* h0, Hit* h1){ - - if( std::abs( h0->Index0 - h1->Index0 ) > 1 ) return false ; - - if( h0->first->layer == h1->first->layer ) - return false ; +//------------------------------------------------------------------------------------------ - if( _caCut > 0. && std::abs( h0->first->layer - h1->first->layer ) == 1 ){ +struct PtSort { // sort tracks wtr to pt - largest first + inline bool operator()(const lcio::LCObject* l, const lcio::LCObject* r) { + return (std::abs(((const lcio::Track*)l)->getOmega()) < + std::abs(((const lcio::Track*)r)->getOmega())); // pt ~ 1./omega + } +}; - dd4hep::rec::Vector3D& p0 = h0->first->pos ; - dd4hep::rec::Vector3D& p1 = h1->first->pos ; - - double cosAlpha = p0.dot( p1 ) / p0.r() / p1.r() ; +//------------------------------------------------------------------------------------------ - // merge hits that seem to come from stiff track from the IP - //fixme: make parameter - if( cosAlpha > _caCut ) return true ; - } +/** Add the elements (Hits) from (First,Last) to the HitListVector - vector needs to be initialized, e.g. with + * hLV.resize( MAX_LAYER_INDEX ) + */ +template +void addToHitListVector(First first, Last last, HitListVector& hLV) { - return ( h0->first->pos - h1->first->pos).r2() < _dCutSquared ; - } - protected: - HitDistance() ; - float _dCutSquared, _caCut ; - } ; - - - // /** Predicate class for 'distance' of NN clustering. */ - - // struct HitDistance{ float _dCutSquared ; - // HitDistance(float dCut) : _dCutSquared( dCut*dCut ) {} - - // inline bool operator()( Hit* h0, Hit* h1){ - - // if( h0->first->layer == h1->first->layer ) - // return false ; - - // return ( h0->first->pos - h1->first->pos).r2() - // < _dCutSquared ; - // } - // } ; - - - - //----------------------------------------------- - - struct LCIOTrackConverter{ - - bool UsePropagate ; - unsigned CaloFaceBarrelID ; - unsigned CaloFaceEndcapID ; - - LCIOTrackConverter() : UsePropagate(false ) , - CaloFaceBarrelID( lcio::ILDDetID::ECAL) , - CaloFaceEndcapID( lcio::ILDDetID::ECAL_ENDCAP){} - - lcio::Track* operator() (CluTrack* c) ; - - } ; - - //------------------------------------------------------------------------------------------ - /** Predicate class for identifying small clusters. */ - struct ClusterSize { - ClusterSize( unsigned n) : _n(n) {} - bool operator()(const CluTrack* cl) const { return cl->size() < _n ; } - unsigned _n ; - }; - - //------------------------------------------------------------------------------------------ - /** Predicate class for identifying clusters with duplicate pad rows - returns true - * if the fraction of duplicate hits is larger than 'fraction'. - */ - struct DuplicatePadRows{ - - unsigned _N ; - float _f ; - DuplicatePadRows(unsigned nPadRows, float fraction) : _N( nPadRows), _f( fraction ) {} - - bool operator()(const CluTrack* cl) const { - - // check for duplicate layer numbers - std::vector hLayer( _N ) ; - typedef CluTrack::const_iterator IT ; - - unsigned nHit = 0 ; - for(IT it=cl->begin() ; it != cl->end() ; ++it ) { - ++ hLayer[ (*it)->first->layer] ; - ++ nHit ; - } - unsigned nDuplicate = 0 ; - for(unsigned i=0 ; i < _N ; ++i ) { - if( hLayer[i] > 1 ) - nDuplicate += hLayer[i] ; - } - return double(nDuplicate)/nHit > _f ; + while (first != last) { + + streamlog_out(DEBUG) << " add hit << " << *first << " to layer " << (*first)->first->layer << std::endl; + + hLV[(*first)->first->layer].push_back(*first); + ++first; + } +} + +//------------------------------------------------------------------------------------------ + +/** Predicate class for 'distance' of NN clustering. */ +class HitDistance { +public: + HitDistance(float dCut, float caCut = -1.0) : _dCutSquared(dCut * dCut), _caCut(caCut) {} + + /** Merge condition: true if distance is less than dCut */ + inline bool operator()(Hit* h0, Hit* h1) { + + if (std::abs(h0->Index0 - h1->Index0) > 1) + return false; + + if (h0->first->layer == h1->first->layer) + return false; + + if (_caCut > 0. && std::abs(h0->first->layer - h1->first->layer) == 1) { + + dd4hep::rec::Vector3D& p0 = h0->first->pos; + dd4hep::rec::Vector3D& p1 = h1->first->pos; + + double cosAlpha = p0.dot(p1) / p0.r() / p1.r(); + + // merge hits that seem to come from stiff track from the IP + // fixme: make parameter + if (cosAlpha > _caCut) + return true; } - }; - - //------------------------------------------------------------------------------------------ - - // helper for sorting cluster wrt layerID - struct LayerSortOut{ - bool operator()( const Hit* l, const Hit* r) { return l->first->layer < r->first->layer ; } - } ; - struct LayerSortIn{ - bool operator()( const Hit* l, const Hit* r) { return l->first->layer > r->first->layer ; } - } ; - - - - - //------------------------------------------------------------------------------------------ - - struct IMarlinTrkFitter{ - - MarlinTrk::IMarlinTrkSystem* _ts ; - double _maxChi2Increment ; - - IMarlinTrkFitter(MarlinTrk::IMarlinTrkSystem* ts, double maxChi2Increment=DBL_MAX ) : - _ts( ts ) , - _maxChi2Increment(maxChi2Increment) {} - - - MarlinTrk::IMarlinTrack* operator() (CluTrack* clu) ; - }; - - //------------------------------------------------------------------------------------- - - /** Try to add hits from hLV (hit lists per layer) to the cluster. The cluster needs to have a fitted KalTrack associated to it. - * Hits are added if the resulting delta Chi2 is less than dChiMax - a maxStep is the maximum number of steps (layers) w/o - * successfully merging a hit. - */ - int addHitsAndFilter( CluTrack* clu, HitListVector& hLV , double dChiMax, double chi2Cut, unsigned maxStep, ZIndex& zIndex, bool backward=false, - MarlinTrk::IMarlinTrkSystem* trkSys=0) ; - //------------------------------------------------------------------------------------------ - - /** Try to add a hit from the given HitList in layer of subdetector to the track. - * A hit is added if the resulting delta Chi2 is less than dChiMax. - */ - bool addHitAndFilter( int detectorID, int layer, CluTrack* clu, HitListVector& hLV , double dChiMax, double chi2Cut) ; - - //------------------------------------------------------------------------------------------ - /** Split up clusters that have a hit multiplicity of 2,3,4,...,N in at least layersWithMultiplicity. - */ - void split_multiplicity( Clusterer::cluster_list& cluList, int layersWithMultiplicity , int N=5) ; - - //------------------------------------------------------------------------------------------ - /** Returns the number of rows where cluster clu has i hits in mult[i] for i=1,2,3,4,.... - - * mult[0] counts all rows that have hits - */ - void getHitMultiplicities( CluTrack* clu, std::vector& mult ) ; - - //------------------------------------------------------------------------------------------ - - /** Split the cluster into two clusters. - */ - void create_two_clusters( Clusterer::cluster_type& clu, Clusterer::cluster_list& cluVec ) ; - - //------------------------------------------------------------------------------------------ - - /** Split the cluster into three clusters. - */ - void create_three_clusters( Clusterer::cluster_type& clu, Clusterer::cluster_list& cluVec ) ; - - - /** Split the cluster into N clusters. - */ - void create_n_clusters( Clusterer::cluster_type& clu, Clusterer::cluster_list& cluVec , unsigned n ) ; - - - - //======================================================================================= - - struct TrackInfoStruct{ - TrackInfoStruct() : zMin(0.), zAvg(0.), zMax(0.), startsInner(false), isCentral(false), isForward(false), isCurler(false) {} - float zMin ; - float zAvg ; - float zMax ; - bool startsInner ; - bool isCentral ; - bool isForward ; - bool isCurler ; - } ; - struct TrackInfo : lcrtrel::LCOwnedExtension {} ; - - /** Helper class to compute track segment properties. - */ - struct ComputeTrackerInfo{ - - void operator()( lcio::LCObject* o ){ - - lcio::Track* lTrk = (lcio::Track*) o ; - - // compute z-extend of this track segment - const lcio::TrackerHitVec& hv = lTrk->getTrackerHits() ; - - float zMin = 1e99 ; - float zMax = -1e99 ; - float zAvg = 0. ; - - if( hv.size() > 1 ) { - zMin = hv[ 0 ]->getPosition()[2] ; - zMax = hv[ hv.size() -1 ]->getPosition()[2] ; - zAvg = ( zMax + zMin ) / 2. ; - } - - if( zMin > zMax ){ // swap - float d = zMax ; - zMax = zMin ; - zMin = d ; - } - - if( ! lTrk->ext() ) - lTrk->ext() = new TrackInfoStruct ; - - lTrk->ext()->zMin = zMin ; - lTrk->ext()->zMax = zMax ; - lTrk->ext()->zAvg = zAvg ; + return (h0->first->pos - h1->first->pos).r2() < _dCutSquared; + } + +protected: + HitDistance(); + float _dCutSquared, _caCut; +}; + +// /** Predicate class for 'distance' of NN clustering. */ + +// struct HitDistance{ float _dCutSquared ; +// HitDistance(float dCut) : _dCutSquared( dCut*dCut ) {} + +// inline bool operator()( Hit* h0, Hit* h1){ + +// if( h0->first->layer == h1->first->layer ) +// return false ; + +// return ( h0->first->pos - h1->first->pos).r2() +// < _dCutSquared ; +// } +// } ; + +//----------------------------------------------- + +struct LCIOTrackConverter { + + bool UsePropagate; + unsigned CaloFaceBarrelID; + unsigned CaloFaceEndcapID; + + LCIOTrackConverter() + : UsePropagate(false), CaloFaceBarrelID(lcio::ILDDetID::ECAL), CaloFaceEndcapID(lcio::ILDDetID::ECAL_ENDCAP) {} + + lcio::Track* operator()(CluTrack* c); +}; +//------------------------------------------------------------------------------------------ +/** Predicate class for identifying small clusters. */ +struct ClusterSize { + ClusterSize(unsigned n) : _n(n) {} + bool operator()(const CluTrack* cl) const { return cl->size() < _n; } + unsigned _n; +}; +//------------------------------------------------------------------------------------------ +/** Predicate class for identifying clusters with duplicate pad rows - returns true + * if the fraction of duplicate hits is larger than 'fraction'. + */ +struct DuplicatePadRows { + + unsigned _N; + float _f; + DuplicatePadRows(unsigned nPadRows, float fraction) : _N(nPadRows), _f(fraction) {} + + bool operator()(const CluTrack* cl) const { + + // check for duplicate layer numbers + std::vector hLayer(_N); + typedef CluTrack::const_iterator IT; + + unsigned nHit = 0; + for (IT it = cl->begin(); it != cl->end(); ++it) { + ++hLayer[(*it)->first->layer]; + ++nHit; } - } ; - //======================================================================================= - - /** helper class for merging split track segments */ - - class TrackSegmentMerger{ - - public: - /** C'tor takes merge distance */ - TrackSegmentMerger(float chi2Max, MarlinTrk::IMarlinTrkSystem* trksystem, float b) : _chi2Max( chi2Max ) , _trksystem( trksystem), _b(b) {} - - float _chi2Max ; - MarlinTrk::IMarlinTrkSystem* _trksystem ; - float _b ; - - /** Merge condition: ... */ - inline bool operator()( nnclu::Element* h0, nnclu::Element* h1){ - - lcio::Track* trk0 = h0->first ; - lcio::Track* trk1 = h1->first ; - - - // protect against merging multiple segments (and thus complete tracks) - if( h0->second || h1->second ) - return false ; - - // const TrackInfoStruct* ti0 = trk0->ext() ; - // const TrackInfoStruct* ti1 = trk1->ext() ; - - // const lcio::TrackState* tsF0 = trk0->getTrackState( lcio::TrackState::AtFirstHit ) ; - // const lcio::TrackState* tsL0 = trk0->getTrackState( lcio::TrackState::AtLastHit ) ; - - // const lcio::TrackState* tsF1 = trk1->getTrackState( lcio::TrackState::AtFirstHit ) ; - // const lcio::TrackState* tsL1 = trk1->getTrackState( lcio::TrackState::AtLastHit ) ; - - // --- get three hits per track : first last midddle - - unsigned nhit0 = trk0->getTrackerHits().size() ; - unsigned nhit1 = trk1->getTrackerHits().size() ; - - lcio::TrackerHit* thf0 = trk0->getTrackerHits()[ 0 ] ; - lcio::TrackerHit* thf1 = trk1->getTrackerHits()[ 0 ] ; - - lcio::TrackerHit* thl0 = trk0->getTrackerHits()[ nhit0 - 1 ] ; - lcio::TrackerHit* thl1 = trk1->getTrackerHits()[ nhit1 - 1 ] ; - - // lcio::TrackerHit* thm1 = trk1->getTrackerHits()[ nhit1 / 2 ] ; - // lcio::TrackerHit* thm0 = trk0->getTrackerHits()[ nhit0 / 2 ] ; - - int lthf0 = lcio::ILD_cellID( thf0 )[ lcio::LCTrackerCellID::layer() ] ; - int lthf1 = lcio::ILD_cellID( thf1 )[ lcio::LCTrackerCellID::layer() ] ; - - int lthl0 = lcio::ILD_cellID( thl0 )[ lcio::LCTrackerCellID::layer() ] ; - int lthl1 = lcio::ILD_cellID( thl1 )[ lcio::LCTrackerCellID::layer() ] ; - - // if( lthf0 <= lthl1 && lthf1 <= lthl0 ) return false ; - - // allow the track segements to overlap slightly - FIXME: make a parameter ... - const int overlapRows = 4 ; - if( lthf0 + overlapRows <= lthl1 && lthf1 + overlapRows <= lthl0 ) return false ; - - // now we take the larger segment and see if we can add the three hits from the other segment... - - lcio::Track* trk = ( nhit0 > nhit1 ? trk0 : trk1 ) ; - lcio::Track* oth = ( nhit0 > nhit1 ? trk1 : trk0 ) ; - - bool outward = ( nhit0 > nhit1 ? lthl0 <= lthf1 + overlapRows : lthl1 <= lthf0 + overlapRows ) ; - - unsigned n = oth->getTrackerHits().size() ; - - lcio::TrackerHit* th0 = ( outward ? oth->getTrackerHits()[ 0 ] : oth->getTrackerHits()[ n - 1 ] ) ; - lcio::TrackerHit* th1 = oth->getTrackerHits()[ n / 2 ] ; - lcio::TrackerHit* th2 = ( outward ? oth->getTrackerHits()[ n -1 ] : oth->getTrackerHits()[ 0 ] ); - - - // track state at last hit migyt be rubish.... - // const lcio::TrackState* ts = ( outward ? trk->getTrackState( lcio::TrackState::AtLastHit ) : trk->getTrackState( lcio::TrackState::AtFirstHit ) ) ; - const lcio::TrackState* ts = trk->getTrackState( lcio::TrackState::AtFirstHit ) ; - - - - streamlog_out( DEBUG3 ) << " ******* TrackSegmentMerger : will extrapolate track " << ( outward ? " outwards\t" : " inwards\t" ) - << lcio::lcshort( trk ) << " vs: [" << std::hex << oth->id() << std::dec << "]" << std::endl ; - - // if( trk->id() == 0x0004534d && oth->id() == 0x000454a6 ){ - // streamlog_out( DEBUG3 ) << " &&&&&&&&&&&&&& Track 1 : \n" << *trk - // << " &&&&&&&&&&&&&& Track 2 : \n" << *oth - // << std::endl ; - // } - - std::unique_ptr mTrk( _trksystem->createTrack() ) ; - - int nHit = trk->getTrackerHits().size() ; - - if( nHit == 0 || ts ==0 ) - return false ; - - // float initial_chi2 = trk->getChi2() ; - // float initial_ndf = trk->getNdf() ; - - streamlog_out( DEBUG3 ) << " -- extrapolate TrackState : " << lcio::lcshort( ts ) << std::endl ; - - //need to add a dummy hit to the track - int result = mTrk->addHit( trk->getTrackerHits()[0] ) ; // is this the right hit ?????????? - - if( result != MarlinTrk::IMarlinTrack::success ){ - return false ; - } - - mTrk->initialise( *ts , _b , MarlinTrk::IMarlinTrack::backward ) ; - - double deltaChi ; - int addHit = 0 ; - - //----- now try to add the three hits : ---------------- - addHit = mTrk->addAndFit( th0 , deltaChi, _chi2Max ) ; - - streamlog_out( DEBUG3 ) << " **** adding first hit : " << dd4hep::rec::Vector3D( th0->getPosition() ) - << " added : " << MarlinTrk::errorCode( addHit ) - << " deltaChi2: " << deltaChi - << std::endl ; - - if( addHit != MarlinTrk::IMarlinTrack::success ) return false ; - - //--------------------- - addHit = mTrk->addAndFit( th1 , deltaChi, _chi2Max ) ; - - streamlog_out( DEBUG3 ) << " **** adding second hit : " << dd4hep::rec::Vector3D( th1->getPosition() ) - << " added : " << MarlinTrk::errorCode( addHit ) - << " deltaChi2: " << deltaChi - << std::endl ; - - if( addHit != MarlinTrk::IMarlinTrack::success ) return false ; - - //-------------------- - addHit = mTrk->addAndFit( th2 , deltaChi, _chi2Max ) ; - - streamlog_out( DEBUG3 ) << " **** adding third hit : " << dd4hep::rec::Vector3D( th2->getPosition() ) - << " added : " << MarlinTrk::errorCode( addHit ) - << " deltaChi2: " << deltaChi - << std::endl ; - - if( addHit != MarlinTrk::IMarlinTrack::success ) return false ; - - - - //////////// - return true ; - /////////// + unsigned nDuplicate = 0; + for (unsigned i = 0; i < _N; ++i) { + if (hLayer[i] > 1) + nDuplicate += hLayer[i]; } + return double(nDuplicate) / nHit > _f; + } +}; - }; - //======================================================================================= - -/** helper class for merging track segments, based on circle (and tan lambda) */ - - class TrackCircleDistance{ - - public: - /** C'tor takes merge distance */ - TrackCircleDistance(float dCut) : _dCutSquared( dCut*dCut ) , _dCut(dCut){} - - /** Merge condition: ... */ - inline bool operator()( nnclu::Element* h0, nnclu::Element* h1){ - - - - lcio::Track* trk0 = h0->first ; - lcio::Track* trk1 = h1->first ; - - const TrackInfoStruct* ti0 = trk0->ext() ; - const TrackInfoStruct* ti1 = trk1->ext() ; - - - streamlog_out( DEBUG2 ) << "TrackCircleDistance::operator() : " << trk0->id() << " <-> " << trk1->id() - << " ( ti0->zAvg > ti1->zAvg ) = " << ( ti0->zAvg > ti1->zAvg ) - << std::endl ; - - - // don't allow overlaps in z !!!! - float epsilon = 0. ; - if( ti0->zAvg > ti1->zAvg ){ - - if( ti1->zMax > ( ti0->zMin + epsilon ) ) - return false ; - - } else { - - if( ti0->zMax > ( ti1->zMin + epsilon ) ) - return false ; - - } - - double tl0 = std::abs( trk0->getTanLambda() ) ; - double tl1 = std::abs( trk1->getTanLambda() ) ; - - if( trk0->getTanLambda() * trk1->getTanLambda() < 0. ) - return false ; // require the same sign - - - double dtl = 2. * std::abs( tl0 - tl1 ) / ( tl0 + tl1 ) ; - - streamlog_out( DEBUG2 ) << "TrackCircleDistance::operator() : " << trk0->id() << " <-> " << trk1->id() - << " dtl : " << dtl << " std::abs( tl0 + tl1 ) = " << std::abs( tl0 + tl1 ) - << " ( dtl > 2. * _dCut && std::abs( tl0 + tl1 ) > 1.e-2 ) = " << ( dtl > 2. * _dCut && std::abs( tl0 + tl1 ) > 1.e-2 ) - << std::endl ; - - if( dtl > 2. * _dCut && std::abs( tl0 + tl1 ) > 1.e-2 ) - return false ; - // for very steep tracks (tanL < 0.001 ) tanL might differ largely for curlers due to multiple scattering - - double r0 = 1. / trk0->getOmega() ; - double r1 = 1. / trk1->getOmega() ; - - double r0abs = std::abs( r0 ) ; - double r1abs = std::abs( r1 ) ; - - - double d0 = trk0->getD0() ; - double d1 = trk1->getD0() ; - - // double z0 = trk0->getZ0() ; - // double z1 = trk1->getZ0() ; - - double rIP = 20. ; - - // streamlog_out( DEBUG2 ) << "TrackCircleDistance::operator() : " << trk0->id() << " <-> " << trk1->id() - // << " ( std::abs( d0 ) < rIP && std::abs( z0 ) < rIP && std::abs( d1 ) < rIP && std::abs( z1 ) < rIP ) " - // << ( std::abs( d0 ) < rIP && std::abs( z0 ) < rIP && std::abs( d1 ) < rIP && std::abs( z1 ) < rIP ) - // << std::endl ; - // // // don't merge tracks that come from an area of 20 mm around the IP - // if( std::abs( d0 ) < rIP && std::abs( z0 ) < rIP && - // std::abs( d1 ) < rIP && std::abs( z1 ) < rIP ) - // return false ; - - - const lcio::TrackState* ts0 = trk0->getTrackState( lcio::TrackState::AtFirstHit ) ; - const lcio::TrackState* ts1 = trk1->getTrackState( lcio::TrackState::AtFirstHit ) ; - - double z0 = ( ts0 ? ts0->getReferencePoint()[2] : 0. ) ; - double z1 = ( ts1 ? ts1->getReferencePoint()[2] : 0. ) ; - - - streamlog_out( DEBUG2 ) << "TrackCircleDistance::operator() : " << trk0->id() << " <-> " << trk1->id() - << " ( std::abs( z0 ) < rIP && std::abs( z1 ) < rIP ) " - << ( std::abs( z0 ) < rIP && std::abs( z1 ) < rIP ) - << std::endl ; - - if( std::abs( z0 ) < rIP && std::abs( z1 ) < rIP ) - return false ; - - - - double p0 = trk0->getPhi() ; - double p1 = trk1->getPhi() ; - - double x0 = ( r0 - d0 ) * sin( p0 ) ; - double x1 = ( r1 - d1 ) * sin( p1 ) ; - - double y0 = ( d0 - r0 ) * cos( p0 ) ; - double y1 = ( d1 - r1 ) * cos( p1 ) ; - - double dr = 2. * std::abs( r0abs - r1abs ) / (r0abs + r1abs ) ; - - double distMS = sqrt ( ( x0 - x1 ) * ( x0 - x1 ) + ( y0 - y1 ) * ( y0 - y1 ) ) ; - - streamlog_out( DEBUG2 ) << "TrackCircleDistance:: operator() : " << trk0->id() << " <-> " << trk1->id() - << "( dr < _dCut * std::abs( r0 ) && distMS < _dCut * std::abs( r0 ) ) " - << ( dr < _dCut * std::abs( r0 ) && distMS < _dCut * std::abs( r0 ) ) - << " dr : " << dr - << " _dCut * std::abs( r0 ) " << _dCut * std::abs( r0 ) - << " distMS :" << distMS - << std::endl ; - - // return ( dr < DRMAX && distMS < _dCut * std::abs( r0 ) ) ; - return ( dr < _dCut * std::abs( r0 ) && distMS < _dCut * std::abs( r0 ) ) ; +//------------------------------------------------------------------------------------------ +// helper for sorting cluster wrt layerID +struct LayerSortOut { + bool operator()(const Hit* l, const Hit* r) { return l->first->layer < r->first->layer; } +}; +struct LayerSortIn { + bool operator()(const Hit* l, const Hit* r) { return l->first->layer > r->first->layer; } +}; + +//------------------------------------------------------------------------------------------ + +struct IMarlinTrkFitter { + + MarlinTrk::IMarlinTrkSystem* _ts; + double _maxChi2Increment; + + IMarlinTrkFitter(MarlinTrk::IMarlinTrkSystem* ts, double maxChi2Increment = DBL_MAX) + : _ts(ts), _maxChi2Increment(maxChi2Increment) {} + + MarlinTrk::IMarlinTrack* operator()(CluTrack* clu); +}; + +//------------------------------------------------------------------------------------- + +/** Try to add hits from hLV (hit lists per layer) to the cluster. The cluster needs to have a fitted KalTrack + * associated to it. Hits are added if the resulting delta Chi2 is less than dChiMax - a maxStep is the maximum number + * of steps (layers) w/o successfully merging a hit. + */ +int addHitsAndFilter(CluTrack* clu, HitListVector& hLV, double dChiMax, double chi2Cut, unsigned maxStep, + ZIndex& zIndex, bool backward = false, MarlinTrk::IMarlinTrkSystem* trkSys = 0); +//------------------------------------------------------------------------------------------ + +/** Try to add a hit from the given HitList in layer of subdetector to the track. + * A hit is added if the resulting delta Chi2 is less than dChiMax. + */ +bool addHitAndFilter(int detectorID, int layer, CluTrack* clu, HitListVector& hLV, double dChiMax, double chi2Cut); + +//------------------------------------------------------------------------------------------ +/** Split up clusters that have a hit multiplicity of 2,3,4,...,N in at least layersWithMultiplicity. + */ +void split_multiplicity(Clusterer::cluster_list& cluList, int layersWithMultiplicity, int N = 5); + +//------------------------------------------------------------------------------------------ +/** Returns the number of rows where cluster clu has i hits in mult[i] for i=1,2,3,4,.... - + * mult[0] counts all rows that have hits + */ +void getHitMultiplicities(CluTrack* clu, std::vector& mult); + +//------------------------------------------------------------------------------------------ + +/** Split the cluster into two clusters. + */ +void create_two_clusters(Clusterer::cluster_type& clu, Clusterer::cluster_list& cluVec); + +//------------------------------------------------------------------------------------------ + +/** Split the cluster into three clusters. + */ +void create_three_clusters(Clusterer::cluster_type& clu, Clusterer::cluster_list& cluVec); + +/** Split the cluster into N clusters. + */ +void create_n_clusters(Clusterer::cluster_type& clu, Clusterer::cluster_list& cluVec, unsigned n); + +//======================================================================================= + +struct TrackInfoStruct { + TrackInfoStruct() + : zMin(0.), zAvg(0.), zMax(0.), startsInner(false), isCentral(false), isForward(false), isCurler(false) {} + float zMin; + float zAvg; + float zMax; + bool startsInner; + bool isCentral; + bool isForward; + bool isCurler; +}; +struct TrackInfo : lcrtrel::LCOwnedExtension {}; + +/** Helper class to compute track segment properties. + */ +struct ComputeTrackerInfo { + + void operator()(lcio::LCObject* o) { + + lcio::Track* lTrk = (lcio::Track*)o; + + // compute z-extend of this track segment + const lcio::TrackerHitVec& hv = lTrk->getTrackerHits(); + + float zMin = 1e99; + float zMax = -1e99; + float zAvg = 0.; + + if (hv.size() > 1) { + zMin = hv[0]->getPosition()[2]; + zMax = hv[hv.size() - 1]->getPosition()[2]; + zAvg = (zMax + zMin) / 2.; } - - protected: - float _dCutSquared ; - float _dCut ; - } ; - - //======================================================================================= - - struct TrackZSort { // sort tracks wtr to abs(z_average ) - inline bool operator()( lcio::Track* l, lcio::Track* r) { - return ( std::abs( l->ext()->zAvg ) < std::abs( r ->ext()->zAvg ) ) ; - } - }; - - - //======================================================================================= - - /** Helper class that creates an Elements for an LCOjects of type T. - */ - template - struct MakeLCIOElement{ - nnclu::Element* operator()( lcio::LCObject* o) { return new nnclu::Element( (T*) o) ; } - } ; - - - //======================================================================================= - - class Timer{ - public: - Timer(){ - _clocks.reserve( 100 ) ; - _names.reserve( 100 ) ; - - _clocks.push_back(0) ; - _names.push_back( "start" ) ; + + if (zMin > zMax) { // swap + float d = zMax; + zMax = zMin; + zMin = d; } - unsigned registerTimer( const std::string& name ){ - _clocks.push_back(0) ; - _names.push_back( name ) ; - return _clocks.size() - 1 ; + + if (!lTrk->ext()) + lTrk->ext() = new TrackInfoStruct; + + lTrk->ext()->zMin = zMin; + lTrk->ext()->zMax = zMax; + lTrk->ext()->zAvg = zAvg; + } +}; +//======================================================================================= + +/** helper class for merging split track segments */ + +class TrackSegmentMerger { + +public: + /** C'tor takes merge distance */ + TrackSegmentMerger(float chi2Max, MarlinTrk::IMarlinTrkSystem* trksystem, float b) + : _chi2Max(chi2Max), _trksystem(trksystem), _b(b) {} + + float _chi2Max; + MarlinTrk::IMarlinTrkSystem* _trksystem; + float _b; + + /** Merge condition: ... */ + inline bool operator()(nnclu::Element* h0, nnclu::Element* h1) { + + lcio::Track* trk0 = h0->first; + lcio::Track* trk1 = h1->first; + + // protect against merging multiple segments (and thus complete tracks) + if (h0->second || h1->second) + return false; + + // const TrackInfoStruct* ti0 = trk0->ext() ; + // const TrackInfoStruct* ti1 = trk1->ext() ; + + // const lcio::TrackState* tsF0 = trk0->getTrackState( lcio::TrackState::AtFirstHit ) ; + // const lcio::TrackState* tsL0 = trk0->getTrackState( lcio::TrackState::AtLastHit ) ; + + // const lcio::TrackState* tsF1 = trk1->getTrackState( lcio::TrackState::AtFirstHit ) ; + // const lcio::TrackState* tsL1 = trk1->getTrackState( lcio::TrackState::AtLastHit ) ; + + // --- get three hits per track : first last midddle + + unsigned nhit0 = trk0->getTrackerHits().size(); + unsigned nhit1 = trk1->getTrackerHits().size(); + + lcio::TrackerHit* thf0 = trk0->getTrackerHits()[0]; + lcio::TrackerHit* thf1 = trk1->getTrackerHits()[0]; + + lcio::TrackerHit* thl0 = trk0->getTrackerHits()[nhit0 - 1]; + lcio::TrackerHit* thl1 = trk1->getTrackerHits()[nhit1 - 1]; + + // lcio::TrackerHit* thm1 = trk1->getTrackerHits()[ nhit1 / 2 ] ; + // lcio::TrackerHit* thm0 = trk0->getTrackerHits()[ nhit0 / 2 ] ; + + int lthf0 = lcio::ILD_cellID(thf0)[lcio::LCTrackerCellID::layer()]; + int lthf1 = lcio::ILD_cellID(thf1)[lcio::LCTrackerCellID::layer()]; + + int lthl0 = lcio::ILD_cellID(thl0)[lcio::LCTrackerCellID::layer()]; + int lthl1 = lcio::ILD_cellID(thl1)[lcio::LCTrackerCellID::layer()]; + + // if( lthf0 <= lthl1 && lthf1 <= lthl0 ) return false ; + + // allow the track segements to overlap slightly - FIXME: make a parameter ... + const int overlapRows = 4; + if (lthf0 + overlapRows <= lthl1 && lthf1 + overlapRows <= lthl0) + return false; + + // now we take the larger segment and see if we can add the three hits from the other segment... + + lcio::Track* trk = (nhit0 > nhit1 ? trk0 : trk1); + lcio::Track* oth = (nhit0 > nhit1 ? trk1 : trk0); + + bool outward = (nhit0 > nhit1 ? lthl0 <= lthf1 + overlapRows : lthl1 <= lthf0 + overlapRows); + + unsigned n = oth->getTrackerHits().size(); + + lcio::TrackerHit* th0 = (outward ? oth->getTrackerHits()[0] : oth->getTrackerHits()[n - 1]); + lcio::TrackerHit* th1 = oth->getTrackerHits()[n / 2]; + lcio::TrackerHit* th2 = (outward ? oth->getTrackerHits()[n - 1] : oth->getTrackerHits()[0]); + + // track state at last hit migyt be rubish.... + // const lcio::TrackState* ts = ( outward ? trk->getTrackState( lcio::TrackState::AtLastHit ) : + // trk->getTrackState( lcio::TrackState::AtFirstHit ) ) ; + const lcio::TrackState* ts = trk->getTrackState(lcio::TrackState::AtFirstHit); + + streamlog_out(DEBUG3) << " ******* TrackSegmentMerger : will extrapolate track " + << (outward ? " outwards\t" : " inwards\t") << lcio::lcshort(trk) << " vs: [" << std::hex + << oth->id() << std::dec << "]" << std::endl; + + // if( trk->id() == 0x0004534d && oth->id() == 0x000454a6 ){ + // streamlog_out( DEBUG3 ) << " &&&&&&&&&&&&&& Track 1 : \n" << *trk + // << " &&&&&&&&&&&&&& Track 2 : \n" << *oth + // << std::endl ; + // } + + std::unique_ptr mTrk(_trksystem->createTrack()); + + int nHit = trk->getTrackerHits().size(); + + if (nHit == 0 || ts == 0) + return false; + + // float initial_chi2 = trk->getChi2() ; + // float initial_ndf = trk->getNdf() ; + + streamlog_out(DEBUG3) << " -- extrapolate TrackState : " << lcio::lcshort(ts) << std::endl; + + // need to add a dummy hit to the track + int result = mTrk->addHit(trk->getTrackerHits()[0]); // is this the right hit ?????????? + + if (result != MarlinTrk::IMarlinTrack::success) { + return false; } - void time(unsigned index){ - _clocks[ index ] = clock() ; + mTrk->initialise(*ts, _b, MarlinTrk::IMarlinTrack::backward); + + double deltaChi; + int addHit = 0; + + //----- now try to add the three hits : ---------------- + addHit = mTrk->addAndFit(th0, deltaChi, _chi2Max); + + streamlog_out(DEBUG3) << " **** adding first hit : " << dd4hep::rec::Vector3D(th0->getPosition()) + << " added : " << MarlinTrk::errorCode(addHit) << " deltaChi2: " << deltaChi + << std::endl; + + if (addHit != MarlinTrk::IMarlinTrack::success) + return false; + + //--------------------- + addHit = mTrk->addAndFit(th1, deltaChi, _chi2Max); + + streamlog_out(DEBUG3) << " **** adding second hit : " << dd4hep::rec::Vector3D(th1->getPosition()) + << " added : " << MarlinTrk::errorCode(addHit) << " deltaChi2: " << deltaChi + << std::endl; + + if (addHit != MarlinTrk::IMarlinTrack::success) + return false; + + //-------------------- + addHit = mTrk->addAndFit(th2, deltaChi, _chi2Max); + + streamlog_out(DEBUG3) << " **** adding third hit : " << dd4hep::rec::Vector3D(th2->getPosition()) + << " added : " << MarlinTrk::errorCode(addHit) << " deltaChi2: " << deltaChi + << std::endl; + + if (addHit != MarlinTrk::IMarlinTrack::success) + return false; + + //////////// + return true; + /////////// + } +}; +//======================================================================================= + +/** helper class for merging track segments, based on circle (and tan lambda) */ + +class TrackCircleDistance { + +public: + /** C'tor takes merge distance */ + TrackCircleDistance(float dCut) : _dCutSquared(dCut * dCut), _dCut(dCut) {} + + /** Merge condition: ... */ + inline bool operator()(nnclu::Element* h0, nnclu::Element* h1) { + + lcio::Track* trk0 = h0->first; + lcio::Track* trk1 = h1->first; + + const TrackInfoStruct* ti0 = trk0->ext(); + const TrackInfoStruct* ti1 = trk1->ext(); + + streamlog_out(DEBUG2) << "TrackCircleDistance::operator() : " << trk0->id() << " <-> " << trk1->id() + << " ( ti0->zAvg > ti1->zAvg ) = " << (ti0->zAvg > ti1->zAvg) << std::endl; + + // don't allow overlaps in z !!!! + float epsilon = 0.; + if (ti0->zAvg > ti1->zAvg) { + + if (ti1->zMax > (ti0->zMin + epsilon)) + return false; + + } else { + + if (ti0->zMax > (ti1->zMin + epsilon)) + return false; } - void start() { time(0) ; } + double tl0 = std::abs(trk0->getTanLambda()); + double tl1 = std::abs(trk1->getTanLambda()); + + if (trk0->getTanLambda() * trk1->getTanLambda() < 0.) + return false; // require the same sign + + double dtl = 2. * std::abs(tl0 - tl1) / (tl0 + tl1); + + streamlog_out(DEBUG2) << "TrackCircleDistance::operator() : " << trk0->id() << " <-> " << trk1->id() + << " dtl : " << dtl << " std::abs( tl0 + tl1 ) = " << std::abs(tl0 + tl1) + << " ( dtl > 2. * _dCut && std::abs( tl0 + tl1 ) > 1.e-2 ) = " + << (dtl > 2. * _dCut && std::abs(tl0 + tl1) > 1.e-2) << std::endl; + + if (dtl > 2. * _dCut && std::abs(tl0 + tl1) > 1.e-2) + return false; + // for very steep tracks (tanL < 0.001 ) tanL might differ largely for curlers due to multiple scattering + + double r0 = 1. / trk0->getOmega(); + double r1 = 1. / trk1->getOmega(); + + double r0abs = std::abs(r0); + double r1abs = std::abs(r1); + + double d0 = trk0->getD0(); + double d1 = trk1->getD0(); + + // double z0 = trk0->getZ0() ; + // double z1 = trk1->getZ0() ; + + double rIP = 20.; + + // streamlog_out( DEBUG2 ) << "TrackCircleDistance::operator() : " << trk0->id() << " <-> " << trk1->id() + // << " ( std::abs( d0 ) < rIP && std::abs( z0 ) < rIP && std::abs( d1 ) < rIP && + // std::abs( z1 ) < rIP ) " + // << ( std::abs( d0 ) < rIP && std::abs( z0 ) < rIP && std::abs( d1 ) < rIP && + // std::abs( z1 ) < rIP ) + // << std::endl ; + // // // don't merge tracks that come from an area of 20 mm around the IP + // if( std::abs( d0 ) < rIP && std::abs( z0 ) < rIP && + // std::abs( d1 ) < rIP && std::abs( z1 ) < rIP ) + // return false ; + + const lcio::TrackState* ts0 = trk0->getTrackState(lcio::TrackState::AtFirstHit); + const lcio::TrackState* ts1 = trk1->getTrackState(lcio::TrackState::AtFirstHit); + + double z0 = (ts0 ? ts0->getReferencePoint()[2] : 0.); + double z1 = (ts1 ? ts1->getReferencePoint()[2] : 0.); + + streamlog_out(DEBUG2) << "TrackCircleDistance::operator() : " << trk0->id() << " <-> " << trk1->id() + << " ( std::abs( z0 ) < rIP && std::abs( z1 ) < rIP ) " + << (std::abs(z0) < rIP && std::abs(z1) < rIP) << std::endl; - std::string toString(){ - - std::stringstream s ; + if (std::abs(z0) < rIP && std::abs(z1) < rIP) + return false; - s << " ============= Timer ================================ " << std::endl ; - unsigned N=_clocks.size() ; - for( unsigned i=1 ; i < N ; ++i){ - s << " " << _names[i] << " : " << double(_clocks[i] - _clocks[i-1] ) / double(CLOCKS_PER_SEC) << std::endl ; - } - s << " Total : " << double(_clocks[N-1] - _clocks[0] ) / double(CLOCKS_PER_SEC) << std::endl ; - s << " ==================================================== " << std::endl ; + double p0 = trk0->getPhi(); + double p1 = trk1->getPhi(); - return s.str() ; + double x0 = (r0 - d0) * sin(p0); + double x1 = (r1 - d1) * sin(p1); + + double y0 = (d0 - r0) * cos(p0); + double y1 = (d1 - r1) * cos(p1); + + double dr = 2. * std::abs(r0abs - r1abs) / (r0abs + r1abs); + + double distMS = sqrt((x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1)); + + streamlog_out(DEBUG2) << "TrackCircleDistance:: operator() : " << trk0->id() << " <-> " << trk1->id() + << "( dr < _dCut * std::abs( r0 ) && distMS < _dCut * std::abs( r0 ) ) " + << (dr < _dCut * std::abs(r0) && distMS < _dCut * std::abs(r0)) << " dr : " << dr + << " _dCut * std::abs( r0 ) " << _dCut * std::abs(r0) << " distMS :" << distMS << std::endl; + + // return ( dr < DRMAX && distMS < _dCut * std::abs( r0 ) ) ; + return (dr < _dCut * std::abs(r0) && distMS < _dCut * std::abs(r0)); + } + +protected: + float _dCutSquared; + float _dCut; +}; + +//======================================================================================= + +struct TrackZSort { // sort tracks wtr to abs(z_average ) + inline bool operator()(lcio::Track* l, lcio::Track* r) { + return (std::abs(l->ext()->zAvg) < std::abs(r->ext()->zAvg)); + } +}; + +//======================================================================================= + +/** Helper class that creates an Elements for an LCOjects of type T. + */ +template +struct MakeLCIOElement { + nnclu::Element* operator()(lcio::LCObject* o) { return new nnclu::Element((T*)o); } +}; + +//======================================================================================= + +class Timer { +public: + Timer() { + _clocks.reserve(100); + _names.reserve(100); + + _clocks.push_back(0); + _names.push_back("start"); + } + unsigned registerTimer(const std::string& name) { + _clocks.push_back(0); + _names.push_back(name); + return _clocks.size() - 1; + } + + void time(unsigned index) { _clocks[index] = clock(); } + void start() { time(0); } + + std::string toString() { + + std::stringstream s; + + s << " ============= Timer ================================ " << std::endl; + unsigned N = _clocks.size(); + for (unsigned i = 1; i < N; ++i) { + s << " " << _names[i] << " : " << double(_clocks[i] - _clocks[i - 1]) / double(CLOCKS_PER_SEC) << std::endl; } - protected: - std::vector< clock_t> _clocks{} ; - std::vector< std::string > _names{} ; - }; + s << " Total : " << double(_clocks[N - 1] - _clocks[0]) / double(CLOCKS_PER_SEC) << std::endl; + s << " ==================================================== " << std::endl; + return s.str(); + } -} +protected: + std::vector _clocks{}; + std::vector _names{}; +}; + +} // namespace clupatra_new #endif diff --git a/src/ClupatraProcessor.cc b/src/ClupatraProcessor.cc index 202ec21..cae4cba 100644 --- a/src/ClupatraProcessor.cc +++ b/src/ClupatraProcessor.cc @@ -2,594 +2,526 @@ #include "clupatra_new.h" -#include -#include -#include -#include #include -#include #include -#include #include #include +#include +#include +#include +#include +#include +#include -//---- MarlinUtil +//---- MarlinUtil #include "MarlinCED.h" //---- LCIO --- +#include "EVENT/SimTrackerHit.h" #include "IMPL/LCCollectionVec.h" +#include "IMPL/LCFlagImpl.h" #include "IMPL/TrackImpl.h" #include "IMPL/TrackerHitImpl.h" -#include "EVENT/SimTrackerHit.h" -#include "IMPL/LCFlagImpl.h" -#include "UTIL/Operators.h" -#include "UTIL/LCTOOLS.h" #include "UTIL/CellIDDecoder.h" +#include "UTIL/LCIterator.h" +#include "UTIL/LCTOOLS.h" #include "UTIL/LCTrackerConf.h" +#include "UTIL/Operators.h" #include -#include "UTIL/LCIterator.h" // --- DD4hep --- +#include "DD4hep/DD4hepUnits.h" #include "DD4hep/Detector.h" -#include "DDRec/Vector3D.h" -#include "DD4hep/DD4hepUnits.h" #include "DDRec/DetectorData.h" - +#include "DDRec/Vector3D.h" //-------gsl ----- -#include "gsl/gsl_randist.h" #include "gsl/gsl_cdf.h" - +#include "gsl/gsl_randist.h" #include "MarlinTrk/Factory.h" #include "MarlinTrk/IMarlinTrack.h" #include "MarlinTrk/IMarlinTrkSystem.h" #include "MarlinTrk/MarlinTrkUtils.h" +using namespace lcio; +using namespace marlin; -using namespace lcio ; -using namespace marlin ; - -using namespace clupatra_new ; +using namespace clupatra_new; #define WRITE_PICKED_DEBUG_TRACKS false /** helper method to create a track collections and add it to the event */ -inline LCCollectionVec* newTrkCol(const std::string& name, LCEvent * evt , bool isSubset=false){ +inline LCCollectionVec* newTrkCol(const std::string& name, LCEvent* evt, bool isSubset = false) { - LCCollectionVec* col = new LCCollectionVec( LCIO::TRACK ) ; + LCCollectionVec* col = new LCCollectionVec(LCIO::TRACK); - LCFlagImpl hitFlag(0) ; - hitFlag.setBit( LCIO::TRBIT_HITS ) ; - col->setFlag( hitFlag.getFlag() ) ; + LCFlagImpl hitFlag(0); + hitFlag.setBit(LCIO::TRBIT_HITS); + col->setFlag(hitFlag.getFlag()); - evt->addCollection( col , name ) ; + evt->addCollection(col, name); - col->setSubset( isSubset ) ; + col->setSubset(isSubset); - return col ; + return col; } //---------------------------------------------------------------- /** helper method to get the collection from the event */ -inline LCCollection* getCollection( const std::string& name, LCEvent * evt ){ - - LCCollection* col = 0 ; - try{ col = evt->getCollection( name ) ; - } catch( lcio::DataNotAvailableException& e) { - streamlog_out( DEBUG4 ) << " input collection not in event : " << name << " !!! " << std::endl ; - } - return col ; +inline LCCollection* getCollection(const std::string& name, LCEvent* evt) { + + LCCollection* col = 0; + try { + col = evt->getCollection(name); + } catch (lcio::DataNotAvailableException& e) { + streamlog_out(DEBUG4) << " input collection not in event : " << name << " !!! " << std::endl; + } + return col; } //---------------------------------------------------------------- -template In find_smallest(In first, In last, Pred p, double& d){ - - In res = last ; +template +In find_smallest(In first, In last, Pred p, double& d) { + + In res = last; + + double min = DBL_MAX; - double min = DBL_MAX ; - - while( first != last ){ + while (first != last) { - double val = p( *first) ; + double val = p(*first); - if( val < min ){ + if (val < min) { - res = first ; - min = val ; + res = first; + min = val; } - - ++first ; + + ++first; } - d = min ; + d = min; - streamlog_out( DEBUG ) << " found smallest " << *res << " min : " << d << std::endl ; + streamlog_out(DEBUG) << " found smallest " << *res << " min : " << d << std::endl; - return res ; + return res; } //---------------------------------------------------------------- template -struct Distance3D2{ - VEC_3D _pos ; - Distance3D2( const VEC_3D& pos) : _pos( pos ) {} +struct Distance3D2 { + VEC_3D _pos; + Distance3D2(const VEC_3D& pos) : _pos(pos) {} template - double operator()( const T* t) { - VEC_3D p( t->getPosition() ) ; - return ( p - _pos ).r2() ; - + double operator()(const T* t) { + VEC_3D p(t->getPosition()); + return (p - _pos).r2(); } }; //---------------------------------------------------------------- template -struct StripDistance2{ - VEC_3D _pos ; - StripDistance2( const VEC_3D& pos) : _pos( pos ) {} - - double operator()( const TrackerHit* t) { +struct StripDistance2 { + VEC_3D _pos; + StripDistance2(const VEC_3D& pos) : _pos(pos) {} + + double operator()(const TrackerHit* t) { - VEC_3D p( t->getPosition() ) ; + VEC_3D p(t->getPosition()); - const TrackerHitPlane* h = (const TrackerHitPlane*) t ; + const TrackerHitPlane* h = (const TrackerHitPlane*)t; - VEC_3D v( 1. , h->getU()[1] , h->getU()[0] , VEC_3D::spherical ) ; + VEC_3D v(1., h->getU()[1], h->getU()[0], VEC_3D::spherical); - double d = ( p - _pos ).dot(v) ; + double d = (p - _pos).dot(v); - streamlog_out( DEBUG ) << " h: " << *h << "\n" - << " v: " << v << "\n" - << " d: " << d << std::endl ; - + streamlog_out(DEBUG) << " h: " << *h << "\n" + << " v: " << v << "\n" + << " d: " << d << std::endl; - return d*d ; + return d * d; } }; //---------------------------------------------------------------- -struct MeanAbsZOfTrack{ - double operator()( const Track* t){ - double z = 0 ; - int hitCount = 0 ; - const TrackerHitVec& hV = t->getTrackerHits() ; - for(unsigned i=0, N = hV.size() ; igetPosition()[2] ; - ++hitCount ; +struct MeanAbsZOfTrack { + double operator()(const Track* t) { + double z = 0; + int hitCount = 0; + const TrackerHitVec& hV = t->getTrackerHits(); + for (unsigned i = 0, N = hV.size(); i < N; ++i) { + z += hV[i]->getPosition()[2]; + ++hitCount; } - return ( hitCount>0 ? std::abs( z ) / hitCount : 0 ) ; + return (hitCount > 0 ? std::abs(z) / hitCount : 0); } }; //---------------------------------------------------------------- //---- debug helper for writing track collection w/ picking in CED -void printAndSaveTrack(const EVENT::LCObject* o ) ; +void printAndSaveTrack(const EVENT::LCObject* o); + +class DebugTracks { + friend void printAndSaveTrack(const EVENT::LCObject* o); -class DebugTracks{ - friend void printAndSaveTrack(const EVENT::LCObject* o ) ; public: - static void setCol( LCCollection* c, Processor* p) { - if( !proc ) proc = p ; - - if( proc == p ){ - - col = c ; - } - else { - throw Exception(" DebugTracks::setCol called from more than one processors ... " ) ; + static void setCol(LCCollection* c, Processor* p) { + if (!proc) + proc = p; + + if (proc == p) { + + col = c; + } else { + throw Exception(" DebugTracks::setCol called from more than one processors ... "); } - } + } + protected: - static LCCollection* col ; - static Processor* proc ; -} ; + static LCCollection* col; + static Processor* proc; +}; + +LCCollection* DebugTracks::col = 0; +Processor* DebugTracks::proc = 0; + +//--------------------------------------------------------------- + +void printAndSaveTrack(const EVENT::LCObject* o) { -LCCollection* DebugTracks::col = 0 ; -Processor* DebugTracks::proc = 0 ; + lcio::TrackImpl* trk = const_cast(dynamic_cast(o)); -//--------------------------------------------------------------- + if (trk) + streamlog_out(MESSAGE) << *trk << std::endl; -void printAndSaveTrack(const EVENT::LCObject* o ){ - - lcio::TrackImpl* trk = const_cast ( dynamic_cast (o) ) ; - - if( trk ) - streamlog_out( MESSAGE ) << *trk << std::endl ; - - if( trk && DebugTracks::col ) { + if (trk && DebugTracks::col) { - DebugTracks::col->addElement( new TrackImpl( *trk ) ) ; + DebugTracks::col->addElement(new TrackImpl(*trk)); - streamlog_out( MESSAGE ) << " =========== added copy of track to debug collection with current size: " << DebugTracks::col->getNumberOfElements() - << " ==========" << std::endl ; + streamlog_out(MESSAGE) << " =========== added copy of track to debug collection with current size: " + << DebugTracks::col->getNumberOfElements() << " ==========" << std::endl; } } //---------------------------------------------------------------- -void printTrackerHit(const EVENT::LCObject* o){ - - lcio::TrackerHit* hit = const_cast ( dynamic_cast (o) ) ; - - if( hit == 0 ) { - - streamlog_out( ERROR ) << " printTrackerHit : dynamic_cast failed for LCObject : " << o << std::endl ; - return ; - +void printTrackerHit(const EVENT::LCObject* o) { + + lcio::TrackerHit* hit = const_cast(dynamic_cast(o)); + + if (hit == 0) { + + streamlog_out(ERROR) << " printTrackerHit : dynamic_cast failed for LCObject : " << o << std::endl; + return; + } else { - - streamlog_out( MESSAGE ) << " --- TrackerHit: " << *hit - << "\n --- delta Chi2 = " << hit->ext() - << "\n --- cov. matrix = " << hit->getCovMatrix()[0] <<", "<getCovMatrix()[2] <<", "<getCovMatrix()[5] <<" "<< std::endl ; + + streamlog_out(MESSAGE) << " --- TrackerHit: " << *hit << "\n --- delta Chi2 = " << hit->ext() + << "\n --- cov. matrix = " << hit->getCovMatrix()[0] << ", " << hit->getCovMatrix()[2] + << ", " << hit->getCovMatrix()[5] << " " << std::endl; } } //---------------------------------------------------------------- -void printSimTrackerHit(const EVENT::LCObject* o){ - - lcio::SimTrackerHit* hit = const_cast ( dynamic_cast (o) ) ; - - if( hit == 0 ) { - - streamlog_out( ERROR ) << " printSimTrackerHit : dynamic_cast failed for LCObject : " << o << std::endl ; - return ; - +void printSimTrackerHit(const EVENT::LCObject* o) { + + lcio::SimTrackerHit* hit = const_cast(dynamic_cast(o)); + + if (hit == 0) { + + streamlog_out(ERROR) << " printSimTrackerHit : dynamic_cast failed for LCObject : " << o + << std::endl; + return; + } else { - - streamlog_out( MESSAGE ) << " --- SimTrackerHit: " << *hit << "\n" - << " MCParticle: " << lcshort( hit->getMCParticle() ) - << std::endl ; + + streamlog_out(MESSAGE) << " --- SimTrackerHit: " << *hit << "\n" + << " MCParticle: " << lcshort(hit->getMCParticle()) << std::endl; } } //---------------------------------------------------------------- +ClupatraProcessor aClupatraProcessor; +ClupatraProcessor::ClupatraProcessor() : Processor("ClupatraProcessor"), _trksystem(0), _tpc(0) { + // modify processor description + _description = "ClupatraProcessor : nearest neighbour clustering seeded pattern recognition"; -ClupatraProcessor aClupatraProcessor ; + registerInputCollection(LCIO::TRACKERHIT, "TPCHitCollection", "Name of the tpc hit input collections", _colName, + "AllTPCTrackerHits"); + registerOutputCollection(LCIO::TRACK, "OutputCollection", "Name of the output collection with final TPC tracks", + _outColName, std::string("ClupatraTracks")); -ClupatraProcessor::ClupatraProcessor() : Processor("ClupatraProcessor") , - _trksystem(0), _tpc(0) { - - // modify processor description - _description = "ClupatraProcessor : nearest neighbour clustering seeded pattern recognition" ; - - - - registerInputCollection( LCIO::TRACKERHIT, - "TPCHitCollection" , - "Name of the tpc hit input collections" , - _colName , - "AllTPCTrackerHits" ) ; - - - registerOutputCollection( LCIO::TRACK, - "OutputCollection" , - "Name of the output collection with final TPC tracks" , - _outColName , - std::string("ClupatraTracks" ) ) ; - - registerOutputCollection( LCIO::TRACK, - "SegmentCollectionName" , - "Name of the output collection that has the individual track segments" , - _segmentsOutColName , - std::string("ClupatraTrackSegments" ) ) ; - - registerProcessorParameter( "DistanceCut" , - "Cut for distance between hits in mm for the seed finding" , - _distCut , - (float) 40.0 ) ; - - - registerProcessorParameter( "CosAlphaCut" , - "Cut for max.angle between hits in consecutive layers for seed finding - NB value should be smaller than 1 - default is 0.9999999 !!!" , - _cosAlphaCut , - (float) 0.9999999 ) ; - - registerProcessorParameter( "NLoopForSeeding" , - "number of seed finding loops - every loop increases the distance cut by DistanceCut/NLoopForSeeding" , - _nLoop , - (int) 4 ) ; - - - registerProcessorParameter( "MinimumClusterSize" , - "minimum number of hits per cluster" , - _minCluSize , - (int) 6) ; - - - registerProcessorParameter( "DuplicatePadRowFraction" , - "allowed fraction of hits in same pad row per track" , - _duplicatePadRowFraction, - (float) 0.1 ) ; - - // registerProcessorParameter( "RCut" , + registerOutputCollection(LCIO::TRACK, "SegmentCollectionName", + "Name of the output collection that has the individual track segments", _segmentsOutColName, + std::string("ClupatraTrackSegments")); + + registerProcessorParameter("DistanceCut", "Cut for distance between hits in mm for the seed finding", _distCut, + (float)40.0); + + registerProcessorParameter("CosAlphaCut", + "Cut for max.angle between hits in consecutive layers for seed finding - NB value should " + "be smaller than 1 - default is 0.9999999 !!!", + _cosAlphaCut, (float)0.9999999); + + registerProcessorParameter( + "NLoopForSeeding", + "number of seed finding loops - every loop increases the distance cut by DistanceCut/NLoopForSeeding", _nLoop, + (int)4); + + registerProcessorParameter("MinimumClusterSize", "minimum number of hits per cluster", _minCluSize, (int)6); + + registerProcessorParameter("DuplicatePadRowFraction", "allowed fraction of hits in same pad row per track", + _duplicatePadRowFraction, (float)0.1); + + // registerProcessorParameter( "RCut" , // "Cut for r_min in mm" , // _rCut , // (float) 0.0 ) ; - - registerProcessorParameter( "MaxDeltaChi2" , - "the maximum delta Chi2 after filtering for which a hit is added to a track segement" , - _dChi2Max , - (float) 35. ) ; - - registerProcessorParameter( "Chi2Cut" , - "the maximum chi2-distance for which a hit is considered for merging " , - _chi2Cut , - (float) 100. ) ; - - registerProcessorParameter( "MaxStepWithoutHit" , - "the maximum number of layers without finding a hit before hit search search is stopped " , - _maxStep , - (int) 3 ) ; - - - registerProcessorParameter( "PadRowRange" , - "number of pad rows used in initial seed clustering" , - _padRowRange , - (int) 12) ; - - registerProcessorParameter( "NumberOfZBins" , - "number of bins in z over total length of TPC - hits from different z bins are nver merged" , - _nZBins, - (int) 150 ) ; - - - registerProcessorParameter( "MinLayerFractionWithMultiplicity" , - "minimum fraction of layers that have a given multiplicity, when forcing a cluster into sub clusters" , - _minLayerFractionWithMultiplicity, - (float) 0.5 ) ; - - registerProcessorParameter( "MinLayerNumberWithMultiplicity" , - "minimum number of layers that have a given multiplicity, when forcing a cluster into sub clusters" , - _minLayerNumberWithMultiplicity, - (int) 3 ) ; - - registerProcessorParameter( "TrackStartsInnerDist" , - "maximum radial distance [mm] from inner field cage of first hit, such that the track is considered to start at the beginning " , - _trackStartsInnerDist , - (float) 25. ) ; - - registerProcessorParameter( "TrackEndsOuterCentralDist" , - "maximum radial distance [mm] from outer field cage of last hit, such that the track is considered to end at the end " , - _trackEndsOuterCentralDist , - (float) 25. ) ; - - registerProcessorParameter( "TrackEndsOuterForwardDist" , - "maximum distance in z [mm] from endplate of last hit, such that the track is considered to end at the end " , - _trackEndsOuterForwardDist , - (float) 40. ) ; - - registerProcessorParameter( "TrackIsCurlerOmega" , - "minimum curvature omega of a track segment for being considered a curler" , - _trackIsCurlerOmega , - (float) 0.001 ) ; - - registerProcessorParameter("MultipleScatteringOn", - "Use MultipleScattering in Fit", - _MSOn, - bool(true)); - - registerProcessorParameter("EnergyLossOn", - "Use Energy Loss in Fit", - _ElossOn, - bool(true)); - - registerProcessorParameter("SmoothOn", - "Smooth All Mesurement Sites in Fit", - _SmoothOn, - bool(false)); - - registerProcessorParameter("pickUpSiHits", - "try to pick up hits from Si-trackers", - _pickUpSiHits, - bool(false)); - - - registerOptionalParameter( "SITHitCollection" , - "name of the SIT hit collections - used to extend TPC tracks if (pickUpSiHits==true)" , - _sitColName , - std::string("SITTrackerHits") ) ; - - registerOptionalParameter( "VXDHitCollection" , - "name of the VXD hit collections - used to extend TPC tracks if (pickUpSiHits==true)" , - _vxdColName , - std::string("VTXTrackerHits") ) ; - - registerOptionalParameter( "SITDetectorName" , - "name of the SIT-like inner Si-tracking barrel detector ", - _sitDetectorName , - std::string("SIT") ) ; - - registerOptionalParameter( "VXDDetectorName" , - "name of the VXD-like inner Si-tracking barrel detector ", - _vxdDetectorName , - std::string("VXD") ) ; - - - registerProcessorParameter("CreateDebugCollections", - "optionally create some debug collection with intermediate track segments and used and unused hits", - _createDebugCollections, - bool(false)); - - registerProcessorParameter( "TrackSystemName", - "Name of the track fitting system to be used ( DDKalTest, aidaTT, ... )", - _trkSystemName, - std::string("DDKalTest") ); - - registerProcessorParameter( "CaloFaceBarrelID" , - "system ID of the subdetector at the calorimeter face in the barrel - default: lcio::ILDDetID::ECAL=20 ", - _caloFaceBarrelID, - (int) 20) ; - - registerProcessorParameter( "CaloFaceEndcapID" , - "system ID of the subdetector at the calorimeter face in the endcap - default: lcio::ILDDetID::ECAL=29 ", - _caloFaceEndcapID, - (int) 29) ; + registerProcessorParameter("MaxDeltaChi2", + "the maximum delta Chi2 after filtering for which a hit is added to a track segement", + _dChi2Max, (float)35.); -} + registerProcessorParameter("Chi2Cut", "the maximum chi2-distance for which a hit is considered for merging ", + _chi2Cut, (float)100.); + + registerProcessorParameter("MaxStepWithoutHit", + "the maximum number of layers without finding a hit before hit search search is stopped ", + _maxStep, (int)3); + + registerProcessorParameter("PadRowRange", "number of pad rows used in initial seed clustering", _padRowRange, + (int)12); + + registerProcessorParameter( + "NumberOfZBins", "number of bins in z over total length of TPC - hits from different z bins are nver merged", + _nZBins, (int)150); + + registerProcessorParameter( + "MinLayerFractionWithMultiplicity", + "minimum fraction of layers that have a given multiplicity, when forcing a cluster into sub clusters", + _minLayerFractionWithMultiplicity, (float)0.5); + + registerProcessorParameter( + "MinLayerNumberWithMultiplicity", + "minimum number of layers that have a given multiplicity, when forcing a cluster into sub clusters", + _minLayerNumberWithMultiplicity, (int)3); + + registerProcessorParameter("TrackStartsInnerDist", + "maximum radial distance [mm] from inner field cage of first hit, such that the track is " + "considered to start at the beginning ", + _trackStartsInnerDist, (float)25.); + + registerProcessorParameter("TrackEndsOuterCentralDist", + "maximum radial distance [mm] from outer field cage of last hit, such that the track is " + "considered to end at the end ", + _trackEndsOuterCentralDist, (float)25.); + + registerProcessorParameter( + "TrackEndsOuterForwardDist", + "maximum distance in z [mm] from endplate of last hit, such that the track is considered to end at the end ", + _trackEndsOuterForwardDist, (float)40.); + + registerProcessorParameter("TrackIsCurlerOmega", + "minimum curvature omega of a track segment for being considered a curler", + _trackIsCurlerOmega, (float)0.001); + + registerProcessorParameter("MultipleScatteringOn", "Use MultipleScattering in Fit", _MSOn, bool(true)); + + registerProcessorParameter("EnergyLossOn", "Use Energy Loss in Fit", _ElossOn, bool(true)); + + registerProcessorParameter("SmoothOn", "Smooth All Mesurement Sites in Fit", _SmoothOn, bool(false)); + + registerProcessorParameter("pickUpSiHits", "try to pick up hits from Si-trackers", _pickUpSiHits, bool(false)); + registerOptionalParameter("SITHitCollection", + "name of the SIT hit collections - used to extend TPC tracks if (pickUpSiHits==true)", + _sitColName, std::string("SITTrackerHits")); -void ClupatraProcessor::init() { + registerOptionalParameter("VXDHitCollection", + "name of the VXD hit collections - used to extend TPC tracks if (pickUpSiHits==true)", + _vxdColName, std::string("VTXTrackerHits")); + + registerOptionalParameter("SITDetectorName", "name of the SIT-like inner Si-tracking barrel detector ", + _sitDetectorName, std::string("SIT")); + + registerOptionalParameter("VXDDetectorName", "name of the VXD-like inner Si-tracking barrel detector ", + _vxdDetectorName, std::string("VXD")); + + registerProcessorParameter( + "CreateDebugCollections", + "optionally create some debug collection with intermediate track segments and used and unused hits", + _createDebugCollections, bool(false)); + + registerProcessorParameter("TrackSystemName", + "Name of the track fitting system to be used ( DDKalTest, aidaTT, ... )", _trkSystemName, + std::string("DDKalTest")); + + registerProcessorParameter( + "CaloFaceBarrelID", + "system ID of the subdetector at the calorimeter face in the barrel - default: lcio::ILDDetID::ECAL=20 ", + _caloFaceBarrelID, (int)20); + + registerProcessorParameter( + "CaloFaceEndcapID", + "system ID of the subdetector at the calorimeter face in the endcap - default: lcio::ILDDetID::ECAL=29 ", + _caloFaceEndcapID, (int)29); +} + +void ClupatraProcessor::init() { // usually a good idea to - printParameters() ; - + printParameters(); + // set upt the geometry - _trksystem = MarlinTrk::Factory::createMarlinTrkSystem( _trkSystemName , 0 , "" ) ; + _trksystem = MarlinTrk::Factory::createMarlinTrkSystem(_trkSystemName, 0, ""); + + if (_trksystem == 0) { - - if( _trksystem == 0 ){ - - throw EVENT::Exception( std::string(" Cannot initialize MarlinTrkSystem of Type: ") + _trkSystemName ) ; + throw EVENT::Exception(std::string(" Cannot initialize MarlinTrkSystem of Type: ") + _trkSystemName); } - - _trksystem->setOption( MarlinTrk::IMarlinTrkSystem::CFG::useQMS, _MSOn ) ; - _trksystem->setOption( MarlinTrk::IMarlinTrkSystem::CFG::usedEdx, _ElossOn) ; - _trksystem->setOption( MarlinTrk::IMarlinTrkSystem::CFG::useSmoothing, _SmoothOn) ; - _trksystem->init() ; - - _nRun = 0 ; - _nEvt = 0 ; - - - if( WRITE_PICKED_DEBUG_TRACKS ) - CEDPickingHandler::getInstance().registerFunction( LCIO::TRACK , &printAndSaveTrack ) ; - - CEDPickingHandler::getInstance().registerFunction( LCIO::TRACKERHIT , &printTrackerHit ) ; - - CEDPickingHandler::getInstance().registerFunction( LCIO::SIMTRACKERHIT , &printSimTrackerHit ) ; - + + _trksystem->setOption(MarlinTrk::IMarlinTrkSystem::CFG::useQMS, _MSOn); + _trksystem->setOption(MarlinTrk::IMarlinTrkSystem::CFG::usedEdx, _ElossOn); + _trksystem->setOption(MarlinTrk::IMarlinTrkSystem::CFG::useSmoothing, _SmoothOn); + _trksystem->init(); + + _nRun = 0; + _nEvt = 0; + + if (WRITE_PICKED_DEBUG_TRACKS) + CEDPickingHandler::getInstance().registerFunction(LCIO::TRACK, &printAndSaveTrack); + + CEDPickingHandler::getInstance().registerFunction(LCIO::TRACKERHIT, &printTrackerHit); + + CEDPickingHandler::getInstance().registerFunction(LCIO::SIMTRACKERHIT, &printSimTrackerHit); } -void ClupatraProcessor::processRunHeader( LCRunHeader* ) { +void ClupatraProcessor::processRunHeader(LCRunHeader*) { _nRun++; } - _nRun++ ; -} +void ClupatraProcessor::processEvent(LCEvent* evt) { + // clock_t start = clock() ; + Timer timer; + unsigned t_init = timer.registerTimer(" initialization "); + unsigned t_seedtracks = timer.registerTimer(" extend seed tracks "); + unsigned t_recluster = timer.registerTimer(" recluster leftovers "); + unsigned t_split = timer.registerTimer(" split clusters "); + unsigned t_finalfit = timer.registerTimer(" final refit "); + unsigned t_merge = timer.registerTimer(" merge segments "); + unsigned t_pickup = timer.registerTimer(" pick up Si hits "); -void ClupatraProcessor::processEvent( LCEvent * evt ) { - - // clock_t start = clock() ; - Timer timer ; - unsigned t_init = timer.registerTimer(" initialization " ) ; - unsigned t_seedtracks = timer.registerTimer(" extend seed tracks " ) ; - unsigned t_recluster = timer.registerTimer(" recluster leftovers " ) ; - unsigned t_split = timer.registerTimer(" split clusters " ) ; - unsigned t_finalfit = timer.registerTimer(" final refit " ) ; - unsigned t_merge = timer.registerTimer(" merge segments " ) ; - unsigned t_pickup = timer.registerTimer(" pick up Si hits " ) ; - - timer.start() ; + timer.start(); - // set the correct configuration for the tracking system for this event - MarlinTrk::TrkSysConfig< MarlinTrk::IMarlinTrkSystem::CFG::useQMS> mson( _trksystem, _MSOn ) ; - MarlinTrk::TrkSysConfig< MarlinTrk::IMarlinTrkSystem::CFG::usedEdx> elosson( _trksystem,_ElossOn) ; - MarlinTrk::TrkSysConfig< MarlinTrk::IMarlinTrkSystem::CFG::useSmoothing> smoothon( _trksystem,_SmoothOn) ; - + // set the correct configuration for the tracking system for this event + MarlinTrk::TrkSysConfig mson(_trksystem, _MSOn); + MarlinTrk::TrkSysConfig elosson(_trksystem, _ElossOn); + MarlinTrk::TrkSysConfig smoothon(_trksystem, _SmoothOn); // the clupa wrapper hits that hold pointers to LCIO hits plus some additional parameters - // create them in a vector for convenient memeory mgmt - std::vector clupaHits ; - + // create them in a vector for convenient memeory mgmt + std::vector clupaHits; + // on top of the clupahits we need the tiny wrappers for clustering - they are created on the heap // and we put them in a vector of pointers that takes ownership (i.e. deletes them at the end) - HitVec nncluHits ; - nncluHits.setOwner( true ) ; - + HitVec nncluHits; + nncluHits.setOwner(true); // this is the final list of cluster tracks - Clusterer::cluster_list cluList ; - cluList.setOwner() ; - - LCIOTrackConverter converter ; - converter.UsePropagate = true ; - converter.CaloFaceBarrelID = _caloFaceBarrelID ; - converter.CaloFaceEndcapID = _caloFaceEndcapID ; + Clusterer::cluster_list cluList; + cluList.setOwner(); + + LCIOTrackConverter converter; + converter.UsePropagate = true; + converter.CaloFaceBarrelID = _caloFaceBarrelID; + converter.CaloFaceEndcapID = _caloFaceEndcapID; // -------- get the TPC geometry information from the DD4hep model dd4hep::Detector& lcdd = dd4hep::Detector::getInstance(); - dd4hep::DetElement tpcDE = lcdd.detector("TPC") ; - _tpc = tpcDE.extension() ; + dd4hep::DetElement tpcDE = lcdd.detector("TPC"); + _tpc = tpcDE.extension(); - double bfieldV[3] ; - lcdd.field().magneticField( { 0., 0., 0. } , bfieldV ) ; - _bfield = bfieldV[2]/dd4hep::tesla ; + double bfieldV[3]; + lcdd.field().magneticField({0., 0., 0.}, bfieldV); + _bfield = bfieldV[2] / dd4hep::tesla; // fixme: currently LCTPC not supported until DDRec data exists ... - static const unsigned int maxTPCLayers = _tpc->maxRow ; - - double driftLength = _tpc->driftLength / dd4hep::mm ; - ZIndex zIndex( -driftLength , driftLength , _nZBins ) ; - - - LCCollection* col = 0 ; - - try{ col = dynamic_cast (evt->getCollection( _colName ) ); - - } catch( lcio::DataNotAvailableException& e) { - - streamlog_out( WARNING ) << " input collection not in event : " << _colName << " - nothing to do !!! " << std::endl ; - - return ; - } - + static const unsigned int maxTPCLayers = _tpc->maxRow; + + double driftLength = _tpc->driftLength / dd4hep::mm; + ZIndex zIndex(-driftLength, driftLength, _nZBins); + + LCCollection* col = 0; + + try { + col = dynamic_cast(evt->getCollection(_colName)); + + } catch (lcio::DataNotAvailableException& e) { + + streamlog_out(WARNING) << " input collection not in event : " << _colName << " - nothing to do !!! " + << std::endl; + + return; + } + //=============================================================================================== // create clupa and clustering hits for every lcio hit //=============================================================================================== - + // CellIDDecoder idDec( col ) ; - - int nHit = col->getNumberOfElements() ; - - clupaHits.resize( nHit ) ; // creates clupa hits (w/ default c'tor) - nncluHits.reserve( nHit ) ; + int nHit = col->getNumberOfElements(); + + clupaHits.resize(nHit); // creates clupa hits (w/ default c'tor) + nncluHits.reserve(nHit); + + streamlog_out(DEBUG1) << " create clupatra TPC hits, n = " << nHit << std::endl; + + for (int i = 0; i < nHit; ++i) { - streamlog_out( DEBUG1 ) << " create clupatra TPC hits, n = " << nHit << std::endl ; - - for(int i=0 ; i < nHit ; ++i ) { - //------ - - TrackerHit* th = (TrackerHit*) col->getElementAt(i) ; - if ( fabs(th->getPosition()[2]) > driftLength ) continue; - - ClupaHit* ch = & clupaHits[i] ; - - Hit* gh = new Hit( ch ) ; - - nncluHits.push_back( gh ) ; - + + TrackerHit* th = (TrackerHit*)col->getElementAt(i); + if (fabs(th->getPosition()[2]) > driftLength) + continue; + + ClupaHit* ch = &clupaHits[i]; + + Hit* gh = new Hit(ch); + + nncluHits.push_back(gh); + //------- - th->ext() = gh ; // assign the clupa hit to the LCIO hit for memory mgmt - - ch->lcioHit = th ; - - ch->pos = dd4hep::rec::Vector3D( th->getPosition() ) ; - + th->ext() = gh; // assign the clupa hit to the LCIO hit for memory mgmt + + ch->lcioHit = th; + + ch->pos = dd4hep::rec::Vector3D(th->getPosition()); + // int padIndex = padLayout.getNearestPad( ch->pos.rho() , ch->pos.phi() ) ; // ch->layer = padLayout.getRowNumber( padIndex ) ; - ch->layer = ILD_cellID( th )[ LCTrackerCellID::layer() ] ; - - streamlog_out( DEBUG ) << " ch->layer = idDec( th )[ LCTrackerCellID::layer() ] = " << ch->layer << " - CellID0 " << th->getCellID0() << std::endl ; - - ch->zIndex = zIndex( th ) ; - - //ch->phiIndex = .... - - } - - //--------------------------------------------------------------------------------------------------------- - - std::sort( nncluHits.begin(), nncluHits.end() , ZSort() ) ; - - //--------------------------------------------------------------------------------------------------------- - - HitListVector hitsInLayer( maxTPCLayers ) ; - addToHitListVector( nncluHits.begin(), nncluHits.end() , hitsInLayer ) ; - - streamlog_out( DEBUG2 ) << " added " << nncluHits.size() << " tp hitsInLayer - > size " << hitsInLayer.size() << std::endl ; + ch->layer = ILD_cellID(th)[LCTrackerCellID::layer()]; + + streamlog_out(DEBUG) << " ch->layer = idDec( th )[ LCTrackerCellID::layer() ] = " << ch->layer << " - CellID0 " + << th->getCellID0() << std::endl; + + ch->zIndex = zIndex(th); + + // ch->phiIndex = .... + } + + //--------------------------------------------------------------------------------------------------------- + + std::sort(nncluHits.begin(), nncluHits.end(), ZSort()); + + //--------------------------------------------------------------------------------------------------------- + + HitListVector hitsInLayer(maxTPCLayers); + addToHitListVector(nncluHits.begin(), nncluHits.end(), hitsInLayer); + + streamlog_out(DEBUG2) << " added " << nncluHits.size() << " tp hitsInLayer - > size " << hitsInLayer.size() + << std::endl; //--------------------------------------------------------------------------------------------------------- @@ -597,1393 +529,1332 @@ void ClupatraProcessor::processEvent( LCEvent * evt ) { // create output collections ( some optional ) //=============================================================================================== - const bool writeSeedCluster = _createDebugCollections ; - const bool writeCluTrackSegments = _createDebugCollections ; - const bool writeLeftoverClusters = _createDebugCollections ; - const bool writeQualityTracks = _createDebugCollections ; - const bool writeDebugTracks = WRITE_PICKED_DEBUG_TRACKS ; - - static const bool copyTrackSegments = false ; - - LCCollectionVec* seedCol = ( writeSeedCluster ? newTrkCol( "ClupatraSeedCluster" , evt ) : 0 ) ; - LCCollectionVec* cluCol = ( writeCluTrackSegments ? newTrkCol( "ClupatraInitialTrackSegments" , evt ) : 0 ) ; - LCCollectionVec* locCol = ( writeCluTrackSegments ? newTrkCol( "ClupatraLeftoverClusters" , evt ) : 0 ) ; - - LCCollectionVec* incSegCol = ( writeCluTrackSegments ? newTrkCol( "ClupatraIncompleteSegments" , evt , true ) : 0 ) ; - LCCollectionVec* curSegCol = ( writeCluTrackSegments ? newTrkCol( "ClupatraCurlerSegments" , evt , true ) : 0 ) ; - LCCollectionVec* finSegCol = ( writeCluTrackSegments ? newTrkCol( "ClupatraFinalTrackSegments" , evt , true ) : 0 ) ; - - //LCCollectionVec* goodCol = ( writeQualityTracks ? newTrkCol( "ClupatraGoodQualityTracks" , evt ,true ) : 0 ) ; - //LCCollectionVec* fairCol = ( writeQualityTracks ? newTrkCol( "ClupatraFairQualityTracks" , evt ,true ) : 0 ) ; - LCCollectionVec* poorCol = ( writeQualityTracks ? newTrkCol( "ClupatraPoorQualityTracks" , evt , true ) : 0 ) ; - - LCCollectionVec* debugCol= ( writeDebugTracks ? newTrkCol( "ClupatraDebugTracks" , evt , false ) : 0 ) ; - if( WRITE_PICKED_DEBUG_TRACKS ) - DebugTracks::setCol( debugCol , this ) ; - - LCCollectionVec* outerCol = ( _createDebugCollections ? newTrkCol( "ClupatraOuterSegments" , evt ,true ) : 0 ) ; - LCCollectionVec* innerCol = ( _createDebugCollections ? newTrkCol( "ClupatraInnerSegments" , evt ,true ) : 0 ) ; - LCCollectionVec* middleCol = ( _createDebugCollections ? newTrkCol( "ClupatraMiddleSegments" , evt ,true ) : 0 ) ; - - - LCCollectionVec* tsCol = newTrkCol( _segmentsOutColName , evt ) ; - - LCCollectionVec* outCol = newTrkCol( _outColName , evt ) ; + const bool writeSeedCluster = _createDebugCollections; + const bool writeCluTrackSegments = _createDebugCollections; + const bool writeLeftoverClusters = _createDebugCollections; + const bool writeQualityTracks = _createDebugCollections; + const bool writeDebugTracks = WRITE_PICKED_DEBUG_TRACKS; + + static const bool copyTrackSegments = false; + + LCCollectionVec* seedCol = (writeSeedCluster ? newTrkCol("ClupatraSeedCluster", evt) : 0); + LCCollectionVec* cluCol = (writeCluTrackSegments ? newTrkCol("ClupatraInitialTrackSegments", evt) : 0); + LCCollectionVec* locCol = (writeCluTrackSegments ? newTrkCol("ClupatraLeftoverClusters", evt) : 0); + + LCCollectionVec* incSegCol = (writeCluTrackSegments ? newTrkCol("ClupatraIncompleteSegments", evt, true) : 0); + LCCollectionVec* curSegCol = (writeCluTrackSegments ? newTrkCol("ClupatraCurlerSegments", evt, true) : 0); + LCCollectionVec* finSegCol = (writeCluTrackSegments ? newTrkCol("ClupatraFinalTrackSegments", evt, true) : 0); + + // LCCollectionVec* goodCol = ( writeQualityTracks ? newTrkCol( "ClupatraGoodQualityTracks" , evt ,true ) : 0 ) + // ; LCCollectionVec* fairCol = ( writeQualityTracks ? newTrkCol( "ClupatraFairQualityTracks" , evt ,true ) : 0 + // ) ; + LCCollectionVec* poorCol = (writeQualityTracks ? newTrkCol("ClupatraPoorQualityTracks", evt, true) : 0); + + LCCollectionVec* debugCol = (writeDebugTracks ? newTrkCol("ClupatraDebugTracks", evt, false) : 0); + if (WRITE_PICKED_DEBUG_TRACKS) + DebugTracks::setCol(debugCol, this); + + LCCollectionVec* outerCol = (_createDebugCollections ? newTrkCol("ClupatraOuterSegments", evt, true) : 0); + LCCollectionVec* innerCol = (_createDebugCollections ? newTrkCol("ClupatraInnerSegments", evt, true) : 0); + LCCollectionVec* middleCol = (_createDebugCollections ? newTrkCol("ClupatraMiddleSegments", evt, true) : 0); + + LCCollectionVec* tsCol = newTrkCol(_segmentsOutColName, evt); + + LCCollectionVec* outCol = newTrkCol(_outColName, evt); //--------------------------------------------------------------------------------------------------------- - - timer.time(t_init ) ; + + timer.time(t_init); //=============================================================================================== // first main step of clupatra: // * cluster in pad row range - starting from the outside - to find clean cluster segments // * extend the track segments with best matching hits, based on extrapolation to next layer(s) // * add the hits and apply a Kalman filter step ( track segement is always best estimate ) - // * repeat in backward direction ( after smoothing back, to get a reasonable track + // * repeat in backward direction ( after smoothing back, to get a reasonable track // state for extrapolating backwards ) //=============================================================================================== - Clusterer nncl ; - - int outerRow = 0 ; - - nnclu::PtrVector seedTrks ; - seedTrks.setOwner() ; // memory mgmt - will delete MarlinTrks at the end - - IMarlinTrkFitter fitter( _trksystem ) ; + Clusterer nncl; + int outerRow = 0; + + nnclu::PtrVector seedTrks; + seedTrks.setOwner(); // memory mgmt - will delete MarlinTrks at the end + + IMarlinTrkFitter fitter(_trksystem); + + streamlog_out(DEBUG5) + << "===============================================================================================\n" + << " first step of Clupatra algorithm: find seeds with NN-clustering in " << _nLoop + << " loops - max dist = " << _distCut << " \n" + << "===============================================================================================\n"; - streamlog_out( DEBUG5 ) << "===============================================================================================\n" - << " first step of Clupatra algorithm: find seeds with NN-clustering in " << _nLoop << " loops - max dist = " << _distCut <<" \n" - << "===============================================================================================\n" ; - // ---- introduce a loop over increasing distance cuts for finding the tracks seeds // -> should fix (some of) the problems seen @ 3 TeV with extremely boosted jets // - double dcut = _distCut / _nLoop ; - for(int nloop=1 ; nloop <= _nLoop ; ++nloop){ + double dcut = _distCut / _nLoop; + for (int nloop = 1; nloop <= _nLoop; ++nloop) { - HitDistance dist( nloop * dcut , _cosAlphaCut ) ; + HitDistance dist(nloop * dcut, _cosAlphaCut); - outerRow = maxTPCLayers - 1 ; - - while( outerRow >= _minCluSize ) { //_padRowRange * .5 ) { + outerRow = maxTPCLayers - 1; + + while (outerRow >= _minCluSize) { //_padRowRange * .5 ) { + + HitVec hits; + hits.reserve(nHit); - HitVec hits ; - hits.reserve( nHit ) ; - // add all hits in pad row range to hits - for(int iRow = outerRow ; iRow > ( outerRow - _padRowRange) ; --iRow ) { + for (int iRow = outerRow; iRow > (outerRow - _padRowRange); --iRow) { - if( iRow > -1 ) { + if (iRow > -1) { - streamlog_out( DEBUG0 ) << " copy " << hitsInLayer[ iRow ].size() << " hits for row " << iRow << std::endl ; + streamlog_out(DEBUG0) << " copy " << hitsInLayer[iRow].size() << " hits for row " << iRow << std::endl; - std::copy( hitsInLayer[ iRow ].begin() , hitsInLayer[ iRow ].end() , std::back_inserter( hits ) ) ; - } + std::copy(hitsInLayer[iRow].begin(), hitsInLayer[iRow].end(), std::back_inserter(hits)); + } } - + //----- cluster in given pad row range ----------------------------- - Clusterer::cluster_list sclu ; - sclu.setOwner() ; - - streamlog_out( DEBUG2 ) << " call cluster_sorted with " << hits.size() << " hits " << std::endl ; - - nncl.cluster_sorted( hits.begin(), hits.end() , std::back_inserter( sclu ), dist , _minCluSize ) ; - - const static int merge_seeds = true ; - - if( merge_seeds ) { //----------------------------------------------------------------------- - - // sometimes we have split seed clusters as one link is just above the cut - // -> recluster in all hits of small clusters with 1.2 * cut - float _smallClusterPadRowFraction = 0.9 ; - float _cutIncrease = 1.2 ; - // fixme: could make parameters .... - - HitVec seedhits ; - Clusterer::cluster_list smallclu ; - smallclu.setOwner() ; - split_list( sclu, std::back_inserter(smallclu), ClusterSize( int( _padRowRange * _smallClusterPadRowFraction) ) ) ; - for( Clusterer::cluster_list::iterator sci=smallclu.begin(), end= smallclu.end() ; sci!=end; ++sci ){ - for( Clusterer::cluster_type::iterator ci=(*sci)->begin(), end1= (*sci)->end() ; ci!=end1;++ci ){ - seedhits.push_back( *ci ) ; - } - } - // free hits from bad clusters - std::for_each( smallclu.begin(), smallclu.end(), std::mem_fn( &CluTrack::freeElements ) ) ; - - HitDistance distLarge( nloop * dcut * _cutIncrease ) ; - - nncl.cluster_sorted( seedhits.begin(), seedhits.end() , std::back_inserter( sclu ), distLarge , _minCluSize ) ; + Clusterer::cluster_list sclu; + sclu.setOwner(); + + streamlog_out(DEBUG2) << " call cluster_sorted with " << hits.size() << " hits " << std::endl; + + nncl.cluster_sorted(hits.begin(), hits.end(), std::back_inserter(sclu), dist, _minCluSize); + + const static int merge_seeds = true; + + if (merge_seeds) { //----------------------------------------------------------------------- + + // sometimes we have split seed clusters as one link is just above the cut + // -> recluster in all hits of small clusters with 1.2 * cut + float _smallClusterPadRowFraction = 0.9; + float _cutIncrease = 1.2; + // fixme: could make parameters .... + + HitVec seedhits; + Clusterer::cluster_list smallclu; + smallclu.setOwner(); + split_list(sclu, std::back_inserter(smallclu), ClusterSize(int(_padRowRange * _smallClusterPadRowFraction))); + for (Clusterer::cluster_list::iterator sci = smallclu.begin(), end = smallclu.end(); sci != end; ++sci) { + for (Clusterer::cluster_type::iterator ci = (*sci)->begin(), end1 = (*sci)->end(); ci != end1; ++ci) { + seedhits.push_back(*ci); + } + } + // free hits from bad clusters + std::for_each(smallclu.begin(), smallclu.end(), std::mem_fn(&CluTrack::freeElements)); + + HitDistance distLarge(nloop * dcut * _cutIncrease); + + nncl.cluster_sorted(seedhits.begin(), seedhits.end(), std::back_inserter(sclu), distLarge, _minCluSize); } //------------------------------------------------------------------------------------------ - streamlog_out( DEBUG3 ) << " found " << sclu.size() << " clusters " << std::endl ; + streamlog_out(DEBUG3) << " found " << sclu.size() << " clusters " << std::endl; // try to split up clusters according to multiplicity - int layerWithMultiplicity = _padRowRange - 2 ; // fixme: make parameter - split_multiplicity( sclu , layerWithMultiplicity , 10 ) ; - + int layerWithMultiplicity = _padRowRange - 2; // fixme: make parameter + split_multiplicity(sclu, layerWithMultiplicity, 10); // remove clusters whith too many duplicate hits per pad row - Clusterer::cluster_list bclu ; // bad clusters - bclu.setOwner() ; - split_list( sclu, std::back_inserter(bclu), DuplicatePadRows( maxTPCLayers, _duplicatePadRowFraction ) ) ; - // free hits from bad clusters - std::for_each( bclu.begin(), bclu.end(), std::mem_fn( &CluTrack::freeElements ) ) ; + Clusterer::cluster_list bclu; // bad clusters + bclu.setOwner(); + split_list(sclu, std::back_inserter(bclu), DuplicatePadRows(maxTPCLayers, _duplicatePadRowFraction)); + // free hits from bad clusters + std::for_each(bclu.begin(), bclu.end(), std::mem_fn(&CluTrack::freeElements)); - // ---- now we also need to remove the hits from good cluster seeds from the hitsInLayers: - for( Clusterer::cluster_list::iterator sci=sclu.begin(), end= sclu.end() ; sci!=end; ++sci ){ - for( Clusterer::cluster_type::iterator ci=(*sci)->begin(), end1= (*sci)->end() ; ci!=end1;++ci ){ - - // this is not cheap ... - hitsInLayer[ (*ci)->first->layer ].remove( *ci ) ; - } + for (Clusterer::cluster_list::iterator sci = sclu.begin(), end = sclu.end(); sci != end; ++sci) { + for (Clusterer::cluster_type::iterator ci = (*sci)->begin(), end1 = (*sci)->end(); ci != end1; ++ci) { + + // this is not cheap ... + hitsInLayer[(*ci)->first->layer].remove(*ci); + } } - + // now we have 'clean' seed clusters // Write debug collection with seed clusters: // convert the clusters into tracks and write the resulting tracks into the existing debug collection seedCol. // The conversion is performed by the STL transform() function, the insertion to the end of the // debug track collection is done by creating an STL back_inserter iterator on the LCCollectionVector seedCol - if( writeSeedCluster ) { - std::transform( sclu.begin(), sclu.end(), std::back_inserter( *seedCol ) , converter ) ; + if (writeSeedCluster) { + std::transform(sclu.begin(), sclu.end(), std::back_inserter(*seedCol), converter); } - + // std::transform( sclu.begin(), sclu.end(), std::back_inserter( seedTrks) , fitter ) ; // reduce memory footprint: deal with one KalTest track at a time and delete it, when done - - streamlog_out( DEBUG3 ) << " -------- search seeds with distCut=" << nloop * dcut - << " starting in row " << outerRow - << " with padrow range " << _padRowRange - << " - found " << sclu.size() << " seed clusters " - << std::endl ; - - for( Clusterer::cluster_list::iterator icv = sclu.begin(), end =sclu.end() ; icv != end ; ++ icv ) { - - int nHitsAdded = 0 ; - - // streamlog_out( DEBUG4 ) << " call fitter for seed cluster with " << (*icv)->size() << " hits " << std::endl ; - - MarlinTrk::IMarlinTrack* mTrk = fitter( *icv ) ; - - nHitsAdded += addHitsAndFilter( *icv , hitsInLayer , _dChi2Max, _chi2Cut , _maxStep , zIndex ) ; - - static const bool backward = true ; - nHitsAdded += addHitsAndFilter( *icv , hitsInLayer , _dChi2Max, _chi2Cut , _maxStep , zIndex, backward ) ; - // in order to use smooth for backward extrapolation call with _trksystem - does not work well... - // nHitsAdded += addHitsAndFilter( *icv , hitsInLayer , _dChi2Max, _chi2Cut , _maxStep , zIndex, backward , _trksystem ) ; - - - // drop seed clusters with no hits added - but not in the very forward region... - if( nHitsAdded < 1 && outerRow > 2*_padRowRange ){ //FIXME: make parameter ? - - std::unique_ptr lcioTrk( converter( *icv ) ) ; - - streamlog_out( DEBUG3) << "============= poor seed cluster - no hits added - started from row " << outerRow << "\n" - << *lcioTrk << std::endl ; - - - for( Clusterer::cluster_type::iterator ci=(*icv)->begin(), end1= (*icv)->end() ; ci!=end1; ++ci ) { - hitsInLayer[ (*ci)->first->layer ].push_back( *ci ) ; - } - (*icv)->freeElements() ; - (*icv)->clear() ; - } - - // if( nHitsAdded < 1 ){ - // Track* lcioTrk = converter( *icv ) ; - // streamlog_out( DEBUG5) << " poor seed cluster - no hits added - n hits = " << nHitsAdded << "\n" - // << *lcioTrk << std::endl ; - // delete lcioTrk ; - // } - - if( writeCluTrackSegments ) // ---- store track segments from the first main step ----- - cluCol->addElement( converter( *icv ) ); - - // reset the pointer to the KalTest track - as we are done with this track - (*icv)->ext() = 0 ; - - delete mTrk ; - } + + streamlog_out(DEBUG3) << " -------- search seeds with distCut=" << nloop * dcut << " starting in row " + << outerRow << " with padrow range " << _padRowRange << " - found " << sclu.size() + << " seed clusters " << std::endl; + + for (Clusterer::cluster_list::iterator icv = sclu.begin(), end = sclu.end(); icv != end; ++icv) { + + int nHitsAdded = 0; + + // streamlog_out( DEBUG4 ) << " call fitter for seed cluster with " << (*icv)->size() << " hits " << + //std::endl ; + + MarlinTrk::IMarlinTrack* mTrk = fitter(*icv); + + nHitsAdded += addHitsAndFilter(*icv, hitsInLayer, _dChi2Max, _chi2Cut, _maxStep, zIndex); + + static const bool backward = true; + nHitsAdded += addHitsAndFilter(*icv, hitsInLayer, _dChi2Max, _chi2Cut, _maxStep, zIndex, backward); + // in order to use smooth for backward extrapolation call with _trksystem - does not work well... + // nHitsAdded += addHitsAndFilter( *icv , hitsInLayer , _dChi2Max, _chi2Cut , _maxStep , zIndex, backward , + // _trksystem ) ; + + // drop seed clusters with no hits added - but not in the very forward region... + if (nHitsAdded < 1 && outerRow > 2 * _padRowRange) { // FIXME: make parameter ? + + std::unique_ptr lcioTrk(converter(*icv)); + + streamlog_out(DEBUG3) << "============= poor seed cluster - no hits added - started from row " << outerRow + << "\n" + << *lcioTrk << std::endl; + + for (Clusterer::cluster_type::iterator ci = (*icv)->begin(), end1 = (*icv)->end(); ci != end1; ++ci) { + hitsInLayer[(*ci)->first->layer].push_back(*ci); + } + (*icv)->freeElements(); + (*icv)->clear(); + } + + // if( nHitsAdded < 1 ){ + // Track* lcioTrk = converter( *icv ) ; + // streamlog_out( DEBUG5) << " poor seed cluster - no hits added - n hits = " << nHitsAdded << "\n" + // << *lcioTrk << std::endl ; + // delete lcioTrk ; + // } + + if (writeCluTrackSegments) // ---- store track segments from the first main step ----- + cluCol->addElement(converter(*icv)); + + // reset the pointer to the KalTest track - as we are done with this track + (*icv)->ext() = 0; + + delete mTrk; + } // merge the good clusters to final list - cluList.merge( sclu ) ; + cluList.merge(sclu); + + outerRow -= _padRowRange; - outerRow -= _padRowRange ; - - } //while outerRow > padRowRange - - }// nloop + } // while outerRow > padRowRange + + } // nloop //--------------------------------------------------------------------------------------------------------- - timer.time( t_seedtracks ) ; - - timer.time( t_recluster ) ; - + timer.time(t_seedtracks); + + timer.time(t_recluster); + //=============================================================================================== // do a global reclustering in leftover hits //=============================================================================================== - static const int do_global_reclustering = true ; - if( do_global_reclustering ) { + static const int do_global_reclustering = true; + if (do_global_reclustering) { - outerRow = maxTPCLayers - 1 ; - - int padRangeRecluster = 50 ; // FIXME: make parameter + outerRow = maxTPCLayers - 1; + + int padRangeRecluster = 50; // FIXME: make parameter // define an inner cylinder where we exclude hits from re-clustering: - double zMaxInnerHits = driftLength * .67 ; // FIXME: make parameter - double rhoMaxInnerHits = ( _tpc->rMinReadout + 0.67 * - ( _tpc->rMaxReadout - _tpc->rMinReadout ) ) /dd4hep::mm ; // FIXME: make parameter - - - streamlog_out( DEBUG5 ) << " ===========================================================================\n" - << " recluster in leftover hits - outside a clyinder of : z =" << zMaxInnerHits << " rho = " << rhoMaxInnerHits << "\n" - << " ===========================================================================\n" << std::endl ; - - - while( outerRow > 0 ) { - - - Clusterer::cluster_list loclu ; // leftover clusters - loclu.setOwner() ; - - HitVec hits ; - - int minRow = ( ( outerRow - padRangeRecluster ) > -1 ? ( outerRow - padRangeRecluster ) : -1 ) ; - + double zMaxInnerHits = driftLength * .67; // FIXME: make parameter + double rhoMaxInnerHits = + (_tpc->rMinReadout + 0.67 * (_tpc->rMaxReadout - _tpc->rMinReadout)) / dd4hep::mm; // FIXME: make parameter + + streamlog_out(DEBUG5) << " ===========================================================================\n" + << " recluster in leftover hits - outside a clyinder of : z =" << zMaxInnerHits + << " rho = " << rhoMaxInnerHits << "\n" + << " ===========================================================================\n" + << std::endl; + + while (outerRow > 0) { + + Clusterer::cluster_list loclu; // leftover clusters + loclu.setOwner(); + + HitVec hits; + + int minRow = ((outerRow - padRangeRecluster) > -1 ? (outerRow - padRangeRecluster) : -1); + // add all hits in pad row range to hits - for(int iRow = outerRow ; iRow > minRow ; --iRow ) { - - streamlog_out( DEBUG ) << " hit candidates in row " << iRow << " : " << hitsInLayer[ iRow ].size() << std::endl ; - - for( HitList::iterator hlIt=hitsInLayer[ iRow ].begin() , end = hitsInLayer[ iRow ].end() ; hlIt != end ; ++hlIt ) { - streamlog_out( DEBUG ) << " hit candidate for reclustering " << (*hlIt)->first - << " ( std::abs( (*hlIt)->first->pos.z() ) > zMaxInnerHits || (*hlIt)->first->pos.rho() > rhoMaxInnerHits ) " - << ( std::abs( (*hlIt)->first->pos.z() ) > zMaxInnerHits || (*hlIt)->first->pos.rho() > rhoMaxInnerHits ) - << std::endl ; - - if( std::abs( (*hlIt)->first->pos.z() ) > zMaxInnerHits || (*hlIt)->first->pos.rho() > rhoMaxInnerHits ) { - hits.push_back( *hlIt ) ; - } - } + for (int iRow = outerRow; iRow > minRow; --iRow) { + + streamlog_out(DEBUG) << " hit candidates in row " << iRow << " : " << hitsInLayer[iRow].size() + << std::endl; + + for (HitList::iterator hlIt = hitsInLayer[iRow].begin(), end = hitsInLayer[iRow].end(); hlIt != end; ++hlIt) { + streamlog_out(DEBUG) << " hit candidate for reclustering " << (*hlIt)->first + << " ( std::abs( (*hlIt)->first->pos.z() ) > zMaxInnerHits || " + "(*hlIt)->first->pos.rho() > rhoMaxInnerHits ) " + << (std::abs((*hlIt)->first->pos.z()) > zMaxInnerHits || + (*hlIt)->first->pos.rho() > rhoMaxInnerHits) + << std::endl; + + if (std::abs((*hlIt)->first->pos.z()) > zMaxInnerHits || (*hlIt)->first->pos.rho() > rhoMaxInnerHits) { + hits.push_back(*hlIt); + } + } } - - - HitDistance distSmall( _distCut ) ; - nncl.cluster( hits.begin(), hits.end() , std::back_inserter( loclu ), distSmall , _minCluSize ) ; - - streamlog_out( DEBUG ) << " reclusterd in the range : " << outerRow << " - " << minRow - << " found " << loclu.size() << " clusters " - << std::endl ; - - // Write debug collection using STL transform() function on the clusters - if( writeLeftoverClusters ) - std::transform( loclu.begin(), loclu.end(), std::back_inserter( *locCol ) , converter ) ; - - + + HitDistance distSmall(_distCut); + nncl.cluster(hits.begin(), hits.end(), std::back_inserter(loclu), distSmall, _minCluSize); + + streamlog_out(DEBUG) << " reclusterd in the range : " << outerRow << " - " << minRow << " found " + << loclu.size() << " clusters " << std::endl; + + // Write debug collection using STL transform() function on the clusters + if (writeLeftoverClusters) + std::transform(loclu.begin(), loclu.end(), std::back_inserter(*locCol), converter); + // timer.time( t_recluster ) ; - + //=============================================================================================== // now we split the clusters based on their hit multiplicities //=============================================================================================== - - + // _dChi2Max = 5. * _dChi2Max ; //FIXME !!!!!!!!! - - for( Clusterer::cluster_list::iterator it= loclu.begin(), end= loclu.end() ; it != end ; ++it ){ - - CluTrack* clu = *it ; - - streamlog_out( DEBUG5 ) << " **** left over cluster with size : " << clu->size() << std::endl ; - - std::vector mult(8) ; - // get hit multiplicities up to 6 ( 7 means 7 or higher ) - getHitMultiplicities( clu , mult ) ; - - streamlog_out( DEBUG3 ) << " **** left over cluster with hit multiplicities: \n" ; - for( unsigned i=0,n=mult.size() ; i= _minLayerFractionWithMultiplicity && mult[5] > _minLayerNumberWithMultiplicity ) { - - Clusterer::cluster_list reclu ; // reclustered leftover clusters - reclu.setOwner() ; - - create_n_clusters( *clu , reclu , 5 ) ; - - std::transform( reclu.begin(), reclu.end(), std::back_inserter( seedTrks) , fitter ) ; - - for( Clusterer::cluster_list::iterator ir= reclu.begin(), end1= reclu.end() ; ir != end1 ; ++ir ){ - - streamlog_out( DEBUG5 ) << " extending mult-5 clustre of length " << (*ir)->size() << std::endl ; - - addHitsAndFilter( *ir , hitsInLayer , _dChi2Max, _chi2Cut , _maxStep , zIndex) ; - static const bool backward = true ; - addHitsAndFilter( *ir , hitsInLayer , _dChi2Max, _chi2Cut , _maxStep , zIndex, backward ) ; - } - - cluList.merge( reclu ) ; - } - - else if( float( mult[4]) / mult[0] >= _minLayerFractionWithMultiplicity && mult[4] > _minLayerNumberWithMultiplicity ) { - - Clusterer::cluster_list reclu ; // reclustered leftover clusters - reclu.setOwner() ; - - create_n_clusters( *clu , reclu , 4 ) ; - - std::transform( reclu.begin(), reclu.end(), std::back_inserter( seedTrks) , fitter ) ; - - for( Clusterer::cluster_list::iterator ir= reclu.begin(), end1= reclu.end() ; ir != end1 ; ++ir ){ - - streamlog_out( DEBUG5 ) << " extending mult-4 clustre of length " << (*ir)->size() << std::endl ; - - addHitsAndFilter( *ir , hitsInLayer , _dChi2Max, _chi2Cut , _maxStep , zIndex) ; - static const bool backward = true ; - addHitsAndFilter( *ir , hitsInLayer , _dChi2Max, _chi2Cut , _maxStep , zIndex, backward ) ; - } - - cluList.merge( reclu ) ; - } - - else if( float( mult[3]) / mult[0] >= _minLayerFractionWithMultiplicity && mult[3] > _minLayerNumberWithMultiplicity ) { - - Clusterer::cluster_list reclu ; // reclustered leftover clusters - reclu.setOwner() ; - - create_three_clusters( *clu , reclu ) ; - - std::transform( reclu.begin(), reclu.end(), std::back_inserter( seedTrks) , fitter ) ; - - for( Clusterer::cluster_list::iterator ir= reclu.begin(), end1= reclu.end() ; ir != end1 ; ++ir ){ - - streamlog_out( DEBUG5 ) << " extending triplet clustre of length " << (*ir)->size() << std::endl ; - - addHitsAndFilter( *ir , hitsInLayer , _dChi2Max, _chi2Cut , _maxStep , zIndex) ; - static const bool backward = true ; - addHitsAndFilter( *ir , hitsInLayer , _dChi2Max, _chi2Cut , _maxStep , zIndex, backward ) ; - } - - cluList.merge( reclu ) ; - } - - else if( float( mult[2]) / mult[0] >= _minLayerFractionWithMultiplicity && mult[2] > _minLayerNumberWithMultiplicity ) { - - Clusterer::cluster_list reclu ; // reclustered leftover clusters - reclu.setOwner() ; - - create_two_clusters( *clu , reclu ) ; - - std::transform( reclu.begin(), reclu.end(), std::back_inserter( seedTrks) , fitter ) ; - - for( Clusterer::cluster_list::iterator ir= reclu.begin(), end1= reclu.end() ; ir != end1 ; ++ir ){ - - streamlog_out( DEBUG5 ) << " extending doublet clustre of length " << (*ir)->size() << std::endl ; - - addHitsAndFilter( *ir , hitsInLayer , _dChi2Max, _chi2Cut , _maxStep , zIndex) ; - static const bool backward = true ; - addHitsAndFilter( *ir , hitsInLayer , _dChi2Max, _chi2Cut , _maxStep , zIndex, backward ) ; - } - - cluList.merge( reclu ) ; - - } - else if( float( mult[1]) / mult[0] >= _minLayerFractionWithMultiplicity && mult[1] > _minLayerNumberWithMultiplicity ) { - - - seedTrks.push_back( fitter( *it ) ); - - addHitsAndFilter( *it , hitsInLayer , _dChi2Max, _chi2Cut , _maxStep , zIndex) ; - static const bool backward = true ; - addHitsAndFilter( *it , hitsInLayer , _dChi2Max, _chi2Cut , _maxStep , zIndex, backward ) ; - - cluList.push_back( *it ) ; - - it = loclu.erase( it ) ; - --it ; // erase returns iterator to next element - - } else { - - // discard cluster and free hits - clu->freeElements() ; - } - - } - - outerRow -= padRangeRecluster ; + for (Clusterer::cluster_list::iterator it = loclu.begin(), end = loclu.end(); it != end; ++it) { + + CluTrack* clu = *it; + + streamlog_out(DEBUG5) << " **** left over cluster with size : " << clu->size() << std::endl; + + std::vector mult(8); + // get hit multiplicities up to 6 ( 7 means 7 or higher ) + getHitMultiplicities(clu, mult); + + streamlog_out(DEBUG3) << " **** left over cluster with hit multiplicities: \n"; + for (unsigned i = 0, n = mult.size(); i < n; ++i) { + streamlog_out(DEBUG3) << " m[" << i << "] = " << mult[i] << "\n"; + } + + if (float(mult[5]) / mult[0] >= _minLayerFractionWithMultiplicity && + mult[5] > _minLayerNumberWithMultiplicity) { + + Clusterer::cluster_list reclu; // reclustered leftover clusters + reclu.setOwner(); + + create_n_clusters(*clu, reclu, 5); + + std::transform(reclu.begin(), reclu.end(), std::back_inserter(seedTrks), fitter); + + for (Clusterer::cluster_list::iterator ir = reclu.begin(), end1 = reclu.end(); ir != end1; ++ir) { + + streamlog_out(DEBUG5) << " extending mult-5 clustre of length " << (*ir)->size() << std::endl; + + addHitsAndFilter(*ir, hitsInLayer, _dChi2Max, _chi2Cut, _maxStep, zIndex); + static const bool backward = true; + addHitsAndFilter(*ir, hitsInLayer, _dChi2Max, _chi2Cut, _maxStep, zIndex, backward); + } + + cluList.merge(reclu); + } + + else if (float(mult[4]) / mult[0] >= _minLayerFractionWithMultiplicity && + mult[4] > _minLayerNumberWithMultiplicity) { + + Clusterer::cluster_list reclu; // reclustered leftover clusters + reclu.setOwner(); + + create_n_clusters(*clu, reclu, 4); + + std::transform(reclu.begin(), reclu.end(), std::back_inserter(seedTrks), fitter); + + for (Clusterer::cluster_list::iterator ir = reclu.begin(), end1 = reclu.end(); ir != end1; ++ir) { + streamlog_out(DEBUG5) << " extending mult-4 clustre of length " << (*ir)->size() << std::endl; + + addHitsAndFilter(*ir, hitsInLayer, _dChi2Max, _chi2Cut, _maxStep, zIndex); + static const bool backward = true; + addHitsAndFilter(*ir, hitsInLayer, _dChi2Max, _chi2Cut, _maxStep, zIndex, backward); + } + + cluList.merge(reclu); + } + + else if (float(mult[3]) / mult[0] >= _minLayerFractionWithMultiplicity && + mult[3] > _minLayerNumberWithMultiplicity) { + + Clusterer::cluster_list reclu; // reclustered leftover clusters + reclu.setOwner(); + + create_three_clusters(*clu, reclu); + + std::transform(reclu.begin(), reclu.end(), std::back_inserter(seedTrks), fitter); + + for (Clusterer::cluster_list::iterator ir = reclu.begin(), end1 = reclu.end(); ir != end1; ++ir) { + + streamlog_out(DEBUG5) << " extending triplet clustre of length " << (*ir)->size() << std::endl; + + addHitsAndFilter(*ir, hitsInLayer, _dChi2Max, _chi2Cut, _maxStep, zIndex); + static const bool backward = true; + addHitsAndFilter(*ir, hitsInLayer, _dChi2Max, _chi2Cut, _maxStep, zIndex, backward); + } + + cluList.merge(reclu); + } + + else if (float(mult[2]) / mult[0] >= _minLayerFractionWithMultiplicity && + mult[2] > _minLayerNumberWithMultiplicity) { + + Clusterer::cluster_list reclu; // reclustered leftover clusters + reclu.setOwner(); + + create_two_clusters(*clu, reclu); + + std::transform(reclu.begin(), reclu.end(), std::back_inserter(seedTrks), fitter); + + for (Clusterer::cluster_list::iterator ir = reclu.begin(), end1 = reclu.end(); ir != end1; ++ir) { + + streamlog_out(DEBUG5) << " extending doublet clustre of length " << (*ir)->size() << std::endl; + + addHitsAndFilter(*ir, hitsInLayer, _dChi2Max, _chi2Cut, _maxStep, zIndex); + static const bool backward = true; + addHitsAndFilter(*ir, hitsInLayer, _dChi2Max, _chi2Cut, _maxStep, zIndex, backward); + } + + cluList.merge(reclu); + + } else if (float(mult[1]) / mult[0] >= _minLayerFractionWithMultiplicity && + mult[1] > _minLayerNumberWithMultiplicity) { + + seedTrks.push_back(fitter(*it)); + + addHitsAndFilter(*it, hitsInLayer, _dChi2Max, _chi2Cut, _maxStep, zIndex); + static const bool backward = true; + addHitsAndFilter(*it, hitsInLayer, _dChi2Max, _chi2Cut, _maxStep, zIndex, backward); + + cluList.push_back(*it); + + it = loclu.erase(it); + --it; // erase returns iterator to next element + + } else { + + // discard cluster and free hits + clu->freeElements(); + } + } + + outerRow -= padRangeRecluster; } } //======================================================================================================================= - // try again to gobble up hits at the ends .... - does not work right now, as there are no fits for the clusters.... + // try again to gobble up hits at the ends .... - does not work right now, as there are no fits for the + // clusters.... //======================================================================================================================= - // streamlog_out( DEBUG5 ) << " =========== gobble up leftover hits at the ends for " << cluList.size() << " clusters " << std::endl ; - + // streamlog_out( DEBUG5 ) << " =========== gobble up leftover hits at the ends for " << cluList.size() << " + // clusters " << std::endl ; + // for( Clusterer::cluster_list::iterator icv = cluList.begin() , end = cluList.end() ; icv != end ; ++ icv ) { - + // if( (*icv)->empty() ) continue ; - + // int nH = 0 ; - // nH += addHitsAndFilter( *icv , hitsInLayer , _dChi2Max, _chi2Cut , _maxStep , zIndex) ; + // nH += addHitsAndFilter( *icv , hitsInLayer , _dChi2Max, _chi2Cut , _maxStep , zIndex) ; // static const bool backward = true ; - // nH += addHitsAndFilter( *icv , hitsInLayer , _dChi2Max, _chi2Cut , _maxStep , zIndex, backward ) ; + // nH += addHitsAndFilter( *icv , hitsInLayer , _dChi2Max, _chi2Cut , _maxStep , zIndex, backward ) ; - // streamlog_out( DEBUG3 ) << " added " << nH << " leftover hits to cluster " << *icv << std::endl ; + // streamlog_out( DEBUG3 ) << " added " << nH << " leftover hits to cluster " << *icv << std::endl ; // } - - timer.time( t_split ) ; + + timer.time(t_split); //=============================================================================================== - // now refit the tracks + // now refit the tracks //=============================================================================================== - streamlog_out( DEBUG5 ) << " =========== refitting final " << cluList.size() << " track segments " << std::endl ; + streamlog_out(DEBUG5) << " =========== refitting final " << cluList.size() << " track segments " << std::endl; //---- refit cluster tracks individually to save memory ( KalTest tracks have ~1MByte each) - IMarlinTrkFitter fit(_trksystem, _dChi2Max) ; // fixme: do we need a different chi2 max here ???? + IMarlinTrkFitter fit(_trksystem, _dChi2Max); // fixme: do we need a different chi2 max here ???? - for( Clusterer::cluster_list::iterator icv = cluList.begin() , end = cluList.end() ; icv != end ; ++ icv ) { + for (Clusterer::cluster_list::iterator icv = cluList.begin(), end = cluList.end(); icv != end; ++icv) { - if( (*icv)->empty() ) - continue ; + if ((*icv)->empty()) + continue; - MarlinTrk::IMarlinTrack* trk = fit( *icv ) ; - trk->smooth() ; - Track* lcioTrk = converter( *icv ) ; - tsCol->push_back( lcioTrk ) ; - lcioTrk->ext() = 0 ; - delete trk ; + MarlinTrk::IMarlinTrack* trk = fit(*icv); + trk->smooth(); + Track* lcioTrk = converter(*icv); + tsCol->push_back(lcioTrk); + lcioTrk->ext() = 0; + delete trk; } - - timer.time( t_finalfit) ; - + + timer.time(t_finalfit); + //=============================================================================================== - // optionally create collections of used and unused TPC hits + // optionally create collections of used and unused TPC hits //=============================================================================================== - - if( _createDebugCollections ) { - LCCollectionVec* usedHits = new LCCollectionVec( LCIO::TRACKERHIT ) ; ; - LCCollectionVec* unUsedHits = new LCCollectionVec( LCIO::TRACKERHIT ) ; ; - evt->addCollection( usedHits , "ClupatraUsedTPCHits" ) ; - evt->addCollection( unUsedHits , "ClupatraUnUsedTPCHits" ) ; - usedHits->setSubset() ; - unUsedHits->setSubset() ; - usedHits->reserve( nncluHits.size() ) ; - unUsedHits->reserve( nncluHits.size() ) ; - - for( HitVec::iterator it = nncluHits.begin(), end = nncluHits.end(); it!=end;++it ){ - - if( (*it)->second != 0 ){ usedHits->push_back( (*it)->first->lcioHit ) ; - } else { unUsedHits->push_back( (*it)->first->lcioHit ) ; + + if (_createDebugCollections) { + LCCollectionVec* usedHits = new LCCollectionVec(LCIO::TRACKERHIT); + ; + LCCollectionVec* unUsedHits = new LCCollectionVec(LCIO::TRACKERHIT); + ; + evt->addCollection(usedHits, "ClupatraUsedTPCHits"); + evt->addCollection(unUsedHits, "ClupatraUnUsedTPCHits"); + usedHits->setSubset(); + unUsedHits->setSubset(); + usedHits->reserve(nncluHits.size()); + unUsedHits->reserve(nncluHits.size()); + + for (HitVec::iterator it = nncluHits.begin(), end = nncluHits.end(); it != end; ++it) { + + if ((*it)->second != 0) { + usedHits->push_back((*it)->first->lcioHit); + } else { + unUsedHits->push_back((*it)->first->lcioHit); } } } - - //=============================================================================================== // compute some track parameters for possible merging //=============================================================================================== - - typedef nnclu::NNClusterer TrackClusterer ; - TrackClusterer nntrkclu ; - MakeLCIOElement trkMakeElement ; - - for( int i=0,N=tsCol->getNumberOfElements() ; igetElementAt(i) ) ; + + typedef nnclu::NNClusterer TrackClusterer; + TrackClusterer nntrkclu; + MakeLCIOElement trkMakeElement; + + for (int i = 0, N = tsCol->getNumberOfElements(); i < N; ++i) { + + computeTrackInfo((Track*)tsCol->getElementAt(i)); } - + //=============================================================================================== - // merge split segements + // merge split segements //=============================================================================================== - - - static const int merge_split_segments = true ; - - if( merge_split_segments ) { - - for(unsigned l=0 ; l < 2 ; ++l ) { // do this twice .... - - streamlog_out( DEBUG5 ) << "===============================================================================================\n" - << " merge split segments\n" - << "===============================================================================================\n" ; - - int nMax = tsCol->size() ; - - TrackClusterer::element_vector incSegVec ; - incSegVec.setOwner() ; - incSegVec.reserve( nMax ) ; - TrackClusterer::cluster_vector incSegCluVec ; - incSegCluVec.setOwner() ; - - for( int i=0,N=tsCol->getNumberOfElements() ; igetElementAt(i) ; - - const TrackInfoStruct* ti = trk->ext() ; - - bool isIncompleteSegment = !ti->isCurler && ( !ti->startsInner || ( !ti->isCentral && !ti->isForward ) ) ; - - std::bitset<32> type = trk->getType() ; - - - if( isIncompleteSegment && ! type[ ILDTrackTypeBit::SEGMENT ]){ - - incSegVec.push_back( trkMakeElement( trk ) ) ; - - if( writeCluTrackSegments ) incSegCol->addElement( trk ) ; - } + + static const int merge_split_segments = true; + + if (merge_split_segments) { + + for (unsigned l = 0; l < 2; ++l) { // do this twice .... + + streamlog_out(DEBUG5) + << "===============================================================================================\n" + << " merge split segments\n" + << "===============================================================================================\n"; + + int nMax = tsCol->size(); + + TrackClusterer::element_vector incSegVec; + incSegVec.setOwner(); + incSegVec.reserve(nMax); + TrackClusterer::cluster_vector incSegCluVec; + incSegCluVec.setOwner(); + + for (int i = 0, N = tsCol->getNumberOfElements(); i < N; ++i) { + + TrackImpl* trk = (TrackImpl*)tsCol->getElementAt(i); + + const TrackInfoStruct* ti = trk->ext(); + + bool isIncompleteSegment = !ti->isCurler && (!ti->startsInner || (!ti->isCentral && !ti->isForward)); + + std::bitset<32> type = trk->getType(); + + if (isIncompleteSegment && !type[ILDTrackTypeBit::SEGMENT]) { + + incSegVec.push_back(trkMakeElement(trk)); + + if (writeCluTrackSegments) + incSegCol->addElement(trk); + } } - - - TrackSegmentMerger trkMerge( _dChi2Max , _trksystem , _bfield ) ; - - nntrkclu.cluster( incSegVec.begin() , incSegVec.end() , std::back_inserter( incSegCluVec ), trkMerge , 2 ) ; - - streamlog_out( DEBUG4 ) << " ===== merged track segments - # cluster: " << incSegCluVec.size() - << " from " << incSegVec.size() << " incomplete track segments " << " ============================== " << std::endl ; - - for( TrackClusterer::cluster_vector::iterator it= incSegCluVec.begin() ; it != incSegCluVec.end() ; ++it) { - - streamlog_out( DEBUG4 ) << lcio::header() << std::endl ; - - TrackClusterer::cluster_type* incSegClu = *it ; - - std::vector mergedTrk ; - - // vector to collect hits from segments - // std::vector< TrackerHit* > hits ; - // hits.reserve( 1024 ) ; - // IMPL::TrackImpl* track = new IMPL::TrackImpl ; - // tsCol->addElement( track ) ; - - CluTrack hits ; - - for( TrackClusterer::cluster_type::iterator itC = incSegClu->begin() ; itC != incSegClu->end() ; ++ itC ){ - - streamlog_out( DEBUG3 ) << lcshort( (*itC)->first ) << std::endl ; - - TrackImpl* trk = (TrackImpl*) (*itC)->first ; - - mergedTrk.push_back( trk ) ; - - // std::copy( trk->getTrackerHits().begin() , trk->getTrackerHits().end() , std::back_inserter( hits ) ) ; - - for( lcio::TrackerHitVec::const_iterator it1 = trk->getTrackerHits().begin() , END = trk->getTrackerHits().end() ; it1 != END ; ++it1 ){ - hits.addElement( (*it1)->ext() ) ; - } - - // flag the segments so they can be ignored for final list - trk->setTypeBit( ILDTrackTypeBit::SEGMENT ) ; - - // add old segments to new track - // track->addTrack( trk ) ; - } - - // MarlinTrk::IMarlinTrack* mTrk = _trksystem->createTrack(); - // EVENT::FloatVec icov( 15 ) ; - // icov[ 0] = 1e2 ; - // icov[ 2] = 1e2 ; - // icov[ 5] = 1e2 ; - // icov[ 9] = 1e2 ; - // icov[14] = 1e2 ; - // int result = createFinalisedLCIOTrack( mTrk, hits, track, !MarlinTrk::IMarlinTrack::backward, icov, _bfield, _dChi2Max ) ; - // //int result = createFinalisedLCIOTrack( mTrk, hits, track, ! MarlinTrk::IMarlinTrack::backward, icov, _bfield, _dChi2Max ) ; - // // ??? - - MarlinTrk::IMarlinTrack* mTrk = fit( &hits ) ; - mTrk->smooth() ; - Track* track = converter( &hits ) ; - tsCol->push_back( track ) ; - track->ext() = 0 ; - delete mTrk ; - computeTrackInfo( track ) ; - - streamlog_out( DEBUG4 ) << " ****** created new track : " << " : " << lcshort( (Track*) track ) << std::endl ; + TrackSegmentMerger trkMerge(_dChi2Max, _trksystem, _bfield); + + nntrkclu.cluster(incSegVec.begin(), incSegVec.end(), std::back_inserter(incSegCluVec), trkMerge, 2); + + streamlog_out(DEBUG4) << " ===== merged track segments - # cluster: " << incSegCluVec.size() << " from " + << incSegVec.size() << " incomplete track segments " + << " ============================== " << std::endl; + + for (TrackClusterer::cluster_vector::iterator it = incSegCluVec.begin(); it != incSegCluVec.end(); ++it) { + + streamlog_out(DEBUG4) << lcio::header() << std::endl; + + TrackClusterer::cluster_type* incSegClu = *it; + + std::vector mergedTrk; + + // vector to collect hits from segments + // std::vector< TrackerHit* > hits ; + // hits.reserve( 1024 ) ; + // IMPL::TrackImpl* track = new IMPL::TrackImpl ; + // tsCol->addElement( track ) ; + + CluTrack hits; + + for (TrackClusterer::cluster_type::iterator itC = incSegClu->begin(); itC != incSegClu->end(); ++itC) { + + streamlog_out(DEBUG3) << lcshort((*itC)->first) << std::endl; + + TrackImpl* trk = (TrackImpl*)(*itC)->first; + + mergedTrk.push_back(trk); + + // std::copy( trk->getTrackerHits().begin() , trk->getTrackerHits().end() , std::back_inserter( hits ) ) ; + + for (lcio::TrackerHitVec::const_iterator it1 = trk->getTrackerHits().begin(), + END = trk->getTrackerHits().end(); + it1 != END; ++it1) { + hits.addElement((*it1)->ext()); + } + + // flag the segments so they can be ignored for final list + trk->setTypeBit(ILDTrackTypeBit::SEGMENT); + + // add old segments to new track + // track->addTrack( trk ) ; + } + + // MarlinTrk::IMarlinTrack* mTrk = _trksystem->createTrack(); + // EVENT::FloatVec icov( 15 ) ; + // icov[ 0] = 1e2 ; + // icov[ 2] = 1e2 ; + // icov[ 5] = 1e2 ; + // icov[ 9] = 1e2 ; + // icov[14] = 1e2 ; + // int result = createFinalisedLCIOTrack( mTrk, hits, track, !MarlinTrk::IMarlinTrack::backward, icov, _bfield, + // _dChi2Max ) ; + // //int result = createFinalisedLCIOTrack( mTrk, hits, track, ! MarlinTrk::IMarlinTrack::backward, icov, + // _bfield, _dChi2Max ) ; + // // ??? + + MarlinTrk::IMarlinTrack* mTrk = fit(&hits); + mTrk->smooth(); + Track* track = converter(&hits); + tsCol->push_back(track); + track->ext() = 0; + delete mTrk; + computeTrackInfo(track); + + streamlog_out(DEBUG4) << " ****** created new track : " << " : " << lcshort((Track*)track) << std::endl; } - }// loop over l + } // loop over l } //=============================================================================================== - // merge curler segments + // merge curler segments //=============================================================================================== - - - static const int merge_curler_segments = true ; - - if( merge_curler_segments ) { + static const int merge_curler_segments = true; + + if (merge_curler_segments) { - streamlog_out( DEBUG5 ) << "===============================================================================================\n" - << " merge curler segments\n" - << "===============================================================================================\n" ; - - int nMax = tsCol->size() ; + streamlog_out(DEBUG5) + << "===============================================================================================\n" + << " merge curler segments\n" + << "===============================================================================================\n"; - TrackClusterer::element_vector curSegVec ; - curSegVec.setOwner() ; - curSegVec.reserve( nMax ) ; - TrackClusterer::cluster_vector curSegCluVec ; - curSegCluVec.setOwner() ; + int nMax = tsCol->size(); + TrackClusterer::element_vector curSegVec; + curSegVec.setOwner(); + curSegVec.reserve(nMax); + TrackClusterer::cluster_vector curSegCluVec; + curSegCluVec.setOwner(); // for( int i=0,N=tsCol->getNumberOfElements() ; igetNumberOfElements()-1 ; i>=0 ; --i ){ - - TrackImpl* trk = (TrackImpl*) tsCol->getElementAt(i) ; - + for (int i = tsCol->getNumberOfElements() - 1; i >= 0; --i) { + + TrackImpl* trk = (TrackImpl*)tsCol->getElementAt(i); + + std::bitset<32> type = trk->getType(); + + if (type[ILDTrackTypeBit::SEGMENT]) + continue; // ignore previously merged track segments - std::bitset<32> type = trk->getType() ; + const TrackInfoStruct* ti = trk->ext(); - if( type[ ILDTrackTypeBit::SEGMENT ] ) - continue ; // ignore previously merged track segments + bool isCompleteTrack = ti && !ti->isCurler && (ti->startsInner && (ti->isCentral || ti->isForward)); - const TrackInfoStruct* ti = trk->ext() ; - - bool isCompleteTrack = ti && !ti->isCurler && ( ti->startsInner && ( ti->isCentral || ti->isForward ) ); - - if( !isCompleteTrack ){ - - curSegVec.push_back( trkMakeElement( trk ) ) ; - - if( writeCluTrackSegments ) curSegCol->addElement( trk ) ; - - } else { // ... is not a curler -> add a copy to the final tracks collection - + if (!isCompleteTrack) { - if( copyTrackSegments) { + curSegVec.push_back(trkMakeElement(trk)); - outCol->addElement( new TrackImpl( *trk ) ) ; + if (writeCluTrackSegments) + curSegCol->addElement(trk); - }else{ + } else { // ... is not a curler -> add a copy to the final tracks collection - outCol->addElement( trk ) ; + if (copyTrackSegments) { - tsCol->removeElementAt( i ) ; - } + outCol->addElement(new TrackImpl(*trk)); - if( writeCluTrackSegments ) finSegCol->addElement( trk ) ; + } else { + + outCol->addElement(trk); + + tsCol->removeElementAt(i); + } + + if (writeCluTrackSegments) + finSegCol->addElement(trk); } } - + //====================================================================================================== + TrackCircleDistance trkMerge(0.1); + + nntrkclu.cluster(curSegVec.begin(), curSegVec.end(), std::back_inserter(curSegCluVec), trkMerge, 2); + + streamlog_out(DEBUG4) << " ===== merged tracks - # cluster: " << curSegCluVec.size() << " from " << tsCol->size() + << " track segments " << " ============================== " << std::endl; + + for (TrackClusterer::cluster_vector::iterator it = curSegCluVec.begin(); it != curSegCluVec.end(); ++it) { - TrackCircleDistance trkMerge( 0.1 ) ; + streamlog_out(DEBUG4) << lcio::header() << std::endl; - nntrkclu.cluster( curSegVec.begin() , curSegVec.end() , std::back_inserter( curSegCluVec ), trkMerge , 2 ) ; + TrackClusterer::cluster_type* curSegClu = *it; + std::list mergedTrk; - streamlog_out( DEBUG4 ) << " ===== merged tracks - # cluster: " << curSegCluVec.size() - << " from " << tsCol->size() << " track segments " << " ============================== " << std::endl ; - - for( TrackClusterer::cluster_vector::iterator it= curSegCluVec.begin() ; it != curSegCluVec.end() ; ++it) { - - streamlog_out( DEBUG4 ) << lcio::header() << std::endl ; - - TrackClusterer::cluster_type* curSegClu = *it ; + for (TrackClusterer::cluster_type::iterator itC = curSegClu->begin(); itC != curSegClu->end(); ++itC) { - std::list mergedTrk ; + streamlog_out(DEBUG4) << lcshort((*itC)->first) << std::endl; - for( TrackClusterer::cluster_type::iterator itC = curSegClu->begin() ; itC != curSegClu->end() ; ++ itC ){ - - streamlog_out( DEBUG4 ) << lcshort( (*itC)->first ) << std::endl ; - - mergedTrk.push_back( (*itC)->first ) ; + mergedTrk.push_back((*itC)->first); } - - mergedTrk.sort( TrackZSort() ) ; - + mergedTrk.sort(TrackZSort()); + //================================================================================ - - if( copyTrackSegments) { - - // ====== create a new LCIO track for the merged cluster ... - TrackImpl* trk = new TrackImpl ; - - trk->setTypeBit( lcio::ILDDetID::TPC ) ; - - // == and copy all the hits - unsigned hitCount = 0 ; - for( std::list::iterator itML = mergedTrk.begin() ; itML != mergedTrk.end() ; ++ itML ){ - - const TrackerHitVec& hV = (*itML)->getTrackerHits() ; - for(unsigned i=0, n=hV.size() ; iaddHit( hV[i] ) ; - } - hitCount += hV.size() ; - - // add a pointer to the original track segment - trk->addTrack( *itML ) ; - } - - // take track states from first and last track : - Track* firstTrk = mergedTrk.front() ; - Track* lastTrk = mergedTrk.back() ; - - const TrackState* ts = 0 ; - ts = firstTrk->getTrackState( lcio::TrackState::AtIP ) ; - if( ts ) trk->addTrackState( new TrackStateImpl( *ts ) ) ; - - ts = firstTrk->getTrackState( lcio::TrackState::AtFirstHit ) ; - if( ts ) trk->addTrackState( new TrackStateImpl( *ts ) ) ; - - ts = lastTrk->getTrackState( lcio::TrackState::AtLastHit ) ; - if( ts ) trk->addTrackState( new TrackStateImpl( *ts ) ) ; - - ts = lastTrk->getTrackState( lcio::TrackState::AtCalorimeter ) ; - if( ts ) trk->addTrackState( new TrackStateImpl( *ts ) ) ; - - - trk->ext() = firstTrk->ext() ; - - int hitsInFit = firstTrk->getSubdetectorHitNumbers()[ 2 * ILDDetID::TPC - 1 ] ; - trk->setChi2( firstTrk->getChi2() ) ; - trk->setNdf( firstTrk->getNdf() ) ; - trk->setdEdx( firstTrk->getdEdx() ) ; - trk->setdEdxError(firstTrk->getdEdxError()) ; - - trk->subdetectorHitNumbers().resize( 2 * ILDDetID::ETD ) ; - trk->subdetectorHitNumbers()[ 2 * ILDDetID::TPC - 2 ] = hitsInFit ; - trk->subdetectorHitNumbers()[ 2 * ILDDetID::TPC - 1 ] = hitCount ; - - ts = trk->getTrackState( lcio::TrackState::AtFirstHit ) ; - double RMin = ( ts ? - sqrt( ts->getReferencePoint()[0] * ts->getReferencePoint()[0] - + ts->getReferencePoint()[1] * ts->getReferencePoint()[1] ) - : 0.0 ) ; - trk->setRadiusOfInnermostHit( RMin ) ; - - - - streamlog_out( DEBUG2 ) << " create new merged track from bestTrack parameters - ptr to MarlinTrk : " << trk->ext() - << " with subdetector hit numbers : " << trk->subdetectorHitNumbers()[0 ] << " , " << trk->subdetectorHitNumbers()[1] - << std::endl ; - - - outCol->addElement( trk ) ; + if (copyTrackSegments) { + + // ====== create a new LCIO track for the merged cluster ... + TrackImpl* trk = new TrackImpl; + + trk->setTypeBit(lcio::ILDDetID::TPC); + + // == and copy all the hits + unsigned hitCount = 0; + for (std::list::iterator itML = mergedTrk.begin(); itML != mergedTrk.end(); ++itML) { + + const TrackerHitVec& hV = (*itML)->getTrackerHits(); + for (unsigned i = 0, n = hV.size(); i < n; ++i) { + + trk->addHit(hV[i]); + } + hitCount += hV.size(); + + // add a pointer to the original track segment + trk->addTrack(*itML); + } + + // take track states from first and last track : + Track* firstTrk = mergedTrk.front(); + Track* lastTrk = mergedTrk.back(); + + const TrackState* ts = 0; + ts = firstTrk->getTrackState(lcio::TrackState::AtIP); + if (ts) + trk->addTrackState(new TrackStateImpl(*ts)); + + ts = firstTrk->getTrackState(lcio::TrackState::AtFirstHit); + if (ts) + trk->addTrackState(new TrackStateImpl(*ts)); + + ts = lastTrk->getTrackState(lcio::TrackState::AtLastHit); + if (ts) + trk->addTrackState(new TrackStateImpl(*ts)); + + ts = lastTrk->getTrackState(lcio::TrackState::AtCalorimeter); + if (ts) + trk->addTrackState(new TrackStateImpl(*ts)); + + trk->ext() = firstTrk->ext(); + + int hitsInFit = firstTrk->getSubdetectorHitNumbers()[2 * ILDDetID::TPC - 1]; + trk->setChi2(firstTrk->getChi2()); + trk->setNdf(firstTrk->getNdf()); + trk->setdEdx(firstTrk->getdEdx()); + trk->setdEdxError(firstTrk->getdEdxError()); + + trk->subdetectorHitNumbers().resize(2 * ILDDetID::ETD); + trk->subdetectorHitNumbers()[2 * ILDDetID::TPC - 2] = hitsInFit; + trk->subdetectorHitNumbers()[2 * ILDDetID::TPC - 1] = hitCount; + + ts = trk->getTrackState(lcio::TrackState::AtFirstHit); + double RMin = (ts ? sqrt(ts->getReferencePoint()[0] * ts->getReferencePoint()[0] + + ts->getReferencePoint()[1] * ts->getReferencePoint()[1]) + : 0.0); + trk->setRadiusOfInnermostHit(RMin); + + streamlog_out(DEBUG2) << " create new merged track from bestTrack parameters - ptr to MarlinTrk : " + << trk->ext() + << " with subdetector hit numbers : " << trk->subdetectorHitNumbers()[0] << " , " + << trk->subdetectorHitNumbers()[1] << std::endl; + + outCol->addElement(trk); } else { //========================== - - // we move the first segment to the final list and keep pointers to the other segments - std::list::iterator itML = mergedTrk.begin() ; + // we move the first segment to the final list and keep pointers to the other segments - TrackImpl* trk = (TrackImpl*) *itML++ ; + std::list::iterator itML = mergedTrk.begin(); - for( ; itML != mergedTrk.end() ; ++itML ){ - - // add a pointer to the original track segment - trk->addTrack( *itML ) ; - } + TrackImpl* trk = (TrackImpl*)*itML++; - outCol->addElement( trk ) ; + for (; itML != mergedTrk.end(); ++itML) { - //remove from segment collection: - for( int i=0,N=tsCol->size() ; igetElementAt(i) ) == trk ){ - tsCol->removeElementAt( i ) ; - break ; - } - } + // add a pointer to the original track segment + trk->addTrack(*itML); + } - }//================================================================================ + outCol->addElement(trk); + // remove from segment collection: + for (int i = 0, N = tsCol->size(); i < N; ++i) { + if (((Track*)tsCol->getElementAt(i)) == trk) { + tsCol->removeElementAt(i); + break; + } + } + + } //================================================================================ } //--------------------------------------------------------------------------------------------- // // add all tracks that have not been merged : - - for( TrackClusterer::element_vector::iterator it = curSegVec.begin(); it != curSegVec.end() ;++it){ - - if( (*it)->second == 0 ){ - - TrackImpl* trk = dynamic_cast( (*it)->first ) ; - - if( copyTrackSegments) { - - TrackImpl* t = new TrackImpl( *trk ) ; - - t->ext() = 0 ; // set extension to 0 to prevent double free ... - - t->ext() = 0 ; // dynamic_cast( (*it)->first )->ext() ; - - streamlog_out( DEBUG2 ) << " create new track from existing LCIO track - ptr to MarlinTrk : " << t->ext() << std::endl ; - - outCol->addElement( t ) ; - - } else { - outCol->addElement( trk ) ; - - //remove from segment collection: - for( int i=0,N=tsCol->size() ; igetElementAt(i) ) == trk ){ - tsCol->removeElementAt( i ) ; - break ; - } - } - } + for (TrackClusterer::element_vector::iterator it = curSegVec.begin(); it != curSegVec.end(); ++it) { + + if ((*it)->second == 0) { + + TrackImpl* trk = dynamic_cast((*it)->first); + + if (copyTrackSegments) { + + TrackImpl* t = new TrackImpl(*trk); + + t->ext() = 0; // set extension to 0 to prevent double free ... + + t->ext() = 0; // dynamic_cast( (*it)->first )->ext() ; + streamlog_out(DEBUG2) << " create new track from existing LCIO track - ptr to MarlinTrk : " + << t->ext() << std::endl; + + outCol->addElement(t); + + } else { + outCol->addElement(trk); + + // remove from segment collection: + for (int i = 0, N = tsCol->size(); i < N; ++i) { + if (((Track*)tsCol->getElementAt(i)) == trk) { + tsCol->removeElementAt(i); + break; + } + } + } } } - } - timer.time( t_merge ) ; - - + timer.time(t_merge); //=============================================================================================== // create some debug collections .... //=============================================================================================== - if( _createDebugCollections ) { - - float r_inner = _tpc->rMinReadout / dd4hep::mm ; - float r_outer = _tpc->rMaxReadout / dd4hep::mm ; + if (_createDebugCollections) { + float r_inner = _tpc->rMinReadout / dd4hep::mm; + float r_outer = _tpc->rMaxReadout / dd4hep::mm; - for( LCIterator it( outCol ) ; TrackImpl* trk = it.next() ; ) { - + for (LCIterator it(outCol); TrackImpl* trk = it.next();) { - const TrackState* tsF = trk->getTrackState( lcio::TrackState::AtFirstHit ) ; - const TrackState* tsL = trk->getTrackState( lcio::TrackState::AtLastHit ) ; - - if( tsF == 0 || tsL == 0 ){ + const TrackState* tsF = trk->getTrackState(lcio::TrackState::AtFirstHit); + const TrackState* tsL = trk->getTrackState(lcio::TrackState::AtLastHit); - streamlog_out( DEBUG5 ) << " Track in ouput collection with invalid TrackStates " << *trk << std::endl ; + if (tsF == 0 || tsL == 0) { - continue; - } + streamlog_out(DEBUG5) << " Track in ouput collection with invalid TrackStates " << *trk << std::endl; - dd4hep::rec::Vector3D fhPos( tsF->getReferencePoint() ) ; - dd4hep::rec::Vector3D lhPos( tsL->getReferencePoint() ) ; - - - bool startsInner = std::abs( fhPos.rho() - r_inner ) < _trackStartsInnerDist ; // first hit close to inner field cage - bool isCentral = std::abs( lhPos.rho() - r_outer ) < _trackEndsOuterCentralDist ; // last hit close to outer field cage - bool isForward = driftLength - std::abs( lhPos.z() ) < _trackEndsOuterForwardDist ; // last hitclose to endcap - bool isCurler = std::abs( tsF->getOmega() ) > _trackIsCurlerOmega ; // curler segment ( r <~ 1m ) - bool endsOuter = isCentral || isForward ; - - - if( isCurler ) continue ; - - - if( !startsInner && endsOuter ) { - - outerCol->addElement( trk ) ; - } - if( startsInner && !endsOuter ) { - - innerCol->addElement( trk ) ; - } - if( !startsInner && !endsOuter ) { - - middleCol->addElement( trk ) ; + continue; } - - } - } - //--------------------------------------------------------------------------------------------------------- + dd4hep::rec::Vector3D fhPos(tsF->getReferencePoint()); + dd4hep::rec::Vector3D lhPos(tsL->getReferencePoint()); + + bool startsInner = std::abs(fhPos.rho() - r_inner) < _trackStartsInnerDist; // first hit close to inner field cage + bool isCentral = + std::abs(lhPos.rho() - r_outer) < _trackEndsOuterCentralDist; // last hit close to outer field cage + bool isForward = driftLength - std::abs(lhPos.z()) < _trackEndsOuterForwardDist; // last hitclose to endcap + bool isCurler = std::abs(tsF->getOmega()) > _trackIsCurlerOmega; // curler segment ( r <~ 1m ) + bool endsOuter = isCentral || isForward; + if (isCurler) + continue; + if (!startsInner && endsOuter) { + + outerCol->addElement(trk); + } + if (startsInner && !endsOuter) { + + innerCol->addElement(trk); + } + if (!startsInner && !endsOuter) { + + middleCol->addElement(trk); + } + } + } + //--------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------- // pick up hits from Si trackers //--------------------------------------------------------------------------------------------------------- - if( _pickUpSiHits ){ - - streamlog_out( DEBUG5 ) << "===============================================================================================\n" - << " picking up inner Si-hits ... \n" - << "===============================================================================================\n" ; + if (_pickUpSiHits) { + + streamlog_out(DEBUG5) + << "===============================================================================================\n" + << " picking up inner Si-hits ... \n" + << "===============================================================================================\n"; - pickUpSiTrackerHits( outCol , evt ) ; - + pickUpSiTrackerHits(outCol, evt); } //--------------------------------------------------------------------------------------------------------- - timer.time( t_pickup ) ; + timer.time(t_pickup); - //--------------------------------------------------------------------------------------------------------- //=============================================================================================== // apply some track quality cuts //=============================================================================================== - - if( writeQualityTracks ) { + + if (writeQualityTracks) { // for now we just copy poor tracks to a special collection - - for( LCIterator it( outCol ) ; TrackImpl* trk = it.next() ; ) { - + + for (LCIterator it(outCol); TrackImpl* trk = it.next();) { + // — Function: double gsl_cdf_chisq_P (double x, double nu) // — Function: double gsl_cdf_chisq_Q (double x, double nu) - //cumulative distribution functions P(x) - lower , Q(x) - upper - + // cumulative distribution functions P(x) - lower , Q(x) - upper + //--------------------------------- - double prob = ( trk->getNdf() > 0 ? gsl_cdf_chisq_Q( trk->getChi2() , (double) trk->getNdf() ) : 0. ) ; - - int hitsInFit = trk->getSubdetectorHitNumbers()[ 2 * ILDDetID::TPC - 2 ] ; - - int hitsInTrack = trk->getSubdetectorHitNumbers()[ 2 * ILDDetID::TPC - 1 ] ; - - int nTrackStates = trk->getTrackStates().size() ; - - - streamlog_out( DEBUG4 ) << " gsl_cdf_chisq_Q( "<< trk->getChi2() << ", " << (double) trk->getNdf() << " ) = " << prob - << " hitsInFit=" << hitsInFit << ", hitsInTrack =" << hitsInTrack - << " # TrackStates=" << nTrackStates - << std::endl ; - - - bool isGoodTrack = true ; - - isGoodTrack = isGoodTrack && ! ( prob < .01 ) ; - - isGoodTrack = isGoodTrack && ! ( (1.*hitsInFit ) / ( 1.*hitsInTrack ) < 0.8 ) ; - - isGoodTrack = isGoodTrack && ! ( nTrackStates < 4 ) ; - - - if( ! isGoodTrack ) - poorCol->addElement( trk ) ; - - } - } - //--------------------------------------------------------------------------------------------------------- + double prob = (trk->getNdf() > 0 ? gsl_cdf_chisq_Q(trk->getChi2(), (double)trk->getNdf()) : 0.); + + int hitsInFit = trk->getSubdetectorHitNumbers()[2 * ILDDetID::TPC - 2]; + int hitsInTrack = trk->getSubdetectorHitNumbers()[2 * ILDDetID::TPC - 1]; + int nTrackStates = trk->getTrackStates().size(); + streamlog_out(DEBUG4) << " gsl_cdf_chisq_Q( " << trk->getChi2() << ", " << (double)trk->getNdf() + << " ) = " << prob << " hitsInFit=" << hitsInFit << ", hitsInTrack =" << hitsInTrack + << " # TrackStates=" << nTrackStates << std::endl; - streamlog_out( DEBUG9 ) << timer.toString () << std::endl ; + bool isGoodTrack = true; - _nEvt ++ ; + isGoodTrack = isGoodTrack && !(prob < .01); + isGoodTrack = isGoodTrack && !((1. * hitsInFit) / (1. * hitsInTrack) < 0.8); + isGoodTrack = isGoodTrack && !(nTrackStates < 4); + + if (!isGoodTrack) + poorCol->addElement(trk); + } + } + //--------------------------------------------------------------------------------------------------------- + + streamlog_out(DEBUG9) << timer.toString() << std::endl; + + _nEvt++; // //DEBUG (check memory usage) - // streamlog_out( MESSAGE5 ) << "\n hit return to continue " << std::endl ; + // streamlog_out( MESSAGE5 ) << "\n hit return to continue " << std::endl ; // char tmp ; // std::cin.getline( &tmp,1 ); - - } - /*************************************************************************************************/ -void ClupatraProcessor::pickUpSiTrackerHits( EVENT::LCCollection* trackCol , LCEvent* evt) { - +void ClupatraProcessor::pickUpSiTrackerHits(EVENT::LCCollection* trackCol, LCEvent* evt) { + /*************************************************************************************************/ - - streamlog_out( DEBUG3 ) << " ************ pickUpSiTrackerHits() called - nTracks : " << trackCol->getNumberOfElements() < > hLMap ; - - UTIL::BitField64 encoder( LCTrackerCellID::encoding_string() ) ; - - - if( parameterSet( "SITHitCollection" ) ) { - - LCIterator it( evt, _sitColName ) ; - - streamlog_out( DEBUG2 ) << " -- pickUpSiTrackerHits - read SIT hits from collection " << _sitColName << " with size = " << it.size() << "\n" ; - - while( TrackerHit* hit = it.next() ){ - - streamlog_out( DEBUG0 ) << " adding SIT space point hit to map : " << hit << std::endl ; - - hLMap[ hit->getCellID0() ].push_back( hit ) ; - } + + streamlog_out(DEBUG3) << " ************ pickUpSiTrackerHits() called - nTracks : " << trackCol->getNumberOfElements() + << std::endl; + + std::map> hLMap; + + UTIL::BitField64 encoder(LCTrackerCellID::encoding_string()); + + if (parameterSet("SITHitCollection")) { + + LCIterator it(evt, _sitColName); + + streamlog_out(DEBUG2) << " -- pickUpSiTrackerHits - read SIT hits from collection " << _sitColName + << " with size = " << it.size() << "\n"; + + while (TrackerHit* hit = it.next()) { + + streamlog_out(DEBUG0) << " adding SIT space point hit to map : " << hit << std::endl; + + hLMap[hit->getCellID0()].push_back(hit); + } } - if( parameterSet( "VXDHitCollection" ) ) { - - LCIterator it( evt, _vxdColName ) ; - while( TrackerHit* hit = it.next() ){ - - streamlog_out( DEBUG0 ) << " adding VXD point hit to map : " << hit << std::endl ; - - hLMap[ hit->getCellID0() ].push_back( hit ) ; - } + if (parameterSet("VXDHitCollection")) { + + LCIterator it(evt, _vxdColName); + while (TrackerHit* hit = it.next()) { + + streamlog_out(DEBUG0) << " adding VXD point hit to map : " << hit << std::endl; + + hLMap[hit->getCellID0()].push_back(hit); + } } + streamlog_out(DEBUG3) << " ***** hitMap size : " << hLMap.size() << std::endl; + + for (std::map>::iterator it = hLMap.begin(), End = hLMap.end(); it != End; ++it) { + + encoder.setValue(it->first); - streamlog_out( DEBUG3 ) << " ***** hitMap size : " << hLMap.size() << std::endl ; - - for( std::map< int , std::list >::iterator it= hLMap.begin(), End = hLMap.end() ; it != End ; ++it ){ - - encoder.setValue( it->first ) ; - - streamlog_out( DEBUG3 ) << " ***** sensor: " << encoder.valueString() << " - nHits: " << it->second.size() << std::endl ; - + streamlog_out(DEBUG3) << " ***** sensor: " << encoder.valueString() << " - nHits: " << it->second.size() + << std::endl; } - - int nSITLayers = 0 ; - int nVXDLayers = 0 ; - int sitID = -1 ; - int vxdID = -1 ; + + int nSITLayers = 0; + int nVXDLayers = 0; + int sitID = -1; + int vxdID = -1; dd4hep::Detector& lcdd = dd4hep::Detector::getInstance(); - try{ + try { - dd4hep::DetElement sitDE = lcdd.detector( _sitDetectorName ) ; + dd4hep::DetElement sitDE = lcdd.detector(_sitDetectorName); - dd4hep::rec::ZPlanarData* sit = sitDE.extension() ; + dd4hep::rec::ZPlanarData* sit = sitDE.extension(); - sitID = sitDE.id() ; - nSITLayers = sit->layers.size() ; + sitID = sitDE.id(); + nSITLayers = sit->layers.size(); - }catch(...){ + } catch (...) { - streamlog_out( ERROR ) << " ==== in pickUpSiTrackerHits() : could not get detector info (ZPlanarData) for SIT " << std::endl ; - return ; + streamlog_out(ERROR) << " ==== in pickUpSiTrackerHits() : could not get detector info (ZPlanarData) for SIT " + << std::endl; + return; } - - try{ + try { - dd4hep::DetElement vxdDE = lcdd.detector( _vxdDetectorName ) ; + dd4hep::DetElement vxdDE = lcdd.detector(_vxdDetectorName); - dd4hep::rec::ZPlanarData* vxd = vxdDE.extension() ; - - vxdID = vxdDE.id() ; - nVXDLayers = vxd->layers.size() ; - - }catch(...){ + dd4hep::rec::ZPlanarData* vxd = vxdDE.extension(); - streamlog_out( ERROR ) << " ==== in pickUpSiTrackerHits() : could not get detector info (ZPlanarData) for SIT " << std::endl ; - return ; - } + vxdID = vxdDE.id(); + nVXDLayers = vxd->layers.size(); + } catch (...) { - int nLayers = nVXDLayers + nSITLayers ; + streamlog_out(ERROR) << " ==== in pickUpSiTrackerHits() : could not get detector info (ZPlanarData) for SIT " + << std::endl; + return; + } + int nLayers = nVXDLayers + nSITLayers; // ============ sort tracks wrt pt (1./omega) =============== - LCCollectionVec* tv = dynamic_cast(trackCol) ; + LCCollectionVec* tv = dynamic_cast(trackCol); - if( ! tv ) { - streamlog_out( ERROR ) << " *** pickUpSiTrackerHits() : dynamic_cast(trackCol) failed !! " << std::endl ; - return ; + if (!tv) { + streamlog_out(ERROR) << " *** pickUpSiTrackerHits() : dynamic_cast(trackCol) failed !! " + << std::endl; + return; } - std::sort( tv->begin() , tv->end() , PtSort() ) ; - - for( LCIterator it( trackCol ) ; TrackImpl* trk = it.next() ; ) - { - + std::sort(tv->begin(), tv->end(), PtSort()); - double initial_chi2 = 0 ; - int initial_ndf = 0 ; - - // ------------------------------------------ + for (LCIterator it(trackCol); TrackImpl* trk = it.next();) { + + double initial_chi2 = 0; + int initial_ndf = 0; + + // ------------------------------------------ #if 1 // this code works for plain lcio tracks, i.e. in the case where the corresponding KalTrack - // has already been deleted + // has already been deleted //=========================================================================================== - //-------------------------------------------- - // create a temporary MarlinTrk - //-------------------------------------------- - - std::unique_ptr mTrk( _trksystem->createTrack() ) ; - - // use track state at last, innermost fitted hit ! - const EVENT::TrackState* ts = trk->getTrackState( lcio::TrackState::AtFirstHit ) ; - - int nHit = trk->getTrackerHits().size() ; - - if( nHit == 0 || ts ==0 ) - continue ; - - - initial_chi2 = trk->getChi2() ; - initial_ndf = trk->getNdf() ; - - auto h = trk->getTrackerHits()[0] ; // fixme: make sure we got the right TPC hit here !?? - - streamlog_out( DEBUG3 ) << " -- extrapolate TrackState : " << lcshort( ts ) - << " adding hit: " << h - << std::endl ; - - //need to add a dummy hit to the track - mTrk->addHit( h ) ; - - mTrk->initialise( *ts , _bfield , MarlinTrk::IMarlinTrack::backward ) ; - + //-------------------------------------------- + // create a temporary MarlinTrk + //-------------------------------------------- + + std::unique_ptr mTrk(_trksystem->createTrack()); + + // use track state at last, innermost fitted hit ! + const EVENT::TrackState* ts = trk->getTrackState(lcio::TrackState::AtFirstHit); + + int nHit = trk->getTrackerHits().size(); + + if (nHit == 0 || ts == 0) + continue; + + initial_chi2 = trk->getChi2(); + initial_ndf = trk->getNdf(); + + auto h = trk->getTrackerHits()[0]; // fixme: make sure we got the right TPC hit here !?? + + streamlog_out(DEBUG3) << " -- extrapolate TrackState : " << lcshort(ts) << " adding hit: " << h << std::endl; + + // need to add a dummy hit to the track + mTrk->addHit(h); + + mTrk->initialise(*ts, _bfield, MarlinTrk::IMarlinTrack::backward); + #else //=========================================================================================== - // use the MarlinTrk allready stored with the TPC track + // use the MarlinTrk allready stored with the TPC track + MarlinTrk::IMarlinTrack* mTrk = trk->ext(); - MarlinTrk::IMarlinTrack* mTrk = trk->ext() ; - - // const EVENT::TrackState* ts = trk->getTrackState( lcio::TrackState::AtIP ) ; + // const EVENT::TrackState* ts = trk->getTrackState( lcio::TrackState::AtIP ) ; - if( mTrk == 0 ){ - - streamlog_out( DEBUG3 ) << " ------ null pointer in ext ! ?? ..... " << std::endl ; - continue ; - } + if (mTrk == 0) { + + streamlog_out(DEBUG3) << " ------ null pointer in ext ! ?? ..... " << std::endl; + continue; + } #endif //=========================================================================================== //-------------------------------------------------- - // get intersection points with SIT and VXD layers + // get intersection points with SIT and VXD layers //------------------------------------------------- + for (int lx = nLayers - 1; lx >= 0; --lx) { + + int detID = (lx >= nVXDLayers ? sitID : vxdID); - for( int lx=nLayers-1 ; lx >=0 ; --lx) { + int layer = (lx >= nVXDLayers ? lx - nVXDLayers : lx); - int detID = ( lx >= nVXDLayers ? sitID : vxdID ) ; + encoder.reset(); + encoder[LCTrackerCellID::subdet()] = detID; + encoder[LCTrackerCellID::layer()] = layer; + int layerID = encoder.lowWord(); - int layer = ( lx >= nVXDLayers ? lx - nVXDLayers : lx ) ; + MarlinTrk::Vector3D point; - encoder.reset() ; - encoder[ LCTrackerCellID::subdet() ] = detID ; - encoder[ LCTrackerCellID::layer() ] = layer ; - int layerID = encoder.lowWord() ; - + int sensorID = -1; - MarlinTrk::Vector3D point ; - - int sensorID = -1 ; + streamlog_out(DEBUG3) << " ******* pickUpSiTrackerHits - look for intersection with SIT/VXD layer " << layer + << " layerID: " << encoder.valueString() << std::endl; - streamlog_out( DEBUG3 ) << " ******* pickUpSiTrackerHits - look for intersection with SIT/VXD layer " << layer - << " layerID: " << encoder.valueString() - << std::endl ; + int intersects = mTrk->intersectionWithLayer(layerID, point, sensorID, MarlinTrk::IMarlinTrack::modeClosest); + encoder.setValue(sensorID); - int intersects = mTrk->intersectionWithLayer( layerID, point, sensorID, MarlinTrk::IMarlinTrack::modeClosest ) ; - - encoder.setValue( sensorID ) ; + streamlog_out(DEBUG3) << " ******* pickUpSiTrackerHits - intersection with SIT/VXD layer " << layer + << " intersects: " << MarlinTrk::errorCode(intersects) + << " sensorID: " << encoder.valueString() << std::endl; - streamlog_out( DEBUG3 ) << " ******* pickUpSiTrackerHits - intersection with SIT/VXD layer " << layer - << " intersects: " << MarlinTrk::errorCode( intersects ) - << " sensorID: " << encoder.valueString() - << std::endl ; - - if( intersects == MarlinTrk::IMarlinTrack::success ){ - - std::list& hL = hLMap[ sensorID ] ; - - streamlog_out( DEBUG3 ) << " **** found candidate hits : " << hL.size() - << " for point " << point << std::endl ; - - double min = 1.e99 ; - double maxDist = 1. ; //FIXME: make parameter - what is reasonable here ? - - std::list::iterator bestIt ; + if (intersects == MarlinTrk::IMarlinTrack::success) { - // SIT is no longer a strip detector ... - // if( detID == ILDDetID::SIT ) { - // bestIt = find_smallest( hL.begin(), hL.end() , StripDistance2( point ) , min ) ; - // } else { + std::list& hL = hLMap[sensorID]; - bestIt = find_smallest( hL.begin(), hL.end() , Distance3D2( point ) , min ) ; + streamlog_out(DEBUG3) << " **** found candidate hits : " << hL.size() << " for point " << point + << std::endl; - if( bestIt == hL.end() || min > maxDist ){ + double min = 1.e99; + double maxDist = 1.; // FIXME: make parameter - what is reasonable here ? - streamlog_out( DEBUG3 ) << " ######### no close by hit found !! " - << " (bestIt == hL.end())" << (bestIt == hL.end()) - << " (min > maxDist)" << (min > maxDist) - << std::endl ; - continue ; // FIXME: need to limit the number of layers w/o hits !!!!!! - } + std::list::iterator bestIt; - double deltaChi ; + // SIT is no longer a strip detector ... + // if( detID == ILDDetID::SIT ) { + // bestIt = find_smallest( hL.begin(), hL.end() , StripDistance2( point ) , min ) ; + // } else { - streamlog_out( DEBUG3 ) << " will add best matching hit : " << *bestIt << " with distance : " << min << std::endl ; + bestIt = find_smallest(hL.begin(), hL.end(), Distance3D2(point), min); - int addHit = mTrk->addAndFit( *bestIt , deltaChi, _dChi2Max ) ; - - streamlog_out( DEBUG3 ) << " **** best matching hit : " << dd4hep::rec::Vector3D( (*bestIt)->getPosition() ) - << " added : " << MarlinTrk::errorCode( addHit ) - << " deltaChi2: " << deltaChi - << std::endl ; + if (bestIt == hL.end() || min > maxDist) { - if( addHit == MarlinTrk::IMarlinTrack::success ){ + streamlog_out(DEBUG3) << " ######### no close by hit found !! " + << " (bestIt == hL.end())" << (bestIt == hL.end()) << " (min > maxDist)" + << (min > maxDist) << std::endl; + continue; // FIXME: need to limit the number of layers w/o hits !!!!!! + } + double deltaChi; - trk->addHit( *bestIt ) ; - hL.erase( bestIt ) ; + streamlog_out(DEBUG3) << " will add best matching hit : " << *bestIt << " with distance : " << min << std::endl; - IMPL::TrackStateImpl tsi ; - double chi2N; int ndfN ; + int addHit = mTrk->addAndFit(*bestIt, deltaChi, _dChi2Max); - mTrk->getTrackState( tsi , chi2N , ndfN ) ; + streamlog_out(DEBUG3) << " **** best matching hit : " << dd4hep::rec::Vector3D((*bestIt)->getPosition()) + << " added : " << MarlinTrk::errorCode(addHit) << " deltaChi2: " << deltaChi + << std::endl; - streamlog_out( DEBUG3 ) << " -- extrapolate TrackState : " << lcshort( (TrackState*)&tsi ) << "\n" - << " chi2: " << chi2N - << " ndfN: " << ndfN - << std::endl ; + if (addHit == MarlinTrk::IMarlinTrack::success) { - } + trk->addHit(*bestIt); + hL.erase(bestIt); + IMPL::TrackStateImpl tsi; + double chi2N; + int ndfN; + + mTrk->getTrackState(tsi, chi2N, ndfN); + + streamlog_out(DEBUG3) << " -- extrapolate TrackState : " << lcshort((TrackState*)&tsi) << "\n" + << " chi2: " << chi2N << " ndfN: " << ndfN << std::endl; + } } } // ------------------------- update the track state ---------------------- // FIXME: should this be done in processEvent() ? - lcio::TrackStateImpl* tsi = new lcio::TrackStateImpl ; - double chi2 ; - int ndf ; - const dd4hep::rec::Vector3D ipv( 0.,0.,0. ); - - - // get track state at the IP - int ret = mTrk->propagate( ipv, *tsi, chi2, ndf ) ; + lcio::TrackStateImpl* tsi = new lcio::TrackStateImpl; + double chi2; + int ndf; + const dd4hep::rec::Vector3D ipv(0., 0., 0.); + + // get track state at the IP + int ret = mTrk->propagate(ipv, *tsi, chi2, ndf); // int ret = mTrk->extrapolate( ipv, *tsi, chi2, ndf ) ; - - if( ret == MarlinTrk::IMarlinTrack::success ){ - - tsi->setLocation( lcio::TrackState::AtIP ) ; - + + if (ret == MarlinTrk::IMarlinTrack::success) { + + tsi->setLocation(lcio::TrackState::AtIP); // the track state at the IP needs to be the first one - // -> we have to copy the whole vector, and then add + // -> we have to copy the whole vector, and then add // all track states except the old one at the IP .... - TrackStateVec tsv = trk->trackStates() ; - trk->trackStates().clear() ; - - trk->addTrackState( tsi ) ; - - for( int i=0, N=tsv.size() ; igetLocation() == lcio::TrackState::AtIP ) { + TrackStateVec tsv = trk->trackStates(); + trk->trackStates().clear(); - delete tsv[i] ; + trk->addTrackState(tsi); - }else{ + for (int i = 0, N = tsv.size(); i < N; ++i) { - trk->addTrackState( tsv[i] ) ; - } - } //----------------------------------------------------------------- + if (tsv[i]->getLocation() == lcio::TrackState::AtIP) { + delete tsv[i]; + } else { - trk->setChi2( chi2 + initial_chi2 ) ; - trk->setNdf( ndf + initial_ndf ) ; + trk->addTrackState(tsv[i]); + } + } //----------------------------------------------------------------- - } else { + trk->setChi2(chi2 + initial_chi2); + trk->setNdf(ndf + initial_ndf); - delete tsi ; + } else { + delete tsi; } } } - /*************************************************************************************************/ +/*************************************************************************************************/ + +void ClupatraProcessor::computeTrackInfo(lcio::Track* lTrk) { -void ClupatraProcessor::computeTrackInfo( lcio::Track* lTrk ){ - - if( ! lTrk->ext() ) - lTrk->ext() = new TrackInfoStruct ; + if (!lTrk->ext()) + lTrk->ext() = new TrackInfoStruct; - float r_inner = _tpc->rMinReadout / dd4hep::mm ; - float r_outer = _tpc->rMaxReadout / dd4hep::mm ; - float driftLength = _tpc->driftLength / dd4hep::mm ; + float r_inner = _tpc->rMinReadout / dd4hep::mm; + float r_outer = _tpc->rMaxReadout / dd4hep::mm; + float driftLength = _tpc->driftLength / dd4hep::mm; // compute z-extend of this track segment - const lcio::TrackerHitVec& hv = lTrk->getTrackerHits() ; - - float zMin = 1e99 ; - float zMax = -1e99 ; - float zAvg = 0. ; - - if( hv.size() > 1 ) { - zMin = hv[ 0 ]->getPosition()[2] ; - zMax = hv[ hv.size() -1 ]->getPosition()[2] ; - zAvg = ( zMax + zMin ) / 2. ; + const lcio::TrackerHitVec& hv = lTrk->getTrackerHits(); + + float zMin = 1e99; + float zMax = -1e99; + float zAvg = 0.; + + if (hv.size() > 1) { + zMin = hv[0]->getPosition()[2]; + zMax = hv[hv.size() - 1]->getPosition()[2]; + zAvg = (zMax + zMin) / 2.; } - - if( zMin > zMax ){ // swap - float d = zMax ; - zMax = zMin ; - zMin = d ; + + if (zMin > zMax) { // swap + float d = zMax; + zMax = zMin; + zMin = d; } - - const lcio::TrackState* tsF = lTrk->getTrackState( lcio::TrackState::AtFirstHit ) ; - const lcio::TrackState* tsL = lTrk->getTrackState( lcio::TrackState::AtLastHit ) ; - - // protect against bad tracks - if( tsF == 0 ) return ; - if( tsL == 0 ) return ; - - dd4hep::rec::Vector3D fhPos( tsF->getReferencePoint() ) ; - dd4hep::rec::Vector3D lhPos( tsL->getReferencePoint() ) ; - - - TrackInfoStruct* ti = lTrk->ext() ; - - ti->startsInner = std::abs( fhPos.rho() - r_inner ) < _trackStartsInnerDist ; // first hit close to inner field cage - ti->isCentral = std::abs( lhPos.rho() - r_outer ) < _trackEndsOuterCentralDist ; // last hit close to outer field cage - ti->isForward = driftLength - std::abs( lhPos.z() ) < _trackEndsOuterForwardDist ; // last hitclose to endcap - ti->isCurler = std::abs( tsF->getOmega() ) > _trackIsCurlerOmega ; // curler segment ( r <~ 1m ) - - ti->zMin = zMin ; - ti->zMax = zMax ; - ti->zAvg = zAvg ; -} + const lcio::TrackState* tsF = lTrk->getTrackState(lcio::TrackState::AtFirstHit); + const lcio::TrackState* tsL = lTrk->getTrackState(lcio::TrackState::AtLastHit); + + // protect against bad tracks + if (tsF == 0) + return; + if (tsL == 0) + return; + + dd4hep::rec::Vector3D fhPos(tsF->getReferencePoint()); + dd4hep::rec::Vector3D lhPos(tsL->getReferencePoint()); + TrackInfoStruct* ti = lTrk->ext(); + + ti->startsInner = std::abs(fhPos.rho() - r_inner) < _trackStartsInnerDist; // first hit close to inner field cage + ti->isCentral = std::abs(lhPos.rho() - r_outer) < _trackEndsOuterCentralDist; // last hit close to outer field cage + ti->isForward = driftLength - std::abs(lhPos.z()) < _trackEndsOuterForwardDist; // last hitclose to endcap + ti->isCurler = std::abs(tsF->getOmega()) > _trackIsCurlerOmega; // curler segment ( r <~ 1m ) + + ti->zMin = zMin; + ti->zMax = zMax; + ti->zAvg = zAvg; +} /*************************************************************************************************/ -void ClupatraProcessor::check( LCEvent * evt ) { - +void ClupatraProcessor::check(LCEvent* evt) { // check that all Clupatra tracks actually have the four canonical track states set: - streamlog_out( DEBUG5 ) << " ------------------- check() called " << std::endl ; + streamlog_out(DEBUG5) << " ------------------- check() called " << std::endl; // for( LCIterator it( evt, _segmentsOutColName ) ; EVENT::Track* trk = it.next() ; ) { - for( LCIterator it( evt, _outColName ) ; EVENT::Track* trk = it.next() ; ) { - - const EVENT::TrackState* ts0 = trk->getTrackState( lcio::TrackState::AtIP ) ; - const EVENT::TrackState* ts1 = trk->getTrackState( lcio::TrackState::AtFirstHit ) ; - const EVENT::TrackState* ts2 = trk->getTrackState( lcio::TrackState::AtLastHit ) ; - const EVENT::TrackState* ts3 = trk->getTrackState( lcio::TrackState::AtCalorimeter ) ; + for (LCIterator it(evt, _outColName); EVENT::Track* trk = it.next();) { + const EVENT::TrackState* ts0 = trk->getTrackState(lcio::TrackState::AtIP); + const EVENT::TrackState* ts1 = trk->getTrackState(lcio::TrackState::AtFirstHit); + const EVENT::TrackState* ts2 = trk->getTrackState(lcio::TrackState::AtLastHit); + const EVENT::TrackState* ts3 = trk->getTrackState(lcio::TrackState::AtCalorimeter); - // streamlog_out( DEBUG2 ) << lcshort( trk ) << ", " << ts0 << ", " << ts1 << ", " << ts2 << ", " << ts3 << std::endl ; - streamlog_out( DEBUG3 ) << " -- " << ts0 << ", " << ts1 << ", " << ts2 << ", " << ts3 << std::endl ; - - if( ! ts0 || ! ts1 || ! ts2 || ! ts3 ) - - streamlog_out( ERROR ) << " clupatra track w/ missing track state : " << lcshort( trk ) - << " ts0-ts3 : " << ts0 << ", " << ts1 << ", " << ts2 << ", " << ts3 << std::endl ; + // streamlog_out( DEBUG2 ) << lcshort( trk ) << ", " << ts0 << ", " << ts1 << ", " << ts2 << ", " << ts3 << + // std::endl ; + streamlog_out(DEBUG3) << " -- " << ts0 << ", " << ts1 << ", " << ts2 << ", " << ts3 << std::endl; + if (!ts0 || !ts1 || !ts2 || !ts3) + streamlog_out(ERROR) << " clupatra track w/ missing track state : " << lcshort(trk) << " ts0-ts3 : " << ts0 + << ", " << ts1 << ", " << ts2 << ", " << ts3 << std::endl; } - streamlog_out( DEBUG5 ) << " ------------------- check() done " << std::endl ; + streamlog_out(DEBUG5) << " ------------------- check() done " << std::endl; /*************************************************************************************************/ } - - //==================================================================================================== -void ClupatraProcessor::end(){ - - streamlog_out( MESSAGE ) << "ClupatraProcessor::end() " << name() - << " processed " << _nEvt << " events in " << _nRun << " runs " - << std::endl ; - -} +void ClupatraProcessor::end() { + streamlog_out(MESSAGE) << "ClupatraProcessor::end() " << name() << " processed " << _nEvt << " events in " << _nRun + << " runs " << std::endl; +} //==================================================================================================== diff --git a/src/DebugDigiProcessor.cc b/src/DebugDigiProcessor.cc index 312966e..34963eb 100644 --- a/src/DebugDigiProcessor.cc +++ b/src/DebugDigiProcessor.cc @@ -1,248 +1,200 @@ #include "DebugDigiProcessor.h" -//#include -// #include -// #include -// #include -// #include -// #include +// #include +// #include +// #include +// #include +// #include +// #include //---- LCIO --- -#include "IMPL/LCCollectionVec.h" #include "EVENT/Track.h" #include "EVENT/TrackerHit.h" +#include "IMPL/LCCollectionVec.h" #include "UTIL/Operators.h" // #include "UTIL/LCRelationNavigator.h" // #include "UTIL/LCTypedVector.h" +#include "UTIL/CellIDDecoder.h" #include "UTIL/LCTrackerConf.h" #include -#include "UTIL/CellIDDecoder.h" // #include "UTIL/LCTOOLS.h" - #include "UTIL/LCIterator.h" -using namespace lcio ; -using namespace marlin ; - +using namespace lcio; +using namespace marlin; //-------------------------------------------------------------------------------------------- template -int subdet( const T* t){ - - static CellIDDecoder idDec( LCTrackerCellID::encoding_string() ) ; - - return idDec( t )[ LCTrackerCellID::subdet() ] ; +int subdet(const T* t) { + + static CellIDDecoder idDec(LCTrackerCellID::encoding_string()); + + return idDec(t)[LCTrackerCellID::subdet()]; } //-------------------------------------------------------------------------------------------- +DebugDigiProcessor aDebugDigiProcessor; +DebugDigiProcessor::DebugDigiProcessor() : Processor("DebugDigiProcessor"), _nRun(0), _nEvt(0) { + // modify processor description + _description = "DebugDigiProcessor: analysis plots for Tracks"; -DebugDigiProcessor aDebugDigiProcessor ; - + registerInputCollection(LCIO::TRACK, "TrackCollection", "Name of the input collections with Tracks", _trkColName, + std::string("TrackCollection")); -DebugDigiProcessor::DebugDigiProcessor() : Processor("DebugDigiProcessor") , - _nRun(0), _nEvt(0) { - - // modify processor description - _description = "DebugDigiProcessor: analysis plots for Tracks" ; - - - registerInputCollection( LCIO::TRACK, - "TrackCollection" , - "Name of the input collections with Tracks" , - _trkColName , - std::string("TrackCollection" ) ) ; - - IntVec subDetIDs ; - subDetIDs.push_back( lcio::ILDDetID::TPC ) ; - - registerProcessorParameter( "SubDetectorIDs" , - "The IDs of the subdetectors corresponding to the hit collections in TrackerHitCollectionNames" , - _subDetIDs , - subDetIDs ) ; - - StringVec hitColNames ; - hitColNames.push_back( std::string( "TPCTrackerHits" ) ) ; - - registerProcessorParameter( "TrackerHitCollections" , - "The tracker hit collection names - needs to run parallel to SubDetectorIDs" , - _hitColNames , - hitColNames ) ; - + IntVec subDetIDs; + subDetIDs.push_back(lcio::ILDDetID::TPC); + registerProcessorParameter( + "SubDetectorIDs", "The IDs of the subdetectors corresponding to the hit collections in TrackerHitCollectionNames", + _subDetIDs, subDetIDs); + StringVec hitColNames; + hitColNames.push_back(std::string("TPCTrackerHits")); + registerProcessorParameter("TrackerHitCollections", + "The tracker hit collection names - needs to run parallel to SubDetectorIDs", _hitColNames, + hitColNames); } - -void DebugDigiProcessor::init() { +void DebugDigiProcessor::init() { // usually a good idea to - printParameters() ; + printParameters(); + if (_subDetIDs.size() != _hitColNames.size()) { - - if( _subDetIDs.size() != _hitColNames.size() ){ - - throw Exception( "DebugDigiProcessor::init() - processor parameters SubDetectorIDs and TrackerHitCollections do not have the same size !" ) ; + throw Exception("DebugDigiProcessor::init() - processor parameters SubDetectorIDs and TrackerHitCollections do not " + "have the same size !"); } - - _nRun = 0 ; - _nEvt = 0 ; + _nRun = 0; + _nEvt = 0; } -void DebugDigiProcessor::processRunHeader( LCRunHeader* ) { +void DebugDigiProcessor::processRunHeader(LCRunHeader*) { _nRun++; } - _nRun++ ; -} +void DebugDigiProcessor::modifyEvent(LCEvent* evt) { + for (unsigned i = 0, N = _hitColNames.size(); i < N; ++i) { + LCCollection* col = 0; + try { -void DebugDigiProcessor::modifyEvent( LCEvent * evt ) { - - for( unsigned i=0,N=_hitColNames.size() ; igetCollection( _hitColNames[ i ] ) ; + col = evt->getCollection(_hitColNames[i]); + } catch (const DataNotAvailableException&) { } - catch( const DataNotAvailableException& ) {} - if( col ) { + if (col) { - evt->removeCollection( _hitColNames[ i ] ) ; - - std::string newName( _hitColNames[ i ] ) ; - newName += "_OLD" ; + evt->removeCollection(_hitColNames[i]); - evt->addCollection( col , newName ) ; + std::string newName(_hitColNames[i]); + newName += "_OLD"; - streamlog_out( DEBUG2 ) << " rename collection " << _hitColNames[ i ] << " to " << newName << std::endl ; + evt->addCollection(col, newName); + streamlog_out(DEBUG2) << " rename collection " << _hitColNames[i] << " to " << newName << std::endl; } } - - LCCollection* col = 0 ; - try { - - col = evt->getCollection( _trkColName ) ; - } - catch( const DataNotAvailableException& ) {} - if( col ) { - - evt->removeCollection( _trkColName ) ; - - std::string newName( _trkColName ) ; - newName += "_OLD" ; + LCCollection* col = 0; + try { - evt->addCollection( col , newName ) ; + col = evt->getCollection(_trkColName); + } catch (const DataNotAvailableException&) { + } - streamlog_out( DEBUG2 ) << " rename collection " << _trkColName << " to " << newName << std::endl ; + if (col) { - } - + evt->removeCollection(_trkColName); + std::string newName(_trkColName); + newName += "_OLD"; + evt->addCollection(col, newName); + + streamlog_out(DEBUG2) << " rename collection " << _trkColName << " to " << newName << std::endl; + } } +void DebugDigiProcessor::processEvent(LCEvent* evt) { + //========================================================================================================================= -void DebugDigiProcessor::processEvent( LCEvent * evt ) { + LCCollection* trkCol = 0; + try { + std::string newName(_trkColName); + newName += "_OLD"; + trkCol = evt->getCollection(newName); + } catch (lcio::DataNotAvailableException& e) { - //========================================================================================================================= - - - LCCollection* trkCol = 0 ; - try{ - - std::string newName( _trkColName ) ; - newName += "_OLD" ; - trkCol = evt->getCollection( newName ) ; - } - catch( lcio::DataNotAvailableException& e){ - - streamlog_out( DEBUG2 ) << " *** collection not in event : " << _trkColName << std::endl ; - return ; // nothing to do in this event (no tracks) + streamlog_out(DEBUG2) << " *** collection not in event : " << _trkColName << std::endl; + return; // nothing to do in this event (no tracks) } - if( trkCol->getNumberOfElements() < 1 ) { - - streamlog_out( DEBUG2) << " not tracks in collection " << _trkColName << " evt : " << evt->getEventNumber() - << " run : " << evt->getRunNumber() << std::endl ; - return ; + if (trkCol->getNumberOfElements() < 1) { + + streamlog_out(DEBUG2) << " not tracks in collection " << _trkColName << " evt : " << evt->getEventNumber() + << " run : " << evt->getRunNumber() << std::endl; + return; } + std::map colMap; - std::map< int , LCCollectionVec* > colMap ; + for (unsigned i = 0, N = _hitColNames.size(); i < N; ++i) { - for( unsigned i=0,N=_hitColNames.size() ; isetSubset(true); - col->setSubset( true ) ; + evt->addCollection(col, _hitColNames[i]); - evt->addCollection( col , _hitColNames[ i ] ) ; - - colMap[ _subDetIDs[i] ] = col ; + colMap[_subDetIDs[i]] = col; - streamlog_out( DEBUG2) << " add collection " << _hitColNames[ i ] << " to event " << std::endl ; + streamlog_out(DEBUG2) << " add collection " << _hitColNames[i] << " to event " << std::endl; } + for (unsigned i = 0, N = trkCol->getNumberOfElements(); i < N; ++i) { - for( unsigned i=0,N=trkCol->getNumberOfElements() ; igetElementAt(i) ) ; + Track* trk = (Track*)(trkCol->getElementAt(i)); - const TrackerHitVec& hits = trk->getTrackerHits() ; + const TrackerHitVec& hits = trk->getTrackerHits(); - for( unsigned j=0,M=hits.size() ; jaddElement( hits[j] ) ; - + streamlog_out(DEBUG) << " add hit " << hits[j] << " to collection for sub detector : " << subDetID << std::endl; + + col->addElement(hits[j]); } } } - //---------------------------------------------------------------------- - - _nEvt ++ ; + //---------------------------------------------------------------------- + _nEvt++; } - - - /*************************************************************************************************/ -void DebugDigiProcessor::check( LCEvent * ) { +void DebugDigiProcessor::check(LCEvent*) { /*************************************************************************************************/ - } //==================================================================================== +void DebugDigiProcessor::end() { - - -void DebugDigiProcessor::end(){ - - streamlog_out( MESSAGE ) << " processed " << _nEvt << " events in " << _nRun << " runs " - << std::endl ; + streamlog_out(MESSAGE) << " processed " << _nEvt << " events in " << _nRun << " runs " << std::endl; } //==================================================================================================== - diff --git a/src/TrackCheckMCTruth.cc b/src/TrackCheckMCTruth.cc index 199f3e8..420d3c1 100644 --- a/src/TrackCheckMCTruth.cc +++ b/src/TrackCheckMCTruth.cc @@ -1,463 +1,440 @@ #include "TrackCheckMCTruth.h" - #include "marlin/AIDAProcessor.h" -//#include -#include -#include +// #include #include -#include #include +#include +#include +#include //---- LCIO --- -#include "IMPL/LCCollectionVec.h" -#include "EVENT/Track.h" #include "EVENT/SimTrackerHit.h" -#include "UTIL/Operators.h" +#include "EVENT/Track.h" +#include "IMPL/LCCollectionVec.h" +#include "UTIL/BitSet32.h" #include "UTIL/LCRelationNavigator.h" #include "UTIL/LCTypedVector.h" -#include "UTIL/BitSet32.h" - +#include "UTIL/Operators.h" #include "DDRec/Vector3D.h" - -//MarlinUtil +// MarlinUtil #include "HelixClass.h" // --- DD4hep --- +#include "DD4hep/DD4hepUnits.h" #include "DD4hep/Detector.h" #include "DDRec/Vector3D.h" -#include "DD4hep/DD4hepUnits.h" - //---- ROOT ----- -#include "TH1F.h" +#include "TH1F.h" #include "UTIL/LCIterator.h" -using namespace lcio ; -using namespace marlin ; - +using namespace lcio; +using namespace marlin; -TrackCheckMCTruth aTrackCheckMCTruth ; +TrackCheckMCTruth aTrackCheckMCTruth; /** helper method to create a track collections and add it to the event */ -inline IMPL::LCCollectionVec* newTrkCol(const std::string& name, LCEvent * evt ){ - - IMPL::LCCollectionVec* col = new IMPL::LCCollectionVec( LCIO::TRACK ) ; +inline IMPL::LCCollectionVec* newTrkCol(const std::string& name, LCEvent* evt) { - col->setFlag( UTIL::make_bitset32( LCIO::TRBIT_HITS ) ) ; + IMPL::LCCollectionVec* col = new IMPL::LCCollectionVec(LCIO::TRACK); + col->setFlag(UTIL::make_bitset32(LCIO::TRBIT_HITS)); - evt->addCollection( col , name ) ; + evt->addCollection(col, name); - return col ; + return col; } //---------------------------------------------------------------- /** helper method to get the collection from the event */ -inline LCCollection* getCollection( const std::string& name, LCEvent * evt ){ - - LCCollection* col = 0 ; - try{ col = evt->getCollection( name ) ; - } catch( lcio::DataNotAvailableException& e) { - streamlog_out( DEBUG4 ) << " input collection not in event : " << name << " !!! " << std::endl ; - } - return col ; +inline LCCollection* getCollection(const std::string& name, LCEvent* evt) { + + LCCollection* col = 0; + try { + col = evt->getCollection(name); + } catch (lcio::DataNotAvailableException& e) { + streamlog_out(DEBUG4) << " input collection not in event : " << name << " !!! " << std::endl; + } + return col; } //---------------------------------------------------------------- -// helper enum defining histogram index in vector +// helper enum defining histogram index in vector namespace TrackCheckMCTruthHistos { - enum index{ - hd0, hphi, homega, hz0, htanL, hpt, - hed0, hephi, heomega, hez0, hetanL, hept, - hdd0, hdphi, hdomega, hdz0, hdtanL, hdpt, - hpd0, hpphi, hpomega, hpz0, hptanL, hppt, - hd0mcp,hphimcp, homegamcp, hz0mcp, htanLmcp, hptmcp, - hdptp2, - hpt_f,hcosth_f, hpt_t, hcosth_t, hacth_t, hacth_f, - //----- keep Size as last : - Size - }; - - -class Histograms{ +enum index { + hd0, + hphi, + homega, + hz0, + htanL, + hpt, + hed0, + hephi, + heomega, + hez0, + hetanL, + hept, + hdd0, + hdphi, + hdomega, + hdz0, + hdtanL, + hdpt, + hpd0, + hpphi, + hpomega, + hpz0, + hptanL, + hppt, + hd0mcp, + hphimcp, + homegamcp, + hz0mcp, + htanLmcp, + hptmcp, + hdptp2, + hpt_f, + hcosth_f, + hpt_t, + hcosth_t, + hacth_t, + hacth_f, + //----- keep Size as last : + Size +}; + +class Histograms { public: Histograms(std::vector& v) : _h(&v) {} - void create(int idx, const char* n, int nBin=100, double min=0., double max=0. ){ - create( idx , n , n , nBin, min , max ) ; + void create(int idx, const char* n, int nBin = 100, double min = 0., double max = 0.) { + create(idx, n, n, nBin, min, max); } - void create(int idx, const char* n, const char* t, int nBin=100, double min=0., double max=0. ){ + void create(int idx, const char* n, const char* t, int nBin = 100, double min = 0., double max = 0.) { // _h->resize( idx+1 ) ; - _h->at( idx ) = new TH1D( n, t , nBin , min, max ) ; + _h->at(idx) = new TH1D(n, t, nBin, min, max); - streamlog_out( DEBUG ) << " create histo " << n << " at index " << idx << std::endl ; + streamlog_out(DEBUG) << " create histo " << n << " at index " << idx << std::endl; } - void create(int idx, const char* n, const char* t, int nBin , double* bins ){ + void create(int idx, const char* n, const char* t, int nBin, double* bins) { - _h->at( idx ) = new TH1D( n, t , nBin , bins ) ; + _h->at(idx) = new TH1D(n, t, nBin, bins); - streamlog_out( DEBUG ) << " create histo " << n << " at index " << idx << std::endl ; + streamlog_out(DEBUG) << " create histo " << n << " at index " << idx << std::endl; } - void fill( int idx , double val, double weight=1.0 ){ _h->at( idx )->Fill( val , weight ) ; } + void fill(int idx, double val, double weight = 1.0) { _h->at(idx)->Fill(val, weight); } protected: - std::vector* _h; }; - - -} -using namespace TrackCheckMCTruthHistos ; - +} // namespace TrackCheckMCTruthHistos +using namespace TrackCheckMCTruthHistos; //====================================================================================================== -#define APPLY_CUT( LEVEL, Cut, Exp ) if( (Exp) == false ) { Cut = false ; \ - streamlog_out( LEVEL )<< " ***** failed cut: [ " << #Exp \ - << " ] in evt: " << evt->getEventNumber() \ - << " run: " << evt->getRunNumber() << std::endl ; } +#define APPLY_CUT(LEVEL, Cut, Exp) \ + if ((Exp) == false) { \ + Cut = false; \ + streamlog_out(LEVEL) << " ***** failed cut: [ " << #Exp << " ] in evt: " << evt->getEventNumber() \ + << " run: " << evt->getRunNumber() << std::endl; \ + } //====================================================================================================== // streamlog_out( LEVEL ) //====================================================================================================== +TrackCheckMCTruth::TrackCheckMCTruth() : Processor("TrackCheckMCTruth"), _nRun(0), _nEvt(0) { -TrackCheckMCTruth::TrackCheckMCTruth() : Processor("TrackCheckMCTruth"), - _nRun(0), _nEvt(0) { - // modify processor description - _description = "TrackCheckMCTruth: analysis plots for Tracks" ; - - - - registerInputCollection( LCIO::MCPARTICLE, - "MCParticlesCollection" , - "Name of the input collections with MCParticles" , - _mcpColName , - std::string("MCParticlesSkimmed" ) ) ; - - StringVec sthVec ; - sthVec.push_back( "TPCCollection" ); - - registerInputCollections( LCIO::SIMTRACKERHIT, - "SimTrackerHitCollection" , - "Name of the input collections with SimTrackerHits" , - _sthColNames , - sthVec ); - - registerInputCollection( LCIO::LCRELATION, - "TrackMCPRelation" , - "Name of the input collections with LCRelation Tracks to MCParticles" , - _relTrkMCPColName , - std::string("TrackRelation" ) ) ; - - registerInputCollection( LCIO::LCRELATION, - "MCPTrackRelation" , - "Name of the input collections with LCRelation MCParticles to tracks" , - _relMCPTrkColName , - std::string("MCPTrkRelation" ) ) ; - - registerInputCollection( LCIO::TRACK, - "TrackCollection" , - "Name of the input collections with Tracks" , - _trkColName , - std::string("ClupatraTracks" ) ) ; - - - registerOutputCollection( LCIO::TRACK, - "SplitTrackCollection" , - "Name of the output collections with split Tracks" , - _splitColName , - std::string("ClupatraSplitTracks" ) ) ; - - registerOutputCollection( LCIO::TRACK, - "MergedTrackCollection" , - "Name of the output collections with merged Tracks" , - _mergedColName , - std::string("ClupatraMergedTracks" ) ) ; - - registerProcessorParameter( "HitFractionSplit" , - "maximal fractions of hits that are allowed to be missing for a split track" , - _hitFractionSplit , - float( 0.05 ) ); - - registerProcessorParameter( "HitFractionMerged" , - "maximal fractions of hits that are allowed to be missing for a merged track" , - _hitFractionMerged , - float( 0.05 ) ); - - FloatVec ptRange ; - ptRange.push_back( 0. ) ; - ptRange.push_back( 1000. ) ; - - registerProcessorParameter( "PtRange" , - "Min and max value of pt range [GeV]" , - _ptRange , - ptRange ) ; - -} + _description = "TrackCheckMCTruth: analysis plots for Tracks"; + registerInputCollection(LCIO::MCPARTICLE, "MCParticlesCollection", "Name of the input collections with MCParticles", + _mcpColName, std::string("MCParticlesSkimmed")); -void TrackCheckMCTruth::init() { + StringVec sthVec; + sthVec.push_back("TPCCollection"); - // usually a good idea to - printParameters() ; + registerInputCollections(LCIO::SIMTRACKERHIT, "SimTrackerHitCollection", + "Name of the input collections with SimTrackerHits", _sthColNames, sthVec); + registerInputCollection(LCIO::LCRELATION, "TrackMCPRelation", + "Name of the input collections with LCRelation Tracks to MCParticles", _relTrkMCPColName, + std::string("TrackRelation")); - if( _ptRange.size() != 2 ) { + registerInputCollection(LCIO::LCRELATION, "MCPTrackRelation", + "Name of the input collections with LCRelation MCParticles to tracks", _relMCPTrkColName, + std::string("MCPTrkRelation")); - throw Exception("TrackCheckMCTruth::init() processor parameter 'ptRange' needs to have two values (min and max pt in GeV)" ) ; - } + registerInputCollection(LCIO::TRACK, "TrackCollection", "Name of the input collections with Tracks", _trkColName, + std::string("ClupatraTracks")); + registerOutputCollection(LCIO::TRACK, "SplitTrackCollection", "Name of the output collections with split Tracks", + _splitColName, std::string("ClupatraSplitTracks")); - _nRun = 0 ; - _nEvt = 0 ; + registerOutputCollection(LCIO::TRACK, "MergedTrackCollection", "Name of the output collections with merged Tracks", + _mergedColName, std::string("ClupatraMergedTracks")); + + registerProcessorParameter("HitFractionSplit", + "maximal fractions of hits that are allowed to be missing for a split track", + _hitFractionSplit, float(0.05)); + + registerProcessorParameter("HitFractionMerged", + "maximal fractions of hits that are allowed to be missing for a merged track", + _hitFractionMerged, float(0.05)); + + FloatVec ptRange; + ptRange.push_back(0.); + ptRange.push_back(1000.); + + registerProcessorParameter("PtRange", "Min and max value of pt range [GeV]", _ptRange, ptRange); } -void TrackCheckMCTruth::processRunHeader( LCRunHeader* ) { +void TrackCheckMCTruth::init() { - _nRun++ ; -} + // usually a good idea to + printParameters(); -void TrackCheckMCTruth::processEvent( LCEvent * evt ) { + if (_ptRange.size() != 2) { + throw Exception( + "TrackCheckMCTruth::init() processor parameter 'ptRange' needs to have two values (min and max pt in GeV)"); + } - clock_t start = clock() ; + _nRun = 0; + _nEvt = 0; +} + +void TrackCheckMCTruth::processRunHeader(LCRunHeader*) { _nRun++; } + +void TrackCheckMCTruth::processEvent(LCEvent* evt) { + + clock_t start = clock(); dd4hep::Detector& theDetector = dd4hep::Detector::getInstance(); - double bfieldV[3] ; - theDetector.field().magneticField( { 0., 0., 0. } , bfieldV ) ; - const double bField = bfieldV[2]/dd4hep::tesla ; + double bfieldV[3]; + theDetector.field().magneticField({0., 0., 0.}, bfieldV); + const double bField = bfieldV[2] / dd4hep::tesla; - static const double alpha = 2.99792458e-4 * bField ; ; + static const double alpha = 2.99792458e-4 * bField; + ; // p_t[GeV] = alpha / omega[mm] ; - //---------------------------------------------------------------------- - Histograms h(_h1) ; + Histograms h(_h1); - if( isFirstEvent() ){ + if (isFirstEvent()) { // this creates a directory for this processor .... - AIDAProcessor::histogramFactory( this ) ; - - _h1.resize( TrackCheckMCTruthHistos::Size ) ; - - static const int nBin = 50 ; + AIDAProcessor::histogramFactory(this); + + _h1.resize(TrackCheckMCTruthHistos::Size); + + static const int nBin = 50; // define binning for pt and omega // double ptBinL = ptMin - ( ptMax - ptMin ) / 10. ; // double ptBinH = ptMax + ( ptMax - ptMin ) / 10. ; - double ptBinL = 0.01 ; - double ptBinH = 20. ; - double omBinL = alpha / ptBinH ; - double omBinH = alpha / ptBinL ; - - - h.create( hd0, "hd0" ) ; - h.create( hphi, "hphi" ) ; - h.create( homega, "homega" ,"omega*mm" , nBin ,omBinL , omBinH ) ; - h.create( hz0, "hz0" , " z0 /mm " , nBin , -3. , 3. ) ; - h.create( htanL, "htanL" ) ; - h.create( hpt, "hpt" , "pt/GeV" , nBin , ptBinL , ptBinH ) ; - - h.create( hd0mcp, "hd0mcp" ) ; - h.create( hphimcp, "hphimcp" ) ; - h.create( homegamcp, "homegamcp" ,"omega*mm" , nBin ,omBinL , omBinH ) ; //, "omega*mm" , 50, 0.0003 , 0.0004 ) ; - h.create( hz0mcp, "hz0mcp" ) ; //, " z0 /mm " , 50 , -3. , 3. ) ; - h.create( htanLmcp, "htanLmcp" ) ; - h.create( hptmcp, "hptmcp" , "pt/GeV" , nBin , ptBinL , ptBinH ) ; - - h.create( hed0, "hed0" ) ; - h.create( hephi, "hephi" ) ; - h.create( heomega, "heomega" ) ; - h.create( hez0, "hez0" ) ; - h.create( hetanL, "hetanL" ) ; - h.create( hept, "hept" ) ; - - h.create( hpd0, "hpd0" , "d0 pull ", 50 , -5. , 5. ) ; - h.create( hpphi, "hpphi" , "phi pull ", 50 , -5. , 5. ) ; - h.create( hpomega, "hpomega" , "omega pull", 50 , -5. , 5. ) ; - h.create( hpz0, "hpz0" , "z0 pull ", 50 , -5. , 5. ) ; - h.create( hptanL, "hptanL" , "tanL pull ", 50 , -5. , 5. ) ; - h.create( hppt, "hppt" , "pt pull ", 50 , -5. , 5. ) ; - - h.create( hdd0, "hdd0" ) ; - h.create( hdphi, "hdphi" ) ; - h.create( hdomega, "hdomega" ) ; - h.create( hdz0, "hdz0" ) ; - h.create( hdtanL, "hdtanL" ) ; - h.create( hdpt, "hdpt" ) ; - - h.create( hdptp2, "hdptp2" ) ; - - h.create( hcosth_t, "hcosth_t" , "cos theta - true ", 21 , -1. , 1. ) ; - h.create( hcosth_f, "hcosth_f" , "cos theta - found ", 21 , -1. , 1. ) ; - - h.create( hacth_t, "hacth_t" , "|cos theta| - true ", 10 , 0. , 1. ) ; - h.create( hacth_f, "hacth_f" , "|cos theta| - found ", 10 , 0. , 1. ) ; + double ptBinL = 0.01; + double ptBinH = 20.; + double omBinL = alpha / ptBinH; + double omBinH = alpha / ptBinL; + + h.create(hd0, "hd0"); + h.create(hphi, "hphi"); + h.create(homega, "homega", "omega*mm", nBin, omBinL, omBinH); + h.create(hz0, "hz0", " z0 /mm ", nBin, -3., 3.); + h.create(htanL, "htanL"); + h.create(hpt, "hpt", "pt/GeV", nBin, ptBinL, ptBinH); + + h.create(hd0mcp, "hd0mcp"); + h.create(hphimcp, "hphimcp"); + h.create(homegamcp, "homegamcp", "omega*mm", nBin, omBinL, omBinH); //, "omega*mm" , 50, 0.0003 , 0.0004 ) ; + h.create(hz0mcp, "hz0mcp"); //, " z0 /mm " , 50 , -3. , 3. ) ; + h.create(htanLmcp, "htanLmcp"); + h.create(hptmcp, "hptmcp", "pt/GeV", nBin, ptBinL, ptBinH); + + h.create(hed0, "hed0"); + h.create(hephi, "hephi"); + h.create(heomega, "heomega"); + h.create(hez0, "hez0"); + h.create(hetanL, "hetanL"); + h.create(hept, "hept"); + + h.create(hpd0, "hpd0", "d0 pull ", 50, -5., 5.); + h.create(hpphi, "hpphi", "phi pull ", 50, -5., 5.); + h.create(hpomega, "hpomega", "omega pull", 50, -5., 5.); + h.create(hpz0, "hpz0", "z0 pull ", 50, -5., 5.); + h.create(hptanL, "hptanL", "tanL pull ", 50, -5., 5.); + h.create(hppt, "hppt", "pt pull ", 50, -5., 5.); + + h.create(hdd0, "hdd0"); + h.create(hdphi, "hdphi"); + h.create(hdomega, "hdomega"); + h.create(hdz0, "hdz0"); + h.create(hdtanL, "hdtanL"); + h.create(hdpt, "hdpt"); + + h.create(hdptp2, "hdptp2"); + + h.create(hcosth_t, "hcosth_t", "cos theta - true ", 21, -1., 1.); + h.create(hcosth_f, "hcosth_f", "cos theta - found ", 21, -1., 1.); + + h.create(hacth_t, "hacth_t", "|cos theta| - true ", 10, 0., 1.); + h.create(hacth_f, "hacth_f", "|cos theta| - found ", 10, 0., 1.); // void create(int idx, const char* n, const char* t, int nBin=100, double min=0., double max=0. ){ // variable bin size histogram for pt - static const int nBins = 9 ; - double bins[nBins+1] = { 0.1, 0.2, 0.5 , 1.0 , 2., 5.0 , 10. , 20. , 50. , 100. } ; + static const int nBins = 9; + double bins[nBins + 1] = {0.1, 0.2, 0.5, 1.0, 2., 5.0, 10., 20., 50., 100.}; - h.create( hpt_t, "hpt_t", "pt - true ", nBins , bins ) ; - h.create( hpt_f, "hpt_f", "pt - found ", nBins , bins ) ; - + h.create(hpt_t, "hpt_t", "pt - true ", nBins, bins); + h.create(hpt_f, "hpt_f", "pt - found ", nBins, bins); } //========================================================================================================================= + LCCollection* relCol = getCollection(_relTrkMCPColName, evt); + if (!relCol) + return; - LCCollection* relCol = getCollection( _relTrkMCPColName, evt ) ; - if( ! relCol ) return ; - - LCCollection* relInverseCol = getCollection( _relMCPTrkColName, evt ) ; - if( ! relInverseCol ) return ; - - LCCollection* trkCol = getCollection( _trkColName , evt ) ; - if( ! trkCol ) return ; + LCCollection* relInverseCol = getCollection(_relMCPTrkColName, evt); + if (!relInverseCol) + return; + LCCollection* trkCol = getCollection(_trkColName, evt); + if (!trkCol) + return; - if( trkCol->getNumberOfElements() < 1 ) { - - streamlog_out( ERROR ) << " not tracks in collection " << _trkColName << " evt : " << evt->getEventNumber() - << " run : " << evt->getRunNumber() << std::endl ; - return ; - } + if (trkCol->getNumberOfElements() < 1) { - LCCollectionVec* splitCol = newTrkCol( _splitColName, evt ) ; - LCCollectionVec* mergedCol = newTrkCol( _mergedColName, evt ) ; - splitCol->setSubset() ; - mergedCol->setSubset() ; + streamlog_out(ERROR) << " not tracks in collection " << _trkColName << " evt : " << evt->getEventNumber() + << " run : " << evt->getRunNumber() << std::endl; + return; + } + LCCollectionVec* splitCol = newTrkCol(_splitColName, evt); + LCCollectionVec* mergedCol = newTrkCol(_mergedColName, evt); + splitCol->setSubset(); + mergedCol->setSubset(); + LCRelationNavigator nav(relCol); - LCRelationNavigator nav( relCol ) ; - - LCRelationNavigator navInverse( relInverseCol ) ; + LCRelationNavigator navInverse(relInverseCol); //--------------------------------------------------------------------------------- // create collections with low, ok and high weight of the truth relation // - LCCollectionVec* laWCol = newTrkCol( "ClupatraTracksLargeWeight" , evt ) ; - LCCollectionVec* okWCol = newTrkCol( "ClupatraTracksOkWeight" , evt ) ; - LCCollectionVec* loWCol = newTrkCol( "ClupatraTracksLowWeight" , evt ) ; - - laWCol->setSubset() ; - okWCol->setSubset() ; - loWCol->setSubset() ; - - for( LCIterator it( relCol) ; LCRelation* rel = it.next() ; ){ - - float weight = rel->getWeight() ; - Track* trk = (Track*)rel->getFrom() ; - - - if( weight <= 0.9 ) - loWCol->addElement( trk ) ; - else if( weight > 0.9 && weight <= 1.0 ) - okWCol->addElement( trk ) ; - else if( weight > 1. ) - laWCol->addElement( trk ) ; + LCCollectionVec* laWCol = newTrkCol("ClupatraTracksLargeWeight", evt); + LCCollectionVec* okWCol = newTrkCol("ClupatraTracksOkWeight", evt); + LCCollectionVec* loWCol = newTrkCol("ClupatraTracksLowWeight", evt); + + laWCol->setSubset(); + okWCol->setSubset(); + loWCol->setSubset(); + + for (LCIterator it(relCol); LCRelation* rel = it.next();) { + + float weight = rel->getWeight(); + Track* trk = (Track*)rel->getFrom(); + + if (weight <= 0.9) + loWCol->addElement(trk); + else if (weight > 0.9 && weight <= 1.0) + okWCol->addElement(trk); + else if (weight > 1.) + laWCol->addElement(trk); } //--------------------------------------------------------------------------------- // create collections with low, ok and high weight of the inverse truth relation // - LCCollectionVec* laWMCPCol = newTrkCol( "ClupatraTracksLargeMCPWeight" , evt ) ; - LCCollectionVec* okWMCPCol = newTrkCol( "ClupatraTracksOkMCPWeight" , evt ) ; - LCCollectionVec* loWMCPCol = newTrkCol( "ClupatraTracksLowMCPWeight" , evt ) ; - - laWMCPCol->setSubset() ; - okWMCPCol->setSubset() ; - loWMCPCol->setSubset() ; - - for( LCIterator it( relInverseCol) ; LCRelation* rel = it.next() ; ){ - - float weight = rel->getWeight() ; - Track* trk = (Track*)rel->getTo() ; - - - if( weight <= 0.7 ) - loWMCPCol->addElement( trk ) ; - else if( weight > 0.7 && weight <= 1.0 ) - okWMCPCol->addElement( trk ) ; - else if( weight > 1. ) - laWMCPCol->addElement( trk ) ; + LCCollectionVec* laWMCPCol = newTrkCol("ClupatraTracksLargeMCPWeight", evt); + LCCollectionVec* okWMCPCol = newTrkCol("ClupatraTracksOkMCPWeight", evt); + LCCollectionVec* loWMCPCol = newTrkCol("ClupatraTracksLowMCPWeight", evt); + + laWMCPCol->setSubset(); + okWMCPCol->setSubset(); + loWMCPCol->setSubset(); + + for (LCIterator it(relInverseCol); LCRelation* rel = it.next();) { + + float weight = rel->getWeight(); + Track* trk = (Track*)rel->getTo(); + + if (weight <= 0.7) + loWMCPCol->addElement(trk); + else if (weight > 0.7 && weight <= 1.0) + okWMCPCol->addElement(trk); + else if (weight > 1.) + laWMCPCol->addElement(trk); } //--------------------------------------------------------------------------------- + LCIterator mcpIt(evt, _mcpColName); + + LCCollectionVec* mcpTracks = new LCCollectionVec(LCIO::MCPARTICLE); + mcpTracks->setSubset(true); + mcpTracks->reserve(mcpIt.size()); - LCIterator mcpIt( evt, _mcpColName ) ; - - LCCollectionVec* mcpTracks = new LCCollectionVec( LCIO::MCPARTICLE ) ; - mcpTracks->setSubset( true ) ; - mcpTracks->reserve( mcpIt.size() ) ; - - std::string name = "MCParticleTracks_" ; - name += this->name() ; - - evt->addCollection( mcpTracks , name ) ; + std::string name = "MCParticleTracks_"; + name += this->name(); - LCCollectionVec* mcpTrksFound = new LCCollectionVec( LCIO::MCPARTICLE ) ; - mcpTrksFound->setSubset( true ) ; - mcpTrksFound->reserve( mcpIt.size() ) ; + evt->addCollection(mcpTracks, name); - name = "MCParticleTracksFound_" ; - name += this->name() ; - evt->addCollection( mcpTrksFound , name ) ; + LCCollectionVec* mcpTrksFound = new LCCollectionVec(LCIO::MCPARTICLE); + mcpTrksFound->setSubset(true); + mcpTrksFound->reserve(mcpIt.size()); + name = "MCParticleTracksFound_"; + name += this->name(); + evt->addCollection(mcpTrksFound, name); //------ count sim hits from every MCParticle - typedef std::map< MCParticle* , int > HITMAP ; - HITMAP hitMap ; + typedef std::map HITMAP; + HITMAP hitMap; + + for (unsigned i = 0, N = _sthColNames.size(); i < N; ++i) { - for( unsigned i=0 ,N = _sthColNames.size() ; i sthIt( evt, _sthColNames[i] ) ; - - while( SimTrackerHit* sth = sthIt.next() ){ - - hitMap[ sth->getMCParticle() ]++ ; + LCIterator sthIt(evt, _sthColNames[i]); + + while (SimTrackerHit* sth = sthIt.next()) { + + hitMap[sth->getMCParticle()]++; } - } catch( lcio::DataNotAvailableException& e){ + } catch (lcio::DataNotAvailableException& e) { - streamlog_out( DEBUG4 ) << " missing input collection: " << _sthColNames[i] << std::endl ; + streamlog_out(DEBUG4) << " missing input collection: " << _sthColNames[i] << std::endl; } } + //================ create denominator for efficency ======================== + while (MCParticle* mcp = mcpIt.next()) { - //================ create denominator for efficency ======================== + bool cut = true; + APPLY_CUT(DEBUG2, cut, std::abs(mcp->getCharge()) > 0.5); - while( MCParticle* mcp = mcpIt.next() ){ - - bool cut = true ; - APPLY_CUT( DEBUG2, cut, std::abs( mcp->getCharge() ) > 0.5 ) ; - - APPLY_CUT( DEBUG2, cut, mcp->getGeneratorStatus() != 2 ) ; // no documentation lines + APPLY_CUT(DEBUG2, cut, mcp->getGeneratorStatus() != 2); // no documentation lines - dd4hep::rec::Vector3D v( mcp->getVertex()[0], mcp->getVertex()[1], mcp->getVertex()[2] ); - dd4hep::rec::Vector3D e( mcp->getEndpoint()[0], mcp->getEndpoint()[1], mcp->getEndpoint()[2] ); - dd4hep::rec::Vector3D p( mcp->getMomentum()[0], mcp->getMomentum()[1], mcp->getMomentum()[2] ); + dd4hep::rec::Vector3D v(mcp->getVertex()[0], mcp->getVertex()[1], mcp->getVertex()[2]); + dd4hep::rec::Vector3D e(mcp->getEndpoint()[0], mcp->getEndpoint()[1], mcp->getEndpoint()[2]); + dd4hep::rec::Vector3D p(mcp->getMomentum()[0], mcp->getMomentum()[1], mcp->getMomentum()[2]); - APPLY_CUT( DEBUG2, cut, v.r() < 100. ) ; // start at IP+/-10cm + APPLY_CUT(DEBUG2, cut, v.r() < 100.); // start at IP+/-10cm // ==== vzeros ========= // APPLY_CUT( DEBUG, cut, v.rho() > 100. ) ; // non prompt track @@ -468,240 +445,217 @@ void TrackCheckMCTruth::processEvent( LCEvent * evt ) { // APPLY_CUT( DEBUG, cut, isVzero ) ; // start at IP+/-10cm // ==== vzeros ========= - APPLY_CUT( DEBUG2, cut, e.rho()==0.0 || e.rho() > 400. ) ; // end at rho > 40 cm + APPLY_CUT(DEBUG2, cut, e.rho() == 0.0 || e.rho() > 400.); // end at rho > 40 cm - APPLY_CUT( DEBUG2, cut, p.rho() > 0.1 ) ; // pt> 100 MeV + APPLY_CUT(DEBUG2, cut, p.rho() > 0.1); // pt> 100 MeV - APPLY_CUT( DEBUG2, cut, std::abs( cos( p.theta() ) ) < 0.99 ) ; // | cos( theta ) | > 0.99 + APPLY_CUT(DEBUG2, cut, std::abs(cos(p.theta())) < 0.99); // | cos( theta ) | > 0.99 - APPLY_CUT( DEBUG2, cut, hitMap[ mcp ] > 5 ) ; // require at least 10 TPC hits (particle actually made it to the TPC) + APPLY_CUT(DEBUG2, cut, hitMap[mcp] > 5); // require at least 10 TPC hits (particle actually made it to the TPC) //.... - if( cut ) - mcpTracks->push_back( mcp ) ; + if (cut) + mcpTracks->push_back(mcp); } - + //================================================================ // name = "MCParticleTracks_" ; // name += this->name() ; // LCIterator trmIt( evt, name ) ; - LCIterator trmIt( mcpTracks ); + LCIterator trmIt(mcpTracks); + + while (MCParticle* trm = trmIt.next()) { - while( MCParticle* trm = trmIt.next() ){ - - double pxmcp = trm->getMomentum()[0] ; - double pymcp = trm->getMomentum()[1] ; + double pxmcp = trm->getMomentum()[0]; + double pymcp = trm->getMomentum()[1]; // double pzmcp = trm->getMomentum()[2] ; - - // double pmcp = sqrt( pxmcp*pxmcp + pymcp*pymcp + pzmcp*pzmcp ) ; - double ptmcp = sqrt( pxmcp*pxmcp + pymcp*pymcp ) ; - + + // double pmcp = sqrt( pxmcp*pxmcp + pymcp*pymcp + pzmcp*pzmcp ) ; + double ptmcp = sqrt(pxmcp * pxmcp + pymcp * pymcp); + // double thmcp = atan2( ptmcp , pzmcp ) ; // double d0mcp = 0. ; //fixme: only true for prompt tracks // double phmcp = atan2( pymcp, pxmcp) ; - // double ommcp = alpha / ptmcp ; - // if( trm->getCharge() < 0. ) + // double ommcp = alpha / ptmcp ; + // if( trm->getCharge() < 0. ) // ommcp = -ommcp ; // double z0mcp = 0 ; //fixme: only true for prompt tracks - // double tLmcp = pzmcp / ptmcp ; - - - HelixClass helix ; - - float pos[3] ; - pos[0] = trm->getVertex()[0] ; - pos[1] = trm->getVertex()[1] ; - pos[2] = trm->getVertex()[2] ; - float mom[3] ; - mom[0] = trm->getMomentum()[0] ; - mom[1] = trm->getMomentum()[1] ; - mom[2] = trm->getMomentum()[2] ; - - dd4hep::rec::Vector3D p( trm->getMomentum()[0], trm->getMomentum()[1], trm->getMomentum()[2] ); - double costhmcp = cos( p.theta() ) ; - - float q = trm->getCharge() ; - - helix.Initialize_VP( pos , mom, q, 3.5 ) ; - - double d0mcp = helix.getD0() ; - double phmcp = helix.getPhi0() ; - double ommcp = helix.getOmega() ; - double z0mcp = helix.getZ0() ; - double tLmcp = helix.getTanLambda() ; - - - h.fill( hd0mcp, d0mcp ) ; - h.fill( hphimcp, phmcp ) ; - h.fill( homegamcp, ommcp ) ; - h.fill( hz0mcp, z0mcp ) ; - h.fill( htanLmcp, tLmcp ) ; - h.fill( hptmcp, ptmcp ) ; - - - h.fill( hpt_t , ptmcp ) ; - h.fill( hcosth_t , costhmcp ) ; - h.fill( hacth_t , std::abs( costhmcp) ) ; - - const EVENT::LCObjectVec& trkV = nav.getRelatedFromObjects( trm ) ; - - std::vector splitTrackIndices ; - splitTrackIndices.reserve( trkV.size() ) ; - - if( trkV.size() > 0 ){ - - const FloatVec& wV = nav.getRelatedFromWeights( trm ) ; - double wMax = 0.0 ; - int iMax = 0 ; - - for(unsigned i=0 ; i wMax ){ - wMax = wV[i] ; - iMax = i ; - } - - if( wV[i] > 0.5 ) { // if we have a track segment that has a weight >0.5 it could be part of a split track.... - splitTrackIndices.push_back( i ) ; - } - } - + // double tLmcp = pzmcp / ptmcp ; + + HelixClass helix; + + float pos[3]; + pos[0] = trm->getVertex()[0]; + pos[1] = trm->getVertex()[1]; + pos[2] = trm->getVertex()[2]; + float mom[3]; + mom[0] = trm->getMomentum()[0]; + mom[1] = trm->getMomentum()[1]; + mom[2] = trm->getMomentum()[2]; + + dd4hep::rec::Vector3D p(trm->getMomentum()[0], trm->getMomentum()[1], trm->getMomentum()[2]); + double costhmcp = cos(p.theta()); + + float q = trm->getCharge(); + + helix.Initialize_VP(pos, mom, q, 3.5); + + double d0mcp = helix.getD0(); + double phmcp = helix.getPhi0(); + double ommcp = helix.getOmega(); + double z0mcp = helix.getZ0(); + double tLmcp = helix.getTanLambda(); + + h.fill(hd0mcp, d0mcp); + h.fill(hphimcp, phmcp); + h.fill(homegamcp, ommcp); + h.fill(hz0mcp, z0mcp); + h.fill(htanLmcp, tLmcp); + h.fill(hptmcp, ptmcp); + + h.fill(hpt_t, ptmcp); + h.fill(hcosth_t, costhmcp); + h.fill(hacth_t, std::abs(costhmcp)); + + const EVENT::LCObjectVec& trkV = nav.getRelatedFromObjects(trm); + + std::vector splitTrackIndices; + splitTrackIndices.reserve(trkV.size()); + + if (trkV.size() > 0) { + + const FloatVec& wV = nav.getRelatedFromWeights(trm); + double wMax = 0.0; + int iMax = 0; + + for (unsigned i = 0; i < wV.size(); ++i) { + + if (wV[i] > wMax) { + wMax = wV[i]; + iMax = i; + } + + if (wV[i] > 0.5) { // if we have a track segment that has a weight >0.5 it could be part of a split track.... + splitTrackIndices.push_back(i); + } + } + // if( trkV.size() > 1 ){ // if we have more than one track it is a split track.... // std::copy( trkV.begin() , trkV.end() , std::back_inserter( *splitCol ) ) ; // } - if( splitTrackIndices.size() > 1 ){ + if (splitTrackIndices.size() > 1) { - for(unsigned i=0,N=splitTrackIndices.size() ; iaddElement( trkV[i ] ) ; - } + for (unsigned i = 0, N = splitTrackIndices.size(); i < N; ++i) { + splitCol->addElement(trkV[i]); + } } + Track* tr = (Track*)(trkV.at(iMax)); - Track* tr = (Track*)( trkV.at(iMax) ) ; - - - double d0 = tr->getD0() ; - double ph = tr->getPhi() ; - double om = tr->getOmega() ; - double z0 = tr->getZ0() ; - double tL = tr->getTanLambda() ; - double pt = std::abs( alpha / om ) ; - - double ed0 = sqrt( tr->getCovMatrix()[0] ); - double eph = sqrt( tr->getCovMatrix()[2] ); - double eom = sqrt( tr->getCovMatrix()[5] ); - double ez0 = sqrt( tr->getCovMatrix()[9] ); - double etL = sqrt( tr->getCovMatrix()[14] ); - - double ept = alpha * eom / ( om * om ) ; // ept = al/om^2 * eom - - - double dd0 = d0 - d0mcp ; - double dph = ph - phmcp ; - if( std::abs(dph) > M_PI ) - dph = 2.* M_PI - std::abs( dph ) ; - - - double dom = om - ommcp ; - double dz0 = z0 - z0mcp ; - double dtL = tL - tLmcp ; - double dpt = pt - ptmcp ; - - bool cut = true ; - - // APPLY_CUT( DEBUG4, cut, std::abs( dph ) < (3.*eph) ) ; - // APPLY_CUT( DEBUG4, cut, std::abs( dom ) < (5.*eom) ) ; // require 5 sigma on omega only for now - // APPLY_CUT( DEBUG4, cut, std::abs( dtL ) < (3.*etL) ) ; - - if( ! cut ) { - streamlog_out(DEBUG3) << " phi : " << dph << " - " << 3.*eph << std::endl ; - streamlog_out(DEBUG3) << " ome : " << dom << " - " << 3.*eom << std::endl ; - streamlog_out(DEBUG3) << " tanL: " << dtL << " - " << 3.*etL << std::endl ; - streamlog_out(DEBUG3) << " pt: " << pt << " dpt: " << dpt << " ept : " << ept << " theta " << 180. * atan( 1. / tL ) / M_PI << std::endl ; - } + double d0 = tr->getD0(); + double ph = tr->getPhi(); + double om = tr->getOmega(); + double z0 = tr->getZ0(); + double tL = tr->getTanLambda(); + double pt = std::abs(alpha / om); + + double ed0 = sqrt(tr->getCovMatrix()[0]); + double eph = sqrt(tr->getCovMatrix()[2]); + double eom = sqrt(tr->getCovMatrix()[5]); + double ez0 = sqrt(tr->getCovMatrix()[9]); + double etL = sqrt(tr->getCovMatrix()[14]); + + double ept = alpha * eom / (om * om); // ept = al/om^2 * eom - if( cut == true ){ - - mcpTrksFound->push_back( trm ) ; - - h.fill( hd0, d0 ) ; - h.fill( hphi, ph ) ; - h.fill( homega, om ) ; - h.fill( hz0, z0 ) ; - h.fill( htanL, tL ) ; - h.fill( hpt, pt ) ; - - h.fill( hed0, ed0 ) ; - h.fill( hephi, eph ) ; - h.fill( heomega, eom ) ; - h.fill( hez0, ez0 ) ; - h.fill( hetanL, etL ) ; - h.fill( hept, ept ) ; - - - - h.fill( hdd0, dd0 ) ; - h.fill( hdphi, dph ) ; - h.fill( hdomega, dom ) ; - h.fill( hdz0, dz0 ) ; - h.fill( hdtanL, dtL ) ; - h.fill( hdpt, dpt ) ; - - h.fill( hpd0, dd0 / ed0 ) ; - h.fill( hpphi, dph / eph ) ; - h.fill( hpomega, dom / eom ) ; - h.fill( hpz0, dz0 / ez0 ) ; - h.fill( hptanL, dtL / etL ) ; - h.fill( hppt, dpt / ept ) ; - - h.fill( hdptp2, dpt / (pt*pt) ) ; - - - h.fill( hpt_f , ptmcp ) ; - h.fill( hcosth_f , costhmcp ) ; - h.fill( hacth_f , std::abs( costhmcp) ) ; + double dd0 = d0 - d0mcp; + double dph = ph - phmcp; + if (std::abs(dph) > M_PI) + dph = 2. * M_PI - std::abs(dph); + double dom = om - ommcp; + double dz0 = z0 - z0mcp; + double dtL = tL - tLmcp; + double dpt = pt - ptmcp; + + bool cut = true; + + // APPLY_CUT( DEBUG4, cut, std::abs( dph ) < (3.*eph) ) ; + // APPLY_CUT( DEBUG4, cut, std::abs( dom ) < (5.*eom) ) ; // require 5 sigma on omega only + // for now APPLY_CUT( DEBUG4, cut, std::abs( dtL ) < (3.*etL) ) ; + + if (!cut) { + streamlog_out(DEBUG3) << " phi : " << dph << " - " << 3. * eph << std::endl; + streamlog_out(DEBUG3) << " ome : " << dom << " - " << 3. * eom << std::endl; + streamlog_out(DEBUG3) << " tanL: " << dtL << " - " << 3. * etL << std::endl; + streamlog_out(DEBUG3) << " pt: " << pt << " dpt: " << dpt << " ept : " << ept << " theta " + << 180. * atan(1. / tL) / M_PI << std::endl; } + if (cut == true) { + + mcpTrksFound->push_back(trm); + + h.fill(hd0, d0); + h.fill(hphi, ph); + h.fill(homega, om); + h.fill(hz0, z0); + h.fill(htanL, tL); + h.fill(hpt, pt); + + h.fill(hed0, ed0); + h.fill(hephi, eph); + h.fill(heomega, eom); + h.fill(hez0, ez0); + h.fill(hetanL, etL); + h.fill(hept, ept); + + h.fill(hdd0, dd0); + h.fill(hdphi, dph); + h.fill(hdomega, dom); + h.fill(hdz0, dz0); + h.fill(hdtanL, dtL); + h.fill(hdpt, dpt); + + h.fill(hpd0, dd0 / ed0); + h.fill(hpphi, dph / eph); + h.fill(hpomega, dom / eom); + h.fill(hpz0, dz0 / ez0); + h.fill(hptanL, dtL / etL); + h.fill(hppt, dpt / ept); + + h.fill(hdptp2, dpt / (pt * pt)); + + h.fill(hpt_f, ptmcp); + h.fill(hcosth_f, costhmcp); + h.fill(hacth_f, std::abs(costhmcp)); + } } } - streamlog_out( DEBUG4 ) << " ===== found " << mcpTrksFound->size() << " tracks of " << mcpTracks->size() - << std::endl ; - - //---------------------------------------------------------------------- - - _nEvt ++ ; - - clock_t end = clock () ; - - streamlog_out( DEBUG ) << "--- histogramming time: " - << double( end - start ) / double(CLOCKS_PER_SEC) << std::endl ; + streamlog_out(DEBUG4) << " ===== found " << mcpTrksFound->size() << " tracks of " << mcpTracks->size() << std::endl; -} + //---------------------------------------------------------------------- + _nEvt++; + clock_t end = clock(); + streamlog_out(DEBUG) << "--- histogramming time: " << double(end - start) / double(CLOCKS_PER_SEC) << std::endl; +} /*************************************************************************************************/ -void TrackCheckMCTruth::check( LCEvent * ) { +void TrackCheckMCTruth::check(LCEvent*) { /*************************************************************************************************/ - - } +} //==================================================================================== +void TrackCheckMCTruth::end() { - - -void TrackCheckMCTruth::end(){ - - streamlog_out( MESSAGE ) << " processed " << _nEvt << " events in " << _nRun << " runs " - << std::endl ; + streamlog_out(MESSAGE) << " processed " << _nEvt << " events in " << _nRun << " runs " << std::endl; } //==================================================================================================== - diff --git a/src/TrackEfficiency.cc b/src/TrackEfficiency.cc index deb735a..392a0a5 100644 --- a/src/TrackEfficiency.cc +++ b/src/TrackEfficiency.cc @@ -1,439 +1,398 @@ #include "TrackEfficiency.h" - #include "marlin/AIDAProcessor.h" -//---- MarlinUtil +//---- MarlinUtil #include "MarlinCED.h" -//#include -#include -#include +// #include #include -#include #include +#include +#include +#include //---- LCIO --- -#include "IMPL/LCCollectionVec.h" -#include "EVENT/Track.h" #include "EVENT/SimTrackerHit.h" -#include "UTIL/Operators.h" -#include "UTIL/LCRelationNavigator.h" -#include "UTIL/LCTypedVector.h" -#include "UTIL/LCTypedVector.h" -#include "UTIL/LCTrackerConf.h" +#include "EVENT/Track.h" +#include "IMPL/LCCollectionVec.h" #include "UTIL/ILDConf.h" +#include "UTIL/LCRelationNavigator.h" #include "UTIL/LCTOOLS.h" +#include "UTIL/LCTrackerConf.h" +#include "UTIL/LCTypedVector.h" +#include "UTIL/Operators.h" // --- DD4hep --- +#include "DD4hep/DD4hepUnits.h" #include "DD4hep/Detector.h" #include "DDRec/Vector3D.h" -#include "DD4hep/DD4hepUnits.h" - -//MarlinUtil +// MarlinUtil #include "HelixClass.h" - //---- ROOT ----- -#include "TH1F.h" +#include "TH1F.h" #include "UTIL/LCIterator.h" -using namespace lcio ; -using namespace marlin ; - +using namespace lcio; +using namespace marlin; -void printSimTrackerHit(const EVENT::LCObject* o) ; +void printSimTrackerHit(const EVENT::LCObject* o); //---------------------------------------------------------------- -TrackEfficiency aTrackEfficiency ; +TrackEfficiency aTrackEfficiency; -// helper enum defining histogram index in vector +// helper enum defining histogram index in vector namespace TrackEfficiencyHistos { - enum index{ - hd0, hphi, homega, hz0, htanL, hpt, - hed0, hephi, heomega, hez0, hetanL, hept, - hdd0, hdphi, hdomega, hdz0, hdtanL, hdpt, - hpd0, hpphi, hpomega, hpz0, hptanL, hppt, - hd0mcp,hphimcp, homegamcp, hz0mcp, htanLmcp, hptmcp, - hdptp2, - hpt_f,hcosth_f, hpt_t, hcosth_t, hacth_t, hacth_f, - //----- keep Size as last : - Size - }; - - - class Histograms{ - public: - Histograms(std::vector& v) : _h(&v) {} - - void create(int idx, const char* n, int nBin=100, double min=0., double max=0. ){ - create( idx , n , n , nBin, min , max ) ; - } - - void create(int idx, const char* n, const char* t, int nBin=100, double min=0., double max=0. ){ - - // _h->resize( idx+1 ) ; - _h->at( idx ) = new TH1D( n, t , nBin , min, max ) ; - - streamlog_out( DEBUG ) << " create histo " << n << " at index " << idx << std::endl ; - } - - void create(int idx, const char* n, const char* t, int nBin , double* bins ){ +enum index { + hd0, + hphi, + homega, + hz0, + htanL, + hpt, + hed0, + hephi, + heomega, + hez0, + hetanL, + hept, + hdd0, + hdphi, + hdomega, + hdz0, + hdtanL, + hdpt, + hpd0, + hpphi, + hpomega, + hpz0, + hptanL, + hppt, + hd0mcp, + hphimcp, + homegamcp, + hz0mcp, + htanLmcp, + hptmcp, + hdptp2, + hpt_f, + hcosth_f, + hpt_t, + hcosth_t, + hacth_t, + hacth_f, + //----- keep Size as last : + Size +}; + +class Histograms { +public: + Histograms(std::vector& v) : _h(&v) {} + + void create(int idx, const char* n, int nBin = 100, double min = 0., double max = 0.) { + create(idx, n, n, nBin, min, max); + } - _h->at( idx ) = new TH1D( n, t , nBin , bins ) ; + void create(int idx, const char* n, const char* t, int nBin = 100, double min = 0., double max = 0.) { - streamlog_out( DEBUG ) << " create histo " << n << " at index " << idx << std::endl ; - } + // _h->resize( idx+1 ) ; + _h->at(idx) = new TH1D(n, t, nBin, min, max); - void fill( int idx , double val, double weight=1.0 ){ _h->at( idx )->Fill( val , weight ) ; } + streamlog_out(DEBUG) << " create histo " << n << " at index " << idx << std::endl; + } - protected: + void create(int idx, const char* n, const char* t, int nBin, double* bins) { - std::vector* _h; - }; + _h->at(idx) = new TH1D(n, t, nBin, bins); + streamlog_out(DEBUG) << " create histo " << n << " at index " << idx << std::endl; + } + void fill(int idx, double val, double weight = 1.0) { _h->at(idx)->Fill(val, weight); } -} -using namespace TrackEfficiencyHistos ; +protected: + std::vector* _h; +}; +} // namespace TrackEfficiencyHistos +using namespace TrackEfficiencyHistos; //====================================================================================================== -// -#define APPLY_CUT(LEVEL, Cut, Exp) \ - if ((Exp) == false) { \ - if (Cut) { \ - streamlog_out(LEVEL) \ - << " ***** failed cut: [ " << #Exp \ - << " ] in evt: " << evt->getEventNumber() \ - << " run: " << evt->getRunNumber() << std::endl; \ - } \ - Cut = false; \ - } +// +#define APPLY_CUT(LEVEL, Cut, Exp) \ + if ((Exp) == false) { \ + if (Cut) { \ + streamlog_out(LEVEL) << " ***** failed cut: [ " << #Exp << " ] in evt: " << evt->getEventNumber() \ + << " run: " << evt->getRunNumber() << std::endl; \ + } \ + Cut = false; \ + } //====================================================================================================== //====================================================================================================== +TrackEfficiency::TrackEfficiency() : Processor("TrackEfficiency"), _nRun(0), _nEvt(0) { -TrackEfficiency::TrackEfficiency() : Processor("TrackEfficiency"), - _nRun(0), _nEvt(0) { - // modify processor description - _description = "TrackEfficiency: analysis plots for Tracks" ; - - - - registerInputCollection( LCIO::MCPARTICLE, - "MCParticlesCollection" , - "Name of the input collections with MCParticles" , - _mcpColName , - std::string("MCParticlesSkimmed" ) ) ; - - registerInputCollection( LCIO::SIMTRACKERHIT, - "SimTrackerHitCollection" , - "Name of the input collections with SimTrackerHits" , - _sthColName , - std::string("TPCCollection" ) ) ; - - registerInputCollection( LCIO::LCRELATION, - "TrackMCTruthRelation" , - "Name of the input collections with LCRelation Tracks to MCParticles" , - _t2mColName , - std::string("TrackMCTruthRelation" ) ) ; - - registerInputCollection( LCIO::LCRELATION, - "MCTruthTrackRelation" , - "Name of the input collections with LCRelation MCParticles to Tracks" , - _m2tColName , - std::string("MCTruthTrackRelation" ) ) ; - - - registerInputCollection( LCIO::TRACK, - "TrackCollection" , - "Name of the input collections with Tracks" , - _trkColName , - std::string("TrackCollection" ) ) ; - - - - FloatVec ptRange ; - ptRange.push_back( 0. ) ; - ptRange.push_back( 1000. ) ; - - registerProcessorParameter( "PtRange" , - "Min and max value of pt range [GeV]" , - _ptRange , - ptRange ) ; - - registerProcessorParameter("PhysSampleOn", - "Enable when we run diagnostics to a simulated physics sample", - _physSampleOn, - bool(false)); - - registerProcessorParameter("CosThetaCut", - "Maximum costheta of examined MCParticles sample", - _cosTheta, - double(0.99)); - - registerProcessorParameter("PCut", - "Minimum momentum of examined MCParticles sample (in GeV)", - _pCut, - double(1.0)); - - registerProcessorParameter("PTCut", - "Minimum transverse momentum of examined MCParticles sample (in GeV)", - _ptCut, - double(0.1)); + _description = "TrackEfficiency: analysis plots for Tracks"; - registerProcessorParameter("DistFromIP", - "Maximum distance from IP of examined MCParticles sample (in mm)", - _originCut, - double(100.0)); + registerInputCollection(LCIO::MCPARTICLE, "MCParticlesCollection", "Name of the input collections with MCParticles", + _mcpColName, std::string("MCParticlesSkimmed")); - registerProcessorParameter("RequiredPurity", - "ratio of hits belonging to the dominant MC particle to total number of track hits", - _minPurity, - double(0.75)); + registerInputCollection(LCIO::SIMTRACKERHIT, "SimTrackerHitCollection", + "Name of the input collections with SimTrackerHits", _sthColName, + std::string("TPCCollection")); - registerProcessorParameter("RequiredSiHits", - "minimum required hits on Si detectors in order to consider the track found", - _minHits, - int(4)); + registerInputCollection(LCIO::LCRELATION, "TrackMCTruthRelation", + "Name of the input collections with LCRelation Tracks to MCParticles", _t2mColName, + std::string("TrackMCTruthRelation")); -} + registerInputCollection(LCIO::LCRELATION, "MCTruthTrackRelation", + "Name of the input collections with LCRelation MCParticles to Tracks", _m2tColName, + std::string("MCTruthTrackRelation")); + registerInputCollection(LCIO::TRACK, "TrackCollection", "Name of the input collections with Tracks", _trkColName, + std::string("TrackCollection")); -void TrackEfficiency::init() { + FloatVec ptRange; + ptRange.push_back(0.); + ptRange.push_back(1000.); - // usually a good idea to - printParameters() ; + registerProcessorParameter("PtRange", "Min and max value of pt range [GeV]", _ptRange, ptRange); + registerProcessorParameter("PhysSampleOn", "Enable when we run diagnostics to a simulated physics sample", + _physSampleOn, bool(false)); - CEDPickingHandler::getInstance().registerFunction( LCIO::SIMTRACKERHIT , &printSimTrackerHit ) ; + registerProcessorParameter("CosThetaCut", "Maximum costheta of examined MCParticles sample", _cosTheta, double(0.99)); - if( _ptRange.size() != 2 ) { + registerProcessorParameter("PCut", "Minimum momentum of examined MCParticles sample (in GeV)", _pCut, double(1.0)); - throw Exception("TrackEfficiency::init() processor parameter 'ptRange' needs to have two values (min and max pt in GeV)" ) ; - } + registerProcessorParameter("PTCut", "Minimum transverse momentum of examined MCParticles sample (in GeV)", _ptCut, + double(0.1)); + registerProcessorParameter("DistFromIP", "Maximum distance from IP of examined MCParticles sample (in mm)", + _originCut, double(100.0)); - _nRun = 0 ; - _nEvt = 0 ; + registerProcessorParameter("RequiredPurity", + "ratio of hits belonging to the dominant MC particle to total number of track hits", + _minPurity, double(0.75)); + + registerProcessorParameter( + "RequiredSiHits", "minimum required hits on Si detectors in order to consider the track found", _minHits, int(4)); } -void TrackEfficiency::processRunHeader( LCRunHeader* ) { +void TrackEfficiency::init() { + + // usually a good idea to + printParameters(); + + CEDPickingHandler::getInstance().registerFunction(LCIO::SIMTRACKERHIT, &printSimTrackerHit); + + if (_ptRange.size() != 2) { - _nRun++ ; -} + throw Exception( + "TrackEfficiency::init() processor parameter 'ptRange' needs to have two values (min and max pt in GeV)"); + } + + _nRun = 0; + _nEvt = 0; +} -void TrackEfficiency::processEvent( LCEvent * evt ) { +void TrackEfficiency::processRunHeader(LCRunHeader*) { _nRun++; } +void TrackEfficiency::processEvent(LCEvent* evt) { - clock_t start = clock() ; + clock_t start = clock(); dd4hep::Detector& theDetector = dd4hep::Detector::getInstance(); - double bfieldV[3] ; - theDetector.field().magneticField( { 0., 0., 0. } , bfieldV ) ; - const double bField = bfieldV[2]/dd4hep::tesla ; + double bfieldV[3]; + theDetector.field().magneticField({0., 0., 0.}, bfieldV); + const double bField = bfieldV[2] / dd4hep::tesla; - - static const double alpha = 2.99792458e-4 * bField ; ; + static const double alpha = 2.99792458e-4 * bField; + ; // p_t[GeV] = alpha / omega[mm] ; - //static const double ptMin = _ptRange[0] ; - //static const double ptMax = _ptRange[1] ; - //static double ptMean = ( ptMax + ptMin ) / 2. ; - + // static const double ptMin = _ptRange[0] ; + // static const double ptMax = _ptRange[1] ; + // static double ptMean = ( ptMax + ptMin ) / 2. ; //---------------------------------------------------------------------- - Histograms h(_h1) ; + Histograms h(_h1); - if( isFirstEvent() ){ + if (isFirstEvent()) { // this creates a directory for this processor .... - AIDAProcessor::histogramFactory( this ) ; - - _h1.resize( TrackEfficiencyHistos::Size ) ; - - static const int nBin = 50 ; + AIDAProcessor::histogramFactory(this); + + _h1.resize(TrackEfficiencyHistos::Size); + + static const int nBin = 50; // define binning for pt and omega // double ptBinL = ptMin - ( ptMax - ptMin ) / 10. ; // double ptBinH = ptMax + ( ptMax - ptMin ) / 10. ; - double ptBinL = 0.01 ; - double ptBinH = 20. ; - double omBinL = alpha / ptBinH ; - double omBinH = alpha / ptBinL ; - - - h.create( hd0, "hd0" ) ; - h.create( hphi, "hphi" ) ; - h.create( homega, "homega" ,"omega*mm" , nBin ,omBinL , omBinH ) ; - h.create( hz0, "hz0" , " z0 /mm " , nBin , -3. , 3. ) ; - h.create( htanL, "htanL" ) ; - h.create( hpt, "hpt" , "pt/GeV" , nBin , ptBinL , ptBinH ) ; - - h.create( hd0mcp, "hd0mcp" ) ; - h.create( hphimcp, "hphimcp" ) ; - h.create( homegamcp, "homegamcp" ,"omega*mm" , nBin ,omBinL , omBinH ) ; //, "omega*mm" , 50, 0.0003 , 0.0004 ) ; - h.create( hz0mcp, "hz0mcp" ) ; //, " z0 /mm " , 50 , -3. , 3. ) ; - h.create( htanLmcp, "htanLmcp" ) ; - h.create( hptmcp, "hptmcp" , "pt/GeV" , nBin , ptBinL , ptBinH ) ; - - h.create( hed0, "hed0" ) ; - h.create( hephi, "hephi" ) ; - h.create( heomega, "heomega" ) ; - h.create( hez0, "hez0" ) ; - h.create( hetanL, "hetanL" ) ; - h.create( hept, "hept" ) ; - - h.create( hpd0, "hpd0" , "d0 pull ", 50 , -5. , 5. ) ; - h.create( hpphi, "hpphi" , "phi pull ", 50 , -5. , 5. ) ; - h.create( hpomega, "hpomega" , "omega pull", 50 , -5. , 5. ) ; - h.create( hpz0, "hpz0" , "z0 pull ", 50 , -5. , 5. ) ; - h.create( hptanL, "hptanL" , "tanL pull ", 50 , -5. , 5. ) ; - h.create( hppt, "hppt" , "pt pull ", 50 , -5. , 5. ) ; - - h.create( hdd0, "hdd0" ) ; - h.create( hdphi, "hdphi" ) ; - h.create( hdomega, "hdomega" ) ; - h.create( hdz0, "hdz0" ) ; - h.create( hdtanL, "hdtanL" ) ; - h.create( hdpt, "hdpt" ) ; - - h.create( hdptp2, "hdptp2" ) ; - - h.create( hcosth_t, "hcosth_t" , "cos theta - true ", 21 , -1. , 1. ) ; - h.create( hcosth_f, "hcosth_f" , "cos theta - found ", 21 , -1. , 1. ) ; - - h.create( hacth_t, "hacth_t" , "|cos theta| - true ", 20 , 0. , 1. ) ; - h.create( hacth_f, "hacth_f" , "|cos theta| - found ", 20 , 0. , 1. ) ; + double ptBinL = 0.01; + double ptBinH = 20.; + double omBinL = alpha / ptBinH; + double omBinH = alpha / ptBinL; + + h.create(hd0, "hd0"); + h.create(hphi, "hphi"); + h.create(homega, "homega", "omega*mm", nBin, omBinL, omBinH); + h.create(hz0, "hz0", " z0 /mm ", nBin, -3., 3.); + h.create(htanL, "htanL"); + h.create(hpt, "hpt", "pt/GeV", nBin, ptBinL, ptBinH); + + h.create(hd0mcp, "hd0mcp"); + h.create(hphimcp, "hphimcp"); + h.create(homegamcp, "homegamcp", "omega*mm", nBin, omBinL, omBinH); //, "omega*mm" , 50, 0.0003 , 0.0004 ) ; + h.create(hz0mcp, "hz0mcp"); //, " z0 /mm " , 50 , -3. , 3. ) ; + h.create(htanLmcp, "htanLmcp"); + h.create(hptmcp, "hptmcp", "pt/GeV", nBin, ptBinL, ptBinH); + + h.create(hed0, "hed0"); + h.create(hephi, "hephi"); + h.create(heomega, "heomega"); + h.create(hez0, "hez0"); + h.create(hetanL, "hetanL"); + h.create(hept, "hept"); + + h.create(hpd0, "hpd0", "d0 pull ", 50, -5., 5.); + h.create(hpphi, "hpphi", "phi pull ", 50, -5., 5.); + h.create(hpomega, "hpomega", "omega pull", 50, -5., 5.); + h.create(hpz0, "hpz0", "z0 pull ", 50, -5., 5.); + h.create(hptanL, "hptanL", "tanL pull ", 50, -5., 5.); + h.create(hppt, "hppt", "pt pull ", 50, -5., 5.); + + h.create(hdd0, "hdd0"); + h.create(hdphi, "hdphi"); + h.create(hdomega, "hdomega"); + h.create(hdz0, "hdz0"); + h.create(hdtanL, "hdtanL"); + h.create(hdpt, "hdpt"); + + h.create(hdptp2, "hdptp2"); + + h.create(hcosth_t, "hcosth_t", "cos theta - true ", 21, -1., 1.); + h.create(hcosth_f, "hcosth_f", "cos theta - found ", 21, -1., 1.); + + h.create(hacth_t, "hacth_t", "|cos theta| - true ", 20, 0., 1.); + h.create(hacth_f, "hacth_f", "|cos theta| - found ", 20, 0., 1.); // void create(int idx, const char* n, const char* t, int nBin=100, double min=0., double max=0. ){ // variable bin size histogram for pt - static const int nBins = 13 ; - double bins[nBins+1] = { 0.1, 0.2, 0.4, 0.6 , 0.8 , 1.0 , 2., 5.0 , 10. , 20. , 50. , 100. , 300. , 500. } ; -// static const int nBins = 9 ; -// double bins[nBins+1] = { 0.1, 0.2, 0.5 , 1.0 , 2., 5.0 , 10. , 20. , 50. , 100.} ; - - h.create( hpt_t, "hpt_t", "pt - true ", nBins , bins ) ; - h.create( hpt_f, "hpt_f", "pt - found ", nBins , bins ) ; - + static const int nBins = 13; + double bins[nBins + 1] = {0.1, 0.2, 0.4, 0.6, 0.8, 1.0, 2., 5.0, 10., 20., 50., 100., 300., 500.}; + // static const int nBins = 9 ; + // double bins[nBins+1] = { 0.1, 0.2, 0.5 , 1.0 , 2., 5.0 , 10. , 20. , 50. , 100.} ; + + h.create(hpt_t, "hpt_t", "pt - true ", nBins, bins); + h.create(hpt_f, "hpt_f", "pt - found ", nBins, bins); } //========================================================================================================================= - - LCCollection* m2tCol = 0 ; - try{ - m2tCol = evt->getCollection( _m2tColName ) ; - } - catch( lcio::DataNotAvailableException& e){ - streamlog_out( DEBUG ) << " *** collection not in event : " << _m2tColName << std::endl ; - return ; // nothing to do in this event (no tracks) + LCCollection* m2tCol = 0; + try { + m2tCol = evt->getCollection(_m2tColName); + } catch (lcio::DataNotAvailableException& e) { + streamlog_out(DEBUG) << " *** collection not in event : " << _m2tColName << std::endl; + return; // nothing to do in this event (no tracks) } - LCCollection* t2mCol = 0 ; - try{ - t2mCol = evt->getCollection( _t2mColName ) ; - } - catch( lcio::DataNotAvailableException& e){ - streamlog_out( DEBUG ) << " *** collection not in event : " << _t2mColName << std::endl ; - return ; // nothing to do in this event (no tracks) + LCCollection* t2mCol = 0; + try { + t2mCol = evt->getCollection(_t2mColName); + } catch (lcio::DataNotAvailableException& e) { + streamlog_out(DEBUG) << " *** collection not in event : " << _t2mColName << std::endl; + return; // nothing to do in this event (no tracks) } + LCCollection* trkCol = 0; + try { - LCCollection* trkCol = 0 ; - try{ - - trkCol = evt->getCollection( _trkColName ) ; - } - catch( lcio::DataNotAvailableException& e){ + trkCol = evt->getCollection(_trkColName); + } catch (lcio::DataNotAvailableException& e) { - streamlog_out( DEBUG ) << " *** collection not ine event : " << _trkColName << std::endl ; - return ; // nothing to do in this event (no tracks) - + streamlog_out(DEBUG) << " *** collection not ine event : " << _trkColName << std::endl; + return; // nothing to do in this event (no tracks) } - if( trkCol->getNumberOfElements() < 1 ) { + if (trkCol->getNumberOfElements() < 1) { - streamlog_out( ERROR ) << " not tracks in collection " << _trkColName << " evt : " << evt->getEventNumber() - << " run : " << evt->getRunNumber() << std::endl ; - return ; + streamlog_out(ERROR) << " not tracks in collection " << _trkColName << " evt : " << evt->getEventNumber() + << " run : " << evt->getRunNumber() << std::endl; + return; } + LCRelationNavigator navm2t(m2tCol); + LCRelationNavigator navt2m(t2mCol); - LCRelationNavigator navm2t( m2tCol ) ; - LCRelationNavigator navt2m( t2mCol ) ; + LCIterator mcpIt(evt, _mcpColName); + LCCollectionVec* mcpTracks = new LCCollectionVec(LCIO::MCPARTICLE); + mcpTracks->setSubset(true); + mcpTracks->reserve(mcpIt.size()); - LCIterator mcpIt( evt, _mcpColName ) ; - - LCCollectionVec* mcpTracks = new LCCollectionVec( LCIO::MCPARTICLE ) ; - mcpTracks->setSubset( true ) ; - mcpTracks->reserve( mcpIt.size() ) ; - - std::string name = "MCParticleTracks_" ; - name += this->name() ; - - evt->addCollection( mcpTracks , name ) ; + std::string name = "MCParticleTracks_"; + name += this->name(); + evt->addCollection(mcpTracks, name); - streamlog_out( DEBUG6 ) << " ----- adding collection " << name << " to the event " << std::endl ; + streamlog_out(DEBUG6) << " ----- adding collection " << name << " to the event " << std::endl; - LCCollectionVec* mcpTrksNotFound = new LCCollectionVec( LCIO::MCPARTICLE ) ; - mcpTrksNotFound->setSubset( true ) ; - mcpTrksNotFound->reserve( mcpIt.size() ) ; + LCCollectionVec* mcpTrksNotFound = new LCCollectionVec(LCIO::MCPARTICLE); + mcpTrksNotFound->setSubset(true); + mcpTrksNotFound->reserve(mcpIt.size()); - name = "MCParticleTracksNotFound_" ; - name += this->name() ; - evt->addCollection( mcpTrksNotFound , name ) ; + name = "MCParticleTracksNotFound_"; + name += this->name(); + evt->addCollection(mcpTrksNotFound, name); - streamlog_out( DEBUG6 ) << " ----- adding collection " << name << " to the event " << std::endl ; + streamlog_out(DEBUG6) << " ----- adding collection " << name << " to the event " << std::endl; + LCCollectionVec* splitTracks = new LCCollectionVec(LCIO::TRACK); + splitTracks->setSubset(true); + splitTracks->reserve(trkCol->getNumberOfElements()); + name = "SplitTracks_"; + name += this->name(); + evt->addCollection(splitTracks, name); - LCCollectionVec* splitTracks = new LCCollectionVec( LCIO::TRACK ) ; - splitTracks->setSubset( true ) ; - splitTracks->reserve( trkCol->getNumberOfElements() ) ; - name = "SplitTracks_" ; - name += this->name() ; - evt->addCollection( splitTracks , name ) ; - //------ count sim hits from every MCParticle - typedef std::map< MCParticle* , int > HITMAP ; - HITMAP hitMap ; - try{ - LCIterator sthIt( evt, _sthColName ) ; - - while( SimTrackerHit* sth = sthIt.next() ){ - - hitMap[ sth->getMCParticle() ]++ ; - } - }catch( lcio::DataNotAvailableException& e){ + typedef std::map HITMAP; + HITMAP hitMap; + try { + LCIterator sthIt(evt, _sthColName); + while (SimTrackerHit* sth = sthIt.next()) { + + hitMap[sth->getMCParticle()]++; + } + } catch (lcio::DataNotAvailableException& e) { } //--- check if we have any tracks in the relation (not always for LEP trk) + while (MCParticle* mcp = mcpIt.next()) { - while( MCParticle* mcp = mcpIt.next() ){ - - - bool cut = true ; + bool cut = true; // APPLY_CUT( DEBUG, cut, std::abs( mcp->getCharge() ) > 0.5 ) ; - if( std::abs( mcp->getCharge() ) < 0.5 ) cut = false ; // silent cut - if( cut ) - streamlog_out( DEBUG ) << lcshort( mcp ) << std::endl ; + if (std::abs(mcp->getCharge()) < 0.5) + cut = false; // silent cut + if (cut) + streamlog_out(DEBUG) << lcshort(mcp) << std::endl; - //if ( _physSampleOn ) - // APPLY_CUT( DEBUG, cut, mcp->getGeneratorStatus() == 1 ) ; // no documentation lines + // if ( _physSampleOn ) + // APPLY_CUT( DEBUG, cut, mcp->getGeneratorStatus() == 1 ) ; // no documentation lines - dd4hep::rec::Vector3D v( mcp->getVertex()[0], mcp->getVertex()[1], mcp->getVertex()[2] ); - dd4hep::rec::Vector3D e( mcp->getEndpoint()[0], mcp->getEndpoint()[1], mcp->getEndpoint()[2] ); - dd4hep::rec::Vector3D p( mcp->getMomentum()[0], mcp->getMomentum()[1], mcp->getMomentum()[2] ); + dd4hep::rec::Vector3D v(mcp->getVertex()[0], mcp->getVertex()[1], mcp->getVertex()[2]); + dd4hep::rec::Vector3D e(mcp->getEndpoint()[0], mcp->getEndpoint()[1], mcp->getEndpoint()[2]); + dd4hep::rec::Vector3D p(mcp->getMomentum()[0], mcp->getMomentum()[1], mcp->getMomentum()[2]); - APPLY_CUT( DEBUG, cut, v.r() < _originCut ) ; // start at IP+/-10cm + APPLY_CUT(DEBUG, cut, v.r() < _originCut); // start at IP+/-10cm // ==== vzeros ========= // APPLY_CUT( DEBUG, cut, v.rho() > 100. ) ; // non prompt track @@ -444,285 +403,256 @@ void TrackEfficiency::processEvent( LCEvent * evt ) { // APPLY_CUT( DEBUG, cut, isVzero ) ; // start at IP+/-10cm // ==== vzeros ========= - APPLY_CUT( DEBUG, cut, e.rho()==0.0 || e.rho() > 40. ) ; // end at rho > 40 cm + APPLY_CUT(DEBUG, cut, e.rho() == 0.0 || e.rho() > 40.); // end at rho > 40 cm - APPLY_CUT( DEBUG, cut, p.rho() > _ptCut ) ; //FIXME 1. Gev <-> pt> 100 MeV - APPLY_CUT( DEBUG, cut, p.r() > _pCut ) ; + APPLY_CUT(DEBUG, cut, p.rho() > _ptCut); // FIXME 1. Gev <-> pt> 100 MeV + APPLY_CUT(DEBUG, cut, p.r() > _pCut); - APPLY_CUT( DEBUG, cut, std::abs( cos( p.theta() ) ) < _cosTheta ) ; //FIXME 0.9 <=> .99 // | cos( theta ) | > 0.99 + APPLY_CUT(DEBUG, cut, std::abs(cos(p.theta())) < _cosTheta); // FIXME 0.9 <=> .99 // | cos( theta ) | > 0.99 - APPLY_CUT( DEBUG, cut, hitMap[ mcp ] > _minHits ) ; // require at least 5 tracker hits + APPLY_CUT(DEBUG, cut, hitMap[mcp] > _minHits); // require at least 5 tracker hits //.... - if( cut ) - mcpTracks->push_back( mcp ) ; + if (cut) + mcpTracks->push_back(mcp); } - - - name = "MCParticleTracks_" ; - name += this->name() ; + name = "MCParticleTracks_"; + name += this->name(); - LCIterator trmIt( evt, name ) ; + LCIterator trmIt(evt, name); // while( MCParticle* trm = trmIt.next() ){ - for(int ii=0,nn=mcpTracks->getNumberOfElements() ; iigetNumberOfElements(); ii < nn; ++ii) { + + MCParticle* trm = (MCParticle*)mcpTracks->getElementAt(ii); - MCParticle* trm = (MCParticle*) mcpTracks->getElementAt(ii) ; - // std::cout << " ----- searching particle track : " << lcshort( trm ) << std::endl; - double pxmcp = trm->getMomentum()[0] ; - double pymcp = trm->getMomentum()[1] ; + double pxmcp = trm->getMomentum()[0]; + double pymcp = trm->getMomentum()[1]; // double pzmcp = trm->getMomentum()[2] ; - + // double pmcp = sqrt( pxmcp*pxmcp + pymcp*pymcp + pzmcp*pzmcp ) ; - double ptmcp = sqrt( pxmcp*pxmcp + pymcp*pymcp ) ; - + double ptmcp = sqrt(pxmcp * pxmcp + pymcp * pymcp); + // double thmcp = atan2( ptmcp , pzmcp ) ; // double d0mcp = 0. ; //fixme: only true for prompt tracks // double phmcp = atan2( pymcp, pxmcp) ; - // double ommcp = alpha / ptmcp ; - // if( trm->getCharge() < 0. ) + // double ommcp = alpha / ptmcp ; + // if( trm->getCharge() < 0. ) // ommcp = -ommcp ; // double z0mcp = 0 ; //fixme: only true for prompt tracks - // double tLmcp = pzmcp / ptmcp ; + // double tLmcp = pzmcp / ptmcp ; + HelixClass helix; - HelixClass helix ; + float pos[3]; + pos[0] = trm->getVertex()[0]; + pos[1] = trm->getVertex()[1]; + pos[2] = trm->getVertex()[2]; + float mom[3]; + mom[0] = trm->getMomentum()[0]; + mom[1] = trm->getMomentum()[1]; + mom[2] = trm->getMomentum()[2]; - float pos[3] ; - pos[0] = trm->getVertex()[0] ; - pos[1] = trm->getVertex()[1] ; - pos[2] = trm->getVertex()[2] ; - float mom[3] ; - mom[0] = trm->getMomentum()[0] ; - mom[1] = trm->getMomentum()[1] ; - mom[2] = trm->getMomentum()[2] ; + dd4hep::rec::Vector3D p(trm->getMomentum()[0], trm->getMomentum()[1], trm->getMomentum()[2]); + double costhmcp = cos(p.theta()); - dd4hep::rec::Vector3D p( trm->getMomentum()[0], trm->getMomentum()[1], trm->getMomentum()[2] ); - double costhmcp = cos( p.theta() ) ; + float q = trm->getCharge(); - float q = trm->getCharge() ; - - helix.Initialize_VP( pos , mom, q, 3.5 ) ; + helix.Initialize_VP(pos, mom, q, 3.5); - double d0mcp = helix.getD0() ; - double phmcp = helix.getPhi0() ; - double ommcp = helix.getOmega() ; - double z0mcp = helix.getZ0() ; - double tLmcp = helix.getTanLambda() ; + double d0mcp = helix.getD0(); + double phmcp = helix.getPhi0(); + double ommcp = helix.getOmega(); + double z0mcp = helix.getZ0(); + double tLmcp = helix.getTanLambda(); + h.fill(hd0mcp, d0mcp); + h.fill(hphimcp, phmcp); + h.fill(homegamcp, ommcp); + h.fill(hz0mcp, z0mcp); + h.fill(htanLmcp, tLmcp); + h.fill(hptmcp, ptmcp); - h.fill( hd0mcp, d0mcp ) ; - h.fill( hphimcp, phmcp ) ; - h.fill( homegamcp, ommcp ) ; - h.fill( hz0mcp, z0mcp ) ; - h.fill( htanLmcp, tLmcp ) ; - h.fill( hptmcp, ptmcp ) ; - + h.fill(hpt_t, ptmcp); + h.fill(hcosth_t, costhmcp); + h.fill(hacth_t, std::abs(costhmcp)); - h.fill( hpt_t , ptmcp ) ; - h.fill( hcosth_t , costhmcp ) ; - h.fill( hacth_t , std::abs( costhmcp) ) ; - + bool useT2M = true; - - bool useT2M = true ; + const EVENT::LCObjectVec& trkV = (useT2M ? navt2m.getRelatedFromObjects(trm) : navm2t.getRelatedToObjects(trm)); - const EVENT::LCObjectVec& trkV = ( useT2M ? navt2m.getRelatedFromObjects( trm ) : navm2t.getRelatedToObjects( trm ) ); - // std::cout << " ------ trkV.size() : " << trkV.size() << std::endl ; - bool foundTrack = false ; + bool foundTrack = false; + + if (trkV.size() > 0) { - if( trkV.size() > 0 ){ - + const FloatVec& wV = (useT2M ? navt2m.getRelatedFromWeights(trm) : navm2t.getRelatedToWeights(trm)); - const FloatVec& wV = ( useT2M ? navt2m.getRelatedFromWeights( trm ) : navm2t.getRelatedToWeights( trm ) ) ; + double wMax = 0.0; + int iMax = 0; - double wMax = 0.0 ; - int iMax = 0 ; + streamlog_out(DEBUG2) << " ------ trkV.size() : " << trkV.size() << std::endl; - streamlog_out( DEBUG2 ) << " ------ trkV.size() : " << trkV.size() << std::endl ; + for (unsigned i = 0; i < wV.size(); ++i) { - for(unsigned i=0 ; igetTrackerHits().size() << " ---- weight : " << wV[i] << std::endl ; + streamlog_out(DEBUG2) << " nhit : " << ((Track*)trkV[i])->getTrackerHits().size() + << " ---- weight : " << wV[i] << std::endl; - if( wV[i] > wMax ){ - wMax = wV[i] ; - iMax = i ; - } - } + if (wV[i] > wMax) { + wMax = wV[i]; + iMax = i; + } + } + + double minGoodHitFraction = _minPurity; // 0.75 ; // 90 ; - double minGoodHitFraction = _minPurity ; //0.75 ; // 90 ; + int nSplitSegments = 0; - int nSplitSegments = 0 ; - // store split tracks collection - if( trkV.size() > 1 ){ - - for(unsigned i=0,N=trkV.size() ; i minGoodHitFraction ) { - - ++nSplitSegments ; - - splitTracks->addElement( trkV[i] ) ; - //} - } + if (trkV.size() > 1) { + + for (unsigned i = 0, N = trkV.size(); i < N; ++i) { + + // if( wV[i] > minGoodHitFraction ) { + + ++nSplitSegments; + + splitTracks->addElement(trkV[i]); + //} + } } + Track* tr = (Track*)(trkV.at(iMax)); - Track* tr = (Track*) ( trkV.at(iMax) ) ; - - double d0 = tr->getD0() ; - double ph = tr->getPhi() ; - double om = tr->getOmega() ; - double z0 = tr->getZ0() ; - double tL = tr->getTanLambda() ; - double pt = std::abs( alpha / om ) ; - - double ed0 = sqrt( tr->getCovMatrix()[0] ); - double eph = sqrt( tr->getCovMatrix()[2] ); - double eom = sqrt( tr->getCovMatrix()[5] ); - double ez0 = sqrt( tr->getCovMatrix()[9] ); - double etL = sqrt( tr->getCovMatrix()[14] ); - - double ept = alpha * eom / ( om * om ) ; // ept = al/om^2 * eom - - - double dd0 = d0 - d0mcp ; - double dph = ph - phmcp ; - if( std::abs(dph) > M_PI ) - dph = 2.* M_PI - std::abs( dph ) ; - - - double dom = om - ommcp ; - double dz0 = z0 - z0mcp ; - double dtL = tL - tLmcp ; - double dpt = pt - ptmcp ; - - bool cut = true ; - - // APPLY_CUT( DEBUG4, cut, std::abs( dph ) < (3.*eph) ) ; - // APPLY_CUT( DEBUG4, cut, std::abs( dom ) < (5.*eom) ) ; // require 5 sigma on omega only for now - // APPLY_CUT( DEBUG4, cut, std::abs( dtL ) < (3.*etL) ) ; + double d0 = tr->getD0(); + double ph = tr->getPhi(); + double om = tr->getOmega(); + double z0 = tr->getZ0(); + double tL = tr->getTanLambda(); + double pt = std::abs(alpha / om); + + double ed0 = sqrt(tr->getCovMatrix()[0]); + double eph = sqrt(tr->getCovMatrix()[2]); + double eom = sqrt(tr->getCovMatrix()[5]); + double ez0 = sqrt(tr->getCovMatrix()[9]); + double etL = sqrt(tr->getCovMatrix()[14]); + + double ept = alpha * eom / (om * om); // ept = al/om^2 * eom + double dd0 = d0 - d0mcp; + double dph = ph - phmcp; + if (std::abs(dph) > M_PI) + dph = 2. * M_PI - std::abs(dph); - // trk->subdetectorHitNumbers()[ 2 * ILDDetID::TPC - 1 ] = hitsInFit ; - // trk->subdetectorHitNumbers()[ 2 * ILDDetID::TPC - 2 ] = hitCount ; - int nTPCHit = tr->getSubdetectorHitNumbers()[ 2 * ILDDetID::TPC - 2 ] ; - int nMCPTPCHit = hitMap[ trm ] ; + double dom = om - ommcp; + double dz0 = z0 - z0mcp; + double dtL = tL - tLmcp; + double dpt = pt - ptmcp; + + bool cut = true; + + // APPLY_CUT( DEBUG4, cut, std::abs( dph ) < (3.*eph) ) ; + // APPLY_CUT( DEBUG4, cut, std::abs( dom ) < (5.*eom) ) ; // require 5 sigma on omega only + // for now APPLY_CUT( DEBUG4, cut, std::abs( dtL ) < (3.*etL) ) ; + + // trk->subdetectorHitNumbers()[ 2 * ILDDetID::TPC - 1 ] = hitsInFit ; + // trk->subdetectorHitNumbers()[ 2 * ILDDetID::TPC - 2 ] = hitCount ; + int nTPCHit = tr->getSubdetectorHitNumbers()[2 * ILDDetID::TPC - 2]; + int nMCPTPCHit = hitMap[trm]; // double goodHitFraction = ( wMax * nTPCHit ) / nMCPTPCHit ; - double goodHitFraction = wMax ; - - APPLY_CUT( DEBUG4, cut, goodHitFraction > minGoodHitFraction ) ; + double goodHitFraction = wMax; + + APPLY_CUT(DEBUG4, cut, goodHitFraction > minGoodHitFraction); // APPLY_CUT( DEBUG4, cut, nSplitSegments < 2 ) ; // don't count split tracks as found.... - + // std::cout << " ========= track found ? -> " << cut << lcshort( trm ) << std::endl ; - if( ! cut ) { - streamlog_out(DEBUG3) << " goodHitFraction : " << wMax<< "*" << nTPCHit << "/" << nMCPTPCHit - << "=" << goodHitFraction << std::endl ; - - streamlog_out(DEBUG3) << " phi : " << dph << " - " << 3.*eph << " - " << dph /ph << std::endl ; - streamlog_out(DEBUG3) << " ome : " << dom << " - " << 3.*eom << " - " << dom /om << std::endl ; - streamlog_out(DEBUG3) << " tanL: " << dtL << " - " << 3.*etL << " - " << dtL /tL << std::endl ; - streamlog_out(DEBUG3) << " pt: " << pt << " dpt: " << dpt << " ept : " << ept << " theta " << 180. * atan( 1. / tL ) / M_PI << std::endl ; - + if (!cut) { + streamlog_out(DEBUG3) << " goodHitFraction : " << wMax << "*" << nTPCHit << "/" << nMCPTPCHit << "=" + << goodHitFraction << std::endl; + streamlog_out(DEBUG3) << " phi : " << dph << " - " << 3. * eph << " - " << dph / ph << std::endl; + streamlog_out(DEBUG3) << " ome : " << dom << " - " << 3. * eom << " - " << dom / om << std::endl; + streamlog_out(DEBUG3) << " tanL: " << dtL << " - " << 3. * etL << " - " << dtL / tL << std::endl; + streamlog_out(DEBUG3) << " pt: " << pt << " dpt: " << dpt << " ept : " << ept << " theta " + << 180. * atan(1. / tL) / M_PI << std::endl; } - - - if( cut == true ){ - - foundTrack = true ; - - h.fill( hd0, d0 ) ; - h.fill( hphi, ph ) ; - h.fill( homega, om ) ; - h.fill( hz0, z0 ) ; - h.fill( htanL, tL ) ; - h.fill( hpt, pt ) ; - - h.fill( hed0, ed0 ) ; - h.fill( hephi, eph ) ; - h.fill( heomega, eom ) ; - h.fill( hez0, ez0 ) ; - h.fill( hetanL, etL ) ; - h.fill( hept, ept ) ; - - - - h.fill( hdd0, dd0 ) ; - h.fill( hdphi, dph ) ; - h.fill( hdomega, dom ) ; - h.fill( hdz0, dz0 ) ; - h.fill( hdtanL, dtL ) ; - h.fill( hdpt, dpt ) ; - - h.fill( hpd0, dd0 / ed0 ) ; - h.fill( hpphi, dph / eph ) ; - h.fill( hpomega, dom / eom ) ; - h.fill( hpz0, dz0 / ez0 ) ; - h.fill( hptanL, dtL / etL ) ; - h.fill( hppt, dpt / ept ) ; - - h.fill( hdptp2, dpt / (pt*pt) ) ; - - - h.fill( hpt_f , ptmcp ) ; - h.fill( hcosth_f , costhmcp ) ; - h.fill( hacth_f , std::abs( costhmcp) ) ; - - + + if (cut == true) { + + foundTrack = true; + + h.fill(hd0, d0); + h.fill(hphi, ph); + h.fill(homega, om); + h.fill(hz0, z0); + h.fill(htanL, tL); + h.fill(hpt, pt); + + h.fill(hed0, ed0); + h.fill(hephi, eph); + h.fill(heomega, eom); + h.fill(hez0, ez0); + h.fill(hetanL, etL); + h.fill(hept, ept); + + h.fill(hdd0, dd0); + h.fill(hdphi, dph); + h.fill(hdomega, dom); + h.fill(hdz0, dz0); + h.fill(hdtanL, dtL); + h.fill(hdpt, dpt); + + h.fill(hpd0, dd0 / ed0); + h.fill(hpphi, dph / eph); + h.fill(hpomega, dom / eom); + h.fill(hpz0, dz0 / ez0); + h.fill(hptanL, dtL / etL); + h.fill(hppt, dpt / ept); + + h.fill(hdptp2, dpt / (pt * pt)); + + h.fill(hpt_f, ptmcp); + h.fill(hcosth_f, costhmcp); + h.fill(hacth_f, std::abs(costhmcp)); } } - - if( ! foundTrack ) { - mcpTrksNotFound->push_back( trm ) ; - streamlog_out( DEBUG3 ) << " ========= track not found " << lcshort( trm ) << std::endl ; + if (!foundTrack) { + mcpTrksNotFound->push_back(trm); + + streamlog_out(DEBUG3) << " ========= track not found " << lcshort(trm) << std::endl; } } - streamlog_out( DEBUG4 ) << " ===== could not find " << mcpTrksNotFound->size() << " tracks of " << mcpTracks->size() - << std::endl ; - - //---------------------------------------------------------------------- - - _nEvt ++ ; + streamlog_out(DEBUG4) << " ===== could not find " << mcpTrksNotFound->size() << " tracks of " << mcpTracks->size() + << std::endl; - clock_t end = clock () ; - - streamlog_out( DEBUG ) << "--- histogramming time: " - << double( end - start ) / double(CLOCKS_PER_SEC) << std::endl ; - -} + //---------------------------------------------------------------------- + _nEvt++; + clock_t end = clock(); + streamlog_out(DEBUG) << "--- histogramming time: " << double(end - start) / double(CLOCKS_PER_SEC) << std::endl; +} /*************************************************************************************************/ -void TrackEfficiency::check( LCEvent * ) { +void TrackEfficiency::check(LCEvent*) { /*************************************************************************************************/ - } //==================================================================================== +void TrackEfficiency::end() { - - -void TrackEfficiency::end(){ - - streamlog_out( MESSAGE ) << " processed " << _nEvt << " events in " << _nRun << " runs " - << std::endl ; + streamlog_out(MESSAGE) << " processed " << _nEvt << " events in " << _nRun << " runs " << std::endl; } //==================================================================================================== - diff --git a/src/clupatra_new.cc b/src/clupatra_new.cc index dfb4ac5..3ea2d72 100644 --- a/src/clupatra_new.cc +++ b/src/clupatra_new.cc @@ -2,1305 +2,1209 @@ #include #include - -#include #include "UTIL/LCTrackerConf.h" -#include +#include #include +#include #include "marlin/Global.h" -#include "IMPL/TrackerHitImpl.h" #include "IMPL/TrackStateImpl.h" +#include "IMPL/TrackerHitImpl.h" #include "MarlinTrk/Factory.h" // --- DD4hep --- +#include "DD4hep/DD4hepUnits.h" #include "DD4hep/Detector.h" -#include "DDRec/Vector3D.h" -#include "DD4hep/DD4hepUnits.h" #include "DDRec/DetectorData.h" +#include "DDRec/Vector3D.h" - -using namespace MarlinTrk ; +using namespace MarlinTrk; using namespace lcio; -namespace lcio{ - // bits 0-15 are reserved !? - const int ILDTrackTypeBit::SEGMENT = 16 ; - const int ILDTrackTypeBit::COMPOSITE = 17 ; -} +namespace lcio { +// bits 0-15 are reserved !? +const int ILDTrackTypeBit::SEGMENT = 16; +const int ILDTrackTypeBit::COMPOSITE = 17; +} // namespace lcio + +namespace clupatra_new { + +/** helper class to compute the chisquared of two points in rho and z coordinate */ +struct Chi2_RPhi_Z_Hit { + // double operator()( const TrackerHit* h, const dd4hep::rec::Vector3D& v1) { + double operator()(const ClupaHit* h, const dd4hep::rec::Vector3D& v1) { + + // dd4hep::rec::Vector3D v0( h->getPosition()[0] , h->getPosition()[1] , h->getPosition()[2] ) ; + const dd4hep::rec::Vector3D& v0 = h->pos; + + double sigsr = h->lcioHit->getCovMatrix()[0] + h->lcioHit->getCovMatrix()[2]; + double sigsz = h->lcioHit->getCovMatrix()[5]; + // double sigsr = 0.01 ; + // double sigsz = 0.1 ; + + double dPhi = std::abs(v0.phi() - v1.phi()); + if (dPhi > M_PI) + dPhi = 2. * M_PI - dPhi; + + double dRPhi = dPhi * v0.rho(); + + double dZ = v0.z() - v1.z(); + + return dRPhi * dRPhi / sigsr + dZ * dZ / sigsz; + } +}; + +//------------------------------------------------------------------------------- + +struct CDot { + CDot(int i, int j, double d) : I(i), J(j), Dot(d) {} + int I; + int J; + double Dot; +}; + +bool sort_CDot(const CDot& c0, const CDot& c1) { return c0.Dot > c1.Dot; } + +//------------------------------------------------------------------------------- -namespace clupatra_new{ - - - /** helper class to compute the chisquared of two points in rho and z coordinate */ - struct Chi2_RPhi_Z_Hit{ - // double operator()( const TrackerHit* h, const dd4hep::rec::Vector3D& v1) { - double operator()( const ClupaHit* h, const dd4hep::rec::Vector3D& v1) { +int addHitsAndFilter(CluTrack* clu, HitListVector& hLV, double dChi2Max, double chi2Cut, unsigned maxStep, + ZIndex& zIndex, bool backward, MarlinTrk::IMarlinTrkSystem* trkSys) { + int nHitsAdded = 0; - // dd4hep::rec::Vector3D v0( h->getPosition()[0] , h->getPosition()[1] , h->getPosition()[2] ) ; - const dd4hep::rec::Vector3D& v0 = h->pos ; + dd4hep::Detector& lcdd = dd4hep::Detector::getInstance(); + dd4hep::DetElement tpcDE = lcdd.detector("TPC"); + dd4hep::rec::FixedPadSizeTPCData* tpc = tpcDE.extension(); + const int maxTPCLayerID = tpc->maxRow; - double sigsr = h->lcioHit->getCovMatrix()[0] + h->lcioHit->getCovMatrix()[2] ; - double sigsz = h->lcioHit->getCovMatrix()[5] ; - // double sigsr = 0.01 ; - // double sigsz = 0.1 ; - - double dPhi = std::abs( v0.phi() - v1.phi() ) ; - if( dPhi > M_PI ) - dPhi = 2.* M_PI - dPhi ; + clu->sort(LayerSortIn()); - double dRPhi = dPhi * v0.rho() ; + int layer = (backward ? clu->front()->first->layer : clu->back()->first->layer); - double dZ = v0.z() - v1.z() ; + streamlog_out(DEBUG3) << " ====================== addHitsAndFilter(): - layer " << layer + << " backward: " << backward << std::endl; - return dRPhi * dRPhi / sigsr + dZ * dZ / sigsz ; + if (layer <= 0 || layer >= maxTPCLayerID) + return nHitsAdded; + + Chi2_RPhi_Z_Hit ch2rzh; + + IMarlinTrack* trk = clu->ext(); + + if (trk == 0) { + streamlog_out(DEBUG3) << " addHitsAndFilter called with null pointer to MarlinTrk - won't do anything " + << std::endl; + return nHitsAdded; + } + + if (streamlog_level(DEBUG3)) { + IMPL::TrackStateImpl ts; + double chi2; + int ndf; + trk->getTrackState(ts, chi2, ndf); + std::vector> hits, outliers; + trk->getHitsInFit(hits); + trk->getOutliers(outliers); + streamlog_out(DEBUG3) << " ====================== addHitsAndFilter(): initial track state: \n" + << ts << "\n chi2: " << chi2 << " ndf: " << ndf << std::endl; + streamlog_out(DEBUG3) << " hits in fit: " << hits.size(); + for (auto p : hits) + streamlog_out(DEBUG3) << "\n" + << UTIL::LCTrackerCellID::valueString(p.first->getCellID0()) << "[" + << p.first->getPosition()[0] << ", " << p.first->getPosition()[1] << ", " + << p.first->getPosition()[2] << "]" + << " - dchi2: " << p.second; + streamlog_out(DEBUG3) << "\n"; + streamlog_out(DEBUG3) << " outliers in fit: " << outliers.size(); + for (auto p : outliers) + streamlog_out(DEBUG3) << "\n" + << UTIL::LCTrackerCellID::valueString(p.first->getCellID0()) << "[" + << p.first->getPosition()[0] << ", " << p.first->getPosition()[1] << ", " + << p.first->getPosition()[2] << "]" + << " - dchi2: " << p.second; + streamlog_out(DEBUG3) << "\n"; + } + + unsigned step = 0; + + UTIL::BitField64 encoder(UTIL::LCTrackerCellID::encoding_string()); + encoder[UTIL::LCTrackerCellID::subdet()] = UTIL::ILDDetID::TPC; + + EVENT::TrackerHit* firstHit = 0; + + IMarlinTrack* bwTrk = 0; + + if (trkSys && + backward) { //==================== only active if called with _trkSystem pointer ============================ + + // need to go back in cluster until 4th hit from the start + CluTrack::iterator it = clu->begin(), end = clu->end(); + int i = 0; + for (; it++ != end && i < 3; ++i) + ; + + if (it == end) + --it; + + streamlog_out(DEBUG2) << " ---- addHitsAndFilter : will smooth back to " << i << "th hit - size of clu " + << clu->size() << std::endl; + + if (!(*it)->first) { + + streamlog_out(ERROR) << " ---- addHitsAndFilter : null pointer at i-th hit : i = " << i << std::endl; + return nHitsAdded; } - }; - - //------------------------------------------------------------------------------- - - struct CDot{ - CDot( int i , int j , double d) : I(i) , J(j) , Dot( d ) {} - int I ; - int J ; - double Dot ; - }; - - bool sort_CDot( const CDot& c0 ,const CDot& c1 ){ - return c0.Dot > c1.Dot ; + + firstHit = (*it)->first->lcioHit; + + int smoothed = trk->smooth(firstHit); + + double chi2; + int ndf; + IMPL::TrackStateImpl ts; + trk->getTrackState(firstHit, ts, chi2, ndf); + + streamlog_out(DEBUG3) << " -- addHitsAndFilter(): smoothed track segment : " << MarlinTrk::errorCode(smoothed) + << " using track state : " << ts << " ---- chi2: " << chi2 << " ndf " << ndf << std::endl; + + bwTrk = trkSys->createTrack(); + + // need to add a dummy hit to the track + bwTrk->addHit(firstHit); // use the hit we smoothed back to + + // note: backward here is forward in the MarlinTrk sense, ie. in direction of energy loss + double unusedField = 0.; // the field is taken from the hits in initialize() + bwTrk->initialise(ts, unusedField, MarlinTrk::IMarlinTrack::forward); } - //------------------------------------------------------------------------------- - - - int addHitsAndFilter( CluTrack* clu, HitListVector& hLV , double dChi2Max, double chi2Cut, unsigned maxStep, ZIndex& zIndex, bool backward, - MarlinTrk::IMarlinTrkSystem* trkSys ) { - - - int nHitsAdded = 0 ; - - dd4hep::Detector& lcdd = dd4hep::Detector::getInstance(); - dd4hep::DetElement tpcDE = lcdd.detector("TPC") ; - dd4hep::rec::FixedPadSizeTPCData* tpc = tpcDE.extension() ; - const int maxTPCLayerID = tpc->maxRow ; - - - clu->sort( LayerSortIn() ) ; - - int layer = ( backward ? clu->front()->first->layer : clu->back()->first->layer ) ; - - - streamlog_out( DEBUG3 ) << " ====================== addHitsAndFilter(): - layer " << layer << " backward: " << backward << std::endl ; - - - if( layer <= 0 || layer >= maxTPCLayerID ) - return nHitsAdded ; - - - Chi2_RPhi_Z_Hit ch2rzh ; - - IMarlinTrack* trk = clu->ext() ; - - if( trk == 0 ){ - streamlog_out( DEBUG3 ) << " addHitsAndFilter called with null pointer to MarlinTrk - won't do anything " << std::endl ; - return nHitsAdded; - } - - - if( streamlog_level( DEBUG3 ) ){ - IMPL::TrackStateImpl ts ; double chi2 ; int ndf ; - trk->getTrackState( ts, chi2, ndf ) ; - std::vector > hits , outliers ; - trk->getHitsInFit( hits ) ; - trk->getOutliers( outliers ) ; - streamlog_out( DEBUG3 ) << " ====================== addHitsAndFilter(): initial track state: \n" << ts - << "\n chi2: " << chi2 << " ndf: " << ndf - << std::endl ; - streamlog_out( DEBUG3 ) << " hits in fit: " << hits.size() ; - for( auto p : hits ) - streamlog_out( DEBUG3 ) << "\n" - << UTIL::LCTrackerCellID::valueString( p.first->getCellID0() ) << "[" - << p.first->getPosition()[0] << ", " - << p.first->getPosition()[1] << ", " - << p.first->getPosition()[2] << "]" - << " - dchi2: " << p.second ; - streamlog_out( DEBUG3 ) << "\n" ; - streamlog_out( DEBUG3 ) << " outliers in fit: " << outliers.size() ; - for( auto p : outliers ) - streamlog_out( DEBUG3 ) << "\n" - << UTIL::LCTrackerCellID::valueString( p.first->getCellID0() ) << "[" - << p.first->getPosition()[0] << ", " - << p.first->getPosition()[1] << ", " - << p.first->getPosition()[2] << "]" - << " - dchi2: " << p.second ; - streamlog_out( DEBUG3 ) << "\n" ; + IMarlinTrack* theTrk = (bwTrk ? bwTrk : trk); + + while (step < maxStep + 1) { + + layer += (backward ? +1 : -1); + + if (layer < 0 || layer > maxTPCLayerID) + break; + + encoder[UTIL::LCTrackerCellID::layer()] = layer; + + MarlinTrk::Vector3D gxv; + + bool hitAdded = false; + + int layerID = encoder.lowWord(); + int elementID = 0; + + // int mode = ( backward ? IMarlinTrack::modeBackward : IMarlinTrack::modeForward ) ; + // int mode = ( backward ? IMarlinTrack::modeForward : IMarlinTrack::modeClosest ) ; + int mode = IMarlinTrack::modeClosest; + + int intersects = -1; + + if (firstHit) { + + intersects = theTrk->intersectionWithLayer(layerID, firstHit, gxv, elementID, mode); + + } else { + + intersects = theTrk->intersectionWithLayer(layerID, gxv, elementID, mode); } - unsigned step = 0 ; - - UTIL::BitField64 encoder( UTIL::LCTrackerCellID::encoding_string() ) ; - encoder[UTIL::LCTrackerCellID::subdet()] = UTIL::ILDDetID::TPC ; - - EVENT::TrackerHit* firstHit = 0 ; + dd4hep::rec::Vector3D xv(gxv.x(), gxv.y(), gxv.z()); - IMarlinTrack* bwTrk = 0 ; + streamlog_out(DEBUG3) << " -- addHitsAndFilter(): looked for intersection - " + << " Step : " << step << " at layer: " << layer + << " intersects: " << MarlinTrk::errorCode(intersects) << " next xing point : " << xv; - if( trkSys && backward ) { //==================== only active if called with _trkSystem pointer ============================ + if (intersects == IMarlinTrack::success) { // found a crossing point - // need to go back in cluster until 4th hit from the start - CluTrack::iterator it = clu->begin() , end = clu->end() ; - int i=0 ; - for( ; it++ != end && i< 3 ; ++i ) ; + int zIndCP = zIndex.index(xv[2]); - if( it == end ) --it ; + HitList& hLL = hLV.at(layer); - streamlog_out( DEBUG2 ) << " ---- addHitsAndFilter : will smooth back to " << i <<"th hit - size of clu " << clu->size() << std::endl ; + double ch2Min = 1.e99; + Hit* bestHit = 0; - if( ! (*it)->first ){ + streamlog_out(DEBUG3) << " -- number of hits on layer " << layer << " : " << hLL.size() << std::endl; - streamlog_out( ERROR ) << " ---- addHitsAndFilter : null pointer at i-th hit : i = " << i << std::endl ; - return nHitsAdded ; - } + for (HitList::const_iterator ih = hLL.begin(), end = hLL.end(); ih != end; ++ih) { + + // if the z indices differ by more than one we can continue + if (nnclu::notInRange<-1, 1>((*ih)->first->zIndex - zIndCP)) + continue; + + double ch2 = ch2rzh((*ih)->first, xv); + + if (ch2 < ch2Min) { + + ch2Min = ch2; + bestHit = (*ih); + } + } //------------------------------------------------------------------- + + if (bestHit != 0) { + + streamlog_out(DEBUG3) << " ************ bestHit " << bestHit + << " pos : " << (bestHit ? bestHit->first->pos : dd4hep::rec::Vector3D()) + << " chi2: " << ch2Min << " chi2Cut: " << chi2Cut << std::endl; + + const dd4hep::rec::Vector3D& hPos = bestHit->first->pos; + + if (ch2Min < chi2Cut) { + double deltaChi = 0.; - firstHit = (*it)->first->lcioHit ; + int addHit = theTrk->addAndFit(bestHit->first->lcioHit, deltaChi, dChi2Max); - int smoothed = trk->smooth( firstHit ) ; + streamlog_out(DEBUG3) << " ***** assigning left over hit : " + << errorCode(addHit) //<< hPos << " <-> " << xv + << " dist: " << (hPos - xv).r() << " chi2: " << ch2Min << " hit errors : rphi=" + << sqrt(bestHit->first->lcioHit->getCovMatrix()[0] + + bestHit->first->lcioHit->getCovMatrix()[2]) + << " z= " << sqrt(bestHit->first->lcioHit->getCovMatrix()[5]) + << " ----- deltaChi = " << deltaChi << std::endl; - double chi2 ; - int ndf ; - IMPL::TrackStateImpl ts ; - trk->getTrackState( firstHit , ts, chi2, ndf ) ; - - streamlog_out( DEBUG3 ) << " -- addHitsAndFilter(): smoothed track segment : " << MarlinTrk::errorCode( smoothed ) - << " using track state : " << ts - << " ---- chi2: " << chi2 - << " ndf " << ndf - << std::endl ; + if (addHit == IMarlinTrack::success) { - + hitAdded = true; - bwTrk = trkSys->createTrack() ; + hLL.remove(bestHit); + clu->addElement(bestHit); - //need to add a dummy hit to the track - bwTrk->addHit( firstHit ) ; // use the hit we smoothed back to - - // note: backward here is forward in the MarlinTrk sense, ie. in direction of energy loss - double unusedField = 0. ; // the field is taken from the hits in initialize() - bwTrk->initialise( ts , unusedField , MarlinTrk::IMarlinTrack::forward ) ; + firstHit = 0; // after we added a hit, the next intersection search should use this last hit... + ++nHitsAdded; + + streamlog_out(DEBUG) << " ---- track state filtered with new hit ! ------- " << std::endl; + } + } // chi2Cut + } // bestHit + + } else { // no intersection found + + // we stop searching here + step = maxStep + 1; } + // reset the step or increment it + step = (hitAdded ? 1 : step + 1); - IMarlinTrack* theTrk = ( bwTrk ? bwTrk : trk ) ; + } // while step < maxStep + if (bwTrk) + delete bwTrk; - while( step < maxStep + 1 ) { - - layer += ( backward ? +1 : -1 ) ; - - if( layer < 0 || layer > maxTPCLayerID ) - break ; + return nHitsAdded; +} +//------------------------------------------------------------------------------------------------------------ - encoder[ UTIL::LCTrackerCellID::layer() ] = layer ; - - MarlinTrk::Vector3D gxv ; - - bool hitAdded = false ; - - int layerID = encoder.lowWord() ; - int elementID = 0 ; - - // int mode = ( backward ? IMarlinTrack::modeBackward : IMarlinTrack::modeForward ) ; - // int mode = ( backward ? IMarlinTrack::modeForward : IMarlinTrack::modeClosest ) ; - int mode = IMarlinTrack::modeClosest ; +bool addHitAndFilter(int detectorID, int layer, CluTrack* clu, HitListVector& hLV, double dChi2Max, double chi2Cut) { + Chi2_RPhi_Z_Hit ch2rzh; - int intersects = -1 ; - - if( firstHit ) { + IMarlinTrack* trk = clu->ext(); - intersects = theTrk->intersectionWithLayer( layerID, firstHit, gxv, elementID , mode ) ; - - } else { + UTIL::BitField64 encoder(UTIL::LCTrackerCellID::encoding_string()); - intersects = theTrk->intersectionWithLayer( layerID, gxv, elementID , mode ) ; - } + encoder[UTIL::LCTrackerCellID::subdet()] = detectorID; + encoder[UTIL::LCTrackerCellID::layer()] = layer; + + int layerID = encoder.lowWord(); + + MarlinTrk::Vector3D gxv; + + int elementID = -1; + + int intersects = trk->intersectionWithLayer(layerID, gxv, elementID, IMarlinTrack::modeClosest); + + dd4hep::rec::Vector3D xv(gxv.x(), gxv.y(), gxv.z()); + + // IMarlinTrack::modeBackward , IMarlinTrack::modeForward - dd4hep::rec::Vector3D xv( gxv.x() , gxv.y(), gxv.z() ) ; - - - streamlog_out( DEBUG3 ) << " -- addHitsAndFilter(): looked for intersection - " - << " Step : " << step - << " at layer: " << layer - << " intersects: " << MarlinTrk::errorCode( intersects ) - << " next xing point : " << xv ; - - if( intersects == IMarlinTrack::success ) { // found a crossing point - - int zIndCP = zIndex.index( xv[2] ) ; - - HitList& hLL = hLV.at( layer ) ; - - double ch2Min = 1.e99 ; - Hit* bestHit = 0 ; - - streamlog_out( DEBUG3 ) << " -- number of hits on layer " << layer << " : " << hLL.size() << std::endl ; - - for( HitList::const_iterator ih = hLL.begin(), end = hLL.end() ; ih != end ; ++ih ){ - - // if the z indices differ by more than one we can continue - if( nnclu::notInRange<-1,1>( (*ih)->first->zIndex - zIndCP ) ) - continue ; - - double ch2 = ch2rzh( (*ih)->first , xv ) ; - - if( ch2 < ch2Min ){ - - ch2Min = ch2 ; - bestHit = (*ih) ; - } - }//------------------------------------------------------------------- - - if( bestHit != 0 ){ - - streamlog_out( DEBUG3 ) << " ************ bestHit " << bestHit - << " pos : " << (bestHit ? bestHit->first->pos : dd4hep::rec::Vector3D() ) - << " chi2: " << ch2Min - << " chi2Cut: " << chi2Cut << std::endl ; - - const dd4hep::rec::Vector3D& hPos = bestHit->first->pos ; - - if( ch2Min < chi2Cut ) { - - double deltaChi = 0. ; - - int addHit = theTrk->addAndFit( bestHit->first->lcioHit, deltaChi, dChi2Max ) ; - - - - streamlog_out( DEBUG3 ) << " ***** assigning left over hit : " << errorCode( addHit ) //<< hPos << " <-> " << xv - << " dist: " << ( hPos - xv ).r() - << " chi2: " << ch2Min - << " hit errors : rphi=" << sqrt( bestHit->first->lcioHit->getCovMatrix()[0] - + bestHit->first->lcioHit->getCovMatrix()[2] ) - << " z= " << sqrt( bestHit->first->lcioHit->getCovMatrix()[5] ) - << " ----- deltaChi = " << deltaChi - << std::endl ; - - - if( addHit == IMarlinTrack::success ) { - - hitAdded = true ; - - hLL.remove( bestHit ) ; - clu->addElement( bestHit ) ; - - firstHit = 0 ; // after we added a hit, the next intersection search should use this last hit... - - ++nHitsAdded ; - - streamlog_out( DEBUG ) << " ---- track state filtered with new hit ! ------- " << std::endl ; - } - } // chi2Cut - } // bestHit - - - } else { // no intersection found - - // we stop searching here - step = maxStep + 1 ; + streamlog_out(DEBUG2) << " ============ addHitAndFilter(): looked for intersection - " + << " detector : " << detectorID << " at layer: " << layer + << " intersects: " << MarlinTrk::errorCode(intersects) << " next xing point : " << xv; + + bool hitAdded = false; + + if (intersects == IMarlinTrack::success) { // found a crossing point + + // FIXME: this is copied from ClupatraProcessor + static const int ZBins = 160; + ZIndex zIndex(-2750., 2750., ZBins); + int zIndCP = zIndex.index(xv[2]); + + HitList& hLL = hLV.at(layer); + + double ch2Min = 1.e99; + Hit* bestHit = 0; + + for (HitList::const_iterator ih = hLL.begin(), end = hLL.end(); ih != end; ++ih) { + + // if the z indices differ by more than one we can continue + if (nnclu::notInRange<-1, 1>((*ih)->first->zIndex - zIndCP)) + continue; + + double ch2 = ch2rzh((*ih)->first, xv); + + if (ch2 < ch2Min) { + + ch2Min = ch2; + bestHit = (*ih); } + } //------------------------------------------------------------------- + + streamlog_out(DEBUG2) << " ************ bestHit " << bestHit + << " pos : " << (bestHit ? bestHit->first->pos : dd4hep::rec::Vector3D()) + << " chi2: " << ch2Min << " chi2Cut: " << chi2Cut << std::endl; - // reset the step or increment it - step = ( hitAdded ? 1 : step + 1 ) ; + if (bestHit != 0) { - } // while step < maxStep - + const dd4hep::rec::Vector3D& hPos = bestHit->first->pos; - if( bwTrk ) delete bwTrk ; + if (ch2Min < chi2Cut) { - return nHitsAdded ; + double deltaChi = 0.; + int addHit = trk->addAndFit(bestHit->first->lcioHit, deltaChi, dChi2Max); + + streamlog_out(DEBUG2) << " ***** assigning left over hit : " + << errorCode(addHit) //<< hPos << " <-> " << xv + << " dist: " << (hPos - xv).r() << " chi2: " << ch2Min << " hit errors : rphi=" + << sqrt(bestHit->first->lcioHit->getCovMatrix()[0] + + bestHit->first->lcioHit->getCovMatrix()[2]) + << " z= " << sqrt(bestHit->first->lcioHit->getCovMatrix()[5]) << std::endl; + + if (addHit == IMarlinTrack::success) { + + hitAdded = true; + + hLL.remove(bestHit); + clu->addElement(bestHit); + + streamlog_out(DEBUG2) << " ---- track state filtered with new hit ! ------- " << std::endl; + } + } // chi2Cut + } // bestHit + + } // intersection found + + return hitAdded; +} + +//------------------------------------------------------------------------------------------------------------ + +void getHitMultiplicities(CluTrack* clu, std::vector& mult) { + + std::map hm; + + for (CluTrack::iterator it = clu->begin(), end = clu->end(); it != end; ++it) { + + ++hm[(*it)->first->layer]; } - //------------------------------------------------------------------------------------------------------------ - - bool addHitAndFilter( int detectorID, int layer, CluTrack* clu, HitListVector& hLV , double dChi2Max, double chi2Cut) { - - Chi2_RPhi_Z_Hit ch2rzh ; - - IMarlinTrack* trk = clu->ext() ; - - UTIL::BitField64 encoder( UTIL::LCTrackerCellID::encoding_string() ) ; - - encoder[ UTIL::LCTrackerCellID::subdet() ] = detectorID ; - encoder[ UTIL::LCTrackerCellID::layer() ] = layer ; - - int layerID = encoder.lowWord() ; - - MarlinTrk::Vector3D gxv ; - - int elementID = -1 ; - - int intersects = trk->intersectionWithLayer( layerID, gxv, elementID , IMarlinTrack::modeClosest ) ; - - dd4hep::rec::Vector3D xv( gxv.x() , gxv.y(), gxv.z() ) ; - - // IMarlinTrack::modeBackward , IMarlinTrack::modeForward - - streamlog_out( DEBUG2 ) << " ============ addHitAndFilter(): looked for intersection - " - << " detector : " << detectorID - << " at layer: " << layer - << " intersects: " << MarlinTrk::errorCode( intersects ) - << " next xing point : " << xv ; - - bool hitAdded = false ; - - if( intersects == IMarlinTrack::success ) { // found a crossing point - - //FIXME: this is copied from ClupatraProcessor - static const int ZBins = 160 ; - ZIndex zIndex( -2750. , 2750. ,ZBins ) ; - int zIndCP = zIndex.index( xv[2] ) ; - - HitList& hLL = hLV.at( layer ) ; - - double ch2Min = 1.e99 ; - Hit* bestHit = 0 ; - - for( HitList::const_iterator ih = hLL.begin(), end = hLL.end() ; ih != end ; ++ih ){ - - // if the z indices differ by more than one we can continue - if( nnclu::notInRange<-1,1>( (*ih)->first->zIndex - zIndCP ) ) - continue ; - - double ch2 = ch2rzh( (*ih)->first , xv ) ; - - if( ch2 < ch2Min ){ - - ch2Min = ch2 ; - bestHit = (*ih) ; - } - }//------------------------------------------------------------------- - - - streamlog_out( DEBUG2 ) << " ************ bestHit " << bestHit - << " pos : " << (bestHit ? bestHit->first->pos : dd4hep::rec::Vector3D() ) - << " chi2: " << ch2Min - << " chi2Cut: " << chi2Cut << std::endl ; - - if( bestHit != 0 ){ - - const dd4hep::rec::Vector3D& hPos = bestHit->first->pos ; - - if( ch2Min < chi2Cut ) { - - double deltaChi = 0. ; - - int addHit = trk->addAndFit( bestHit->first->lcioHit, deltaChi, dChi2Max ) ; - - - - streamlog_out( DEBUG2 ) << " ***** assigning left over hit : " << errorCode( addHit ) //<< hPos << " <-> " << xv - << " dist: " << ( hPos - xv ).r() - << " chi2: " << ch2Min - << " hit errors : rphi=" << sqrt( bestHit->first->lcioHit->getCovMatrix()[0] - + bestHit->first->lcioHit->getCovMatrix()[2] ) - << " z= " << sqrt( bestHit->first->lcioHit->getCovMatrix()[5] ) - << std::endl ; - - - - - - if( addHit == IMarlinTrack::success ) { - - hitAdded = true ; - - hLL.remove( bestHit ) ; - clu->addElement( bestHit ) ; - - - streamlog_out( DEBUG2 ) << " ---- track state filtered with new hit ! ------- " << std::endl ; - } - } // chi2Cut - } // bestHit - - } // intersection found + unsigned maxN = mult.size() - 1; + + // for( unsigned i=0 ; i < hLV.size() ; ++i ){ + // unsigned m = hLV[i].size() ; + + for (std::map::iterator it = hm.begin(), end = hm.end(); it != end; ++it) { + + unsigned m = (it->second < maxN ? it->second : maxN); + + if (m == 0) + continue; + + ++mult[m]; - return hitAdded ; + ++mult[0]; } +} +//------------------------------------------------------------------------------------------------------------------------- +void split_multiplicity(Clusterer::cluster_list& cluList, int layerWithMultiplicity, int N) { - //------------------------------------------------------------------------------------------------------------ + for (Clusterer::cluster_list::iterator it = cluList.begin(), end = cluList.end(); it != end; ++it) { - void getHitMultiplicities( CluTrack* clu, std::vector& mult ){ - - std::map hm ; - - for( CluTrack::iterator it=clu->begin(), end =clu->end() ; it != end ; ++ it ){ - - ++hm[ (*it)->first->layer ] ; - } + CluTrack* clu = *it; + + std::vector mult(N + 2); + // get hit multiplicities up to N ( N+1 means N+1 or higher ) + getHitMultiplicities(clu, mult); + + streamlog_out(DEBUG2) << " **** split_multiplicity - hit multiplicities: \n"; - unsigned maxN = mult.size() - 1 ; - - // for( unsigned i=0 ; i < hLV.size() ; ++i ){ - // unsigned m = hLV[i].size() ; - - for( std::map::iterator it= hm.begin() , end = hm.end() ; it != end ; ++ it ){ - - unsigned m = ( it->second < maxN ? it->second : maxN ) ; - - if( m == 0 ) - continue ; - - ++mult[m] ; - - ++mult[0] ; + for (unsigned i = 0, n = mult.size(); i < n; ++i) { + streamlog_out(DEBUG2) << " m[" << i << "] = " << mult[i] << "\n"; } - } - //------------------------------------------------------------------------------------------------------------------------- - void split_multiplicity( Clusterer::cluster_list& cluList, int layerWithMultiplicity , int N) { - - for( Clusterer::cluster_list::iterator it= cluList.begin(), end= cluList.end() ; it != end ; ++it ){ - - CluTrack* clu = *it ; - - std::vector mult( N + 2 ) ; - // get hit multiplicities up to N ( N+1 means N+1 or higher ) - getHitMultiplicities( clu , mult ) ; - - - streamlog_out( DEBUG2 ) << " **** split_multiplicity - hit multiplicities: \n" ; - - for( unsigned i=0,n=mult.size() ; i= layerWithMultiplicity ) - continue ; - - bool split_cluster = false ; - - for( int m=2 ; m= layerWithMultiplicity ){ - - streamlog_out( DEBUG3 ) << " **** split_multiplicity - create_two_clusters \n" ; - - create_two_clusters( *clu , cluList ) ; - - split_cluster = true ; - } - else if( m == 3 && mult[m] >= layerWithMultiplicity ){ - - streamlog_out( DEBUG3 ) << " **** split_multiplicity - create_three_clusters \n" ; - - create_three_clusters( *clu , cluList ) ; - - split_cluster = true ; - } - else if( mult[m] >= layerWithMultiplicity ){ - - streamlog_out( DEBUG3 ) << " **** split_multiplicity - create_n_clusters \n" ; - - create_n_clusters( *clu ,cluList , m ) ; - - split_cluster = true ; - } + if (mult[1] >= layerWithMultiplicity) + continue; - } - if( split_cluster ){ - - clu->clear() ; + bool split_cluster = false; + + for (int m = 2; m < N; ++m) { + + if (m == 2 && mult[m] >= layerWithMultiplicity) { + + streamlog_out(DEBUG3) << " **** split_multiplicity - create_two_clusters \n"; + + create_two_clusters(*clu, cluList); + + split_cluster = true; + } else if (m == 3 && mult[m] >= layerWithMultiplicity) { + + streamlog_out(DEBUG3) << " **** split_multiplicity - create_three_clusters \n"; + + create_three_clusters(*clu, cluList); + + split_cluster = true; + } else if (mult[m] >= layerWithMultiplicity) { + + streamlog_out(DEBUG3) << " **** split_multiplicity - create_n_clusters \n"; + + create_n_clusters(*clu, cluList, m); - it = cluList.erase( it ) ; - --it ; // erase returns iterator to next element + split_cluster = true; } - - } + if (split_cluster) { + + clu->clear(); + + it = cluList.erase(it); + --it; // erase returns iterator to next element + } + } +} + +//------------------------------------------------------------------------------------------------------------------------- + +void create_n_clusters(Clusterer::cluster_type& hV, Clusterer::cluster_list& cluVec, unsigned n) { + + if (n < 4) { + + streamlog_out(ERROR) << " create_n_clusters called for n = " << n << std::endl; + return; + } + + // copy of the algorithm for creating three clusters (minimize angle between hits as seen from IP) + + hV.freeElements(); + + dd4hep::Detector& lcdd = dd4hep::Detector::getInstance(); + dd4hep::DetElement tpcDE = lcdd.detector("TPC"); + dd4hep::rec::FixedPadSizeTPCData* tpc = tpcDE.extension(); + const int tpcNRow = tpc->maxRow; + + HitListVector hitsInLayer(tpcNRow); + addToHitListVector(hV.begin(), hV.end(), hitsInLayer); + + std::vector clu(n); + + std::vector lastp(n); + + for (unsigned i = 0; i < n; ++i) { + + clu[i] = new CluTrack; + + cluVec.push_back(clu[i]); } - //------------------------------------------------------------------------------------------------------------------------- + for (int l = tpcNRow - 1; l >= 0; --l) { + + HitList& hL = hitsInLayer[l]; + + streamlog_out(DEBUG) << " create_n_clusters --- layer " << l << " size: " << hL.size() << std::endl; - void create_n_clusters( Clusterer::cluster_type& hV, Clusterer::cluster_list& cluVec , unsigned n ) { - - if( n < 4 ){ - - streamlog_out( ERROR ) << " create_n_clusters called for n = " << n << std::endl ; - return ; + if (hL.size() != n) { // ignore layers with different hit numbers + + continue; } - - // copy of the algorithm for creating three clusters (minimize angle between hits as seen from IP) - - hV.freeElements() ; - - dd4hep::Detector& lcdd = dd4hep::Detector::getInstance(); - dd4hep::DetElement tpcDE = lcdd.detector("TPC") ; - dd4hep::rec::FixedPadSizeTPCData* tpc = tpcDE.extension() ; - const int tpcNRow = tpc->maxRow ; - - - HitListVector hitsInLayer( tpcNRow ) ; - addToHitListVector( hV.begin(), hV.end(), hitsInLayer ) ; - - std::vector< CluTrack*> clu(n) ; - - std::vector< dd4hep::rec::Vector3D > lastp(n) ; - - for(unsigned i=0; i= 0 ; --l){ - - HitList& hL = hitsInLayer[ l ] ; - - streamlog_out( DEBUG ) << " create_n_clusters --- layer " << l << " size: " << hL.size() << std::endl ; - - if( hL.size() != n ){ // ignore layers with different hit numbers - - continue ; - } - - HitList::iterator iH = hL.begin() ; - - std::vector h(n) ; - std::vector< dd4hep::rec::Vector3D> p(n) ; - - - streamlog_out( DEBUG2 ) << " create_n_clusters --- layer " << l << std::endl ; - - for(unsigned i=0; ifirst->pos ; - - streamlog_out( DEBUG2 ) << " h"<< i << ": " << p[i] << std::endl ; - } - - streamlog_out( DEBUG2 ) << " ---------------------------- " << std::endl ; - - - if( clu[0]->empty() ){ // first hit tuple - - streamlog_out( DEBUG ) << " create_n_clusters --- initialize clusters " << std::endl ; - - for(unsigned i=0; iaddElement( h[i] ) ; - - lastp[i] = ( 1. / p[i].r() ) * p[i] ; - } - - continue ; //---------- that's all for the first layer w/ hits - } - - - // unit vector in direction of current hits - std::vector< dd4hep::rec::Vector3D > pu(n) ; - for(unsigned i=0; i h(n); + std::vector p(n); + + streamlog_out(DEBUG2) << " create_n_clusters --- layer " << l << std::endl; + + for (unsigned i = 0; i < n; ++i) { + + h[i] = *iH++; + + p[i] = h[i]->first->pos; + + streamlog_out(DEBUG2) << " h" << i << ": " << p[i] << std::endl; + } + + streamlog_out(DEBUG2) << " ---------------------------- " << std::endl; + + if (clu[0]->empty()) { // first hit tuple + + streamlog_out(DEBUG) << " create_n_clusters --- initialize clusters " << std::endl; - pu[i] = ( 1. / p[i].r() ) * p[i] ; + for (unsigned i = 0; i < n; ++i) { + + clu[i]->addElement(h[i]); + + lastp[i] = (1. / p[i].r()) * p[i]; } - - std::list< CDot > cDot ; - - // create list of dot products between last hit in cluster and current hit - // cos( angle between hits as seen from IP ) - for( unsigned i = 0 ; i < n ; ++i ){ - for( unsigned j = 0 ; j < n ; ++j ){ - - cDot.push_back( CDot( i , j , lastp[i].dot( pu[ j ] ) )) ; - } - } - - // sort dot products in descending order - cDot.sort( sort_CDot ) ; - - // assign hits to clusters with largest dot product ( smallest angle ) - - std::set cluIdx ; - std::set hitIdx ; - - for( std::list::iterator it = cDot.begin() ; it != cDot.end() ; ++ it ) { - - streamlog_out( DEBUG2 ) << " I : " << it->I - << " J : " << it->J - << " d : " << it->Dot - << std::endl ; - unsigned i = it->I ; - unsigned j = it->J ; - - // ignore clusters or hits that hvae already been assigned - if( cluIdx.find( i ) == cluIdx.end() && hitIdx.find( j ) == hitIdx.end() ){ - - cluIdx.insert( i ) ; - hitIdx.insert( j ) ; - - clu[ i ]->addElement( h[ j ] ) ; - - // cluDir[i] = - ( p[j] - lastp[i] ) ; - // cluDir[i] = ( 1. / cluDir[i].r() ) * cluDir[i] ; - - lastp[i] = p[j] ; - - streamlog_out( DEBUG2 ) << " **** adding to cluster : " << it->I - << " hit : " << it->J - << " d : " << it->Dot - << std::endl ; - } - + + continue; //---------- that's all for the first layer w/ hits + } + + // unit vector in direction of current hits + std::vector pu(n); + + for (unsigned i = 0; i < n; ++i) { + + pu[i] = (1. / p[i].r()) * p[i]; + } + + std::list cDot; + + // create list of dot products between last hit in cluster and current hit + // cos( angle between hits as seen from IP ) + for (unsigned i = 0; i < n; ++i) { + for (unsigned j = 0; j < n; ++j) { + + cDot.push_back(CDot(i, j, lastp[i].dot(pu[j]))); } } + // sort dot products in descending order + cDot.sort(sort_CDot); - streamlog_out( DEBUG ) << " create_three_clusters --- clu[0] " << clu[0]->size() - << " clu[1] " << clu[1]->size() - << " clu[2] " << clu[2]->size() - << std::endl ; + // assign hits to clusters with largest dot product ( smallest angle ) + std::set cluIdx; + std::set hitIdx; + for (std::list::iterator it = cDot.begin(); it != cDot.end(); ++it) { + streamlog_out(DEBUG2) << " I : " << it->I << " J : " << it->J << " d : " << it->Dot << std::endl; + unsigned i = it->I; + unsigned j = it->J; - return ; + // ignore clusters or hits that hvae already been assigned + if (cluIdx.find(i) == cluIdx.end() && hitIdx.find(j) == hitIdx.end()) { + + cluIdx.insert(i); + hitIdx.insert(j); + + clu[i]->addElement(h[j]); + + // cluDir[i] = - ( p[j] - lastp[i] ) ; + // cluDir[i] = ( 1. / cluDir[i].r() ) * cluDir[i] ; + + lastp[i] = p[j]; + + streamlog_out(DEBUG2) << " **** adding to cluster : " << it->I << " hit : " << it->J << " d : " << it->Dot + << std::endl; + } + } } + streamlog_out(DEBUG) << " create_three_clusters --- clu[0] " << clu[0]->size() << " clu[1] " << clu[1]->size() + << " clu[2] " << clu[2]->size() << std::endl; + + return; +} //====================================================================================================================== - void create_three_clusters( Clusterer::cluster_type& hV, Clusterer::cluster_list& cluVec ) { - - hV.freeElements() ; - - dd4hep::Detector& lcdd = dd4hep::Detector::getInstance(); - dd4hep::DetElement tpcDE = lcdd.detector("TPC") ; - dd4hep::rec::FixedPadSizeTPCData* tpc = tpcDE.extension() ; - const int tpcNRow = tpc->maxRow ; - - HitListVector hitsInLayer( tpcNRow ) ; - addToHitListVector( hV.begin(), hV.end(), hitsInLayer ) ; - - CluTrack* clu[3] ; - - dd4hep::rec::Vector3D lastp[3] ; - // dd4hep::rec::Vector3D cluDir[3] ; - - clu[0] = new CluTrack ; - clu[1] = new CluTrack ; - clu[2] = new CluTrack ; - - cluVec.push_back( clu[0] ) ; - cluVec.push_back( clu[1] ) ; - cluVec.push_back( clu[2] ) ; - - - for( int l=tpcNRow-1 ; l >= 0 ; --l){ - - HitList& hL = hitsInLayer[ l ] ; - - streamlog_out( DEBUG ) << " create_three_clusters --- layer " << l << " size: " << hL.size() << std::endl ; - - if( hL.size() != 3 ){ - - continue ; - } - - HitList::iterator iH = hL.begin() ; - - Hit* h[3] ; - h[0] = *iH++ ; - h[1] = *iH++ ; - h[2] = *iH ; - - dd4hep::rec::Vector3D p[3] ; - p[0] = h[0]->first->pos ; - p[1] = h[1]->first->pos ; - p[2] = h[2]->first->pos ; - - - streamlog_out( DEBUG ) << " create_three_clusters --- layer " << l - << " h0 : " << p[0] - << " h1 : " << p[1] - << " h2 : " << p[2] ; - // << std::endl ; - - if( clu[0]->empty() ){ // first hit triplet - - streamlog_out( DEBUG ) << " create_three_clusters --- initialize clusters " << std::endl ; - - clu[0]->addElement( h[0] ) ; - clu[1]->addElement( h[1] ) ; - clu[2]->addElement( h[2] ) ; - - // lastp[0] = p[0] ; - // lastp[1] = p[1] ; - // lastp[2] = p[2] ; - - lastp[0] = ( 1. / p[0].r() ) * p[0] ; - lastp[1] = ( 1. / p[1].r() ) * p[1] ; - lastp[2] = ( 1. / p[2].r() ) * p[2] ; - - continue ; - } - - - // unit vector in direction of current hits - dd4hep::rec::Vector3D pu[3] ; - pu[0] = ( 1. / p[0].r() ) * p[0] ; - pu[1] = ( 1. / p[1].r() ) * p[1] ; - pu[2] = ( 1. / p[2].r() ) * p[2] ; - - - std::list< CDot > cDot ; - - // create list of dot products between last hit in cluster and current hit - // cos( angle between hits as seen from IP ) - for( int i = 0 ; i < 3 ; ++i ){ - for( int j = 0 ; j < 3 ; ++j ){ - - // // unit vector in direction of last hit and - // dd4hep::rec::Vector3D pu = - ( p[0] - lastp[0] ) ; - // pu[1] = - ( p[1] - lastp[1] ) ; - // pu[2] = - ( p[2] - lastp[2] ) ; - // pu[0] = ( 1. / pu[0].r() ) * pu[0] ; - // pu[1] = ( 1. / pu[1].r() ) * pu[1] ; - // pu[2] = ( 1. / pu[2].r() ) * pu[2] ; - // cDot.push_back( CDot( i , j , cluDir[i].dot( pu[ j ] ) )) ; - - cDot.push_back( CDot( i , j , lastp[i].dot( pu[ j ] ) )) ; - - } - } - - // sort dot products in descending order - cDot.sort( sort_CDot ) ; - - // assign hits to clusters with largest dot product ( smallest angle ) - - std::set cluIdx ; - std::set hitIdx ; - - for( std::list::iterator it = cDot.begin() ; it != cDot.end() ; ++ it ) { - - streamlog_out( DEBUG ) << " I : " << it->I - << " J : " << it->J - << " d : " << it->Dot - << std::endl ; - - int i = it->I ; - int j = it->J ; - - // ignore clusters or hits that hvae already been assigned - if( cluIdx.find( i ) == cluIdx.end() && hitIdx.find( j ) == hitIdx.end() ){ - - cluIdx.insert( i ) ; - hitIdx.insert( j ) ; - - clu[ i ]->addElement( h[ j ] ) ; - - // cluDir[i] = - ( p[j] - lastp[i] ) ; - // cluDir[i] = ( 1. / cluDir[i].r() ) * cluDir[i] ; - - lastp[i] = p[j] ; - - streamlog_out( DEBUG ) << " **** adding to cluster : " << it->I - << " hit : " << it->J - << " d : " << it->Dot - << std::endl ; - } - - } +void create_three_clusters(Clusterer::cluster_type& hV, Clusterer::cluster_list& cluVec) { + + hV.freeElements(); + + dd4hep::Detector& lcdd = dd4hep::Detector::getInstance(); + dd4hep::DetElement tpcDE = lcdd.detector("TPC"); + dd4hep::rec::FixedPadSizeTPCData* tpc = tpcDE.extension(); + const int tpcNRow = tpc->maxRow; + + HitListVector hitsInLayer(tpcNRow); + addToHitListVector(hV.begin(), hV.end(), hitsInLayer); + + CluTrack* clu[3]; + + dd4hep::rec::Vector3D lastp[3]; + // dd4hep::rec::Vector3D cluDir[3] ; + + clu[0] = new CluTrack; + clu[1] = new CluTrack; + clu[2] = new CluTrack; + + cluVec.push_back(clu[0]); + cluVec.push_back(clu[1]); + cluVec.push_back(clu[2]); + + for (int l = tpcNRow - 1; l >= 0; --l) { + + HitList& hL = hitsInLayer[l]; + + streamlog_out(DEBUG) << " create_three_clusters --- layer " << l << " size: " << hL.size() << std::endl; + + if (hL.size() != 3) { + + continue; + } + + HitList::iterator iH = hL.begin(); + + Hit* h[3]; + h[0] = *iH++; + h[1] = *iH++; + h[2] = *iH; + + dd4hep::rec::Vector3D p[3]; + p[0] = h[0]->first->pos; + p[1] = h[1]->first->pos; + p[2] = h[2]->first->pos; + + streamlog_out(DEBUG) << " create_three_clusters --- layer " << l << " h0 : " << p[0] << " h1 : " << p[1] + << " h2 : " << p[2]; + // << std::endl ; + + if (clu[0]->empty()) { // first hit triplet + + streamlog_out(DEBUG) << " create_three_clusters --- initialize clusters " << std::endl; + + clu[0]->addElement(h[0]); + clu[1]->addElement(h[1]); + clu[2]->addElement(h[2]); - // lastp[0] = pu[0] ; - // lastp[1] = pu[1] ; - // lastp[2] = pu[2] ; // lastp[0] = p[0] ; // lastp[1] = p[1] ; // lastp[2] = p[2] ; - - + + lastp[0] = (1. / p[0].r()) * p[0]; + lastp[1] = (1. / p[1].r()) * p[1]; + lastp[2] = (1. / p[2].r()) * p[2]; + + continue; } + // unit vector in direction of current hits + dd4hep::rec::Vector3D pu[3]; + pu[0] = (1. / p[0].r()) * p[0]; + pu[1] = (1. / p[1].r()) * p[1]; + pu[2] = (1. / p[2].r()) * p[2]; + + std::list cDot; + + // create list of dot products between last hit in cluster and current hit + // cos( angle between hits as seen from IP ) + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + + // // unit vector in direction of last hit and + // dd4hep::rec::Vector3D pu = - ( p[0] - lastp[0] ) ; + // pu[1] = - ( p[1] - lastp[1] ) ; + // pu[2] = - ( p[2] - lastp[2] ) ; + // pu[0] = ( 1. / pu[0].r() ) * pu[0] ; + // pu[1] = ( 1. / pu[1].r() ) * pu[1] ; + // pu[2] = ( 1. / pu[2].r() ) * pu[2] ; + // cDot.push_back( CDot( i , j , cluDir[i].dot( pu[ j ] ) )) ; + + cDot.push_back(CDot(i, j, lastp[i].dot(pu[j]))); + } + } + + // sort dot products in descending order + cDot.sort(sort_CDot); + + // assign hits to clusters with largest dot product ( smallest angle ) + + std::set cluIdx; + std::set hitIdx; + + for (std::list::iterator it = cDot.begin(); it != cDot.end(); ++it) { + + streamlog_out(DEBUG) << " I : " << it->I << " J : " << it->J << " d : " << it->Dot << std::endl; - streamlog_out( DEBUG ) << " create_three_clusters --- clu[0] " << clu[0]->size() - << " clu[1] " << clu[1]->size() - << " clu[2] " << clu[2]->size() - << std::endl ; + int i = it->I; + int j = it->J; + // ignore clusters or hits that hvae already been assigned + if (cluIdx.find(i) == cluIdx.end() && hitIdx.find(j) == hitIdx.end()) { + cluIdx.insert(i); + hitIdx.insert(j); + clu[i]->addElement(h[j]); + + // cluDir[i] = - ( p[j] - lastp[i] ) ; + // cluDir[i] = ( 1. / cluDir[i].r() ) * cluDir[i] ; + + lastp[i] = p[j]; + + streamlog_out(DEBUG) << " **** adding to cluster : " << it->I << " hit : " << it->J << " d : " << it->Dot + << std::endl; + } + } - return ; + // lastp[0] = pu[0] ; + // lastp[1] = pu[1] ; + // lastp[2] = pu[2] ; + // lastp[0] = p[0] ; + // lastp[1] = p[1] ; + // lastp[2] = p[2] ; } - //----------------------------------------------------------------- - void create_two_clusters( Clusterer::cluster_type& clu, Clusterer::cluster_list& cluVec ) { - + streamlog_out(DEBUG) << " create_three_clusters --- clu[0] " << clu[0]->size() << " clu[1] " << clu[1]->size() + << " clu[2] " << clu[2]->size() << std::endl; - clu.freeElements() ; - - streamlog_out( DEBUG ) << " create_two_clusters --- called ! - size : " << clu.size() << std::endl ; + return; +} +//----------------------------------------------------------------- - dd4hep::Detector& lcdd = dd4hep::Detector::getInstance(); - dd4hep::DetElement tpcDE = lcdd.detector("TPC") ; - dd4hep::rec::FixedPadSizeTPCData* tpc = tpcDE.extension() ; - const int tpcNRow = tpc->maxRow ; - - HitListVector hitsInLayer( tpcNRow ) ; +void create_two_clusters(Clusterer::cluster_type& clu, Clusterer::cluster_list& cluVec) { - addToHitListVector( clu.begin(), clu.end(), hitsInLayer ) ; - + clu.freeElements(); - CluTrack* clu0 = new CluTrack ; - CluTrack* clu1 = new CluTrack ; + streamlog_out(DEBUG) << " create_two_clusters --- called ! - size : " << clu.size() << std::endl; - cluVec.push_back( clu0 ) ; - cluVec.push_back( clu1 ) ; + dd4hep::Detector& lcdd = dd4hep::Detector::getInstance(); + dd4hep::DetElement tpcDE = lcdd.detector("TPC"); + dd4hep::rec::FixedPadSizeTPCData* tpc = tpcDE.extension(); + const int tpcNRow = tpc->maxRow; + HitListVector hitsInLayer(tpcNRow); - dd4hep::rec::Vector3D lastDiffVec(0.,0.,0.) ; - - for( int l=tpcNRow-1 ; l >= 0 ; --l){ + addToHitListVector(clu.begin(), clu.end(), hitsInLayer); - HitList& hL = hitsInLayer[ l ] ; - - streamlog_out( DEBUG ) << " create_two_clusters --- layer " << l << " size: " << hL.size() << std::endl ; + CluTrack* clu0 = new CluTrack; + CluTrack* clu1 = new CluTrack; - if( hL.size() != 2 ){ - - // if there is not exactly two hits in the layer, we simply copy the unassigned hits to the leftover hit vector - // std::copy( hL.begin(), hL.end() , std::back_inserter( hV ) ) ; - continue ; - } + cluVec.push_back(clu0); + cluVec.push_back(clu1); - HitList::iterator iH = hL.begin() ; - - Hit* h0 = *iH++ ; - Hit* h1 = *iH ; - - dd4hep::rec::Vector3D& p0 = h0->first->pos ; - dd4hep::rec::Vector3D& p1 = h1->first->pos ; - - - streamlog_out( DEBUG ) << " create_two_clusters --- layer " << l - << " h0 : " << p0 - << " h1 : " << p1 ; - // << std::endl ; - - if( clu0->empty() ){ // first hit pair - - streamlog_out( DEBUG ) << " create_two_clusters --- initialize clusters " << std::endl ; - - clu0->addElement( h0 ) ; - clu1->addElement( h1 ) ; - - lastDiffVec = p1 - p0 ; - - continue ; - } + dd4hep::rec::Vector3D lastDiffVec(0., 0., 0.); - dd4hep::rec::Vector3D d = p1 - p0 ; - - float s0 = ( lastDiffVec + d ).r() ; - float s1 = ( lastDiffVec - d ).r() ; - - if( s0 > s1 ){ // same orientation, i.e. h0 in this layer belongs to h0 in first layer - - streamlog_out( DEBUG ) << " create_two_clusters --- same orientation " << std::endl ; - clu0->addElement( h0 ) ; - clu1->addElement( h1 ) ; - - } else{ // oposite orientation, i.e. h1 in this layer belongs to h0 in first layer - - streamlog_out( DEBUG2 ) << " create_two_clusters --- oposite orientation " << std::endl ; - clu0->addElement( h1 ) ; - clu1->addElement( h0 ) ; - } + for (int l = tpcNRow - 1; l >= 0; --l) { + + HitList& hL = hitsInLayer[l]; + + streamlog_out(DEBUG) << " create_two_clusters --- layer " << l << " size: " << hL.size() << std::endl; + + if (hL.size() != 2) { + // if there is not exactly two hits in the layer, we simply copy the unassigned hits to the leftover hit vector + // std::copy( hL.begin(), hL.end() , std::back_inserter( hV ) ) ; + continue; } - // clu.freeHits() ; + HitList::iterator iH = hL.begin(); - streamlog_out( DEBUG1 ) << " create_two_clusters --- clu0 " << clu0->size() - << " clu1 " << clu1->size() << std::endl ; + Hit* h0 = *iH++; + Hit* h1 = *iH; - // return std::make_pair( clu0 , clu1 ) ; + dd4hep::rec::Vector3D& p0 = h0->first->pos; + dd4hep::rec::Vector3D& p1 = h1->first->pos; - return ; - } + streamlog_out(DEBUG) << " create_two_clusters --- layer " << l << " h0 : " << p0 << " h1 : " << p1; + // << std::endl ; - //------------------------------------------------------------------------------------------------------------------------- - - - // /** Find the nearest hits in the previous and next layers - (at most maxStep layers appart - NOT YET). - // */ - // void findNearestHits( CluTrack& clu, int maxLayerID, int maxStep){ - - // HitListVector hitsInLayer( maxLayerID ) ; - // addToHitListVector( clu.begin(), clu.end(), hitsInLayer ) ; - - // for(CluTrack::iterator it= clu.begin() ; it != clu.end() ; ++it ){ - - // Hit* hit0 = *it ; - // dd4hep::rec::Vector3D& pos0 = hit0->first->pos ; - - // int layer = hit0->first->layerID ; - - // int l=0 ; - // if( (l=layer+1) < maxLayerID ) { - - // HitList& hL = hitsInLayer[ l ] ; - - // double minDist2 = 1.e99 ; - // Hit* bestHit = 0 ; - - // for( HitList::iterator iH = hL.begin() ; iH != hL.end() ; ++iH ) { - - // Hit* hit1 = *iH ; - // dd4hep::rec::Vector3D& pos1 = hit1->first->pos ; - - // double dist2 = ( pos0 - pos1 ).r2() ; - - // if( dist2 < minDist2 ){ - // minDist2 = dist2 ; - // bestHit = hit1 ; - // } - // } - // if( bestHit ){ - - // hit0->first->nNNHit = bestHit->first ; - // hit0->first->nDist = minDist2 ; - // } - // } - - // if( (l=layer-1) > 0 ) { - - // HitList& hL = hitsInLayer[ l ] ; - - // double minDist2 = 1.e99 ; - // Hit* bestHit = 0 ; - - // for( HitList::iterator iH = hL.begin() ; iH != hL.end() ; ++iH ) { - - // Hit* hit1 = *iH ; - // dd4hep::rec::Vector3D& pos1 = hit1->first->pos ; - - // double dist2 = ( pos0 - pos1 ).r2() ; - - // if( dist2 < minDist2 ){ - // minDist2 = dist2 ; - // bestHit = hit1 ; - // } - // } - // if( bestHit ){ - - // hit0->first->pNNHit = bestHit->first ; - // hit0->first->pDist = minDist2 ; - // } - // } - - // } - // } - - - //------------------------------------------------------------------------------------------------------------------------- - - MarlinTrk::IMarlinTrack* IMarlinTrkFitter::operator() (CluTrack* clu) { - - bool isFirstFit = true ; - double maxChi2 = _maxChi2Increment ; - - start: - - MarlinTrk::IMarlinTrack* trk = _ts->createTrack(); - - //if( clu->empty() ){ - if( clu->size() < 3 ){ - - streamlog_out( ERROR ) << " IMarlinTrkFitter::operator() : cannot fit cluster track with less than 3 hits ! " << std::endl ; - - return trk ; - } - - clu->ext() = trk ; - - clu->sort( LayerSortOut() ) ; - - // need to reverse the order for incomming track segments (curlers) - // assume particle comes from IP - Hit* hf = clu->front() ; - Hit* hb = clu->back() ; - - bool reverse_order = ( std::abs( hf->first->pos.z() ) > std::abs( hb->first->pos.z()) + 3. ) ; - - unsigned nHit = 0 ; - - if( reverse_order ){ - - for( CluTrack::reverse_iterator it=clu->rbegin() ; it != clu->rend() ; ++it){ - - trk->addHit( (*it)->first->lcioHit ) ; - ++nHit ; - - streamlog_out( DEBUG1 ) << " hit added " << *(*it)->first->lcioHit << std::endl ; - } - - trk->initialise( MarlinTrk::IMarlinTrack::forward ) ; - - } else { - - for( CluTrack::iterator it=clu->begin() ; it != clu->end() ; ++it){ - - trk->addHit( (*it)->first->lcioHit ) ; - ++nHit ; - - streamlog_out( DEBUG1 ) << " hit added "<< *(*it)->first->lcioHit << std::endl ; - } - - trk->initialise( MarlinTrk::IMarlinTrack::backward ) ; - } - - - int code = trk->fit( maxChi2 ) ; - - if( code != MarlinTrk::IMarlinTrack::success ){ - - streamlog_out( ERROR ) << " >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IMarlinTrkFitter : problem fitting track " - << " error code : " << MarlinTrk::errorCode( code ) - << std::endl ; - + if (clu0->empty()) { // first hit pair + + streamlog_out(DEBUG) << " create_two_clusters --- initialize clusters " << std::endl; + + clu0->addElement(h0); + clu1->addElement(h1); + + lastDiffVec = p1 - p0; + + continue; } - - - //----- if the fit did not fail but has a small number of hits used, - // we try again one more time with a larger max-chi2-increment - - std::vector > hitsInFit ; - trk->getHitsInFit( hitsInFit ) ; - - if( isFirstFit && ( 1.*hitsInFit.size()) / (1.*nHit ) < 0.2 ) { // fixme: parameter - - isFirstFit = false ; - - maxChi2 = 2. * _maxChi2Increment ; - - streamlog_out( DEBUG4 ) << " >>>>>> IMarlinTrkFitter : small number of hits used in fit " << hitsInFit.size() << "/" << nHit << " = " - << ( 1.*hitsInFit.size()) / (1.*nHit ) << " refit with larger max chi2 increment: " << maxChi2 << std::endl ; - delete trk ; - - goto start ; // ;-) + + dd4hep::rec::Vector3D d = p1 - p0; + + float s0 = (lastDiffVec + d).r(); + float s1 = (lastDiffVec - d).r(); + + if (s0 > s1) { // same orientation, i.e. h0 in this layer belongs to h0 in first layer + + streamlog_out(DEBUG) << " create_two_clusters --- same orientation " << std::endl; + clu0->addElement(h0); + clu1->addElement(h1); + + } else { // oposite orientation, i.e. h1 in this layer belongs to h0 in first layer + + streamlog_out(DEBUG2) << " create_two_clusters --- oposite orientation " << std::endl; + clu0->addElement(h1); + clu1->addElement(h0); } - //---------------------------------------------------------------------- + } + + // clu.freeHits() ; + + streamlog_out(DEBUG1) << " create_two_clusters --- clu0 " << clu0->size() << " clu1 " << clu1->size() << std::endl; + + // return std::make_pair( clu0 , clu1 ) ; + + return; +} + +//------------------------------------------------------------------------------------------------------------------------- + +// /** Find the nearest hits in the previous and next layers - (at most maxStep layers appart - NOT YET). +// */ +// void findNearestHits( CluTrack& clu, int maxLayerID, int maxStep){ + +// HitListVector hitsInLayer( maxLayerID ) ; +// addToHitListVector( clu.begin(), clu.end(), hitsInLayer ) ; + +// for(CluTrack::iterator it= clu.begin() ; it != clu.end() ; ++it ){ + +// Hit* hit0 = *it ; +// dd4hep::rec::Vector3D& pos0 = hit0->first->pos ; + +// int layer = hit0->first->layerID ; + +// int l=0 ; +// if( (l=layer+1) < maxLayerID ) { + +// HitList& hL = hitsInLayer[ l ] ; + +// double minDist2 = 1.e99 ; +// Hit* bestHit = 0 ; + +// for( HitList::iterator iH = hL.begin() ; iH != hL.end() ; ++iH ) { + +// Hit* hit1 = *iH ; +// dd4hep::rec::Vector3D& pos1 = hit1->first->pos ; + +// double dist2 = ( pos0 - pos1 ).r2() ; + +// if( dist2 < minDist2 ){ +// minDist2 = dist2 ; +// bestHit = hit1 ; +// } +// } +// if( bestHit ){ + +// hit0->first->nNNHit = bestHit->first ; +// hit0->first->nDist = minDist2 ; +// } +// } + +// if( (l=layer-1) > 0 ) { + +// HitList& hL = hitsInLayer[ l ] ; + +// double minDist2 = 1.e99 ; +// Hit* bestHit = 0 ; + +// for( HitList::iterator iH = hL.begin() ; iH != hL.end() ; ++iH ) { + +// Hit* hit1 = *iH ; +// dd4hep::rec::Vector3D& pos1 = hit1->first->pos ; + +// double dist2 = ( pos0 - pos1 ).r2() ; + +// if( dist2 < minDist2 ){ +// minDist2 = dist2 ; +// bestHit = hit1 ; +// } +// } +// if( bestHit ){ + +// hit0->first->pNNHit = bestHit->first ; +// hit0->first->pDist = minDist2 ; +// } +// } + +// } +// } + +//------------------------------------------------------------------------------------------------------------------------- + +MarlinTrk::IMarlinTrack* IMarlinTrkFitter::operator()(CluTrack* clu) { + + bool isFirstFit = true; + double maxChi2 = _maxChi2Increment; + +start: + + MarlinTrk::IMarlinTrack* trk = _ts->createTrack(); + + // if( clu->empty() ){ + if (clu->size() < 3) { + + streamlog_out(ERROR) << " IMarlinTrkFitter::operator() : cannot fit cluster track with less than 3 hits ! " + << std::endl; return trk; } - - - //--------------------------------------------------------------------------------------------------------------------------- - - lcio::Track* LCIOTrackConverter::operator() (CluTrack* c) { - - static lcio::BitField64 encoder( lcio::LCTrackerCellID::encoding_string() ) ; - - lcio::TrackImpl* trk = new lcio::TrackImpl ; - - trk->setTypeBit( lcio::ILDDetID::TPC ) ; - - double e = 0.0 ; - int nHit = 0 ; - for( CluTrack::iterator hi = c->begin(); hi != c->end() ; hi++) { - - // reset outliers (not used in fit) bit - // IMPL::TrackerHitImpl* thi = dynamic_cast ( (*hi)->first->lcioHit ) ; - // thi->setQualityBit( UTIL::ILDTrkHitQualityBit::USED_IN_FIT , 0 ) ; - - trk->addHit( (*hi)->first->lcioHit ) ; - e += (*hi)->first->lcioHit->getEDep() ; - nHit++ ; + + clu->ext() = trk; + + clu->sort(LayerSortOut()); + + // need to reverse the order for incomming track segments (curlers) + // assume particle comes from IP + Hit* hf = clu->front(); + Hit* hb = clu->back(); + + bool reverse_order = (std::abs(hf->first->pos.z()) > std::abs(hb->first->pos.z()) + 3.); + + unsigned nHit = 0; + + if (reverse_order) { + + for (CluTrack::reverse_iterator it = clu->rbegin(); it != clu->rend(); ++it) { + + trk->addHit((*it)->first->lcioHit); + ++nHit; + + streamlog_out(DEBUG1) << " hit added " << *(*it)->first->lcioHit << std::endl; } - MarlinTrk::IMarlinTrack* mtrk = c->ext() ; - - trk->ext() = mtrk ; - - trk->setdEdx( ( nHit ? e/nHit : -1. ) ) ; - trk->subdetectorHitNumbers().resize( 2 * lcio::ILDDetID::ETD ) ; - - trk->subdetectorHitNumbers()[ 2*lcio::ILDDetID::TPC - 2 ] = 0 ; - trk->subdetectorHitNumbers()[ 2*lcio::ILDDetID::TPC - 1 ] = nHit ; - - if( mtrk != 0 && ! c->empty() ){ - - - std::vector > hitsInFit ; - mtrk->getHitsInFit( hitsInFit ) ; - trk->subdetectorHitNumbers()[ 2*lcio::ILDDetID::TPC - 2 ] = hitsInFit.size() ; - - if( ! hitsInFit.empty() ){ - - // store the delta chi2 for the given hit - for(unsigned i=0, N=hitsInFit.size() ; iext() = hitsInFit[i].second ; - - //IMPL::TrackerHitImpl* thi = dynamic_cast ( hitsInFit[i].first ) ; - //thi->setQualityBit( UTIL::ILDTrkHitQualityBit::USED_IN_FIT , 1 ) ; - } - - lcio::TrackStateImpl* tsIP = new lcio::TrackStateImpl ; - lcio::TrackStateImpl* tsFH = new lcio::TrackStateImpl ; - lcio::TrackStateImpl* tsLH = new lcio::TrackStateImpl ; - lcio::TrackStateImpl* tsCA = new lcio::TrackStateImpl ; - - tsIP->setLocation( lcio::TrackState::AtIP ) ; - tsFH->setLocation( lcio::TrackState::AtFirstHit ) ; - tsLH->setLocation( lcio::TrackState::AtLastHit) ; - tsCA->setLocation( lcio::TrackState::AtCalorimeter ) ; - - double chi2 ; - int ndf ; - int code ; - - // Hit* hf = c->front() ; - // Hit* hb = c->back() ; - // bool reverse_order = ( std::abs( hf->first->pos.z() ) > std::abs( hb->first->pos.z()) + 3. ) ; - // lcio::TrackerHit* fHit = ( reverse_order ? hb->first->lcioHit : hf->first->lcioHit ) ; - // lcio::TrackerHit* lHit = ( reverse_order ? hf->first->lcioHit : hb->first->lcioHit ) ; - - lcio::TrackerHit* fHit = hitsInFit.back().first ; - lcio::TrackerHit* lHit = hitsInFit.front().first ; - //order of hits in fit is reversed wrt time (we fit inwards) - - // ======= get TrackState at first hit ======================== - - code = mtrk->getTrackState( fHit, *tsFH, chi2, ndf ) ; - - if( code != MarlinTrk::IMarlinTrack::success ){ - - streamlog_out( DEBUG6 ) << " >>>>>>>>>>> LCIOTrackConverter : could not get TrackState at first Hit !!?? " - << " error code : " << MarlinTrk::errorCode( code ) - << std::endl ; - } - - // ======= get TrackState at last hit ======================== + trk->initialise(MarlinTrk::IMarlinTrack::forward); + + } else { + + for (CluTrack::iterator it = clu->begin(); it != clu->end(); ++it) { + + trk->addHit((*it)->first->lcioHit); + ++nHit; + + streamlog_out(DEBUG1) << " hit added " << *(*it)->first->lcioHit << std::endl; + } + + trk->initialise(MarlinTrk::IMarlinTrack::backward); + } + + int code = trk->fit(maxChi2); + + if (code != MarlinTrk::IMarlinTrack::success) { + + streamlog_out(ERROR) << " >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IMarlinTrkFitter : problem fitting track " + << " error code : " << MarlinTrk::errorCode(code) << std::endl; + } + + //----- if the fit did not fail but has a small number of hits used, + // we try again one more time with a larger max-chi2-increment + + std::vector> hitsInFit; + trk->getHitsInFit(hitsInFit); + + if (isFirstFit && (1. * hitsInFit.size()) / (1. * nHit) < 0.2) { // fixme: parameter + + isFirstFit = false; + + maxChi2 = 2. * _maxChi2Increment; + + streamlog_out(DEBUG4) << " >>>>>> IMarlinTrkFitter : small number of hits used in fit " << hitsInFit.size() + << "/" << nHit << " = " << (1. * hitsInFit.size()) / (1. * nHit) + << " refit with larger max chi2 increment: " << maxChi2 << std::endl; + delete trk; + + goto start; // ;-) + } + //---------------------------------------------------------------------- + + return trk; +} + +//--------------------------------------------------------------------------------------------------------------------------- + +lcio::Track* LCIOTrackConverter::operator()(CluTrack* c) { + + static lcio::BitField64 encoder(lcio::LCTrackerCellID::encoding_string()); + + lcio::TrackImpl* trk = new lcio::TrackImpl; + + trk->setTypeBit(lcio::ILDDetID::TPC); + + double e = 0.0; + int nHit = 0; + for (CluTrack::iterator hi = c->begin(); hi != c->end(); hi++) { + + // reset outliers (not used in fit) bit + // IMPL::TrackerHitImpl* thi = dynamic_cast ( (*hi)->first->lcioHit ) ; + // thi->setQualityBit( UTIL::ILDTrkHitQualityBit::USED_IN_FIT , 0 ) ; + + trk->addHit((*hi)->first->lcioHit); + e += (*hi)->first->lcioHit->getEDep(); + nHit++; + } + + MarlinTrk::IMarlinTrack* mtrk = c->ext(); + + trk->ext() = mtrk; + + trk->setdEdx((nHit ? e / nHit : -1.)); + trk->subdetectorHitNumbers().resize(2 * lcio::ILDDetID::ETD); + + trk->subdetectorHitNumbers()[2 * lcio::ILDDetID::TPC - 2] = 0; + trk->subdetectorHitNumbers()[2 * lcio::ILDDetID::TPC - 1] = nHit; + + if (mtrk != 0 && !c->empty()) { + + std::vector> hitsInFit; + mtrk->getHitsInFit(hitsInFit); + trk->subdetectorHitNumbers()[2 * lcio::ILDDetID::TPC - 2] = hitsInFit.size(); + + if (!hitsInFit.empty()) { + + // store the delta chi2 for the given hit + for (unsigned i = 0, N = hitsInFit.size(); i < N; ++i) { + + hitsInFit[i].first->ext() = hitsInFit[i].second; + + // IMPL::TrackerHitImpl* thi = dynamic_cast ( hitsInFit[i].first ) ; + // thi->setQualityBit( UTIL::ILDTrkHitQualityBit::USED_IN_FIT , 1 ) ; + } + + lcio::TrackStateImpl* tsIP = new lcio::TrackStateImpl; + lcio::TrackStateImpl* tsFH = new lcio::TrackStateImpl; + lcio::TrackStateImpl* tsLH = new lcio::TrackStateImpl; + lcio::TrackStateImpl* tsCA = new lcio::TrackStateImpl; + + tsIP->setLocation(lcio::TrackState::AtIP); + tsFH->setLocation(lcio::TrackState::AtFirstHit); + tsLH->setLocation(lcio::TrackState::AtLastHit); + tsCA->setLocation(lcio::TrackState::AtCalorimeter); + + double chi2; + int ndf; + int code; + + // Hit* hf = c->front() ; + // Hit* hb = c->back() ; + // bool reverse_order = ( std::abs( hf->first->pos.z() ) > std::abs( hb->first->pos.z()) + 3. ) ; + // lcio::TrackerHit* fHit = ( reverse_order ? hb->first->lcioHit : hf->first->lcioHit ) ; + // lcio::TrackerHit* lHit = ( reverse_order ? hf->first->lcioHit : hb->first->lcioHit ) ; + + lcio::TrackerHit* fHit = hitsInFit.back().first; + lcio::TrackerHit* lHit = hitsInFit.front().first; + // order of hits in fit is reversed wrt time (we fit inwards) + + // ======= get TrackState at first hit ======================== + + code = mtrk->getTrackState(fHit, *tsFH, chi2, ndf); + + if (code != MarlinTrk::IMarlinTrack::success) { + + streamlog_out(DEBUG6) << " >>>>>>>>>>> LCIOTrackConverter : could not get TrackState at first Hit !!?? " + << " error code : " << MarlinTrk::errorCode(code) << std::endl; + } + + // ======= get TrackState at last hit ======================== #define use_fit_at_last_hit 0 #if use_fit_at_last_hit - code = mtrk->getTrackState( lHit, *tsLH, chi2, ndf ) ; -#else // get the track state at the last hit by propagating from the last(first) constrained fit position (a la MarlinTrkUtils) - EVENT::TrackerHit* last_constrained_hit = 0 ; - mtrk->getTrackerHitAtPositiveNDF( last_constrained_hit ); - code = mtrk->smooth() ; - dd4hep::rec::Vector3D last_hit_pos( lHit->getPosition() ); - code = mtrk->propagate( last_hit_pos, last_constrained_hit, *tsLH, chi2, ndf); + code = mtrk->getTrackState(lHit, *tsLH, chi2, ndf); +#else // get the track state at the last hit by propagating from the last(first) constrained fit position (a la + // MarlinTrkUtils) + EVENT::TrackerHit* last_constrained_hit = 0; + mtrk->getTrackerHitAtPositiveNDF(last_constrained_hit); + code = mtrk->smooth(); + dd4hep::rec::Vector3D last_hit_pos(lHit->getPosition()); + code = mtrk->propagate(last_hit_pos, last_constrained_hit, *tsLH, chi2, ndf); #endif - - if( code != MarlinTrk::IMarlinTrack::success ){ - - streamlog_out( DEBUG6 ) << " >>>>>>>>>>> LCIOTrackConverter : could not get TrackState at last Hit !!?? " << std::endl ; - } - - // ======= get TrackState at calo face ======================== - - encoder.reset() ; - encoder[ lcio::LCTrackerCellID::subdet() ] = CaloFaceBarrelID ; - encoder[ lcio::LCTrackerCellID::layer() ] = 0 ; - encoder[ lcio::LCTrackerCellID::side() ] = lcio::ILDDetID::barrel; - int layerID = encoder.lowWord() ; - int sensorID = -1 ; - + + if (code != MarlinTrk::IMarlinTrack::success) { + + streamlog_out(DEBUG6) << " >>>>>>>>>>> LCIOTrackConverter : could not get TrackState at last Hit !!?? " + << std::endl; + } + + // ======= get TrackState at calo face ======================== + + encoder.reset(); + encoder[lcio::LCTrackerCellID::subdet()] = CaloFaceBarrelID; + encoder[lcio::LCTrackerCellID::layer()] = 0; + encoder[lcio::LCTrackerCellID::side()] = lcio::ILDDetID::barrel; + int layerID = encoder.lowWord(); + int sensorID = -1; + #if use_fit_at_last_hit - code = mtrk->propagateToLayer( layerID , lHit, *tsCA, chi2, ndf, sensorID, MarlinTrk::IMarlinTrack::modeClosest ) ; -#else // get the track state at the calorimter from a propagating from the last(first) constrained fit position - code = mtrk->propagateToLayer( layerID , last_constrained_hit, *tsCA, chi2, ndf, sensorID, MarlinTrk::IMarlinTrack::modeClosest ) ; + code = mtrk->propagateToLayer(layerID, lHit, *tsCA, chi2, ndf, sensorID, MarlinTrk::IMarlinTrack::modeClosest); +#else // get the track state at the calorimter from a propagating from the last(first) constrained fit position + code = mtrk->propagateToLayer(layerID, last_constrained_hit, *tsCA, chi2, ndf, sensorID, + MarlinTrk::IMarlinTrack::modeClosest); #endif - - if( code == MarlinTrk::IMarlinTrack::no_intersection ){ - - encoder[ lcio::LCTrackerCellID::subdet() ] = CaloFaceEndcapID ; - encoder[ lcio::LCTrackerCellID::side() ] = ( lHit->getPosition()[2] > 0. ? lcio::ILDDetID::fwd : lcio::ILDDetID::bwd ) ; - - layerID = encoder.lowWord() ; - + + if (code == MarlinTrk::IMarlinTrack::no_intersection) { + + encoder[lcio::LCTrackerCellID::subdet()] = CaloFaceEndcapID; + encoder[lcio::LCTrackerCellID::side()] = + (lHit->getPosition()[2] > 0. ? lcio::ILDDetID::fwd : lcio::ILDDetID::bwd); + + layerID = encoder.lowWord(); + #if use_fit_at_last_hit - code = mtrk->propagateToLayer( layerID , lHit, *tsCA, chi2, ndf, sensorID, MarlinTrk::IMarlinTrack::modeClosest ) ; -#else // get the track state at the calorimter from a propagating from the last(first) constrained fit position - code = mtrk->propagateToLayer( layerID , last_constrained_hit, *tsCA, chi2, ndf, sensorID, MarlinTrk::IMarlinTrack::modeClosest ) ; + code = mtrk->propagateToLayer(layerID, lHit, *tsCA, chi2, ndf, sensorID, MarlinTrk::IMarlinTrack::modeClosest); +#else // get the track state at the calorimter from a propagating from the last(first) constrained fit position + code = mtrk->propagateToLayer(layerID, last_constrained_hit, *tsCA, chi2, ndf, sensorID, + MarlinTrk::IMarlinTrack::modeClosest); #endif + } + if (code != MarlinTrk::IMarlinTrack::success) { + + streamlog_out(DEBUG6) << " >>>>>>>>>>> LCIOTrackConverter : could not get TrackState at calo face !!?? " + << std::endl; + } + + // fg: for curling tracks the propagated track has the wrong z0 whereas it should be 0. really + if (std::abs(tsCA->getZ0()) > std::abs(2. * M_PI / tsCA->getOmega() * tsCA->getTanLambda())) { + + streamlog_out(DEBUG2) + << " >>>>>>>>>>> createTrackStateAtCaloFace : setting z0 to 0. for track state at calorimeter : " + << toString(tsCA) << std::endl; + + tsCA->setZ0(0.); + } + + // ======= get TrackState at IP ======================== - } - if ( code !=MarlinTrk::IMarlinTrack::success ) { - - streamlog_out( DEBUG6 ) << " >>>>>>>>>>> LCIOTrackConverter : could not get TrackState at calo face !!?? " << std::endl ; - } - - //fg: for curling tracks the propagated track has the wrong z0 whereas it should be 0. really - if( std::abs( tsCA->getZ0() ) > std::abs( 2.*M_PI/tsCA->getOmega() * tsCA->getTanLambda() ) ){ - - streamlog_out( DEBUG2 ) << " >>>>>>>>>>> createTrackStateAtCaloFace : setting z0 to 0. for track state at calorimeter : " - << toString(tsCA) << std::endl ; - - tsCA->setZ0( 0. ) ; - } - - // ======= get TrackState at IP ======================== - - const dd4hep::rec::Vector3D ipv( 0.,0.,0. ); - - // fg: propagate is quite slow and might not really be needed for the TPC - - code = ( UsePropagate ? mtrk->propagate( ipv, fHit, *tsIP, chi2, ndf ) : mtrk->extrapolate( ipv, *tsIP, chi2, ndf ) ) ; - - if( code != MarlinTrk::IMarlinTrack::success ){ - - streamlog_out( DEBUG6 ) << " >>>>>>>>>>> LCIOTrackConverter : could not extrapolate TrackState to IP !!?? " << std::endl ; - } - - trk->addTrackState( tsIP ) ; - trk->addTrackState( tsFH ) ; - trk->addTrackState( tsLH ) ; - trk->addTrackState( tsCA ) ; - - double RMin = sqrt( tsFH->getReferencePoint()[0] * tsFH->getReferencePoint()[0] - + tsFH->getReferencePoint()[1] * tsFH->getReferencePoint()[1] ) ; - - trk->setRadiusOfInnermostHit( RMin ) ; - - trk->setChi2( chi2 ) ; - trk->setNdf( ndf ) ; - - } else { - - streamlog_out( WARNING ) << " >>>>>>>>>>> LCIOTrackConverter::operator() - hitsInFitEmpty ! - nHits " << nHit << std::endl ; + const dd4hep::rec::Vector3D ipv(0., 0., 0.); + + // fg: propagate is quite slow and might not really be needed for the TPC + + code = (UsePropagate ? mtrk->propagate(ipv, fHit, *tsIP, chi2, ndf) : mtrk->extrapolate(ipv, *tsIP, chi2, ndf)); + + if (code != MarlinTrk::IMarlinTrack::success) { + + streamlog_out(DEBUG6) << " >>>>>>>>>>> LCIOTrackConverter : could not extrapolate TrackState to IP !!?? " + << std::endl; } - + + trk->addTrackState(tsIP); + trk->addTrackState(tsFH); + trk->addTrackState(tsLH); + trk->addTrackState(tsCA); + + double RMin = sqrt(tsFH->getReferencePoint()[0] * tsFH->getReferencePoint()[0] + + tsFH->getReferencePoint()[1] * tsFH->getReferencePoint()[1]); + + trk->setRadiusOfInnermostHit(RMin); + + trk->setChi2(chi2); + trk->setNdf(ndf); + } else { - - // this is not an error for debug collections that just consist of track hits (no fit ) - // streamlog_out( ERROR ) << " >>>>>>>>>>> LCIOTrackConverter::operator() (CluTrack* c) : " - // << " no MarlinTrk::IMarlinTrack* found for cluster !!?? " << std::endl ; + + streamlog_out(WARNING) << " >>>>>>>>>>> LCIOTrackConverter::operator() - hitsInFitEmpty ! - nHits " << nHit + << std::endl; } - - return trk ; + } else { + + // this is not an error for debug collections that just consist of track hits (no fit ) + // streamlog_out( ERROR ) << " >>>>>>>>>>> LCIOTrackConverter::operator() (CluTrack* c) : " + // << " no MarlinTrk::IMarlinTrack* found for cluster !!?? " << std::endl ; } + return trk; +} -}//namespace +} // namespace clupatra_new