KaliVeda  1.12/06
Heavy-Ion Analysis Toolkit
KVASGroup.cpp
Go to the documentation of this file.
1 //Created by KVClassFactory on Fri Apr 26 14:01:32 2013
2 //Author: John Frankland,,,
3 
4 #include "KVASGroup.h"
5 
7 
8 // BEGIN_HTML <!--
10 /* -->
11 <h2>KVASGroup</h2>
12 <h4>Group in axially-symmetric multidetector</h4>
13 <!-- */
14 // --> END_HTML
16 
17 
18 
22 {
23  // Default constructor
24  init();
25 }
26 
27 
30 
32 {
33  //Default initialisation
34 
35  fNumberOfLayers = 0;
36  fLayNumMin = 0;
37  fLayNumMax = 0;
38 }
39 
40 
41 
46 
48 {
49  // Overrides KVGeoStrucElement method
50  // Only KVTelescope-derived objects can be added to KVASGroups
51  // All detectors in the telescope are added to the group's list.
52 
53  if (!b->InheritsFrom("KVTelescope")) return;
55  KVTelescope* tel = dynamic_cast<KVTelescope*>(b);
56  TIter next(tel->GetDetectors());
57  KVDetector* d;
58  while ((d = (KVDetector*)next())) KVGeoStrucElement::Add(d);
59 }
60 
61 
62 
65 
67 {
68  // Destructor
69  fNumberOfLayers = 0;
70  fLayNumMin = 0;
71  fLayNumMax = 0;
72 }
73 
74 
75 
76 
79 
81 {
82  //Set dimensions of group according to dimensions of all its telescopes.
83  KVTelescope* tel, *tel1;
84  TIter next(GetTelescopes());
85  tel = (KVTelescope*) next();
86  if (!tel)
87  return;
88  tel1 = (KVTelescope*) next();
89  if (!tel1)
90  return;
91  SetDimensions(tel, tel1);
92  while ((tel = (KVTelescope*) next())) {
93  SetDimensions(this, tel);
94  }
95 }
96 
97 
98 
99 
107 
109 {
110  //Adjust angular dimensions of group according to theta-min/max, phi-min/max
111  //of p1 and p2, where p1 and p2 are either two telescopes or a group (most
112  //probably this group) and a telescope.
113  //For theta-min/max, it is the smallest/largest angle which is used for the group dimension.
114  //For azimuthal/phi angles, all 4 combinations of "min" and "max" are tried and the one
115  //which gives the greatest azimuthal width to the group is kept.
116 
117  Float_t theta_min = TMath::Min(p1->GetThetaMin(), p2->GetThetaMin());
118  Float_t theta_max = TMath::Max(p1->GetThetaMax(), p2->GetThetaMax());
119  SetPolarMinMax(theta_min, theta_max);
120 
121  KVPosition* pp[2]; //array of pointers
122  pp[0] = p1;
123  pp[1] = p2;
124  Float_t max_width = 0.;
125  for (int i = 0; i < 2; i++) {
126  for (int j = 0; j < 2; j++) {
127  if (GetAzimuthalWidth(pp[i]->GetPhiMin(), pp[j]->GetPhiMax()) >
128  max_width) {
129  SetAzimuthalMinMax(pp[i]->GetPhiMin(), pp[j]->GetPhiMax());
130  max_width = GetAzimuthalWidth();
131  }
132  }
133  }
134 }
135 
136 
137 
138 
143 
145 {
146  //Make sure telescopes are ordered by increasing layer number i.e. increasing distance from target.
147  //This is so that when simulating the energy losses of a charged particle passing
148  //through the telescopes of the group, we get it in the right order!
149 
150  SortStructures();
151 }
152 
153 
154 
162 
164 {
165  //Calculate energy losses of a charged particle traversing the telescopes of the group.
166  //This method return a list of TNamed where each detector which is throught in the particle
167  //are written with the corrresponding energy loss
168  //WARNING : this KVNameValueList has to be deleted by the user
169  // after use
170  //return 0 if no telescope are on the path of the particle (DEAD zone)
171  TList* d = GetTelescopesWithAngles(part->GetTheta(), part->GetPhi());
172  if (d) {
173  TIter nextd(d);
174  KVTelescope* t = 0;
175  KVNameValueList* nvl = new KVNameValueList();
176  while ((t = (KVTelescope*) nextd())) {
177  t->DetectParticle(part, nvl);
178  if (part->GetEnergy() <= 0.0) {
179  delete d;
180  return nvl;
181  }
182  }
183  delete d;
184  return nvl;
185  }
186  return 0;
187 }
188 
189 
190 
191 
196 
198 {
199  //Create and fill list of telescopes in group at position (theta,phi),
200  //sorted according to distance from target (smallest layer number i.e. closest first).
201  //User must delete list after use.
202 
203  TIter next(GetTelescopes());
204  KVTelescope* t;
205  TList* list = 0;
206  while ((t = (KVTelescope*) next())) {
207  if (t->IsInPolarRange(theta) && t->IsInPhiRange(phi)) {
208  if (!list)
209  list = new TList;
210  list->Add(t);
211  }
212  }
213  if (list)
214  list->Sort();
215  return list;
216 }
217 
218 
219 
220 
224 
226 {
227  //Create and fill list of telescopes belonging to Layer number nlayer in the group.
228  //User must delete list after use.
229 
230  TIter next(GetTelescopes());
231  KVTelescope* t;
232  TList* list = 0;
233  while ((t = (KVTelescope*) next())) {
234  if (t->GetParentStructure("RING")->GetParentStructure("LAYER")->GetNumber() == nlayer) {
235  if (!list)
236  list = new TList;
237  list->Add(t);
238  }
239  }
240  return list;
241 }
242 
243 
244 
250 
252 {
253  //Count the number of different layers to which telescopes in the group belong.
254  //This is based on different layers having different numbers.
255  //The layer closest to the target is assumed to have the smallest layer number,
256  //the layer furthest from the target is assumed to have the largest layer number.
257  fNumberOfLayers = 0;
258  fLayNumMin = 99;
259  fLayNumMax = 0;
260  if (GetTelescopes()) {
261  TIter ntel(GetTelescopes());
262  KVTelescope* tel;
263  UInt_t laynums[10];
264  while ((tel = (KVTelescope*) ntel())) {
265  if (fNumberOfLayers) {
266  Bool_t found = kFALSE;
267  //Check to make sure layer number not already in array
268  for (UInt_t i = 0; i < fNumberOfLayers; i++) {
269  if (tel->GetParentStructure("RING")->GetParentStructure("LAYER")->GetNumber() == laynums[i])
270  found = kTRUE;
271  }
272  if (!found) {
273  laynums[fNumberOfLayers++] = tel->GetParentStructure("RING")->GetParentStructure("LAYER")->GetNumber();
274  if (fNumberOfLayers > 9) {
275  Warning("CountLayers", "Too many layers in group");
276  }
277  if (tel->GetParentStructure("RING")->GetParentStructure("LAYER")->GetNumber() > fLayNumMax)
278  fLayNumMax = tel->GetParentStructure("RING")->GetParentStructure("LAYER")->GetNumber();
279  if (tel->GetParentStructure("RING")->GetParentStructure("LAYER")->GetNumber() < fLayNumMin)
280  fLayNumMin = tel->GetParentStructure("RING")->GetParentStructure("LAYER")->GetNumber();
281  }
282  }
283  else {
284  laynums[fNumberOfLayers++] = tel->GetParentStructure("RING")->GetParentStructure("LAYER")->GetNumber();
285  if (fNumberOfLayers > 9) {
286  Warning("CountLayers", "Too many layers in group");
287  }
288  if (tel->GetParentStructure("RING")->GetParentStructure("LAYER")->GetNumber() > fLayNumMax)
289  fLayNumMax = tel->GetParentStructure("RING")->GetParentStructure("LAYER")->GetNumber();
290  if (tel->GetParentStructure("RING")->GetParentStructure("LAYER")->GetNumber() < fLayNumMin)
291  fLayNumMin = tel->GetParentStructure("RING")->GetParentStructure("LAYER")->GetNumber();
292  }
293  }
294  }
295 }
296 
297 
298 
302 
304 {
305  //Returns the total number of detector layers in the group,
306  //including counting the detectors inside the telescopes
307 
308  UInt_t ndl = 0;
309  UInt_t imin = GetLayerNearestTarget();
311  for (UInt_t i = imin; i <= imax; i++) {
312  TList* list = GetTelescopesInLayer(i);
313  //note we take the max number of detectors in telescopes of layer i
314  Int_t max = 0;
315  if (list) {
316  TIter it(list);
317  KVTelescope* tel = 0;
318  while ((tel = (KVTelescope*)it.Next()))
319  if (max < tel->GetDetectors()->GetSize())
320  max = tel->GetDetectors()->GetSize();
321  ndl += max;
322  //
323  //before it was assume that all telescopes in same layer are identically constructed
324  // ndl += ((KVTelescope *) list->At(0))->GetDetectors()->GetSize();
325  //
326  delete list;
327  }
328  }
329 
330  return ndl;
331 }
332 
333 
334 
335 
341 
343 {
344  //Creates and fills a list with all the detectors in the "detector layer"
345  //lay. Detector layers are always numbered from 1 (nearest target) to
346  //GetNumberOfDetectorLayers().
347  //Delete list after use.
348 
349  if (lay < 1)
350  return 0;
351  UInt_t ndl = 0;
352  UInt_t imin = GetLayerNearestTarget();
354  for (UInt_t i = imin; i <= imax; i++) {
355  unique_ptr<TList> tlist(GetTelescopesInLayer(i));
356  if (tlist.get()) {
357  //note we take the max number of detectors in telescopes of layer i
358  Int_t max = 0;
359  TIter it(tlist.get());
360  KVTelescope* tel = 0;
361  while ((tel = (KVTelescope*)it.Next()))
362  if (max < tel->GetDetectors()->GetSize())
363  max = tel->GetDetectors()->GetSize();
364  ndl += max;
365  //
366  //before it was assume that all telescopes in same layer are identically constructed
367  //ndl += ((KVTelescope *) tlist->At(0))->GetDetectors()->GetSize();
368  //
369  if (ndl >= lay) {
370  //the required detector layer is in the telescopes in the list
371 
372  //calculate rank of detectors in telescopes
373  UInt_t rank = max - ndl + lay;
374  TIter next(tlist.get());
375  KVTelescope* tel;
376  TList* list = new TList;
377  while ((tel = (KVTelescope*) next())) {
378  if (rank <= (UInt_t)tel->GetSize()) {
379  KVDetector* ddd = tel->GetDetector(rank);
380  if (ddd)
381  list->Add(ddd);
382  else
383  Warning("GetDetectorsInLayer", "pb d index pour GetDetector");
384  }
385  }
386  return list;
387  }
388  }
389  }
390  return 0;
391 
392 }
393 
394 
395 
396 
399 
401 {
402  //Find the "detector layer" to which this detector belongs
403 
404  for (UInt_t i = 1; i <= GetNumberOfDetectorLayers(); i++) {
405  unique_ptr<TList> list(GetDetectorsInLayer(i));
406  if (list->FindObject(det)) {
407  return i;
408  }
409  }
410  return 0;
411 }
412 
413 
414 
415 
424 
426 {
427  //Fill TList with all detectors aligned with "det" which are closer to the target.
428  //These are the detectors through which any particle stopping in "det" will have
429  //to pass. By default (dir=KVGroup::kBackwards) the list starts with "det" and
430  //goes towards the target. Use dir=KVGroup::kForwards to have the list in the
431  //order seen by an impinging particle.
432  //
433  //Delete TList after use.
434 
435  TList* tmp = new TList;
436 
437  UInt_t last_layer = GetDetectorLayer(det);
438  UInt_t first_layer = 1;
439 
440  if (dir == kForwards) {
441  for (UInt_t lay = first_layer; lay <= last_layer; lay++) {
442  unique_ptr<TList> dets(GetDetectorsInLayer(lay));
443  if (dets.get()) {
444  TIter next(dets.get());
445  KVDetector* d2;
446  while ((d2 = (KVDetector*) next())) {
447  if (((KVTelescope*)d2->GetParentStructure("TELESCOPE"))->IsOverlappingWith(
448  (KVTelescope*)det->GetParentStructure("TELESCOPE"))) {
449  tmp->Add(d2);
450  }
451  }
452  }
453  }
454  }
455  else {
456  for (UInt_t lay = last_layer; lay >= first_layer; lay--) {
457  unique_ptr<TList> dets(GetDetectorsInLayer(lay));
458  if (dets.get()) {
459  TIter next(dets.get());
460  KVDetector* d2;
461  while ((d2 = (KVDetector*) next())) {
462  if (((KVTelescope*)d2->GetParentStructure("TELESCOPE"))->
463  IsOverlappingWith((KVTelescope*)det->GetParentStructure("TELESCOPE"))) {
464  tmp->Add(d2);
465  }
466  }
467  }
468  }
469  }
470 
471  return tmp;
472 }
473 
474 
475 
476 
482 
484 {
485  //
486  //Returns the layer number of the layer in the group which is nearest to the target
487  //i.e. the layer with the smallest layer number
488  //
489  if (!fLayNumMin)
490  ((KVGroup*) this)->CountLayers();
491  return fLayNumMin;
492 }
493 
494 
495 
496 
502 
504 {
505  //
506  //Returns the layer number of the layer in the group which is furthest from the target
507  //i.e. the layer with the largest layer number
508  //
509 
510  if (!fLayNumMax)
511  ((KVGroup*) this)->CountLayers();
512  return fLayNumMax;
513 }
514 
515 
516 
519 
521 {
522  // Returns true if telescope belongs to this group
523  return (GetTelescopes()->FindObject(name) != 0);
524 }
525 
526 
527 
int Int_t
unsigned int UInt_t
ClassImp(KVPartitionList) void KVPartitionList
Initialisation.
#define d(i)
#define b(i)
unsigned char UChar_t
const Bool_t kFALSE
bool Bool_t
float Float_t
const Bool_t kTRUE
Group in axially-symmetric array (obsolete)
Definition: KVASGroup.h:16
TList * GetDetectorsInLayer(UInt_t lay)
Definition: KVASGroup.cpp:342
virtual ~KVASGroup()
Destructor.
Definition: KVASGroup.cpp:66
UInt_t GetLayerNearestTarget() const
Definition: KVASGroup.cpp:483
void Add(KVBase *)
Definition: KVASGroup.cpp:47
UInt_t fLayNumMin
minimum layer number (nearest to target)
Definition: KVASGroup.h:20
void SetDimensions()
Set dimensions of group according to dimensions of all its telescopes.
Definition: KVASGroup.cpp:80
void Sort()
Definition: KVASGroup.cpp:144
UInt_t fNumberOfLayers
number of different layers in group
Definition: KVASGroup.h:19
TList * GetTelescopesWithAngles(Float_t theta, Float_t phi) const
Definition: KVASGroup.cpp:197
UInt_t GetLayerFurthestTarget() const
Definition: KVASGroup.cpp:503
UInt_t fLayNumMax
maximum layer number (furthest from target)
Definition: KVASGroup.h:21
KVNameValueList * DetectParticle(KVNucleus *part)
Definition: KVASGroup.cpp:163
const KVSeqCollection * GetTelescopes() const
Definition: KVASGroup.h:48
UInt_t GetDetectorLayer(KVDetector *det)
Find the "detector layer" to which this detector belongs.
Definition: KVASGroup.cpp:400
UInt_t GetNumberOfDetectorLayers()
Definition: KVASGroup.cpp:303
TList * GetAlignedDetectors(KVDetector *, UChar_t dir=kBackwards)
Definition: KVASGroup.cpp:425
Bool_t Contains(KVBase *name) const
Returns true if telescope belongs to this group.
Definition: KVASGroup.cpp:520
void CountLayers()
Definition: KVASGroup.cpp:251
void init()
Default initialisation.
Definition: KVASGroup.cpp:31
TList * GetTelescopesInLayer(UInt_t nlayer)
Definition: KVASGroup.cpp:225
Base class for KaliVeda framework.
Definition: KVBase.h:135
UInt_t GetNumber() const
Definition: KVBase.h:213
Base class for detector geometry description, interface to energy-loss calculations.
Definition: KVDetector.h:121
KVGeoStrucElement * GetParentStructure(const Char_t *type, const Char_t *name="") const
void SortStructures(Bool_t order=kSortAscending)
const KVSeqCollection * GetDetectors() const
virtual void Add(KVBase *)
KVGeoStrucElement * GetParentStructure(const Char_t *type, const Char_t *name="") const
Group of detectors which can be treated independently of all others in array.
Definition: KVGroup.h:19
@ kForwards
Definition: KVGroup.h:32
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
Description of properties and kinematics of atomic nuclei.
Definition: KVNucleus.h:125
Double_t GetTheta() const
Definition: KVParticle.h:641
Double_t GetEnergy() const
Definition: KVParticle.h:582
Double_t GetPhi() const
Definition: KVParticle.h:649
Base class used for handling geometry in a multidetector array.
Definition: KVPosition.h:90
Bool_t IsInPhiRange(const Double_t phi)
Definition: KVPosition.cpp:336
virtual void SetAzimuthalMinMax(Double_t min, Double_t max)
Set min and max azimuthal angles and calculate (mean) phi.
Definition: KVPosition.cpp:216
Double_t GetPhiMax() const
Definition: KVPosition.h:145
Double_t GetPhiMin() const
Definition: KVPosition.h:141
Double_t GetThetaMin() const
Definition: KVPosition.h:149
Double_t GetAzimuthalWidth(Double_t phmin=-1., Double_t phimax=-1.) const
Definition: KVPosition.cpp:612
Bool_t IsInPolarRange(const Double_t theta)
kTRUE if given angle theta is within the polar range of this solid angle element
Definition: KVPosition.cpp:362
virtual void SetPolarMinMax(Double_t min, Double_t max)
Set min and max polar angles and calculate (mean) theta.
Definition: KVPosition.cpp:171
Bool_t IsOverlappingWith(KVPosition *pos)
kTRUE if there is at least partial overlap between two solid angle elements
Definition: KVPosition.cpp:408
Double_t GetThetaMax() const
Definition: KVPosition.h:153
virtual Int_t GetSize() const
Associates two detectors placed one behind the other.
Definition: KVTelescope.h:35
KVDetector * GetDetector(Int_t n) const
Definition: KVTelescope.h:49
virtual void DetectParticle(KVNucleus *kvp, KVNameValueList *nvl=0)
Int_t GetSize() const
Definition: KVTelescope.h:61
TObject * Next()
virtual void Add(TObject *obj)
virtual void Sort(Bool_t order=kSortAscending)
virtual void Warning(const char *method, const char *msgfmt,...) const
virtual TObject * FindObject(const char *name) const
Double_t Min(Double_t a, Double_t b)
Double_t Max(Double_t a, Double_t b)