diff --git a/core/detectors/mvd/CbmMvdSensor.cxx b/core/detectors/mvd/CbmMvdSensor.cxx index ca9c480304c3ecd80ed62f009746522bb430581a..a851f9694154d982f5fac3f4aaf155ee790a7524 100644 --- a/core/detectors/mvd/CbmMvdSensor.cxx +++ b/core/detectors/mvd/CbmMvdSensor.cxx @@ -460,7 +460,7 @@ void CbmMvdSensor::TopToPixel(Double_t* lab, Int_t& pixelNumberX, Int_t& pixelNu // ------------------------------------------------------------------------- -Int_t CbmMvdSensor::GetFrameNumber(Int_t pixelNumberY, Double_t absoluteTime) const +Int_t CbmMvdSensor::GetFrameNumber(Double_t absoluteTime, Int_t pixelNumberY) const { @@ -483,6 +483,33 @@ Int_t CbmMvdSensor::GetFrameNumber(Int_t pixelNumberY, Double_t absoluteTime) co } // ------------------------------------------------------------------------- +Double_t CbmMvdSensor::ComputeIndecatedAnalogTime(Double_t hitMCTime, Float_t diodeCharge){ + + Double_t delay = fSensorData->ComputeHitDelay(diodeCharge); + Double_t jitter= fSensorData->ComputeHitJitter(diodeCharge); + + return hitMCTime + delay+jitter; +} + +Double_t CbmMvdSensor::ComputeEndOfBusyTime(Double_t hitMCTime, Float_t diodeCharge, Int_t pixelNumberY) { + + Double_t endOfAnalogChannelDeadTime= hitMCTime + fSensorData->ComputeHitDeadTime(diodeCharge); + Int_t frameNumberAtEndOfDeadTime= GetFrameNumber(endOfAnalogChannelDeadTime,pixelNumberY); + Double_t endOfDeadTime = GetFrameEndTime (frameNumberAtEndOfDeadTime); + /* Anticipated condition for end of deadtime: + * Analog electronics must be below threshold AND HEREAFTER a new frame must have started. + * Neglected: Tail of the falling edge of the analog pulse is artificially cut. + */ + return endOfDeadTime; +} + +// ------------------------------------------------------------------------- +Double_t CbmMvdSensor::GetFrameStartTime(Int_t frameNumber) { + + return fSensorStartTime + frameNumber * fSensorData->GetIntegrationTime(); + +} + // ------------------------------------------------------------------------- Double_t CbmMvdSensor::GetReadoutTime(Double_t absoluteTime) const { diff --git a/core/detectors/mvd/CbmMvdSensor.h b/core/detectors/mvd/CbmMvdSensor.h index ed75e54250e1da53a8217bace00e9706364574e5..2b5d137469365eb1cb319aeea39eae9937f454f7 100644 --- a/core/detectors/mvd/CbmMvdSensor.h +++ b/core/detectors/mvd/CbmMvdSensor.h @@ -85,6 +85,8 @@ public: void SendInputToPlugin(Int_t nPlugin, TObject* input); + + /** Coordinate transformations **/ void LocalToTop(Double_t* local, Double_t* lab); void TopToLocal(Double_t* lab, Double_t* local); @@ -92,12 +94,18 @@ public: void PixelToLocal(Int_t pixelNumberX, Int_t pixelNumberY, Double_t* local); void PixelToTop(Int_t pixelNumberX, Int_t pixelNumberY, Double_t* lab); void TopToPixel(Double_t* lab, Int_t& pixelNumberX, Int_t& pixelNumberY); - Int_t GetFrameNumber(Int_t pixelNumberY, Double_t absoluteTime) const; + Int_t GetFrameNumber(Double_t absoluteTime, Int_t pixelNumberY =0) const; + Double_t GetFrameStartTime(Int_t frameNumber); + Double_t GetFrameEndTime(Int_t frameNumber) {return GetFrameStartTime (frameNumber+1);} Int_t GetDigiPlugin() const { return fDigiPlugin; }; Int_t GetHitPlugin() const { return fHitPlugin; }; Int_t GetClusterPlugin() const { return fClusterPlugin; } TObjArray* GetPluginArray() { return fPluginArray; } + Double_t ComputeIndecatedAnalogTime(Double_t hitMCTime, Float_t diodeCharge); + Double_t ComputeEndOfBusyTime(Double_t hitMCTime, Float_t diodeCharge, Int_t pixelNumberY); + + void SetDigiPlugin(const Int_t& nPlugin) { fDigiPlugin = nPlugin; }; void SetHitPlugin(const Int_t& nPlugin) { fHitPlugin = nPlugin; }; void SetClusterPlugin(const Int_t& nPlugin) { fClusterPlugin = nPlugin; } diff --git a/core/detectors/mvd/SensorDataSheets/CbmMvdMimosis.cxx b/core/detectors/mvd/SensorDataSheets/CbmMvdMimosis.cxx index 5d8a3594ed361caa1ff4038557471dd628bc3945..4d184f5c63b35bb2dfba48a14151496bd79485db 100644 --- a/core/detectors/mvd/SensorDataSheets/CbmMvdMimosis.cxx +++ b/core/detectors/mvd/SensorDataSheets/CbmMvdMimosis.cxx @@ -28,8 +28,8 @@ CbmMvdMimosis::CbmMvdMimosis() fPixelSignY = 1; // Direction of the pixel count Y, if true, Pixel x=0 is at // the lower corner, else at upper corner fShutterSign = 1; - fIntegrationTime = 30.0e3; // Integration time of the pixels in ns - fEpiTh = 18e-4; // Thickness of the epitaxial layer + fIntegrationTime = 5.0e3; // Integration time of the pixels in ns + fEpiTh = 25e-4; // Thickness of the epitaxial layer fChargeThreshold = 1.; fAnalogThreshold = 150; //Threshold in electrons @@ -55,12 +55,38 @@ CbmMvdMimosis::CbmMvdMimosis() fStatesPerFrame = 570; fPixelsPerBank = 64; + fSignalRiseTime = 0.1; // to be updated. + fSignalFallTime = 10; // to be updated. + fShaperNormalisationFactor=1.; // to be updated + /** Self-organizsation **/ fValidData = kTRUE; } + + +Double_t CbmMvdMimosis::ComputeHitDeadTime(Float_t charge) {return 2519.5443 * std::pow(charge,0.035720252);} //Fast settings, AC -1V + +Double_t CbmMvdMimosis::ComputeHitDelay(Float_t charge){ + + Double_t delay=47591.8471 * std::pow(charge,-0.9990384691); + Double_t delaySigma=11909.5799315438 * std::pow(charge,-1.0784955428); + return delay + fRandom.Gaus(delay,delaySigma); //models the pixel-to-pixel variation in terms of delay + +} + +Double_t CbmMvdMimosis::ComputeHitJitter (Float_t charge){ + + Double_t jitter = 194945.6385 * std::pow(charge,-1.6138338012); // Full width of jitter as function of charge + return fRandom.Uniform(-(jitter / 2.), jitter / 2.); + +} + + + + // ----- Destructor ---------------------------------------------------- CbmMvdMimosis::~CbmMvdMimosis() {} // ------------------------------------------------------------------------- diff --git a/core/detectors/mvd/SensorDataSheets/CbmMvdMimosis.h b/core/detectors/mvd/SensorDataSheets/CbmMvdMimosis.h index 6b04ba5c83404326f246199a3b11b02499e1f526..77048209b1fc205fbf67229714d7dcc99b7ea103 100644 --- a/core/detectors/mvd/SensorDataSheets/CbmMvdMimosis.h +++ b/core/detectors/mvd/SensorDataSheets/CbmMvdMimosis.h @@ -32,6 +32,14 @@ public: /** Default constructor **/ CbmMvdMimosis(); + Double_t ComputeExpireTime(Double_t hitMCTime, Double_t deadTime, Double_t endOfFrameTime); + + Double_t ComputeHitDeadTime(Float_t charge); + Double_t ComputeHitDelay(Float_t charge); + Double_t ComputeHitJitter (Float_t charge); + + TRandom fRandom; + /** Destructor **/ ~CbmMvdMimosis(); diff --git a/core/detectors/mvd/SensorDataSheets/CbmMvdSensorDataSheet.cxx b/core/detectors/mvd/SensorDataSheets/CbmMvdSensorDataSheet.cxx index 02bf56678d9afb7c78ca0b1bf8da08534586e02b..f154b16e4594af12e0d011da112b2b9d2acf9174 100644 --- a/core/detectors/mvd/SensorDataSheets/CbmMvdSensorDataSheet.cxx +++ b/core/detectors/mvd/SensorDataSheets/CbmMvdSensorDataSheet.cxx @@ -16,6 +16,59 @@ #include <ostream> // for operator<<, stringstream, basic_ostream using std::endl; +/* +<<<<<<< HEAD +======= +*/ + +// ----- Default constructor ------------------------------------------- +CbmMvdSensorDataSheet::CbmMvdSensorDataSheet() + : TNamed() + , fMimosaName("DefaulSensor") + , fPixelPitchX(18.4e-4) + , fPixelPitchY(18.4e-4) + , fNPixelsX(0) + , fNPixelsY(0) + , fNPixels(0) + , fPixelSignX(1) + , fPixelSignY(1) + , fShutterSign(1) + , fIntegrationTime(50e3) + , fEpiTh(14e-4) + , fChargeThreshold(1) + , fSignalRiseTime(nan("NotSet")) + , fSignalFallTime(nan("NotSet")) + , fShaperNormalisationFactor(1) + , fNoise(0) + , fLandauMPV(8.62131e+02) + , fLandauSigma(2.e+02) + , fLandauGain(1.56) + , fLorentzPar0(4.12073e+02) + , fLorentzPar1(0.8e+00) + , fLorentzPar2(0.) + , fAdcDynamic(150) + , fAdcOffset(0) + , fAdcBits(1) + , fAdcSteps(TMath::Power(2, fAdcBits)) + , fAdcStepSize(fAdcDynamic / fAdcSteps) + , fStatesPerBank(0) + , fStatesPerLine(0) + , fStatesPerFrame(0) + , fPixelsPerBank(0) + , fAnalogThreshold(-1) + , fValidData(kFALSE) + + + +{ +} + +// ----- Destructor ---------------------------------------------------- +CbmMvdSensorDataSheet::~CbmMvdSensorDataSheet() {} +// ------------------------------------------------------------------------- + + +//>>>>>>> ddd5fbbb (Time response added) // ----- Public method Print ------------------------------------------- void CbmMvdSensorDataSheet::Print(Option_t* /*opt*/) const { LOG(info) << ToString(); } diff --git a/core/detectors/mvd/SensorDataSheets/CbmMvdSensorDataSheet.h b/core/detectors/mvd/SensorDataSheets/CbmMvdSensorDataSheet.h index b92e80d64b83888d7b53e0952dc5043d8777ee15..bbf9610a6be3e959989a8a3663bffbd478462c3a 100644 --- a/core/detectors/mvd/SensorDataSheets/CbmMvdSensorDataSheet.h +++ b/core/detectors/mvd/SensorDataSheets/CbmMvdSensorDataSheet.h @@ -53,10 +53,24 @@ protected: // Defined according to pixelNumberX=fPixelSign * const * x Int_t fPixelSignY = 1; // Direction of the pixel count Y. // Defined according to pixelNumberY=fPixelSign * const * y +/* +<<<<<<< HEAD Int_t fShutterSign = 0; // Direction of the rolling shutter. // 1 => parallel to y-axis, -1 => anti-parallel Double_t fIntegrationTime = 50e3; // Integration time of the pixels Double_t fEpiTh = 14e-4; // Thickness of the epitaxial layer +======= +*/ + Int_t fShutterSign; // Direction of the rolling shutter. + // 1 => parallel to y-axis, -1 => anti-parallel + Double_t fIntegrationTime; // Integration time of the pixels + Double_t fEpiTh; // Thickness of the epitaxial layer + + Double_t fChargeThreshold; + Double_t fSignalRiseTime; + Double_t fSignalFallTime; + Double_t fShaperNormalisationFactor; +//>>>>>>> ddd5fbbb (Time response added) Double_t fChargeThreshold = 0.; Double_t fSignalRiseTime = nan("NotSet"); @@ -108,8 +122,17 @@ public: virtual Double_t GetIntegrationTime() { return fIntegrationTime; }; virtual Double_t GetEpiThickness() { return fEpiTh; } virtual Double_t GetNoise() { return fNoise; }; +/* +<<<<<<< HEAD virtual Double_t GetSignalRiseTime() { return fSignalRiseTime; }; virtual Double_t GetSignalFallTime() { return fSignalFallTime; }; +======= +*/ + virtual Double_t GetSignalRiseTime (){ return fSignalRiseTime;}; + virtual Double_t GetSignalFallTime (){ return fSignalFallTime;}; + virtual Float_t GetShaperNormalisationFactor(){return fShaperNormalisationFactor;} + +//>>>>>>> ddd5fbbb (Time response added) /** Description of the sensor for the digitizer **/ @@ -122,8 +145,18 @@ public: virtual Double_t GetChargeThreshold() { return fChargeThreshold; }; +/* +<<<<<<< HEAD virtual Int_t GetAnalogThreshold() { return fAnalogThreshold; }; +======= +*/ + virtual Int_t GetAnalogThreshold () {return fAnalogThreshold;}; + + virtual Double_t ComputeHitDeadTime(Float_t charge){return charge * 0.;}; // Multiplication only to suppress "variable not used" warning. + virtual Double_t ComputeHitDelay(Float_t charge){return charge * 0.;}; + virtual Double_t ComputeHitJitter (Float_t charge){return charge * 0.;}; +//>>>>>>> ddd5fbbb (Time response added) /** ADC description **/ diff --git a/macro/mvd/qa/mvd_qa3_digitize.C b/macro/mvd/qa/mvd_qa3_digitize.C index d2d8816c9cdaa6d1b2948bc058f908bf89f729ec..918cf234c44c4c6934bf7755db5f5acaa5ed2111 100644 --- a/macro/mvd/qa/mvd_qa3_digitize.C +++ b/macro/mvd/qa/mvd_qa3_digitize.C @@ -40,11 +40,14 @@ void mvd_qa3_digitize(const char* setup = "sis100_electron") Int_t nEvents = 5; // Verbosity level (0=quiet, 1=event level, 2=track level, 3=debug) - Int_t iVerbose = 0; + Int_t iVerbose = 3; FairLogger* logger = FairLogger::GetLogger(); - logger->SetLogScreenLevel("INFO"); - logger->SetLogVerbosityLevel("LOW"); + //logger->SetLogScreenLevel("INFO"); + //logger->SetLogVerbosityLevel("LOW"); + + logger->SetLogScreenLevel("DEBUG4"); + logger->SetLogVerbosityLevel("DEBUG4"); TString setupFile = inDir + "/geometry/setup/setup_" + setup + ".C"; diff --git a/sim/detectors/mvd/CbmMvdDigitizer.cxx b/sim/detectors/mvd/CbmMvdDigitizer.cxx index 97761f33460a6d8d3a5d15aaa3be7cd0f4bc8984..1fc16f3dccbe9faf737008fe8073d512ebec36b1 100644 --- a/sim/detectors/mvd/CbmMvdDigitizer.cxx +++ b/sim/detectors/mvd/CbmMvdDigitizer.cxx @@ -122,6 +122,7 @@ void CbmMvdDigitizer::Exec(Option_t* /*opt*/) fTimer.Start(); GetEventInfo(); // event number and time + cout << "- I - CbmMvdDigitizer:: Exec : Event time = " << fCurrentEventTime << endl; // Add points from BG and Delta files to the array if needed BuildEvent(); @@ -131,7 +132,7 @@ void CbmMvdDigitizer::Exec(Option_t* /*opt*/) CbmMvdPoint* point = 0; fTmpDigi->Clear(); fTmpMatch->Clear(); - + cout << fName <<"Debug: 1" << endl; if (fInputPoints->GetEntriesFast() > 0) { LOG(debug) << "//----------------------------------------//"; @@ -146,12 +147,14 @@ void CbmMvdDigitizer::Exec(Option_t* /*opt*/) fDetector->SendInputToSensorPlugin(point->GetDetectorID(), nTargetPlugin, static_cast<TObject*>(point)); } + cout << fName <<"Debug: 2" << endl; + // Execute the plugged digitizer plugin for all sensors LOG(debug) << fName << ": Execute DigitizerPlugin Nr. " << fDigiPluginNr; fDetector->Exec(fDigiPluginNr); LOG(debug) << fName << ": End Chain"; - + cout << fName <<"Debug: 3" << endl; // --- Send produced digis to DAQ //fTmpDigi = fDetector->GetOutputDigis(); //fTmpMatch = fDetector->GetOutputDigiMatchs(); @@ -186,6 +189,8 @@ void CbmMvdDigitizer::Exec(Option_t* /*opt*/) //digi1->SetMatch(match1); SendData(digi1->GetTime(), digi1, match1); nDigis++; + + cout << fName <<"Debug: 7" << endl; } diff --git a/sim/detectors/mvd/CbmMvdPixelCharge.cxx b/sim/detectors/mvd/CbmMvdPixelCharge.cxx index 611a8466c205ba130d76be395b0d9812f2c1fe49..4622f9c3d4e6e1d8cc251b3ee590e199565b0728 100644 --- a/sim/detectors/mvd/CbmMvdPixelCharge.cxx +++ b/sim/detectors/mvd/CbmMvdPixelCharge.cxx @@ -18,16 +18,19 @@ Bool_t CbmMvdPixelCharge::TestXY(Int_t channelNrX, Int_t channelNrY) // ----- Constructor with parameters ----------------------------------- CbmMvdPixelCharge::CbmMvdPixelCharge(Float_t charge, Int_t channelNrX, Int_t channelNrY, Int_t pointId, Int_t trackId, - Float_t pointPosX, Float_t pointPosY, Float_t time, Int_t frame) + Float_t pointPosX, Float_t pointPosY, Float_t time, Int_t frame, Float_t endOfBusyTime) : TObject() , fFrame(frame) - , fCharge(charge) + //, fCharge(charge) , fMaxChargeContribution(charge) , fChannelNrX(channelNrX) , fChannelNrY(channelNrY) , fTrackCharge(charge) , fPixelTime(time) + , fEndOfBusyTime(endOfBusyTime) { + fCharge.push_back(charge); + fDominatorIndex = fPointWeight.size(); } // ------- DigestCharge ----------------------------------------------------# @@ -45,7 +48,7 @@ void CbmMvdPixelCharge::DigestCharge(Float_t pointX, Float_t pointY, Double_t ti } if (chargeContr > 0.) { - fCharge = fTrackCharge; + fCharge.push_back(fTrackCharge); fTrackId.push_back(trackId); fPointId.push_back(pointId); diff --git a/sim/detectors/mvd/CbmMvdPixelCharge.h b/sim/detectors/mvd/CbmMvdPixelCharge.h index 72b92da7cbb7cffcff07fa7ef623ac4f4cf05a53..fa556264e74e567cbe7846710e88a2efd00bb13f 100644 --- a/sim/detectors/mvd/CbmMvdPixelCharge.h +++ b/sim/detectors/mvd/CbmMvdPixelCharge.h @@ -25,7 +25,7 @@ public: /** Constructor with all variables **/ CbmMvdPixelCharge(Float_t charge, Int_t channelNrX, Int_t channelNrY, Int_t hitId, Int_t trackId, Float_t pointX, - Float_t pointY, Float_t time = 0.0, Int_t frame = 0); + Float_t pointY, Float_t time = 0.0, Int_t frame = 0,Float_t endOfBusyTime=-1); virtual ~CbmMvdPixelCharge() = default; @@ -36,7 +36,7 @@ public: void AddCharge(Float_t charge) { fTrackCharge = fTrackCharge + charge; }; - Float_t GetCharge() { return fCharge; }; + Int_t GetX() { return fChannelNrX; }; Int_t GetY() { return fChannelNrY; }; Float_t GetMaxChargeContribution() { return fMaxChargeContribution; }; @@ -47,9 +47,26 @@ public: std::vector<Float_t>& GetPointX() { return fPointX; } std::vector<Float_t>& GetPointY() { return fPointY; } std::vector<Float_t>& GetPointWeight() { return fPointWeight; } +/*<<<<<<< HEAD std::vector<Double_t>& GetTime() { return fTime; } Float_t GetPixelTime() { return fPixelTime; } +======= +*/ + std::vector<Double_t>& GetTime() {return fTime;} + std::vector<Float_t>& GetCharge() { return fCharge; }; + Float_t GetPixelTime() { if (GetNContributors()!=0) {return fTime.front();} else {return -1.;};} //kept for backward compatibility + + Float_t GetEarliestHitTime(){if (GetNContributors()!=0) {return fTime.front();} else {return -1.;}}; + Float_t GetLatestHitTime(){if (GetNContributors()!=0) {return fTime.back();} else {return -1.;}}; + + Float_t GetEarliestHitCharge(){if (GetNContributors()!=0) {return fCharge.front();}else {return -1.;}}; + Float_t GetLatestHitCharge() {if (GetNContributors()!=0) {return fCharge.back();}else {return -1.;}}; + + Float_t GetEndOfBusyTime() {return fEndOfBusyTime;} + +//>>>>>>> ddd5fbbb (Time response added) Int_t GetFrame() { return fFrame; } + void SetEndOfBusyTime(Double_t endOfBusyTime) {fEndOfBusyTime=endOfBusyTime;} virtual void Clear(Option_t* = "") {}; @@ -57,6 +74,8 @@ public: private: Int_t fFrame = {-1}; +/* +<<<<<<< HEAD Float_t fCharge = {-1.}; Float_t fMaxChargeContribution = {0.}; Float_t fDominatingPointX = {-1.}; @@ -76,6 +95,31 @@ private: std::vector<Float_t> fPointY = {}; std::vector<Double_t> fTime = {}; std::vector<CbmLink> fLink = {}; +======= +*/ + //Float_t fCharge = {-1.}; + Float_t fMaxChargeContribution = {0.}; + Float_t fDominatingPointX = {-1.}; + Float_t fDominatingPointY = {-1.}; + Short_t fContributors = {0}; + Int_t fChannelNrX = {0}; + Int_t fChannelNrY = {0}; + Float_t fTrackCharge = {0.}; + Int_t fDominatorTrackId = {-1}; + Int_t fDominatorPointId = {-1}; + Short_t fDominatorIndex = {0}; + Float_t fPixelTime = {-1.}; + Double_t fEndOfBusyTime; + + std::vector<Int_t> fTrackId = {}; + std::vector<Int_t> fPointId = {}; + std::vector<Float_t> fPointWeight = {}; + std::vector<Float_t> fPointX = {}; + std::vector<Float_t> fPointY = {}; + std::vector<Double_t> fTime = {}; + std::vector<Float_t> fCharge = {}; + std::vector<CbmLink> fLink = {}; +//>>>>>>> ddd5fbbb (Time response added) ClassDef(CbmMvdPixelCharge, 1); }; diff --git a/sim/detectors/mvd/plugins/tasks/CbmMvdSensorDigitizerTask.cxx b/sim/detectors/mvd/plugins/tasks/CbmMvdSensorDigitizerTask.cxx index ab8e62a8c7b429c8d92dcc60d7207eb857ca31b9..df930f6ce9f8171af11584cb9be05b526c97adb0 100644 --- a/sim/detectors/mvd/plugins/tasks/CbmMvdSensorDigitizerTask.cxx +++ b/sim/detectors/mvd/plugins/tasks/CbmMvdSensorDigitizerTask.cxx @@ -120,7 +120,7 @@ CbmMvdSensorDigitizerTask::CbmMvdSensorDigitizerTask() , fPixelScanAccelerator(nullptr) , fChargeMap() , fChargeMapIt() - , fsensorDataSheet(nullptr) + , fSensorDataSheet(nullptr) , fMode(0) , fSigmaX(0.0005) , fSigmaY(0.0005) @@ -223,7 +223,7 @@ CbmMvdSensorDigitizerTask::CbmMvdSensorDigitizerTask(Int_t iMode) , fPixelScanAccelerator(nullptr) , fChargeMap() , fChargeMapIt() - , fsensorDataSheet(nullptr) + , fSensorDataSheet(nullptr) , fMode(iMode) , fSigmaX(0.0005) , fSigmaY(0.0005) @@ -344,6 +344,7 @@ InitStatus CbmMvdSensorDigitizerTask::ReadSensorInformation() CbmMvdSensorDataSheet* sensorData; sensorData = fSensor->GetDataSheet(); if (!sensorData) { return kERROR; } + fSensorDataSheet=sensorData; fPixelSizeX = sensorData->GetPixelPitchX(); fPixelSizeY = sensorData->GetPixelPitchY(); @@ -368,7 +369,7 @@ InitStatus CbmMvdSensorDigitizerTask::ReadSensorInformation() return kSUCCESS; } - +// // ----------------------------------------------------------------------------- void CbmMvdSensorDigitizerTask::SetInputArray(TClonesArray* inputStream) @@ -413,6 +414,9 @@ void CbmMvdSensorDigitizerTask::Exec() fOutputBuffer->Clear("C"); fDigis->Clear("C"); fDigiMatch->Clear("C"); + + + if (fInputPoints->GetEntriesFast() > 0) { for (Int_t iPoint = 0; iPoint < fInputPoints->GetEntriesFast(); iPoint++) { @@ -475,9 +479,23 @@ void CbmMvdSensorDigitizerTask::Exec() else { //LOG(debug) << "charge under threshold, digi rejected"; } + /* Clean pixel charges, which do not reach threshold. + * This avoids that the first entries in the pixelCharge objects contain information about hits, which are insufficient + * for creating a hit. Having first entries below threshold complicates defining the hit time. + * Draw back: The charge of tracks from different events does not add. + */ +/* + ProduceDigis(); + CleanPixelChargeList(); + + + + + + if (fproduceNoise) ProduceNoise(); + +*/ } - //LOG(debug) << nDigis <<" new Digis at on Sensor " << fSensor->GetSensorNr() << " from " << fInputPoints->GetEntriesFast()<< " McPoints"; - } else { //LOG(debug)<< "No input found on Sensor " << fSensor->GetSensorNr() << " from " << fInputPoints->GetEntriesFast()<< " McPoints"; @@ -491,6 +509,11 @@ void CbmMvdSensorDigitizerTask::Exec() } // end of exec // ------------------------------------------------------------------------- +void CbmMvdSensorDigitizerTask::ProduceDigis(){ + + Int_t nDigis = 0; + CbmMvdPixelCharge* pixel; + GetEventInfo(fInputNr, fEventNr, fEventTime); Int_t CbmMvdSensorDigitizerTask::GetPixelCharge(CbmMvdPixelCharge* /*myPixel*/, Double_t readoutTime) @@ -519,6 +542,142 @@ Int_t CbmMvdSensorDigitizerTask::GetPixelCharge(CbmMvdPixelCharge* /*myPixel*/, * (1 - TMath::Exp(-(readoutTime - hitTime) / pixelSignalFallTime)); //exponential signal fall of the analog charge +/* ======= + + for (Int_t i = 0; i < fPixelCharge->GetEntriesFast(); i++) { + pixel = (CbmMvdPixelCharge*) fPixelCharge->At(i); + + if (pixel->GetEndOfBusyTime()>fEventTime){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 + */ + + Int_t numberOfContributorCausingHit=CheckForHit(pixel); + + if (numberOfContributorCausingHit==-1){ + fPixelCharge->RemoveAt(i); // pixel did not fire and busy time has expired. Forget about it. + continue; + } + + Int_t diodeCharge= GetPixelCharge(pixel, pixel->GetTime()[numberOfContributorCausingHit]); + // Compute charge causing the hitCharge + + Double_t analogHitTime= fSensor->ComputeIndecatedAnalogTime(pixel->GetTime()[numberOfContributorCausingHit], diodeCharge); + + // Write Digis + + nDigis = fDigis->GetEntriesFast(); + + new ((*fDigis)[nDigis]) CbmMvdDigi(fSensor->GetSensorNr(), pixel->GetX(), pixel->GetY(), diodeCharge, + fPixelSizeX, fPixelSizeY, fEventTime+analogHitTime, fSensor->GetFrameNumber(fEventTime+analogHitTime, pixel->GetY())); + + + new ((*fOutputBuffer)[nDigis]) + CbmMvdDigi(fSensor->GetSensorNr(), pixel->GetX(), pixel->GetY(), diodeCharge, + fPixelSizeX, fPixelSizeY, fEventTime+analogHitTime, fSensor->GetFrameNumber(fEventTime+analogHitTime, pixel->GetY())); + + // 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. + + new ((*fDigiMatch)[nDigis]) CbmMatch(); + CbmMatch* match = (CbmMatch*) fDigiMatch->At(nDigis); + for (Int_t iLink = 0; iLink < pixel->GetNContributors(); iLink++) { + if (pixel->GetTrackID()[iLink] > -1) + match->AddLink((Double_t) pixel->GetPointWeight()[iLink], pixel->GetPointID()[iLink], fEventNr, fInputNr); + else + match->AddLink((Double_t) pixel->GetPointWeight()[iLink], pixel->GetPointID()[iLink]); + } + } + +} + + + + +// ------------------------------------------------------------------------- +void CbmMvdSensorDigitizerTask::CleanPixelChargeList(){ + + // So far a code fragment + + /* + Float_t sensorAnalogThreshold=fSensorDataSheet->GetAnalogThreshold (); + + for (Int_t i=0; i<fPixelCharge->GetEntriesFast();i++){ + CbmMvdPixelCharge* pixel= (CbmMvdPixelCharge*) fPixelCharge->At(i); + + if(pixel->GetEarliestHitCharge()> sensorAnalogThreshold) {continue;} //pixel has fired, nothing to be done + + else if (pixel->GetNContributors()>1) {// pixel was hit multiple times within the event, check if charge sums up within an event. + Float_t summedCharge=0.; + + for(Int_t iContributor; iContributor<pixel->GetNContributors(); iContributor++){ + + if(pixel->GetTime[iContributor] < (pixel->GetEarliestHitTime() + fSensorDataSheet->GetSignalRiseTime ()) {summedCharge = summedCharge + pixel->fCharge[iContributor]} + else{break;} //Sum up charges impinging within the integration time. If going beyond the integration time, skip. + } + + if (summedCharge<sensorAnalogThreshold) {continue;} //pixel fired due to combined charge of hits. Nothing to be done. + // to be done -> Think about events and signal rise time. + + if (pixel->GetNContributors()==1 && pixel->GetEarliestHitCharge()<sensorAnalogThreshold) { //pixel was hit by one particle and did not fire. + fPixelCharge->RemoveAt(i); // pixel is considered as cleared after the event + } + + */ + +} + +// ------------------------------------------------------------------------- + +Int_t CbmMvdSensorDigitizerTask::CheckForHit(CbmMvdPixelCharge* pixel){ + + /* Intended to spot the number of contributors to the pixel charge, which fired the pixel. + * The number of the contributor is returned + */ + if (!fSensorDataSheet) {cout << " - E - CbmMvdSensorDigitizerTask::CheckForHit : Missing Datasheet." << endl;} + if (pixel->GetEarliestHitCharge() > fSensorDataSheet->GetAnalogThreshold()) {return 0;} + /* The pixel fired immedeately, easiest case.else ... + * Else: Check if a later impact fired the pixel + */ + + Int_t nContributors=pixel->GetNContributors(); + Int_t charge=0; + + // Get charge and time arrays from pixel (both stl::vector) + + for(Int_t i=1; i<nContributors; i++){ + + // compute charge at the time of the impinging of particle i accounting for pixel history. + // pixel->GetCharge[i] stands for the charge of the particle under study, GetPixelCharge wraps up the history. + + charge=pixel->GetCharge()[i]+GetPixelCharge(pixel, pixel->GetTime()[i]); + if(charge>fSensorDataSheet->GetAnalogThreshold()){return i;} + } + + return -1; +}; + +// ------------------------------------------------------------------------- + +Int_t CbmMvdSensorDigitizerTask::GetPixelCharge(CbmMvdPixelCharge* myPixel, Double_t readoutTime) { +/* Adds the accumulated charge of the pixel until readout time. + * Accounts for a signal rise and signal fall time (clearance) of the analog amplifier. + */ + + Int_t pixelCharge=0; + Double_t pixelSignalRiseTime=fSensorDataSheet->GetSignalRiseTime(); + Double_t pixelSignalFallTime=fSensorDataSheet->GetSignalFallTime(); + Int_t nHits=myPixel->GetNContributors(); + + for(Int_t hitNr=0; hitNr<nHits; hitNr++){ + Int_t hitTime=myPixel->GetTime()[hitNr]; + if (hitTime>readoutTime){break;} + Int_t hitCharge=myPixel->GetCharge()[hitNr]; + + + pixelCharge=pixelCharge + hitCharge * (1- TMath::Exp(-(readoutTime-hitTime)/pixelSignalRiseTime)); //exponential signal rise of the analog charge + pixelCharge=pixelCharge - hitCharge * (1- TMath::Exp(-(readoutTime-hitTime)/pixelSignalFallTime)); //exponential signal fall of the analog charge + pixelCharge=pixelCharge * fSensorDataSheet->GetShaperNormalisationFactor(); } return pixelCharge; @@ -538,6 +697,17 @@ Bool_t CbmMvdSensorDigitizerTask::GetSignalAboveThreshold(CbmMvdPixelCharge* myP return (GetPixelCharge(myPixel, readoutTime) > fsensorDataSheet->GetAnalogThreshold()); } +/* +Bool_t CbmMvdSensorDigitizerTask::GetPixelIsBusy(CbmMvdPixelCharge* myPixel, Double_t readoutTime) {} +*/ + + + + + + + + // ------------------------------------------------------------------------------ @@ -954,6 +1124,26 @@ void CbmMvdSensorDigitizerTask::ProducePixelCharge(CbmMvdPoint* point) pixelCharge->DigestCharge(((float) (point->GetX() + point->GetXOut()) / 2), ((float) (point->GetY() + point->GetYOut()) / 2), fEventTime + point->GetTime(), point->GetPointId(), point->GetTrackID()); +/* ======= + ((float) (point->GetY() + point->GetYOut()) / 2), fEventTime + point->GetTime(),point->GetPointId(), + point->GetTrackID()); + + // So far, the charge created by this MC-hit in a given pixel was added up in the Pixel charge objects. + // Digest charge closes the summing and adds the MC information related to the hit. The MC information will be forwarded to the digi links later. + // Digest charge also stores the history of the pixel to process possible dead times of the sensor. + + Float_t latestHitCharge=pixelCharge->GetLatestHitCharge(); + Double_t endOfBusyTime= fSensor->ComputeEndOfBusyTime(fEventTime + point->GetTime(), latestHitCharge, pixelCharge->GetY()); + if (endOfBusyTime > pixelCharge->GetEndOfBusyTime()) {pixel->SetEndOfBusyTime(endOfBusyTime);} + + /* Next, the pixelChargeObject is combined with a time information on the endOfBusyTime of the pixelChargeObject. + * This end of busy is reached once the related channel is ready for receiving new hit information. + * In case a hit arrives until then, the information is recorded and the end-of-busy is postponed in accordance with the new hit. + * Note: This endOfBusyTime is not equal to the analog dead time of the channel but accounts also for the frame readout. + */ + + +*/ } else { LOG(warning) << "Warning working on broken pixel "; diff --git a/sim/detectors/mvd/plugins/tasks/CbmMvdSensorDigitizerTask.h b/sim/detectors/mvd/plugins/tasks/CbmMvdSensorDigitizerTask.h index 27c4f6d5e12297b531c283cc21b1793fd36779b4..3c0396a90875f9962022e3b64056fe35e84fbc2a 100644 --- a/sim/detectors/mvd/plugins/tasks/CbmMvdSensorDigitizerTask.h +++ b/sim/detectors/mvd/plugins/tasks/CbmMvdSensorDigitizerTask.h @@ -77,6 +77,13 @@ public: void ProduceNoise(); Bool_t GetSignalAboveThreshold(CbmMvdPixelCharge* myPixel, Double_t readoutTime); Int_t GetPixelCharge(CbmMvdPixelCharge* myPixel, Double_t readoutTime); +/* + void ProduceDigis(); + void CleanPixelChargeList(); + // Bool_t GetSignalAboveThreshold (CbmMvdPixelCharge* myPixel, Double_t readoutTime); + Int_t GetPixelCharge(CbmMvdPixelCharge* myPixel, Double_t readoutTime); + Int_t CheckForHit(CbmMvdPixelCharge* pixel); +*/ void SetProduceNoise() { fproduceNoise = kTRUE; }; @@ -177,7 +184,7 @@ public: private: - CbmMvdSensorDataSheet* fsensorDataSheet; + CbmMvdSensorDataSheet* fSensorDataSheet; /** Hit producer mode (0 = MAPS, 1 = Ideal) **/ Int_t fMode;