#include "CbmTrdModuleRecT.h" #include "CbmTrdDigi.h" #include "CbmTrdCluster.h" #include "CbmTrdHit.h" #include "CbmTrdParModDigi.h" #include "CbmTrdFASP.h" #include #include #include #include #include #include #include using std::cout; using std::endl; using std::vector; Double_t CbmTrdModuleRecT::fgDT[] = {4.181e-6, 1586, 24}; TGraphErrors* CbmTrdModuleRecT::fgEdep = NULL; TGraphErrors* CbmTrdModuleRecT::fgT = NULL; TF1* CbmTrdModuleRecT::fgPRF = NULL; //_______________________________________________________________________________ CbmTrdModuleRecT::CbmTrdModuleRecT() : CbmTrdModuleRec() ,fConfigMap(0) ,fT0(0) ,fBuffer() ,vs() ,vse() ,vt() ,vx() ,vxe() { } //_______________________________________________________________________________ CbmTrdModuleRecT::CbmTrdModuleRecT(Int_t mod, Int_t ly, Int_t rot) : CbmTrdModuleRec(mod, ly, rot) ,fConfigMap(0) ,fT0(0) ,fBuffer() ,vs() ,vse() ,vt() ,vx() ,vxe() { //printf("AddModuleT @ %d\n", mod); Config(1,0); SetNameTitle(Form("TrdRecT%d", mod), "Reconstructor for triangular read-out."); } //_______________________________________________________________________________ CbmTrdModuleRecT::~CbmTrdModuleRecT() { } //_______________________________________________________________________________ Bool_t CbmTrdModuleRecT::AddDigi(const CbmTrdDigi *d, Int_t id) { /* Add digi to cluster fragments. At first clusters are ordered on pad rows and time. * No channel ordering is assumed. The time condition for a digi to enter a cluster * chunk is to have abs(dt)<5 wrt cluster t0 */ if(CWRITE()) cout<<"add @"<ToString(); Int_t ch = d->GetAddressChannel(), col, row = GetPadRowCol(ch, col), dtime; Double_t t, r = d->GetCharge(t, dtime); Int_t tm = d->GetTimeDAQ()-fT0, terminator(0); if(dtime<0) tm+=dtime; // correct for the difference between tilt and rect if(r<1) terminator=1; else if(t<1) terminator=-1; if(CWRITE()) printf("row[%2d] col[%2d] tm[%2d] terminator[%d]\n", row, col, tm, terminator); CbmTrdCluster *cl(NULL); // get the link to saved clusters std::map>::iterator it=fBuffer.find(row); // check for saved if(it!=fBuffer.end()){ Bool_t kINSERT(kFALSE); std::list::iterator itc=fBuffer[row].begin(); for(; itc!=fBuffer[row].end(); itc++){ if(CWRITE()) cout<<(*itc)->ToString(); UShort_t tc = (*itc)->GetStartTime(); Int_t dt = tc - tm; if(dt<-5) continue; else if(dt<5) { if(CWRITE()) printf("match time dt=%d\n", dt); if((*itc)->IsChannelInRange(ch)==0){ if(!(*itc)->AddDigi(id, ch, terminator, dt)) break; kINSERT=kTRUE; if(CWRITE()) cout<<" => Cl (Ad) "<<(*itc)->ToString(); break; } } else { if(CWRITE()) printf("break for time dt=%d\n", dt); break; } } if(!kINSERT){ if(itc != fBuffer[row].end() && itc != fBuffer[row].begin()){ itc--; fBuffer[row].insert(itc, cl = new CbmTrdCluster(fModAddress, id, ch, row, tm)); if(CWRITE()) cout<<" => Cl (I) "<ToString(); } else { fBuffer[row].push_back(cl = new CbmTrdCluster(fModAddress, id, ch, row, tm)); if(CWRITE()) cout<<" => Cl (Pb) "<ToString(); } cl->SetTrianglePads(); if(terminator<0) cl->SetProfileStart(); else if(terminator>0) cl->SetProfileStop(); } } else { fBuffer[row].push_back(cl = new CbmTrdCluster(fModAddress, id, ch, row, tm)); cl->SetTrianglePads(); if(terminator<0) cl->SetProfileStart(); else if(terminator>0) cl->SetProfileStop(); if(CWRITE()) cout<<" => Cl (Nw) "<ToString(); } return kTRUE; } //_______________________________________________________________________________ Int_t CbmTrdModuleRecT::GetOverThreshold() const { Int_t nch(0); for(std::map>::const_iterator ir=fBuffer.cbegin(); ir!=fBuffer.cend(); ir++){ for(std::list::const_iterator itc=(*ir).second.cbegin(); itc!=(*ir).second.cend(); itc++) nch+=(*itc)->GetNCols(); } return nch; } //_______________________________________________________________________________ Int_t CbmTrdModuleRecT::FindClusters() { CbmTrdCluster *cl(NULL); // get the link to saved clusters Int_t ncl(0); std::list::iterator itc0, itc1; for(std::map>::iterator ir=fBuffer.begin(); ir!=fBuffer.end(); ir++){ itc0=(*ir).second.begin(); while((*ir).second.size()>1 && itc0!=(*ir).second.end()){ // try merge clusters itc1=itc0; itc1++; Bool_t kMERGE=kFALSE; while(itc1!=(*ir).second.end()){ if(CWRITE()) cout<<" base cl[0] : "<<(*itc0)->ToString() <<" + cl[1] : "<<(*itc1)->ToString(); if((*itc0)->Merge((*itc1))){ if(CWRITE()) cout<<" SUM : "<<(*itc0)->ToString(); kMERGE = kTRUE; delete (*itc1); itc1=(*ir).second.erase(itc1); if(itc1==(*ir).second.end()) break; } else itc1++; } if(!kMERGE) itc0++; } for(itc0=(*ir).second.begin(); itc0!=(*ir).second.end(); itc0++){ cl = (*itc0); cl = new((*fClusters)[ncl++]) CbmTrdCluster(*cl); cl->SetTrianglePads(); delete (*itc0); } } fBuffer.clear(); //printf("fClusters[%p] nCl[%d]\n", (void*)fClusters, fClusters->GetEntriesFast()); //LOG(info) << GetName() << "::FindClusters : " << ncl; return ncl; } //_______________________________________________________________________________ Bool_t CbmTrdModuleRecT::MakeHits() { return kTRUE; } //_______________________________________________________________________________ Bool_t CbmTrdModuleRecT::Finalize() { /* Steering routine for classifying hits and apply further analysis * -> hit deconvolution (see Deconvolute) * -> hit merging for row-cross (see RowCross) */ // Int_t nhits=fHits->GetEntriesFast(); // //if(CWRITE()) // LOG(info) << "\n"<ToString(); // cout<<"-> "<ToString(); // } // } return kTRUE; } #include #include #define NANODE 9 //_______________________________________________________________________________ CbmTrdHit* CbmTrdModuleRecT::MakeHit(Int_t ic, const CbmTrdCluster *cl, std::vector *digis) { if(!fgEdep){ // first use initialization of PRF helppers LOG(info) << GetName()<<"::MakeHit: Init static helpers. "; fgEdep = new TGraphErrors; fgEdep->SetLineColor(kBlue);fgEdep->SetLineWidth(2); fgT = new TGraphErrors; fgT->SetLineColor(kBlue);fgT->SetLineWidth(2); fgPRF=new TF1("prf", "[0]*exp(-0.5*((x-[1])/[2])**2)", -10, 10); fgPRF->SetLineColor(kRed); fgPRF->SetParNames("E", "x", "prf"); } TH1 *hf(NULL); TCanvas *cvs(NULL); if(CDRAW()){ cvs = new TCanvas("c", "TRD Anode Hypothesis",10,600,1000,500); cvs->Divide(2,1,1.e-5,1.e-5); TVirtualPad *vp = cvs->cd(1); vp->SetLeftMargin(0.06904908); vp->SetRightMargin(0.009969325); vp->SetTopMargin(0.01402806); vp = cvs->cd(2); vp->SetLeftMargin(0.06904908); vp->SetRightMargin(0.009969325); vp->SetTopMargin(0.01402806); hf = new TH1I("hf", ";x [pw];s [ADC chs]", 100,-3, 3); hf->GetYaxis()->SetRangeUser(-50, 4500); hf->Draw("p"); } if(CWRITE()) cout<ToString(); // check cluster integrity and do digi merging if needed vector vmask(digis->size(), 0); // masks in case of merged Digis vector vdgM; if(cl->GetNCols() != digis->size() && !MergeDigis(digis, &vdgM, &vmask)){ cout<ToString(); for(vector::iterator i=digis->begin(); i!= digis->end(); i++) cout<<(*i)->ToString(); return NULL; } // Read in all digis information() ULong64_t t0=fT0+cl->GetStartTime(); // absolute hit time (prompt signal) Int_t n0(0), ovf(0), cM; if(!(n0 = LoadDigis(digis, &vdgM, &vmask, t0, cM))){ cout<ToString(); for(vector::iterator i=digis->begin(); i!= digis->end(); i++) cout<<(*i)->ToString(); return NULL; } if(n0<0){ovf=1; n0*=-1;} // analyse digis topology; no of signal types, maximum, etc Bool_t tM(kTRUE); // maximum type tilt=1; rect=0 Int_t nL(0); // signal index for the max signal Int_t col, row= GetPadRowCol(cl->GetStartCh(), col); Double_t max(0.), // maximum signal LS(0.), // left side sum of signals S(0.); // sum of signals Int_t nr(0), nt(0); for(Int_t is(1); is<=n0; is++){ if(vxe[is]>0) { // select tilted coupling nt++; S+=vs[is]; if(vs[is]>max){ max=vs[is]; tM=kTRUE; nL=is; LS+=vs[is]; } } else { // select rectangular coupling nr++; S+=vs[is]; if(vs[is]>max){ max=vs[is]; tM=kFALSE; nL=is; LS+=vs[is]; } } } col+=cM; S-=LS; LS-=max; // evaluate asymmetry Int_t lr(0), // max signal left-right asymmetry wrt central pad tr(0), // left-right innequality for symmetric clusters nR(n0+1-nL); // no of signals to the right of maximum if(nLnR) lr=-1; if(!lr&&(n0%2)) tr=(LSHasOpenStart() && cl->HasOpenStop()) { dx = cM?-1.:0.; dy = -0.5; } // RT else { dx = 0.; dy = 0.5; } // TR break; case 3: if(tM&&lr) {dx = cM?-1.:0.; dy = GetYoffset(n0); } // TRT asymm else if(!tM&&!lr) {dx = 0.; dy = GetYoffset(n0);} // TRT symm else if(tM&&!lr) {dx = GetXoffset(n0); dy = 0.;} // RTR symm else if(!tM&&lr) {dx = GetXoffset(n0); dy = cM?0.5:-0.5;} // RTR asymm break; default: dx = GetXoffset(n0); dy = GetYoffset(n0); break; } if(dx<-0.5 && cM>0) { // shift graph representation to fit dx[pw] in [-0.5, 0.5] dx += 1.; col-=1; for(UInt_t idx(0); idx0.5) { // dirty fix for compound clusters TODO Int_t ishift = Int_t(dx-0.5)+1; dx -= ishift; col+=ishift; for(UInt_t idx(0); idxGetPadSizeX(0); dy*=fDigiPar->GetPadSizeY(0); // apply systematic correction for x (MC derived) Int_t typ=0; // [0] center hit type // [1] side hit type if((n0==5&&((tM&&!lr)||(!tM&&lr))) || // TRTRT symm/asymm n0==4 || (n0==3&&((tM&&!lr)||(!tM&&lr!=0)))) typ=1; // RTR symm/asymm Double_t xcorr(0.); Int_t nbins((NBINSCORRX-1)>>1), ii = nbins+TMath::Nint(dx/fgCorrXdx), i0, i1; if(ii<0||ii>=NBINSCORRX) LOG(warn)<0.5*fDigiPar->GetPadSizeX(0)) dx = 0.5*fDigiPar->GetPadSizeX(0); else if(dx<-0.5*fDigiPar->GetPadSizeX(0)) dx = -0.5*fDigiPar->GetPadSizeX(0); if(dy>0.5 * fDigiPar->GetPadSizeY(0)) { // //printf("BEFORE dy[%+6.4f] dx[%+6.4f] {n[%d] max[%c] lr[%+d]}\n", dy, dx, n0, tM?'T':'R', lr); dy-=fDigiPar->GetPadSizeY(0); } if(dy<-0.5 * fDigiPar->GetPadSizeY(0)) { // //printf("(BEFORE) dy[%+6.4f] dx[%+6.4f] {n[%d] max[%c] lr[%+d]}\n", dy, dx, n0, tM?'T':'R', lr); dy+=fDigiPar->GetPadSizeY(0); } // process y offset // apply systematic correction for y (MC derived) Float_t fdy(1.), yoff(0.); switch(n0){ case 3: fdy = fgCorrYval[0][0]; yoff = fgCorrYval[0][1]; if(tM&&!lr) dy-=tr*0.5*fDigiPar->GetPadSizeY(0); else if(lr) dy-= 0.5*fDigiPar->GetPadSizeY(0);; break; case 4: fdy = fgCorrYval[1][0]; yoff = fgCorrYval[1][1]; if((!tM&&lr==1)||(tM&&lr==-1)) yoff*=-1; break; case 5: case 7: case 9: case 11: fdy = fgCorrYval[2][0]; yoff = fgCorrYval[2][1]; break; case 6: case 8: case 10: fdy = fgCorrYval[3][0]; yoff = fgCorrYval[3][1]; if((!tM&&lr==1)||(tM&&lr==-1)) yoff*=-1; break; } dy*=fdy; dy+=yoff; if(dy>0.5 * fDigiPar->GetPadSizeY(0)) dy = 0.5 * fDigiPar->GetPadSizeY(0); else if(dy<-0.5 * fDigiPar->GetPadSizeY(0)) dy = -0.5 * fDigiPar->GetPadSizeY(0); // get anode wire offset Int_t ia(0); Float_t ya; // anode position in local pad coordinates for(; ia<=NANODE; ia++) { ya=-1.35+ia*0.3; if(dy > ya + 0.15) continue; break; } // Error parametrization X : parabolic model on cl size Double_t parX[] = {0.713724, -0.318667, 0.0366036}; Int_t nex = TMath::Min(n0, 7); edx = parX[0] + parX[1] * nex + parX[2] * nex * nex; Double_t parY[] = {0.0886413, 0., 0.0435141}; edy = parY[0] + parY[2] * dy * dy; if(CWRITE()) { printf("row[%2d] col[%2d] sz[%d%c] M[%d%c] dx[mm]=%6.3f dy[mm]=%6.3f t0[clk]=%llu OVF[%c]\n", row, col, n0, (lr?(lr<0?'L':'R'):'C'), cM, (tM?'T':'R'), 10*dx, 10*dy, t0, (ovf?'y':'n')); for(UInt_t idx(0); idx0){ fgEdep->SetPoint(idx, vx[idx]+dy/fDigiPar->GetPadSizeY(0), vs[idx]); fgEdep->SetPointError(idx, vxe[idx], vse[idx]); } else { fgEdep->SetPoint(idx, vx[idx], vs[idx]); fgEdep->SetPointError(idx, vxe[idx], vse[idx]); } } Double_t xc=vx[n0+2]; for(Int_t ip(vs.size()); ipGetN(); ip++){ //fgEdep->RemovePoint(ip); xc+=0.5; fgEdep->SetPoint(ip, xc, 0); fgEdep->SetPointError(ip, 0., 300); } if(CWRITE()) fgEdep->Print(); Double_t e(0.), chi(100), xlo(*vx.begin()), xhi(*vx.rbegin()); fgPRF->SetParameter(0, max); fgPRF->FixParameter(1, dx/fDigiPar->GetPadSizeX(0)); fgPRF->SetParameter(2, 0.65); fgPRF->SetParLimits(2, 0.45, 10.5); fgEdep->Fit(fgPRF, "QBN", "goff", xlo-0.5, xhi+0.5); if(!fgPRF->GetNDF()) return NULL; chi = fgPRF->GetChisquare()/fgPRF->GetNDF(); e = fgPRF->Integral(xlo-0.5, xhi+0.5); // apply MC correction Float_t gain0 = 210.21387; //(XeCO2 @ 1900V) // Float_t grel[3] = {1., 0.98547803, 0.93164071}, // goff[3][3] = { // {0.05714, -0.09, -0.09}, // {0., -0.14742, -0.14742}, // {0., -0.29, -0.393} // }; // Int_t ian=0; // if(TMath::Abs(dy)<=0.3) ian=0; // else if(TMath::Abs(dy)<=0.6) ian=1; // else if(TMath::Abs(dy)<=0.9) ian=2; // Int_t isize=0; // if(n0<=3) isize=0; // else if(n0<=4) isize=1; // else isize=2; Float_t gain = gain0;//*grel[ian]; e/=gain; // apply effective gain //e+=goff[ian][isize]; // apply missing energy offset TVector3 local_pad, local_pad_err; Int_t srow, sector= fDigiPar->GetSectorRow(row, srow); fDigiPar->GetPadPosition(sector, col, srow, local_pad, local_pad_err); //printf("r[%2d] c[%2d] max[%d] lr[%d] n0[%d] cM[%d] nM[%d] dx[%7.4f] dy[%7.4f] loc[%6.2f %6.2f %6.2f] err[%6.2f %6.2f %6.2f] e[%f] chi[%f]\n", row, col, mtyp, lr, n0, cM, nM, dx, dy, local_pad[0], local_pad[1], local_pad[2], local_pad_err[0], local_pad_err[1], local_pad_err[2], e, chi); Double_t local[3] = { local_pad[0]+dx, local_pad[1]+dy, local_pad[2]}, global[3], globalErr[3] = {edx, edy, 0.}; LocalToMaster(local, global); // process time profile for(Int_t idx(1); idx<=n0; idx++){ Double_t dtFEE = fgDT[0]*(vs[idx]-fgDT[1])*(vs[idx]-fgDT[1])/CbmTrdDigi::Clk(CbmTrdDigi::kFASP); if(vxe[idx]>0) vx[idx] += dy/fDigiPar->GetPadSizeY(0); fgT->SetPoint(idx-1, vx[idx], vt[idx] - dtFEE); } xc=vx[n0+2]; for(Int_t ip(n0); ipGetN(); ip++){ fgT->SetPoint(ip, xc, 0); xc+=0.5;} Double_t time(-21.), edt(26.33), // should be parametrized as function of da TODO tdrift(100); // should depend on Ua if(n0>1 && (fgT->Fit("pol1", "QC", "goff") == 0)) { TF1 *f = fgT->GetFunction("pol1"); time = f->GetParameter(0)-fgDT[2]; if(TMath::IsNaN(time)) time = -21; //dtime += TMath::Abs(f->GetParameter(1)*(vx[n0+1] - vx[1])); } if(CDRAW()){ Double_t rangex(vx[0]-0.25), rangeX(vx[n0+2]+0.25); cvs->cd(1); hf->Draw("p"); hf->GetXaxis()->SetRangeUser(rangex, rangeX); hf->SetTitle(Form("%d[%d] row[%d] col[%2d] an[%+d] m[%+4.2f] s[%4.2f] E[%7.2f] chi2[%7.2f]", ic, Int_t(vs.size()), row, col, ia, fgPRF->GetParameter(1), fgPRF->GetParameter(2), e, chi)); hf->GetXaxis()->SetRangeUser(rangex, rangeX); hf->GetYaxis()->SetRangeUser(-100., 4500); fgEdep->Draw("pl"); fgPRF->Draw("same"); cvs->cd(2); hf = (TH1*)hf->DrawClone("p"); hf->GetXaxis()->SetRangeUser(rangex, rangeX); hf->GetYaxis()->SetRangeUser(-10, 20); //hf->SetTitle(Form("%d row[%d] col[%2d] an[%+d] m[%+4.2f] s[%4.2f] E[%7.2f] chi2[%7.2f]", ic, row, col, ia, fgPRF->GetParameter(1), fgPRF->GetParameter(2), fgPRF->Integral(xlo, xhi), fgPRF->GetChisquare()/fgPRF->GetNDF())); // hf->GetXaxis()->SetRangeUser(xlo-0.25, xhi+0.25); // //hf->GetYaxis()->SetRangeUser(0., 4500); fgT->Draw("pl"); cvs->Modified(); cvs->Update(); cvs->SaveAs(Form("cl_%02d_A%d.gif", ic, ia)); } Int_t nofHits = fHits->GetEntriesFast(); CbmTrdHit *hit = new ((*fHits)[nofHits]) CbmTrdHit(fModAddress, global, globalErr, 0., // sxy chi, ic, e, // energy CbmTrdDigi::Clk(CbmTrdDigi::kFASP)*(t0+time)- tdrift+30.29, edt); hit->SetClassType(); hit->SetMaxType(tM); if(ovf) hit->SetOverFlow(); if(CWRITE()) cout<ToString(); return hit; } //_______________________________________________________________________________ Double_t CbmTrdModuleRecT::GetXoffset(Int_t n0) const { Double_t dx(0.), R(0.); for(Int_t ir(1); ir<=n0; ir++){ if(vxe[ir]>0) continue; // select rectangular coupling R +=vs[ir]; dx+=vs[ir]*vx[ir]; } if(TMath::Abs(R)>0) return dx/R; LOG(warn) << GetName() << "::GetDx : Unexpected null sum."; return 0. ; } //_______________________________________________________________________________ Double_t CbmTrdModuleRecT::GetYoffset(Int_t n0) const { Double_t dy(0.), T(0.); for(Int_t it(1); it<=n0; it++) { if(vxe[it]>0){ // select tilted coupling T +=vs[it]; dy+=vs[it]*vx[it]; } } if(TMath::Abs(T)>0) return dy/T; LOG(warn) << GetName() << "::GetDy : Unexpected null sum."; return 0.; } //_______________________________________________________________________________ Int_t CbmTrdModuleRecT::LoadDigis(vector *digis, vector *vdgM, vector *vmask, ULong64_t &t0, Int_t &cM) { /* Load digis information in working vectors. * The digis as provided by the digitizer are replaced by the merged one * according to the vmask map. Digis are represented in the normal coordinate system of * (pad width [pw], DAQ time [clk], signal [ADC chs]) with rectangular signals at integer * positions. */ vs.clear();vse.clear(); vx.clear();vxe.clear(); vt.clear(); cM=0; // relative position of maximum signal Int_t n0(0), // number of measured signals ovf(1), // over-flow flag for at least one of the digis dt; Char_t ddt, // signal time offset wrt prompt dt0(0); // cluster time offset wrt arbitrary t0 Double_t r, re(100.), // rect signal t, te(100.), // tilt signal err, // final error parametrization for signal xc(-0.5), // running signal-pad position max(0.); // max signal Int_t j(0), col0(-1), col1(0); const CbmTrdDigi *dg(NULL); vector::iterator idgM=vdgM->begin(); for(vector::iterator i=digis->begin(); i!= digis->end(); i++, j++){ dg = (*i); if((*vmask)[j]) {dg = (*idgM); idgM++;} if(CWRITE()) cout<ToString(); r = dg->GetCharge(t, dt); if(t0==0) t0 = dg->GetTimeDAQ(); // set arbitrary t0 to avoid double digis loop if(col0<0) GetPadRowCol(dg->GetAddressChannel(), col0); // initialilze ddt=dg->GetTimeDAQ()-t0; if(ddt < dt0) dt0 = ddt; // check column wise organization GetPadRowCol(dg->GetAddressChannel(), col1); if(col0 + j != col1) { LOG(error) << GetName() << "::LoadDigis : digis in cluster not in increasing order !"; return 0; } // process tilt signal if(t>0) { err = te; if(t>4094){ovf=-1; err=150.;} t-=CbmTrdFASP::GetBaselineCorr(); n0++; if(t>max){ max=t; cM=j;} } else err=300.; vt.push_back(ddt); vs.push_back(t); vse.push_back(err); vx.push_back(xc); vxe.push_back(0.035); xc+=0.5; // process rect signal ddt+=dt; if(ddt < dt0) dt0 = ddt; if(r>0){ err = re; if(r>4094){ovf=-1; err=150.;} r-=CbmTrdFASP::GetBaselineCorr(); n0++; if(r>max){ max=r; cM=j;} } else err=300.; vt.push_back(ddt); vs.push_back(r); vse.push_back(err); vx.push_back(xc); vxe.push_back(0.); xc+=0.5; } // remove merged digis if they were created if(idgM != vdgM->end()) LOG(warn) << GetName() << "::LoadDigis : not all merged digis have been consumed !"; for(idgM=vdgM->begin(); idgM!=vdgM->end(); idgM++) delete (*idgM); // add front and back anchor points if needed if(TMath::Abs(vs[0])>1.e-3) { xc = vx[0]; ddt=vt[0]; vs.insert(vs.begin(), 0); vse.insert(vse.begin(), 300); vt.insert(vt.begin(), ddt); vx.insert(vx.begin(), xc-0.5); vxe.insert(vxe.begin(), 0); } Int_t n(vs.size()-1); if(TMath::Abs(vs[n])>1.e-3) { xc = vx[n]+0.5; ddt=vt[n]; vs.push_back(0); vse.push_back(300); vt.push_back(ddt); vx.push_back(xc); vxe.push_back(0.035); } // recenter time and space profile t0+=dt0; for(UInt_t idx(0); idx *digis, vector *vdgM, vector *vmask) { /* Merge digis in the cluster if their topology within it allows it although cuts in the * digi merger procedure (CbmTrdFASP::WriteDigi()) were not fulfilled. * Normally this are boundary signals with large time delays wrt neighbors */ CbmTrdDigi *dgM(NULL); if(digis->size()<2){ // sanity check ... just in case LOG(warn) << GetName() << "::MergeDigis : Bad digi config for cluster :"; return kFALSE; } Double_t r,t; Int_t colR, colT, dt, contor(0); Bool_t kFOUND(0); for(vector::iterator idig = digis->begin(), jdig=idig+1; jdig!=digis->end(); idig++, jdig++, contor++){ const CbmTrdDigi *dgT((*idig)); // tilt signal digi const CbmTrdDigi *dgR((*jdig)); // rect signal digi GetPadRowCol(dgR->GetAddressChannel(), colR); GetPadRowCol(dgT->GetAddressChannel(), colT); if(colR!=colT) continue; dgM = new CbmTrdDigi(*dgT); r = dgR->GetCharge(t,dt); dgT->GetCharge(t,dt); dt = dgR->GetTimeDAQ() - dgT->GetTimeDAQ(); dgM->SetCharge(t,r,dt); Int_t rtrg(dgR->GetTriggerType()&2), ttrg(dgT->GetTriggerType()&1); dgM->SetTriggerType(rtrg|ttrg); //merge the triggers if(CWRITE()){ cout<<"MERGE"<ToString(); cout<ToString(); cout<<"TO"<ToString(); cout<<"..."<push_back(dgM); (*vmask)[contor]=1; jdig = digis->erase(jdig); if(jdig==digis->end()) break; } if(!kFOUND){ LOG(warn) << GetName() << "::MergeDigis : Digi to pads matching failed for cluster :"; return kFALSE; } return kTRUE; } Float_t CbmTrdModuleRecT::fgCorrXdx=0.005; Float_t CbmTrdModuleRecT::fgCorrXval[2][NBINSCORRX] = {{ 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.144, -0.091, -0.134, -0.185, -0.120, -0.115, -0.125, -0.125, -0.124, -0.124, -0.122, -0.120, -0.119, -0.116, -0.114, -0.113, -0.111, -0.109, -0.107, -0.105, -0.102, -0.100, -0.098, -0.097, -0.093, -0.091, -0.089, -0.087, -0.084, -0.082, -0.079, -0.077, -0.074, -0.072, -0.068, -0.065, -0.062, -0.059, -0.056, -0.053, -0.049, -0.046, -0.043, -0.039, -0.036, -0.032, -0.029, -0.025, -0.022, -0.018, -0.015, -0.011, -0.007, -0.003, 0.000, 0.003, 0.007, 0.011, 0.014, 0.018, 0.022, 0.025, 0.029, 0.032, 0.036, 0.039, 0.043, 0.046, 0.049, 0.053, 0.056, 0.059, 0.062, 0.065, 0.068, 0.071, 0.074, 0.077, 0.080, 0.082, 0.084, 0.087, 0.090, 0.091, 0.094, 0.096, 0.098, 0.100, 0.103, 0.104, 0.107, 0.108, 0.110, 0.113, 0.115, 0.116, 0.120, 0.121, 0.121, 0.123, 0.125, 0.124, 0.127, 0.140, 0.119, 0.114, 0.028, 0.049, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 }, { 0.003, 0.013, 0.026, 0.039, 0.052, 0.065, 0.078, 0.091, 0.104, 0.118, 0.132, 0.145, 0.160, 0.174, 0.189, 0.203, 0.219, 0.234, 0.250, 0.267, 0.283, 0.301, 0.319, 0.338, 0.357, 0.375, 0.398, 0.419, 0.440, 0.464, 0.491, 0.514, 0.541, 0.569, 0.598, 0.623, 0.660, 0.696, 0.728, 0.763, 0.804, 0.847, 0.888, 0.930, 0.988, 1.015, 1.076, 1.128, 1.167, 1.228, 1.297, 1.374, 1.443, 1.511, 1.564, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -1.992, -1.884, -1.765, -1.703, -1.609, -1.572, -1.493, -1.426, -1.356, -1.309, -1.243, -1.202, -1.109, -1.069, -1.026, -0.970, -0.933, -0.881, -0.844, -0.803, -0.767, -0.721, -0.691, -0.659, -0.629, -0.596, -0.569, -0.541, -0.514, -0.490, -0.466, -0.441, -0.419, -0.397, -0.377, -0.357, -0.337, -0.319, -0.301, -0.283, -0.267, -0.250, -0.234, -0.218, -0.203, -0.189, -0.174, -0.160, -0.145, -0.131, -0.119, -0.104, -0.091, -0.078, -0.064, -0.052, -0.039, -0.026, -0.013, -0.002} }; Float_t CbmTrdModuleRecT::fgCorrYval[NBINSCORRY][2] = { {2.421729, 0.}, {1.537359, 0.483472}, {1.1752, 0.}, {1.154183,-0.090229} }; ClassImp(CbmTrdModuleRecT)