DbigEVD4apaFD_module.cc
Go to the documentation of this file.
1 #ifndef DbigEVD4_Module
2 #define DbigEVD4_Module
3 
4 // LArSoft includes
14 
15 // Framework includes
20 #include "art_root_io/TFileService.h"
22 #include "canvas/Persistency/Common/FindManyP.h"
24 #include "fhiclcpp/ParameterSet.h"
25 
26 // ROOT includes.
27 #include "TH1.h"
28 #include "TH2.h"
29 #include "TTree.h"
30 #include "TLorentzVector.h"
31 #include "TVector3.h"
32 #include "TCanvas.h"
33 #include "TPad.h"
34 
35 // C++ Includes
36 #include <map>
37 #include <vector>
38 #include <algorithm>
39 #include <iostream>
40 #include <string>
41 #include <cmath>
42 
43 namespace AnalysisExample{
44 
46  public:
47 
48  explicit DbigEVD4apaFD(fhicl::ParameterSet const& pset);
49  virtual ~DbigEVD4apaFD();
50 
51  void beginJob();
52 
53  void beginRun(const art::Run& run);
54 
55  void reconfigure(fhicl::ParameterSet const& pset);
56 
57  void analyze(const art::Event& evt);
58 
59  private:
60 
61  // the parameters we'll read from the .fcl
66  unsigned int fAPA;
67  unsigned int fEvent;
68 
69 
70  // diagnostics on other apas to help find other activity
71  std::map< unsigned int, unsigned int > fAPAToNumHits;
72 
73  // pointers to the time-channel/wire histograms
74  std::vector<std::vector<TH2I*> > fAmbigWireU0;
75  std::vector<std::vector<TH2I*> > fAmbigWireV0;
76  std::vector<std::vector<TH2I*> > fAmbigWireU1;
77  std::vector<std::vector<TH2I*> > fAmbigWireV1;
78  std::vector<std::vector<TH2I*> > fDisambigWireU0;
79  std::vector<std::vector<TH2I*> > fDisambigWireV0;
80  std::vector<std::vector<TH2I*> > fDisambigWireU1;
81  std::vector<std::vector<TH2I*> > fDisambigWireV1;
82  std::vector<std::vector<TH2I*> > fCheatWireU0;
83  std::vector<std::vector<TH2I*> > fCheatWireV0;
84  std::vector<std::vector<TH2I*> > fCheatWireU1;
85  std::vector<std::vector<TH2I*> > fCheatWireV1;
86  std::vector<std::vector<TH2I*> > fTimeChanZ0; // fcl option to time reverse for display clarity
87  std::vector<std::vector<TH2I*> > fTimeChanZ1;
88 
89 
90 
91  // show color-coded channel clusters
92  // index in the vector corresponds with root Color_t 0-9
93  //std::vector<TH2I*> fClusChanU;
94  //std::vector<TH2I*> fClusChanV;
95  //std::vector<TH2I*> fClusChanZ0;
96  //std::vector<TH2I*> fClusChanZ1;
97  // ^^^ removed for now
98 
99  // number of time bins for histograms
100  unsigned int fNticks;
101 
102  // find channel boundaries for each view
103  unsigned int fUChMin;
104  unsigned int fUChMax;
105  unsigned int fVChMin;
106  unsigned int fVChMax;
107  unsigned int fZ0ChMin;
108  unsigned int fZ0ChMax;
109  unsigned int fZ1ChMin;
110  unsigned int fZ1ChMax;
111 
112  unsigned int fnAPAs;
113  unsigned int fnEvts;
114  unsigned int fChansPerAPA;
115 
116  unsigned int fUWireMax;
117  unsigned int fVWireMax;
118  unsigned int fZ0WireMax;
119  unsigned int fZ1WireMax;
120 
121  unsigned int fMinT, fMaxT, fMaxTimeRange;
122  bool fTimeReverseZ0 = true;
123 
124  bool fGotFirstEvtNum = false;
126 
128 
129  }; // class DbigEVD4apaFD
130 
131  //-----------------------------------------------------------------------
132 
133  // read in the parameters from the .fcl file
135  : EDAnalyzer( parameterSet )
136  , fEvent(-1)
137  {
138  this->reconfigure(parameterSet);
139  }
140 
141 
142  //-----------------------------------------------------------------------
143 
145  fChanHitLabel = p.get< std::string >("ChanHitLabel");
146  fWidHitLabel = p.get< std::string >("WidHitLabel");
147  fHitCheatLabel = p.get< std::string >("HitCheatLabel");
148  fClusLabel = p.get< std::string >("ClusLabel");
149  fnEvts = p.get< unsigned int >("nEvents");
150 
151  fTimeReverseZ0 = p.get< bool >("TimeReverseZ0");
152 
153  auto const *fDetProp = lar::providerFrom<detinfo::DetectorPropertiesService>();
154  fNticks = fDetProp->NumberTimeSamples();
155  fnAPAs = fGeom->NTPC()/2;
156  return;
157  }
158 
159 
160  //-----------------------------------------------------------------------
161 
163  }
164 
165  //-----------------------------------------------------------------------
166 
168 
169  // loop through channels in the first APA to find the channel boundaries for each view
170  // will adjust for desired APA after
171  fUChMin = 0;
172  fChansPerAPA = ( fGeom->Nchannels() )/ (fGeom->NTPC()/2 );
173  fZ1ChMax = ( fGeom->Nchannels() )/ (fGeom->NTPC()/2 ) - 1;
174  for ( unsigned int c = fUChMin + 1; c < fZ1ChMax; c++ ){
175  if ( fGeom->View(c) == geo::kV && fGeom->View(c-1) == geo::kU ){
176  fVChMin = c;
177  fUChMax = c - 1;
178  }
179  if ( fGeom->View(c) == geo::kZ && fGeom->View(c-1) == geo::kV ){
180  fZ0ChMin = c;
181  fVChMax = c-1;
182  }
183  if ( fGeom->View(c) == geo::kZ && fGeom->ChannelToWire(c)[0].TPC == fGeom->ChannelToWire(c-1)[0].TPC + 1 ){
184  fZ1ChMin = c;
185  fZ0ChMax = c-1;
186  }
187  }
188 
189  //fUWireMax = fGeom->Nwires(0, std::floor( fAPA/2 ), 0);
190  //fVWireMax = fGeom->Nwires(1, std::floor( fAPA/2 ), 0);
191  //fZ0WireMax = fGeom->Nwires(2, std::floor( fAPA/2 ), 0);
192  fUWireMax = fGeom->Nwires(0, 0, 0);
193  fVWireMax = fGeom->Nwires(1, 0, 0);
194  fZ0WireMax = fGeom->Nwires(2, 0, 0);
196 
197 
198  unsigned int minT = 0;
199  unsigned int maxT = fNticks;
200 
201  float ThumbFactor = 0.85;
202  unsigned int binT = (maxT-minT)*ThumbFactor;
203 
204  // Access ART's TFileService, which will handle creating and writing
205  // histograms and n-tuples for us.
207 
208  int minZ0T = minT;
209  int maxZ0T = maxT;
210  // makes for more logical display in the root display script
211  if(fTimeReverseZ0){ minZ0T = -fNticks;
212  maxZ0T = 0; }
213 
214 
215  std::stringstream hname;
216  fAmbigWireU0.resize(fnEvts); fAmbigWireU1.resize(fnEvts);
217  fCheatWireU0.resize(fnEvts); fCheatWireU1.resize(fnEvts);
218  fDisambigWireU0.resize(fnEvts); fDisambigWireU1.resize(fnEvts);
219  fAmbigWireV0.resize(fnEvts); fAmbigWireV1.resize(fnEvts);
220  fCheatWireV0.resize(fnEvts); fCheatWireV1.resize(fnEvts);
221  fDisambigWireV0.resize(fnEvts); fDisambigWireV1.resize(fnEvts);
222  fTimeChanZ0.resize(fnEvts); fTimeChanZ1.resize(fnEvts);
223 
224  // art starts events at number 1
225  for(unsigned int evt=1; evt<=fnEvts; evt++){
226  // index with evt-1
227  fAmbigWireU0[evt-1].resize(fnAPAs); fAmbigWireU1[evt-1].resize(fnAPAs);
228  fCheatWireU0[evt-1].resize(fnAPAs); fCheatWireU1[evt-1].resize(fnAPAs);
229  fDisambigWireU0[evt-1].resize(fnAPAs); fDisambigWireU1[evt-1].resize(fnAPAs);
230  fAmbigWireV0[evt-1].resize(fnAPAs); fAmbigWireV1[evt-1].resize(fnAPAs);
231  fCheatWireV0[evt-1].resize(fnAPAs); fCheatWireV1[evt-1].resize(fnAPAs);
232  fDisambigWireV0[evt-1].resize(fnAPAs); fDisambigWireV1[evt-1].resize(fnAPAs);
233  fTimeChanZ0[evt-1].resize(fnAPAs); fTimeChanZ1[evt-1].resize(fnAPAs);
234 
235 
236  for(unsigned int apa=0; apa<fnAPAs; apa++){
237  //unsigned int fUChanMin = fUChMin + apa*fChansPerAPA;
238  //unsigned int fUChanMax = fUChMax + apa*fChansPerAPA;
239  //unsigned int fVChanMin = fVChMin + apa*fChansPerAPA;
240  //unsigned int fVChanMax = fVChMax + apa*fChansPerAPA;
241  unsigned int fZ0ChanMin = fZ0ChMin + apa*fChansPerAPA;
242  unsigned int fZ0ChanMax = fZ0ChMax + apa*fChansPerAPA;
243  unsigned int fZ1ChanMin = fZ1ChMin + apa*fChansPerAPA;
244  unsigned int fZ1ChanMax = fZ1ChMax + apa*fChansPerAPA;
245 
246  hname.str(""); hname << "fAmbigWireU0_" << apa << "_" << evt;
247  fAmbigWireU0[evt-1][apa] = tfs->make<TH2I>(hname.str().c_str(), "U Ambiguous Hits (side 0)", fUWireMax, 0, fUWireMax, binT, minT, maxT);
248  hname.str(""); hname << "fCheatWireU0_" << apa << "_" << evt;
249  fCheatWireU0[evt-1][apa] = tfs->make<TH2I>(hname.str().c_str(), "U Cheated Hits (side 0)", fUWireMax, 0, fUWireMax, binT, minT, maxT);
250  hname.str(""); hname << "fDisambigWireU0_" << apa << "_" << evt;
251  fDisambigWireU0[evt-1][apa] = tfs->make<TH2I>(hname.str().c_str(), "U Disambiguated Hits (side 0)", fUWireMax, 0, fUWireMax, binT, minT, maxT);
252 
253  hname.str(""); hname << "fAmbigWireV0_" << apa << "_" << evt;
254  fAmbigWireV0[evt-1][apa] = tfs->make<TH2I>(hname.str().c_str(), "V Ambiguous Hits (side 0)", fVWireMax, 0, fVWireMax, binT, minT, maxT);
255  hname.str(""); hname << "fCheatWireV0_" << apa << "_" << evt;
256  fCheatWireV0[evt-1][apa] = tfs->make<TH2I>(hname.str().c_str(), "V Cheated Hits (side 0)", fVWireMax, 0, fVWireMax, binT, minT, maxT);
257  hname.str(""); hname << "fDisambigWireV0_" << apa << "_" << evt;
258  fDisambigWireV0[evt-1][apa] = tfs->make<TH2I>(hname.str().c_str(), "V Disambiguated Hits (side 0)", fVWireMax, 0, fVWireMax, binT, minT, maxT);
259 
260  hname.str(""); hname << "fAmbigWireU1_" << apa << "_" << evt;
261  fAmbigWireU1[evt-1][apa] = tfs->make<TH2I>(hname.str().c_str(), "U Ambiguous Hits (side 1)", fUWireMax, 0, fUWireMax, binT, minT, maxT);
262  hname.str(""); hname << "fCheatWireU1_" << apa << "_" << evt;
263  fCheatWireU1[evt-1][apa] = tfs->make<TH2I>(hname.str().c_str(), "U Cheated Hits (side 1)", fUWireMax, 0, fUWireMax, binT, minT, maxT);
264  hname.str(""); hname << "fDisambigWireU1_" << apa << "_" << evt;
265  fDisambigWireU1[evt-1][apa] = tfs->make<TH2I>(hname.str().c_str(), "U Disambiguated Hits (side 1)", fUWireMax, 0, fUWireMax, binT, minT, maxT);
266 
267  hname.str(""); hname << "fAmbigWireV1_" << apa << "_" << evt;
268  fAmbigWireV1[evt-1][apa] = tfs->make<TH2I>(hname.str().c_str(), "V Ambiguous Hits (side 1)", fVWireMax, 0, fVWireMax, binT, minT, maxT);
269  hname.str(""); hname << "fCheatWireV1_" << apa << "_" << evt;
270  fCheatWireV1[evt-1][apa] = tfs->make<TH2I>(hname.str().c_str(), "V Cheated Hits (side 1)", fVWireMax, 0, fVWireMax, binT, minT, maxT);
271  hname.str(""); hname << "fDisambigWireV1_" << apa << "_" << evt;
272  fDisambigWireV1[evt-1][apa] = tfs->make<TH2I>(hname.str().c_str(), "V Disambiguated Hits (side 1)", fVWireMax, 0, fVWireMax, binT, minT, maxT);
273 
274 
275  fAmbigWireU0[evt-1][apa]->SetStats(0); fAmbigWireV0[evt-1][apa]->SetStats(0);
276  fAmbigWireU1[evt-1][apa]->SetStats(0); fAmbigWireV1[evt-1][apa]->SetStats(0);
277  fDisambigWireU0[evt-1][apa]->SetStats(0); fDisambigWireV0[evt-1][apa]->SetStats(0);
278  fDisambigWireU1[evt-1][apa]->SetStats(0); fDisambigWireV1[evt-1][apa]->SetStats(0);
279  fCheatWireU0[evt-1][apa]->SetStats(0); fCheatWireV0[evt-1][apa]->SetStats(0);
280  fCheatWireU1[evt-1][apa]->SetStats(0); fCheatWireV1[evt-1][apa]->SetStats(0);
281 
282  fDisambigWireU0[evt-1][apa]->SetMarkerColor(2); fDisambigWireV0[evt-1][apa]->SetMarkerColor(2);
283  fDisambigWireU1[evt-1][apa]->SetMarkerColor(2); fDisambigWireV1[evt-1][apa]->SetMarkerColor(2);
284 
285  hname.str(""); hname << "fTimeChanZ0_" << apa << "_" << evt;
286  fTimeChanZ0[evt-1][apa] = tfs->make<TH2I>( hname.str().c_str(), "",
287  (fZ0ChanMax - fZ0ChanMin + 1)*ThumbFactor,
288  fZ0ChanMin, fZ0ChanMax,
289  binT, minZ0T, maxZ0T); // NOTE: Time reversed with a fcl trigger
290 
291  hname.str(""); hname << "fTimeChanZ1_" << apa << "_" << evt;
292  fTimeChanZ1[evt-1][apa] = tfs->make<TH2I>( hname.str().c_str(), "",
293  (fZ1ChanMax - fZ1ChanMin + 1)*ThumbFactor,
294  fZ1ChanMin, fZ1ChanMax, binT, minT, maxT);
295 
296  fTimeChanZ0[evt-1][apa]->SetStats(0); fTimeChanZ1[evt-1][apa]->SetStats(0);
297 
298  } // apas
299  } // evts
300 
301 
302  }
303 
304  //-----------------------------------------------------------------------
305 
307 
308  }
309 
310 
311  //-----------------------------------------------------------------------
312 
314 
315  // Get the index for Hist vectors - not 1 if reading a file that
316  // started at a custom firstEvent in the fcl file
317  if(!fGotFirstEvtNum){ fFirstEvt = event.id().event(); fGotFirstEvtNum = true; }
318  // This works if all evts are contiguously numbered, which if produced by a filter
319  // may not be the case.
320  // unsigned int evtIndex = event.id().event() - fFirstEvt;
321  unsigned int evtIndex = ++fEvent;
322 
324  event.getByLabel(fChanHitLabel, ChHits);
326  event.getByLabel(fWidHitLabel, WidHits);
328  event.getByLabel(fHitCheatLabel, CheatedHits);
329 
330 
331  // plot hits on a given side of an APA vs all
332  // wireIDs corresponding to the it channel
333  for( auto const& hit : (*ChHits) ){
334  uint32_t chan = hit.Channel();
335  unsigned int apa = std::floor( chan/fChansPerAPA );
336  double startT = hit.PeakTimeMinusRMS();
337  double endT = hit.PeakTimePlusRMS();
338  double charge = hit.PeakAmplitude();
339  std::vector< geo::WireID > wids = fGeom->ChannelToWire(chan);
340 
341  //if( fAPAToNumHits.count(apa) == 0 ) fAPAToNumHits[apa] = 0;
342  //fAPAToNumHits[apa]++;
343 
344  for(size_t i=0; i<wids.size(); i++){
345 
346  unsigned int wire = wids[i].Wire;
347 
348  if( wids[i].TPC % 2 == 0 ){
349 
350  if( fGeom->View(chan) == geo::kU ){
351  for( double t = startT; t <= endT; t++ ){
352  fAmbigWireU0[evtIndex][apa]->Fill(wire, t, charge);
353  }
354  }
355  else if( fGeom->View(chan) == geo::kV ){
356  for( double t = startT; t <= endT; t++ ){
357  fAmbigWireV0[evtIndex][apa]->Fill(wire, t, charge);
358  }
359  }
360  else if ( fGeom->View(chan) == geo::kZ ){
361  for( double t = startT; t <= endT; t++ ){
362  double Z0fillT = t;
363  if(fTimeReverseZ0) Z0fillT = -t; // time reverse for geometrically logical display
364  fTimeChanZ0[evtIndex][apa]->Fill(chan, Z0fillT, charge);
365  }
366  }
367 
368  } else if( wids[i].TPC % 2 == 1 ){
369 
370  if( fGeom->View(chan) == geo::kU ){
371  for( double t = startT; t <= endT; t++ ){
372  fAmbigWireU1[evtIndex][apa]->Fill(wire, t, charge);
373  }
374  }
375  else if( fGeom->View(chan) == geo::kV ){
376  for( double t = startT; t <= endT; t++ ){
377  fAmbigWireV1[evtIndex][apa]->Fill(wire, t, charge);
378  }
379  }
380  else if ( hit.View() == geo::kZ ){
381  for( double t = startT; t <= endT; t++ ){
382  fTimeChanZ1[evtIndex][apa]->Fill(chan, t, charge);
383  }
384  }
385 
386  }
387 
388  } // end wid loop
389  } // end channel hit per wireID loop
390 
391 
392 
393  // for now, let user know where other activity is from here
394 
395  //std::map<unsigned int, unsigned int>::iterator apa_it;
396  //for( apa_it=fAPAToNumHits.begin(); apa_it!=fAPAToNumHits.end(); apa_it++ )
397  // mf::LogVerbatim("DbigEVD4apaFD") << "APA " << apa_it->first
398  // << " has " << apa_it->second << " hits.";
399 
400 
401 
402  // plot hits on a given side of an APA vs. disambiguated wireID
403  for( auto const& hit : (*WidHits) ){
404  uint32_t chan = hit.Channel();
405  unsigned int apa = std::floor( chan/fChansPerAPA );
406  unsigned int wire = hit.WireID().Wire;
407  double startT = hit.PeakTimeMinusRMS();
408  double endT = hit.PeakTimePlusRMS();
409  double charge = hit.PeakAmplitude();
410 
411  if(hit.WireID().TPC % 2 == 0){
412 
413  if( fGeom->View(chan) == geo::kU ){
414  for( double t = startT; t <= endT; t++ ){
415  fDisambigWireU0[evtIndex][apa]->Fill(wire, t, charge);
416  }
417  }
418  if( fGeom->View(chan) == geo::kV ){
419  for( double t = startT; t <= endT; t++ ){
420  fDisambigWireV0[evtIndex][apa]->Fill(wire, t, charge);
421  }
422  }
423 
424  } else if(hit.WireID().TPC % 2 == 1){
425 
426  if( fGeom->View(chan) == geo::kU ){
427  for( double t = startT; t <= endT; t++ ){
428  fDisambigWireU1[evtIndex][apa]->Fill(wire, t, charge);
429  }
430  }
431  if( fGeom->View(chan) == geo::kV ){
432  for( double t = startT; t <= endT; t++ ){
433  fDisambigWireV1[evtIndex][apa]->Fill(wire, t, charge);
434  }
435  }
436 
437  }
438 
439  } // end wireID hit per wireID loop
440 
441 
442  // plot cheated hits on a given side of an APA vs. cheated wireID
443  for( auto const& hit : (*CheatedHits) ){
444  uint32_t chan = hit.Channel();
445  unsigned int apa = std::floor( chan/fChansPerAPA );
446  unsigned int wire = hit.WireID().Wire;
447  double startT = hit.PeakTimeMinusRMS();
448  double endT = hit.PeakTimePlusRMS();
449  double charge = hit.PeakAmplitude();
450 
451  if(hit.WireID().TPC % 2 == 0){
452 
453  if( fGeom->View(chan) == geo::kU ){
454  for( double t = startT; t <= endT; t++ ){
455  fCheatWireU0[evtIndex][apa]->Fill(wire, t, charge);
456  }
457  }
458  if( fGeom->View(chan) == geo::kV ){
459  for( double t = startT; t <= endT; t++ ){
460  fCheatWireV0[evtIndex][apa]->Fill(wire, t, charge);
461  }
462  }
463 
464  } else if(hit.WireID().TPC % 2 == 1){
465 
466  if( fGeom->View(chan) == geo::kU ){
467  for( double t = startT; t <= endT; t++ ){
468  fCheatWireU1[evtIndex][apa]->Fill(wire, t, charge);
469  }
470  }
471  if( fGeom->View(chan) == geo::kV ){
472  for( double t = startT; t <= endT; t++ ){
473  fCheatWireV1[evtIndex][apa]->Fill(wire, t, charge);
474  }
475  }
476 
477  }
478 
479  } // end cheated hit loop
480 
481 
482  return;
483  }
484 
486 
487 } // namespace AnalysisExample
488 
489 #endif // DbigEVD4_Module
Store parameters for running LArG4.
std::vector< std::vector< TH2I * > > fAmbigWireU0
DbigEVD4apaFD(fhicl::ParameterSet const &pset)
std::string string
Definition: nybbler.cc:12
Planes which measure V.
Definition: geo_types.h:126
Declaration of signal hit object.
std::vector< std::vector< TH2I * > > fDisambigWireU1
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
Planes which measure Z direction.
Definition: geo_types.h:128
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:27
Particle class.
std::vector< std::vector< TH2I * > > fCheatWireV1
std::map< unsigned int, unsigned int > fAPAToNumHits
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< std::vector< TH2I * > > fAmbigWireU1
Definition: Run.h:21
unsigned int Nchannels() const
Returns the number of TPC readout channels in the detector.
Planes which measure U.
Definition: geo_types.h:125
std::vector< std::vector< TH2I * > > fTimeChanZ0
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:69
std::vector< std::vector< TH2I * > > fDisambigWireU0
std::vector< std::vector< TH2I * > > fCheatWireV0
unsigned int uint32_t
Definition: stdint.h:126
std::vector< std::vector< TH2I * > > fAmbigWireV0
void analyze(const art::Event &evt)
T get(std::string const &key) const
Definition: ParameterSet.h:231
art::ServiceHandle< geo::Geometry > fGeom
Declaration of cluster object.
View_t View(geo::PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
Definition of data types for geometry description.
std::vector< std::vector< TH2I * > > fCheatWireU1
Detector simulation of raw signals on wires.
unsigned int NTPC(unsigned int cstat=0) const
Returns the total number of TPCs in the specified cryostat.
std::vector< std::vector< TH2I * > > fDisambigWireV1
p
Definition: test.py:223
object containing MC truth information necessary for making RawDigits and doing back tracking ...
std::vector< std::vector< TH2I * > > fAmbigWireV1
TCEvent evt
Definition: DataStructs.cxx:7
std::vector< std::vector< TH2I * > > fDisambigWireV0
void beginRun(const art::Run &run)
std::vector< std::vector< TH2I * > > fTimeChanZ1
Event finding and building.
unsigned int run
std::vector< std::vector< TH2I * > > fCheatWireU0
void reconfigure(fhicl::ParameterSet const &pset)