LArSoft  v07_13_02
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 pedestal = 0;
874  if (rawopt->fPedestalOption == 0)
875  {
876  pedestal = pedestalRetrievalAlg.PedMean(channel);
877  }
878  else if (rawopt->fPedestalOption == 1)
879  {
880  pedestal = hit.GetPedestal();
881  }
882  else if (rawopt->fPedestalOption == 2)
883  {
884  pedestal = 0;
885  }
886  else
887  {
888  mf::LogWarning ("RawDataDrawer") << " PedestalOption is not understood: " << rawopt->fPedestalOption << ". Pedestals not subtracted.";
889  }
890 
891  // loop over all the wires that are covered by this channel;
892  // without knowing better, we have to draw into all of them
893  for (geo::WireID const& wireID: WireIDs){
894  // check that the plane and tpc are the correct ones to draw
895  if (wireID.planeID() != pid) continue; // not us!
896 
897  // do we have anything to do with this wire?
898  if (!operation->ProcessWire(wireID)) continue;
899 
900  // get an iterator over the adc values
901  // accumulate all the data of this wire in our "cells"
902  size_t const max_tick = std::min({
903  uncompressed.size(),
904  size_t(fStartTick + fTicks)
905  });
906 
907  for (size_t iTick = fStartTick; iTick < max_tick; ++iTick) {
908 
909  // do we have anything to do with this wire?
910  if (!operation->ProcessTick(iTick)) continue;
911 
912  float const adc = uncompressed[iTick] - pedestal;
913  //std::cout << "adc, pedestal: " << adc << " " << pedestal << std::endl;
914 
915  if (!operation->Operate(wireID, iTick, adc)) return false;
916 
917  } // if good
918  } // for wires
919  } // for channels
920 
921  return operation->Finish();
922  } // ChannelLooper()
923 
924 
925  //......................................................................
927  public:
928 
930  geo::PlaneID const& pid,
931  RawDataDrawer* dataDrawer,
932  evdb::View2D* new_view
933  )
934  : OperationBaseClass(pid, dataDrawer)
935  , view(new_view)
936  , rawCharge(0.), convertedCharge(0.)
937  , drawingRange(*(dataDrawer->fDrawingRange))
938  , ADCCorrector(PlaneID())
939  {}
940 
941  virtual bool Initialize() override
942  {
944 
945  // set up the size of the grid to be visualized;
946  // the information on the size has to be already there:
947  // caller should have user ExtractRange(), or similar, first.
948  // set the minimum cell in ticks to at least match fTicksPerPoint
949  drawingRange.SetMinTDCCellSize((float) rawopt->fTicksPerPoint);
950  // also set the minimum wire cell size to 1,
951  // otherwise there will be cells represented by no wire.
952  drawingRange.SetMinWireCellSize(1.F);
953  boxInfo.clear();
954  boxInfo.resize(drawingRange.NCells());
955  return true;
956  }
957 
958  virtual bool ProcessWire(geo::WireID const& wire) override
959  { return drawingRange.hasWire((int) wire.Wire); }
960 
961  virtual bool ProcessTick(size_t tick) override
962  { return drawingRange.hasTick((float) tick); }
963 
964  virtual bool Operate
965  (geo::WireID const& wireID, size_t tick, float adc) override
966  {
967  geo::WireID::WireID_t const wire = wireID.Wire;
968  std::ptrdiff_t cell = drawingRange.GetCell(wire, tick);
969  if (cell < 0) return true;
970 
971  BoxInfo_t& info = boxInfo[cell];
972  info.good = true; // if in range, we mark this cell as good
973 
974  rawCharge += adc;
975  convertedCharge += ADCCorrector(adc);
976 
977  // draw maximum digit in the cell
978  if (std::abs(info.adc) <= std::abs(adc)) info.adc = adc;
979 
980  return true;
981  }
982 
983  virtual bool Finish() override
984  {
985  // write the information back
986  geo::PlaneID::PlaneID_t const plane = PlaneID().Plane;
987  RawDataDrawerPtr()->fRawCharge[plane] = rawCharge;
988  RawDataDrawerPtr()->fConvertedCharge[plane] = convertedCharge;
989 
990  // the cell size might have changed because of minimum size settings
991  // from configuration (see Initialize())
992  *(RawDataDrawerPtr()->fDrawingRange) = drawingRange;
993 
994  // complete the drawing
995  RawDataDrawerPtr()->QueueDrawingBoxes(view, PlaneID(), boxInfo);
996 
997  return true;
998  }
999 
1000  private:
1002 
1003  double rawCharge = 0., convertedCharge = 0.;
1005  std::vector<BoxInfo_t> boxInfo;
1007  }; // class RawDataDrawer::BoxDrawer
1008 
1009 
1011  evdb::View2D* view,
1012  geo::PlaneID const& pid,
1013  std::vector<BoxInfo_t> const& BoxInfo
1014  )
1015  {
1016  //
1017  // All the information is now collected in BoxInfo.
1018  // Make boxes out of it.
1019  //
1020  evd::RawDrawingOptions const& rawopt
1022 
1023  LOG_DEBUG("RawDataDrawer")
1024  << "Filling " << BoxInfo.size() << " boxes to be rendered";
1025 
1026  // drawing options:
1027  float const MinSignal = rawopt.fMinSignal;
1028  bool const bScaleDigitsByCharge = rawopt.fScaleDigitsByCharge;
1029 
1031 
1033  geo::SigType_t const sigType = geom.SignalType(pid);
1034  evdb::ColorScale const& ColorSet = cst->RawQ(sigType);
1035  size_t const nBoxes = BoxInfo.size();
1036  unsigned int nDrawnBoxes = 0;
1037  for (size_t iBox = 0; iBox < nBoxes; ++iBox) {
1038  BoxInfo_t const& info = BoxInfo[iBox];
1039 
1040  // too little signal, don't bother drawing
1041  if(info.good && (std::abs(info.adc) < MinSignal)) continue;
1042 
1043  // skip the bad cells
1044  if (!info.good) continue;
1045 
1046  // box color, proportional to the ADC count
1047  int const color = ColorSet.GetColor(info.adc);
1048 
1049  // scale factor, proportional to ADC count (optional)
1050  constexpr float q0 = 1000.;
1051  float const sf = bScaleDigitsByCharge
1052  ? std::min(std::sqrt((float) info.adc / q0), 1.0F)
1053  : 1.;
1054 
1055  // coordinates of the cell box
1056  float min_wire, max_wire, min_tick, max_tick;
1057  std::tie(min_wire, min_tick, max_wire, max_tick)
1058  = fDrawingRange->GetCellBox(iBox);
1059  /*
1060  LOG_TRACE("RawDataDrawer")
1061  << "Wires ( " << min_wire << " - " << max_wire << " ) ticks ("
1062  << min_tick << " - " << max_tick << " ) for cell " << iBox;
1063  */
1064  if (sf != 1.) { // need to shrink the box
1065  float const nsf = 1. - sf; // negation of scale factor
1066  float const half_box_wires = (max_wire - min_wire) / 2.,
1067  half_box_ticks = (max_tick - min_tick) / 2.;
1068 
1069  // shrink the box:
1070  min_wire += nsf * half_box_wires;
1071  max_wire -= nsf * half_box_wires;
1072  min_tick += nsf * half_box_ticks;
1073  max_tick -= nsf * half_box_ticks;
1074  } // if scaling
1075 
1076  // allocate the box on the view;
1077  // the order of the coordinates depends on the orientation
1078  TBox* pBox;
1079  if (rawopt.fAxisOrientation < 1)
1080  pBox = &(view->AddBox(min_wire, min_tick, max_wire, max_tick));
1081  else
1082  pBox = &(view->AddBox(min_tick, min_wire, max_tick, max_wire));
1083 
1084  pBox->SetFillStyle(1001);
1085  pBox->SetFillColor(color);
1086  pBox->SetBit(kCannotPick);
1087 
1088  ++nDrawnBoxes;
1089  } // for (iBox)
1090 
1091  LOG_DEBUG("RawDataDrawer")
1092  << "Sent " << nDrawnBoxes << "/" << BoxInfo.size()
1093  << " boxes to be rendered";
1094  } // RawDataDrawer::QueueDrawingBoxes()
1095 
1096 
1098  (art::Event const& evt, evdb::View2D* view, unsigned int plane)
1099  {
1100 
1101  // Check if we're supposed to draw raw hits at all
1103  if (rawopt->fDrawRawDataOrCalibWires == 1) return;
1104 
1105  geo::PlaneID const pid(rawopt->CurrentTPC(), plane);
1106  BoxDrawer drawer(pid, this, view);
1107  if (!RunOperation(evt, &drawer)) {
1109  << "RawDataDrawer::RunDrawOperation(): "
1110  "somewhere something went somehow wrong";
1111  }
1112 
1113  } // RawDataDrawer::RunDrawOperation()
1114 
1115 
1116  //......................................................................
1119  {
1120  public:
1121 
1122  float const RoIthreshold;
1123 
1125  : OperationBaseClass(pid, data_drawer)
1126  , RoIthreshold
1127  (art::ServiceHandle<evd::RawDrawingOptions>()->RoIthreshold(PlaneID()))
1128  {}
1129 
1130  virtual bool Operate
1131  (geo::WireID const& wireID, size_t tick, float adc) override
1132  {
1133  if (std::abs(adc) < RoIthreshold) return true;
1134  WireRange.add(wireID.Wire);
1135  TDCrange.add(tick);
1136  return true;
1137  } // Operate()
1138 
1139  virtual bool Finish() override
1140  {
1141  geo::PlaneID::PlaneID_t const plane = PlaneID().Plane;
1142  int& WireMin = pRawDataDrawer->fWireMin[plane];
1143  int& WireMax = pRawDataDrawer->fWireMax[plane];
1144  int& TimeMin = pRawDataDrawer->fTimeMin[plane];
1145  int& TimeMax = pRawDataDrawer->fTimeMax[plane];
1146 
1147  if ((WireMin == WireMax) && WireRange.has_data()) {
1149  mf::LogInfo("RawDataDrawer") << "Region of interest for "
1150  << std::string(PlaneID()) << " detected to be within wires "
1151  << WireRange.min() << " to " << WireRange.max()
1152  << " (plane has " << geom.Nwires(PlaneID()) << " wires)";
1153  WireMax = WireRange.max() + 1;
1154  WireMin = WireRange.min();
1155  }
1156  if ((TimeMin == TimeMax) && TDCrange.has_data()) {
1157  mf::LogInfo("RawDataDrawer") << "Region of interest for "
1158  << std::string(PlaneID()) << " detected to be within ticks "
1159  << TDCrange.min() << " to " << TDCrange.max();
1160  TimeMax = TDCrange.max() + 1;
1161  TimeMin = TDCrange.min();
1162  }
1163  return true;
1164  } // Finish()
1165 
1166  private:
1168  }; // class RawDataDrawer::RoIextractorClass
1169 
1170 
1172  (art::Event const& evt, unsigned int plane)
1173  {
1175  geo::PlaneID const pid(rawopt->CurrentTPC(), plane);
1176 
1177  // if we have no region of interest, prepare to extract it
1178  bool const bExtractRoI = !hasRegionOfInterest(plane);
1179  LOG_TRACE("RawDataDrawer") << "Region of interest for " << pid
1180  << (bExtractRoI? " extracted": " not extracted") << " on this draw";
1181 
1182  if (!bExtractRoI) return;
1183 
1184  RoIextractorClass Extractor(pid, this);
1185  if (!RunOperation(evt, &Extractor)) {
1186  throw std::runtime_error
1187  ("RawDataDrawer::RunRoIextractor(): somewhere something went somehow wrong");
1188  }
1189 
1190  } // RawDataDrawer::RunRoIextractor()
1191 
1192 
1193  //......................................................................
1194 
1196  art::Event const& evt, evdb::View2D* view, unsigned int plane,
1197  bool bZoomToRoI /* = false */
1198  )
1199  {
1200 
1202  geo::PlaneID const pid(rawopt->CurrentTPC(), plane);
1203 
1204  bool const bDraw = (rawopt->fDrawRawDataOrCalibWires != 1);
1205  // if we don't need to draw, don't bother doing anything;
1206  // if the region of interest is required, RunRoIextractor() should be called
1207  // (ok, now it's private, but it could be exposed)
1208  if (!bDraw) return;
1209 
1210  // make sure we reset what needs to be reset
1211  // before the operations are initialized;
1212  // we call for reading raw digits; they will be cached, so it's not a waste
1213  details::CacheID_t NewCacheID(evt, rawopt->fRawDataLabel, pid);
1214  GetRawDigits(evt, NewCacheID);
1215 
1216  bool const hasRoI = hasRegionOfInterest(plane);
1217 
1218  // - if we don't have a RoI yet, we want to get it while we draw
1219  // * if we are zooming into it now, we have to extract it first, then draw
1220  // * if we are not zooming, we can do both at the same time
1221  // - if we have a RoI, we don't want to extract it again
1222  if (!bZoomToRoI) { // we are not required to zoom to the RoI
1223 
1224  std::unique_ptr<OperationBaseClass> operation;
1225 
1226  // we will do the drawing in one pass
1227  LOG_DEBUG("RawDataDrawer")
1228  << __func__ << "() setting up one-pass drawing";
1229  operation.reset(new BoxDrawer(pid, this, view));
1230 
1231  if (!hasRoI) { // we don't have any RoI; since it's cheap, let's get it
1232  LOG_DEBUG("RawDataDrawer") << __func__ << "() adding RoI extraction";
1233 
1234  // swap cards: operation becomes a multiple operation:
1235  // - prepare the two operations (one is there already, somehow)
1236  std::unique_ptr<OperationBaseClass> drawer(std::move(operation));
1237  std::unique_ptr<OperationBaseClass> extractor
1238  (new RoIextractorClass(pid, this));
1239  // - create a new composite operation and give it the sub-ops
1240  operation.reset(new ManyOperations(pid, this));
1241  ManyOperations* pManyOps
1242  = static_cast<ManyOperations*>(operation.get());
1243  pManyOps->AddOperation(std::move(drawer));
1244  pManyOps->AddOperation(std::move(extractor));
1245  }
1246 
1247  if (!RunOperation(evt, operation.get())) {
1249  << "RawDataDrawer::RunDrawOperation(): "
1250  "somewhere something went somehow wrong";
1251  }
1252  }
1253  else { // we are zooming to RoI
1254  // first, we want the RoI extracted; the extractor will update this object
1255  if (!hasRoI) {
1256  LOG_DEBUG("RawDataDrawer") << __func__
1257  << "() setting up RoI extraction for " << pid;
1258  RoIextractorClass extractor(pid, this);
1259  if (!RunOperation(evt, &extractor)) {
1261  << "RawDataDrawer::RunDrawOperation():"
1262  " something went somehow wrong while extracting RoI";
1263  }
1264  }
1265  else {
1266  LOG_DEBUG("RawDataDrawer") << __func__
1267  << "() using existing RoI for " << pid
1268  << ": wires ( " << fWireMin[plane] << " - " << fWireMax[plane]
1269  << " ), ticks ( " << fTimeMin[plane] << " - " << fTimeMax[plane]
1270  << " )";
1271  }
1272 
1273  // adopt the drawing limits information from the wire/time limits
1275 
1276  // then we draw
1277  LOG_DEBUG("RawDataDrawer") << __func__ << "() setting up drawing";
1278  BoxDrawer drawer(pid, this, view);
1279  if (!RunOperation(evt, &drawer)) {
1281  << "RawDataDrawer::RunDrawOperation():"
1282  " something went somehow wrong while drawing";
1283  }
1284  }
1285  } // RawDataDrawer::RawDigit2D()
1286 
1287 
1288  //........................................................................
1289  int RawDataDrawer::GetRegionOfInterest(int plane,int& minw,int& maxw,int& mint,int& maxt)
1290  {
1292 
1293  if((unsigned int)plane>=fWireMin.size())
1294  {mf::LogWarning ("RawDataDrawer") << " Requested plane " << plane <<" is larger than those available " << std::endl;
1295  return -1;
1296  }
1297 
1298  minw=fWireMin[plane];
1299  maxw=fWireMax[plane];
1300  mint=fTimeMin[plane];
1301  maxt=fTimeMax[plane];
1302 
1303  if ((minw == maxw) || (mint == maxt)) return 1;
1304 
1305  //make values a bit larger, but make sure they don't go out of bounds
1306  minw= (minw-30<0) ? 0 : minw-30;
1307  mint= (mint-10<0) ? 0 : mint-10;
1308 
1309  maxw= (maxw+10>(int)geo->Nwires(plane)) ? geo->Nwires(plane) : maxw+10;
1310  maxt= (maxt+10>TotalClockTicks()) ? TotalClockTicks() : maxt+10;
1311 
1312  return 0;
1313  }
1314 
1315  //......................................................................
1316  void RawDataDrawer::GetChargeSum(int plane,double& charge,double& convcharge)
1317  {
1318  charge=fRawCharge[plane];
1319  convcharge=fConvertedCharge[plane];
1320 
1321  }
1322 
1323  //......................................................................
1325  unsigned int plane,
1326  TH1F* histo)
1327  {
1328 
1329  // Check if we're supposed to draw raw hits at all
1331  if (rawopt->fDrawRawDataOrCalibWires==1) return;
1332 
1334 
1335  geo::PlaneID const pid(rawopt->CurrentTPC(), plane);
1336  details::CacheID_t NewCacheID(evt, rawopt->fRawDataLabel, pid);
1337  GetRawDigits(evt, NewCacheID);
1338 
1339  lariov::ChannelStatusProvider const& channelStatus
1341 
1342  //get pedestal conditions
1343  const lariov::DetPedestalProvider& pedestalRetrievalAlg = art::ServiceHandle<lariov::DetPedestalService>()->GetPedestalProvider();
1344 
1345  for (evd::details::RawDigitInfo_t const& digit_info: *digit_cache) {
1346  raw::RawDigit const& hit = digit_info.Digit();
1347  raw::ChannelID_t const channel = hit.Channel();
1348 
1349  if (!channelStatus.IsPresent(channel)) continue;
1350 
1351  // The following test is meant to be temporary until the "correct" solution is implemented
1352  if (!ProcessChannelWithStatus(channelStatus.Status(channel))) continue;
1353 
1354  // to be explicit: we don't cound bad channels in
1355  if (!rawopt->fSeeBadChannels && channelStatus.IsBad(channel)) continue;
1356 
1357  std::vector<geo::WireID> wireids = geo->ChannelToWire(channel);
1358  for(auto const& wid : wireids){
1359  // check that the plane and tpc are the correct ones to draw
1360  if (wid.planeID() != pid) continue;
1361 
1362  raw::RawDigit::ADCvector_t const& uncompressed = digit_info.Data();
1363 
1364  //float const pedestal = pedestalRetrievalAlg.PedMean(channel);
1365  // recover the pedestal
1366  float pedestal = 0;
1367  if (rawopt->fPedestalOption == 0)
1368  {
1369  pedestal = pedestalRetrievalAlg.PedMean(channel);
1370  }
1371  else if (rawopt->fPedestalOption == 1)
1372  {
1373  pedestal = hit.GetPedestal();
1374  }
1375  else if (rawopt->fPedestalOption == 2)
1376  {
1377  pedestal = 0;
1378  }
1379  else
1380  {
1381  mf::LogWarning ("RawDataDrawer") << " PedestalOption is not understood: " << rawopt->fPedestalOption << ". Pedestals not subtracted.";
1382  }
1383 
1384  for(short d: uncompressed)
1385  histo->Fill(float(d) - pedestal); //pedestals[plane]); //hit.GetPedestal());
1386 
1387  // this channel is on the correct plane, don't double count the raw signal
1388  // if there are more than one wids for the channel
1389  break;
1390  }// end loop over wids
1391  }//end loop over raw hits
1392 
1393  }
1394 
1395  //......................................................................
1397  unsigned int plane,
1398  unsigned int wire,
1399  TH1F* histo)
1400  {
1401 
1402  // Check if we're supposed to draw raw hits at all
1404  if (rawopt->fDrawRawDataOrCalibWires==1) return;
1405 
1406  // make sure we have the raw digits cached
1407  geo::PlaneID const pid(rawopt->CurrentTPC(), plane);
1408  details::CacheID_t NewCacheID(evt, rawopt->fRawDataLabel, pid);
1409  GetRawDigits(evt, NewCacheID);
1410 
1411  if (digit_cache->empty()) return;
1412 
1413  geo::WireID const wireid(pid, wire);
1414 
1415  // find the channel
1417  raw::ChannelID_t const channel = geom->PlaneWireToChannel(wireid);
1418  if (!raw::isValidChannelID(channel)) { // no channel, empty histogram
1419  mf::LogError("RawDataDrawer") << __func__ << ": no channel associated to "
1420  << std::string(wireid);
1421  return;
1422  } // if no channel
1423 
1424  // check the channel status; bad channels are still ok.
1425  lariov::ChannelStatusProvider const& channelStatus
1427 
1428  if (!channelStatus.IsPresent(channel)) return;
1429 
1430  // The following test is meant to be temporary until the "correct" solution is implemented
1431  if (!ProcessChannelWithStatus(channelStatus.Status(channel))) return;
1432 
1433 
1434  // we accept to see the content of a bad channel, so this is commented out:
1435  if (!rawopt->fSeeBadChannels && channelStatus.IsBad(channel)) return;
1436 
1437  //get pedestal conditions
1438  const lariov::DetPedestalProvider& pedestalRetrievalAlg = art::ServiceHandle<lariov::DetPedestalService>()->GetPedestalProvider();
1439 
1440  // find the raw digit
1441  // (iDigit is an iterator to a evd::details::RawDigitInfo_t)
1442  evd::details::RawDigitInfo_t const* pDigit
1443  = digit_cache->FindChannel(channel);
1444  if (!pDigit) { // this is weird...
1445  mf::LogWarning("RawDataDrawer") << __func__
1446  << ": can't find raw digit for channel #" << channel
1447  << " (" << std::string(wireid) << ")";
1448  return;
1449  }
1450 
1451  raw::RawDigit::ADCvector_t const& uncompressed = pDigit->Data();
1452 
1453 
1454  // recover the pedestal
1455  float pedestal = 0;
1456  if (rawopt->fPedestalOption == 0)
1457  {
1458  pedestal = pedestalRetrievalAlg.PedMean(channel);
1459  }
1460  else if (rawopt->fPedestalOption == 1)
1461  {
1462  pedestal = pDigit->DigitPtr()->GetPedestal();
1463  }
1464  else if (rawopt->fPedestalOption == 2)
1465  {
1466  pedestal = 0;
1467  }
1468  else
1469  {
1470  mf::LogWarning ("RawDataDrawer") << " PedestalOption is not understood: " << rawopt->fPedestalOption << ". Pedestals not subtracted.";
1471  }
1472 
1473  for(size_t j = 0; j < uncompressed.size(); ++j)
1474  histo->Fill(float(j), float(uncompressed[j]) - pedestal); //pedestals[plane]); //hit.GetPedestal());
1475 
1476  } // RawDataDrawer::FillTQHisto()
1477 
1478  //......................................................................
1479 
1480  // void RawDataDrawer::RawDigit3D(const art::Event& evt,
1481  // evdb::View3D* view)
1482  // {
1483  // // Check if we're supposed to draw raw hits at all
1484  // art::ServiceHandle<evd::RawDrawingOptions> rawopt;
1485  // if (rawopt->fDrawRawOrCalibHits!=0) return;
1486 
1487 
1488  // art::ServiceHandle<geo::Geometry> geom;
1489 
1490  // HitTower tower;
1491  // tower.fQscale = 0.01;
1492 
1493  // for (unsigned int imod=0; imod<rawopt->fRawDigitModules.size(); ++imod) {
1494  // const char* which = rawopt->fRawDigitModules[imod].c_str();
1495 
1496  // std::vector<raw::RawDigit> rawhits;
1497  // GetRawDigits(evt, which, rawhits);
1498 
1499  // for (unsigned int i=0; i<rawhits.size(); ++i) {
1500  // double t = 0;
1501  // double q = 0;
1502  // t = rawhits[i]->fTDC[0];
1503  // for (unsigned int j=0; j<rawhits[i]->NADC(); ++j) {
1504  // q += rawhits[i]->ADC(j);
1505  // }
1506  // // Hack for now...
1507  // if (q<=0.0) q = 1+i%10;
1508 
1509  // // Get the cell geometry for the hit
1510  // int iplane = cmap->GetPlane(rawhits[i].get());
1511  // int icell = cmap->GetCell(rawhits[i].get());
1512  // double xyz[3];
1513  // double dpos[3];
1514  // geo::View_t v;
1515  // geom->CellInfo(iplane, icell, &v, xyz, dpos);
1516 
1517  // switch (rawopt->fRawDigit3DStyle) {
1518  // case 1:
1519  // //
1520  // // Render digits as towers
1521  // //
1522  // if (v==geo::kX) {
1523  // tower.AddHit(v, iplane, icell, xyz[0], xyz[2], q, t);
1524  // }
1525  // else if (v==geo::kY) {
1526  // tower.AddHit(v, iplane, icell, xyz[1], xyz[2], q, t);
1527  // }
1528  // else abort();
1529  // break;
1530  // default:
1531  // //
1532  // // Render Digits as boxes
1533  // //
1534  // TPolyLine3D& p = view->AddPolyLine3D(5,kGreen+1,1,2);
1535  // double sf = std::sqrt(0.01*q);
1536  // if (v==geo::kX) {
1537  // double x1 = xyz[0] - sf*dpos[0];
1538  // double x2 = xyz[0] + sf*dpos[0];
1539  // double z1 = xyz[2] - sf*dpos[2];
1540  // double z2 = xyz[2] + sf*dpos[2];
1541  // p.SetPoint(0, x1, geom->DetHalfHeight(), z1);
1542  // p.SetPoint(1, x2, geom->DetHalfHeight(), z1);
1543  // p.SetPoint(2, x2, geom->DetHalfHeight(), z2);
1544  // p.SetPoint(3, x1, geom->DetHalfHeight(), z2);
1545  // p.SetPoint(4, x1, geom->DetHalfHeight(), z1);
1546  // }
1547  // else if (v==geo::kY) {
1548  // double y1 = xyz[1] - sf*dpos[1];
1549  // double y2 = xyz[1] + sf*dpos[1];
1550  // double z1 = xyz[2] - sf*dpos[2];
1551  // double z2 = xyz[2] + sf*dpos[2];
1552  // p.SetPoint(0, geom->DetHalfWidth(), y1, z1);
1553  // p.SetPoint(1, geom->DetHalfWidth(), y2, z1);
1554  // p.SetPoint(2, geom->DetHalfWidth(), y2, z2);
1555  // p.SetPoint(3, geom->DetHalfWidth(), y1, z2);
1556  // p.SetPoint(4, geom->DetHalfWidth(), y1, z1);
1557  // }
1558  // else abort();
1559  // break;
1560  // } // switch fRawDigit3DStyle
1561  // }//end loop over raw digits
1562  // }// end loop over RawDigit modules
1563 
1564  // // Render the towers for that style choice
1565  // if (rawopt->fRawDigit3DStyle==1) tower.Draw(view);
1566  // }
1567 
1568  //......................................................................
1570 
1571  return (fWireMax[plane] != -1) && (fTimeMax[plane] != -1);
1572 
1573  } // RawDataDrawer::hasRegionOfInterest()
1574 
1575 
1576  //......................................................................
1578 
1579  LOG_DEBUG("RawDataDrawer") << "RawDataDrawer[" << ((void*) this)
1580  << "]: resetting the region of interest";
1581 
1582  std::fill(fWireMin.begin(), fWireMin.end(), -1);
1583  std::fill(fWireMax.begin(), fWireMax.end(), -1);
1584  std::fill(fTimeMin.begin(), fTimeMin.end(), -1);
1585  std::fill(fTimeMax.begin(), fTimeMax.end(), -1);
1586 
1587  } // RawDataDrawer::ResetRegionOfInterest()
1588 
1589 
1590  //......................................................................
1591 
1593  (art::Event const& evt, details::CacheID_t const& new_timestamp)
1594  {
1595  LOG_DEBUG("RawDataDrawer") << "GetRawDigits() for " << new_timestamp
1596  << " (last for: " << *fCacheID << ")";
1597 
1598  // update cache
1599  digit_cache->Update(evt, new_timestamp);
1600 
1601  // if time stamp is changing, we want to reconsider which region is
1602  // interesting
1603  if (!fCacheID->sameTPC(new_timestamp)) ResetRegionOfInterest();
1604 
1605  // all the caches have been properly updated or invalidated;
1606  // we are now on a new cache state
1607  *fCacheID = new_timestamp;
1608 
1609  } // RawDataDrawer::GetRawDigits()
1610 
1611 
1612  //......................................................................
1614  (lariov::ChannelStatusProvider::Status_t channel_status) const
1615  {
1616  // if we don't have a valid status, we can't reject the channel
1617  if (!lariov::ChannelStatusProvider::IsValidStatus(channel_status))
1618  return true;
1619 
1620  // is the status "too bad"?
1622  if (channel_status > drawopt->fMaxChannelStatus) return false;
1623  if (channel_status < drawopt->fMinChannelStatus) return false;
1624 
1625  // no reason to reject it...
1626  return true;
1627  } // RawDataDrawer::ProcessChannel()
1628 
1629  //----------------------------------------------------------------------------
1630  namespace details {
1631 
1632  //--------------------------------------------------------------------------
1633  //--- RawDigitInfo_t
1634  //---
1635  raw::RawDigit::ADCvector_t const& RawDigitInfo_t::Data() const {
1636  if (!data.hasData()) UncompressData();
1637  return *data;
1638  } // RawDigitInfo_t::Data()
1639 
1640 
1642  data.Clear();
1643  digit = src;
1644  } // RawDigitInfo_t::Fill()
1645 
1646 
1647  void RawDigitInfo_t::Clear() {
1648  data.Clear();
1649  sample_info.reset();
1650  }
1651 
1652 
1653  void RawDigitInfo_t::UncompressData() const {
1654  data.Clear();
1655 
1656  if (!digit) return; // no original data, can't do anything
1657 
1659 
1660  if (digit->Compression() == kNone) {
1661  // no compression, we can refer to the original data directly
1662  data.PointToData(digit->ADCs());
1663  }
1664  else {
1665  // data is compressed, need to do the real work
1666  if (drawopt->fUncompressWithPed){//Use pedestal in uncompression
1667  int pedestal = (int)digit->GetPedestal();
1669  samples.resize(digit->Samples());
1670  Uncompress(digit->ADCs(), samples, pedestal, digit->Compression());
1671  data.StealData(std::move(samples));
1672  }
1673  else{
1675  samples.resize(digit->Samples());
1676  Uncompress(digit->ADCs(), samples, digit->Compression());
1677  data.StealData(std::move(samples));
1678  }
1679  }
1680  } // RawDigitInfo_t::UncompressData()
1681 
1682 
1683  void RawDigitInfo_t::CollectSampleInfo() const {
1684  raw::RawDigit::ADCvector_t const& samples = Data();
1685 
1686  // lar::util::StatCollector<double> stat;
1687  // stat.add(samples.begin(), samples.end());
1688 
1690  (samples.begin(), samples.end());
1691 
1692  sample_info.reset(new SampleInfo_t);
1693  sample_info->min_charge = stat.min();
1694  sample_info->max_charge = stat.max();
1695  // sample_info->average_charge = stat.Average();
1696 
1697  } // RawDigitInfo_t::CollectSampleInfo()
1698 
1699 
1700  RawDigitInfo_t::SampleInfo_t const& RawDigitInfo_t::SampleInfo() const {
1701  if (!sample_info) CollectSampleInfo();
1702  return *sample_info;
1703  } // SampleInfo()
1704 
1705  template <typename Stream>
1706  void RawDigitInfo_t::Dump(Stream&& out) const {
1707  out << " digit at " << ((void*) digit.get()) << " on channel #" << digit->Channel()
1708  << " with " << digit->NADC();
1709  if (digit->Compression() == kNone) out << " uncompressed data";
1710  else out << " data items compressed with <" << digit->Compression() << ">";
1711  if (data.hasData())
1712  out << " with data (" << data->size() << " samples)";
1713  else out << " without data";
1714  } // RawDigitInfo_t::Dump()
1715 
1716  //--------------------------------------------------------------------------
1717  //--- RawDigitCacheDataClass
1718  //---
1719 
1720  RawDigitInfo_t const* RawDigitCacheDataClass::FindChannel
1721  (raw::ChannelID_t channel) const
1722  {
1723  auto iDigit = std::find_if(
1724  digits.cbegin(), digits.cend(),
1725  [channel](evd::details::RawDigitInfo_t const& digit)
1726  { return digit.Channel() == channel; }
1727  );
1728  return (iDigit == digits.cend())? nullptr: &*iDigit;
1729  } // RawDigitCacheDataClass::FindChannel()
1730 
1731  std::vector<raw::RawDigit> const* RawDigitCacheDataClass::ReadProduct
1732  (art::Event const& evt, art::InputTag label)
1733  {
1735  if (!evt.getByLabel(label, rdcol)) return nullptr;
1736  return &*rdcol;
1737  } // RawDigitCacheDataClass::ReadProduct()
1738 
1739 
1740  void RawDigitCacheDataClass::Refill
1741  (art::Handle<std::vector<raw::RawDigit>>& rdcol)
1742  {
1743  digits.resize(rdcol->size());
1744  for(size_t iDigit = 0; iDigit < rdcol->size(); ++iDigit) {
1745  art::Ptr<raw::RawDigit> pDigit(rdcol, iDigit);
1746  digits[iDigit].Fill(pDigit);
1747  size_t samples = pDigit->Samples();
1748  if (samples > max_samples) max_samples = samples;
1749  } // for
1750  } // RawDigitCacheDataClass::Refill()
1751 
1752 
1753  void RawDigitCacheDataClass::Invalidate() {
1754  timestamp.clear();
1755  } // RawDigitCacheDataClass::Invalidate()
1756 
1757 
1758  void RawDigitCacheDataClass::Clear() {
1759  Invalidate();
1760  digits.clear();
1761  max_samples = 0;
1762  } // RawDigitCacheDataClass::Clear()
1763 
1764 
1766  RawDigitCacheDataClass::CheckUpToDate
1767  (CacheID_t const& ts, art::Event const* evt /* = nullptr */) const
1768  {
1769  BoolWithUpToDateMetadata res{ false, nullptr };
1770 
1771  // normally only if either the event or the product label have changed,
1772  // cache becomes invalid:
1773  if (!ts.sameProduct(timestamp)) return res; // outdated cache
1774 
1775  // But: our cache stores pointers to the original data, and on a new TPC
1776  // the event display may reload the event anew, removing the "old" data
1777  // from memory.
1778  // Since TPC can change with or without the data being invalidated,
1779  // a more accurate verification is needed.
1780 
1781  // if the cache is empty, well, it does not make much difference;
1782  // we invalidate it to be sure
1783  if (empty())
1784  return res; // outdated cache
1785 
1786  if (!evt)
1787  return res; // outdated, since we can't know better without the event
1788 
1789  // here we force reading of the product
1790  res.digits = ReadProduct(*evt, ts.inputLabel());
1791  if (!res.digits)
1792  return res; // outdated cache; this is actually an error
1793 
1794  if (res.digits->empty())
1795  return res; // outdated; no digits (strange!), invalidate just in case
1796 
1797  // use the first digit as test
1798  raw::ChannelID_t channel = res.digits->front().Channel();
1799  RawDigitInfo_t const* pInfo = FindChannel(channel);
1800  if (!pInfo)
1801  return res; // outdated: we don't even have this channel in cache!
1802 
1803  if (&(pInfo->Digit()) != &(res.digits->front()))
1804  return res; // outdated: different memory address for data
1805 
1806  res.bUpToDate = true;
1807  return res; // cache still valid
1808  } // RawDigitCacheDataClass::CheckUpToDate()
1809 
1810 
1812  (art::Event const& evt, CacheID_t const& new_timestamp)
1813  {
1814  BoolWithUpToDateMetadata update_info = CheckUpToDate(new_timestamp, &evt);
1815 
1816  if (update_info) return false; // already up to date: move on!
1817 
1818  LOG_DEBUG("RawDataDrawer")
1819  << "Refilling raw digit cache RawDigitCacheDataClass["
1820  << ((void*) this ) << "] for " << new_timestamp;
1821 
1822  Clear();
1823 
1825  if (!evt.getByLabel(new_timestamp.inputLabel(), rdcol)) {
1826  mf::LogWarning("RawDataDrawer") << "no RawDigit collection '"
1827  << new_timestamp.inputLabel() << "' found";
1828  return true;
1829  }
1830 
1831  Refill(rdcol);
1832 
1833  timestamp = new_timestamp;
1834  return true;
1835  } // RawDigitCacheDataClass::Update()
1836 
1837 
1838  template <typename Stream>
1839  void RawDigitCacheDataClass::Dump(Stream&& out) const {
1840  out << "Cache at " << ((void*) this)
1841  << " with time stamp " << std::string(timestamp)
1842  << " and " << digits.size()
1843  << " entries (maximum sample: " << max_samples << ");"
1844  << " data at " << ((void*) digits.data());
1845  for (RawDigitInfo_t const& digitInfo: digits) {
1846  out << "\n ";
1847  digitInfo.Dump(out);
1848  } // for
1849  out << "\n";
1850  } // RawDigitCacheDataClass::Dump()
1851 
1852 
1853  //--------------------------------------------------------------------------
1854  //--- GridAxisClass
1855  //---
1856  std::ptrdiff_t GridAxisClass::GetCell(float coord) const {
1857  return std::ptrdiff_t((coord - min) / cell_size); // truncate
1858  } // GridAxisClass::GetCell()
1859 
1860 
1861  //--------------------------------------------------------------------------
1862  bool GridAxisClass::Init(size_t nDiv, float new_min, float new_max) {
1863 
1864  n_cells = std::max(nDiv, size_t(1));
1865  return SetLimits(new_min, new_max);
1866 
1867  } // GridAxisClass::Init()
1868 
1869 
1870  //--------------------------------------------------------------------------
1871  bool GridAxisClass::SetLimits(float new_min, float new_max) {
1872  min = new_min;
1873  max = new_max;
1874  cell_size = Length() / float(n_cells);
1875 
1876  return std::isnormal(cell_size);
1877  } // GridAxisClass::SetLimits()
1878 
1879 
1880  //--------------------------------------------------------------------------
1881  bool GridAxisClass::SetMinCellSize(float min_size) {
1882  if (cell_size >= min_size) return false;
1883 
1884  // n_cells gets truncated
1885  n_cells = (size_t) std::max(std::floor(Length() / min_size), 1.0F);
1886 
1887  // reevaluate cell size, that might be different than min_size
1888  // because of n_cells truncation or minimum value
1889  cell_size = Length() / float(n_cells);
1890  return true;
1891  } // GridAxisClass::SetMinCellSize()
1892 
1893 
1894  //--------------------------------------------------------------------------
1895  bool GridAxisClass::SetMaxCellSize(float max_size) {
1896  if (cell_size <= max_size) return false;
1897 
1898  // n_cells gets rounded up
1899  n_cells = (size_t) std::max(std::ceil(Length() / max_size), 1.0F);
1900 
1901  // reevaluate cell size, that might be different than max_size
1902  // because of n_cells rounding or minimum value
1903  cell_size = Length() / float(n_cells);
1904  return true;
1905  } // GridAxisClass::SetMaxCellSize()
1906 
1907 
1908  //--------------------------------------------------------------------------
1909  template <typename Stream>
1910  void GridAxisClass::Dump(Stream&& out) const {
1911  out << NCells() << " cells from " << Min() << " to " << Max()
1912  << " (length: " << Length() << ")";
1913  } // GridAxisClass::Dump()
1914 
1915 
1916  //--------------------------------------------------------------------------
1917  //--- CellGridClass
1918  //---
1919  CellGridClass::CellGridClass(unsigned int nWires, unsigned int nTDC)
1920  : wire_axis((size_t) nWires, 0., float(nWires))
1921  , tdc_axis((size_t) nTDC, 0., float(nTDC))
1922  {
1923  } // CellGridClass::CellGridClass(int, int)
1924 
1925 
1926  //--------------------------------------------------------------------------
1928  float min_wire, float max_wire, unsigned int nWires,
1929  float min_tdc, float max_tdc, unsigned int nTDC
1930  )
1931  : wire_axis((size_t) nWires, min_wire, max_wire)
1932  , tdc_axis((size_t) nTDC, min_tdc, max_tdc)
1933  {
1934  } // CellGridClass::CellGridClass({ float, float, int } x 2)
1935 
1936 
1937  //--------------------------------------------------------------------------
1938  std::ptrdiff_t CellGridClass::GetCell(float wire, float tick) const {
1939  std::ptrdiff_t iWireCell = wire_axis.GetCell(wire);
1940  if (!wire_axis.hasCell(iWireCell)) return std::ptrdiff_t(-1);
1941  std::ptrdiff_t iTDCCell = tdc_axis.GetCell(tick);
1942  if (!tdc_axis.hasCell(iTDCCell)) return std::ptrdiff_t(-1);
1943  return iWireCell * TDCAxis().NCells() + iTDCCell;
1944  } // CellGridClass::GetCell()
1945 
1946 
1947  //--------------------------------------------------------------------------
1948  std::tuple<float, float, float, float> CellGridClass::GetCellBox
1949  (std::ptrdiff_t iCell) const
1950  {
1951  // { w1, t1, w2, t2 }
1952  size_t const nTDCCells = TDCAxis().NCells();
1953  std::ptrdiff_t iWireCell = (std::ptrdiff_t) (iCell / nTDCCells),
1954  iTDCCell = (std::ptrdiff_t) (iCell % nTDCCells);
1955 
1956 
1957  return std::tuple<float, float, float, float>(
1958  WireAxis().LowerEdge(iWireCell), TDCAxis().LowerEdge(iTDCCell),
1959  WireAxis().UpperEdge(iWireCell), TDCAxis().UpperEdge(iTDCCell)
1960  );
1961  } // CellGridClass::GetCellBox()
1962 
1963 
1964  //--------------------------------------------------------------------------
1965  template <typename Stream>
1966  void CellGridClass::Dump(Stream&& out) const {
1967  out << "Wire axis: ";
1968  WireAxis().Dump(out);
1969  out << "; time axis: ";
1970  TDCAxis().Dump(out);
1971  } // CellGridClass::Dump()
1972 
1973 
1974  //--------------------------------------------------------------------------
1975 
1976  } // details
1977 
1978 } // namespace evd
1979 
int GetRegionOfInterest(int plane, int &minw, int &maxw, int &mint, int &maxt)
float GetPedestal() const
Definition: RawDigit.h:213
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.
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.
TCEvent evt
Definition: DataStructs.cxx:5
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.
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.
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.