LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
RawDataDrawer.cxx
Go to the documentation of this file.
1 
54 #include <cmath> // std::abs(), ...
55 #include <utility> // std::pair<>, std::move()
56 #include <memory> // std::unique_ptr()
57 #include <tuple>
58 #include <limits> // std::numeric_limits<>
59 #include <type_traits> // std::add_const_t<>, ...
60 #include <typeinfo> // to use typeid()
61 #include <algorithm> // std::fill(), std::find_if(), ...
62 #include <cstddef> // std::ptrdiff_t
63 
64 #include "TH1F.h"
65 // #include "TPolyLine3D.h"
66 #include "TBox.h"
67 #include "TFrame.h"
68 #include "TVirtualPad.h"
69 
70 #include "lareventdisplay/EventDisplay/ChangeTrackers.h" // util::PlaneDataChangeTracker_t
76 #include "larevt/CalibrationDBI/Interface/DetPedestalService.h"
77 #include "larevt/CalibrationDBI/Interface/DetPedestalProvider.h"
78 #include "lardataobj/RawData/raw.h"
80 #include "larevt/CalibrationDBI/Interface/ChannelStatusService.h"
81 #include "larevt/CalibrationDBI/Interface/ChannelStatusProvider.h"
85 #include "lardata/Utilities/StatCollector.h" // lar::util::MinMaxCollector<>
89 
90 
98 #include "cetlib_except/demangle.h"
99 
100 
101 namespace {
102  template <typename Stream, typename T>
103  void PrintRange
104  (Stream&& out, std::string header, lar::util::MinMaxCollector<T> const& range)
105  {
106  out << header << ": " << range.min() << " -- " << range.max()
107  << " (" << (range.has_data()? "valid": "invalid") << ")";
108  } // PrintRange()
109 } // local namespace
110 
111 
112 // internal use classes declaration;
113 // it can't live in the header because it uses C++11/14
114 namespace details {
116  template <typename T>
118  public:
119  using value_type = T;
120  using const_value_type = std::add_const_t<value_type>;
121  using reference = std::add_lvalue_reference_t<value_type>;
122  using const_reference
123  = std::add_lvalue_reference_t<const_value_type>;
124  using pointer = std::add_pointer_t<value_type>;
125  using const_pointer = std::add_pointer_t<const_value_type>;
126 
129 
132  const_reference operator* () const { return *pData; }
133  reference operator* () { return *pData; }
134 
135  const_pointer operator-> () const { return pData; }
136  pointer operator-> () { return pData; }
138 
140  operator bool() const { return hasData(); }
141 
143  bool operator! () const { return !hasData(); }
144 
146  bool hasData() const { return bool(pData); }
147 
149  bool owned() const { return bOwned && hasData(); }
150 
152  void SetData(pointer data, bool owned)
153  {
154  Clear();
155  bOwned = owned;
156  pData = data;
157  }
159  void AcquireData(pointer data) { SetData(data, true); }
161  void PointToData(pointer data) { SetData(data, false); }
163  void PointToData(reference data) { SetData(&data, false); }
165  void StealData(std::remove_const_t<T>&& data)
166  { AcquireData(new T(std::move(data))); }
168  void NewData(T const& data) { AcquireData(new T(data)); }
170  void Clear()
171  {
172  if (bOwned) delete pData;
173  pData = nullptr;
174  bOwned = false;
175  } // Clear()
176 
177  protected:
178  bool bOwned = false;
179  pointer pData = nullptr;
180  }; // class PointerToData_t<>
181 }
182 
183 namespace evd {
184  namespace details {
185 
188  public:
190  art::Ptr<raw::RawDigit> DigitPtr() const { return digit; }
191 
193  raw::RawDigit const& Digit() const { return *digit; }
194 
197  { return digit? digit->Channel(): raw::InvalidChannelID; }
198 
200  short MinCharge() const { return SampleInfo().min_charge; }
201 
203  short MaxCharge() const { return SampleInfo().max_charge; }
204 
206  // short AverageCharge() const { return SampleInfo().average_charge; }
207 
209  raw::RawDigit::ADCvector_t const& Data() const;
210 
212  void Fill(art::Ptr<raw::RawDigit> const& src);
213 
215  void Clear();
216 
218  template <typename Stream>
219  void Dump(Stream&& out) const;
220 
221  private:
222  typedef struct {
223  short min_charge = std::numeric_limits<short>::max();
224  short max_charge = std::numeric_limits<short>::max();
225  // float average_charge = 0.; ///< average charge
226  } SampleInfo_t; // SampleInfo_t
227 
229 
231  mutable ::details::PointerToData_t<raw::RawDigit::ADCvector_t const> data;
232 
234  mutable std::unique_ptr<SampleInfo_t> sample_info;
235 
237  void UncompressData() const;
238 
240  void CollectSampleInfo() const;
241 
243  SampleInfo_t const& SampleInfo() const;
244 
245  }; // class RawDigitInfo_t
246 
247 
250  public:
251 
253  std::vector<RawDigitInfo_t> const& Digits() const { return digits; }
254 
256  RawDigitInfo_t const* FindChannel(raw::ChannelID_t channel) const;
257 
259  size_t MaxSamples() const { return max_samples; }
260 
262  bool empty() const { return digits.empty(); }
263 
265  void Clear();
266 
268  void Refill(art::Handle<std::vector<raw::RawDigit>>& rdcol);
269 
271  void Invalidate();
272 
275  bool Update(art::Event const& evt, CacheID_t const& new_timestamp);
276 
278  template <typename Stream>
279  void Dump(Stream&& out) const;
280 
281  private:
282 
284 
285  bool bUpToDate = false;
286  std::vector<raw::RawDigit> const* digits = nullptr;
287 
288  BoolWithUpToDateMetadata() = default;
290  (bool uptodate, std::vector<raw::RawDigit> const* newdigits):
291  bUpToDate(uptodate), digits(newdigits)
292  {}
293 
294  operator bool() const { return bUpToDate; }
295  }; // struct BoolWithUpToDateMetadata
296 
297  std::vector<RawDigitInfo_t> digits;
298 
300 
301  size_t max_samples = 0;
302 
304  BoolWithUpToDateMetadata CheckUpToDate
305  (CacheID_t const& ts, art::Event const* evt = nullptr) const;
306 
307  static std::vector<raw::RawDigit> const* ReadProduct
308  (art::Event const& evt, art::InputTag label);
309 
310  }; // struct RawDigitCacheDataClass
311 
312 
314  (RawDigitCacheDataClass const& cache)
315  { return cache.Digits().cbegin(); }
317  (RawDigitCacheDataClass const& cache)
318  { return cache.Digits().cend(); }
319 
320 
321 
324  public:
326  GridAxisClass() { Init(0, 0., 0.); }
327 
329  GridAxisClass(size_t nDiv, float new_min, float new_max)
330  { Init(nDiv, new_min, new_max); }
331 
333  std::ptrdiff_t GetCell(float coord) const;
335  std::ptrdiff_t operator() (float coord) const { return GetCell(coord); }
337 
339  bool hasCell(std::ptrdiff_t iCell) const
340  { return (iCell >= 0) && ((size_t) iCell < NCells()); }
341 
343  bool hasCoord(float coord) const
344  { return (coord >= Min()) && (coord < Max()); }
345 
346 
348  float Min() const { return min; }
350  float Max() const { return max; }
352 
354  float Length() const { return max - min; }
355 
357  size_t NCells() const { return n_cells; }
358 
360  bool isEmpty() const { return max == min; }
361 
363  float CellSize() const { return cell_size; }
364 
366  float LowerEdge(std::ptrdiff_t iCell) const
367  { return Min() + CellSize() * iCell; }
368 
370  float UpperEdge(std::ptrdiff_t iCell) const
371  { return LowerEdge(iCell + 1); }
372 
374  bool Init(size_t nDiv, float new_min, float new_max);
375 
377  bool SetLimits(float new_min, float new_max);
378 
381  bool SetMinCellSize(float min_size);
382 
385  bool SetMaxCellSize(float max_size);
386 
389  bool SetCellSizeBoundary(float min_size, float max_size)
390  { return SetMinCellSize(min_size) || SetMaxCellSize(max_size); }
391 
392  template <typename Stream>
393  void Dump(Stream&& out) const;
394 
395  private:
396  size_t n_cells;
397  float min, max;
398 
399  float cell_size;
400 
401  }; // GridAxisClass
402 
403 
406  public:
407 
409  CellGridClass(): wire_axis(), tdc_axis() {}
410 
412  CellGridClass(unsigned int nWires, unsigned int nTDC);
413 
416  float min_wire, float max_wire, unsigned int nWires,
417  float min_tdc, float max_tdc, unsigned int nTDC
418  );
419 
421  size_t NCells() const { return wire_axis.NCells() * tdc_axis.NCells(); }
422 
424  GridAxisClass const& WireAxis() const { return wire_axis; }
425 
427  GridAxisClass const& TDCAxis() const { return tdc_axis; }
428 
429 
431  std::ptrdiff_t GetCell(float wire, float tick) const;
432 
434  std::tuple<float, float, float, float> GetCellBox
435  (std::ptrdiff_t iCell) const;
436 
438  bool hasWire(float wire) const { return wire_axis.hasCoord(wire); }
440  bool hasWire(int wire) const { return hasWire((float) wire); }
442 
444  bool hasTick(float tick) const { return tdc_axis.hasCoord(tick); }
446  bool hasTick(int tick) const { return hasTick((float) tick); }
448 
449 
452  template <typename CONT>
453  bool Add(CONT& cont, float wire, float tick, typename CONT::value_type v)
454  {
455  std::ptrdiff_t cell = GetCell(wire, tick);
456  if (cell < 0) return false;
457  cont[(size_t) cell] += v;
458  return true;
459  } // Add()
460 
461 
465  void SetWireRange(unsigned int nWires)
466  { SetWireRange(0., (float) nWires, nWires); }
467 
469  void SetWireRange(float min_wire, float max_wire)
470  { wire_axis.SetLimits(min_wire, max_wire); }
471 
473  void SetWireRange(float min_wire, float max_wire, unsigned int nWires)
474  { wire_axis.Init(nWires, min_wire, max_wire); }
475 
477  void SetWireRange
478  (float min_wire, float max_wire, unsigned int nWires, float min_size)
479  {
480  wire_axis.Init(nWires, min_wire, max_wire);
481  wire_axis.SetMinCellSize(min_size);
482  }
483 
485  void SetTDCRange(unsigned int nTDC)
486  { SetTDCRange(0., (float) nTDC, nTDC); }
487 
489  void SetTDCRange(float min_tdc, float max_tdc, unsigned int nTDC)
490  { tdc_axis.Init(nTDC, min_tdc, max_tdc); }
491 
493  void SetTDCRange(float min_tdc, float max_tdc)
494  { tdc_axis.SetLimits(min_tdc, max_tdc); }
495 
497  void SetTDCRange
498  (float min_tdc, float max_tdc, unsigned int nTDC, float min_size)
499  {
500  tdc_axis.Init(nTDC, min_tdc, max_tdc);
501  tdc_axis.SetMinCellSize(min_size);
502  }
503 
505 
507  bool SetMinWireCellSize(float min_size)
508  { return wire_axis.SetMinCellSize(min_size); }
509 
511  bool SetMinTDCCellSize(float min_size)
512  { return tdc_axis.SetMinCellSize(min_size); }
513 
515  template <typename Stream>
516  void Dump(Stream&& out) const;
517 
518  protected:
521  }; // CellGridClass
522 
523 
524  //--------------------------------------------------------------------------
527  public:
530 
532  ADCCorrectorClass(geo::PlaneID const& pid) { update(pid); }
533 
535  double Correct(float adc) const
536  {
537  if (adc < 0.) return 0.;
538  double const dQdX = adc / wirePitch / electronsToADC;
539  detinfo::DetectorProperties const* detp = lar::providerFrom<detinfo::DetectorPropertiesService>();
540  return detp->BirksCorrection(dQdX);
541  } // Correct()
542  double operator() (float adc) const { return Correct(adc); }
543 
544  void update(geo::PlaneID const& pid)
545  {
547  wirePitch = geo->WirePitch(pid);
548 
549  detinfo::DetectorProperties const* detp = lar::providerFrom<detinfo::DetectorPropertiesService>();
550  electronsToADC = detp->ElectronsToADC();
551  } // update()
552 
553  protected:
554  float wirePitch;
556 
557  }; // ADCCorrectorClass
558  //--------------------------------------------------------------------------
559  } // namespace details
560 } // namespace evd
561 
562 namespace evd {
563 
564  // empty vector
565  std::vector<raw::RawDigit> const RawDataDrawer::EmptyRawDigits;
566 
567  //......................................................................
568  RawDataDrawer::RawDataDrawer()
569  : digit_cache(new details::RawDigitCacheDataClass)
570  , fStartTick(0),fTicks(2048)
571  , fCacheID(new details::CacheID_t)
572  , fDrawingRange(new details::CellGridClass)
573  {
575 
577  geo::TPCID tpcid(rawopt->fCryostat, rawopt->fTPC);
578 
579  fStartTick = rawopt->fStartTick;
580  fTicks = rawopt->fTicks;
581 
582  // set the list of bad channels in this detector
583  unsigned int nplanes=geo->Nplanes(tpcid);
584  fWireMin.resize(nplanes,-1);
585  fWireMax.resize(nplanes,-1);
586  fTimeMin.resize(nplanes,-1);
587  fTimeMax.resize(nplanes,-1);
588  fRawCharge.resize(nplanes,0);
589  fConvertedCharge.resize(nplanes,0);
590  }
591 
592  //......................................................................
594  {
595  delete digit_cache;
596  delete fDrawingRange;
597  delete fCacheID;
598  }
599 
600 
601  //......................................................................
603  (float low_wire, float high_wire, float low_tdc, float high_tdc)
604  {
605  LOG_DEBUG("RawDataDrawer") << __func__
606  << "() setting drawing range as wires ( "
607  << low_wire << " - " << high_wire
608  << " ), ticks ( " << low_tdc << " - " << high_tdc << " )";
609 
610  // we need to set the minimum cell size to 1, otherwise some cell will not
611  // cover any wire/tick and they will be always empty
612  if (PadResolution) {
613  // TODO implement support for swapping axes here
614  unsigned int wire_pixels = PadResolution.width;
615  unsigned int tdc_pixels = PadResolution.height;
616  fDrawingRange->SetWireRange(low_wire, high_wire, wire_pixels, 1.F);
617  fDrawingRange->SetTDCRange(low_tdc, high_tdc, tdc_pixels, 1.F);
618  }
619  else {
620  LOG_DEBUG("RawDataDrawer")
621  << "Pad size not available -- using existing cell size";
622  fDrawingRange->SetWireRange(low_wire, high_wire);
624  fDrawingRange->SetTDCRange(low_tdc, high_tdc);
626  }
627 
628  } // RawDataDrawer::SetDrawingLimits()
629 
630 
633  {
635  (fWireMin[plane], fWireMax[plane], fTimeMin[plane], fTimeMax[plane]);
636  } // RawDataDrawer::SetDrawingLimitsFromRoI()
637 
638 
640  (TVirtualPad* pPad, std::vector<double> const* zoom /* = nullptr */)
641  {
642  mf::LogDebug log("RawDataDrawer");
643  log << "ExtractRange() on pad '" << pPad->GetName() << "'";
644 
645  TFrame const* pFrame = pPad->GetFrame();
646  if (pFrame) {
647  // these coordinates are used to find the actual extent of pad in pixels
648  double low_wire = pFrame->GetX1(), high_wire = pFrame->GetX2();
649  double low_tdc = pFrame->GetY1(), high_tdc = pFrame->GetY2();
650  double const wire_pixels = pPad->XtoAbsPixel(high_wire) - pPad->XtoAbsPixel(low_wire);
651  double const tdc_pixels = -(pPad->YtoAbsPixel(high_tdc) - pPad->YtoAbsPixel(low_tdc));
652 
653  PadResolution.width = (unsigned int) wire_pixels;
654  PadResolution.height = (unsigned int) tdc_pixels;
655 
656  log << "\n frame window is "
658  << " pixel big and";
659  // those coordinates also are a (unreliable) estimation of the zoom;
660  // if we have a better one, let's use it
661  // (this does not change the size of the window in terms of pixels)
662  if (zoom) {
663  log << ", from external source,";
664  low_wire = (*zoom)[0];
665  high_wire = (*zoom)[1];
666  low_tdc = (*zoom)[2];
667  high_tdc = (*zoom)[3];
668  }
669 
670  log << " spans wires "
671  << low_wire << "-" << high_wire << " and TDC " << low_tdc << "-" << high_tdc;
672 
673  // TODO support swapping axes here:
674  // if (rawopt.fAxisOrientation < 1) { normal ; } else { swapped; }
675 
676  fDrawingRange->SetWireRange(low_wire, high_wire, (unsigned int) wire_pixels, 1.0);
677  fDrawingRange->SetTDCRange(low_tdc, high_tdc, (unsigned int) tdc_pixels, 1.0);
678  }
679  else {
680  // keep the old frame (if any)
681  log << "\n no frame!";
682  }
683 
684  } // RawDataDrawer::ExtractRange()
685 
686 
687  //......................................................................
689  public:
691  (geo::PlaneID const& pid, RawDataDrawer* data_drawer = nullptr)
692  : pRawDataDrawer(data_drawer), planeID(pid) {}
693 
694  virtual ~OperationBaseClass() = default;
695 
696  virtual bool Initialize() { return true; }
697 
698  virtual bool ProcessWire(geo::WireID const&) { return true; }
699  virtual bool ProcessTick(size_t) { return true; }
700 
701  virtual bool Operate(geo::WireID const& wireID, size_t tick, float adc) = 0;
702 
703  virtual bool Finish() { return true; }
704 
705  virtual std::string Name() const
706  { return cet::demangle_symbol(typeid(*this).name()); }
707 
708  bool operator() (geo::WireID const& wireID, size_t tick, float adc)
709  { return Operate(wireID, tick, adc); }
710 
711  geo::PlaneID const& PlaneID() const { return planeID; }
712  RawDataDrawer* RawDataDrawerPtr() const { return pRawDataDrawer; }
713 
714  protected:
715  RawDataDrawer* pRawDataDrawer = nullptr;
716 
717  private:
719  }; // class RawDataDrawer::OperationBaseClass
720 
721  //......................................................................
723  {
724  std::vector<std::unique_ptr<RawDataDrawer::OperationBaseClass>> operations;
725  public:
726 
728  (geo::PlaneID const& pid, RawDataDrawer* data_drawer = nullptr):
729  OperationBaseClass(pid, data_drawer)
730  {}
731 
732  virtual bool Initialize() override
733  {
734  bool bAllOk = true;
735  for (std::unique_ptr<OperationBaseClass> const& op: operations)
736  if (!op->Initialize()) bAllOk = false;
737  return bAllOk;
738  }
739 
740  virtual bool ProcessWire(geo::WireID const& wireID) override
741  {
742  for (std::unique_ptr<OperationBaseClass> const& op: operations)
743  if (op->ProcessWire(wireID)) return true;
744  return false;
745  }
746  virtual bool ProcessTick(size_t tick) override
747  {
748  for (std::unique_ptr<OperationBaseClass> const& op: operations)
749  if (op->ProcessTick(tick)) return true;
750  return false;
751  }
752 
753  virtual bool Operate
754  (geo::WireID const& wireID, size_t tick, float adc) override
755  {
756  for (std::unique_ptr<OperationBaseClass> const& op: operations)
757  if (!op->Operate(wireID, tick, adc)) return false;
758  return true;
759  }
760 
761  virtual bool Finish() override
762  {
763  bool bAllOk = true;
764  for (std::unique_ptr<OperationBaseClass> const& op: operations)
765  if (!op->Finish()) bAllOk = false;
766  return bAllOk;
767  }
768 
769  virtual std::string Name() const override
770  {
771  std::string msg = cet::demangle_symbol(typeid(*this).name());
772  msg +=
773  (" [running " + std::to_string(operations.size()) + " operations:");
774  for (auto const& op: operations) {// it's unique_ptr<OperationBaseClass>
775  if (op) msg += " " + op->Name();
776  else msg += " <invalid>";
777  }
778  return msg + " ]";
779  }
780 
782  { return operations.at(iOp).get(); }
783  OperationBaseClass const* Operator(size_t iOp) const
784  { return operations.at(iOp).get(); }
785 
786  void AddOperation(std::unique_ptr<OperationBaseClass> new_op)
787  {
788  if (!new_op) return;
789  if (PlaneID() != new_op->PlaneID()) {
791  << "RawDataDrawer::ManyOperations(): trying to run operations on "
792  << std::string(PlaneID()) << " and "
793  << std::string(new_op->PlaneID()) << " at the same time";
794  }
795  if (RawDataDrawerPtr()
796  && (RawDataDrawerPtr() != new_op->RawDataDrawerPtr())
797  )
798  {
800  << "RawDataDrawer::ManyOperations(): "
801  "trying to run operations on different RawDataDrawer"
802  ; // possible, but very unlikely
803  }
804  operations.emplace_back(std::move(new_op));
805  }
806 
807  }; // class RawDataDrawer::ManyOperations
808 
809  //......................................................................
811  (art::Event const& evt, OperationBaseClass* operation)
812  {
813  geo::PlaneID const& pid = operation->PlaneID();
814 
816  details::CacheID_t NewCacheID(evt, rawopt->fRawDataLabel, pid);
817  GetRawDigits(evt, NewCacheID);
818 
819  if(digit_cache->empty()) return true;
820 
821  LOG_DEBUG("RawDataDrawer") << "RawDataDrawer::RunOperation() running "
822  << operation->Name();
823 
824  // if we have an initialization failure, return false immediately;
825  // but it's way better if the failure throws an exception
826  if (!operation->Initialize()) return false;
827 
828  lariov::ChannelStatusProvider const& channelStatus
830 
831  //get pedestal conditions
832  const lariov::DetPedestalProvider& pedestalRetrievalAlg = *(lar::providerFrom<lariov::DetPedestalService>());
833 
834  geo::GeometryCore const& geom = *(lar::providerFrom<geo::Geometry>());
835 
836  // loop over all the channels/raw digits
837  for (evd::details::RawDigitInfo_t const& digit_info: *digit_cache) {
838  raw::RawDigit const& hit = digit_info.Digit();
839  raw::ChannelID_t const channel = hit.Channel();
840 
841  // skip the bad channels
842  if (!channelStatus.IsPresent(channel)) continue;
843  // The following test is meant to be temporary until the "correct" solution is implemented
844  if (!ProcessChannelWithStatus(channelStatus.Status(channel))) continue;
845 
846  // we have a list of all channels, but we are drawing only on one plane;
847  // most of the channels will not contribute to this plane,
848  // and before we start querying databases, unpacking data etc.
849  // we want to know it's for something
850 
851  std::vector<geo::WireID> WireIDs = geom.ChannelToWire(channel);
852 
853  bool bDrawChannel = false;
854  for (geo::WireID const& wireID: WireIDs){
855  if (wireID.planeID() != pid) continue; // not us!
856  bDrawChannel = true;
857  break;
858  } // for wires
859  if (!bDrawChannel) continue;
860 
861  // collect bad channels
862  bool const bGood = rawopt->fSeeBadChannels || !channelStatus.IsBad(channel);
863 
864  // nothing else to be done if the channel is not good:
865  // cells are marked bad by default and if any good channel falls in any of
866  // them, they become good
867  if (!bGood) continue;
868 
869  // at this point we know we have to process this channel
870  raw::RawDigit::ADCvector_t const& uncompressed = digit_info.Data();
871 
872  // recover the pedestal
873  float const pedestal = pedestalRetrievalAlg.PedMean(channel);
874 
875  // loop over all the wires that are covered by this channel;
876  // without knowing better, we have to draw into all of them
877  for (geo::WireID const& wireID: WireIDs){
878  // check that the plane and tpc are the correct ones to draw
879  if (wireID.planeID() != pid) continue; // not us!
880 
881  // do we have anything to do with this wire?
882  if (!operation->ProcessWire(wireID)) continue;
883 
884  // get an iterator over the adc values
885  // accumulate all the data of this wire in our "cells"
886  size_t const max_tick = std::min({
887  uncompressed.size(),
888  size_t(fStartTick + fTicks)
889  });
890 
891  for (size_t iTick = fStartTick; iTick < max_tick; ++iTick) {
892 
893  // do we have anything to do with this wire?
894  if (!operation->ProcessTick(iTick)) continue;
895 
896  float const adc = uncompressed[iTick] - pedestal;
897 
898  if (!operation->Operate(wireID, iTick, adc)) return false;
899 
900  } // if good
901  } // for wires
902  } // for channels
903 
904  return operation->Finish();
905  } // ChannelLooper()
906 
907 
908  //......................................................................
910  public:
911 
913  geo::PlaneID const& pid,
914  RawDataDrawer* dataDrawer,
915  evdb::View2D* new_view
916  )
917  : OperationBaseClass(pid, dataDrawer)
918  , view(new_view)
919  , rawCharge(0.), convertedCharge(0.)
920  , drawingRange(*(dataDrawer->fDrawingRange))
921  , ADCCorrector(PlaneID())
922  {}
923 
924  virtual bool Initialize() override
925  {
927 
928  // set up the size of the grid to be visualized;
929  // the information on the size has to be already there:
930  // caller should have user ExtractRange(), or similar, first.
931  // set the minimum cell in ticks to at least match fTicksPerPoint
932  drawingRange.SetMinTDCCellSize((float) rawopt->fTicksPerPoint);
933  // also set the minimum wire cell size to 1,
934  // otherwise there will be cells represented by no wire.
935  drawingRange.SetMinWireCellSize(1.F);
936  boxInfo.clear();
937  boxInfo.resize(drawingRange.NCells());
938  return true;
939  }
940 
941  virtual bool ProcessWire(geo::WireID const& wire) override
942  { return drawingRange.hasWire((int) wire.Wire); }
943 
944  virtual bool ProcessTick(size_t tick) override
945  { return drawingRange.hasTick((float) tick); }
946 
947  virtual bool Operate
948  (geo::WireID const& wireID, size_t tick, float adc) override
949  {
950  geo::WireID::WireID_t const wire = wireID.Wire;
951  std::ptrdiff_t cell = drawingRange.GetCell(wire, tick);
952  if (cell < 0) return true;
953 
954  BoxInfo_t& info = boxInfo[cell];
955  info.good = true; // if in range, we mark this cell as good
956 
957  rawCharge += adc;
958  convertedCharge += ADCCorrector(adc);
959 
960  // draw maximum digit in the cell
961  if (std::abs(info.adc) <= std::abs(adc)) info.adc = adc;
962 
963  return true;
964  }
965 
966  virtual bool Finish() override
967  {
968  // write the information back
969  geo::PlaneID::PlaneID_t const plane = PlaneID().Plane;
970  RawDataDrawerPtr()->fRawCharge[plane] = rawCharge;
971  RawDataDrawerPtr()->fConvertedCharge[plane] = convertedCharge;
972 
973  // the cell size might have changed because of minimum size settings
974  // from configuration (see Initialize())
975  *(RawDataDrawerPtr()->fDrawingRange) = drawingRange;
976 
977  // complete the drawing
978  RawDataDrawerPtr()->QueueDrawingBoxes(view, PlaneID(), boxInfo);
979 
980  return true;
981  }
982 
983  private:
985 
986  double rawCharge = 0., convertedCharge = 0.;
988  std::vector<BoxInfo_t> boxInfo;
990  }; // class RawDataDrawer::BoxDrawer
991 
992 
994  evdb::View2D* view,
995  geo::PlaneID const& pid,
996  std::vector<BoxInfo_t> const& BoxInfo
997  )
998  {
999  //
1000  // All the information is now collected in BoxInfo.
1001  // Make boxes out of it.
1002  //
1003  evd::RawDrawingOptions const& rawopt
1005 
1006  LOG_DEBUG("RawDataDrawer")
1007  << "Filling " << BoxInfo.size() << " boxes to be rendered";
1008 
1009  // drawing options:
1010  float const MinSignal = rawopt.fMinSignal;
1011  bool const bScaleDigitsByCharge = rawopt.fScaleDigitsByCharge;
1012 
1014 
1016  geo::SigType_t const sigType = geom.SignalType(pid);
1017  evdb::ColorScale const& ColorSet = cst->RawQ(sigType);
1018  size_t const nBoxes = BoxInfo.size();
1019  unsigned int nDrawnBoxes = 0;
1020  for (size_t iBox = 0; iBox < nBoxes; ++iBox) {
1021  BoxInfo_t const& info = BoxInfo[iBox];
1022 
1023  // too little signal, don't bother drawing
1024  if(info.good && (std::abs(info.adc) < MinSignal)) continue;
1025 
1026  // skip the bad cells
1027  if (!info.good) continue;
1028 
1029  // box color, proportional to the ADC count
1030  int const color = ColorSet.GetColor(info.adc);
1031 
1032  // scale factor, proportional to ADC count (optional)
1033  constexpr float q0 = 1000.;
1034  float const sf = bScaleDigitsByCharge
1035  ? std::min(std::sqrt((float) info.adc / q0), 1.0F)
1036  : 1.;
1037 
1038  // coordinates of the cell box
1039  float min_wire, max_wire, min_tick, max_tick;
1040  std::tie(min_wire, min_tick, max_wire, max_tick)
1041  = fDrawingRange->GetCellBox(iBox);
1042  /*
1043  LOG_TRACE("RawDataDrawer")
1044  << "Wires ( " << min_wire << " - " << max_wire << " ) ticks ("
1045  << min_tick << " - " << max_tick << " ) for cell " << iBox;
1046  */
1047  if (sf != 1.) { // need to shrink the box
1048  float const nsf = 1. - sf; // negation of scale factor
1049  float const half_box_wires = (max_wire - min_wire) / 2.,
1050  half_box_ticks = (max_tick - min_tick) / 2.;
1051 
1052  // shrink the box:
1053  min_wire += nsf * half_box_wires;
1054  max_wire -= nsf * half_box_wires;
1055  min_tick += nsf * half_box_ticks;
1056  max_tick -= nsf * half_box_ticks;
1057  } // if scaling
1058 
1059  // allocate the box on the view;
1060  // the order of the coordinates depends on the orientation
1061  TBox* pBox;
1062  if (rawopt.fAxisOrientation < 1)
1063  pBox = &(view->AddBox(min_wire, min_tick, max_wire, max_tick));
1064  else
1065  pBox = &(view->AddBox(min_tick, min_wire, max_tick, max_wire));
1066 
1067  pBox->SetFillStyle(1001);
1068  pBox->SetFillColor(color);
1069  pBox->SetBit(kCannotPick);
1070 
1071  ++nDrawnBoxes;
1072  } // for (iBox)
1073 
1074  LOG_DEBUG("RawDataDrawer")
1075  << "Sent " << nDrawnBoxes << "/" << BoxInfo.size()
1076  << " boxes to be rendered";
1077  } // RawDataDrawer::QueueDrawingBoxes()
1078 
1079 
1081  (art::Event const& evt, evdb::View2D* view, unsigned int plane)
1082  {
1083 
1084  // Check if we're supposed to draw raw hits at all
1086  if (rawopt->fDrawRawDataOrCalibWires == 1) return;
1087 
1088  geo::PlaneID const pid(rawopt->CurrentTPC(), plane);
1089  BoxDrawer drawer(pid, this, view);
1090  if (!RunOperation(evt, &drawer)) {
1092  << "RawDataDrawer::RunDrawOperation(): "
1093  "somewhere something went somehow wrong";
1094  }
1095 
1096  } // RawDataDrawer::RunDrawOperation()
1097 
1098 
1099  //......................................................................
1102  {
1103  public:
1104 
1105  float const RoIthreshold;
1106 
1108  : OperationBaseClass(pid, data_drawer)
1109  , RoIthreshold
1110  (art::ServiceHandle<evd::RawDrawingOptions>()->RoIthreshold(PlaneID()))
1111  {}
1112 
1113  virtual bool Operate
1114  (geo::WireID const& wireID, size_t tick, float adc) override
1115  {
1116  if (std::abs(adc) < RoIthreshold) return true;
1117  WireRange.add(wireID.Wire);
1118  TDCrange.add(tick);
1119  return true;
1120  } // Operate()
1121 
1122  virtual bool Finish() override
1123  {
1124  geo::PlaneID::PlaneID_t const plane = PlaneID().Plane;
1125  int& WireMin = pRawDataDrawer->fWireMin[plane];
1126  int& WireMax = pRawDataDrawer->fWireMax[plane];
1127  int& TimeMin = pRawDataDrawer->fTimeMin[plane];
1128  int& TimeMax = pRawDataDrawer->fTimeMax[plane];
1129 
1130  if ((WireMin == WireMax) && WireRange.has_data()) {
1132  mf::LogInfo("RawDataDrawer") << "Region of interest for "
1133  << std::string(PlaneID()) << " detected to be within wires "
1134  << WireRange.min() << " to " << WireRange.max()
1135  << " (plane has " << geom.Nwires(PlaneID()) << " wires)";
1136  WireMax = WireRange.max() + 1;
1137  WireMin = WireRange.min();
1138  }
1139  if ((TimeMin == TimeMax) && TDCrange.has_data()) {
1140  mf::LogInfo("RawDataDrawer") << "Region of interest for "
1141  << std::string(PlaneID()) << " detected to be within ticks "
1142  << TDCrange.min() << " to " << TDCrange.max();
1143  TimeMax = TDCrange.max() + 1;
1144  TimeMin = TDCrange.min();
1145  }
1146  return true;
1147  } // Finish()
1148 
1149  private:
1151  }; // class RawDataDrawer::RoIextractorClass
1152 
1153 
1155  (art::Event const& evt, unsigned int plane)
1156  {
1158  geo::PlaneID const pid(rawopt->CurrentTPC(), plane);
1159 
1160  // if we have no region of interest, prepare to extract it
1161  bool const bExtractRoI = !hasRegionOfInterest(plane);
1162  LOG_TRACE("RawDataDrawer") << "Region of interest for " << pid
1163  << (bExtractRoI? " extracted": " not extracted") << " on this draw";
1164 
1165  if (!bExtractRoI) return;
1166 
1167  RoIextractorClass Extractor(pid, this);
1168  if (!RunOperation(evt, &Extractor)) {
1169  throw std::runtime_error
1170  ("RawDataDrawer::RunRoIextractor(): somewhere something went somehow wrong");
1171  }
1172 
1173  } // RawDataDrawer::RunRoIextractor()
1174 
1175 
1176  //......................................................................
1177 
1179  art::Event const& evt, evdb::View2D* view, unsigned int plane,
1180  bool bZoomToRoI /* = false */
1181  )
1182  {
1183 
1185  geo::PlaneID const pid(rawopt->CurrentTPC(), plane);
1186 
1187  bool const bDraw = (rawopt->fDrawRawDataOrCalibWires != 1);
1188  // if we don't need to draw, don't bother doing anything;
1189  // if the region of interest is required, RunRoIextractor() should be called
1190  // (ok, now it's private, but it could be exposed)
1191  if (!bDraw) return;
1192 
1193  // make sure we reset what needs to be reset
1194  // before the operations are initialized;
1195  // we call for reading raw digits; they will be cached, so it's not a waste
1196  details::CacheID_t NewCacheID(evt, rawopt->fRawDataLabel, pid);
1197  GetRawDigits(evt, NewCacheID);
1198 
1199  bool const hasRoI = hasRegionOfInterest(plane);
1200 
1201  // - if we don't have a RoI yet, we want to get it while we draw
1202  // * if we are zooming into it now, we have to extract it first, then draw
1203  // * if we are not zooming, we can do both at the same time
1204  // - if we have a RoI, we don't want to extract it again
1205  if (!bZoomToRoI) { // we are not required to zoom to the RoI
1206 
1207  std::unique_ptr<OperationBaseClass> operation;
1208 
1209  // we will do the drawing in one pass
1210  LOG_DEBUG("RawDataDrawer")
1211  << __func__ << "() setting up one-pass drawing";
1212  operation.reset(new BoxDrawer(pid, this, view));
1213 
1214  if (!hasRoI) { // we don't have any RoI; since it's cheap, let's get it
1215  LOG_DEBUG("RawDataDrawer") << __func__ << "() adding RoI extraction";
1216 
1217  // swap cards: operation becomes a multiple operation:
1218  // - prepare the two operations (one is there already, somehow)
1219  std::unique_ptr<OperationBaseClass> drawer(std::move(operation));
1220  std::unique_ptr<OperationBaseClass> extractor
1221  (new RoIextractorClass(pid, this));
1222  // - create a new composite operation and give it the sub-ops
1223  operation.reset(new ManyOperations(pid, this));
1224  ManyOperations* pManyOps
1225  = static_cast<ManyOperations*>(operation.get());
1226  pManyOps->AddOperation(std::move(drawer));
1227  pManyOps->AddOperation(std::move(extractor));
1228  }
1229 
1230  if (!RunOperation(evt, operation.get())) {
1232  << "RawDataDrawer::RunDrawOperation(): "
1233  "somewhere something went somehow wrong";
1234  }
1235  }
1236  else { // we are zooming to RoI
1237  // first, we want the RoI extracted; the extractor will update this object
1238  if (!hasRoI) {
1239  LOG_DEBUG("RawDataDrawer") << __func__
1240  << "() setting up RoI extraction for " << pid;
1241  RoIextractorClass extractor(pid, this);
1242  if (!RunOperation(evt, &extractor)) {
1244  << "RawDataDrawer::RunDrawOperation():"
1245  " something went somehow wrong while extracting RoI";
1246  }
1247  }
1248  else {
1249  LOG_DEBUG("RawDataDrawer") << __func__
1250  << "() using existing RoI for " << pid
1251  << ": wires ( " << fWireMin[plane] << " - " << fWireMax[plane]
1252  << " ), ticks ( " << fTimeMin[plane] << " - " << fTimeMax[plane]
1253  << " )";
1254  }
1255 
1256  // adopt the drawing limits information from the wire/time limits
1258 
1259  // then we draw
1260  LOG_DEBUG("RawDataDrawer") << __func__ << "() setting up drawing";
1261  BoxDrawer drawer(pid, this, view);
1262  if (!RunOperation(evt, &drawer)) {
1264  << "RawDataDrawer::RunDrawOperation():"
1265  " something went somehow wrong while drawing";
1266  }
1267  }
1268  } // RawDataDrawer::RawDigit2D()
1269 
1270 
1271  //........................................................................
1272  int RawDataDrawer::GetRegionOfInterest(int plane,int& minw,int& maxw,int& mint,int& maxt)
1273  {
1275 
1276  if((unsigned int)plane>=fWireMin.size())
1277  {mf::LogWarning ("RawDataDrawer") << " Requested plane " << plane <<" is larger than those available " << std::endl;
1278  return -1;
1279  }
1280 
1281  minw=fWireMin[plane];
1282  maxw=fWireMax[plane];
1283  mint=fTimeMin[plane];
1284  maxt=fTimeMax[plane];
1285 
1286  if ((minw == maxw) || (mint == maxt)) return 1;
1287 
1288  //make values a bit larger, but make sure they don't go out of bounds
1289  minw= (minw-30<0) ? 0 : minw-30;
1290  mint= (mint-10<0) ? 0 : mint-10;
1291 
1292  maxw= (maxw+10>(int)geo->Nwires(plane)) ? geo->Nwires(plane) : maxw+10;
1293  maxt= (maxt+10>TotalClockTicks()) ? TotalClockTicks() : maxt+10;
1294 
1295  return 0;
1296  }
1297 
1298  //......................................................................
1299  void RawDataDrawer::GetChargeSum(int plane,double& charge,double& convcharge)
1300  {
1301  charge=fRawCharge[plane];
1302  convcharge=fConvertedCharge[plane];
1303 
1304  }
1305 
1306  //......................................................................
1308  unsigned int plane,
1309  TH1F* histo)
1310  {
1311 
1312  // Check if we're supposed to draw raw hits at all
1314  if (rawopt->fDrawRawDataOrCalibWires==1) return;
1315 
1317 
1318  geo::PlaneID const pid(rawopt->CurrentTPC(), plane);
1319  details::CacheID_t NewCacheID(evt, rawopt->fRawDataLabel, pid);
1320  GetRawDigits(evt, NewCacheID);
1321 
1322  lariov::ChannelStatusProvider const& channelStatus
1324 
1325  //get pedestal conditions
1326  const lariov::DetPedestalProvider& pedestalRetrievalAlg = art::ServiceHandle<lariov::DetPedestalService>()->GetPedestalProvider();
1327 
1328  for (evd::details::RawDigitInfo_t const& digit_info: *digit_cache) {
1329  raw::RawDigit const& hit = digit_info.Digit();
1330  raw::ChannelID_t const channel = hit.Channel();
1331 
1332  if (!channelStatus.IsPresent(channel)) continue;
1333 
1334  // The following test is meant to be temporary until the "correct" solution is implemented
1335  if (!ProcessChannelWithStatus(channelStatus.Status(channel))) continue;
1336 
1337  // to be explicit: we don't cound bad channels in
1338  if (!rawopt->fSeeBadChannels && channelStatus.IsBad(channel)) continue;
1339 
1340  std::vector<geo::WireID> wireids = geo->ChannelToWire(channel);
1341  for(auto const& wid : wireids){
1342  // check that the plane and tpc are the correct ones to draw
1343  if (wid.planeID() != pid) continue;
1344 
1345  raw::RawDigit::ADCvector_t const& uncompressed = digit_info.Data();
1346 
1347  float const pedestal = pedestalRetrievalAlg.PedMean(channel);
1348 
1349  for(short d: uncompressed)
1350  histo->Fill(float(d) - pedestal); //pedestals[plane]); //hit.GetPedestal());
1351 
1352  // this channel is on the correct plane, don't double count the raw signal
1353  // if there are more than one wids for the channel
1354  break;
1355  }// end loop over wids
1356  }//end loop over raw hits
1357 
1358  }
1359 
1360  //......................................................................
1362  unsigned int plane,
1363  unsigned int wire,
1364  TH1F* histo)
1365  {
1366 
1367  // Check if we're supposed to draw raw hits at all
1369  if (rawopt->fDrawRawDataOrCalibWires==1) return;
1370 
1371  // make sure we have the raw digits cached
1372  geo::PlaneID const pid(rawopt->CurrentTPC(), plane);
1373  details::CacheID_t NewCacheID(evt, rawopt->fRawDataLabel, pid);
1374  GetRawDigits(evt, NewCacheID);
1375 
1376  if (digit_cache->empty()) return;
1377 
1378  geo::WireID const wireid(pid, wire);
1379 
1380  // find the channel
1382  raw::ChannelID_t const channel = geom->PlaneWireToChannel(wireid);
1383  if (!raw::isValidChannelID(channel)) { // no channel, empty histogram
1384  mf::LogError("RawDataDrawer") << __func__ << ": no channel associated to "
1385  << std::string(wireid);
1386  return;
1387  } // if no channel
1388 
1389  // check the channel status; bad channels are still ok.
1390  lariov::ChannelStatusProvider const& channelStatus
1392 
1393  if (!channelStatus.IsPresent(channel)) return;
1394 
1395  // The following test is meant to be temporary until the "correct" solution is implemented
1396  if (!ProcessChannelWithStatus(channelStatus.Status(channel))) return;
1397 
1398 
1399  // we accept to see the content of a bad channel, so this is commented out:
1400  if (!rawopt->fSeeBadChannels && channelStatus.IsBad(channel)) return;
1401 
1402  //get pedestal conditions
1403  const lariov::DetPedestalProvider& pedestalRetrievalAlg = art::ServiceHandle<lariov::DetPedestalService>()->GetPedestalProvider();
1404 
1405  // find the raw digit
1406  // (iDigit is an iterator to a evd::details::RawDigitInfo_t)
1407  evd::details::RawDigitInfo_t const* pDigit
1408  = digit_cache->FindChannel(channel);
1409  if (!pDigit) { // this is weird...
1410  mf::LogWarning("RawDataDrawer") << __func__
1411  << ": can't find raw digit for channel #" << channel
1412  << " (" << std::string(wireid) << ")";
1413  return;
1414  }
1415 
1416  raw::RawDigit::ADCvector_t const& uncompressed = pDigit->Data();
1417 
1418  float const pedestal = pedestalRetrievalAlg.PedMean(channel);
1419 
1420  for(size_t j = 0; j < uncompressed.size(); ++j)
1421  histo->Fill(float(j), float(uncompressed[j]) - pedestal); //pedestals[plane]); //hit.GetPedestal());
1422 
1423  } // RawDataDrawer::FillTQHisto()
1424 
1425  //......................................................................
1426 
1427  // void RawDataDrawer::RawDigit3D(const art::Event& evt,
1428  // evdb::View3D* view)
1429  // {
1430  // // Check if we're supposed to draw raw hits at all
1431  // art::ServiceHandle<evd::RawDrawingOptions> rawopt;
1432  // if (rawopt->fDrawRawOrCalibHits!=0) return;
1433 
1434 
1435  // art::ServiceHandle<geo::Geometry> geom;
1436 
1437  // HitTower tower;
1438  // tower.fQscale = 0.01;
1439 
1440  // for (unsigned int imod=0; imod<rawopt->fRawDigitModules.size(); ++imod) {
1441  // const char* which = rawopt->fRawDigitModules[imod].c_str();
1442 
1443  // std::vector<raw::RawDigit> rawhits;
1444  // GetRawDigits(evt, which, rawhits);
1445 
1446  // for (unsigned int i=0; i<rawhits.size(); ++i) {
1447  // double t = 0;
1448  // double q = 0;
1449  // t = rawhits[i]->fTDC[0];
1450  // for (unsigned int j=0; j<rawhits[i]->NADC(); ++j) {
1451  // q += rawhits[i]->ADC(j);
1452  // }
1453  // // Hack for now...
1454  // if (q<=0.0) q = 1+i%10;
1455 
1456  // // Get the cell geometry for the hit
1457  // int iplane = cmap->GetPlane(rawhits[i].get());
1458  // int icell = cmap->GetCell(rawhits[i].get());
1459  // double xyz[3];
1460  // double dpos[3];
1461  // geo::View_t v;
1462  // geom->CellInfo(iplane, icell, &v, xyz, dpos);
1463 
1464  // switch (rawopt->fRawDigit3DStyle) {
1465  // case 1:
1466  // //
1467  // // Render digits as towers
1468  // //
1469  // if (v==geo::kX) {
1470  // tower.AddHit(v, iplane, icell, xyz[0], xyz[2], q, t);
1471  // }
1472  // else if (v==geo::kY) {
1473  // tower.AddHit(v, iplane, icell, xyz[1], xyz[2], q, t);
1474  // }
1475  // else abort();
1476  // break;
1477  // default:
1478  // //
1479  // // Render Digits as boxes
1480  // //
1481  // TPolyLine3D& p = view->AddPolyLine3D(5,kGreen+1,1,2);
1482  // double sf = std::sqrt(0.01*q);
1483  // if (v==geo::kX) {
1484  // double x1 = xyz[0] - sf*dpos[0];
1485  // double x2 = xyz[0] + sf*dpos[0];
1486  // double z1 = xyz[2] - sf*dpos[2];
1487  // double z2 = xyz[2] + sf*dpos[2];
1488  // p.SetPoint(0, x1, geom->DetHalfHeight(), z1);
1489  // p.SetPoint(1, x2, geom->DetHalfHeight(), z1);
1490  // p.SetPoint(2, x2, geom->DetHalfHeight(), z2);
1491  // p.SetPoint(3, x1, geom->DetHalfHeight(), z2);
1492  // p.SetPoint(4, x1, geom->DetHalfHeight(), z1);
1493  // }
1494  // else if (v==geo::kY) {
1495  // double y1 = xyz[1] - sf*dpos[1];
1496  // double y2 = xyz[1] + sf*dpos[1];
1497  // double z1 = xyz[2] - sf*dpos[2];
1498  // double z2 = xyz[2] + sf*dpos[2];
1499  // p.SetPoint(0, geom->DetHalfWidth(), y1, z1);
1500  // p.SetPoint(1, geom->DetHalfWidth(), y2, z1);
1501  // p.SetPoint(2, geom->DetHalfWidth(), y2, z2);
1502  // p.SetPoint(3, geom->DetHalfWidth(), y1, z2);
1503  // p.SetPoint(4, geom->DetHalfWidth(), y1, z1);
1504  // }
1505  // else abort();
1506  // break;
1507  // } // switch fRawDigit3DStyle
1508  // }//end loop over raw digits
1509  // }// end loop over RawDigit modules
1510 
1511  // // Render the towers for that style choice
1512  // if (rawopt->fRawDigit3DStyle==1) tower.Draw(view);
1513  // }
1514 
1515  //......................................................................
1517 
1518  return (fWireMax[plane] != -1) && (fTimeMax[plane] != -1);
1519 
1520  } // RawDataDrawer::hasRegionOfInterest()
1521 
1522 
1523  //......................................................................
1525 
1526  LOG_DEBUG("RawDataDrawer") << "RawDataDrawer[" << ((void*) this)
1527  << "]: resetting the region of interest";
1528 
1529  std::fill(fWireMin.begin(), fWireMin.end(), -1);
1530  std::fill(fWireMax.begin(), fWireMax.end(), -1);
1531  std::fill(fTimeMin.begin(), fTimeMin.end(), -1);
1532  std::fill(fTimeMax.begin(), fTimeMax.end(), -1);
1533 
1534  } // RawDataDrawer::ResetRegionOfInterest()
1535 
1536 
1537  //......................................................................
1538 
1540  (art::Event const& evt, details::CacheID_t const& new_timestamp)
1541  {
1542  LOG_DEBUG("RawDataDrawer") << "GetRawDigits() for " << new_timestamp
1543  << " (last for: " << *fCacheID << ")";
1544 
1545  // update cache
1546  digit_cache->Update(evt, new_timestamp);
1547 
1548  // if time stamp is changing, we want to reconsider which region is
1549  // interesting
1550  if (!fCacheID->sameTPC(new_timestamp)) ResetRegionOfInterest();
1551 
1552  // all the caches have been properly updated or invalidated;
1553  // we are now on a new cache state
1554  *fCacheID = new_timestamp;
1555 
1556  } // RawDataDrawer::GetRawDigits()
1557 
1558 
1559  //......................................................................
1561  (lariov::ChannelStatusProvider::Status_t channel_status) const
1562  {
1563  // if we don't have a valid status, we can't reject the channel
1564  if (!lariov::ChannelStatusProvider::IsValidStatus(channel_status))
1565  return true;
1566 
1567  // is the status "too bad"?
1569  if (channel_status > drawopt->fMaxChannelStatus) return false;
1570  if (channel_status < drawopt->fMinChannelStatus) return false;
1571 
1572  // no reason to reject it...
1573  return true;
1574  } // RawDataDrawer::ProcessChannel()
1575 
1576  //----------------------------------------------------------------------------
1577  namespace details {
1578 
1579  //--------------------------------------------------------------------------
1580  //--- RawDigitInfo_t
1581  //---
1582  raw::RawDigit::ADCvector_t const& RawDigitInfo_t::Data() const {
1583  if (!data.hasData()) UncompressData();
1584  return *data;
1585  } // RawDigitInfo_t::Data()
1586 
1587 
1589  data.Clear();
1590  digit = src;
1591  } // RawDigitInfo_t::Fill()
1592 
1593 
1594  void RawDigitInfo_t::Clear() {
1595  data.Clear();
1596  sample_info.reset();
1597  }
1598 
1599 
1600  void RawDigitInfo_t::UncompressData() const {
1601  data.Clear();
1602 
1603  if (!digit) return; // no original data, can't do anything
1604 
1606 
1607  if (digit->Compression() == kNone) {
1608  // no compression, we can refer to the original data directly
1609  data.PointToData(digit->ADCs());
1610  }
1611  else {
1612  // data is compressed, need to do the real work
1613  if (drawopt->fUncompressWithPed){//Use pedestal in uncompression
1614  int pedestal = (int)digit->GetPedestal();
1616  Uncompress(digit->ADCs(), samples, pedestal, digit->Compression());
1617  data.StealData(std::move(samples));
1618  }
1619  else{
1621  Uncompress(digit->ADCs(), samples, digit->Compression());
1622  data.StealData(std::move(samples));
1623  }
1624  }
1625  } // RawDigitInfo_t::UncompressData()
1626 
1627 
1628  void RawDigitInfo_t::CollectSampleInfo() const {
1629  raw::RawDigit::ADCvector_t const& samples = Data();
1630 
1631  // lar::util::StatCollector<double> stat;
1632  // stat.add(samples.begin(), samples.end());
1633 
1635  (samples.begin(), samples.end());
1636 
1637  sample_info.reset(new SampleInfo_t);
1638  sample_info->min_charge = stat.min();
1639  sample_info->max_charge = stat.max();
1640  // sample_info->average_charge = stat.Average();
1641 
1642  } // RawDigitInfo_t::CollectSampleInfo()
1643 
1644 
1645  RawDigitInfo_t::SampleInfo_t const& RawDigitInfo_t::SampleInfo() const {
1646  if (!sample_info) CollectSampleInfo();
1647  return *sample_info;
1648  } // SampleInfo()
1649 
1650  template <typename Stream>
1651  void RawDigitInfo_t::Dump(Stream&& out) const {
1652  out << " digit at " << ((void*) digit.get()) << " on channel #" << digit->Channel()
1653  << " with " << digit->NADC();
1654  if (digit->Compression() == kNone) out << " uncompressed data";
1655  else out << " data items compressed with <" << digit->Compression() << ">";
1656  if (data.hasData())
1657  out << " with data (" << data->size() << " samples)";
1658  else out << " without data";
1659  } // RawDigitInfo_t::Dump()
1660 
1661  //--------------------------------------------------------------------------
1662  //--- RawDigitCacheDataClass
1663  //---
1664 
1665  RawDigitInfo_t const* RawDigitCacheDataClass::FindChannel
1666  (raw::ChannelID_t channel) const
1667  {
1668  auto iDigit = std::find_if(
1669  digits.cbegin(), digits.cend(),
1670  [channel](evd::details::RawDigitInfo_t const& digit)
1671  { return digit.Channel() == channel; }
1672  );
1673  return (iDigit == digits.cend())? nullptr: &*iDigit;
1674  } // RawDigitCacheDataClass::FindChannel()
1675 
1676  std::vector<raw::RawDigit> const* RawDigitCacheDataClass::ReadProduct
1678  {
1680  if (!evt.getByLabel(label, rdcol)) return nullptr;
1681  return &*rdcol;
1682  } // RawDigitCacheDataClass::ReadProduct()
1683 
1684 
1685  void RawDigitCacheDataClass::Refill
1686  (art::Handle<std::vector<raw::RawDigit>>& rdcol)
1687  {
1688  digits.resize(rdcol->size());
1689  for(size_t iDigit = 0; iDigit < rdcol->size(); ++iDigit) {
1690  art::Ptr<raw::RawDigit> pDigit(rdcol, iDigit);
1691  digits[iDigit].Fill(pDigit);
1692  size_t samples = pDigit->Samples();
1693  if (samples > max_samples) max_samples = samples;
1694  } // for
1695  } // RawDigitCacheDataClass::Refill()
1696 
1697 
1698  void RawDigitCacheDataClass::Invalidate() {
1699  timestamp.clear();
1700  } // RawDigitCacheDataClass::Invalidate()
1701 
1702 
1703  void RawDigitCacheDataClass::Clear() {
1704  Invalidate();
1705  digits.clear();
1706  max_samples = 0;
1707  } // RawDigitCacheDataClass::Clear()
1708 
1709 
1711  RawDigitCacheDataClass::CheckUpToDate
1712  (CacheID_t const& ts, art::Event const* evt /* = nullptr */) const
1713  {
1714  BoolWithUpToDateMetadata res{ false, nullptr };
1715 
1716  // normally only if either the event or the product label have changed,
1717  // cache becomes invalid:
1718  if (!ts.sameProduct(timestamp)) return res; // outdated cache
1719 
1720  // But: our cache stores pointers to the original data, and on a new TPC
1721  // the event display may reload the event anew, removing the "old" data
1722  // from memory.
1723  // Since TPC can change with or without the data being invalidated,
1724  // a more accurate verification is needed.
1725 
1726  // if the cache is empty, well, it does not make much difference;
1727  // we invalidate it to be sure
1728  if (empty())
1729  return res; // outdated cache
1730 
1731  if (!evt)
1732  return res; // outdated, since we can't know better without the event
1733 
1734  // here we force reading of the product
1735  res.digits = ReadProduct(*evt, ts.inputLabel());
1736  if (!res.digits)
1737  return res; // outdated cache; this is actually an error
1738 
1739  if (res.digits->empty())
1740  return res; // outdated; no digits (strange!), invalidate just in case
1741 
1742  // use the first digit as test
1743  raw::ChannelID_t channel = res.digits->front().Channel();
1744  RawDigitInfo_t const* pInfo = FindChannel(channel);
1745  if (!pInfo)
1746  return res; // outdated: we don't even have this channel in cache!
1747 
1748  if (&(pInfo->Digit()) != &(res.digits->front()))
1749  return res; // outdated: different memory address for data
1750 
1751  res.bUpToDate = true;
1752  return res; // cache still valid
1753  } // RawDigitCacheDataClass::CheckUpToDate()
1754 
1755 
1757  (art::Event const& evt, CacheID_t const& new_timestamp)
1758  {
1759  BoolWithUpToDateMetadata update_info = CheckUpToDate(new_timestamp, &evt);
1760 
1761  if (update_info) return false; // already up to date: move on!
1762 
1763  LOG_DEBUG("RawDataDrawer")
1764  << "Refilling raw digit cache RawDigitCacheDataClass["
1765  << ((void*) this ) << "] for " << new_timestamp;
1766 
1767  Clear();
1768 
1770  if (!evt.getByLabel(new_timestamp.inputLabel(), rdcol)) {
1771  mf::LogWarning("RawDataDrawer") << "no RawDigit collection '"
1772  << new_timestamp.inputLabel() << "' found";
1773  return true;
1774  }
1775 
1776  Refill(rdcol);
1777 
1778  timestamp = new_timestamp;
1779  return true;
1780  } // RawDigitCacheDataClass::Update()
1781 
1782 
1783  template <typename Stream>
1784  void RawDigitCacheDataClass::Dump(Stream&& out) const {
1785  out << "Cache at " << ((void*) this)
1786  << " with time stamp " << std::string(timestamp)
1787  << " and " << digits.size()
1788  << " entries (maximum sample: " << max_samples << ");"
1789  << " data at " << ((void*) digits.data());
1790  for (RawDigitInfo_t const& digitInfo: digits) {
1791  out << "\n ";
1792  digitInfo.Dump(out);
1793  } // for
1794  out << "\n";
1795  } // RawDigitCacheDataClass::Dump()
1796 
1797 
1798  //--------------------------------------------------------------------------
1799  //--- GridAxisClass
1800  //---
1801  std::ptrdiff_t GridAxisClass::GetCell(float coord) const {
1802  return std::ptrdiff_t((coord - min) / cell_size); // truncate
1803  } // GridAxisClass::GetCell()
1804 
1805 
1806  //--------------------------------------------------------------------------
1807  bool GridAxisClass::Init(size_t nDiv, float new_min, float new_max) {
1808 
1809  n_cells = std::max(nDiv, size_t(1));
1810  return SetLimits(new_min, new_max);
1811 
1812  } // GridAxisClass::Init()
1813 
1814 
1815  //--------------------------------------------------------------------------
1816  bool GridAxisClass::SetLimits(float new_min, float new_max) {
1817  min = new_min;
1818  max = new_max;
1819  cell_size = Length() / float(n_cells);
1820 
1821  return std::isnormal(cell_size);
1822  } // GridAxisClass::SetLimits()
1823 
1824 
1825  //--------------------------------------------------------------------------
1826  bool GridAxisClass::SetMinCellSize(float min_size) {
1827  if (cell_size >= min_size) return false;
1828 
1829  // n_cells gets truncated
1830  n_cells = (size_t) std::max(std::floor(Length() / min_size), 1.0F);
1831 
1832  // reevaluate cell size, that might be different than min_size
1833  // because of n_cells truncation or minimum value
1834  cell_size = Length() / float(n_cells);
1835  return true;
1836  } // GridAxisClass::SetMinCellSize()
1837 
1838 
1839  //--------------------------------------------------------------------------
1840  bool GridAxisClass::SetMaxCellSize(float max_size) {
1841  if (cell_size <= max_size) return false;
1842 
1843  // n_cells gets rounded up
1844  n_cells = (size_t) std::max(std::ceil(Length() / max_size), 1.0F);
1845 
1846  // reevaluate cell size, that might be different than max_size
1847  // because of n_cells rounding or minimum value
1848  cell_size = Length() / float(n_cells);
1849  return true;
1850  } // GridAxisClass::SetMaxCellSize()
1851 
1852 
1853  //--------------------------------------------------------------------------
1854  template <typename Stream>
1855  void GridAxisClass::Dump(Stream&& out) const {
1856  out << NCells() << " cells from " << Min() << " to " << Max()
1857  << " (length: " << Length() << ")";
1858  } // GridAxisClass::Dump()
1859 
1860 
1861  //--------------------------------------------------------------------------
1862  //--- CellGridClass
1863  //---
1864  CellGridClass::CellGridClass(unsigned int nWires, unsigned int nTDC)
1865  : wire_axis((size_t) nWires, 0., float(nWires))
1866  , tdc_axis((size_t) nTDC, 0., float(nTDC))
1867  {
1868  } // CellGridClass::CellGridClass(int, int)
1869 
1870 
1871  //--------------------------------------------------------------------------
1873  float min_wire, float max_wire, unsigned int nWires,
1874  float min_tdc, float max_tdc, unsigned int nTDC
1875  )
1876  : wire_axis((size_t) nWires, min_wire, max_wire)
1877  , tdc_axis((size_t) nTDC, min_tdc, max_tdc)
1878  {
1879  } // CellGridClass::CellGridClass({ float, float, int } x 2)
1880 
1881 
1882  //--------------------------------------------------------------------------
1883  std::ptrdiff_t CellGridClass::GetCell(float wire, float tick) const {
1884  std::ptrdiff_t iWireCell = wire_axis.GetCell(wire);
1885  if (!wire_axis.hasCell(iWireCell)) return std::ptrdiff_t(-1);
1886  std::ptrdiff_t iTDCCell = tdc_axis.GetCell(tick);
1887  if (!tdc_axis.hasCell(iTDCCell)) return std::ptrdiff_t(-1);
1888  return iWireCell * TDCAxis().NCells() + iTDCCell;
1889  } // CellGridClass::GetCell()
1890 
1891 
1892  //--------------------------------------------------------------------------
1893  std::tuple<float, float, float, float> CellGridClass::GetCellBox
1894  (std::ptrdiff_t iCell) const
1895  {
1896  // { w1, t1, w2, t2 }
1897  size_t const nTDCCells = TDCAxis().NCells();
1898  std::ptrdiff_t iWireCell = (std::ptrdiff_t) (iCell / nTDCCells),
1899  iTDCCell = (std::ptrdiff_t) (iCell % nTDCCells);
1900 
1901 
1902  return std::tuple<float, float, float, float>(
1903  WireAxis().LowerEdge(iWireCell), TDCAxis().LowerEdge(iTDCCell),
1904  WireAxis().UpperEdge(iWireCell), TDCAxis().UpperEdge(iTDCCell)
1905  );
1906  } // CellGridClass::GetCellBox()
1907 
1908 
1909  //--------------------------------------------------------------------------
1910  template <typename Stream>
1911  void CellGridClass::Dump(Stream&& out) const {
1912  out << "Wire axis: ";
1913  WireAxis().Dump(out);
1914  out << "; time axis: ";
1915  TDCAxis().Dump(out);
1916  } // CellGridClass::Dump()
1917 
1918 
1919  //--------------------------------------------------------------------------
1920 
1921  } // details
1922 
1923 } // namespace evd
1924 
int GetRegionOfInterest(int plane, int &minw, int &maxw, int &mint, int &maxt)
Data_t max() const
Returns the accumulated maximum, or a very small number if no values.
virtual bool Initialize() override
const_pointer operator->() const
details::CellGridClass drawingRange
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)
bool sameProduct(PlaneDataChangeTracker_t const &as) const
Returns whether we are in the same event (the rest could differ)
bool SetCellSizeBoundary(float min_size, float max_size)
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
virtual bool ProcessTick(size_t tick) override
raw::RawDigit const & Digit() const
Returns an art pointer to the actual digit.
Encapsulate the construction of a single cyostat.
const std::string label
double Correct(float adc) const
Applies Birks correction to the specified pedestal-subtracted charge.
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
virtual bool ProcessTick(size_t tick) override
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)
virtual double BirksCorrection(double dQdX) const =0
dQ/dX in electrons/cm, returns dE/dX in MeV/cm.
void Dump(Stream &&out) const
Prints the current axes on the specified stream.
void SetDrawingLimitsFromRoI(geo::PlaneID::PlaneID_t plane)
double fStartTick
low tick
art::InputTag fRawDataLabel
module label that made the raw digits, default is daq
The data type to uniquely identify a Plane.
Definition: geo_types.h:250
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:211
std::vector< std::unique_ptr< RawDataDrawer::OperationBaseClass > > operations
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.
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
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 update(geo::PlaneID const &pid)
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.
BoxDrawer(geo::PlaneID const &pid, RawDataDrawer *dataDrawer, evdb::View2D *new_view)
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:313
int GetColor(double x) const
Definition: ColorScale.cxx:126
SigType_t SignalType(geo::PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
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)
virtual std::string Name() const override
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
Singleton to hold the current art::Event for the event display.
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
std::vector< double > fRawCharge
Sum of Raw Charge.
unsigned int Nwires(unsigned int p, unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wires in the specified plane.
std::vector< int > fWireMin
lowest wire in interesting region for each plane
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.
unsigned short Samples() const
Number of samples in the uncompressed ADC data.
Definition: RawDigit.h:212
size_t n_cells
number of cells in the axis
friend class RoIextractorClass
details::ADCCorrectorClass ADCCorrector
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)
c1 Update()
OperationBaseClass const * Operator(size_t iOp) const
unsigned int PlaneID_t
Type for the ID number.
Definition: geo_types.h:251
std::add_lvalue_reference_t< value_type > reference
Data_t min() const
Returns the accumulated minimum, or a very large number if no values.
virtual bool Finish() override
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
Int_t max
Definition: plot.C:27
constexpr ChannelID_t InvalidChannelID
ID of an invalid channel.
Definition: RawTypes.h:31
void RunDrawOperation(art::Event const &evt, evdb::View2D *view, unsigned int plane)
float Length() const
Returns the length of the axis.
double fTicks
number of ticks of the clock
intermediate_table::const_iterator const_iterator
mutable::details::PointerToData_t< raw::RawDigit::ADCvector_t const > data
Uncompressed data.
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
bool SetMinWireCellSize(float min_size)
Sets the minimum size for wire cells.
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.
bool hasWire(int wire) const
Returns whether the range includes the specified wire.
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
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
void RawDigit2D(art::Event const &evt, evdb::View2D *view, unsigned int plane, bool bZoomToRoI=false)
Draws raw digit content in 2D wire plane representation.
std::add_lvalue_reference_t< const_value_type > const_reference
Float_t d
Definition: plot.C:237
constexpr bool isValidChannelID(raw::ChannelID_t channel)
Definition: RawTypes.h:36
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:85
The data type to uniquely identify a TPC.
Definition: geo_types.h:195
Description of geometry of one entire detector.
virtual bool ProcessWire(geo::WireID const &wire) override
virtual bool Operate(geo::WireID const &wireID, size_t tick, float adc)=0
ADCCorrectorClass()
Default constructor: awaits for update()
float Max() const
Returns the extremes of the axis.
bool isEmpty() const
Returns whether minimum and maximum match.
virtual bool Initialize() override
bool bOwned
whether we own our data
Class to aid in the rendering of RawData objects.
Detector simulation of raw signals on wires.
virtual bool ProcessWire(geo::WireID const &wireID) override
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)
unsigned int WireID_t
Type for the ID number.
Definition: geo_types.h:306
void NewData(T const &data)
Create a owned copy of the specified object.
raw::ChannelID_t PlaneWireToChannel(WireID const &wireid) const
Returns the ID of the TPC channel connected to the specified wire.
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
virtual bool ProcessWire(geo::WireID const &)
std::string to_string(Flag_t< Storage > const flag)
Convert a flag into a stream (shows its index).
Definition: BitMask.h:187
Encapsulate the construction of a single detector plane.
ADCCorrectorClass(geo::PlaneID const &pid)
Constructor: update()s with the specified information.
bool fSeeBadChannels
Allow "bad" channels to be viewed.
virtual bool Finish() override
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
Int_t min
Definition: plot.C:26
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
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.
Aid in the rendering of RawData objects.
Definition: RawDataDrawer.h:40
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.
#define LOG_DEBUG(id)
HLT enums.
double fStartTick
Starting tick for the display.
bool good
whether the channel is not bad
void Dump(Stream &&out) const
bool owned() const
Returns whether we have data and we own it.
float electronsToADC
conversion constant
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:35
std::add_const_t< value_type > const_value_type
Manages a grid-like division of 2D space.
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:27
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:756
evd::details::RawDigitCacheDataClass * digit_cache
Cache of raw digits.
void SetTDCRange(unsigned int nTDC)
Sets a simple TDC range: all the ticks, one cell per tick.
virtual double ElectronsToADC() const =0
void StealData(std::remove_const_t< T > &&data)
Move data from the specified object, and own it.
Namespace collecting geometry-related classes utilities.
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)
#define LOG_TRACE(id)
std::tuple< float, float, float, float > GetCellBox(std::ptrdiff_t iCell) const
Returns the coordinates { w1, t1, w2, t2 } of specified cell.
art framework interface to geometry description
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 fUncompressWithPed
Option to uncompress with pedestal. Turned off by default.
Encapsulate the construction of a single detector plane.
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.