From c59a55aeacaddaf1aef582ce311febb240a4a4eb Mon Sep 17 00:00:00 2001 From: Florian Uhlig <f.uhlig@gsi.de> Date: Mon, 13 Nov 2023 17:08:45 +0100 Subject: [PATCH] Fix generation of MvdDigi in event based mode Flush the internal buffer after each event when running in event based mode. This creates digis for all channels even if the dead time of the channel is not yet reached. All digis are written into the current timeslice. Flushing the internal buffer after the last event when running in time based mode to avoid losing data. Create and send digi matches only if required. Should fix a memory leak. Add LOG information in the init about run mode. Remove obsolete code. --- sim/detectors/mvd/CbmMvdDigitizer.cxx | 57 +++----- .../tasks/CbmMvdSensorDigitizerTask.cxx | 132 ++++++++++-------- .../plugins/tasks/CbmMvdSensorDigitizerTask.h | 12 ++ 3 files changed, 109 insertions(+), 92 deletions(-) diff --git a/sim/detectors/mvd/CbmMvdDigitizer.cxx b/sim/detectors/mvd/CbmMvdDigitizer.cxx index 3cbb300d9f..05fe019b8f 100644 --- a/sim/detectors/mvd/CbmMvdDigitizer.cxx +++ b/sim/detectors/mvd/CbmMvdDigitizer.cxx @@ -69,8 +69,8 @@ CbmMvdDigitizer::CbmMvdDigitizer() , fDeltaManager(nullptr) { - fTmpDigi = new TClonesArray("CbmMvdDigi", 1000); - fTmpMatch = new TClonesArray("CbmMatch", 1000); + fTmpDigi = new TClonesArray("CbmMvdDigi", 1000); + fTmpMatch = new TClonesArray("CbmMatch", 1000); fHistoArray = 0; } // ------------------------------------------------------------------------- @@ -105,8 +105,8 @@ CbmMvdDigitizer::CbmMvdDigitizer(const char* name, Int_t iMode, Int_t /*iVerbose , fDeltaManager(nullptr) { - fTmpDigi = new TClonesArray("CbmMvdDigi", 1000); - fTmpMatch = new TClonesArray("CbmMatch", 1000); + fTmpDigi = new TClonesArray("CbmMvdDigi", 1000); + fTmpMatch = new TClonesArray("CbmMatch", 1000); fHistoArray = 0; } // ------------------------------------------------------------------------- @@ -189,44 +189,21 @@ void CbmMvdDigitizer::Exec(Option_t* /*opt*/) CbmMvdDigi* digi1 = new CbmMvdDigi(*digi); assert(digi1); fDigiVect.push_back(digi1); - // // Create new digi in the output digi outputfrom the one in the internal TClonesArray - // fDigiVect.emplace_back(new CbmMvdDigi(*(static_cast<CbmMvdDigi*>(fTmpDigi->At(index))))); - - // CbmMatch match{*(dynamic_cast<CbmMatch*>(fTmpMatch->At(index)))}; - // CbmMatch* match1 = new CbmMatch(match); - CbmMatch* match = dynamic_cast<CbmMatch*>(fTmpMatch->At(index)); - CbmMatch* match1 = new CbmMatch(*match); - fMatchVect.push_back(match1); - // // Create new match in the output match vector from the one in the internal TClonesArray - // fMatchVect.emplace_back(new CbmMatch(*(static_cast<CbmMatch*>(fTmpMatch->At(index))))); - - //digi1->SetMatch(match1); - SendData(digi1->GetTime(), digi1, match1); + + if (fCreateMatches) { + CbmMatch* match = dynamic_cast<CbmMatch*>(fTmpMatch->At(index)); + CbmMatch* match1 = new CbmMatch(*match); + fMatchVect.push_back(match1); + SendData(digi1->GetTime(), digi1, match1); + } + else { + SendData(digi1->GetTime(), digi1); + } nDigis++; // cout << fName <<"Debug: 7" << endl; } - - /* - for (Int_t index = 0; index < fTmpDigi->GetEntriesFast(); index++) { - - LOG(info) << "Size: " << fTmpDigi->GetEntriesFast() << ", " - << fTmpDigi->GetEntries(); - - CbmMvdDigi* digi = dynamic_cast<CbmMvdDigi*>(fTmpDigi->Remove(fTmpDigi->At(index))); - digi->Print(); - fDigiVect.push_back(digi); - - CbmMatch* match = dynamic_cast<CbmMatch*>(fTmpMatch->Remove(fTmpMatch->At(index))); - match->Print(); - fMatchVect.push_back(match); - - digi->SetMatch(match); - SendDigi(digi); - nDigis++; - } -*/ // TODO: (VF) There seem to be no entries in the match array, nor matches // attached to the digi object LOG(debug) << fName << ": Sent " << nDigis << " digis to DAQ"; @@ -312,6 +289,11 @@ InitStatus CbmMvdDigitizer::Init() } + if (fEventMode) { LOG(info) << GetName() << ": Running in event mode"; } + else { + LOG(info) << GetName() << ": Running in time based mode"; + } + // Add the digitizer plugin to all sensors std::map<int, CbmMvdSensor*>& sensorMap = fDetector->GetSensorMap(); UInt_t plugincount = fDetector->GetPluginCount(); @@ -319,6 +301,7 @@ InitStatus CbmMvdDigitizer::Init() for (auto itr = sensorMap.begin(); itr != sensorMap.end(); itr++) { CbmMvdSensorDigitizerTask* digiTask = new CbmMvdSensorDigitizerTask(); if (fNoiseSensors) digiTask->SetProduceNoise(); + if (fEventMode) { digiTask->SetEventMode(); } itr->second->AddPlugin(digiTask); itr->second->SetDigiPlugin(plugincount); } diff --git a/sim/detectors/mvd/plugins/tasks/CbmMvdSensorDigitizerTask.cxx b/sim/detectors/mvd/plugins/tasks/CbmMvdSensorDigitizerTask.cxx index 7de80248ce..174e629f8c 100644 --- a/sim/detectors/mvd/plugins/tasks/CbmMvdSensorDigitizerTask.cxx +++ b/sim/detectors/mvd/plugins/tasks/CbmMvdSensorDigitizerTask.cxx @@ -480,8 +480,6 @@ void CbmMvdSensorDigitizerTask::Exec() // ------------------------------------------------------------------------- void CbmMvdSensorDigitizerTask::ProduceDigis() { - pair<Int_t, Int_t> thispoint; - Int_t nDigis = 0; CbmMvdPixelCharge* pixel; GetEventInfo(fInputNr, fEventNr, fEventTime); @@ -495,81 +493,93 @@ void CbmMvdSensorDigitizerTask::ProduceDigis() // LOG(debug)<< " CbmMvdSensorDigitizerTask::ProduceDigis() - PixelChargeTime = " << pixel->GetEndOfBusyTime(); // LOG(debug)<< " CbmMvdSensorDigitizerTask::ProduceDigis() - EventTime = " << fEventTime; - if (pixel->GetEndOfBusyTime() - > fEventTime) { //LOG(debug)<< " CbmMvdSensorDigitizerTask::ProduceDigis() - will care for this later"; - continue; + // When in event based mode create the digi even if busy time isn't + // reached + if (!fEventMode) { + if (pixel->GetEndOfBusyTime() > fEventTime) { + //LOG(debug)<< " CbmMvdSensorDigitizerTask::ProduceDigis() - will care for this later"; + continue; + } } - /* The digi is only generated once the busy-time has passed. This is an easy way to avoid double counting of hits. - * If no digi is formed, the initial hit information remains stored in the CbmMvdPixelCharge - */ - // LOG(debug)<< " CbmMvdSensorDigitizerTask::ProduceDigis() - Working on PixelCharge " << i << " Address = " << pixel; - Int_t numberOfContributorCausingHit = CheckForHit(pixel); - LOG(debug) << " CbmMvdSensorDigitizerTask::ProduceDigis() - PixelCharge >" << pixel->GetEarliestHitCharge(); + FlushBuffer(pixel, i); + } + // LOG(debug)<< "CbmMvdSensorDigitizerTask::ProduceDigis() - NumberOfPixelCharge before compress = " << fPixelCharge->GetEntriesFast(); - if (numberOfContributorCausingHit == -1) { // pixel did not fire and busy time has expired. Forget about it. - thispoint = std::make_pair(pixel->GetX(), pixel->GetY()); - fChargeMap.erase(thispoint); // Delete entry in the fChargeMap (points from coordinate to the pixel - fPixelCharge->RemoveAt(i); // Delete the pixelCharge object - LOG(debug) << " CbmMvdSensorDigitizerTask::ProduceDigis() - PixelCharge " << i << " deleted (to few charge)."; + fPixelCharge->Compress(); + // LOG(debug)<< "CbmMvdSensorDigitizerTask::ProduceDigis() - NumberOfPixelCharge after compress = " << fPixelCharge->GetEntriesFast(); +} - continue; - } +void CbmMvdSensorDigitizerTask::FlushBuffer(CbmMvdPixelCharge* pixel, Int_t i) +{ - // LOG(debug)<< " CbmMvdSensorDigitizerTask::ProduceDigis() - Starting to create Digi from PixelCharge " << i; + pair<Int_t, Int_t> thispoint; + Int_t nDigis = 0; + /* The digi is only generated once the busy-time has passed. This is an easy way to avoid double counting of hits. + * If no digi is formed, the initial hit information remains stored in the CbmMvdPixelCharge + */ + // LOG(debug)<< " CbmMvdSensorDigitizerTask::ProduceDigis() - Working on PixelCharge " << i << " Address = " << pixel; + Int_t numberOfContributorCausingHit = CheckForHit(pixel); - Int_t diodeCharge = pixel->GetCharge()[numberOfContributorCausingHit] - + GetPixelCharge(pixel, pixel->GetTime()[numberOfContributorCausingHit]); - // Compute charge causing the hit. Note: GetPixelCharge does not account for the charge caused by the last hit if handed over the time of the last hit as the - // signal in the shaper did not yet build up. Therefore, this charge is added explicitely. + LOG(debug) << " CbmMvdSensorDigitizerTask::ProduceDigis() - PixelCharge >" << pixel->GetEarliestHitCharge(); - LOG(debug) << " --- CbmMvdSensorDigitizerTask::ProduceDigis() - DiodeCharge0 = " << pixel->GetCharge()[0]; - LOG(debug) << " --- CbmMvdSensorDigitizerTask::ProduceDigis() - Full diode charge = " << diodeCharge; + if (numberOfContributorCausingHit == -1) { // pixel did not fire and busy time has expired. Forget about it. + thispoint = std::make_pair(pixel->GetX(), pixel->GetY()); + fChargeMap.erase(thispoint); // Delete entry in the fChargeMap (points from coordinate to the pixel + fPixelCharge->RemoveAt(i); // Delete the pixelCharge object + LOG(debug) << " CbmMvdSensorDigitizerTask::ProduceDigis() - PixelCharge " << i << " deleted (to few charge)."; - Double_t analogHitTime = - fSensor->ComputeIndecatedAnalogTime(pixel->GetTime()[numberOfContributorCausingHit], diodeCharge); - // Write Digis + return; + } - nDigis = fDigis->GetEntriesFast(); + // LOG(debug)<< " CbmMvdSensorDigitizerTask::ProduceDigis() - Starting to create Digi from PixelCharge " << i; - new ((*fDigis)[nDigis]) - CbmMvdDigi(fSensor->GetSensorNr(), pixel->GetX(), pixel->GetY(), diodeCharge, fPixelSizeX, fPixelSizeY, - fEventTime + analogHitTime, fSensor->GetFrameNumber(fEventTime + analogHitTime, pixel->GetY())); + Int_t diodeCharge = pixel->GetCharge()[numberOfContributorCausingHit] + + GetPixelCharge(pixel, pixel->GetTime()[numberOfContributorCausingHit]); + // Compute charge causing the hit. Note: GetPixelCharge does not account for the charge caused by the last hit if handed over the time of the last hit as the + // signal in the shaper did not yet build up. Therefore, this charge is added explicitely. + LOG(debug) << " --- CbmMvdSensorDigitizerTask::ProduceDigis() - DiodeCharge0 = " << pixel->GetCharge()[0]; + LOG(debug) << " --- CbmMvdSensorDigitizerTask::ProduceDigis() - Full diode charge = " << diodeCharge; - new ((*fOutputBuffer)[nDigis]) - CbmMvdDigi(fSensor->GetSensorNr(), pixel->GetX(), pixel->GetY(), diodeCharge, fPixelSizeX, fPixelSizeY, - fEventTime + analogHitTime, fSensor->GetFrameNumber(fEventTime + analogHitTime, pixel->GetY())); + Double_t analogHitTime = + fSensor->ComputeIndecatedAnalogTime(pixel->GetTime()[numberOfContributorCausingHit], diodeCharge); - // To Do: Time and pixel charge are now in an array. Write function testing if the pixel is busy at a given time. - // Write function which computes the status of the pixel at the time of readout and which cell one has to readout. + // Write Digis - new ((*fDigiMatch)[nDigis]) CbmMatch(); - CbmMatch* match = (CbmMatch*) fDigiMatch->At(nDigis); - for (Int_t iLink = 0; iLink < pixel->GetNContributors(); iLink++) { + nDigis = fDigis->GetEntriesFast(); - if (pixel->GetTrackID()[iLink] > -2) { - match->AddLink((Double_t) pixel->GetPointWeight()[iLink], pixel->GetPointID()[iLink], fEventNr, fInputNr); - std::cout << "CbmMvdSensorDigitizerTask::ProduceDigis() : PointID= " << pixel->GetPointID()[iLink] << std::endl; - } + new ((*fDigis)[nDigis]) + CbmMvdDigi(fSensor->GetSensorNr(), pixel->GetX(), pixel->GetY(), diodeCharge, fPixelSizeX, fPixelSizeY, + fEventTime + analogHitTime, fSensor->GetFrameNumber(fEventTime + analogHitTime, pixel->GetY())); - else - match->AddLink((Double_t) pixel->GetPointWeight()[iLink], pixel->GetPointID()[iLink]); - } - thispoint = std::make_pair(pixel->GetX(), pixel->GetY()); - fChargeMap.erase(thispoint); // Delete entry in the fChargeMap (points from coordinate to the pixel - fPixelCharge->RemoveAt(i); // Delete the pixelCharge object - LOG(debug) << " CbmMvdSensorDigitizerTask::ProduceDigis() - PixelCharge " << i << " deleted (digi produced)."; - } + new ((*fOutputBuffer)[nDigis]) + CbmMvdDigi(fSensor->GetSensorNr(), pixel->GetX(), pixel->GetY(), diodeCharge, fPixelSizeX, fPixelSizeY, + fEventTime + analogHitTime, fSensor->GetFrameNumber(fEventTime + analogHitTime, pixel->GetY())); - // LOG(debug)<< "CbmMvdSensorDigitizerTask::ProduceDigis() - NumberOfPixelCharge before compress = " << fPixelCharge->GetEntriesFast(); + // To Do: Time and pixel charge are now in an array. Write function testing if the pixel is busy at a given time. + // Write function which computes the status of the pixel at the time of readout and which cell one has to readout. - fPixelCharge->Compress(); + new ((*fDigiMatch)[nDigis]) CbmMatch(); + CbmMatch* match = (CbmMatch*) fDigiMatch->At(nDigis); + for (Int_t iLink = 0; iLink < pixel->GetNContributors(); iLink++) { - // LOG(debug)<< "CbmMvdSensorDigitizerTask::ProduceDigis() - NumberOfPixelCharge after compress = " << fPixelCharge->GetEntriesFast(); + if (pixel->GetTrackID()[iLink] > -2) { + match->AddLink((Double_t) pixel->GetPointWeight()[iLink], pixel->GetPointID()[iLink], fEventNr, fInputNr); + // std::cout << "CbmMvdSensorDigitizerTask::ProduceDigis() : PointID= " << pixel->GetPointID()[iLink] << std::endl; + } + + else + match->AddLink((Double_t) pixel->GetPointWeight()[iLink], pixel->GetPointID()[iLink]); + } + + thispoint = std::make_pair(pixel->GetX(), pixel->GetY()); + fChargeMap.erase(thispoint); // Delete entry in the fChargeMap (points from coordinate to the pixel + fPixelCharge->RemoveAt(i); // Delete the pixelCharge object + LOG(debug) << " CbmMvdSensorDigitizerTask::ProduceDigis() - PixelCharge " << i << " deleted (digi produced)."; } @@ -1293,6 +1303,18 @@ void CbmMvdSensorDigitizerTask::ReInit(CbmMvdSensor* sensor) void CbmMvdSensorDigitizerTask::Finish() { + // In time base mode flush the buffers after the last event + if (!fEventMode) { + + GetEventInfo(fInputNr, fEventNr, fEventTime); + LOG(debug) << "CbmMvdSensorDigitizerTask::Finish() - NumberOfPixelCharge = " << fPixelCharge->GetEntriesFast(); + + for (Int_t i = 0; i < fPixelCharge->GetEntriesFast(); i++) { + CbmMvdPixelCharge* pixel = (CbmMvdPixelCharge*) fPixelCharge->At(i); + + FlushBuffer(pixel, i); + } + } // PrintParameters(); diff --git a/sim/detectors/mvd/plugins/tasks/CbmMvdSensorDigitizerTask.h b/sim/detectors/mvd/plugins/tasks/CbmMvdSensorDigitizerTask.h index e6e813fc1e..3f606067c3 100644 --- a/sim/detectors/mvd/plugins/tasks/CbmMvdSensorDigitizerTask.h +++ b/sim/detectors/mvd/plugins/tasks/CbmMvdSensorDigitizerTask.h @@ -87,6 +87,12 @@ public: void SetProduceNoise() { fproduceNoise = kTRUE; }; + /** Switch from time based mode to evnt based mode + The difference is that in the event based mode the internal + buffer is flushed after each input event + **/ + void SetEventMode() { fEventMode = kTRUE; } + /** Modifiers **/ void SetSegmentLength(Double_t segmentLength) { fSegmentLength = segmentLength; } void SetDiffusionCoef(Double_t diffCoeff) { fDiffusionCoefficient = diffCoeff; } @@ -176,6 +182,8 @@ public: Bool_t fproduceNoise; + Bool_t fEventMode {kFALSE}; + std::vector<CbmMvdPixelCharge*> fPixelChargeShort; TObjArray* fPixelScanAccelerator; @@ -278,6 +286,10 @@ private: **/ Int_t GetMvdGeometry(); + /** Create MvdDigi and MvdDigiMatch object and store + ** them in the output buffers + **/ + void FlushBuffer(CbmMvdPixelCharge* pixel, Int_t i); TH1F* h_trackLength; TH1F* h_numSegments; -- GitLab