cpr( const Matrix &M, boost::function<bool(size_t)> pmask, const amg_params &prm = amg_params() ) : aprm(prm) { typedef typename backend::row_iterator<Matrix>::type row_iterator; const size_t n = backend::rows(M); // Extract system matrix subblocks: // - App, // - Asp, // - Dss = Dia(Ass), // - Aps * Dss^-1 np = boost::count_if(boost::irange<size_t>(0, n), pmask); size_t ns = n - np; build_matrix App, Aps, Asp; boost::shared_ptr<build_matrix> B = boost::make_shared<build_matrix>(); std::vector<value_type> Dss(ns); App.nrows = np; App.ncols = np; App.ptr.resize(np + 1, 0); Aps.nrows = np; Aps.ncols = ns; Aps.ptr.resize(np + 1, 0); Asp.nrows = ns; Asp.ncols = np; Asp.ptr.resize(ns + 1, 0); B->nrows = np; B->ncols = n; B->ptr.resize(np + 1, 1); B->ptr[0] = 0; std::vector<ptrdiff_t> idx(n); pix.resize(np); for(size_t i = 0, ip = 0, is = 0; i < n; ++i) { if (pmask(i)) { pix[ip] = i; idx[i] = ip++; } else { idx[i] = is++; } for(row_iterator a = backend::row_begin(M, i); a; ++a) { size_t j = a.col(); if (pmask(i)) { if (pmask(j)) { ++App.ptr[ip]; } else { ++Aps.ptr[ip]; ++B->ptr[ip]; } } else { if (j == i) { Dss[idx[i]] = a.value(); } else if (pmask(j)) { ++Asp.ptr[is]; } } } } boost::partial_sum(App.ptr, App.ptr.begin()); App.col.resize(App.ptr.back()); App.val.resize(App.ptr.back()); boost::partial_sum(Aps.ptr, Aps.ptr.begin()); Aps.col.resize(Aps.ptr.back()); Aps.val.resize(Aps.ptr.back()); boost::partial_sum(Asp.ptr, Asp.ptr.begin()); Asp.col.resize(Asp.ptr.back()); Asp.val.resize(Asp.ptr.back()); boost::partial_sum(B->ptr, B->ptr.begin()); B->col.resize(B->ptr.back()); B->val.resize(B->ptr.back()); for(size_t i = 0; i < n; ++i) { size_t ii = idx[i]; if (pmask(i)) { size_t p_head = App.ptr[ii]; size_t s_head = Aps.ptr[ii]; size_t b_head = B->ptr[ii]; B->col[b_head] = i; B->val[b_head] = 1; ++b_head; for(row_iterator a = backend::row_begin(M, i); a; ++a) { size_t j = a.col(); size_t jj = idx[j]; if (pmask(j)) { App.col[p_head] = jj; App.val[p_head] = a.value(); ++p_head; } else { value_type aps = a.value() / Dss[jj]; Aps.col[s_head] = jj; Aps.val[s_head] = aps; ++s_head; B->col[b_head] = j; B->val[b_head] = -aps; ++b_head; } } } else { size_t p_head = Asp.ptr[ii]; for(row_iterator a = backend::row_begin(M, i); a; ++a) { size_t j = a.col(); if (pmask(j)) { Asp.col[p_head] = idx[j]; Asp.val[p_head] = a.value(); ++p_head; } } } } // Now we need to compute the matrix Ap that will be used for // construction of amg preconditioner. In the original CPR method // the matrix is written as // Ap = App - Aps * Dss^-1 * Asp, // but we use the simplified form of // Ap = App - Dia(Aps * Dss*-1 * Asp) // This allows us to modify App in place. for(size_t i = 0; i < np; ++i) { typedef typename backend::row_iterator<build_matrix>::type row_iterator; // Find the diagonal of App (we need to update it): size_t pp_dia = App.ptr[i]; for(; pp_dia < App.ptr[i+1]; ++pp_dia) if (App.col[pp_dia] == i) break; assert(App.col[pp_dia] == i && "No diagonal in App?"); // Compute i-th diagonal of Aps * Asp: value_type apsp = 0; for(row_iterator a = backend::row_begin(Aps, i); a; ++a) for(row_iterator b = backend::row_begin(Asp, a.col()); b; ++b) if (b.col() == i) apsp += a.value() * b.value(); App.val[pp_dia] -= apsp; } // We are ready to create AMG and ILU preconditioners, and also // transfer the Br matrix to the backend. boost::shared_ptr<build_matrix> m = boost::make_shared<build_matrix>(M); A = Backend::copy_matrix(m, aprm.backend); Br = Backend::copy_matrix(B, aprm.backend); tmp = Backend::create_vector(n, aprm.backend); bp = Backend::create_vector(np, aprm.backend); xp = Backend::create_vector(np, aprm.backend); P = boost::make_shared<AMG>(App, aprm); iprm.damping = 1; I = boost::make_shared<ILU>(*m, iprm, aprm.backend); }
void plotSingleM2Dss3body(TString Tag="Dl"){ TString Dssfile = "AWG82/ntuples/small/semFull_RunAll.root"; TChain Dss("ntp1"); Dss.Add(Dssfile); TString Dss3file = "AWG82/ntuples/small/Dss3body_RunAll.root"; TChain Dss3("ntp1"); Dss3.Add(Dss3file); TString lund[] = {"10423","10413","425","415"}; TString name[] = {"D_{1} (D#pi#pi) l #nu (","D_{1} (D*#pi) l #nu (","D_{2} (D^{(}*^{)}#pi) l #nu ("}; if(Tag.Contains("D1p")){ lund[0] = "20413";lund[1] = "20423";lund[2] = "10411";lund[3] = "10421"; name[0] = "D_{1}' (D^{(}*^{)}#pi#pi) l #nu ("; name[1] = "D_{1}' (D*#pi) l #nu ("; name[2] = "D_{0} (D#pi) l #nu ("; } TCut modeCut[2]; TString decay[2]; TString limits[2]; modeCut[0] = "(MCType==5||MCType==6)"; modeCut[1] = "(MCType==11||MCType==12)"; decay[0] = "D** #tau #nu"; decay[1] = "D** #tau #nu"; limits[0] = "(35,-0.5,8)"; limits[1] = "(35,-0.5,8)"; TString Dnames[] = {"D^{0}","D*^{0}","D^{+}","D*^{+}"}; TH1F *mmiss[4][3]; TLatex *label = new TLatex(); label->SetNDC(kTRUE); label->SetTextSize(0.08); TCanvas c("cMvaDl","Plot for the different channels",1000,600); c.Divide(2,2); gStyle->SetOptStat(0); int a=0; for(int i=0; i<4; i++){ a = i%2; c.cd(i+1); TString cuts = "candType=="; cuts += i+1; TString cut1 = "((abs(MCD)=="; cut1+=lund[0]; cut1+="||abs(MCD)=="; cut1+=lund[1]; cut1+=")&&MCTaumode==-1)"; TString cut2 = "((abs(MCD)=="; cut2+=lund[2]; cut2+="||abs(MCD)=="; cut2+=lund[3]; cut2+=")&&MCTaumode==-1)"; TCut tot1 = cut1; tot1+=MvaAll; tot1 += cuts; tot1*="wBF"; TCut tot2 = cut2; tot2+=MvaAll; tot2 += cuts; tot2*="wBF"; TString vari = "candM2>>h"; vari+=limits[a]; if(Tag.Contains("pi0")){ vari = "mm2pi0>>h"; vari+=limits[a]; } Dss3.Draw(vari,tot1); TH1F *h = (TH1F*)gDirectory->Get("h"); mmiss[i][0] = (TH1F*)h->Clone("cand"+i); Dss.Draw(vari,tot1); TH1F *h = (TH1F*)gDirectory->Get("h"); mmiss[i][1] = (TH1F*)h->Clone("candMva"+i); Dss.Draw(vari,tot2); TH1F *h = (TH1F*)gDirectory->Get("h"); mmiss[i][2] = (TH1F*)h->Clone("candMva"+i); mmiss[i][2]->SetLineColor(4); double ngen = mmiss[i][0]->Integral(); double nsig = mmiss[i][1]->Integral(); double nold = mmiss[i][2]->Integral(); if(nsig!=0) { if(ngen!=0) mmiss[i][1]->Scale(ngen/nsig); else if(nold!=0) mmiss[i][2]->Scale(nsig/nold); } if(nold!=0 && ngen!=0) mmiss[i][2]->Scale(ngen/nold); double maxi = mmiss[i][0]->GetMaximum(); if(maxi<mmiss[i][1]->GetMaximum()) maxi = mmiss[i][1]->GetMaximum(); if(maxi<mmiss[i][2]->GetMaximum()) maxi = mmiss[i][2]->GetMaximum(); mmiss[i][0]->SetMaximum(1.15*maxi); mmiss[i][0]->GetXaxis()->SetTitleOffset(.7); mmiss[i][0]->GetXaxis()->SetTitleSize(0.059); mmiss[i][0]->GetYaxis()->SetLabelSize(0.062); mmiss[i][0]->GetXaxis()->SetLabelSize(0.056); mmiss[i][0]->GetYaxis()->SetNdivisions(5+100*2); mmiss[i][0]->GetXaxis()->SetNdivisions(6+100*2); mmiss[i][0]->SetLineWidth(2); mmiss[i][0]->SetTitle(""); mmiss[i][0]->SetXTitle("m^{2}_{miss} [GeV^{2}]"); mmiss[i][0]->Draw(); mmiss[i][1]->SetLineWidth(2); mmiss[i][1]->SetLineColor(2); mmiss[i][2]->Draw("same"); mmiss[i][0]->Draw("same"); mmiss[i][1]->Draw("same"); TString tag = Dnames[i]; if(Tag.Contains("pi0")) tag += "#pi^{0}"; tag+= " channel"; label->DrawLatex(.11,0.92,tag); TLegend *leg; if(Tag=="pi0Ds0"||Tag=="pi0D0") leg = new TLegend(0.1,.66,0.43,0.9); else leg = new TLegend(0.45,.62,0.9,0.9); leg->SetTextSize(0.068); leg->SetFillColor(0); TString legtag = name[0]; legtag+=round(ngen,0); legtag+=")"; leg->AddEntry(mmiss[i][0],legtag); legtag = name[1]; legtag+=round(nsig,0); legtag+=")"; leg->AddEntry(mmiss[i][1],legtag); legtag = name[2]; legtag+=round(nold,0); legtag+=")"; leg->AddEntry(mmiss[i][2],legtag); leg->Draw(); } c.SaveAs("babar_code/eps/Dss3bodyMmiss_"+Tag+".eps"); }