Double_t d1x[32],d2x[32],d3x[32];//xe
Double_t d1y[32],d2x[32],d3x[32];//ye
Double_t d1t[32],d2t[32],d3t[32];//xt
Int_t d1xhit, d2xhit,d3xhit;//hit
Int_t d1yhit, d2yhit,d3yhit;
Int_t    d1xs[d1xhit],d2xs[d2xhit],d3xs[d3xhit];//strip
Double_t d1xe[d1xhit],d2xe[d2xhit],d3xe[d3xhit];//energy
Int_t    d1ys[d1yhit],d2ys[d2yhit],d3ys[d3yhit];
Double_t d1ye[d1yhit],d2ye[d2yhit],d3ye[d3yhit];
//vec.h
struct dssd
{
  Int_t id;
  Double_t e;
  Doutle_t t;
};
vector<dssd> x1v,x2v,x3v;
vector<dssd> y1v,y2v,y3v;
#include <iostream> 
#include <TFile.h>
#include <TTree.h>
#include <TString.h>
#include "ana.h"  //用户代码头文件
using namespace std;
int main(int argc, char** argv)
{
   TString InputPath, OutputPath, infile, outfile;  
    InputPath = "./";
    OutputPath = "./";
    infile.Form("%scal_16C.root", InputPath.Data());
    outfile.Form("%svec_16C.root", OutputPath.Data());
    //input
    TFile *ipf = new TFile(infile);
    if(!ipf->IsOpen()) {
        cout<<"Cannot open input file: "<<infile<<endl;
        return -1;
    }
    TTree *ipt = (TTree*)ipf->Get("tree");
    //output
    TFile *opf = new TFile(outfile,"RECREATE");
    TTree *opt = new TTree("tree","vector branch");
    //
    ana *tk = new ana(ipt,opt); 
    tk->Analysis(); //等价于原Loop函数
    opt->Write();
    //
    ipf->Close();
    opf->Close();
    return 1;       
}
#ifndef ana_h
#define ana_h
#include <TRandom3.h>
#include <iostream>
#include "test.h"  //包含基类头文件
using namespace std;
struct dssd
{
  Int_t id;
  Double_t e;
  Double_t t;
};
class ana : public test //从test类中继承其成员变量和成员函数
{
 public:
  vector<dssd> x1v,x2v,x3v;
  vector<dssd> y1v,y2v,y3v;
  TTree *opt;
  TRandom3 *gr;
 ana(TTree* ipt_,TTree *opt_): test(ipt_),opt(opt_) {} 
  virtual ~ana() {};
  virtual void     Analysis();//分析函数,作用等价于原Loop函数
  virtual void     SetOutBranch();
  virtual void     ProcessDS(Double_t ee[32], vector<dssd> &vec);
};
#endif
#include "ana.h"
using namespace std;
void ana::SetOutBranch()
{
  opt->Branch("x1v",&x1v);
  opt->Branch("x2v",&x2v);
  opt->Branch("x3v",&x3v);
  opt->Branch("y1v",&y1v);
  opt->Branch("y2v",&y2v);
  opt->Branch("y3v",&y3v);
  opt->Branch("sx1e",&sx1e,"sx1e");//normal branch
  opt->Branch("sx2e",&sx2e,"sx2e");
  opt->Branch("sx3e",&sx3e,"sx3e");
  opt->Branch("sy1e",&sy1e,"sy1e");
  opt->Branch("sy2e",&sy2e,"sy2e");
  opt->Branch("sy3e",&sy3e,"sy3e");
}
void ana::ProcessDS(Double_t ee[32], vector<dssd> &vec)
{
   vec.clear();
    dssd ds;
    for(int i=0;i<32;i++) {
      if(ee[i]<1) continue;
    ds.id=i;
    ds.e=ee[i];
    vec.push_back(ds);
    }
}
void ana::Analysis()
{
  SetOutBranch();
  if (fChain == 0) return;
  Long64_t nentries = fChain->GetEntriesFast();
  Long64_t nbytes = 0, nb = 0;
  for (Long64_t jentry=0; jentry<nentries;jentry++) {
    Long64_t ientry = LoadTree(jentry);
    if (ientry < 0) break;
    nb = fChain->GetEntry(jentry);   nbytes += nb;
    ProcessDS(d1x,x1v);
    ProcessDS(d1y,y1v);
    ProcessDS(d2x,x2v);
    ProcessDS(d2y,y2v);
    ProcessDS(d3x,x3v);
    ProcessDS(d3y,y3v);
    bool b1=x1v.size()>0 || y1v.size()>0;
    bool b2=x2v.size()>0 || y2v.size()>0;
    bool b3=x3v.size()>0 || x3v.size()>0;
    if(b1||b2||b3) opt->Fill();
    if((jentry) % 1000 == 0) {
      printf("Process %.2f % %dk / %dk\r",Double_t(jentry)/nentries*100.,
         int(jentry/1000), int(nentries/1000));
      fflush(stdout);
    }
  }
}
#ifdef __CINT__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ nestedclasses;
// 添加/修改以下内容
#pragma link C++ class dssd+;//声明用到的结构体
#pragma link C++ class vector<dssd>+;//声明vector 
#endif
#############################################################################
OBJ = dssd
MainFile = main.cpp
###############################################################################
LinkFile = LinkDict.cc
###############################################################################
SourceFile := $(LinkFile) $(MainFile) $(wildcard $(shell pwd)/src/*.c $(shell pwd)/src/*.cc $(shell pwd)/src/*.C $(shell pwd)/src/*.cpp $(shell pwd)/src/*.cxx) 
IncludeFile := $(wildcard $(shell pwd)/include/*.h $(shell pwd)/include/*.hh $(shell pwd)/include/*.hpp)
###############################################################################
ROOTCFLAGS  = $(shell root-config --cflags)
ROOTLIBS    = $(shell root-config --libs)
ROOTGLIBS = $(shell root-config --glibs)
GXX = g++ 
# -Wl ,--no-as-needed
DIR_INC = -I$(ROOTSYS)/include  -I$(shell pwd)/include
CFLAGS = -Wall -O2 $(DIR_INC) -I$(ROOTSYS)/include  $(ROOTLIBS) -lSpectrum -lXMLParser  -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
###############################################################################
all:$(OBJ)
#以下在 Linkdef.h 之前添加 Linkdef.h 中包含 vector 类的文件
$(LinkFile) : include/ana.h Linkdef.h
    rootcling -f $(LinkFile) -c $^  
$(OBJ): $(SourceFile)
    $(GXX) $(CFLAGS) $(ROOTCFLAGS) $(ROOTLIBS) $(ROOTGLIBS) -o $@ $(SourceFile)
    @echo "=============================================================="
    @echo "$@ done !"
    @echo "=============================================================="
clean:
    rm -f *.o *.d $(OBJ) *Dict*
TCanvas *c1=new TCanvas;
TFile *ff=new TFile("vec_16C.root");
tree->Draw("@x1v.size()");//显示vector的大小
c1->Draw();
tree->Scan("x1v[0].id:x1v[0].e:x1v[0].t:x1v[1].id:x1v[1].e:x1v[1].t","@x1v.size()==2","",10,1)
tree->Scan("x1v.id:x1v.e:x1v.t","@x1v.size()==2","",10,1)
tree->Print();
#ifndef ana_h
#define ana_h
#include <vector>
#include <algorithm>
#include <TFile.h>
#include <TTree.h>
using namespace std;
struct dssd//aside
{
  Int_t id;
  Double_t e;
  Double_t t;
};
struct DSSD//x-y side
{
 int xid;
 int yid;
 double xe;//xe
 double ye;//xt
};
class ana 
{
 public:
  vector<dssd> *br_x1v, *br_x2v, *br_x3v;  //声明vector指针
  vector<dssd> *br_y1v, *br_y2v, *br_y3v;
  Double_t sx1e,sx2e,sx3e;//sum
  Double_t sy1e,sy2e,sy3e;    
  TTree *ipt;
  TTree *opt;
  vector<DSSD> d1,d2,d3; //output
 ana(TTree* ipt_,TTree *opt_): ipt(ipt_),opt(opt_) {} 
  virtual ~ana() {};
  virtual void     SetBranchInput();
  virtual void     GetDSSD(vector<dssd> *x, vector<dssd> *y, vector<DSSD> &xy);
  virtual void     Analysis();
  virtual void     BranchOutput();
};
#endif
#include "ana.h"
using namespace std;
void ana::SetBranchInput()
{
  br_x1v = NULL; //给指针初始化, 这一步必需。
  br_x2v = NULL;
  br_x3v = NULL;
  br_y1v = NULL;
  br_y2v = NULL;
  br_y3v = NULL;
  ipt->SetBranchAddress("x1v", &br_x1v); //将变量指向对应Branch的地址
  ipt->SetBranchAddress("x2v", &br_x2v);
  ipt->SetBranchAddress("x3v", &br_x3v);
  ipt->SetBranchAddress("y1v", &br_y1v);
  ipt->SetBranchAddress("y1v", &br_y2v);
  ipt->SetBranchAddress("y1v", &br_y3v);
  ipt->SetBranchAddress("sx1e", &sx1e);  
  ipt->SetBranchAddress("sx2e", &sx2e);  
  ipt->SetBranchAddress("sx3e", &sx3e);  
  ipt->SetBranchAddress("sy1e", &sy1e);  
  ipt->SetBranchAddress("sy2e", &sy2e);  
  ipt->SetBranchAddress("sy3e", &sy3e);  
}
void ana::BranchOutput()
{ 
  opt->Branch("d1",&d1);
  opt->Branch("d2",&d2);
  opt->Branch("d3",&d3);
}
bool SortDS(dssd *a,dssd *b)
{
  return a->e > b->e;
}
void ana::GetDSSD(vector<dssd> *x, vector<dssd> *y, vector<DSSD> &xy)
{
 int hit=min(x->size(),y->size());
 xy.clear();
 DSSD dxy;
 for(int i=0;i<hit;i++) {
     double xe=(*x)[i].e;//按照下标读取vector内的值 
     double ye=(*y)[i].e;
     int ix=(*x)[i].id;
     int iy=(*y)[i].id;     
     if(abs(xe-ye)<50) {
         dxy.xe=xe;
         dxy.ye=ye;
         dxy.xid=ix;
         dxy.yid=iy;
         xy.push_back(dxy);
     }
 }     
}
void ana::Analysis()
{
  SetBranchInput();
  BranchOutput();
  if (ipt == 0) return;
  Long64_t nentries = ipt->GetEntriesFast();
  for (Long64_t jentry=0; jentry<nentries;jentry++) {
    ipt->GetEntry(jentry);
    sort(br_x1v.begin(),br_x1v.end(),SortDS);
    sort(br_y1v.begin(),br_y1v.end(),SortDS);  
    sort(br_x2v.begin(),br_x2v.end(),SortDS);
    sort(br_y2v.begin(),br_y2v.end(),SortDS);
    sort(br_x3v.begin(),br_x3v.end(),SortDS);
    sort(br_y3v.begin(),br_y3v.end(),SortDS);
    getDSSD(br_x1v,br_y1v,d1);
    getDSSD(br_x2v,br_y2v,d2);
    getDSSD(br_x3v,br_y3v,d3);
    if(d1.size()>0 || d2.size()>0 || d3.size()>0)
        opt->Fill();
    if((jentry) % 1000 == 0) {
      printf("Process %.2f %, %dk / %dk\r",Double_t(jentry)/nentries*100.,
         int(jentry/1000), int(nentries/1000));
      fflush(stdout);
    }
  }
}
#include <iostream> 
#include <TFile.h>
#include <TTree.h>
#include <TString.h>
#include "ana.h"  //用户代码头文件
using namespace std;
int main(int argc, char** argv)
{
   TString InputPath, OutputPath, infile, outfile;  
    InputPath = "./";
    OutputPath = "./";
    infile.Form("%svec_16C.root", InputPath.Data());
    outfile.Form("%ssort_16C.root", OutputPath.Data());
    //input
    TFile *ipf = new TFile(infile);
    if(!ipf->IsOpen()) {
        cout<<"Cannot open input file: "<<infile<<endl;
        return -1;
    }
    TTree *ipt = (TTree*)ipf->Get("tree");
    //output
    TFile *opf = new TFile(outfile,"RECREATE");
    TTree *opt = new TTree("tree","vector branch");
    //
    ana *tk = new ana(ipt,opt); 
    tk->Analysis(); //等价于原Loop函数
    opt->Write();
    //
    ipf->Close();
    opf->Close();
    return 1;       
}
#ifdef __CINT__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ nestedclasses;
// 添加/修改以下内容
#pragma link C++ class dssd+;//声明用到的结构体
#pragma link C++ class vector<dssd>+;//声明vector 
#pragma link C++ class DSSD+;//声明用到的结构体
#pragma link C++ class vector<DSSD>+;//声明vector
#endif
vector::size(); //返回 vector 大小
 vector::clear();//清空 vector
 vector::push_back(value);//在vector内填入元素
 vector::begin();//返回vector的首地址
 vector::end();//返回vector的尾地址
 vector::assign(v1.begin(), v2.end());//将v1拷贝到vector中
 vector::erase(it);//删除it位置变量,返回下一个元素的指针
bool SortDS(dssd &a,dssd &b)
{
  return a.e > b.e;
}
sort(x1v.begin(),x1v.end(),SortDS);
bool Equal(dssd &a, dssd &b)
{
  return Long64_t(a.e- b.e)==0 && a.id==b.id;
}
void Unique(vector<dssd> &a) 
{
  a.erase(unique(a.begin(),a.end(),Equal),a.end());
}
//remove identical events, probably caused by bugs in Digital modules
Unique(xvec);
void tCut(vector<dssd> &a, vector<dssd> &b, double t1,double t2)
{
   if(b.size()>0) {   
     for(auto it=a.begin();it!=a.end() ; ) {
       int dt=Long64_t(it->ts-b[0].t);
       if(dt<t1 || dt>t2) 
         it=a.erase(it);
       else
         ++it;
     }
   }
}
tCut(x1v,x1v,-20,20);