LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
RawDataDrawer.cxx
Go to the documentation of this file.
1 
54 #include <algorithm> // std::fill(), std::find_if(), ...
55 #include <cmath> // std::abs(), ...
56 #include <cstddef> // std::ptrdiff_t
57 #include <limits> // std::numeric_limits<>
58 #include <memory> // std::unique_ptr()
59 #include <tuple>
60 #include <type_traits> // std::add_const_t<>, ...
61 #include <typeinfo> // to use typeid()
62 #include <utility> // std::move()
63 
64 #include "TBox.h"
65 #include "TFrame.h"
66 #include "TH1F.h"
67 #include "TVirtualPad.h"
68 
72 #include "lardataalg/Utilities/StatCollector.h" // lar::util::MinMaxCollector<>
74 #include "lardataobj/RawData/raw.h"
75 #include "lareventdisplay/EventDisplay/ChangeTrackers.h" // util::PlaneDataChangeTracker_t
79 #include "larevt/CalibrationDBI/Interface/ChannelStatusProvider.h"
80 #include "larevt/CalibrationDBI/Interface/ChannelStatusService.h"
81 #include "larevt/CalibrationDBI/Interface/DetPedestalProvider.h"
82 #include "larevt/CalibrationDBI/Interface/DetPedestalService.h"
84 
91 #include "cetlib_except/demangle.h"
93 
94 namespace {
95  template <typename Stream, typename T>
96  void PrintRange(Stream&& out, std::string header, lar::util::MinMaxCollector<T> const& range)
97  {
98  out << header << ": " << range.min() << " -- " << range.max() << " ("
99  << (range.has_data() ? "valid" : "invalid") << ")";
100  } // PrintRange()
101 } // local namespace
102 
103 // internal use classes declaration;
104 // it can't live in the header because it uses C++11/14
105 namespace details {
107  template <typename T>
109  public:
110  using value_type = T;
111  using const_value_type = std::add_const_t<value_type>;
112  using reference = std::add_lvalue_reference_t<value_type>;
113  using const_reference = std::add_lvalue_reference_t<const_value_type>;
114  using pointer = std::add_pointer_t<value_type>;
115  using const_pointer = std::add_pointer_t<const_value_type>;
116 
119 
122  const_reference operator*() const { return *pData; }
123  reference operator*() { return *pData; }
124 
125  const_pointer operator->() const { return pData; }
126  pointer operator->() { return pData; }
128 
130  operator bool() const { return hasData(); }
131 
133  bool operator!() const { return !hasData(); }
134 
136  bool hasData() const { return bool(pData); }
137 
139  bool owned() const { return bOwned && hasData(); }
140 
142  void SetData(pointer data, bool owned)
143  {
144  Clear();
145  bOwned = owned;
146  pData = data;
147  }
149  void AcquireData(pointer data) { SetData(data, true); }
151  void PointToData(pointer data) { SetData(data, false); }
153  void PointToData(reference data) { SetData(&data, false); }
155  void StealData(std::remove_const_t<T>&& data) { AcquireData(new T(std::move(data))); }
157  void NewData(T const& data) { AcquireData(new T(data)); }
159  void Clear()
160  {
161  if (bOwned) delete pData;
162  pData = nullptr;
163  bOwned = false;
164  } // Clear()
165 
166  protected:
167  bool bOwned = false;
168  pointer pData = nullptr;
169  }; // class PointerToData_t<>
170 }
171 
172 namespace evd {
173  namespace details {
174 
177  public:
179  art::Ptr<raw::RawDigit> DigitPtr() const { return digit; }
180 
182  raw::RawDigit const& Digit() const { return *digit; }
183 
185  raw::ChannelID_t Channel() const { return digit ? digit->Channel() : raw::InvalidChannelID; }
186 
188  short MinCharge() const { return SampleInfo().min_charge; }
189 
191  short MaxCharge() const { return SampleInfo().max_charge; }
192 
194  // short AverageCharge() const { return SampleInfo().average_charge; }
195 
197  raw::RawDigit::ADCvector_t const& Data() const;
198 
200  void Fill(art::Ptr<raw::RawDigit> const& src);
201 
203  void Clear();
204 
206  template <typename Stream>
207  void Dump(Stream&& out) const;
208 
209  private:
210  struct SampleInfo_t {
211  short min_charge = std::numeric_limits<short>::max();
212  short max_charge = std::numeric_limits<short>::max();
213  };
214 
216 
218  mutable ::details::PointerToData_t<raw::RawDigit::ADCvector_t const> data;
219 
221  mutable std::unique_ptr<SampleInfo_t> sample_info;
222 
224  void UncompressData() const;
225 
227  void CollectSampleInfo() const;
228 
230  SampleInfo_t const& SampleInfo() const;
231 
232  }; // class RawDigitInfo_t
233 
236  public:
238  std::vector<RawDigitInfo_t> const& Digits() const { return digits; }
239 
241  RawDigitInfo_t const* FindChannel(raw::ChannelID_t channel) const;
242 
244  size_t MaxSamples() const { return max_samples; }
245 
247  bool empty() const { return digits.empty(); }
248 
250  void Clear();
251 
253  void Refill(art::Handle<std::vector<raw::RawDigit>>& rdcol);
254 
256  void Invalidate();
257 
260  bool Update(art::Event const& evt, CacheID_t const& new_timestamp);
261 
263  template <typename Stream>
264  void Dump(Stream&& out) const;
265 
266  private:
268 
269  bool bUpToDate = false;
270  std::vector<raw::RawDigit> const* digits = nullptr;
271 
272  BoolWithUpToDateMetadata() = default;
273  BoolWithUpToDateMetadata(bool uptodate, std::vector<raw::RawDigit> const* newdigits)
274  : bUpToDate(uptodate), digits(newdigits)
275  {}
276 
277  operator bool() const { return bUpToDate; }
278  }; // struct BoolWithUpToDateMetadata
279 
280  std::vector<RawDigitInfo_t> digits;
281 
283 
284  size_t max_samples = 0;
285 
287  BoolWithUpToDateMetadata CheckUpToDate(CacheID_t const& ts,
288  art::Event const* evt = nullptr) const;
289 
290  static std::vector<raw::RawDigit> const* ReadProduct(art::Event const& evt,
291  art::InputTag label);
292 
293  }; // struct RawDigitCacheDataClass
294 
296  RawDigitCacheDataClass const& cache)
297  {
298  return cache.Digits().cbegin();
299  }
301  RawDigitCacheDataClass const& cache)
302  {
303  return cache.Digits().cend();
304  }
305 
308  public:
310  GridAxisClass() { Init(0, 0., 0.); }
311 
313  GridAxisClass(size_t nDiv, float new_min, float new_max) { Init(nDiv, new_min, new_max); }
314 
316  std::ptrdiff_t GetCell(float coord) const;
318  std::ptrdiff_t operator()(float coord) const { return GetCell(coord); }
320 
322  bool hasCell(std::ptrdiff_t iCell) const
323  {
324  return (iCell >= 0) && ((size_t)iCell < NCells());
325  }
326 
328  bool hasCoord(float coord) const { return (coord >= Min()) && (coord < Max()); }
329 
331  float Min() const { return min; }
333  float Max() const { return max; }
335 
337  float Length() const { return max - min; }
338 
340  size_t NCells() const { return n_cells; }
341 
343  bool isEmpty() const { return max == min; }
344 
346  float CellSize() const { return cell_size; }
347 
349  float LowerEdge(std::ptrdiff_t iCell) const { return Min() + CellSize() * iCell; }
350 
352  float UpperEdge(std::ptrdiff_t iCell) const { return LowerEdge(iCell + 1); }
353 
355  bool Init(size_t nDiv, float new_min, float new_max);
356 
358  bool SetLimits(float new_min, float new_max);
359 
362  bool SetMinCellSize(float min_size);
363 
366  bool SetMaxCellSize(float max_size);
367 
370  bool SetCellSizeBoundary(float min_size, float max_size)
371  {
372  return SetMinCellSize(min_size) || SetMaxCellSize(max_size);
373  }
374 
375  template <typename Stream>
376  void Dump(Stream&& out) const;
377 
378  private:
379  size_t n_cells;
380  float min, max;
381 
382  float cell_size;
383 
384  }; // GridAxisClass
385 
388  public:
390  CellGridClass() : wire_axis(), tdc_axis() {}
391 
393  CellGridClass(unsigned int nWires, unsigned int nTDC);
394 
396  CellGridClass(float min_wire,
397  float max_wire,
398  unsigned int nWires,
399  float min_tdc,
400  float max_tdc,
401  unsigned int nTDC);
402 
404  size_t NCells() const { return wire_axis.NCells() * tdc_axis.NCells(); }
405 
407  GridAxisClass const& WireAxis() const { return wire_axis; }
408 
410  GridAxisClass const& TDCAxis() const { return tdc_axis; }
411 
413  std::ptrdiff_t GetCell(float wire, float tick) const;
414 
416  std::tuple<float, float, float, float> GetCellBox(std::ptrdiff_t iCell) const;
417 
419  bool hasWire(float wire) const { return wire_axis.hasCoord(wire); }
421  bool hasWire(int wire) const { return hasWire((float)wire); }
423 
425  bool hasTick(float tick) const { return tdc_axis.hasCoord(tick); }
427  bool hasTick(int tick) const { return hasTick((float)tick); }
429 
432  template <typename CONT>
433  bool Add(CONT& cont, float wire, float tick, typename CONT::value_type v)
434  {
435  std::ptrdiff_t cell = GetCell(wire, tick);
436  if (cell < 0) return false;
437  cont[(size_t)cell] += v;
438  return true;
439  } // Add()
440 
444  void SetWireRange(unsigned int nWires) { SetWireRange(0., (float)nWires, nWires); }
445 
447  void SetWireRange(float min_wire, float max_wire) { wire_axis.SetLimits(min_wire, max_wire); }
448 
450  void SetWireRange(float min_wire, float max_wire, unsigned int nWires)
451  {
452  wire_axis.Init(nWires, min_wire, max_wire);
453  }
454 
456  void SetWireRange(float min_wire, float max_wire, unsigned int nWires, float min_size)
457  {
458  wire_axis.Init(nWires, min_wire, max_wire);
459  wire_axis.SetMinCellSize(min_size);
460  }
461 
463  void SetTDCRange(unsigned int nTDC) { SetTDCRange(0., (float)nTDC, nTDC); }
464 
466  void SetTDCRange(float min_tdc, float max_tdc, unsigned int nTDC)
467  {
468  tdc_axis.Init(nTDC, min_tdc, max_tdc);
469  }
470 
472  void SetTDCRange(float min_tdc, float max_tdc) { tdc_axis.SetLimits(min_tdc, max_tdc); }
473 
475  void SetTDCRange(float min_tdc, float max_tdc, unsigned int nTDC, float min_size)
476  {
477  tdc_axis.Init(nTDC, min_tdc, max_tdc);
478  tdc_axis.SetMinCellSize(min_size);
479  }
480 
482 
484  bool SetMinWireCellSize(float min_size) { return wire_axis.SetMinCellSize(min_size); }
485 
487  bool SetMinTDCCellSize(float min_size) { return tdc_axis.SetMinCellSize(min_size); }
488 
490  template <typename Stream>
491  void Dump(Stream&& out) const;
492 
493  private:
496  }; // CellGridClass
497 
498  //--------------------------------------------------------------------------
501  public:
503  : detProp{dp}
504  , wirePitch{art::ServiceHandle<geo::WireReadout const>()->Get().Plane(pid).WirePitch()}
505  , electronsToADC{dp.ElectronsToADC()}
506  {}
507 
509  double operator()(float adc) const
510  {
511  if (adc < 0.) return 0.;
512  double const dQdX = adc / wirePitch / electronsToADC;
513  return detProp.BirksCorrection(dQdX);
514  }
515 
516  private:
518  double wirePitch;
519  double electronsToADC;
520 
521  }; // ADCCorrectorClass
522  //--------------------------------------------------------------------------
523  } // namespace details
524 } // namespace evd
525 
526 namespace evd {
527 
528  // empty vector
529  std::vector<raw::RawDigit> const RawDataDrawer::EmptyRawDigits;
530 
531  //......................................................................
532  RawDataDrawer::RawDataDrawer()
533  : digit_cache(new details::RawDigitCacheDataClass)
534  , fStartTick(0)
535  , fTicks(2048)
536  , fCacheID(new details::CacheID_t)
537  , fDrawingRange(new details::CellGridClass)
538  {
540  geo::TPCID tpcid(rawopt->fCryostat, rawopt->fTPC);
541 
542  fStartTick = rawopt->fStartTick;
543  fTicks = rawopt->fTicks;
544 
545  // set the list of bad channels in this detector
546  auto const& wireReadoutGeom = art::ServiceHandle<geo::WireReadout const>()->Get();
547  unsigned int nplanes = wireReadoutGeom.Nplanes(tpcid);
548  fWireMin.resize(nplanes, -1);
549  fWireMax.resize(nplanes, -1);
550  fTimeMin.resize(nplanes, -1);
551  fTimeMax.resize(nplanes, -1);
552  fRawCharge.resize(nplanes, 0);
553  fConvertedCharge.resize(nplanes, 0);
554  }
555 
556  //......................................................................
558  {
559  delete digit_cache;
560  delete fDrawingRange;
561  delete fCacheID;
562  }
563 
564  //......................................................................
565  void RawDataDrawer::SetDrawingLimits(float low_wire,
566  float high_wire,
567  float low_tdc,
568  float high_tdc)
569  {
570  MF_LOG_DEBUG("RawDataDrawer") << __func__ << "() setting drawing range as wires ( " << low_wire
571  << " - " << high_wire << " ), ticks ( " << low_tdc << " - "
572  << high_tdc << " )";
573 
574  // we need to set the minimum cell size to 1, otherwise some cell will not
575  // cover any wire/tick and they will be always empty
576  if (PadResolution) {
577  // TODO implement support for swapping axes here
578  unsigned int wire_pixels = PadResolution.width;
579  unsigned int tdc_pixels = PadResolution.height;
580  fDrawingRange->SetWireRange(low_wire, high_wire, wire_pixels, 1.F);
581  fDrawingRange->SetTDCRange(low_tdc, high_tdc, tdc_pixels, 1.F);
582  }
583  else {
584  MF_LOG_DEBUG("RawDataDrawer") << "Pad size not available -- using existing cell size";
585  fDrawingRange->SetWireRange(low_wire, high_wire);
587  fDrawingRange->SetTDCRange(low_tdc, high_tdc);
589  }
590 
591  } // RawDataDrawer::SetDrawingLimits()
592 
594  {
595  SetDrawingLimits(fWireMin[plane], fWireMax[plane], fTimeMin[plane], fTimeMax[plane]);
596  } // RawDataDrawer::SetDrawingLimitsFromRoI()
597 
598  void RawDataDrawer::ExtractRange(TVirtualPad* pPad,
599  std::vector<double> const* zoom /* = nullptr */)
600  {
601  mf::LogDebug log("RawDataDrawer");
602  log << "ExtractRange() on pad '" << pPad->GetName() << "'";
603 
604  TFrame const* pFrame = pPad->GetFrame();
605  if (pFrame) {
606  // these coordinates are used to find the actual extent of pad in pixels
607  double low_wire = pFrame->GetX1(), high_wire = pFrame->GetX2();
608  double low_tdc = pFrame->GetY1(), high_tdc = pFrame->GetY2();
609  double const wire_pixels = pPad->XtoAbsPixel(high_wire) - pPad->XtoAbsPixel(low_wire);
610  double const tdc_pixels = -(pPad->YtoAbsPixel(high_tdc) - pPad->YtoAbsPixel(low_tdc));
611 
612  PadResolution.width = (unsigned int)wire_pixels;
613  PadResolution.height = (unsigned int)tdc_pixels;
614 
615  log << "\n frame window is " << PadResolution.width << "x" << PadResolution.height
616  << " pixel big and";
617  // those coordinates also are a (unreliable) estimation of the zoom;
618  // if we have a better one, let's use it
619  // (this does not change the size of the window in terms of pixels)
620  if (zoom) {
621  log << ", from external source,";
622  low_wire = (*zoom)[0];
623  high_wire = (*zoom)[1];
624  low_tdc = (*zoom)[2];
625  high_tdc = (*zoom)[3];
626  }
627 
628  log << " spans wires " << low_wire << "-" << high_wire << " and TDC " << low_tdc << "-"
629  << high_tdc;
630 
631  // TODO support swapping axes here:
632  // if (rawopt.fAxisOrientation < 1) { normal ; } else { swapped; }
633 
634  fDrawingRange->SetWireRange(low_wire, high_wire, (unsigned int)wire_pixels, 1.0);
635  fDrawingRange->SetTDCRange(low_tdc, high_tdc, (unsigned int)tdc_pixels, 1.0);
636  }
637  else {
638  // keep the old frame (if any)
639  log << "\n no frame!";
640  }
641 
642  } // RawDataDrawer::ExtractRange()
643 
644  //......................................................................
646  public:
647  OperationBaseClass(geo::PlaneID const& pid, RawDataDrawer* data_drawer = nullptr)
648  : pRawDataDrawer(data_drawer), planeID(pid)
649  {}
650 
651  virtual ~OperationBaseClass() = default;
652 
653  virtual bool Initialize() { return true; }
654 
655  virtual bool ProcessWire(geo::WireID const&) { return true; }
656  virtual bool ProcessTick(size_t) { return true; }
657 
658  virtual bool Operate(geo::WireID const& wireID, size_t tick, float adc) = 0;
659 
660  virtual bool Finish() { return true; }
661 
662  virtual std::string Name() const { return cet::demangle_symbol(typeid(*this).name()); }
663 
664  bool operator()(geo::WireID const& wireID, size_t tick, float adc)
665  {
666  return Operate(wireID, tick, adc);
667  }
668 
669  geo::PlaneID const& PlaneID() const { return planeID; }
670  RawDataDrawer* RawDataDrawerPtr() const { return pRawDataDrawer; }
671 
672  protected:
673  RawDataDrawer* pRawDataDrawer = nullptr;
674 
675  private:
677  }; // class RawDataDrawer::OperationBaseClass
678 
679  //......................................................................
681  std::vector<std::unique_ptr<RawDataDrawer::OperationBaseClass>> operations;
682 
683  public:
684  ManyOperations(geo::PlaneID const& pid, RawDataDrawer* data_drawer = nullptr)
685  : OperationBaseClass(pid, data_drawer)
686  {}
687 
688  bool Initialize() override
689  {
690  bool bAllOk = true;
691  for (std::unique_ptr<OperationBaseClass> const& op : operations)
692  if (!op->Initialize()) bAllOk = false;
693  return bAllOk;
694  }
695 
696  bool ProcessWire(geo::WireID const& wireID) override
697  {
698  for (std::unique_ptr<OperationBaseClass> const& op : operations)
699  if (op->ProcessWire(wireID)) return true;
700  return false;
701  }
702  bool ProcessTick(size_t tick) override
703  {
704  for (std::unique_ptr<OperationBaseClass> const& op : operations)
705  if (op->ProcessTick(tick)) return true;
706  return false;
707  }
708 
709  bool Operate(geo::WireID const& wireID, size_t tick, float adc) override
710  {
711  for (std::unique_ptr<OperationBaseClass> const& op : operations)
712  if (!op->Operate(wireID, tick, adc)) return false;
713  return true;
714  }
715 
716  bool Finish() override
717  {
718  bool bAllOk = true;
719  for (std::unique_ptr<OperationBaseClass> const& op : operations)
720  if (!op->Finish()) bAllOk = false;
721  return bAllOk;
722  }
723 
724  std::string Name() const override
725  {
726  std::string msg = cet::demangle_symbol(typeid(*this).name());
727  msg += (" [running " + std::to_string(operations.size()) + " operations:");
728  for (auto const& op : operations) { // it's unique_ptr<OperationBaseClass>
729  if (op)
730  msg += " " + op->Name();
731  else
732  msg += " <invalid>";
733  }
734  return msg + " ]";
735  }
736 
737  OperationBaseClass* Operator(size_t iOp) { return operations.at(iOp).get(); }
738  OperationBaseClass const* Operator(size_t iOp) const { return operations.at(iOp).get(); }
739 
740  void AddOperation(std::unique_ptr<OperationBaseClass> new_op)
741  {
742  if (!new_op) return;
743  if (PlaneID() != new_op->PlaneID()) {
745  << "RawDataDrawer::ManyOperations(): trying to run operations on "
746  << std::string(PlaneID()) << " and " << std::string(new_op->PlaneID())
747  << " at the same time";
748  }
749  if (RawDataDrawerPtr() && (RawDataDrawerPtr() != new_op->RawDataDrawerPtr())) {
751  << "RawDataDrawer::ManyOperations(): "
752  "trying to run operations on different RawDataDrawer"; // possible, but very unlikely
753  }
754  operations.emplace_back(std::move(new_op));
755  }
756 
757  }; // class RawDataDrawer::ManyOperations
758 
759  //......................................................................
761  {
762  geo::PlaneID const& pid = operation->PlaneID();
764 
765  if (digit_cache->empty()) return true;
766 
767  MF_LOG_DEBUG("RawDataDrawer") << "RawDataDrawer::RunOperation() running " << operation->Name();
768 
769  // if we have an initialization failure, return false immediately;
770  // but it's way better if the failure throws an exception
771  if (!operation->Initialize()) return false;
772 
773  lariov::ChannelStatusProvider const& channelStatus =
775 
776  //get pedestal conditions
777  const lariov::DetPedestalProvider& pedestalRetrievalAlg =
778  *(lar::providerFrom<lariov::DetPedestalService>());
779 
780  auto const& wireReadoutGeom = art::ServiceHandle<geo::WireReadout const>()->Get();
781 
782  // loop over all the channels/raw digits
783  for (evd::details::RawDigitInfo_t const& digit_info : *digit_cache) {
784  raw::RawDigit const& hit = digit_info.Digit();
785  raw::ChannelID_t const channel = hit.Channel();
786 
787  // skip the bad channels
788  if (!channelStatus.IsPresent(channel)) continue;
789  // The following test is meant to be temporary until the "correct" solution is implemented
790  if (!ProcessChannelWithStatus(channelStatus.Status(channel))) continue;
791 
792  // we have a list of all channels, but we are drawing only on one plane;
793  // most of the channels will not contribute to this plane,
794  // and before we start querying databases, unpacking data etc.
795  // we want to know it's for something
796 
797  std::vector<geo::WireID> WireIDs = wireReadoutGeom.ChannelToWire(channel);
798 
799  bool bDrawChannel = false;
800  for (geo::WireID const& wireID : WireIDs) {
801  if (wireID.planeID() != pid) continue; // not us!
802  bDrawChannel = true;
803  break;
804  } // for wires
805  if (!bDrawChannel) continue;
806 
807  // collect bad channels
808  bool const bGood = rawopt->fSeeBadChannels || !channelStatus.IsBad(channel);
809 
810  // nothing else to be done if the channel is not good:
811  // cells are marked bad by default and if any good channel falls in any of
812  // them, they become good
813  if (!bGood) continue;
814 
815  // at this point we know we have to process this channel
816  raw::RawDigit::ADCvector_t const& uncompressed = digit_info.Data();
817 
818  // recover the pedestal
819  float pedestal = 0;
820  if (rawopt->fPedestalOption == 0) { pedestal = pedestalRetrievalAlg.PedMean(channel); }
821  else if (rawopt->fPedestalOption == 1) {
822  pedestal = hit.GetPedestal();
823  }
824  else if (rawopt->fPedestalOption == 2) {
825  pedestal = 0;
826  }
827  else {
828  mf::LogWarning("RawDataDrawer")
829  << " PedestalOption is not understood: " << rawopt->fPedestalOption
830  << ". Pedestals not subtracted.";
831  }
832 
833  // loop over all the wires that are covered by this channel;
834  // without knowing better, we have to draw into all of them
835  for (geo::WireID const& wireID : WireIDs) {
836  // check that the plane and tpc are the correct ones to draw
837  if (wireID.planeID() != pid) continue; // not us!
838 
839  // do we have anything to do with this wire?
840  if (!operation->ProcessWire(wireID)) continue;
841 
842  // get an iterator over the adc values
843  // accumulate all the data of this wire in our "cells"
844  size_t const max_tick = std::min({uncompressed.size(), size_t(fStartTick + fTicks)});
845 
846  for (size_t iTick = fStartTick; iTick < max_tick; ++iTick) {
847 
848  // do we have anything to do with this wire?
849  if (!operation->ProcessTick(iTick)) continue;
850 
851  float const adc = uncompressed[iTick] - pedestal;
852  //std::cout << "adc, pedestal: " << adc << " " << pedestal << std::endl;
853 
854  if (!operation->Operate(wireID, iTick, adc)) return false;
855 
856  } // if good
857  } // for wires
858  } // for channels
859 
860  return operation->Finish();
861  } // ChannelLooper()
862 
863  //......................................................................
865  public:
867  geo::PlaneID const& pid,
868  RawDataDrawer* dataDrawer,
869  evdb::View2D* new_view)
870  : OperationBaseClass(pid, dataDrawer)
871  , view(new_view)
872  , rawCharge(0.)
873  , convertedCharge(0.)
874  , drawingRange(*(dataDrawer->fDrawingRange))
875  , ADCCorrector(detProp, PlaneID())
876  {}
877 
878  bool Initialize() override
879  {
881 
882  // set up the size of the grid to be visualized;
883  // the information on the size has to be already there:
884  // caller should have user ExtractRange(), or similar, first.
885  // set the minimum cell in ticks to at least match fTicksPerPoint
886  drawingRange.SetMinTDCCellSize((float)rawopt->fTicksPerPoint);
887  // also set the minimum wire cell size to 1,
888  // otherwise there will be cells represented by no wire.
889  drawingRange.SetMinWireCellSize(1.F);
890  boxInfo.clear();
891  boxInfo.resize(drawingRange.NCells());
892  return true;
893  }
894 
895  bool ProcessWire(geo::WireID const& wire) override
896  {
897  return drawingRange.hasWire((int)wire.Wire);
898  }
899 
900  bool ProcessTick(size_t tick) override { return drawingRange.hasTick((float)tick); }
901 
902  bool Operate(geo::WireID const& wireID, size_t tick, float adc) override
903  {
904  geo::WireID::WireID_t const wire = wireID.Wire;
905  std::ptrdiff_t cell = drawingRange.GetCell(wire, tick);
906  if (cell < 0) return true;
907 
908  BoxInfo_t& info = boxInfo[cell];
909  info.good = true; // if in range, we mark this cell as good
910 
911  rawCharge += adc;
912  convertedCharge += ADCCorrector(adc);
913 
914  // draw maximum digit in the cell
915  if (std::abs(info.adc) <= std::abs(adc)) info.adc = adc;
916 
917  return true;
918  }
919 
920  bool Finish() override
921  {
922  // write the information back
923  geo::PlaneID::PlaneID_t const plane = PlaneID().Plane;
924  RawDataDrawerPtr()->fRawCharge[plane] = rawCharge;
925  RawDataDrawerPtr()->fConvertedCharge[plane] = convertedCharge;
926 
927  // the cell size might have changed because of minimum size settings
928  // from configuration (see Initialize())
929  *(RawDataDrawerPtr()->fDrawingRange) = drawingRange;
930 
931  // complete the drawing
932  RawDataDrawerPtr()->QueueDrawingBoxes(view, PlaneID(), boxInfo);
933 
934  return true;
935  }
936 
937  private:
939 
940  double rawCharge = 0., convertedCharge = 0.;
942  std::vector<BoxInfo_t> boxInfo;
944  }; // class RawDataDrawer::BoxDrawer
945 
947  geo::PlaneID const& pid,
948  std::vector<BoxInfo_t> const& BoxInfo)
949  {
950  //
951  // All the information is now collected in BoxInfo.
952  // Make boxes out of it.
953  //
955 
956  MF_LOG_DEBUG("RawDataDrawer") << "Filling " << BoxInfo.size() << " boxes to be rendered";
957 
958  // drawing options:
959  float const MinSignal = rawopt.fMinSignal;
960  bool const bScaleDigitsByCharge = rawopt.fScaleDigitsByCharge;
961 
963 
964  auto const& wireReadoutGeom = art::ServiceHandle<geo::WireReadout const>()->Get();
965 
966  geo::SigType_t const sigType = wireReadoutGeom.SignalType(pid);
967  evdb::ColorScale const& ColorSet = cst->RawQ(sigType);
968  size_t const nBoxes = BoxInfo.size();
969  unsigned int nDrawnBoxes = 0;
970  for (size_t iBox = 0; iBox < nBoxes; ++iBox) {
971  BoxInfo_t const& info = BoxInfo[iBox];
972 
973  // too little signal, don't bother drawing
974  if (info.good && (std::abs(info.adc) < MinSignal)) continue;
975 
976  // skip the bad cells
977  if (!info.good) continue;
978 
979  // box color, proportional to the ADC count
980  int const color = ColorSet.GetColor(info.adc);
981 
982  // scale factor, proportional to ADC count (optional)
983  constexpr float q0 = 1000.;
984  float const sf = bScaleDigitsByCharge ? std::min(std::sqrt((float)info.adc / q0), 1.0F) : 1.;
985 
986  // coordinates of the cell box
987  float min_wire, max_wire, min_tick, max_tick;
988  std::tie(min_wire, min_tick, max_wire, max_tick) = fDrawingRange->GetCellBox(iBox);
989  if (sf != 1.) { // need to shrink the box
990  float const nsf = 1. - sf; // negation of scale factor
991  float const half_box_wires = (max_wire - min_wire) / 2.,
992  half_box_ticks = (max_tick - min_tick) / 2.;
993 
994  // shrink the box:
995  min_wire += nsf * half_box_wires;
996  max_wire -= nsf * half_box_wires;
997  min_tick += nsf * half_box_ticks;
998  max_tick -= nsf * half_box_ticks;
999  } // if scaling
1000 
1001  // allocate the box on the view;
1002  // the order of the coordinates depends on the orientation
1003  TBox* pBox;
1004  if (rawopt.fAxisOrientation < 1)
1005  pBox = &(view->AddBox(min_wire, min_tick, max_wire, max_tick));
1006  else
1007  pBox = &(view->AddBox(min_tick, min_wire, max_tick, max_wire));
1008 
1009  pBox->SetFillStyle(1001);
1010  pBox->SetFillColor(color);
1011  pBox->SetBit(kCannotPick);
1012 
1013  ++nDrawnBoxes;
1014  } // for (iBox)
1015 
1016  MF_LOG_DEBUG("RawDataDrawer") << "Sent " << nDrawnBoxes << "/" << BoxInfo.size()
1017  << " boxes to be rendered";
1018  } // RawDataDrawer::QueueDrawingBoxes()
1019 
1021  detinfo::DetectorPropertiesData const& detProp,
1022  evdb::View2D* view,
1023  unsigned int plane)
1024  {
1025 
1026  // Check if we're supposed to draw raw hits at all
1028  if (rawopt->fDrawRawDataOrCalibWires == 1) return;
1029 
1030  geo::PlaneID const pid(rawopt->CurrentTPC(), plane);
1031  BoxDrawer drawer(detProp, pid, this, view);
1032  if (!RunOperation(evt, &drawer)) {
1033  throw art::Exception(art::errors::Unknown) << "RawDataDrawer::RunDrawOperation(): "
1034  "somewhere something went somehow wrong";
1035  }
1036 
1037  } // RawDataDrawer::RunDrawOperation()
1038 
1039  //......................................................................
1041  public:
1042  float const RoIthreshold;
1043 
1045  : OperationBaseClass(pid, data_drawer)
1046  , RoIthreshold(art::ServiceHandle<evd::RawDrawingOptions const>()->RoIthreshold(PlaneID()))
1047  {}
1048 
1049  bool Operate(geo::WireID const& wireID, size_t tick, float adc) override
1050  {
1051  if (std::abs(adc) < RoIthreshold) return true;
1052  WireRange.add(wireID.Wire);
1053  TDCrange.add(tick);
1054  return true;
1055  } // Operate()
1056 
1057  bool Finish() override
1058  {
1059  geo::PlaneID::PlaneID_t const plane = PlaneID().Plane;
1060  int& WireMin = pRawDataDrawer->fWireMin[plane];
1061  int& WireMax = pRawDataDrawer->fWireMax[plane];
1062  int& TimeMin = pRawDataDrawer->fTimeMin[plane];
1063  int& TimeMax = pRawDataDrawer->fTimeMax[plane];
1064 
1065  if ((WireMin == WireMax) && WireRange.has_data()) {
1066  auto const& wireReadoutGeom = art::ServiceHandle<geo::WireReadout>()->Get();
1067  mf::LogInfo("RawDataDrawer")
1068  << "Region of interest for " << std::string(PlaneID()) << " detected to be within wires "
1069  << WireRange.min() << " to " << WireRange.max() << " (plane has "
1070  << wireReadoutGeom.Nwires(PlaneID()) << " wires)";
1071  WireMax = WireRange.max() + 1;
1072  WireMin = WireRange.min();
1073  }
1074  if ((TimeMin == TimeMax) && TDCrange.has_data()) {
1075  mf::LogInfo("RawDataDrawer")
1076  << "Region of interest for " << std::string(PlaneID()) << " detected to be within ticks "
1077  << TDCrange.min() << " to " << TDCrange.max();
1078  TimeMax = TDCrange.max() + 1;
1079  TimeMin = TDCrange.min();
1080  }
1081  return true;
1082  } // Finish()
1083 
1084  private:
1086  }; // class RawDataDrawer::RoIextractorClass
1087 
1088  void RawDataDrawer::RunRoIextractor(art::Event const& evt, unsigned int plane)
1089  {
1091  geo::PlaneID const pid(rawopt->CurrentTPC(), plane);
1092 
1093  // if we have no region of interest, prepare to extract it
1094  bool const bExtractRoI = !hasRegionOfInterest(plane);
1095  MF_LOG_TRACE("RawDataDrawer") << "Region of interest for " << pid
1096  << (bExtractRoI ? " extracted" : " not extracted")
1097  << " on this draw";
1098 
1099  if (!bExtractRoI) return;
1100 
1101  RoIextractorClass Extractor(pid, this);
1102  if (!RunOperation(evt, &Extractor)) {
1103  throw std::runtime_error(
1104  "RawDataDrawer::RunRoIextractor(): somewhere something went somehow wrong");
1105  }
1106 
1107  } // RawDataDrawer::RunRoIextractor()
1108 
1109  //......................................................................
1110 
1112  detinfo::DetectorPropertiesData const& detProp,
1113  evdb::View2D* view,
1114  unsigned int plane,
1115  bool bZoomToRoI /* = false */
1116  )
1117  {
1119  geo::PlaneID const pid(rawopt->CurrentTPC(), plane);
1120 
1121  bool const bDraw = (rawopt->fDrawRawDataOrCalibWires != 1);
1122 
1123  // if we don't need to draw, don't bother doing anything;
1124  // if the region of interest is required, RunRoIextractor() should be called
1125  // (ok, now it's private, but it could be exposed)
1126  if (!bDraw) return;
1127 
1128  // Need to loop over the labels, but we don't want to zap existing cached RawDigits that are valid
1129  // So... do the painful search to make sure the RawDigits we recover at those we are searching for.
1130  bool theDroidIAmLookingFor = false;
1131 
1132  auto const& wireReadoutGeom = art::ServiceHandle<geo::WireReadout const>()->Get();
1133 
1134  // Loop over labels
1135  for (const auto& rawDataLabel : rawopt->fRawDataLabels) {
1136  // make sure we reset what needs to be reset
1137  // before the operations are initialized;
1138  // we call for reading raw digits; they will be cached, so it's not a waste
1139  details::CacheID_t NewCacheID(evt, rawDataLabel, pid);
1140  GetRawDigits(evt, NewCacheID);
1141 
1142  // Painful check to see if these RawDigits contain the droids we are looking for
1143  for (const auto& rawDigit : digit_cache->Digits()) {
1144  std::vector<geo::WireID> WireIDs = wireReadoutGeom.ChannelToWire(rawDigit.Channel());
1145 
1146  for (geo::WireID const& wireID : WireIDs) {
1147  if (wireID.planeID() != pid) continue; // not us!
1148  theDroidIAmLookingFor = true;
1149  break;
1150  } // for wires
1151 
1152  if (theDroidIAmLookingFor) break;
1153  }
1154 
1155  if (theDroidIAmLookingFor) break;
1156  }
1157 
1158  if (!theDroidIAmLookingFor) return;
1159 
1160  bool const hasRoI = hasRegionOfInterest(plane);
1161 
1162  // - if we don't have a RoI yet, we want to get it while we draw
1163  // * if we are zooming into it now, we have to extract it first, then draw
1164  // * if we are not zooming, we can do both at the same time
1165  // - if we have a RoI, we don't want to extract it again
1166  if (!bZoomToRoI) { // we are not required to zoom to the RoI
1167 
1168  std::unique_ptr<OperationBaseClass> operation;
1169 
1170  // we will do the drawing in one pass
1171  MF_LOG_DEBUG("RawDataDrawer") << __func__ << "() setting up one-pass drawing";
1172  operation.reset(new BoxDrawer(detProp, pid, this, view));
1173 
1174  if (!hasRoI) { // we don't have any RoI; since it's cheap, let's get it
1175  MF_LOG_DEBUG("RawDataDrawer") << __func__ << "() adding RoI extraction";
1176 
1177  // swap cards: operation becomes a multiple operation:
1178  // - prepare the two operations (one is there already, somehow)
1179  std::unique_ptr<OperationBaseClass> drawer(std::move(operation));
1180  std::unique_ptr<OperationBaseClass> extractor(new RoIextractorClass(pid, this));
1181  // - create a new composite operation and give it the sub-ops
1182  operation.reset(new ManyOperations(pid, this));
1183  ManyOperations* pManyOps = static_cast<ManyOperations*>(operation.get());
1184  pManyOps->AddOperation(std::move(drawer));
1185  pManyOps->AddOperation(std::move(extractor));
1186  }
1187 
1188  if (!RunOperation(evt, operation.get())) {
1189  throw art::Exception(art::errors::Unknown) << "RawDataDrawer::RunDrawOperation(): "
1190  "somewhere something went somehow wrong";
1191  }
1192  }
1193  else { // we are zooming to RoI
1194  // first, we want the RoI extracted; the extractor will update this object
1195  if (!hasRoI) {
1196  MF_LOG_DEBUG("RawDataDrawer") << __func__ << "() setting up RoI extraction for " << pid;
1197  RoIextractorClass extractor(pid, this);
1198  if (!RunOperation(evt, &extractor)) {
1200  << "RawDataDrawer::RunDrawOperation():"
1201  " something went somehow wrong while extracting RoI";
1202  }
1203  }
1204  else {
1205  MF_LOG_DEBUG("RawDataDrawer")
1206  << __func__ << "() using existing RoI for " << pid << ": wires ( " << fWireMin[plane]
1207  << " - " << fWireMax[plane] << " ), ticks ( " << fTimeMin[plane] << " - "
1208  << fTimeMax[plane] << " )";
1209  }
1210 
1211  // adopt the drawing limits information from the wire/time limits
1213 
1214  // then we draw
1215  MF_LOG_DEBUG("RawDataDrawer") << __func__ << "() setting up drawing";
1216  BoxDrawer drawer(detProp, pid, this, view);
1217  if (!RunOperation(evt, &drawer)) {
1218  throw art::Exception(art::errors::Unknown) << "RawDataDrawer::RunDrawOperation():"
1219  " something went somehow wrong while drawing";
1220  }
1221  }
1222  } // RawDataDrawer::RawDigit2D()
1223 
1224  //........................................................................
1225  int RawDataDrawer::GetRegionOfInterest(int plane, int& minw, int& maxw, int& mint, int& maxt)
1226  {
1227  if ((unsigned int)plane >= fWireMin.size()) {
1228  mf::LogWarning("RawDataDrawer")
1229  << " Requested plane " << plane << " is larger than those available " << std::endl;
1230  return -1;
1231  }
1232 
1233  minw = fWireMin[plane];
1234  maxw = fWireMax[plane];
1235  mint = fTimeMin[plane];
1236  maxt = fTimeMax[plane];
1237 
1238  if ((minw == maxw) || (mint == maxt)) return 1;
1239 
1240  //make values a bit larger, but make sure they don't go out of bounds
1241  minw = (minw - 30 < 0) ? 0 : minw - 30;
1242  mint = (mint - 10 < 0) ? 0 : mint - 10;
1243 
1244  auto const& wireReadoutGeom = art::ServiceHandle<geo::WireReadout>()->Get();
1245  geo::PlaneID const planeid(0, 0, plane);
1246  maxw = (maxw + 10 > (int)wireReadoutGeom.Nwires(planeid)) ? wireReadoutGeom.Nwires(planeid) :
1247  maxw + 10;
1248  maxt = (maxt + 10 > TotalClockTicks()) ? TotalClockTicks() : maxt + 10;
1249 
1250  return 0;
1251  }
1252 
1253  //......................................................................
1254  void RawDataDrawer::GetChargeSum(int plane, double& charge, double& convcharge)
1255  {
1256  charge = fRawCharge[plane];
1257  convcharge = fConvertedCharge[plane];
1258  }
1259 
1260  //......................................................................
1261  void RawDataDrawer::FillQHisto(const art::Event& evt, unsigned int plane, TH1F* histo)
1262  {
1263 
1264  // Check if we're supposed to draw raw hits at all
1266  if (rawopt->fDrawRawDataOrCalibWires == 1) return;
1267 
1268  auto const& wireReadoutGeom = art::ServiceHandle<geo::WireReadout const>()->Get();
1269 
1270  geo::PlaneID const pid(rawopt->CurrentTPC(), plane);
1271 
1272  for (const auto& rawDataLabel : rawopt->fRawDataLabels) {
1273  details::CacheID_t NewCacheID(evt, rawDataLabel, pid);
1274  GetRawDigits(evt, NewCacheID);
1275 
1276  lariov::ChannelStatusProvider const& channelStatus =
1278 
1279  //get pedestal conditions
1280  const lariov::DetPedestalProvider& pedestalRetrievalAlg =
1282 
1283  for (evd::details::RawDigitInfo_t const& digit_info : *digit_cache) {
1284  raw::RawDigit const& hit = digit_info.Digit();
1285  raw::ChannelID_t const channel = hit.Channel();
1286 
1287  if (!channelStatus.IsPresent(channel)) continue;
1288 
1289  // The following test is meant to be temporary until the "correct" solution is implemented
1290  if (!ProcessChannelWithStatus(channelStatus.Status(channel))) continue;
1291 
1292  // to be explicit: we don't cound bad channels in
1293  if (!rawopt->fSeeBadChannels && channelStatus.IsBad(channel)) continue;
1294 
1295  std::vector<geo::WireID> wireids = wireReadoutGeom.ChannelToWire(channel);
1296  for (auto const& wid : wireids) {
1297  // check that the plane and tpc are the correct ones to draw
1298  if (wid.planeID() != pid) continue;
1299 
1300  raw::RawDigit::ADCvector_t const& uncompressed = digit_info.Data();
1301 
1302  //float const pedestal = pedestalRetrievalAlg.PedMean(channel);
1303  // recover the pedestal
1304  float pedestal = 0;
1305  if (rawopt->fPedestalOption == 0) { pedestal = pedestalRetrievalAlg.PedMean(channel); }
1306  else if (rawopt->fPedestalOption == 1) {
1307  pedestal = hit.GetPedestal();
1308  }
1309  else if (rawopt->fPedestalOption == 2) {
1310  pedestal = 0;
1311  }
1312  else {
1313  mf::LogWarning("RawDataDrawer")
1314  << " PedestalOption is not understood: " << rawopt->fPedestalOption
1315  << ". Pedestals not subtracted.";
1316  }
1317 
1318  for (short d : uncompressed)
1319  histo->Fill(float(d) - pedestal);
1320 
1321  // this channel is on the correct plane, don't double count the raw signal
1322  // if there are more than one wids for the channel
1323  break;
1324  } // end loop over wids
1325  } //end loop over raw hits
1326  } //end loop over labels
1327  }
1328 
1329  //......................................................................
1331  unsigned int plane,
1332  unsigned int wire,
1333  TH1F* histo)
1334  {
1335  // Check if we're supposed to draw raw hits at all
1337  if (rawopt->fDrawRawDataOrCalibWires == 1) return;
1338 
1339  // make sure we have the raw digits cached
1340  geo::PlaneID const pid(rawopt->CurrentTPC(), plane);
1341 
1342  auto const& wireReadoutGeom = art::ServiceHandle<geo::WireReadout const>()->Get();
1343 
1344  // loop over labels
1345  for (const auto& rawDataLabel : rawopt->fRawDataLabels) {
1346  details::CacheID_t NewCacheID(evt, rawDataLabel, pid);
1347  GetRawDigits(evt, NewCacheID);
1348 
1349  if (digit_cache->empty()) return;
1350 
1351  geo::WireID const wireid(pid, wire);
1352 
1353  // find the channel
1354  raw::ChannelID_t const channel = wireReadoutGeom.PlaneWireToChannel(wireid);
1355  if (!raw::isValidChannelID(channel)) { // no channel, empty histogram
1356  mf::LogError("RawDataDrawer")
1357  << __func__ << ": no channel associated to " << std::string(wireid);
1358  return;
1359  } // if no channel
1360 
1361  // check the channel status; bad channels are still ok.
1362  lariov::ChannelStatusProvider const& channelStatus =
1364 
1365  if (!channelStatus.IsPresent(channel)) return;
1366 
1367  // The following test is meant to be temporary until the "correct" solution is implemented
1368  if (!ProcessChannelWithStatus(channelStatus.Status(channel))) return;
1369 
1370  // we accept to see the content of a bad channel, so this is commented out:
1371  if (!rawopt->fSeeBadChannels && channelStatus.IsBad(channel)) return;
1372 
1373  //get pedestal conditions
1374  const lariov::DetPedestalProvider& pedestalRetrievalAlg =
1376 
1377  // find the raw digit
1378  // (iDigit is an iterator to a evd::details::RawDigitInfo_t)
1379  evd::details::RawDigitInfo_t const* pDigit = digit_cache->FindChannel(channel);
1380 
1381  if (
1382  !pDigit) { // this is weird... actually no, this can happen if the RawDigits are per TPC (or something)
1383  continue;
1384  }
1385 
1386  raw::RawDigit::ADCvector_t const& uncompressed = pDigit->Data();
1387 
1388  // recover the pedestal
1389  float pedestal = 0;
1390  if (rawopt->fPedestalOption == 0) { pedestal = pedestalRetrievalAlg.PedMean(channel); }
1391  else if (rawopt->fPedestalOption == 1) {
1392  pedestal = pDigit->DigitPtr()->GetPedestal();
1393  }
1394  else if (rawopt->fPedestalOption == 2) {
1395  pedestal = 0;
1396  }
1397  else {
1398  mf::LogWarning("RawDataDrawer")
1399  << " PedestalOption is not understood: " << rawopt->fPedestalOption
1400  << ". Pedestals not subtracted.";
1401  }
1402 
1403  for (size_t j = 0; j < uncompressed.size(); ++j)
1404  histo->Fill(float(j), float(uncompressed[j]) - pedestal);
1405  }
1406 
1407  } // RawDataDrawer::FillTQHisto()
1408 
1409  //......................................................................
1411  {
1412 
1413  return (fWireMax[plane] != -1) && (fTimeMax[plane] != -1);
1414 
1415  } // RawDataDrawer::hasRegionOfInterest()
1416 
1417  //......................................................................
1419  {
1420 
1421  MF_LOG_DEBUG("RawDataDrawer") << "RawDataDrawer[" << ((void*)this)
1422  << "]: resetting the region of interest";
1423 
1424  std::fill(fWireMin.begin(), fWireMin.end(), -1);
1425  std::fill(fWireMax.begin(), fWireMax.end(), -1);
1426  std::fill(fTimeMin.begin(), fTimeMin.end(), -1);
1427  std::fill(fTimeMax.begin(), fTimeMax.end(), -1);
1428 
1429  } // RawDataDrawer::ResetRegionOfInterest()
1430 
1431  //......................................................................
1432 
1434  {
1435  MF_LOG_DEBUG("RawDataDrawer") << "GetRawDigits() for " << new_timestamp
1436  << " (last for: " << *fCacheID << ")";
1437 
1438  // update cache
1439  digit_cache->Update(evt, new_timestamp);
1440 
1441  // if time stamp is changing, we want to reconsider which region is
1442  // interesting
1443  if (!fCacheID->sameTPC(new_timestamp)) ResetRegionOfInterest();
1444 
1445  // all the caches have been properly updated or invalidated;
1446  // we are now on a new cache state
1447  *fCacheID = new_timestamp;
1448 
1449  } // RawDataDrawer::GetRawDigits()
1450 
1451  //......................................................................
1453  lariov::ChannelStatusProvider::Status_t channel_status) const
1454  {
1455  // if we don't have a valid status, we can't reject the channel
1456  if (!lariov::ChannelStatusProvider::IsValidStatus(channel_status)) return true;
1457 
1458  // is the status "too bad"?
1460  if (channel_status > drawopt->fMaxChannelStatus) return false;
1461  if (channel_status < drawopt->fMinChannelStatus) return false;
1462 
1463  // no reason to reject it...
1464  return true;
1465  } // RawDataDrawer::ProcessChannel()
1466 
1467  //----------------------------------------------------------------------------
1468  namespace details {
1469 
1470  //--------------------------------------------------------------------------
1471  //--- RawDigitInfo_t
1472  //---
1473  raw::RawDigit::ADCvector_t const& RawDigitInfo_t::Data() const
1474  {
1475  if (!data.hasData()) UncompressData();
1476  return *data;
1477  } // RawDigitInfo_t::Data()
1478 
1480  {
1481  data.Clear();
1482  digit = src;
1483  } // RawDigitInfo_t::Fill()
1484 
1485  void RawDigitInfo_t::Clear()
1486  {
1487  data.Clear();
1488  sample_info.reset();
1489  }
1490 
1491  void RawDigitInfo_t::UncompressData() const
1492  {
1493  data.Clear();
1494 
1495  if (!digit) return; // no original data, can't do anything
1496 
1498 
1499  if (digit->Compression() == kNone) {
1500  // no compression, we can refer to the original data directly
1501  data.PointToData(digit->ADCs());
1502  }
1503  else {
1504  // data is compressed, need to do the real work
1505  if (drawopt->fUncompressWithPed) { //Use pedestal in uncompression
1506  int pedestal = (int)digit->GetPedestal();
1508  samples.resize(digit->Samples());
1509  Uncompress(digit->ADCs(), samples, pedestal, digit->Compression());
1510  data.StealData(std::move(samples));
1511  }
1512  else {
1514  samples.resize(digit->Samples());
1515  Uncompress(digit->ADCs(), samples, digit->Compression());
1516  data.StealData(std::move(samples));
1517  }
1518  }
1519  } // RawDigitInfo_t::UncompressData()
1520 
1521  void RawDigitInfo_t::CollectSampleInfo() const
1522  {
1523  raw::RawDigit::ADCvector_t const& samples = Data();
1524 
1526  samples.end());
1527 
1528  sample_info.reset(new SampleInfo_t);
1529  sample_info->min_charge = stat.min();
1530  sample_info->max_charge = stat.max();
1531 
1532  } // RawDigitInfo_t::CollectSampleInfo()
1533 
1534  RawDigitInfo_t::SampleInfo_t const& RawDigitInfo_t::SampleInfo() const
1535  {
1536  if (!sample_info) CollectSampleInfo();
1537  return *sample_info;
1538  } // SampleInfo()
1539 
1540  template <typename Stream>
1541  void RawDigitInfo_t::Dump(Stream&& out) const
1542  {
1543  out << " digit at " << ((void*)digit.get()) << " on channel #" << digit->Channel()
1544  << " with " << digit->NADC();
1545  if (digit->Compression() == kNone)
1546  out << " uncompressed data";
1547  else
1548  out << " data items compressed with <" << digit->Compression() << ">";
1549  if (data.hasData())
1550  out << " with data (" << data->size() << " samples)";
1551  else
1552  out << " without data";
1553  } // RawDigitInfo_t::Dump()
1554 
1555  //--------------------------------------------------------------------------
1556  //--- RawDigitCacheDataClass
1557  //---
1558 
1559  RawDigitInfo_t const* RawDigitCacheDataClass::FindChannel(raw::ChannelID_t channel) const
1560  {
1561  auto iDigit = std::find_if(
1562  digits.cbegin(), digits.cend(), [channel](evd::details::RawDigitInfo_t const& digit) {
1563  return digit.Channel() == channel;
1564  });
1565  return (iDigit == digits.cend()) ? nullptr : &*iDigit;
1566  } // RawDigitCacheDataClass::FindChannel()
1567 
1568  std::vector<raw::RawDigit> const* RawDigitCacheDataClass::ReadProduct(art::Event const& evt,
1569  art::InputTag label)
1570  {
1572  if (!evt.getByLabel(label, rdcol)) return nullptr;
1573  return &*rdcol;
1574  } // RawDigitCacheDataClass::ReadProduct()
1575 
1576  void RawDigitCacheDataClass::Refill(art::Handle<std::vector<raw::RawDigit>>& rdcol)
1577  {
1578  digits.resize(rdcol->size());
1579  for (size_t iDigit = 0; iDigit < rdcol->size(); ++iDigit) {
1580  art::Ptr<raw::RawDigit> pDigit(rdcol, iDigit);
1581  digits[iDigit].Fill(pDigit);
1582  size_t samples = pDigit->Samples();
1583  if (samples > max_samples) max_samples = samples;
1584  } // for
1585  } // RawDigitCacheDataClass::Refill()
1586 
1587  void RawDigitCacheDataClass::Invalidate()
1588  {
1589  timestamp.clear();
1590  } // RawDigitCacheDataClass::Invalidate()
1591 
1592  void RawDigitCacheDataClass::Clear()
1593  {
1594  Invalidate();
1595  digits.clear();
1596  max_samples = 0;
1597  } // RawDigitCacheDataClass::Clear()
1598 
1599  RawDigitCacheDataClass::BoolWithUpToDateMetadata RawDigitCacheDataClass::CheckUpToDate(
1600  CacheID_t const& ts,
1601  art::Event const* evt /* = nullptr */) const
1602  {
1603  BoolWithUpToDateMetadata res{false, nullptr};
1604 
1605  // normally only if either the event or the product label have changed,
1606  // cache becomes invalid:
1607  if (!ts.sameProduct(timestamp)) return res; // outdated cache
1608 
1609  // But: our cache stores pointers to the original data, and on a new TPC
1610  // the event display may reload the event anew, removing the "old" data
1611  // from memory.
1612  // Since TPC can change with or without the data being invalidated,
1613  // a more accurate verification is needed.
1614 
1615  // if the cache is empty, well, it does not make much difference;
1616  // we invalidate it to be sure
1617  if (empty()) return res; // outdated cache
1618 
1619  if (!evt) return res; // outdated, since we can't know better without the event
1620 
1621  // here we force reading of the product
1622  res.digits = ReadProduct(*evt, ts.inputLabel());
1623  if (!res.digits) return res; // outdated cache; this is actually an error
1624 
1625  if (res.digits->empty())
1626  return res; // outdated; no digits (strange!), invalidate just in case
1627 
1628  // use the first digit as test
1629  raw::ChannelID_t channel = res.digits->front().Channel();
1630  RawDigitInfo_t const* pInfo = FindChannel(channel);
1631  if (!pInfo) return res; // outdated: we don't even have this channel in cache!
1632 
1633  if (&(pInfo->Digit()) != &(res.digits->front()))
1634  return res; // outdated: different memory address for data
1635 
1636  res.bUpToDate = true;
1637  return res; // cache still valid
1638  } // RawDigitCacheDataClass::CheckUpToDate()
1639 
1640  bool RawDigitCacheDataClass::Update(art::Event const& evt, CacheID_t const& new_timestamp)
1641  {
1642  BoolWithUpToDateMetadata update_info = CheckUpToDate(new_timestamp, &evt);
1643 
1644  if (update_info) return false; // already up to date: move on!
1645 
1646  MF_LOG_DEBUG("RawDataDrawer") << "Refilling raw digit cache RawDigitCacheDataClass["
1647  << ((void*)this) << "] for " << new_timestamp;
1648 
1649  Clear();
1650 
1652  if (!evt.getByLabel(new_timestamp.inputLabel(), rdcol)) {
1653  mf::LogWarning("RawDataDrawer")
1654  << "no RawDigit collection '" << new_timestamp.inputLabel() << "' found";
1655  return true;
1656  }
1657 
1658  Refill(rdcol);
1659 
1660  timestamp = new_timestamp;
1661  return true;
1662  } // RawDigitCacheDataClass::Update()
1663 
1664  template <typename Stream>
1665  void RawDigitCacheDataClass::Dump(Stream&& out) const
1666  {
1667  out << "Cache at " << ((void*)this) << " with time stamp " << std::string(timestamp)
1668  << " and " << digits.size() << " entries (maximum sample: " << max_samples << ");"
1669  << " data at " << ((void*)digits.data());
1670  for (RawDigitInfo_t const& digitInfo : digits) {
1671  out << "\n ";
1672  digitInfo.Dump(out);
1673  } // for
1674  out << "\n";
1675  } // RawDigitCacheDataClass::Dump()
1676 
1677  //--------------------------------------------------------------------------
1678  //--- GridAxisClass
1679  //---
1680  std::ptrdiff_t GridAxisClass::GetCell(float coord) const
1681  {
1682  return std::ptrdiff_t((coord - min) / cell_size); // truncate
1683  } // GridAxisClass::GetCell()
1684 
1685  //--------------------------------------------------------------------------
1686  bool GridAxisClass::Init(size_t nDiv, float new_min, float new_max)
1687  {
1688 
1689  n_cells = std::max(nDiv, size_t(1));
1690  return SetLimits(new_min, new_max);
1691 
1692  } // GridAxisClass::Init()
1693 
1694  //--------------------------------------------------------------------------
1695  bool GridAxisClass::SetLimits(float new_min, float new_max)
1696  {
1697  min = new_min;
1698  max = new_max;
1699  cell_size = Length() / float(n_cells);
1700 
1701  return std::isnormal(cell_size);
1702  } // GridAxisClass::SetLimits()
1703 
1704  //--------------------------------------------------------------------------
1705  bool GridAxisClass::SetMinCellSize(float min_size)
1706  {
1707  if (cell_size >= min_size) return false;
1708 
1709  // n_cells gets truncated
1710  n_cells = (size_t)std::max(std::floor(Length() / min_size), 1.0F);
1711 
1712  // reevaluate cell size, that might be different than min_size
1713  // because of n_cells truncation or minimum value
1714  cell_size = Length() / float(n_cells);
1715  return true;
1716  } // GridAxisClass::SetMinCellSize()
1717 
1718  //--------------------------------------------------------------------------
1719  bool GridAxisClass::SetMaxCellSize(float max_size)
1720  {
1721  if (cell_size <= max_size) return false;
1722 
1723  // n_cells gets rounded up
1724  n_cells = (size_t)std::max(std::ceil(Length() / max_size), 1.0F);
1725 
1726  // reevaluate cell size, that might be different than max_size
1727  // because of n_cells rounding or minimum value
1728  cell_size = Length() / float(n_cells);
1729  return true;
1730  } // GridAxisClass::SetMaxCellSize()
1731 
1732  //--------------------------------------------------------------------------
1733  template <typename Stream>
1734  void GridAxisClass::Dump(Stream&& out) const
1735  {
1736  out << NCells() << " cells from " << Min() << " to " << Max() << " (length: " << Length()
1737  << ")";
1738  } // GridAxisClass::Dump()
1739 
1740  //--------------------------------------------------------------------------
1741  //--- CellGridClass
1742  //---
1743  CellGridClass::CellGridClass(unsigned int nWires, unsigned int nTDC)
1744  : wire_axis((size_t)nWires, 0., float(nWires)), tdc_axis((size_t)nTDC, 0., float(nTDC))
1745  {} // CellGridClass::CellGridClass(int, int)
1746 
1747  //--------------------------------------------------------------------------
1749  float max_wire,
1750  unsigned int nWires,
1751  float min_tdc,
1752  float max_tdc,
1753  unsigned int nTDC)
1754  : wire_axis((size_t)nWires, min_wire, max_wire), tdc_axis((size_t)nTDC, min_tdc, max_tdc)
1755  {} // CellGridClass::CellGridClass({ float, float, int } x 2)
1756 
1757  //--------------------------------------------------------------------------
1758  std::ptrdiff_t CellGridClass::GetCell(float wire, float tick) const
1759  {
1760  std::ptrdiff_t iWireCell = wire_axis.GetCell(wire);
1761  if (!wire_axis.hasCell(iWireCell)) return std::ptrdiff_t(-1);
1762  std::ptrdiff_t iTDCCell = tdc_axis.GetCell(tick);
1763  if (!tdc_axis.hasCell(iTDCCell)) return std::ptrdiff_t(-1);
1764  return iWireCell * TDCAxis().NCells() + iTDCCell;
1765  } // CellGridClass::GetCell()
1766 
1767  //--------------------------------------------------------------------------
1768  std::tuple<float, float, float, float> CellGridClass::GetCellBox(std::ptrdiff_t iCell) const
1769  {
1770  // { w1, t1, w2, t2 }
1771  size_t const nTDCCells = TDCAxis().NCells();
1772  std::ptrdiff_t iWireCell = (std::ptrdiff_t)(iCell / nTDCCells),
1773  iTDCCell = (std::ptrdiff_t)(iCell % nTDCCells);
1774 
1775  return std::tuple<float, float, float, float>(WireAxis().LowerEdge(iWireCell),
1776  TDCAxis().LowerEdge(iTDCCell),
1777  WireAxis().UpperEdge(iWireCell),
1778  TDCAxis().UpperEdge(iTDCCell));
1779  } // CellGridClass::GetCellBox()
1780 
1781  //--------------------------------------------------------------------------
1782  template <typename Stream>
1783  void CellGridClass::Dump(Stream&& out) const
1784  {
1785  out << "Wire axis: ";
1786  WireAxis().Dump(out);
1787  out << "; time axis: ";
1788  TDCAxis().Dump(out);
1789  } // CellGridClass::Dump()
1790 
1791  //--------------------------------------------------------------------------
1792 
1793  } // details
1794 
1795 } // namespace evd
1796 
int GetRegionOfInterest(int plane, int &minw, int &maxw, int &mint, int &maxt)
float GetPedestal() const
Definition: RawDigit.h:221
Data_t max() const
Returns the accumulated maximum, or a very small number if no values.
const_pointer operator->() const
bool Operate(geo::WireID const &wireID, size_t tick, float adc) override
details::CellGridClass drawingRange
float Length(const PFPStruct &pfp)
Definition: PFPUtils.cxx:3267
short MaxCharge() const
maximum charge
bool has_data() const
Returns whether at least one datum has been added.
~PointerToData_t()
Destructor: gets rid of the owned data.
int fScaleDigitsByCharge
scale the size of the digit by the charge
bool Update(art::Event const &evt, CacheID_t const &new_timestamp)
BoxDrawer(detinfo::DetectorPropertiesData const &detProp, geo::PlaneID const &pid, RawDataDrawer *dataDrawer, evdb::View2D *new_view)
bool sameProduct(PlaneDataChangeTracker_t const &as) const
Returns whether we are in the same event (the rest could differ)
BoolWithUpToDateMetadata(bool uptodate, std::vector< raw::RawDigit > const *newdigits)
bool SetCellSizeBoundary(float min_size, float max_size)
ULong64_t Samples() const
Number of samples in the uncompressed ADC data.
Definition: RawDigit.h:217
bool ProcessTick(size_t tick) override
unsigned int fTPC
TPC number to draw, typically set by TWQProjectionView.
Collection of charge vs time digitized from a single readout channel.
Definition: RawDigit.h:68
void SetWireRange(float min_wire, float max_wire)
Sets the wire range, leaving the number of wire cells unchanged.
void FillTQHisto(const art::Event &evt, unsigned int plane, unsigned int wire, TH1F *histo)
int adc
total ADC count in this box
Definition: RawDataDrawer.h:99
raw::RawDigit const & Digit() const
Returns an art pointer to the actual digit.
void SetTDCRange(float min_tdc, float max_tdc, unsigned int nTDC, float min_size)
Sets the complete TDC range, with minimum cell size.
void SetWireRange(float min_wire, float max_wire, unsigned int nWires, float min_size)
Sets the complete wire range, with minimum cell size.
bool Operate(geo::WireID const &wireID, size_t tick, float adc) override
OperationBaseClass(geo::PlaneID const &pid, RawDataDrawer *data_drawer=nullptr)
void RunDrawOperation(art::Event const &evt, detinfo::DetectorPropertiesData const &detProp, evdb::View2D *view, unsigned int plane)
void SetWireRange(unsigned int nWires)
Sets the wire range, leaving the number of wire cells unchanged.
Display parameters for the raw data.
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
int fDrawRawDataOrCalibWires
0 for raw
const_reference operator*() const
auto coord(Vector &v, unsigned int n) noexcept
Returns an object to manage the coordinate n of a vector.
TNtupleSim Fill(f1, f2, f3, f4)
void Dump(Stream &&out) const
Prints the current axes on the specified stream.
void SetDrawingLimitsFromRoI(geo::PlaneID::PlaneID_t plane)
double fStartTick
low tick
unsigned int PlaneID_t
Type for the ID number.
Definition: geo_types.h:365
The data type to uniquely identify a Plane.
Definition: geo_types.h:364
details::CacheID_t * fCacheID
information about the last processed plane
GridAxisClass const & WireAxis() const
Return the information about the wires.
std::unique_ptr< SampleInfo_t > sample_info
Information collected from the uncompressed data.
CacheID_t timestamp
object expressing validity range of cached data
ChannelID_t Channel() const
DAQ channel this raw data was read from.
Definition: RawDigit.h:213
std::vector< std::unique_ptr< RawDataDrawer::OperationBaseClass > > operations
constexpr auto abs(T v)
Returns the absolute value of the argument.
Classes detecting configuration changes.
float cell_size
size of each cell
std::vector< short > ADCvector_t
Type representing a (compressed) vector of ADC counts.
Definition: RawDigit.h:72
bool SetMinTDCCellSize(float min_size)
Sets the minimum size for TDC cells.
std::ptrdiff_t GetCell(float wire, float tick) const
Returns the index of specified cell, or -1 if out of range.
GridAxisClass()
Default constructor: an invalid range.
void SetTDCRange(float min_tdc, float max_tdc)
Sets the TDC range, leaving the number of ticks unchanged.
std::vector< BoxInfo_t > boxInfo
Definition of basic raw digits.
void RawDigit2D(art::Event const &evt, detinfo::DetectorPropertiesData const &detProp, evdb::View2D *view, unsigned int plane, bool bZoomToRoI=false)
Draws raw digit content in 2D wire plane representation.
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
Definition: AddMC.C:8
bool hasTick(int tick) const
Returns whether the range includes the specified wire.
bool operator!() const
Returns whether we point to nothing.
A collection of drawable 2-D objects.
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:430
intermediate_table::const_iterator const_iterator
int GetColor(double x) const
Definition: ColorScale.cxx:126
ManyOperations(geo::PlaneID const &pid, RawDataDrawer *data_drawer=nullptr)
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
void PointToData(pointer data)
Point to the specified data, not acquiring ownership.
raw::ChannelID_t Channel() const
Returns the channel of this digit (for convenience)
lar::util::MinMaxCollector< float > WireRange
bool ProcessChannelWithStatus(lariov::ChannelStatusProvider::Status_t channel_status) const
Returns whether a channel with the specified status should be processed.
Classes gathering simple statistics.
no compression
Definition: RawTypes.h:9
std::vector< double > fRawCharge
Sum of Raw Charge.
std::vector< int > fWireMin
lowest wire in interesting region for each plane
bool Update(detinfo::DetectorPropertiesData const &detProp, const TCSlice &slc, PFPStruct &pfp)
Definition: PFPUtils.cxx:1048
double electronsToADC
conversion constant
Manages a cell-like division of a coordinate.
std::add_pointer_t< value_type > pointer
void SetDrawingLimits(float low_wire, float high_wire, float low_tdc, float high_tdc)
Fills the viewport borders from the specified extremes.
size_t n_cells
number of cells in the axis
friend class RoIextractorClass
details::ADCCorrectorClass ADCCorrector
IDparameter< geo::PlaneID > PlaneID
Member type of validated geo::PlaneID parameter.
std::vector< int > fTimeMax
highest time in interesting region for each plane
The color scales used by the event display.
Keeps track of the minimum and maximum value we observed.
TBox & AddBox(double x1, double y1, double x2, double y2)
Definition: View2D.cxx:263
Information about a RawDigit; may contain uncompressed duplicate of data.
art::InputTag const & inputLabel() const
Returns whether we are in the same event (the rest could differ)
OperationBaseClass const * Operator(size_t iOp) const
std::add_lvalue_reference_t< value_type > reference
Data_t min() const
Returns the accumulated minimum, or a very large number if no values.
constexpr ChannelID_t InvalidChannelID
ID of an invalid channel.
Definition: RawTypes.h:31
detinfo::DetectorPropertiesData const & detProp
float Length() const
Returns the length of the axis.
double fTicks
number of ticks of the clock
mutable::details::PointerToData_t< raw::RawDigit::ADCvector_t const > data
Uncompressed data.
bool ProcessWire(geo::WireID const &wire) override
LArSoft includes.
void AcquireData(pointer data)
Acquire ownership of the specified data.
PadResolution_t PadResolution
stored pad resolution
short MinCharge() const
minimum charge
raw::RawDigit::ADCvector_t const & Data() const
average charge
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
bool SetMinWireCellSize(float min_size)
Sets the minimum size for wire cells.
double operator()(float adc) const
Applies Birks correction to the specified pedestal-subtracted charge.
Build an association between a numerical range and a ROOT color index for use in, eg...
Definition: ColorScale.h:44
bool Add(CONT &cont, float wire, float tick, typename CONT::value_type v)
const evdb::ColorScale & RawQ(geo::SigType_t st) const
unsigned int fCryostat
Cryostat number to draw, typically set by TWQProjectionView.
enum geo::_plane_sigtype SigType_t
Enumerate the possible plane projections.
std::string Name() const override
bool hasWire(int wire) const
Returns whether the range includes the specified wire.
std::ptrdiff_t operator()(float coord) const
Returns the index of the specified cell.
ADCCorrectorClass(detinfo::DetectorPropertiesData const &dp, geo::PlaneID const &pid)
unsigned int fMaxChannelStatus
Display channels with this status and below.
Cached set of RawDigitInfo_t.
Collect all the RawData header files together.
std::vector< evd::details::RawDigitInfo_t >::const_iterator begin(RawDigitCacheDataClass const &cache)
float UpperEdge(std::ptrdiff_t iCell) const
Returns the upper edge of the cell.
float LowerEdge(std::ptrdiff_t iCell) const
Returns the lower edge of the cell.
void FillQHisto(const art::Event &evt, unsigned int plane, TH1F *histo)
void GetChargeSum(int plane, double &charge, double &convcharge)
double fMinSignal
minimum ADC count to display a time bin
#define MF_LOG_TRACE(id)
void RunRoIextractor(art::Event const &evt, unsigned int plane)
std::vector< int > fWireMax
highest wire in interesting region for each plane
double fTicks
number of TDC ticks to display, ie # fTicks past fStartTick
std::add_lvalue_reference_t< const_value_type > const_reference
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
Definition: electronics.h:73
Float_t d
Definition: plot.C:235
constexpr bool isValidChannelID(raw::ChannelID_t channel)
Definition: RawTypes.h:35
void GetRawDigits(art::Event const &evt)
Reads raw::RawDigits; also triggers Reset()
geo::TPCID CurrentTPC() const
Returns the current TPC as a TPCID.
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
bool hasCell(std::ptrdiff_t iCell) const
Returns whether the cell is present or not.
double TotalClockTicks() const
Definition: RawDataDrawer.h:78
The data type to uniquely identify a TPC.
Definition: geo_types.h:306
virtual bool Operate(geo::WireID const &wireID, size_t tick, float adc)=0
bool operator()(geo::WireID const &wireID, size_t tick, float adc)
float Max() const
Returns the extremes of the axis.
bool isEmpty() const
Returns whether minimum and maximum match.
bool bOwned
whether we own our data
Class to aid in the rendering of RawData objects.
Detector simulation of raw signals on wires.
void SetTDCRange(float min_tdc, float max_tdc, unsigned int nTDC)
Sets the complete TDC range.
float CellSize() const
Returns the cell size.
Detects the presence of a new event, data product or wire plane.
std::vector< RawDigitInfo_t > const & Digits() const
Returns the list of digit info.
CellGridClass()
Default constructor: invalid ranges.
bool empty() const
Returns whether the cache is empty() (STL-like interface)
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
geo::PlaneID const & PlaneID() const
std::size_t color(std::string const &procname)
void NewData(T const &data)
Create a owned copy of the specified object.
RawDigitInfo_t const * FindChannel(raw::ChannelID_t channel) const
Returns a pointer to the digit info of given channel, nullptr if none.
int fTicksPerPoint
number of ticks to include in one point
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
virtual bool ProcessWire(geo::WireID const &)
Encapsulate the construction of a single detector plane .
bool fSeeBadChannels
Allow "bad" channels to be viewed.
bool hasCoord(float coord) const
Returns whether the coordinate is included in the range or not.
bool hasRegionOfInterest(geo::PlaneID::PlaneID_t plane) const
friend class BoxDrawer
void SetWireRange(float min_wire, float max_wire, unsigned int nWires)
Sets the complete wire range.
void PointToData(reference data)
Point to the specified data, not acquiring ownership.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
#define MF_LOG_DEBUG(id)
pointer pData
pointer to data
size_t NCells() const
Returns the length of the axis.
void QueueDrawingBoxes(evdb::View2D *view, geo::PlaneID const &pid, std::vector< BoxInfo_t > const &BoxInfo)
int fAxisOrientation
0 = TDC values on y-axis, wire number on x-axis, 1 = swapped
void Clear()
Stop pointing to the data; if owned, delete it.
std::vector< art::InputTag > fRawDataLabels
module label that made the raw digits, default is daq
Aid in the rendering of RawData objects.
Definition: RawDataDrawer.h:41
art::Ptr< raw::RawDigit > digit
a pointer to the actual digit
GridAxisClass(size_t nDiv, float new_min, float new_max)
Constructor: sets the limits and the number of cells.
bool ProcessTick(size_t tick) override
Definition: MVAAlg.h:12
double fStartTick
Starting tick for the display.
bool good
whether the channel is not bad
void Dump(Stream &&out) const
unsigned int WireID_t
Type for the ID number.
Definition: geo_types.h:422
bool owned() const
Returns whether we have data and we own it.
RawDataDrawer * RawDataDrawerPtr() const
size_t MaxSamples() const
Returns the largest number of samples in the unpacked raw digits.
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
RoIextractorClass(geo::PlaneID const &pid, RawDataDrawer *data_drawer)
void ResetRegionOfInterest()
Forgets about the current region of interest.
details::CellGridClass * fDrawingRange
information about the viewport
std::vector< int > fTimeMin
lowest time in interesting region for each plane
::util::PlaneDataChangeTracker_t CacheID_t
Definition: RawDataDrawer.h:36
std::add_const_t< value_type > const_value_type
Manages a grid-like division of 2D space.
TCEvent evt
Definition: DataStructs.cxx:8
bool ProcessWire(geo::WireID const &wireID) override
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
Applies Birks correction.
OperationBaseClass * Operator(size_t iOp)
virtual std::string Name() const
void Uncompress(const std::vector< short > &adc, std::vector< short > &uncompressed, raw::Compress_t compress)
Uncompresses a raw data buffer.
Definition: raw.cxx:744
evd::details::RawDigitCacheDataClass * digit_cache
Cache of raw digits.
int fPedestalOption
0: use DetPedestalService; 1: Use pedestal in raw::RawDigt; 2: no ped subtraction ...
void SetTDCRange(unsigned int nTDC)
Sets a simple TDC range: all the ticks, one cell per tick.
void StealData(std::remove_const_t< T > &&data)
Move data from the specified object, and own it.
std::vector< RawDigitInfo_t > digits
vector of raw digit information
GridAxisClass const & TDCAxis() const
Return the information about the TDCs.
bool hasData() const
Returns whether we have data.
art::Ptr< raw::RawDigit > DigitPtr() const
Returns an art pointer to the actual digit.
bool RunOperation(art::Event const &evt, OperationBaseClass *operation)
std::tuple< float, float, float, float > GetCellBox(std::ptrdiff_t iCell) const
Returns the coordinates { w1, t1, w2, t2 } of specified cell.
size_t NCells() const
Returns the total number of cells in the grid.
void SetData(pointer data, bool owned)
Sets the data and the ownership.
bool Operate(geo::WireID const &wireID, size_t tick, float adc) override
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:109
bool fUncompressWithPed
Option to uncompress with pedestal. Turned off by default.
std::add_pointer_t< const_value_type > const_pointer
std::ptrdiff_t GetCell(float coord) const
Returns the index of the specified cell.
void AddOperation(std::unique_ptr< OperationBaseClass > new_op)
std::vector< double > fConvertedCharge
Sum of Charge Converted using Birks&#39; formula.
void ExtractRange(TVirtualPad *pPad, std::vector< double > const *zoom=nullptr)
Fills the viewport information from the specified pad.