diff --git a/core/detectors/trd/CbmTrdFASP.cxx b/core/detectors/trd/CbmTrdFASP.cxx index fcd255666bdbb3fce900ebe56451b804a8f838d6..99f4b5c6f8acbbea2c75a16a206ff62daf9e2199 100644 --- a/core/detectors/trd/CbmTrdFASP.cxx +++ b/core/detectors/trd/CbmTrdFASP.cxx @@ -30,12 +30,14 @@ using namespace std; -Bool_t CbmTrdFASP::fgNeighbour = kTRUE; // by default enable neighbour trigger +// Bool_t CbmTrdFASP::fgNeighbour = kTRUE; // by default enable neighbour trigger +Bool_t CbmTrdFASP::fgNeighbour = kFALSE; // AB : match HW on mCBM22 // Float_t CbmTrdFASP::fgShaperThr = 0.2; // [V] // Float_t CbmTrdFASP::fgNeighbourThr = 0.07; // [V] -Float_t CbmTrdFASP::fgShaperThr = 0.05; // [V] -Float_t CbmTrdFASP::fgNeighbourThr = 0.04; // [V] -Float_t CbmTrdFASP::fgBaseline = 0.25; // [V] +//Float_t CbmTrdFASP::fgShaperThr = 0.05; // [V] +Float_t CbmTrdFASP::fgShaperThr = 0.08; //[V] AB : match HW on mCBM22 +Float_t CbmTrdFASP::fgNeighbourThr = 0.04; //[V] +Float_t CbmTrdFASP::fgBaseline = 0.25; //[V] AB : match HW on mCBM22 Float_t CbmTrdFASP::fgOutGain = 2.025; // [V/ 4095 ADC chs] const Int_t CbmTrdFASP::fgkNclkFT = 14; // [clk] Int_t CbmTrdFASP::fgNclkLG = 31; // [clk] @@ -43,27 +45,6 @@ const Int_t CbmTrdFASP::fgkBufferKeep = 400; // [5*ns] //___________________________________________________________________ CbmTrdFASP::CbmTrdFASP(UInt_t uslice) : TObject() - , fStartTime(0) - , fProcTime(0) - , fCol(-1) - , fRow(-1) - , fAsicId(-1) - , fNraw(0) - , fDigi(nullptr) - , fHitThPrev(uslice) - , fShaper(uslice) - , fShaperNext(uslice) - , fDigiProc() - , fPar(nullptr) - , fTimeLG(-1) - , fTimeFT(-1) - , fTimeDY(-1) - , fFT(0) - , fGraphId(0) - , fOut() - , fGraphMap() - , fGthr(nullptr) - , fMonitor(nullptr) { /** Build the FASP simulator for a microslice of 5*uslice [ns] */ @@ -104,106 +85,134 @@ void CbmTrdFASP::Clear(Option_t* opt) { // printf("CbmTrdFASP::Clear : Nphys[0] = %d\n", fNphys[0]); - if (fNphys[0]) ProcessShaper('R'); // process last rect channel without interference from current tilt + if (fNphys[1]) ProcessShaper('R'); // process last rect channel without interference from current tilt fHitThPrev.assign(fHitThPrev.size(), 0); //*sizeof(Bool_t)); WriteDigi(); // finalize fDigi list if (strcmp(opt, "draw") == 0) Draw(); } //___________________________________________________________________ -void CbmTrdFASP::Draw(Option_t* /*opt*/) +void CbmTrdFASP::InitChannel(int id, const CbmTrdParFaspChannel* par, int asicId, int chId) { - // printf("CbmTrdFASP::Draw : row[%2d] col[%2d] asic[%2d]\n", fRow, fCol, fAsicId); - if (!DRAW) return; - if (!fGraphMap.size()) return; + if (id < 0 || id > 1) { + LOG(error) << "FASP simulator supports only two channels at time. Request for channel " << id << " was skipped."; + return; + } + fPar[id] = par; + fAsicId[id] = asicId; + if (asicId < 0) { + fChId[id] = -1; + return; + } - Int_t nasic(0), last(-1), nlast(0); - vector<pair<Int_t, Int_t>>::iterator ig = fGraphMap.begin(); - while (ig != fGraphMap.end()) { - if (last < 0 || ig->first != last) { - nasic++; - last = ig->first; - nlast = 0; + if (chId < 0 || chId >= NFASPCH) { + LOG(warn) << "FASP ASIC implements " << NFASPCH << " channels. Channel identifier " << chId << " not considered."; + fChId[id] = -1; + return; + } + else + fChId[id] = chId; + + if (DRAW) { + if (fGraphMap.find(fAsicId[id]) == fGraphMap.end()) fGraphMap[fAsicId[id]] = {0}; + else { + int jg = fGraphMap[fAsicId[id]][fChId[id]]; + if (jg > 0) { + memset(fGraph[jg]->GetY(), 0, fGraph[jg]->GetN() * sizeof(double)); + memset(fGraphShp[jg]->GetY(), 0, fGraphShp[jg]->GetN() * sizeof(double)); + memset(fGraphPhys[jg]->GetY(), 0, fGraphPhys[jg]->GetN() * sizeof(double)); + } } - nlast++; - ig++; } - if (nasic <= 1) return; +} + +//___________________________________________________________________ +int CbmTrdFASP::AddGraph(char typ) +{ + int gid(0); + if (fNgraph >= NGRAPH) { + LOG(warn) << "CbmTrdFASP::AddGraph : Draw buffer size " << NGRAPH << " exhausted. Expert setting."; + return gid; + } + + int id(typ == 'T' ? 0 : 1); + gid = fNgraph; + fGraph[gid] = new TGraph(/*fOut.size()*/); + fGraph[gid]->SetNameTitle(Form("g%03d", gid), + Form("FASP id/ch [%3d / %2d] pad[%3d][%c]", fAsicId[id], fChId[id], fPad, typ)); + fGraph[gid]->SetFillStyle(0); + fGraph[gid]->SetMarkerStyle(7); + fGraph[gid]->SetLineColor(kRed); + fGraph[gid]->SetMarkerColor(kRed); + + fGraphShp[gid] = (TGraph*) fGraph[gid]->Clone(); + fGraphShp[gid]->SetName(Form("gs%03d", gid)); + fGraphShp[gid]->SetLineColor(kBlack); + fGraphShp[gid]->SetMarkerColor(kBlack); + + fGraphPhys[gid] = (TGraph*) fGraph[gid]->Clone(); + fGraphPhys[gid]->SetName(Form("gp%03d", gid)); + fGraphPhys[gid]->SetMarkerStyle(20); + fGraphPhys[gid]->SetLineWidth(2); + for (UInt_t ip(0), tm(fStartTime / 5); ip < fOut.size(); ip++, tm += 5) + fGraphPhys[gid]->SetPoint(ip, tm, 0.); + + fNgraph++; + + return gid; +} + +//___________________________________________________________________ +void CbmTrdFASP::Draw(Option_t* /*opt*/) +{ + if (!DRAW) return; + if (!fGraphMap.size()) return; TH1* h(nullptr); - TString st, sch; - Int_t ch, jg; TVirtualPad* c1(nullptr); if (!fMonitor) { - fMonitor = new TCanvas("c", "FASP Simulator", 10, 10, 1500, 2000); - fMonitor->Divide(2, 8, 1.e-5, 1.e-5); - for (Int_t ic(0); ic < 16; ic++) { - c1 = fMonitor->cd(ic + 1); + fMonitor = new TCanvas("c", "FASP Simulator", 10, 10, 1850, 2500); + fMonitor->Divide(4, 4, 1.e-5, 1.e-5); + for (Int_t ic(1); ic <= NFASPCH; ic++) { + c1 = fMonitor->cd(ic); + c1->SetLogy(); c1->SetLeftMargin(0.03580097); c1->SetRightMargin(0.006067961); c1->SetTopMargin(0.01476793); } - // fMonitor = new TCanvas("c", "FASP Simulator",10,10,500,1000); - // fMonitor->Divide(1,2,1.e-5, 1.e-5); - // for(Int_t ic(0); ic<2; ic++){ - // c1 = fMonitor->cd(ic+1); - // c1->SetLeftMargin(0.03580097); - // c1->SetRightMargin(0.006067961); - // c1->SetTopMargin(0.01476793); - // } fGthr = new TLine(); fGthr->SetLineStyle(2); } - ig = fGraphMap.begin(); - last = ig->first; - for (Int_t iasic(0); iasic < nasic - 1; iasic++) { - while (ig != fGraphMap.end()) { - if (ig->first != last) { // save graphs - fMonitor->Modified(); - fMonitor->Update(); - fMonitor->SaveAs(Form("FASP_analog_ASIC%03d.gif", last)); - for (Int_t ic(0); ic < /*2*/ 16; ic++) - fMonitor->cd(ic + 1)->Clear(); - last = ig->first; - break; - } - jg = ig->second; - st = fGraph[jg]->GetTitle(); - sch = st(st.Sizeof() - 3, 2); - ch = sch.Atoi(); - if (ch >= 8) c1 = fMonitor->cd(2 + 2 * (ch - 8)); //->SetLogy(); + for (auto iasic : fGraphMap) { + for (Int_t ic(0); ic < NFASPCH; ic++) + fMonitor->cd(ic + 1)->Clear(); + for (int ich(0), jg(0); ich < NFASPCH; ich++) { + if (!(jg = iasic.second[ich])) continue; + + int rch = ich / 4, cch = ich % 4; + c1 = fMonitor->cd(4 * cch + rch + 1); + + if (!fGraph[jg]) LOG(error) << "Missing graph for " << jg; + else + fGraph[jg]->Draw("al"); + if (!fGraphShp[jg]) LOG(error) << "Missing shaper graph for " << jg; else - c1 = fMonitor->cd(1 + 2 * ch); - fGraph[jg]->Draw("al"); - fGraphShp[jg]->Draw("l"); - fGraphPhys[jg]->Draw("lp"); + fGraphShp[jg]->Draw("l"); + if (!fGraphPhys[jg]) LOG(error) << "Missing physics graph for " << jg; + else + fGraphPhys[jg]->Draw("lp"); fGthr->SetLineColor(kGreen); fGthr->DrawLine(0, fgShaperThr + 0.2, 5 * fOut.size(), fgShaperThr + 0.2); fGthr->SetLineColor(kRed); fGthr->DrawLine(0, fgNeighbourThr + 0.2, 5 * fOut.size(), fgNeighbourThr + 0.2); h = fGraph[jg]->GetHistogram(); - h->GetYaxis()->SetRangeUser(0.01, 5.3); - - ig++; + h->GetYaxis()->SetRangeUser(0.1, 6); } + fMonitor->Modified(); + fMonitor->Update(); + fMonitor->SaveAs(Form("FASP%03d_sim.png", iasic.first)); } - - //swap draw buffer - TGraph* buffer[NGRAPH] = {nullptr}; - memcpy(buffer, fGraph, (jg + 1) * sizeof(TGraph*)); - memcpy(fGraph, &fGraph[jg + 1], nlast * sizeof(TGraph*)); - memcpy(&fGraph[nlast], buffer, (jg + 1) * sizeof(TGraph*)); - memcpy(buffer, fGraphShp, (jg + 1) * sizeof(TGraph*)); - memcpy(fGraphShp, &fGraphShp[jg + 1], nlast * sizeof(TGraph*)); - memcpy(&fGraphShp[nlast], buffer, (jg + 1) * sizeof(TGraph*)); - memcpy(buffer, fGraphPhys, (jg + 1) * sizeof(TGraph*)); - memcpy(fGraphPhys, &fGraphPhys[jg + 1], nlast * sizeof(TGraph*)); - memcpy(&fGraphPhys[nlast], buffer, (jg + 1) * sizeof(TGraph*)); - fGraphId -= jg + 1; - fGraphMap.clear(); - for (Int_t ich(0); ich < nlast; ich++) - fGraphMap.push_back(make_pair(last, ich)); } //___________________________________________________________________ @@ -245,17 +254,17 @@ void CbmTrdFASP::GetShaperSignal(Double_t charge) } if (idx0 < 0) { // above calibrated region - if (VERBOSE) printf("refMax[%2d]=%5.1f\n", fgkNDB - 1, fgkCharge[fgkNDB - 1]); + if (VERBOSE) printf(" refMax[%2d]=%5.1f", fgkNDB - 1, fgkCharge[fgkNDB - 1]); memcpy(fSignal, fgkShaper[fgkNDB - 1], FASP_WINDOW * sizeof(Float_t)); } else if (idx0 == 0 && charge < fgkCharge[0]) { // below calibrated region - if (VERBOSE) printf("refMin[0]={%5.1f}\n", fgkCharge[0]); + if (VERBOSE) printf(" refMin[0]={%5.1f}", fgkCharge[0]); for (Int_t it(0); it < FASP_WINDOW; it++) fSignal[it] = charge * fgkShaper[0][it] / fgkCharge[0]; } else { idx1 = idx0 + 1; - if (VERBOSE) printf("ref={%5.1f[%2d] %5.1f[%2d]}\n", fgkCharge[idx0], idx0, fgkCharge[idx1], idx1); + if (VERBOSE) printf(" ref={%5.1f[%2d] %5.1f[%2d]}", fgkCharge[idx0], idx0, fgkCharge[idx1], idx1); // linear interpolation Double_t dq(fgkCharge[idx0] - fgkCharge[idx1]); for (Int_t it(0); it < FASP_WINDOW; it++) @@ -265,9 +274,6 @@ void CbmTrdFASP::GetShaperSignal(Double_t charge) } } -//___________________________________________________________________ -void CbmTrdFASP::Init(Int_t /*col*/, CbmTrdParFaspChannel* /*par*/) {} - //___________________________________________________________________ Double_t CbmTrdFASP::MakeOut(Int_t time) { @@ -295,14 +301,14 @@ Double_t CbmTrdFASP::MakeOut(Int_t time) } //___________________________________________________________________ -void CbmTrdFASP::PhysToRaw(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* vdigi, Int_t col, Int_t row) +void CbmTrdFASP::PhysToRaw(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* vdigi) { /** Public interface for converting physical digi to raw digi. See ScanDigi and ScanDigiNE for * the actual algorithms */ - if (fgNeighbour) ScanDigiNE(vdigi, col, row); + if (fgNeighbour) ScanDigiNE(vdigi); else - ScanDigi(vdigi, col, row); + ScanDigi(vdigi); } //___________________________________________________________________ @@ -311,7 +317,7 @@ void CbmTrdFASP::Print(Option_t* opt) const /** Dump settings for the FASP simulator and optionally the content of the current buffers. */ - printf("FASP Simulator : Col[%2d] NeighbourTrigger[%c]\n", fCol, fgNeighbour ? 'y' : 'n'); + printf("FASP Simulator : Pad[%3d] NeighbourTrigger[%c]\n", fPad, fgNeighbour ? 'y' : 'n'); printf(" Main CH : Trigger[V]=%4.2f Flat-Top[ns]=%5.1f\n", fgShaperThr, fgkNclkFT * CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP)); printf(" Neighbour CH : Trigger[V]=%4.2f Linear-gate[ns]=%5.1f\n", fgNeighbourThr, @@ -342,12 +348,13 @@ Int_t CbmTrdFASP::ProcessShaper(Char_t typ) * Optionally the analog input and output for the current channel are also saved if DRAW is defined. */ + int id(typ == 'T' ? 0 : 1), chId = fChId[id], asicId = fAsicId[id]; if (VERBOSE) - printf(" CbmTrdFASP::ProcessShaper(%c) : row[%2d] col[%2d] asic[%4d] " - "PhysDigi[%d] GraphPtr[%d] ...\n", - typ, fRow, fCol, fAsicId, fNphys[0], (DRAW ? fGraphId : -1)); - fTimeFT = -1; - fTimeLG = -1; + printf(" CbmTrdFASP::ProcessShaper(%c) : pad [%3d] asic/ch[%4d/%2d] " + "digis[%d] ...\n", + typ, fPad, asicId, chId, fNphys[id]); + fTimeFT = -1; // length of the FT gate in 5ns bins (see fgkNclkFT) + fTimeLG = -1; // length of the LG gate in 5ns bins (see fgkNclkLG) fFT = 0; // digital signals Bool_t ht(0), htf(0), // hit_threshold level/front for current FASP channel @@ -356,19 +363,21 @@ Int_t CbmTrdFASP::ProcessShaper(Char_t typ) pk_cmd(0), // peak_command level lg_cmd(0), // linear-gate_command level trigger(0); // trigger type [1] = self [0]=neighbour - UInt_t n(0), // no of raw digi found in current shaper - htime(0); // hit time on current channel - Double_t out, max(-1), old(-1); + uint n(0), // no of raw digi found in current shaper + ht_time(0), // hit time on current channel + cs_time(0); // CS time on current channel + double out, max(-1), old(-1); for (size_t i = 1; i < fShaper.size() - 1; i++) { // compute hit threshold level/front for current and neighbour channels htf_prev = 0; htf = 0; htf_next = 0; - if (/*fShaper[i-1]<fgNeighbourThr && */ fShaper[i] >= fgNeighbourThr) htime = i * 5; + //TODO NE if (/*fShaper[i-1]<fgNeighbourThr && */ fShaper[i] >= fgNeighbourThr) ht_time = i * 5; if (fShaper[i - 1] < fgShaperThr && fShaper[i] >= fgShaperThr) { ht = 1; htf = 1; trigger = 1; + ht_time = i * 5; if (VERBOSE) printf(" %4lu : HT 1\n", i * 5); } else if (fShaper[i - 1] >= fgShaperThr && fShaper[i] < fgShaperThr) { @@ -396,8 +405,11 @@ Int_t CbmTrdFASP::ProcessShaper(Char_t typ) if (fTimeLG < 0) { // check if linear-gate is closed if ((fgNeighbour && (htf_prev || htf || htf_next)) || (!fgNeighbour && htf)) { lg_cmd = 1; - fTimeLG = i + 0.2 * fgNclkLG * CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP); - if (VERBOSE) printf(" %4lu : LG_CMD 1 -> MinGateEnd[ns]=%d\n", i * 5, fTimeLG * 5); + fTimeLG = + i + + 0.2 * fgNclkLG + * CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP); // compute the end time of LG in FASP-sim 5ns clks + if (VERBOSE) printf(" %4lu : LG_CMD 1 -> LG_End[ns]=%d\n", i * 5, fTimeLG * 5); } } else if (static_cast<size_t>(fTimeLG) < i && !ht && !pk_cmd && (fgNeighbour && (!fHitThPrev[i] && !ht_next))) { @@ -424,18 +436,21 @@ Int_t CbmTrdFASP::ProcessShaper(Char_t typ) max = out; if (VERBOSE) printf(" %4lu : MAX[V]=%5.2f\n", i * 5, max); } - if (out < max - 0.05) { + // start digital processing when the analog signal drops 50 mV under the max value. + // Adjust this value to the measured data in order to correctly describe the time difference spectra obtained (e.g. mCBM22) + if (out < max - 0.02) { fTimeFT = i + 0.2 * fgkNclkFT * CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP); fTimeDY = -1; fFT = max + 0.01; + cs_time = uint((i + 3) * 5); // save data for digi update fDigiProc.push_back(make_tuple( - htime, UInt_t((i + 3) * 5), UInt_t(4095 * TMath::Min(Float_t(1.), (fgBaseline + fFT) / fgOutGain)), trigger)); + ht_time, cs_time, UInt_t(4095 * TMath::Min(Float_t(1.), (fgBaseline + fFT) / fgOutGain)), trigger)); n++; if (VERBOSE) - printf(" %4lu : HT[ns]=%4d FT[V]=%5.2f CS[ns]+=15 |CS[ns]=%d " + printf(" %4lu : HT[ns]=%4u FT[V]=%5.2f CS[ns]=%4u CS_End[ns]=%d " "Trig[%c]\n", - i * 5, htime, fFT, fTimeFT * 5, trigger ? 'S' : 'N'); + i * 5, ht_time, fFT, cs_time, fTimeFT * 5, trigger ? 'S' : 'N'); } } if (fTimeFT > 0 && static_cast<size_t>(fTimeFT) <= i) { @@ -458,91 +473,72 @@ Int_t CbmTrdFASP::ProcessShaper(Char_t typ) // save results for draw if (DRAW) { - if (fGraphId < NGRAPH - 1) { - Int_t ch = 2 * (fCol % 8) + (typ == 'R' ? 1 : 0), ip(0), time = fStartTime; - if (!fGraph[fGraphId]) { - fGraph[fGraphId] = new TGraph(fOut.size()); - fGraph[fGraphId]->SetName(Form("g%03d", fGraphId)); - fGraph[fGraphId]->SetFillStyle(0); - fGraph[fGraphId]->SetMarkerStyle(7); - fGraph[fGraphId]->SetLineColor(kRed); - fGraph[fGraphId]->SetMarkerColor(kRed); - fGraphShp[fGraphId] = (TGraph*) fGraph[fGraphId]->Clone(); - fGraphShp[fGraphId]->SetName(Form("gs%03d", fGraphId)); - fGraphShp[fGraphId]->SetLineColor(kBlack); - fGraphShp[fGraphId]->SetMarkerColor(kBlack); - } - fGraph[fGraphId]->SetTitle(Form("Col[%2d] Row[%2d] ASIC[%3d] Channel = %2d", fCol, fRow, fAsicId, ch)); - fGraphMap.push_back(make_pair(fAsicId, fGraphId)); - vector<Float_t>::const_iterator ot = fOut.cbegin(), st = fShaper.cbegin(); - while (ot != fOut.cend()) { - fGraph[fGraphId]->SetPoint(ip, time, 0.3 + *ot); - ot++; - fGraphShp[fGraphId]->SetPoint(ip, time, 0.2 + *st); - st++; - time += 5; - ip++; + int gid = fGraphMap[asicId][chId]; + if (!gid) + LOG(warn) << "CbmTrdFASP::ProcessShaper : Draw representation missing for " + << Form(" FASP id/ch[%3d/%2d].", asicId, chId); + else { + double time = fStartTime; + //printf("AB :: g%d[%s] size[%lu]\n", gid, fGraph[gid]->GetName(), fShaper.size()); + for (uint ip(0); ip < fShaper.size(); ip++, time += 5.) { + //printf("time[%3d]=%.0f out[%f] shp[%f]\n", ip, time, 0.3+fOut[ip], 0.2+fShaper[ip]); + fGraph[gid]->SetPoint(ip, time, 0.3 + fOut[ip]); + fGraphShp[gid]->SetPoint(ip, time, 0.2 + fShaper[ip]); } - fGraphId += 1; } - else - LOG(warn) << "CbmTrdFASP::ProcessShaper : Draw buffer exhausted. Expert setting."; } // move to the next channel memcpy(fShaper.data(), fShaperNext.data(), fShaper.size() * sizeof(Float_t)); memset(fShaperNext.data(), 0, fShaperNext.size() * sizeof(Float_t)); - fNphys[0] = fNphys[1]; - fNphys[1] = 0; return n; } //___________________________________________________________________ -void CbmTrdFASP::ScanDigi(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* vdigi, Int_t col, Int_t row) +void CbmTrdFASP::ScanDigi(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* vdigi) { /** Transform point like time distribution of digis into the time dependent analog signal of the first FASP shaper */ - CbmTrdDigi* digi(nullptr); - ULong64_t time; - Int_t dt, gid, asic = row * 9 + col / 8; - Double_t t, r; - if (fAsicId < 0) fAsicId = asic; // init asic identifier - fCol = col; - fRow = row; - fAsicId = asic; - if (DRAW) { - gid = fGraphId + 1; - if (fGraphPhys[gid]) memset(fGraphPhys[gid]->GetY(), 0, fGraphPhys[gid]->GetN() * sizeof(Double_t)); - else { - fGraphPhys[gid] = new TGraph(fOut.size()); - fGraphPhys[gid]->SetName(Form("gp%03d", gid)); - fGraphPhys[gid]->SetMarkerStyle(20); - fGraphPhys[gid]->SetLineWidth(2); - for (UInt_t ip(0), tm(fStartTime / 5); ip < fOut.size(); ip++, tm += 5) - fGraphPhys[gid]->SetPoint(ip, tm, 0.); - } - } + fPad = -1; + fNphys[0] = 0; + fNphys[1] = 0; + // process digi - std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>::iterator iv = vdigi->begin(); vector<Float_t>::iterator itb; - while (iv != vdigi->end()) { - digi = iv->first; - time = (digi->GetTimeDAQ() - fStartTime) / 5; // get time in 5ns bins + for (auto iv : (*vdigi)) { + CbmTrdDigi* digi = iv.first; + + // first time initialize geographic location + if (fPad < 0) { + fPad = digi->GetAddressChannel(); + + if (VERBOSE > 1) + printf(" AB :: (%3d) fStartTime = %llu N=%lu ASIC=[%3d | %2d] ASIC=[%3d | %2d]\n", fPad, fStartTime, + vdigi->size(), fAsicId[0], fChId[0], fAsicId[1], fChId[1]); + } + ULong64_t time = (digi->GetTime() - fStartTime) / 5; // get time in 5ns bins + + if (VERBOSE > 1) printf(" AB :: digi->GetTime() = %f sim->time = %llu\n", digi->GetTime(), time * 5); if (time + FASP_WINDOW > fShaper.size()) { - LOG(debug) << "CbmTrdFASP::ScanDigi() : Digi @ row[" << row << "] col[" << col << "] time[" << digi->GetTimeDAQ() + LOG(debug) << "CbmTrdFASP::ScanDigi() : Digi @ pad[" << fPad << " time[" << digi->GetTime() << "] dows not fit in the current buffer starting @ " << fStartTime << "ns. Skip this time."; break; } - r = digi->GetCharge(t, dt); + int dt; + double t, r = digi->GetCharge(t, dt); t /= 10; r /= 10; if (VERBOSE) printf(" time buffer[5ns]=%4llu / phys[ns]=%llu charge[fC]=%5.1f / %5.1f", time, digi->GetTimeDAQ(), t, r); // tilt pad channel - if (t > 0) { - if (DRAW) fGraphPhys[gid]->SetPoint(time, digi->GetTimeDAQ(), t / 100.); + if (t > 0 && fChId[0] >= 0) { + if (DRAW) { + int gid = fGraphMap[fAsicId[0]][fChId[0]]; + if (!gid) fGraphMap[fAsicId[0]][fChId[0]] = gid = AddGraph('T'); + if (gid) fGraphPhys[gid]->SetPoint(time, digi->GetTime(), t / 10.); + } GetShaperSignal(t); itb = fShaper.begin(); itb += time; @@ -550,11 +546,14 @@ void CbmTrdFASP::ScanDigi(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* vdigi, (*itb) += fSignal[it]; fNphys[0]++; } - else if (VERBOSE) - printf("\n"); + // rect pad channel - if (r > 0) { - if (DRAW) fGraphPhys[gid]->SetPoint(time, digi->GetTimeDAQ(), r / 100.); + if (r > 0 && fChId[1] >= 0) { + if (DRAW) { + int gid = fGraphMap[fAsicId[1]][fChId[1]]; + if (!gid) fGraphMap[fAsicId[1]][fChId[1]] = gid = AddGraph('R'); + fGraphPhys[gid]->SetPoint(time, digi->GetTime(), r / 10.); + } GetShaperSignal(r); itb = fShaperNext.begin(); itb += time + dt; @@ -562,176 +561,185 @@ void CbmTrdFASP::ScanDigi(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* vdigi, (*itb) += fSignal[it]; fNphys[1]++; } - else if (VERBOSE) - printf("\n"); - iv++; - } + + if (VERBOSE) printf("\n"); + } // end reading the digis + if (fNphys[0]) fNraw = ProcessShaper('T'); // process tilt if (fNphys[1]) ProcessShaper('R'); // process rect + fDigi = vdigi; WriteDigi(); } //___________________________________________________________________ -void CbmTrdFASP::ScanDigiNE(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* vdigi, Int_t col, Int_t row) +void CbmTrdFASP::ScanDigiNE(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* /*vdigi*/) { /** Transform point like time distribution of digis into the time dependent analog signal * of the first FASP shaper and process output (see ProcessShaper()) */ - CbmTrdDigi* digi(nullptr); - ULong64_t time; - Int_t dt, gid, asic = row * 9 + col / 8; - Double_t t, r; - std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>::iterator iv; - vector<Float_t>::iterator itb; - - if (fAsicId < 0) fAsicId = asic; // init asic identifier - - // printf("CbmTrdFASP::ScanDigiNE : fCol[%2d] col[%2d] graph[%d]\n", fCol, col, fGraphId); - // No interference from the previous data - if (fCol < 0 || // first data in the module - (fCol >= 0 && col != fCol + 1) || // column jump - (fRow >= 0 && row != fRow)) { // row jump - Clear((fAsicId != asic ? "draw" : "")); - - if (DRAW) { - gid = fGraphId; - if (fGraphPhys[gid]) memset(fGraphPhys[gid]->GetY(), 0, fGraphPhys[gid]->GetN() * sizeof(Double_t)); - else { - fGraphPhys[gid] = new TGraph(fOut.size()); - fGraphPhys[gid]->SetName(Form("gp%03d", gid)); - fGraphPhys[gid]->SetMarkerStyle(20); - fGraphPhys[gid]->SetLineWidth(2); - for (UInt_t ip(0), tm(fStartTime / 5); ip < fOut.size(); ip++, tm += 5) - fGraphPhys[gid]->SetPoint(ip, tm, 0.); - } - } - - // load data from current tilt channel - iv = vdigi->begin(); - while (iv != vdigi->end()) { - digi = iv->first; - time = (digi->GetTimeDAQ() - fStartTime) / 5; // get time from buffer start in 5ns bins - if (time + FASP_WINDOW > fShaper.size()) { - LOG(debug) << "CbmTrdFASP::ScanDigiNE() : T-Digi @ row[" << row << "] col[" << col << "] time[" - << digi->GetTimeDAQ() << "] does not fit in the current buffer starting @ " << fStartTime - << "ns. Skip this time."; - break; - } - digi->GetCharge(t, dt); - t /= 10.; + LOG(info) << "CbmTrdFASP::ScanDigiNE() : **Method under construction**. Use CbmTrdFASP::ScanDigi() instead by " + "selecting CbmTrdFASP:: SetNeighbourTrigger(0)"; + return; if (VERBOSE) printf(" [T] time buffer[5ns]=%4llu / phys[ns]=%llu charge[fC]=%5.1f ", time, digi->GetTimeDAQ(), t); - // tilt pad channel - if (t > 0) { - if (DRAW) fGraphPhys[gid]->SetPoint(time, digi->GetTimeDAQ(), t / 100.); - GetShaperSignal(t); - itb = fShaper.begin(); - itb += time; - for (Int_t it(0); it < FASP_WINDOW && itb != fShaper.end(); it++, itb++) - (*itb) += fSignal[it]; - fNphys[0]++; - } - else if (VERBOSE) - printf("\n"); - iv++; - } - } - else { - if (DRAW) { - gid = fGraphId + 1; - if (fGraphPhys[gid]) memset(fGraphPhys[gid]->GetY(), 0, fGraphPhys[gid]->GetN() * sizeof(Double_t)); - else { - fGraphPhys[gid] = new TGraph(fOut.size()); - fGraphPhys[gid]->SetName(Form("gp%03d", gid)); - fGraphPhys[gid]->SetMarkerStyle(20); - fGraphPhys[gid]->SetLineWidth(2); - for (UInt_t ip(0), tm(fStartTime / 5); ip < fOut.size(); ip++, tm += 5) - fGraphPhys[gid]->SetPoint(ip, tm, 0.); - } - } - - // load tilt digi to account for neighbour trigger - iv = vdigi->begin(); - while (iv != vdigi->end()) { - digi = iv->first; - time = (digi->GetTimeDAQ() - fStartTime) / 5; // get time from buffer start in 5ns bins - if (time + FASP_WINDOW > fShaper.size()) { - LOG(debug) << "CbmTrdFASP::ScanDigiNE() : T-Digi @ row[" << row << "] col[" << col << "] time[" - << digi->GetTimeDAQ() << "] does not fit in the current buffer starting @ " << fStartTime - << "ns. Skip this time."; - break; - } - digi->GetCharge(t, dt); - t /= 10.; - if (VERBOSE) printf(" [T] time buffer[5ns]=%4llu / phys[ns]=%llu charge[fC]=%5.1f ", time, digi->GetTimeDAQ(), t); - // tilt pad channel - if (t > 0) { - if (DRAW) fGraphPhys[gid]->SetPoint(time, digi->GetTimeDAQ(), t / 100.); - GetShaperSignal(t); - itb = fShaperNext.begin(); - itb += time; - for (Int_t it(0); it < FASP_WINDOW && itb != fShaperNext.end(); it++, itb++) - (*itb) += fSignal[it]; - fNphys[1]++; - } - else if (VERBOSE) - printf("\n"); - iv++; - } - ProcessShaper('R'); // process previous rect channel - WriteDigi(); // finalize fDigi list - } - - fCol = col; - fRow = row; - fAsicId = asic; - - if (DRAW) { - gid = fGraphId + 1; - if (fGraphPhys[gid]) memset(fGraphPhys[gid]->GetY(), 0, fGraphPhys[gid]->GetN() * sizeof(Double_t)); - else { - fGraphPhys[gid] = new TGraph(fOut.size()); - fGraphPhys[gid]->SetName(Form("gp%03d", gid)); - fGraphPhys[gid]->SetMarkerStyle(20); - fGraphPhys[gid]->SetLineWidth(2); - for (UInt_t ip(0), tm(fStartTime / 5); ip < fOut.size(); ip++, tm += 5) - fGraphPhys[gid]->SetPoint(ip, tm, 0.); - } - } - iv = vdigi->begin(); - while (iv != vdigi->end()) { - digi = iv->first; - time = (digi->GetTimeDAQ() - fStartTime) / 5; // get time from buffer start in 5ns bins - if (time + FASP_WINDOW > fShaper.size()) { - LOG(debug) << "CbmTrdFASP::ScanDigiNE() : R-Digi @ row[" << row << "] col[" << col << "] time[" - << digi->GetTimeDAQ() << "] dows not fit in the current buffer starting @ " << fStartTime - << "ns. Skip this time."; - break; - } - r = digi->GetCharge(t, dt); - r /= 10.; if (VERBOSE) printf(" [R] time buffer[5ns]=%4llu / phys[ns]=%llu charge[fC]=%5.1f ", time, digi->GetTimeDAQ(), r); - // rect pad channel - if (r > 0) { - if (DRAW) fGraphPhys[gid]->SetPoint(time, digi->GetTimeDAQ(), r / 100.); - GetShaperSignal(r); - itb = fShaperNext.begin(); - itb += time + dt; - for (Int_t it(0); it < FASP_WINDOW && itb != fShaperNext.end(); it++, itb++) - (*itb) += fSignal[it]; - fNphys[1]++; - } - else if (VERBOSE) - printf("\n"); - iv++; - } - fNraw = ProcessShaper('T'); // process tilt on current channel - fDigi = vdigi; // save link for further processing + // CbmTrdDigi* digi(nullptr); + // ULong64_t time; + // Int_t dt, gid, asic = row * 9 + col / 8; // TODO should come from calibration + // Double_t t, r; + // std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>::iterator iv; + // vector<Float_t>::iterator itb; + // + // if (fAsicId < 0) fAsicId = asic; // init asic identifier + // + // // printf("CbmTrdFASP::ScanDigiNE : fCol[%2d] col[%2d] graph[%d]\n", fCol, col, fGraphId); + // // No interference from the previous data + // if (fCol < 0 || // first data in the module + // (fCol >= 0 && col != fCol + 1) || // column jump + // (fRow >= 0 && row != fRow)) { // row jump + // Clear((fAsicId != asic ? "draw" : "")); + // + // if (DRAW) { + // gid = fGraphId; + // if (fGraphPhys[gid]) memset(fGraphPhys[gid]->GetY(), 0, fGraphPhys[gid]->GetN() * sizeof(Double_t)); + // else { + // fGraphPhys[gid] = new TGraph(fOut.size()); + // fGraphPhys[gid]->SetName(Form("gp%03d", gid)); + // fGraphPhys[gid]->SetMarkerStyle(20); + // fGraphPhys[gid]->SetLineWidth(2); + // for (UInt_t ip(0), tm(fStartTime / 5); ip < fOut.size(); ip++, tm += 5) + // fGraphPhys[gid]->SetPoint(ip, tm, 0.); + // } + // } + // + // // load data from current tilt channel + // iv = vdigi->begin(); + // while (iv != vdigi->end()) { + // digi = iv->first; + // // TODO:AB GetTimeDAQ() [clk] and fStartTime [ns] + // time = (digi->GetTimeDAQ() - fStartTime) / 5; // get time from buffer start in 5ns bins + // if (time + FASP_WINDOW > fShaper.size()) { + // LOG(debug) << "CbmTrdFASP::ScanDigiNE() : T-Digi @ row[" << row << "] col[" << col << "] time[" + // << digi->GetTimeDAQ() << "] does not fit in the current buffer starting @ " << fStartTime + // << "ns. Skip this time."; + // break; + // } + // digi->GetCharge(t, dt); + // t /= 10.; + // if (VERBOSE) printf(" [T] time buffer[5ns]=%4llu / phys[ns]=%lu charge[fC]=%5.1f ", time, digi->GetTimeDAQ(), t); + // // tilt pad channel + // if (t > 0) { + // if (DRAW) fGraphPhys[gid]->SetPoint(time, digi->GetTimeDAQ(), t / 100.); + // GetShaperSignal(t); + // itb = fShaper.begin(); + // itb += time; + // for (Int_t it(0); it < FASP_WINDOW && itb != fShaper.end(); it++, itb++) + // (*itb) += fSignal[it]; + // fNphys[0]++; + // } + // else if (VERBOSE) + // printf("\n"); + // iv++; + // } + // } + // else { + // if (DRAW) { + // gid = fGraphId + 1; + // if (fGraphPhys[gid]) memset(fGraphPhys[gid]->GetY(), 0, fGraphPhys[gid]->GetN() * sizeof(Double_t)); + // else { + // fGraphPhys[gid] = new TGraph(fOut.size()); + // fGraphPhys[gid]->SetName(Form("gp%03d", gid)); + // fGraphPhys[gid]->SetMarkerStyle(20); + // fGraphPhys[gid]->SetLineWidth(2); + // for (UInt_t ip(0), tm(fStartTime / 5); ip < fOut.size(); ip++, tm += 5) + // fGraphPhys[gid]->SetPoint(ip, tm, 0.); + // } + // } + // + // // load tilt digi to account for neighbour trigger + // iv = vdigi->begin(); + // while (iv != vdigi->end()) { + // digi = iv->first; + // time = (digi->GetTimeDAQ() - fStartTime) / 5; // get time from buffer start in 5ns bins + // if (time + FASP_WINDOW > fShaper.size()) { + // LOG(debug) << "CbmTrdFASP::ScanDigiNE() : T-Digi @ row[" << row << "] col[" << col << "] time[" + // << digi->GetTimeDAQ() << "] does not fit in the current buffer starting @ " << fStartTime + // << "ns. Skip this time."; + // break; + // } + // digi->GetCharge(t, dt); + // t /= 10.; + // + // if (VERBOSE) printf(" [T] time buffer[5ns]=%4llu / phys[ns]=%lu charge[fC]=%5.1f ", time, digi->GetTimeDAQ(), t); + // // tilt pad channel + // if (t > 0) { + // if (DRAW) fGraphPhys[gid]->SetPoint(time, digi->GetTimeDAQ(), t / 100.); + // GetShaperSignal(t); + // itb = fShaperNext.begin(); + // itb += time; + // for (Int_t it(0); it < FASP_WINDOW && itb != fShaperNext.end(); it++, itb++) + // (*itb) += fSignal[it]; + // fNphys[1]++; + // } + // else if (VERBOSE) + // printf("\n"); + // iv++; + // } + // ProcessShaper('R'); // process previous rect channel + // WriteDigi(); // finalize fDigi list + // } + // + // fCol = col; + // fRow = row; + // fAsicId = asic; + // + // if (DRAW) { + // gid = fGraphId + 1; + // if (fGraphPhys[gid]) memset(fGraphPhys[gid]->GetY(), 0, fGraphPhys[gid]->GetN() * sizeof(Double_t)); + // else { + // fGraphPhys[gid] = new TGraph(fOut.size()); + // fGraphPhys[gid]->SetName(Form("gp%03d", gid)); + // fGraphPhys[gid]->SetMarkerStyle(20); + // fGraphPhys[gid]->SetLineWidth(2); + // for (UInt_t ip(0), tm(fStartTime / 5); ip < fOut.size(); ip++, tm += 5) + // fGraphPhys[gid]->SetPoint(ip, tm, 0.); + // } + // } + // iv = vdigi->begin(); + // while (iv != vdigi->end()) { + // digi = iv->first; + // time = (digi->GetTimeDAQ() - fStartTime) / 5; // get time from buffer start in 5ns bins + // if (time + FASP_WINDOW > fShaper.size()) { + // LOG(debug) << "CbmTrdFASP::ScanDigiNE() : R-Digi @ row[" << row << "] col[" << col << "] time[" + // << digi->GetTimeDAQ() << "] dows not fit in the current buffer starting @ " << fStartTime + // << "ns. Skip this time."; + // break; + // } + // r = digi->GetCharge(t, dt); + // r /= 10.; + // if (VERBOSE) printf(" [R] time buffer[5ns]=%4llu / phys[ns]=%lu charge[fC]=%5.1f ", time, digi->GetTimeDAQ(), r); + // + // // rect pad channel + // if (r > 0) { + // if (DRAW) fGraphPhys[gid]->SetPoint(time, digi->GetTimeDAQ(), r / 100.); + // GetShaperSignal(r); + // itb = fShaperNext.begin(); + // itb += time + dt; + // for (Int_t it(0); it < FASP_WINDOW && itb != fShaperNext.end(); it++, itb++) + // (*itb) += fSignal[it]; + // fNphys[1]++; + // } + // else if (VERBOSE) + // printf("\n"); + // iv++; + // } + // fNraw = ProcessShaper('T'); // process tilt on current channel + // fDigi = vdigi; // save link for further processing } //___________________________________________________________________ @@ -748,55 +756,53 @@ void CbmTrdFASP::WriteDigi() { if (!fDigi) return; - if (VERBOSE) - printf(" CbmTrdFASP::WriteDigi(T[%d], R[%d]) ...\n", fNraw + 1, Int_t(fDigiProc.size()) - fNraw + 1); + if (VERBOSE) printf(" CbmTrdFASP::WriteDigi(T[%d], R[%d]) ...\n", fNraw, Int_t(fDigiProc.size()) - fNraw); - vector<tuple<UInt_t, UInt_t, UInt_t, Bool_t>>::iterator it = fDigiProc.begin(), // begin [tilt] iterator - jt = it + fNraw, // middle [rect] iterator - lt = jt; // middle iterator + auto it = fDigiProc.begin(), // [tilt] iterator + ir = it + fNraw, // [rect] iterator + im = ir; // middle iterator CbmTrdDigi *digi(nullptr), *digi1(nullptr); CbmMatch* dmatch(nullptr); - ULong64_t time, dtime; - Int_t dt, ddt, trigger(0); - Double_t t, r, t0, r0; - UInt_t hTime, // hit time [ns] - csTime, // CS time [ns] + ULong64_t time, // relative time[ns] of PHYSICAL digi wrt the simulator window start + dtime; // relative time[ns] of DIGITAL digi wrt the simulator window start + int dt, ddt, trigger(0); + double t, r, t0, r0; + uint ht_time, // hit time [ns] + cs_time, // CS time [ns] tADC, // tilt channel signal [ADC] rADC; // rect channel signal [ADC] //Bool_t mask(0), pileup(0); - std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>::iterator jv, iv = fDigi->begin(); - - while (iv != fDigi->end()) { - digi = iv->first; - dmatch = iv->second; - time = (digi->GetTimeDAQ() - fStartTime); // digi time in [ns] from buffer start + for (auto dd : (*fDigi)) { + digi = dd.first; + dmatch = dd.second; + time = (digi->GetTime() - fStartTime); // digi time in [ns] from buffer start // stop digi finalize if (time > fProcTime) break; r = digi->GetCharge(t, dt); r /= 10.; t /= 10.; - if (VERBOSE) cout << " IN : " << digi->ToString() << " " << dmatch->ToString(); + if (VERBOSE) cout << " IN : " << digi->ToString() << " " << dmatch->ToString(); rADC = 0; tADC = 0; - dtime = 0; - ddt = 0; /*mask=0; pileup=0;*/ + dtime = 0; // relative time of the prompt(T and R) CS signals expressed in ns + ddt = 0; // time difference between the T and R signals expressed in clks trigger = 0; - hTime = 0; - while (it != lt) { - hTime = get<0>(*it); - if (VERBOSE) printf(" [T] htime[ns]=%d FT[ADC]=%4d ... \n", hTime, get<2>(*it)); - if (hTime > time) break; + ht_time = 0; + while (it != im) { + ht_time = get<0>(*it); + if (VERBOSE) printf(" [T] htime[ns]=%d FT[ADC]=%4d ... \n", ht_time, get<2>(*it)); + if (ht_time > time) break; it++; } - if (t > 0. && it != lt) { - csTime = get<1>(*it); - //printf("match T htime[%d] time[%d]\n", hTime, time); - if (hTime - time < 400) { // found converted hit + if (t > 0. && it != im) { + cs_time = get<1>(*it); + //printf("match T htime[%d] time[%llu]\n", ht_time, time); + if (ht_time - time < 400) { // found converted hit if (VERBOSE) - printf(" [T] ht[ns]=%4d CS[ns]=%4d FT[ADC]=%4u Trg[%s]\n", hTime, csTime, get<2>(*it), + printf(" [T] ht[ns]=%4d CS[ns]=%4d FT[ADC]=%4u Trg[%s]\n", ht_time, cs_time, get<2>(*it), (get<3>(*it) ? "S" : "N")); - dtime = csTime; + dtime = cs_time; tADC = get<2>(*it); if (get<3>(*it)) trigger |= 1; //if(csTime-hTime > 350) pileup = kTRUE; // 350 ns max peak time @@ -804,59 +810,60 @@ void CbmTrdFASP::WriteDigi() } //else if(t>40.) mask=kTRUE; // hit not converted : possible under threshold, masked // 40fC threshold } + //printf("AB :: time[%llu] dtime[%llu] dt[%d]\n", time, dtime, dt); time += dt; - hTime = 0; - while (jt != fDigiProc.end()) { - hTime = get<0>(*jt); - if (VERBOSE) printf(" [R] htime[ns]=%d FT[ADC]=%4d ...\n", hTime, get<2>(*jt)); - if (hTime > time) break; - jt++; + ht_time = 0; + while (ir != fDigiProc.end()) { + ht_time = get<0>(*ir); + if (VERBOSE) printf(" [R] htime[ns]=%d FT[ADC]=%4d ...\n", ht_time, get<2>(*ir)); + if (ht_time > time) break; + ir++; } - if (r > 0. && jt != fDigiProc.end()) { - csTime = get<1>(*jt); - //printf("match R htime[%d] time[%d]\n", hTime, time); - if (hTime - time < 400) { // found converted hit + if (r > 0. && ir != fDigiProc.end()) { + cs_time = get<1>(*ir); + //printf("match R htime[%d] time[%llu]\n", ht_time, time); + if (ht_time - time < 400) { // found converted hit if (VERBOSE) - printf(" [R] ht[ns]=%4d CS[ns]=%4d FT[ADC]=%4u Trg[%s]\n", hTime, csTime, get<2>(*jt), - (get<3>(*jt) ? "S" : "N")); + printf(" [R] ht[ns]=%4d CS[ns]=%4d FT[ADC]=%4u Trg[%s]\n", ht_time, cs_time, get<2>(*ir), + (get<3>(*ir) ? "S" : "N")); if (dtime) { - if (csTime > dtime) - ddt = TMath::Ceil(Int_t(csTime - dtime) / CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP)); + if (cs_time > dtime) + ddt = TMath::Ceil(Int_t(cs_time - dtime) / CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP)); else - ddt = TMath::Floor(Int_t(csTime - dtime) / CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP)); + ddt = TMath::Floor(Int_t(cs_time - dtime) / CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP)); } else - dtime = csTime; - rADC = get<2>(*jt); - if (get<3>(*jt)) trigger |= 2; + dtime = cs_time; + rADC = get<2>(*ir); + if (get<3>(*ir)) trigger |= 2; //if(csTime-hTime > 350) pileup = kTRUE; // 350 ns max peak time - jt++; + ir++; } //else if(r>40.) mask=kTRUE; // hit not converted : possible under threshold, masked // 40fC threshold } + //printf("AB :: time[%llu] dtime[%llu] ddt[%d]\n", time, dtime, ddt); //update digi digi->SetMasked(1); // mark as processed if (dtime) { digi->SetTime(fStartTime + dtime); digi->SetCharge(tADC, rADC, ddt); digi->SetTriggerType(trigger); - if (VERBOSE) cout << " OUT: " << digi->ToString(); + if (VERBOSE) cout << " OUT: " << digi->ToString(); } else digi->SetFlag(0, kTRUE); // mark for deletion if (VERBOSE) cout << " ====================================" << "\n"; - iv++; } // try to merge digits ULong64_t time0, time1; Char_t type0, // prompt digi. kTRUE if rectangle type1; // late digi. kTRUE if rectangle - for (iv = fDigi->begin(); iv != fDigi->end(); iv++) { + for (auto iv = fDigi->begin(); iv != fDigi->end(); iv++) { digi = iv->first; if (digi->IsFlagged(0)) continue; // no output if (!digi->IsMasked()) break; // not finalized @@ -864,7 +871,7 @@ void CbmTrdFASP::WriteDigi() if (r0 > 0. && t0 > 0.) continue; // already complete type0 = (r0 > 0. ? 1 : 0); // mark type for prompt digi time0 = digi->GetTimeDAQ(); // mark time for prompt digi - for (jv = iv + 1; jv != fDigi->end(); jv++) { + for (auto jv = iv + 1; jv != fDigi->end(); jv++) { digi1 = jv->first; if (digi1->IsFlagged(0)) continue; // no output r = digi1->GetCharge(t, dt); diff --git a/core/detectors/trd/CbmTrdFASP.h b/core/detectors/trd/CbmTrdFASP.h index f30a2a643e4fa75c9bb79452b6e762ff6bdb6e06..25ee4e0407cd1ec6aa6e71228561de5e4380cc42 100644 --- a/core/detectors/trd/CbmTrdFASP.h +++ b/core/detectors/trd/CbmTrdFASP.h @@ -5,13 +5,15 @@ #ifndef CBMTRDFASP_H #define CBMTRDFASP_H +#include "CbmTrdParFasp.h" + #include <Rtypes.h> // for THashConsistencyHolder, ClassDef #include <RtypesCore.h> // for Int_t, Float_t, ULong64_t, UInt_t, Bool_t #include <TObject.h> // for TObject #include <tuple> // for tuple +#include <map> // for map #include <utility> // for pair -#include <vector> // for vector class CbmMatch; class CbmTrdDigi; @@ -22,7 +24,7 @@ class TLine; #define FASP_WINDOW 200 #define SHAPER_LUT 80 -#define NGRAPH 160 +#define NGRAPH (NFASPMOD * NFASPCH + 1) /** \brief FASP channel simulator **/ class CbmTrdFASP : public TObject { @@ -42,23 +44,19 @@ public: static Float_t GetBaselineCorr() { return 4095. * fgBaseline / fgOutGain; } /** \brief Check if there is enough time elapsed from fStartTime to run simulator*/ virtual Bool_t Go(ULong64_t time); - /** \brief [Re]Start processing of one channel - * \param[in] col current column - * \param[in] par FASP channel parametrization + /** \brief [Re]Initialize one of the two FASP channels + * \param[in] id FASP-CHANNEL identifier + * \param[in] par FASP-CHANNEL parametrization + * \param[in] asicId FASP id on the module (as in the DAQ mapping) to be used on drawing + * \param[in] chId FASP-CHANNEL id on the module (as in the DAQ mapping) to be used on drawing */ - virtual void Init(Int_t col, CbmTrdParFaspChannel* par); + virtual void InitChannel(int id, const CbmTrdParFaspChannel* par, int asicId = -1, int chId = -1); /** \brief Convert physics information in digi to the raw format - * \param[in] digi list of digits for the current channel - * \param[in] col column of current digis - * \param[in] row row of current digis + * \param[in] digi list of digits for the current pad */ - virtual void PhysToRaw(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* digi, Int_t col = 0, Int_t row = 0); + virtual void PhysToRaw(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* digi); /** \brief Print-out FASP analog/digital response to currently stored data*/ virtual void Print(Option_t* opt = "") const; - /** \brief Set column for the current channel - * \param[in] col column number in the current row. Default -1 for the first data - */ - void SetCol(Int_t col) { fCol = col; } /** \brief Set linear-gate minimum length * \param[in] nclk number of clock cycles at current clock frequency */ @@ -81,6 +79,7 @@ public: void SetStartTime(ULong64_t t) { fStartTime = t; } protected: + int AddGraph(char typ = 'T'); /** \brief Retrive linear interpolation of CADENCE for signal * \param[in] charge charge on channel */ @@ -91,46 +90,50 @@ protected: * \return no. of raw digi found */ Int_t ProcessShaper(Char_t typ = 'T'); - /** \brief Read digi array for single channel processing */ - void ScanDigi(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* digi, Int_t col, Int_t row); + /** \brief Read digi array for one pair T/R defined by the pad column + \param[in] digi the set of digi and their MC info if avilable + */ + void ScanDigi(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* digi); /** \brief Read digi array for neighbour trigger processing */ - void ScanDigiNE(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* digi, Int_t col, Int_t row); + void ScanDigiNE(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* digi); /** \brief Write processed digi to output array */ void WriteDigi(); - ULong64_t fStartTime; ///< time offset [ns] for the current simulation - UInt_t fProcTime; ///< time window [ns] for actual digi processing (excluded fgkBufferKeep) - Int_t fCol; ///< current column - Int_t fRow; ///< current row - Int_t fAsicId; ///< identifier of FASP in module + ULong64_t fStartTime = 0; ///< time offset [ns] for the current simulation + UInt_t fProcTime = 0; ///< time window [ns] for actual digi processing (excluded fgkBufferKeep) + int fPad = -1; ///< current pad as defined by CbmTrdModuleAbstract::GetPadAddress() Int_t fNphys[2]; ///< number of physical digi in the current [0] and next [1] shaper - Int_t fNraw; ///< number of raw digi for the tilt channel - std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* fDigi; ///< link to digi vector to be transformed + Int_t fNraw = 0; ///< number of raw digi for the tilt channel + std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* fDigi = nullptr; ///< link to digi vector to be transformed // analog support - std::vector<bool> fHitThPrev; ///< previous channel hit threshold - std::vector<Float_t> fShaper; ///< current channel shaper analog - std::vector<Float_t> fShaperNext; ///< next channel shaper analog - std::vector<std::tuple<UInt_t, UInt_t, UInt_t, Bool_t>> - fDigiProc; ///< proccessed info <hit_time[ns], CS_time[ns], OUT[ADC], trigger> - Float_t fSignal[FASP_WINDOW]; ///< temporary array to store shaper analog signal for current charge interpolation + std::vector<bool> fHitThPrev = {0}; ///< previous channel hit threshold + std::vector<Float_t> fShaper = {0.}; ///< current channel shaper analog + std::vector<Float_t> fShaperNext = {0.}; ///< next channel shaper analog + std::vector<std::tuple<UInt_t, UInt_t, UInt_t, Bool_t>> fDigiProc = + {}; ///< proccessed info wrt fStartTime <hit_time[ns], CS_time[ns], OUT[ADC], trigger> + Float_t fSignal[FASP_WINDOW] = { + 0.}; ///< temporary array to store shaper analog signal for current charge interpolation // FASP channel characteristics - CbmTrdParFaspChannel* fPar; ///< current FASP channel parametrization - Int_t fTimeLG; ///< Linear gate time length [5*ns] - Int_t fTimeFT; ///< Chip Select time legth [5*ns] - Int_t fTimeDY; ///< Time decay from FT [5*ns] - Float_t fFT; ///< Flat Top value [V] - - // draw support - Int_t fGraphId; ///< current graph to be filled if draw support is compiled - std::vector<Float_t> fOut; ///< analog output for the current channel - std::vector<std::pair<Int_t, Int_t>> fGraphMap; ///< map of ASIC id and output FASP signals - TGraph* fGraph[NGRAPH]; ///< graph representations of analog FASP response - TGraph* fGraphShp[NGRAPH]; ///< graph representations of FASP shaper - TGraph* fGraphPhys[NGRAPH]; ///< graph representations of physics digi - TLine* fGthr; ///< graph representation of various thresholds - TCanvas* fMonitor; ///< monitor canvas when drawing + const CbmTrdParFaspChannel* fPar[2] = {nullptr}; ///< current FASP ASIC parametrization + Int_t fTimeLG = -1; ///< Linear gate time length [5*ns] + Int_t fTimeFT = -1; ///< Chip Select time legth [5*ns] + Int_t fTimeDY = -1; ///< Time decay from FT [5*ns] + Float_t fFT = 0.; ///< Flat Top value [V] + + // FASP graphic support + int fNgraph = 1; ///< No of graphs generated + int fAsicId[2] = {-1, -1}; ///< identifier of FASP(s) in module + int fChId[2] = {-1, -1}; ///< FASP channels being processed + std::vector<Float_t> fOut = {0.}; ///< analog output for the current channel + std::map<int, std::array<int, NFASPCH>> fGraphMap = + {}; ///< map of ASIC_id and (ch_id, output_id of FASP signals graphs) pairs + TGraph* fGraph[NGRAPH] = {nullptr}; ///< graph representations of analog FASP response + TGraph* fGraphShp[NGRAPH] = {nullptr}; ///< graph representations of FASP shaper + TGraph* fGraphPhys[NGRAPH] = {nullptr}; ///< graph representations of physics digi + TLine* fGthr = nullptr; ///< graph representation of various thresholds + TCanvas* fMonitor = nullptr; ///< monitor canvas when drawing // CADENCE parameters static const Int_t fgkNDB = 53; ///< DB shaper size diff --git a/sim/detectors/trd/CbmTrdDigitizer.cxx b/sim/detectors/trd/CbmTrdDigitizer.cxx index 64786daa32001a677185a6def50efb6e88300b27..a328d179b11f3b10bdea1b7a1eaf5c8766fc18ee 100644 --- a/sim/detectors/trd/CbmTrdDigitizer.cxx +++ b/sim/detectors/trd/CbmTrdDigitizer.cxx @@ -210,7 +210,6 @@ void CbmTrdDigitizer::Exec(Option_t*) nofLatticeHits += n1; nofPointsAboveThreshold += n2; std::map<Int_t, std::pair<CbmTrdDigi*, CbmMatch*>>* digis = imod->second->GetDigiMap(); - //printf(" Digits[%d] %d\n", imod->first, digis->size()); for (std::map<Int_t, pair<CbmTrdDigi*, CbmMatch*>>::iterator it = digis->begin(); it != digis->end(); it++) { assert(it->second.second); CbmTrdDigi* digi = it->second.first; @@ -309,6 +308,8 @@ CbmTrdModuleSim* CbmTrdDigitizer::AddModule(Int_t detId) else SetUseFASP(); module = fModuleMap[moduleAddress] = new CbmTrdModuleSim2D(moduleAddress, lyId, orientation, UseFASP()); + // AB :: calibration wrt the Tof detector as the T0 simulation is still in development (14.07.2022) + module->SetTimeSysOffset(-400); Int_t rType(-1); if ((rType = geoHandler.GetRadiatorType(path)) >= 0) { if (!fRadiator2D) { // strong TRD-2D entrance window diff --git a/sim/detectors/trd/CbmTrdModuleSim.h b/sim/detectors/trd/CbmTrdModuleSim.h index 478adae7c61a2674e479e346eb703e06d647569c..777cae79e6f8d2ef775197c6bc88400a50339e3b 100644 --- a/sim/detectors/trd/CbmTrdModuleSim.h +++ b/sim/detectors/trd/CbmTrdModuleSim.h @@ -86,12 +86,14 @@ public: virtual void ResetCounters() { ; } virtual void SetMessageConverter(CbmTrdRawToDigiR* conv = NULL) = 0; virtual void SetQA(CbmTrdCheckUtil* qa = NULL) = 0; + virtual void SetTimeSysOffset(int dt) { fTimeSysOffset = dt; } protected: // definitions of MC input Int_t fPointId; ///< MC point id being processed Int_t fEventId; ///< MC event id being processed Int_t fInputId; ///< MC input file number + Int_t fTimeSysOffset = 0; ///< Time offset of TRD digis to align them with other detectors (T0, ToF) Double_t fXYZ[3]; ///< MC position of the point in module coordinates CbmTrdDigitizer* fDigitizer; //! Pointer to digitizer diff --git a/sim/detectors/trd/CbmTrdModuleSim2D.cxx b/sim/detectors/trd/CbmTrdModuleSim2D.cxx index 0e064138b21a7eebe5e4cf02d97f0f1aada23809..6196159cc56e28e6782f21964e3b0d379f373697 100644 --- a/sim/detectors/trd/CbmTrdModuleSim2D.cxx +++ b/sim/detectors/trd/CbmTrdModuleSim2D.cxx @@ -49,7 +49,7 @@ CbmTrdModuleSim2D::CbmTrdModuleSim2D(Int_t mod, Int_t ly, Int_t rot, Bool_t FASP , fTimeSlice(NULL) , fTimeOld(0) { - SetNameTitle(Form("TrdSimT%d", mod), "Simulator for triangular read-out."); + SetNameTitle(Form("TrdSim2D%d", mod), "Simulator for triangular read-out."); SetFasp(FASP); } @@ -546,7 +546,8 @@ void CbmTrdModuleSim2D::AddDigi(Int_t address, Double_t* charge, Double_t time / // make digi CbmTrdDigi *digi(NULL), *sdigi(NULL); CbmMatch* digiMatch(NULL); - digi = new CbmTrdDigi(address, charge[0], charge[1], ULong64_t(TMath::Ceil(time))); + digi = new CbmTrdDigi(address, charge[0], charge[1], + ULong64_t(TMath::Ceil(time / CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP)))); digi->SetAddressModule(fModAddress); // may not be needed in the future digiMatch = new CbmMatch(); Double_t weighting = fChmbPar->EfCkeV(charge[0] * 0.1); // save th. energy which is seen by pads; @@ -586,12 +587,11 @@ Int_t CbmTrdModuleSim2D::FlushBuffer(ULong64_t time) * Calculate timely interaction between digits which are produced either on different anode wires for the same particle or * are produced by 2 particle close by. Also take into account FASP dead time and mark such digits correspondingly */ - if (UseFasp()) { if (!fFASP) { // Build & configure FASP simulator - fFASP = new CbmTrdFASP(1000); - fFASP->SetNeighbourTrigger(1); - fFASP->SetLGminLength(31); + fFASP = new CbmTrdFASP(1000); // initialize the FASP simulator for a time window of 5*1000 [ns] + fFASP->SetNeighbourTrigger(0); // process neighbor trigger` + fFASP->SetLGminLength(31); // linear gate length in [clk] } } else { @@ -603,7 +603,10 @@ Int_t CbmTrdModuleSim2D::FlushBuffer(ULong64_t time) fTimeSlice = (CbmTimeSlice*) ioman->GetObject("TimeSlice."); } Bool_t closeTS(kFALSE); - if (fTimeSlice) closeTS = (fTimeOld - fTimeSlice->GetEndTime() - 1000) > 0.; + if (fTimeSlice) { + closeTS = (fTimeOld - fTimeSlice->GetEndTime() - 1000) > 0.; + if (!time) closeTS = true; + } fTimeOld = time; if (VERBOSE) @@ -620,58 +623,62 @@ Int_t CbmTrdModuleSim2D::FlushBuffer(ULong64_t time) cout << "\nPHYS DIGITS : \n"; DumpBuffer(); } - Int_t /*n1(0),*/ rowOld(-1), asicId, asicOld(-1); - CbmTrdDigi* digi(NULL); - CbmMatch* digiMatch(NULL); - // CbmTrdParFasp *fasp(NULL); const CbmTrdParFaspChannel *chFasp[2]={NULL}; (VF) not used + Int_t asicId, asicOld(-1); + CbmTrdDigi* digi(nullptr); + CbmMatch* digiMatch(nullptr); + CbmTrdParFasp* fasp(nullptr); + const CbmTrdParFaspChannel* chFasp[2] = {nullptr}; // write from saved buffer - Int_t localAddress(0), ndigi(0) /*, n2(0)*/; + Int_t padAddress(0), ndigi(0); std::map<Int_t, std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>>::iterator it = fBuffer.begin(); for (; it != fBuffer.end(); it++) { - localAddress = it->first; - ndigi = fBuffer[localAddress].size(); + padAddress = it->first; // pad-column address + ndigi = fBuffer[padAddress].size(); + //printf("AB :: pad_address_%d [ndigi=%d (%lu)]\n", padAddress, ndigi, it->second.size()); if (!ndigi) { //printf("FOUND saved vector empty @ %d\n", localAddress); continue; } // compute CBM address - Int_t col, row = GetPadRowCol(localAddress, col); - - // get ASIC channel calibration - Int_t asicAddress = fAsicPar->GetAsicAddress(localAddress << 1); - if (asicAddress < 0) { - LOG(debug) << GetName() << "::FlushBuffer: FASP Calibration for ro_ch " << localAddress << " in module " - << fModAddress << " missing."; + Int_t col, row = GetPadRowCol(padAddress, col); + + // query FASP calibration + int chId[] = {-1, -1}, // read-out channels on the FASP ASIC + localAddress[] = {2 * padAddress, 2 * padAddress + 1}, // local channel address in module + faspIdOnMod[] = { // fasp identifier in module according to par mapping + fAsicPar->GetAsicAddress(localAddress[0]), fAsicPar->GetAsicAddress(localAddress[1])}; + // missing read-out; remove digis + if (faspIdOnMod[0] < 0 && faspIdOnMod[1] < 0) { + LOG(debug) << GetName() << "::FlushBuffer: FASP Calibration for pad " << padAddress << " at r/c=" << row << "/" + << col << " in module " << fModAddress << " missing."; // clear physical digi for which there is no ASIC model available - for (auto iv = fBuffer[localAddress].begin(); iv != fBuffer[localAddress].end(); iv++) + for (auto iv = fBuffer[padAddress].begin(); iv != fBuffer[padAddress].end(); iv++) delete (*iv).first; - fBuffer[localAddress].clear(); - } - else { - LOG(debug2) << GetName() << "::FlushBuffer: Found FASP " << asicAddress % 1000 << " for ro_ch " << localAddress - << " in module " << fModAddress; - // fasp = (CbmTrdParFasp*)fAsicPar->GetAsicPar(asicAddress); (VF) not used - //fasp->Print(); - // chFasp[0] = fasp->GetChannel(localAddress, 0); - // chFasp[1] = fasp->GetChannel(localAddress, 1); - } - - if (rowOld < 0) { // first row - rowOld = row; - //printf("PROCESS FIRST ROW %d\n", row); - } - asicId = row * 9 + col / 8; - if (asicOld < 0) { // first row - asicOld = asicId; - //printf("PROCESS FIRST ASIC %d\n", asicId); + fBuffer[padAddress].clear(); + continue; } - if (row != rowOld || asicId != asicOld) { // next row - //printf("PROCESS ASIC[%3d] ROW[%2d]\n", asicId, row); - rowOld = row; - asicOld = asicId; + for (int ifasp(0); ifasp < 2; ifasp++) { + asicId = faspIdOnMod[ifasp]; + // check FASP individually + if (asicId < 0) { + fFASP->InitChannel(ifasp, nullptr); + continue; + } + // load relevant FASP parameters if needed + if (asicId != asicOld) { + asicOld = asicId; + + LOG(debug) << GetName() << "::FlushBuffer: Found FASP " << asicId % 1000 << " for module " << fModAddress + << " local " << localAddress[ifasp]; + fasp = (CbmTrdParFasp*) fAsicPar->GetAsicPar(asicId); + if (VERBOSE > 1) fasp->Print(); + } + chId[ifasp] = fasp->QueryChannel(localAddress[ifasp]); + chFasp[ifasp] = fasp->GetChannel(chId[ifasp]); + fFASP->InitChannel(ifasp, chFasp[ifasp], asicId, chId[ifasp]); } - fFASP->PhysToRaw(&(it->second), col, row); + fFASP->PhysToRaw(&(it->second)); } if (fFASP) fFASP->Clear("draw"); // clear buffer @@ -683,24 +690,23 @@ Int_t CbmTrdModuleSim2D::FlushBuffer(ULong64_t time) //save digitisation results Int_t n(0), nDigiLeft(0); - Double_t timeMin(-1), timeMax(0); - ULong64_t newStartTime(0); + double timeMin(-1), timeMax(0), // time [ns] + newStartTime(0); it = fBuffer.begin(); - std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>::iterator iv; while (it != fBuffer.end()) { - localAddress = it->first; - if (!fBuffer[localAddress].size()) { + padAddress = it->first; + if (!fBuffer[padAddress].size()) { it++; continue; } digiMatch = NULL; Int_t col(-1), row(-1), srow, sec; - iv = fBuffer[localAddress].begin(); - while (iv != fBuffer[localAddress].end()) { + auto iv = fBuffer[padAddress].begin(); + while (iv != fBuffer[padAddress].end()) { digi = iv->first; if (!digi->IsMasked()) { // no more digi processed - if (newStartTime == 0 || digi->GetTimeDAQ() < newStartTime) newStartTime = digi->GetTimeDAQ(); + if (digi->GetTime() < newStartTime) newStartTime = digi->GetTime(); break; } if (digi->IsFlagged(0)) { // phys digi didn't produce CS/FT update last digiMatch @@ -709,12 +715,12 @@ Int_t CbmTrdModuleSim2D::FlushBuffer(ULong64_t time) digiMatch->AddLink(iv->second->GetLink(0)); if (VERBOSE) cout << "\t" << digiMatch->ToString(); } - iv = fBuffer[localAddress].erase(iv); // remove from saved buffer + iv = fBuffer[padAddress].erase(iv); // remove from saved buffer continue; } if (col < 0) { - row = GetPadRowCol(localAddress, col); + row = GetPadRowCol(padAddress, col); sec = fDigiPar->GetSector(row, srow); if (VERBOSE) printf("CbmTrdModuleSim2D::FlushBuffer : request ly[%d] mod[%d] " @@ -736,13 +742,13 @@ Int_t CbmTrdModuleSim2D::FlushBuffer(ULong64_t time) if (r > 1) r += (noise[1] - 0.5) * CbmTrdParFaspChannel::fgkSgmCh; digi->SetCharge(t, r, dt); - fDigitizer->SendData(digi->GetTime(), digi, digiMatch); + fDigitizer->SendData(digi->GetTime() + fTimeSysOffset, digi, digiMatch); n++; - iv = fBuffer[localAddress].erase(iv); // remove from saved buffer + iv = fBuffer[padAddress].erase(iv); // remove from saved buffer } // clear address if there are no more digits available - if (fBuffer[localAddress].size()) { - nDigiLeft += fBuffer[localAddress].size(); + if (fBuffer[padAddress].size()) { + nDigiLeft += fBuffer[padAddress].size(); //printf("%d left-overs @ %d\n", fBuffer[localAddress].size(), localAddress); it++; } @@ -750,11 +756,13 @@ Int_t CbmTrdModuleSim2D::FlushBuffer(ULong64_t time) it = fBuffer.erase(it); } if (VERBOSE) - printf("CbmTrdModuleSim2D::FlushBuffer : write %d digis from %duns to " - "%duns. Digits still in buffer %d\n", + printf("CbmTrdModuleSim2D::FlushBuffer : write %d digis in [%d - " + "%d]ns. Digits still in buffer %d\n", n, TMath::Nint(timeMin), TMath::Nint(timeMax), nDigiLeft); - fFASP->SetStartTime(newStartTime); - fFASP->SetProcTime(); + if (newStartTime > 0) fFASP->SetStartTime(newStartTime); + else + fFASP->SetStartTime(fFASP->GetEndTime()); + fFASP->SetProcTime(time); //iteratively process all digi at the end of run if (time == 0 && nDigiLeft) n += FlushBuffer(); @@ -767,11 +775,11 @@ void CbmTrdModuleSim2D::DumpBuffer() const for (std::map<Int_t, std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>>::const_iterator it = fBuffer.begin(); it != fBuffer.end(); it++) { if (!it->second.size()) continue; - printf("address[%10d] n[%2d]\n", it->first, (Int_t) it->second.size()); + if (VERBOSE > 1) printf("address[%10d] n[%2d]\n", it->first, (Int_t) it->second.size()); for (std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>::const_iterator iv = it->second.cbegin(); iv != it->second.cend(); iv++) { cout << "\t" << (iv->first->IsFlagged(0) ? 'P' : 'D') << "[" << iv->first << "] " << iv->first->ToString(); - cout << "\t" << iv->second->ToString(); + if (VERBOSE > 2) cout << "\t" << iv->second->ToString(); } } }