#include #include namespace RAT { PingCratesTriggerSignals::PingCratesTriggerSignals() : Processor("PingCratesTriggerSignals"){ } void PingCratesTriggerSignals::BeginOfRun(DS::Run&){ DBLinkPtr fDB = DB::Get()->GetLink("PING_CRATES_CONTROL"); fBaselineSamples = fDB->GetI("baseline_samples"); fVFraction = fDB->GetD("vfraction"); fCalType = fDB->GetD("caltype"); } Processor::Result PingCratesTriggerSignals::DSEvent(DS::Run&, DS::Entry& ds){ for(size_t iEV = 0; iEV < ds.GetEVCount(); iEV++){ Event(ds, ds.GetEV(iEV)); } return OK; } Processor::Result PingCratesTriggerSignals::Event(DS::Entry& ds, DS::EV& ev){ // Check the trigger type is a pedestal // Need to do this because all events have header info if(ev.GetTrigType() & DU::TrigBits::GetMask("Pedestal")){ if(ds.HeaderInfoExists()){ const DS::HeaderInfo& header = ds.GetHeaderInfo(); if(header.ECAHeaderExists()){ // Header information for the ping crates const DS::ECAHeader& eped = header.GetECAHeader(); int fPattern = eped.GetPatternID(); if(eped.GetCalType() == fCalType){ try{ const RAT::DS::Digitiser& digitiser = ev.GetDigitiser(); std::vector ids = digitiser.GetIDs(); for(size_t iWaveform = 0; iWaveform < ids.size(); iWaveform++){ if(!digitiser.ExistsWaveform(ids[iWaveform])) continue; int id = ids[iWaveform]; std::vector waveform = digitiser.GetWaveform(id); // Convert to type to use with CAENBits int type = id - (id%10); // Check N100 and N20 signals on the CAEN if(type == RAT::NH100Lo || type == RAT::NH20Lo){ double baseline = Baseline(waveform, fBaselineSamples); double max_adc = Maximum(waveform, baseline); int nsamples = NSamples(waveform, baseline, max_adc*fVFraction); int rise = RiseTime(waveform, baseline, max_adc); int fall = FallTime(waveform, baseline, max_adc); // Push information about CAEN traces fID.push_back(fPattern); fType.push_back(id); fBaseline.push_back(baseline); fPeak.push_back(max_adc); fSamples.push_back(nsamples); fRise.push_back(rise); fFall.push_back(fall); } } } // Catch missing CAEN data catch(...){ detail << "Missing CAEN Data" << endl; } } } } } return OK; } void PingCratesTriggerSignals::EndOfRun( DS::Run& run ){ RAT::DBTable PCtable("PING_CRATES_RUN_LEVEL"); PCtable.SetI("version",1); PCtable.SetIndex(""); PCtable.SetRunRange(run.GetRunID(), run.GetRunID()); PCtable.SetPassNumber(-1); PCtable.SetIArray("id", fID); PCtable.SetIArray("caen_type", fType); PCtable.SetDArray("baseline", fBaseline); PCtable.SetDArray("max", fPeak); PCtable.SetDArray("samples", fSamples); PCtable.SetIArray("rise", fRise); PCtable.SetIArray("fall", fFall); PCtable.SaveAs("PingCratesData.ratdb"); } // Calculates the maximum of the waveform double PingCratesTriggerSignals::Maximum(std::vector waveform, double baseline){ double max_adc = 4096; for(size_t iSample = 0; iSample < waveform.size(); iSample++){ double adc_counts = waveform.at(iSample) - baseline; // Pulses are downward going if(adc_counts < max_adc){ max_adc = adc_counts; } } return max_adc; } // Calculates the baseline of the CAEN signal using the beginning of the // CAEN window, with baseline_samples number of samples double PingCratesTriggerSignals::Baseline(std::vector waveform, size_t fBaselineSamples){ double baseline = 0; // If baseline samples is set too large, use the entire waveform if(fBaselineSamples > waveform.size()){ fBaselineSamples = waveform.size(); } for(size_t iSample = 0; iSample < fBaselineSamples; iSample++){ baseline += waveform.at(iSample); } baseline /= fBaselineSamples; return baseline; } // NSamples with adc values smaller than a fraction of the peak of the waveform int PingCratesTriggerSignals::NSamples(std::vector waveform, double baseline, double fraction_peak){ int nsamples = 0; for(size_t iSample = 0; iSample < waveform.size(); iSample++){ double adc = waveform.at(iSample) - baseline; // Pulses are downward going if(adc < fraction_peak){ nsamples++; } } return nsamples; } // NSamples in the rise time, calculated by looking at the number of // samples with ADC counts between 20% of the maximum and 80% of the maximum int PingCratesTriggerSignals::RiseTime(std::vector waveform, double baseline, int max_adc){ int riseTimeCount = 0; for(size_t iSample = 0; iSample < waveform.size(); iSample++){ // Counts bins in the rise time for downward going pulses if((waveform.at(iSample) - baseline) < max_adc*0.2 && (waveform.at(iSample) - baseline) > max_adc){ riseTimeCount++; } if((waveform.at(iSample) - baseline) <= max_adc*0.8){ break; } } return riseTimeCount; } // NSamples in the fall time, calculated by looking at the number of // samples with ADC counts between 80% of the maximum and 20% of the maximum. int PingCratesTriggerSignals::FallTime(std::vector waveform, double baseline, int max_adc){ int fallTimeCount = 0; int maxSample = 0; for(size_t iSample = 0; iSample < waveform.size(); iSample++){ if((waveform.at(iSample) - baseline) <= max_adc){ maxSample = iSample; // sample correspond to maximum break; } } for(size_t iSample = maxSample; iSample < waveform.size(); iSample++){ // Counts bins in the fall time for downward going pulses if((waveform.at(iSample) - baseline) < max_adc*0.2 && (waveform.at(iSample) - baseline) > max_adc*0.8){ fallTimeCount++; } if((waveform.at(iSample) - baseline) >= max_adc*0.2){ break; } } return fallTimeCount; } }