KaliVeda
Toolkit for HIC analysis
Loading...
Searching...
No Matches
KVIDZAGrid.cpp
1/***************************************************************************
2 KVIDZAGrid.cpp - description
3 -------------------
4 begin : Nov 24 2004
5 copyright : (C) 2004 by J.D. Frankland
6 email : frankland@ganil.fr
7
8$Id: KVIDZAGrid.cpp,v 1.24 2009/05/05 15:57:52 franklan Exp $
9***************************************************************************/
10
11/***************************************************************************
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 * *
18 ***************************************************************************/
19
20
21#include "KVIDZAGrid.h"
22#include "KVIDZALine.h"
23#include "KVIDCutLine.h"
24#include "TCanvas.h"
25#include "TROOT.h"
26#include "KVIdentificationResult.h"
27
28
31
34{
35 //default ctor.
36 init();
37}
38
39
40
43
45{
46 //default dtor.
47}
48
49
50
53
55{
56 //Copy constructor
57 init();
58 grid.Copy(*this);
59}
60
61
62
65
66void KVIDZAGrid::Copy(TObject& obj) const
67{
68 //Copy this to 'obj'
69 KVIDGrid::Copy(obj);
70 // find the fZmax and fZmaxline pointer for new copy
71 ((KVIDZAGrid&) obj).Initialize();
72}
73
74
75
76
79
81{
82 //initialisation
83 fZMax = 0;
84 fZMaxLine = 0;
85
86 kinfi = kinf = ksup = ksups = -1;
87 dinf = dsup = dinfi = dsups = 0.;
88 winf = wsup = winfi = wsups = 0.;
89 Zinfi = Zinf = Zsup = Zsups = Ainfi = Ainf = Asup = Asups = 0;
90 fDistanceClosest = -1.;
91 fClosest = fLsups = fLsup = fLinf = fLinfi = 0;
92 fIdxClosest = -1;
93}
94
95
96
97
100
102{
103 // Remove and destroy identifier
104
105 gROOT->ProcessLine("if(gROOT->FindObject(\"gIDGridEditorCanvas\")) gIDGridEditor->Clear()");
106
107 Int_t toto = -1;
108 KVIDZALine* tmpline = 0;
109 if ((A > 0) && (!IsOnlyZId())) {
110 if ((tmpline = GetZALine(Z, A, toto))) RemoveIdentifier((KVIDentifier*)tmpline);
111 }
112 else {
113 if (!IsOnlyZId()) {
114 KVList* tmplist = (KVList*)fIdentifiers.GetSubListWithMethod(Form("%d", Z), "GetZ");
115 TIter next_id(tmplist);
116 while ((tmpline = (KVIDZALine*)next_id())) {
117 if (tmpline) RemoveIdentifier((KVIDentifier*)tmpline);
118 }
119 delete tmplist;
120 }
121 else if ((tmpline = GetZLine(Z, toto))) RemoveIdentifier((KVIDentifier*)tmpline);
122 }
123}
124
125
126
127
130
132{
133 // Remove and destroy identifiers
134 KVNumberList ZL(ZList);
135 ZL.Begin();
136 while (!ZL.End()) {
137 Int_t Z = ZL.Next();
138 RemoveLine(Z, -1);
139 }
140}
141
142
143
144
150
152{
153 //Returns ID line for which GetZ() returns 'z'. index=index of line found in
154 //fIDLines list (-1 if not found).
155 //To increase speed, this is done by dichotomy, rather than by looping over
156 //all the lines in the list.
157
158 index = -1;
159 Int_t nlines = GetNumberOfIdentifiers();
160 UInt_t idx_min = 0; //minimum index
161 UInt_t idx_max = nlines - 1; // maximum index
162 //as a first guess, we suppose that the lines are numbered sequentially from
163 //Z=1 (index 0) to Z=zmax=nlines (index nlines-1) with no gaps
164 UInt_t idx = ((UInt_t) z - 1 > idx_max ? idx_max : (UInt_t) z - 1);
165
166 while (idx_max > idx_min + 1) {
167
169 Int_t zline = line->GetZ();
170 //Found it ?
171 if (zline == z) {
172 index = idx;
173 return line;
174 }
175
176
177 if (z > zline) {
178 //increase index
179 idx_min = idx;
180 idx += (Int_t)((idx_max - idx) / 2 + 0.5);
181 }
182 else {
183 //decrease index
184 idx_max = idx;
185 idx -= (Int_t)((idx - idx_min) / 2 + 0.5);
186 }
187 }
188 //if one of these two lines has the right Z, return its pointer
190 if (line->GetZ() == z) {
191 index = idx_min;
192 return line;
193 }
194 line = (KVIDZALine*) GetIdentifierAt(idx_max);
195 if (line->GetZ() == z) {
196 index = idx_max;
197 return line;
198 }
199 //if not, there is no line in the grid with the right Z
200 return 0;
201}
202
203
204
205
211
213{
214 //Returns ID line corresponding to nucleus (Z,A) and its index in fIDLines.
215 //First we use GetLine(z) to find a line with the right Z (in
216 //principal there are several in the grid), then search for the correct
217 //isotope among these.
218
219 Int_t idx;
220 index = -1;
221 KVIDZALine* line = GetZLine(z, idx);
222 //no line with correct Z ?
223 if (!line)
224 return 0;
225 //got right mass?
226 if (line->GetA() == a) {
227 index = idx;
228 return line;
229 }
230 //increase/decreas index depending on if mass of line is greater than or less than a
231 if (a > line->GetA()) {
232 for (int i = idx; i < (int) GetNumberOfIdentifiers(); i++) {
234 if (line->GetZ() != z)
235 return 0; //no longer correct Z
236 if (line->GetA() == a) {
237 index = i;
238 return line;
239 }
240 }
241 //gone to the end of the list and still not found it
242 return 0;
243 }
244 else if (a < line->GetA()) {
245 for (int i = idx; i > 0; i--) {
247 if (line->GetZ() != z)
248 return 0; //no longer correct Z
249 if (line->GetA() == a) {
250 index = i;
251 return line;
252 }
253 }
254 //got to start of list and still not found
255 return 0;
256 }
257 return 0;
258}
259
260
261
262
286
288{
289 //Calculate natural "width" of each line in the grid.
290 //The lines in the grid are first sorted so that they are in order of ascending 'Y'
291 //i.e. first line is 1H, last line is the heaviest isotope (highest line).
292 //
293 //Then, for a given line :
294 //
295 // **** if the grid is to be used for A & Z identification (default)**** :
296 // - if the next line (above) has the same Z, we use the separation between these
297 // two lines corresponding to different isotopes of the same element
298 // - if the next line (above) has a different Z, but the line before (below) has
299 // the same Z, we use the separation between the line below and this one
300 // - if neither adjacent line has the same Z, the width is set to 16000 (huge).
301 //
302 // **** if the grid is to be used for Z identification (fOnlyZid=kTRUE)**** :
303 // - we use the separation between each pair of lines
304 //
305 //In each case we find D_L (the separation between the two lines at their extreme left)
306 //and D_R (their separation at extreme right). The width of the line is then calculated
307 //from these two using the method KVIDZALine::SetAsymWidth (which may be overridden in child
308 //classes).
309
310
311// Info("CalculateLineWidths",
312// "For grid %s (%s vs. %s, runs %s).", GetName(), GetVarY(), GetVarX(), GetRunList());
313
314 for (Int_t i = 0; i < (Int_t) GetNumberOfIdentifiers(); i++) {
315
317 if (!obj->InheritsFrom("KVIDZALine")) continue;
318 KVIDZALine* _line = (KVIDZALine*) obj;
319// KVIDZALine* _line = (KVIDZALine*) GetIdentifierAt(i);
320
321 //Z of lines above and below this line - Zxx=-1 if there is no line above or below
322 Int_t Zhi =
323 (i <
325 1 ? ((KVIDZALine*) GetIdentifierAt(i + 1))->GetZ() : -1);
326 Int_t Zlo = (i > 0 ? ((KVIDZALine*) GetIdentifierAt(i - 1))->GetZ() : -1);
327 Int_t Z = _line->GetZ();
328
329 // find line for comparison.
330 // if we are dealing with a grid with several isotopes for each Z, the priority
331 // is to calculate isotopic line widths using lines with same Z, different A.
332 // if the grid is 'OnlyZId' it should have only one line per Z, so we calculate
333 // widths by comparing neighbouring Z.
334 // if the grid is not 'OnlyZId', it may still have some lines with just one isotope
335 // per Z, in this case we calculate a width based on the separation from the
336 // neighbouring Z, as if it were 'OnlyZId'.
337 Int_t i_other;// index of line used to calculate width
338 if (IsOnlyZId()) { //grid is 'OnlyZId':calculate widths by comparing neighbouring Z.
339 i_other = (Zhi > -1 ? i + 1 : (Zlo > -1 ? i - 1 : -1));
340 }
341 else {
342 //grid with several isotopes for each Z:calculate isotopic widths using lines with same Z, different A
343 i_other = (Zhi == Z ? i + 1 : (Zlo == Z ? i - 1 : -1));
344 }
345 if (!IsOnlyZId() && i_other < 0) { //grid is not 'OnlyZId' but only one isotope for this Z
346 i_other = (Zhi > -1 ? i + 1 : (Zlo > -1 ? i - 1 : -1));
347 }
348
349 //default width of 16000 in case of "orphan" line
350 if (i_other < 0) {
351 //Info("CalculateLineWidths", "No line found for comparison with %s. Width set to 16000", _line->GetName());
352 _line->SetWidth(16000.);
353 continue; // skip to next line
354 }
355
356 KVIDZALine* _otherline = (KVIDZALine*) GetIdentifierAt(i_other);
357
358 //calculate asymptotic distances between lines at left and right.
359 //do this by finding which line's endpoint is between both endpoints of the other line
360 Double_t D_L, D_R;
361
362 //*************** LEFT SIDE ********************************
363
364 //get coordinates of first point of our line
365 Double_t x1, y1;
366 _line->GetStartPoint(x1, y1);
367 KVIDZALine* _aline, *_bline;
368
369 if (_otherline->IsBetweenEndPoints(x1, y1, "x")) {
370
371 //first point of our line is "inside" the X-coords of the other line:
372 //asymptotic distance LEFT is distance from our line's starting point (x1,Y1) to the other line
373 _aline = _otherline;
374 _bline = _line;
375
376 }
377 else {
378
379 //first point of other line is "inside" the X-coords of the our line:
380 //asymptotic distance LEFT is distance from other line's starting point (x1,Y1) to our line
381 _aline = _line;
382 _bline = _otherline;
383 _otherline->GetStartPoint(x1, y1);
384
385 }
386
387 //calculate D_L
388 Int_t dummy = 0;
389 D_L = _aline->DistanceToLine(x1, y1, dummy);
390
391 //make sure that D_L is positive : if not, we try to calculate other way (inverse line and starting point)
392 if (D_L < 0.) {
393
394 Double_t oldD_L = D_L;
395
396 _aline->GetStartPoint(x1, y1);
397 D_L = _bline->DistanceToLine(x1, y1, dummy);
398
399 //still no good ? then we keep the smallest absolute value
400 if (D_L < 0.) {
401 D_L = TMath::Abs(TMath::Max(D_L, oldD_L));
402 }
403 }
404 //*************** RIGHT SIDE ********************************
405
406 //get coordinates of last point of our line
407 _line->GetEndPoint(x1, y1);
408
409 if (_otherline->IsBetweenEndPoints(x1, y1, "x")) {
410
411 //last point of our line is "inside" the X-coords of the other line:
412 //asymptotic distance RIGHT is distance from our line's end point (x1,Y1) to the other line
413 _aline = _otherline;
414 _bline = _line;
415
416 }
417 else {
418
419 //last point of other line is "inside" the X-coords of the our line:
420 //asymptotic distance RIGHT is distance from other line's end point (x1,Y1) to our line
421 _aline = _line;
422 _bline = _otherline;
423 _otherline->GetEndPoint(x1, y1);
424
425 }
426
427 //calculate D_R
428 D_R = _aline->DistanceToLine(x1, y1, dummy);
429
430 //make sure that D_R is positive : if not, we try to calculate other way (inverse line and end point)
431 if (D_R < 0.) {
432
433 Double_t oldD_R = D_R;
434
435 _aline->GetEndPoint(x1, y1);
436 D_R = _bline->DistanceToLine(x1, y1, dummy);
437
438 //still no good ? then we keep the smallest absolute value
439 if (D_R < 0.) {
440 D_R = TMath::Abs(TMath::Max(D_R, oldD_R));
441 }
442 }
443 //*************** SET NATURAL WIDTH OF LINE ********************************
444
445 _line->SetAsymWidth(D_L, D_R);
446
447
448 //Info("CalculateLineWidths", "...width for line %s set to : %f (D_L=%f,D_R=%f)", _line->GetName(), _line->GetWidth(), D_L, D_R);
449 }
450}
451
452
453
454
458
460{
461 //This method displays the grid as in KVIDGrid::Draw, but
462 //the natural line widths are shown as error bars
463
464 if (!gPad) {
465 new TCanvas("c1", GetName());
466 }
467 else {
468 gPad->SetTitle(GetName());
469 }
470 if (!gPad->GetListOfPrimitives()->GetSize()) {
471 //calculate size of pad necessary to show grid
472 if (GetXmin() == GetXmax())
473 const_cast < KVIDZAGrid* >(this)->FindAxisLimits();
474 gPad->DrawFrame(GetXmin(), GetYmin(), GetXmax(), GetYmax());
475 }
476 TIter nextID(GetIdentifiers());
478 while ((line = (KVIDZALine*)nextID())) {
479 line->GetLineWithWidth()->Draw("3PL");
480 }
481 {
482 GetCuts()->R__FOR_EACH(KVIDLine, Draw)("PL");
483 }
484 gPad->Modified();
485 gPad->Update();
486}
487
488
489
490
517
519{
520 // This method will locate (at most) four lines close to the point (x,y), the point must
521 // lie within the endpoints (in X) of each line (the lines "embrace" the point).
522 // Returns kTRUE if at least one line is found. Identification can then be carried out with
523 // either IdentZA or IdentZ (see Identify).
524 // Returns kFALSE if no lines are found (not even a closest embracing line).
525 //
526 // We look for two lines above the point and two lines below the point, as in one of the following two cases:
527 //
528 // ------------------------ ksups ---------------------
529 //
530 // closest ---> ------------------------ ksup ---------------------
531 // X
532 //
533 // X
534 // ------------------------ kinf --------------------- <--- closest
535 //
536 // ------------------------ kinfi ---------------------
537 //
538 // First we find the closest embracing line to the point, using FindNearestEmbracingIDLine.
539 // Then we search above and below for the other 'embracing' lines. Note that no condition is
540 // applied regarding the distances to these lines: the lines must have been sorted in order of increasing
541 // ordinate before hand in Initialize(), we simply use the order of lines in the list of identifiers.
542 // The Z, A, width and distance to each of these lines are stored in the variables
543 // Zsups, Asups, wsups, dsups
544 // etc. etc. to be used by IdentZA or IdentZ.
545
546
547 kinfi = kinf = ksup = ksups = -1;
548 dinf = dsup = dinfi = dsups = 0.;
549 winf = wsup = winfi = wsups = 16000.;
550 Zinfi = Zinf = Zsup = Zsups = Ainfi = Ainf = Asup = Asups = -1;
551 fDistanceClosest = -1.;
552 fClosest = fLsups = fLsup = fLinf = fLinfi = 0;
553 fIdxClosest = -1;
554
556
557 if (!fClosest) return kFALSE; // no lines found
558
559 Int_t dummy = 0;
560 if (kinf > -1 && kinf == fIdxClosest) {
561 //point is above closest line, closest line is "kinf"
562 //need to look for 2 lines above (ksup, ksups) and 1 line below (kinfi)
563 fLinf = fClosest;
564 if (fLinf->InheritsFrom("KVIDZALine")) {
565 winf = ((KVIDZALine*)fLinf)->GetWidth();
566 Zinf = fLinf->GetZ();
567 Ainf = fLinf->GetA();
568 }
569 if (ksup > -1) {
571 if (fLsup->InheritsFrom("KVIDZALine")) {
572 wsup = ((KVIDZALine*)fLsup)->GetWidth();
573 Zsup = fLsup->GetZ();
574 Asup = fLsup->GetA();
575 }
576 }
577 }
578 else if (ksup > -1 && ksup == fIdxClosest) {
579 //point is below closest line, closest line is "ksup"
580 //need to look for 1 line above (ksups) and 2 lines below (kinf, kinfi)
581 fLsup = fClosest;
582 if (fLsup->InheritsFrom("KVIDZALine")) {
583 wsup = ((KVIDZALine*)fLsup)->GetWidth();
584 Zsup = fLsup->GetZ();
585 Asup = fLsup->GetA();
586 }
587 if (kinf > -1) {
589 if (fLinf->InheritsFrom("KVIDZALine")) {
590 winf = ((KVIDZALine*)fLinf)->GetWidth();
591 Zinf = fLinf->GetZ();
592 Ainf = fLinf->GetA();
593 }
594 }
595 }
596 else {
597 Error("FindFourEmbracingLines",
598 "I do not understand the result of FindNearestEmbracingIDLine!!!");
599 return kFALSE;
600 }
601
602
603 if (kinf > -1) {
604 // look for kinfi line -> next line below 'inf' line
605 kinfi = kinf;
606 fLinfi = FindNextEmbracingLine(kinfi, -1, x, y, "x");
607 if (!fLinfi) kinfi = -1; // no 'infi' line found
608 else {
610 if (fLinfi->InheritsFrom("KVIDZALine")) {
611 winfi = ((KVIDZALine*)fLinfi)->GetWidth();
612 Zinfi = fLinfi->GetZ();
613 Ainfi = fLinfi->GetA();
614 }
615 }
616 }
617 if (ksup > -1) {
618 // look for ksups line -> next line above 'sup' line
619 ksups = ksup;
620 fLsups = FindNextEmbracingLine(ksups, 1, x, y, "x");
621 if (!fLsups) ksups = -1; // no 'sups' line found
622 else {
624 if (fLsups->InheritsFrom("KVIDZALine")) {
625 wsups = ((KVIDZALine*)fLsups)->GetWidth();
626 Zsups = fLsups->GetZ();
627 Asups = fLsups->GetA();
628 }
629 }
630 }
631 return kTRUE;
632}
633
634
635
636
642
644{
645 //Finds Z, A and 'real A' for point (x,y) once closest lines to point have been found
646 //by calling method FindFourEmbracingLines beforehand.
647 //This is a line-for-line copy of the latter part of IdnCsOr, even the same
648 //variable names and comments have been used (as much as possible).
649
650 fICode = kICODE0;
651 Z = -1;
652 A = -1;
653 Aint = 0;
654 /* cout << "kinfi = " << kinfi << " Zinfi = " << Zinfi << " Ainfi = " << Ainfi << " winfi = " << winfi << " dinfi = " << dinfi << endl;
655 cout << "kinf = " << kinf << " Zinf = " << Zinf << " Ainf = " << Ainf << " winf = " << winf << " dinf = " << dinf << endl;
656 cout << "ksup = " << ksup << " Zsup = " << Zsup << " Asup = " << Asup << " wsup = " << wsup << " dsup = " << dsup << endl;
657 cout << "ksups = " << ksups << " Zsups = " << Zsups << " Asups = " << Asups << " wsups = " << wsups << " dsups = " << dsups << endl;
658 */
659 Int_t ibif = 0;
660 Int_t k = -1;
661 Double_t yy, y1, y2;
662 Int_t ix1, ix2;
663 yy = y1 = y2 = 0;
664 ix1 = ix2 = 0;
665 if (ksup > -1) {
666 if (kinf > -1) {
667 //cout << " /******************* 2 lignes encadrant le point ont ete trouvees ************************/" << endl;
668 Double_t dt = dinf + dsup; //distance between the 2 lines
669 if (Zinf == Zsup) {
670 // cout << " /****************meme Z**************/" << endl;
671 Z = Zinf;
672 Int_t dA = Asup - Ainf;
673 Double_t dist = dt / dA; //distance between the 2 lines normalised to difference in A of lines
674 /*** A = Asup ***/
675 if (dinf > dsup) { //point is closest to upper line, 'sup' line
676 ibif = 1;
677 k = ksup;
678 yy = -dsup;
679 A = Asup;
680 Aint = Asup;
681 if (ksups > -1) { // there is a 'sups' line above the 2 which encadrent le point
682 y2 = dsups - dsup;
683 if (Zsups == Zsup) {
684 ibif = 0;
685 y2 /= 2.;
686 ix2 = Asups - Asup;
687 }
688 else {
689 y2 /= 2.;
690 Double_t x2 = wsup;
691 x2 = 0.5 * TMath::Max(x2, dist);
692 y2 = TMath::Min(y2, x2);
693 ix2 = 1;
694 }
695 }
696 else { // ksups == -1 i.e. no 'sups' line
697 y2 = wsup;
698 y2 = 0.5 * TMath::Max(y2, dist);
699 ix2 = 1;
700 }
701 y1 = -dt / 2.;
702 ix1 = -dA;
703 }
704 /*** A = Ainf ***/
705 else { //point is closest to lower line, 'inf' line
706 ibif = 2;
707 k = kinf;
708 yy = dinf;
709 A = Ainf;
710 Aint = Ainf;
711 if (kinfi > -1) { // there is a 'infi' line below the 2 which encadrent le point
712 y1 = 0.5 * (dinfi - dinf);
713 if (Zinfi == Zinf) {
714 ibif = 0;
715 ix1 = Ainfi - Ainf;
716 y1 = -y1;
717 }
718 else {
719 Double_t x1 = winf;
720 x1 = 0.5 * TMath::Max(x1, dist);
721 y1 = -TMath::Min(y1, x1);
722 ix1 = -1;
723 }
724 }
725 else { // kinfi = -1 i.e. no 'infi' line
726 y1 = winf;
727 y1 = -0.5 * TMath::Max(y1, dist);
728 ix1 = -1;
729 }
730 y2 = dt / 2.;
731 ix2 = dA;
732 }
733 }
734 else {
735 //cout << " /****************Z differents**************/ " << endl;
736 /*** Z = Zsup ***/
737 ibif = 3;
738 if (dinf > dsup) { // closest to upper 'sup' line
739 k = ksup;
740 yy = -dsup;
741 Z = Zsup;
742 A = Asup;
743 Aint = Asup;
744 y1 = 0.5 * wsup;
745 if (ksups > -1) { // there is a 'sups' line above the 2 which encadrent the point
746 y2 = dsups - dsup;
747 if (Zsups == Zsup) {
748 ibif = 2;
749 ix2 = Asups - Asup;
750 Double_t x1 = y2 / ix2 / 2.;
751 y1 = TMath::Max(y1, x1);
752 y1 = -TMath::Min(y1, dt / 2.);
753 ix1 = -1;
754 y2 /= 2.;
755 }
756 else {
757 y2 /= 2.;
758 y2 = TMath::Min(y1, y2);
759 ix2 = 1;
760 y1 = -TMath::Min(y1, dt / 2.);
761 ix1 = -1;
762 }
763 }
764 else { // ksups == -1, i.e. no 'sups' line
765 fICode = kICODE7; //a gauche de la ligne fragment, Z est alors un Zmin et le plus probable
766 y2 = y1;
767 ix2 = 1;
768 y1 = -TMath::Min(y1, dt / 2.);
769 ix1 = -1;
770 }
771 }
772 /*** Z = Zinf ***/
773 else { // closest to lower 'inf' line
774 k = kinf;
775 yy = dinf;
776 Z = Zinf;
777 A = Ainf;
778 Aint = Ainf;
779 y2 = 0.5 * winf;
780 if (kinfi > -1) { // there is a 'infi' line below the 2 which encadrent the point
781 y1 = dinfi - dinf;
782 if (Zinfi == Zinf) {
783 ibif = 1;
784 ix1 = Ainfi - Ainf;
785 Double_t x2 = -y1 / ix1 / 2.;
786 y2 = TMath::Max(y2, x2);
787 y2 = TMath::Min(y2, dt / 2.);
788 ix2 = 1;
789 y1 /= -2.;
790 }
791 else {
792 y1 = -TMath::Min(y2, y1 / 2.);
793 ix1 = -1;
794 y2 = TMath::Min(y2, dt / 2.);
795 ix2 = 1;
796 }
797 }
798 else { // no kinfi line, kinfi==-1
799 y1 = -y2;
800 ix1 = -1;
801 y2 = TMath::Min(y2, dt / 2.);
802 ix1 = 1;
803 }
804 }
805 }
806 }//if(kinf>-1)...
807 else if (Zsup > 0) {
808 //cout<<" /****************** Seule une ligne superieure a ete trouvee *********************/" << endl;
809 ibif = 3;
810 k = ksup;
811 yy = -dsup;
812 Z = Zsup;
813 A = Asup;
814 Aint = Asup;
815 y1 = 0.5 * wsup;
816 if (ksups > -1) { // there is a 'sups' line above the closest line to the point
817 y2 = dsups - dsup;
818 if (Zsups == Zsup) {
819 ibif = 2;
820 ix2 = Asups - Asup;
821 Double_t x1 = y2 / ix2 / 2.;
822 y1 = -TMath::Max(y1, x1);
823 ix1 = -1;
824 y2 /= 2.;
825 }
826 else {
827 y2 /= 2.;
828 y2 = TMath::Min(y1, y2);
829 ix2 = 1;
830 y1 = -y1;
831 ix1 = -1;
832 }
833 }
834 else { // no 'sups' line above closest line
835 fICode = kICODE7; //Z est alors un Zmin et le plus probable
836 y2 = y1;
837 ix2 = 1;
838 y1 = -y1;
839 ix1 = -1;
840 }
841 if (yy >= y1)
842 fICode = kICODE0; // we are within the 'natural width' of the last line
843 else {
844 fICode = kICODE6; // we are too far from first line to extrapolate correctly
845 Z = Zsup - 1; // give Z below first line of grid, but this is an upper limit
846 }
847 }
848 else {
849 fICode = kICODE8; // Z indetermine ou (x,y) hors limites
850 }
851 }
852 else if (kinf > -1) {
853
854 //cout <<"/****************** Seule une ligne inferieure a ete trouvee ***********************/" << endl;
855
856 ibif = 3;
857 k = kinf;
858 Z = Zinf;
859 A = Ainf;
860 Aint = Ainf;
861 yy = dinf;
862 y2 = 0.5 * winf;
863 if (kinfi > -1) {
864 y1 = dinfi - dinf;
865 if (Zinfi == Zinf) {
866 ibif = 1;
867 ix1 = Ainfi - Ainf;
868 Double_t x2 = -y1 / ix1 / 2.;
869 y2 = TMath::Max(y2, x2);
870 ix2 = 1;
871 y1 /= -2.;
872 }
873 else {
874 y1 = -TMath::Min(y2, y1 / 2.);
875 ix1 = -1;
876 ix2 = 1;
877 }
878 }
879 else {
880 y1 = -y2;
881 ix1 = -1;
882 ix2 = 1;
883 }
884 if (yy <= y2)
885 fICode = kICODE0; // we are within the 'natural width' of the last line
886 else
887 fICode = kICODE7; // we are too far from last line to extrapolate correctly
888
889 }
890 /*****************Aucune ligne n'a ete trouvee*********************************/
891 else {
892 fICode = kICODE8; // Z indetermine ou (x,y) hors limites
893 }
894 /****************Test des bornes********************************************/
895 if (k > -1 && fICode == kICODE0) {
896 if (yy > y2)
897 fICode = kICODE4; // Z ok, masse hors limite superieure ou egale a A
898 }
899 if (k > -1 && (fICode == kICODE0 || fICode == kICODE7)) {
900 if (yy < y1)
901 fICode = kICODE5; // Z ok, masse hors limite inferieure ou egale a A
902 }
903 if (fICode == kICODE4 || fICode == kICODE5) {
904 A = -1;
905 Aint = 0;
906 }
907 /****************Interpolation de la masse: da = f*log(1+b*dy)********************/
908 if (fICode == kICODE0) {
909 Double_t deltaA = 0.;
910 Bool_t i = kFALSE;
911 Double_t dt, dist = y1 * y2;
912 dt = 0.;
913 if (ix2 == -ix1) { //dA1 = dA2
914 if (dist != 0) {
915 dt = -(y1 + y2) / dist;
916 i = kTRUE;
917 }
918 /*else
919 Warning("IdentZA","%s : cannot calculate interpolated mass, Areal will equal Aint (Z=%d Aint=%d fICode=%d)",
920 GetName(), Z, Aint, fICode);*/
921 }
922 else if (ix2 == -ix1 * 2) { // dA2 = 2*dA1
923 Double_t tmp = y1 * y1 - 4. * dist;
924 if (tmp > 0 && dist != 0) {
925 dt = -(y1 + 2. * y2 -
926 TMath::Sqrt(tmp)) / dist / 2.;
927 i = kTRUE;
928 }
929 /*else
930 Warning("IdentZA","%s : cannot calculate interpolated mass, Areal will equal Aint (Z=%d Aint=%d fICode=%d)",
931 GetName(), Z, Aint, fICode);*/
932 }
933 else if (ix1 == -ix2 * 2) { // dA1 = 2*dA2
934 Double_t tmp = y2 * y2 - 4. * dist;
935 if (tmp > 0 && dist != 0) {
936 dt = -(y2 + 2. * y1 +
937 TMath::Sqrt(tmp)) / dist / 2.;
938 i = kTRUE;
939 }
940 /*else
941 Warning("IdentZA","%s : cannot calculate interpolated mass, Areal will equal Aint (Z=%d Aint=%d fICode=%d)",
942 GetName(), Z, Aint, fICode);*/
943 }
944 if (i) {
945 dist = dt * y2;
946 if (TMath::Abs(dist) < 0.001) {
947 if (y2 != 0)
948 deltaA = yy * ix2 / y2 / 2.;
949 /*else
950 Warning("IdentZA","%s : cannot calculate interpolated mass (y2=%f), Areal will equal Aint (Z=%d Aint=%d fICode=%d)",
951 GetName(), y2, Z, Aint, fICode);*/
952 }
953 else {
954 if (dist > -1. && dt * yy > -1.)
955 deltaA = ix2 / 2. / TMath::Log(1. + dist) * TMath::Log(1. + dt * yy);
956 /*else
957 Warning("IdentZA","%s : cannot calculate interpolated mass (dist=%f dt*yy=%f), Areal will equal Aint (Z=%d Aint=%d fICode=%d)",
958 GetName(), dist, dt*yy, Z, Aint, fICode);*/
959 }
960 A += deltaA;
961 }
962 }
963 /***************D'autres masses sont-elles possibles ?*************************/
964 if (fICode == kICODE0 && (ibif > 0 && ibif < 4)) {
965 if (ibif != 2) { /***Masse superieure***/
966 //We look at next line in the complete list of lines, after the closest line.
967 //If it has the same Z as the closest line, but was excluded from research for closest line
968 //because the point lies outside the endpoints, there remains a doubt about the mass:
969 //on rajoute 1 a fICode, effectivement on le met = kICODE1
970 Int_t idx = fIdxClosest; // index of closest line
971 if (idx > -1 && ++idx < GetNumberOfIdentifiers()) {
972 KVIDentifier* nextline = GetIdentifierAt(idx);
973 if (nextline->GetZ() == Z
974 && !((KVIDLine*)nextline)->IsBetweenEndPoints(x, y, "x")) {
975 fICode++; // Z ok, mais les masses superieures a A sont possibles
976 //cout <<"//on rajoute 1 a fICode, effectivement on le met = kICODE1" << endl;
977 }
978 }
979 }
980 if (ibif != 1) { /***Masse inferieure***/
981 //We look at line below the closest line in the complete list of lines.
982 //If it has the same Z as the closest line, but was excluded from research for closest line
983 //because the point lies outside the endpoints, there remains a doubt about the mass:
984 //on rajoute 2 a fICode, so it can be = kICODE2 or kICODE3
985 Int_t idx = fIdxClosest;
986 if (idx > -1 && --idx >= 0) {
987 KVIDentifier* nextline = GetIdentifierAt(idx);
988 if (nextline->GetZ() == Z
989 && !((KVIDLine*)nextline)->IsBetweenEndPoints(x, y, "x")) {
990 fICode += 2;
991 //cout << "//on rajoute 2 a fICode, so it can be = kICODE2 or kICODE3" << endl;
992 }
993 }
994 }
995 }
996
997 if (fICode < kICODE4) ReCheckQuality(Z, A);
998
999
1000 //cout << "Z = " << Z << " A = " << A << " icode = " << fICode << endl;
1001}
1002
1003
1004
1021
1023{
1024 //Recheck the identification quality using the 'manual' width set for each Z in the parameter list
1025 //
1026 //If abs(Aint-Areal)> ManualWidth + ManualWidthScaling*sqrt(Z), kIDCode5 is returned.
1027 //To be activated, a parameter "ManualWidth" should be added to the grid's parameter list.
1028 //
1029 //Acceptable values for FAZIA are :
1030 // * ManualWidth : 0.3
1031 // * ManualWidthScaling : 0.05
1032 //
1033 // Example of use :
1034 //~~~~{.cpp}
1035 //KVIDZAGrid grid;
1036 //grid.ReadAsciiFile("my_grid_file.dat");
1037 //grid.SetManualWidth(0.3,0.05);
1038 //~~~~
1039
1040 double da = 1.;
1041 double das = 0.;
1042
1043 if (!GetParameters()->HasParameter("ManualWidth")) return;
1044 da = GetParameters()->GetDoubleValue("ManualWidth");
1045
1046 if (GetParameters()->HasParameter("ManualWidthScaling")) das = GetParameters()->GetDoubleValue("ManualWidthScaling");
1047 da += das * TMath::Sqrt(Z);
1048
1049 int aa = TMath::Nint(A);
1050
1051 KVNucleus nn(Z, aa);
1052 if (nn.GetLifeTime() < 1e-9) fICode = kICODE5;
1053
1054// if (Z == 1 && aa == 1) da *= .75;
1055 if (TMath::Abs(aa - A) > da) fICode = kICODE5;
1056}
1057
1058
1059
1061
1062void KVIDZAGrid::SetManualWidth(Double_t manual_width, Double_t manual_width_scaling)
1063{
1064 GetParameters()->SetValue("ManualWidth", manual_width);
1065 GetParameters()->SetValue("ManualWidthScaling", manual_width_scaling);
1066}
1067
1068
1069
1070
1075
1077{
1078 // Finds Z & 'real Z' for point (x,y) once closest lines to point have been found (see GetNearestIDLine).
1079 // This is is based on the algorithm developed by L. Tassan-Got in IdnCsOr, even the same
1080 // variable names and comments have been used (as much as possible).
1081
1082 fICode = kICODE0;
1083 Z = -1;
1084 Aint = 0;
1085 Zint = 0;
1086 /* cout << "kinfi = " << kinfi << " Zinfi = " << Zinfi << " Ainfi = " << Ainfi << " winfi = " << winfi << " dinfi = " << dinfi << endl;
1087 cout << "kinf = " << kinf << " Zinf = " << Zinf << " Ainf = " << Ainf << " winf = " << winf << " dinf = " << dinf << endl;
1088 cout << "ksup = " << ksup << " Zsup = " << Zsup << " Asup = " << Asup << " wsup = " << wsup << " dsup = " << dsup << endl;
1089 cout << "ksups = " << ksups << " Zsups = " << Zsups << " Asups = " << Asups << " wsups = " << wsups << " dsups = " << dsups << endl;
1090 */
1091 Int_t ibif = 0;
1092 Int_t k = -1;
1093 Double_t yy, y1, y2;
1094 Int_t ix1, ix2;
1095 yy = y1 = y2 = 0;
1096 ix1 = ix2 = 0;
1097
1098 if (ksup > -1) { // there is a line above the point
1099 if (kinf > -1) { // there is a line below the point
1100
1101 //printf("------------>/* We found a line above and a line below the point */\n");
1102
1103 Double_t dt = dinf + dsup; //distance between the 2 lines
1104 Int_t dZ = Zsup - Zinf;
1105 Double_t dist = dt / (1.0 * dZ); //distance between the 2 lines normalised to difference in Z of lines
1106
1107 /*** Z = Zsup ***/
1108 if (dinf > dsup) { //point is closest to upper line, 'sup' line
1109 ibif = 1;
1110 k = ksup;
1111 yy = -dsup;
1112 Z = Zsup;
1113 Zint = Zsup;
1114 Aint = Asup;
1115 if (ksups > -1) { // there is a 'sups' line above the 2 which encadrent le point
1116 y2 = dsups - dsup;
1117
1118 ibif = 0;
1119 y2 /= 2.;
1120 ix2 = Zsups - Zsup;
1121 }
1122 else { // ksups == -1 i.e. no 'sups' line
1123 y2 = wsup;
1124 y2 = 0.5 * TMath::Max(y2, dist);
1125 ix2 = 1;
1126 }
1127 y1 = -dt / 2.;
1128 ix1 = -dZ;
1129 }
1130 /*** Z = Zinf ***/
1131 else { //point is closest to lower line, 'inf' line
1132 ibif = 2;
1133 k = kinf;
1134 yy = dinf;
1135 Z = Zinf;
1136 Zint = Zinf;
1137 Aint = Ainf;
1138 if (kinfi > -1) { // there is a 'infi' line below the 2 which encadrent le point
1139 y1 = 0.5 * (dinfi - dinf);
1140
1141 ibif = 0;
1142 ix1 = Zinfi - Zinf;
1143 y1 = -y1;
1144
1145 }
1146 else { // kinfi = -1 i.e. no 'infi' line
1147 y1 = winf;
1148 y1 = -0.5 * TMath::Max(y1, dist);
1149 ix1 = -1;
1150 }
1151 y2 = dt / 2.;
1152 ix2 = dZ;
1153 }
1154
1155 }//if(kinf>-1)...*******************************************************
1156 else {
1157 //printf("------------>/* Only a line above the point was found, no line below */\n");
1158 /* This means the point is below the first Z line of the grid (?) */
1159 ibif = 3;
1160 k = ksup;
1161 yy = -dsup;
1162 Z = Zsup;
1163 Zint = Zsup;
1164 Aint = Asup;
1165 y1 = 0.5 * wsup;
1166 if (ksups > -1) { // there is a 'sups' line above the closest line to the point
1167 y2 = dsups - dsup;
1168
1169 ibif = 2;
1170 ix2 = Zsups - Zsup;
1171 Double_t x1 = y2 / ix2 / 2.;
1172 y1 = -TMath::Max(y1, x1);
1173 ix1 = -1;
1174 y2 /= 2.;
1175
1176 }
1177 else { // no 'sups' line above closest line
1178 y2 = y1;
1179 ix2 = 1;
1180 y1 = -y1;
1181 ix1 = -1;
1182 }
1183 if (yy >= y1)
1184 fICode = kICODE0; // we are within the 'natural width' of the last line
1185 else {
1186 fICode = kICODE6; // we are too far from first line to extrapolate correctly
1187 Z = Zsup - 1; // give Z below first line of grid, but this is an upper limit
1188 Zint = Zsup - 1;
1189 Aint = 0;
1190 }
1191 }
1192 } //if(ksup>-1)***************************************************************
1193 else if (kinf > -1) {
1194
1195 //printf("------------>/* Only a line below the point was found, no line above */\n");
1196 /* This means the point is above the last Z line of the grid (?) */
1197 ibif = 3;
1198 k = kinf;
1199 Z = Zinf;
1200 Zint = Zinf;
1201 Aint = Ainf;
1202 yy = dinf;
1203 y2 = 0.5 * winf;
1204 if (kinfi > -1) { // there is a 'infi' line below the closest line to the point
1205 y1 = dinfi - dinf;
1206 ibif = 1;
1207 ix1 = Zinfi - Zinf;
1208 Double_t x2 = -y1 / ix1 / 2.;
1209 y2 = TMath::Max(y2, x2);
1210 ix2 = 1;
1211 y1 /= -2.;
1212 }
1213 else {
1214 y1 = -y2;
1215 ix1 = -1;
1216 ix2 = 1;
1217 }
1218 if (yy <= y2)
1219 fICode = kICODE0; // we are within the 'natural width' of the last line
1220 else {
1221 fICode = kICODE7; // we are too far from last line to extrapolate correctly
1222 Z = Zinf + 1; // give Z above last line in grid, it is a lower limit
1223 Zint = Zinf + 1;
1224 Aint = 0;//calculate mass from Z
1225 }
1226
1227 }
1228 /*no lines found at all*/
1229 else {
1230 fICode = kICODE8; // Z indetermine ou (x,y) hors limites
1231 }
1232
1233
1234 /****************Test des bornes********************************************/
1235 if (k > -1 && fICode == kICODE0) {
1236 if (yy > y2)
1237 fICode = kICODE4; // Z ok, masse hors limite superieure ou egale a A
1238 }
1239 if (k > -1 && fICode == kICODE0) {
1240 if (yy < y1)
1241 fICode = kICODE5; // Z ok, masse hors limite inferieure ou egale a A
1242 }
1243 if (fICode == kICODE4 || fICode == kICODE5) Aint = 0;
1244
1245 /****************Interpolation to find 'real Z': dz = f*log(1+b*dy)********************/
1246
1247 if (fICode < kICODE6) {
1248 Double_t deltaZ = 0.;
1249 Bool_t i = kFALSE;
1250 Double_t dt, dist = y1 * y2;
1251 dt = 0.;
1252 if (ix2 == -ix1) { //dZ1 = dZ2
1253 if (dist != 0) {
1254 dt = -(y1 + y2) / dist;
1255 i = kTRUE;
1256 }
1257 /*else
1258 Warning("IdentZ","%s : cannot calculate interpolated charge, Zreal will equal Zint (Zint=%d fICode=%d)",
1259 GetName(), Zint, fICode);*/
1260 }
1261 else if (ix2 == -ix1 * 2) { // dZ2 = 2*dZ1
1262 Double_t tmp = y1 * y1 - 4. * dist;
1263 if (tmp > 0. && dist != 0) {
1264 dt = -(y1 + 2. * y2 -
1265 TMath::Sqrt(tmp)) / dist / 2.;
1266 i = kTRUE;
1267 }
1268 /*else
1269 Warning("IdentZ","%s : cannot calculate interpolated charge, Zreal will equal Zint (Zint=%d fICode=%d)",
1270 GetName(), Zint, fICode);*/
1271 }
1272 else if (ix1 == -ix2 * 2) { // dZ1 = 2*dZ2
1273 Double_t tmp = y2 * y2 - 4. * dist;
1274 if (tmp > 0. && dist != 0) {
1275 dt = -(y2 + 2. * y1 +
1276 TMath::Sqrt(tmp)) / dist / 2.;
1277 i = kTRUE;
1278 }
1279 /*else
1280 Warning("IdentZ","%s : cannot calculate interpolated charge, Zreal will equal Zint (Zint=%d fICode=%d)",
1281 GetName(), Zint, fICode);*/
1282 }
1283 if (i) {
1284 dist = dt * y2;
1285 if (TMath::Abs(dist) < 0.001) {
1286 if (y2 != 0)
1287 deltaZ = yy * ix2 / y2 / 2.;
1288 /*else
1289 Warning("IdentZ","%s : cannot calculate interpolated charge (y2=%f), Zreal will equal Zint (Zint=%d fICode=%d)",
1290 GetName(), y2, Zint, fICode);*/
1291 }
1292 else {
1293 if (dist > -1. && dt * yy > -1.)
1294 deltaZ = ix2 / 2. / TMath::Log(1. + dist) * TMath::Log(1. + dt * yy);
1295 /*else
1296 Warning("IdentZ","%s : cannot calculate interpolated charge (dist=%f dt*yy=%f), Zreal will equal Zint (Zint=%d fICode=%d)",
1297 GetName(), dist, dt*yy, Zint, fICode);*/
1298 }
1299 Z += deltaZ;
1300 }
1301 }
1302 /***************Is there still a doubt about the Z ?*************************/
1303 if (fICode == kICODE0 && (ibif > 0 && ibif < 4)) {
1304 /***z superieure***/
1305 if (ibif != 2) {
1306 //We look at next line in the complete list of lines, after the closest line.
1307 //If it was excluded from research for closest line
1308 //because the point lies outside the endpoints, there remains a doubt about the Z:
1309 //on rajoute 1 a fICode, effectivement on le met = kICODE1
1310 Int_t idx = fIdxClosest;
1311 if (idx > -1 && ++idx < GetNumberOfIdentifiers()) {
1312 KVIDLine* nextline = (KVIDLine*)GetIdentifierAt(idx);
1313 if (!nextline->IsBetweenEndPoints(x, y, "x")) {
1314 fICode++; // Z might be bigger than we think
1315 //cout <<"//on rajoute 1 a fICode, effectivement on le met = kICODE1" << endl;
1316 }
1317 }
1318 }
1319 /***z inferieure***/
1320 if (ibif != 1) {
1321 //We look at line below the closest line in the complete list of lines.
1322 //If it was excluded from research for closest line
1323 //because the point lies outside the endpoints, there remains a doubt about the Z:
1324 //on rajoute 2 a fICode, so it can be = kICODE2 or kICODE3
1325 Int_t idx = fIdxClosest;
1326 if (idx > -1 && --idx >= 0) {
1327 KVIDLine* nextline = (KVIDLine*) GetIdentifierAt(idx);
1328 if (!nextline->IsBetweenEndPoints(x, y, "x")) {
1329 fICode += 2;
1330 //cout << "//on rajoute 2 a fICode, so it can be = kICODE2 or kICODE3" << endl;
1331 }
1332 }
1333 }
1334 }
1335
1336}
1337
1338
1339
1340
1366
1368{
1369 // Fill the KVIdentificationResult object with the results of identification for point (x,y)
1370 // corresponding to some physically measured quantities related to a reconstructed nucleus.
1371 //
1372 // By default (OnlyZId()=kFALSE) this means identifying the Z & A of the nucleus.
1373 // In this case, we consider that the nucleus' Z & A have been correctly measured
1374 // if the 'quality code' returned by IdentZA() is < kICODE4:
1375 // we set idr->Zident and idr->Aident to kTRUE if fICode<kICODE4
1376 //
1377 // If OnlyZId()=kTRUE, only the Z of the nucleus is established.
1378 // In this case, we consider that the nucleus' Z has been correctly measured
1379 // if the 'quality code' returned by IdentZ() is < kICODE4, thus:
1380 // we set idr->Zident to kTRUE if fICode<kICODE4
1381 // The mass idr->A is set to the mass of the nearest line.
1382 //
1383 // Real & integer masses for isotopically identified particles
1384 // ===================================================
1385 // For points lying between two lines of same Z and different A (fICode<kIDCode4)
1386 // the "real" mass is given by interpolation between the two masses.
1387 // The integer mass is the A of the line closest to the point.
1388 // This means that the integer A is not always = nint("real" A),
1389 // as for example if a grid is drawn with lines for 7Be & 9Be but not 8Be
1390 // (usual case), then particles between the two lines can have "real" masses
1391 // between 7.5 and 8.5, but their integer A will be =7 or =9, never 8.
1392 //
1393
1394 SetInfos(x, y, idr);
1395
1396 idr->IDOK = kFALSE;
1397 idr->Aident = idr->Zident = kFALSE;
1398
1399 if (!const_cast<KVIDZAGrid*>(this)->FindFourEmbracingLines(x, y, "above")) {
1400 //no lines corresponding to point were found
1401 const_cast < KVIDZAGrid* >(this)->fICode = kICODE8; // Z indetermine ou (x,y) hors limites
1402 idr->IDquality = kICODE8;
1403 idr->SetComment("no identification: (x,y) out of range covered by grid");
1404 return;
1405 }
1406 if (IsOnlyZId()) {
1407 Double_t Z;
1408 const_cast < KVIDZAGrid* >(this)->IdentZ(x, y, Z);
1409 idr->IDquality = fICode;
1410 if (fICode < kICODE4 || fICode == kICODE7) {
1411 idr->Zident = kTRUE;
1412 }
1413 if (fICode < kICODE4) {
1414 idr->IDOK = kTRUE;
1415 }
1416 idr->Z = Zint;
1417 idr->PID = Z;
1418 idr->A = Aint;
1419
1420 switch (fICode) {
1421 case kICODE0:
1422 idr->SetComment("ok");
1423 break;
1424 case kICODE1:
1425 idr->SetComment("slight ambiguity of Z, which could be larger");
1426 break;
1427 case kICODE2:
1428 idr->SetComment("slight ambiguity of Z, which could be smaller");
1429 break;
1430 case kICODE3:
1431 idr->SetComment("slight ambiguity of Z, which could be larger or smaller");
1432 break;
1433 case kICODE4:
1434 idr->SetComment("point is in between two lines of different Z, too far from either to be considered well-identified");
1435 break;
1436 case kICODE5:
1437 idr->SetComment("point is in between two lines of different Z, too far from either to be considered well-identified");
1438 break;
1439 case kICODE6:
1440 idr->SetComment("(x,y) is below first line in grid");
1441 break;
1442 case kICODE7:
1443 idr->SetComment("(x,y) is above last line in grid");
1444 break;
1445 default:
1446 idr->SetComment("no identification: (x,y) out of range covered by grid");
1447 }
1448 }
1449 else {
1450
1451 Int_t Z;
1452 Double_t A;
1453 const_cast < KVIDZAGrid* >(this)->IdentZA(x, y, Z, A);
1454 idr->IDquality = fICode;
1455 idr->Z = Z;
1456 idr->PID = A;
1457
1458 if (fICode < kICODE4 || fICode == kICODE7) {
1459 idr->Zident = kTRUE;
1460 }
1461 idr->A = Aint;
1462 if (fICode < kICODE4) {
1463 idr->Aident = kTRUE;
1464 idr->IDOK = kTRUE;
1465 }
1466 switch (fICode) {
1467 case kICODE0:
1468 idr->SetComment("ok");
1469 break;
1470 case kICODE1:
1471 idr->SetComment("slight ambiguity of A, which could be larger");
1472 break;
1473 case kICODE2:
1474 idr->SetComment("slight ambiguity of A, which could be smaller");
1475 break;
1476 case kICODE3:
1477 idr->SetComment("slight ambiguity of A, which could be larger or smaller");
1478 break;
1479 case kICODE4:
1480 idr->SetComment("point is in between two isotopes of different Z, too far from either to be considered well-identified");
1481 break;
1482 case kICODE5:
1483 idr->SetComment("point is in between two isotopes of different Z, too far from either to be considered well-identified");
1484 break;
1485 case kICODE6:
1486 idr->SetComment("(x,y) is below first line in grid");
1487 break;
1488 case kICODE7:
1489 idr->SetComment("(x,y) is above last line in grid");
1490 break;
1491 default:
1492 idr->SetComment("no identification: (x,y) out of range covered by grid");
1493 }
1494 }
1495}
1496
1497
1498
1499
1506
1508{
1509 // General initialisation method for identification grid.
1510 // This method MUST be called once before using the grid for identifications.
1511 // The ID lines are sorted.
1512 // The natural line widths of all ID lines are calculated.
1513 // The line with the largest Z (Zmax line) is found.
1514
1516 // Zmax should be Z of last line in sorted list
1518 if (fZMaxLine) fZMax = fZMaxLine->GetZ();
1519 else fZMax = 0; // protection au cas ou il n y a aucune ligne de Z
1520}
1521
1522
1523
1524
1525
1528
1529void KVIDZAGrid::Streamer(TBuffer& R__b)
1530{
1531 // Stream an object of class KVIDZAGrid.
1532
1533 UInt_t R__s, R__c;
1534 if (R__b.IsReading()) {
1535 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
1536 if (R__v < 2) {
1537 R__v = R__b.ReadVersion(&R__s, &R__c);// read version of KVIDZGrid
1538 if (R__v != 1) {
1539 Warning("Streamer", "Reading KVIDZGrid with version=%d", R__v);
1540 }
1541 KVIDGrid::Streamer(R__b);
1542 R__b >> fZMax;
1543 }
1544 else {
1545 R__b.ReadClassBuffer(KVIDZAGrid::Class(), this, R__v, R__s, R__c);
1546 }
1547 }
1548 else {
1549 R__b.WriteClassBuffer(KVIDZAGrid::Class(), this);
1550 }
1551}
1552
1553
1554
1555// void KVIDZAGrid::MakeEDeltaEZGrid(Int_t Zmin, Int_t Zmax, Int_t npoints, Double_t gamma)
1556// {
1557// // Generate dE-Eres grid for associated ID telescope.
1558// // 1 line per Z is generated, using mass formula set for grid.
1559// // For each (Z,A) we calculate npoints corresponding to incident energies from the punch-through
1560// // of the first member up to the punch-through of the second.
1561// // gamma controls the spacing of the incident energies:
1562// // gamma = 1 : equidistant steps in Einc
1563// // gamma > 1 : steps at low Einc are more closely spaced, more & more for gamma >> 1
1564//
1565// KVIDTelescope* tel = ((KVIDTelescope*)fTelescopes.At(0));
1566// if (!tel)
1567// {
1568// Error("MakeEDeltaEZGrid",
1569// "No identification telescope associated to this grid");
1570// return;
1571// }
1572// KVDetector *dEDet = tel->GetDetector(1);
1573// KVDetector *ErDet = tel->GetDetector(2);
1574// if (!ErDet)
1575// {
1576// Error("MakeEDeltaEZGrid",
1577// "This identification telescope only has one member !");
1578// return;
1579// }
1580// Double_t x_scale = GetXScaleFactor();
1581// Double_t y_scale = GetYScaleFactor();
1582// //clear old lines from grid (and scaling parameters)
1583// Clear();
1584//
1585// //loop over Z
1586// KVNucleus part;
1587// //set mass formula used for calculating A from Z
1588// part.SetMassFormula(GetMassFormula());
1589//
1590// Info("MakeEDeltaEZGrid",
1591// "Calculating grid: dE detector = %s, E detector = %s",
1592// dEDet->GetName(), ErDet->GetName());
1593//
1594// for (Int_t z=Zmin; z<=Zmax; z++)
1595// {
1596//
1597// part.SetZ(z);
1598//
1599// //loop over energy
1600// //first find :
1601// // E1 = dE punch through + 0.1 MeV
1602// // E2 = 95% of energy at which particle passes Eres
1603// //then perform npoints calculations between these two energies and use these
1604// //to construct a KVIDZLine
1605//
1606// Double_t E1, E2, E1bis;
1607// E1bis = dEDet->GetEIncOfMaxDeltaE(z, part.GetA());
1608// E1 = dEDet->GetPunchThroughEnergy(z, part.GetA()) + 0.1;
1609// if(E1 < E1bis) E1 = E1bis;
1610// E2 = 0.95*dEDet->GetIncidentEnergyFromERes(z, part.GetA(), ErDet->GetPunchThroughEnergy(z, part.GetA()));
1611// Info("MakeEDeltaEZGrid","Z= %d, E1=%lf E2=%lf",z,E1,E2);
1612//
1613// // check we are within limits of validity of energy loss tables
1614// if ( E2 > dEDet->GetEmaxValid(z, part.GetA()) )
1615// {
1616// Warning("MakeEDeltaEZGrid",
1617// "Emax=%f MeV for Z=%d : beyond validity of range tables. Will use max limit=%f MeV",
1618// E2, z, dEDet->GetEmaxValid(z,part.GetA()));
1619// E2 = dEDet->GetEmaxValid(z,part.GetA());
1620// }
1621// if ( E2 > dEDet->GetEmaxValid(z, part.GetA()) )
1622// {
1623// Warning("MakeEDeltaEZGrid",
1624// "Emax=%f MeV for Z=%d : beyond validity of range tables. Will use max limit=%f MeV",
1625// E2, z, dEDet->GetEmaxValid(z,part.GetA()));
1626// E2 = dEDet->GetEmaxValid(z,part.GetA());
1627// }
1628//
1629// KVIDentifier *line = NewLine("ID");
1630// Add("ID", line);
1631// line->SetZ(z);
1632// line->SetMassFormula(part.GetMassFormula());
1633//
1634// Double_t dE = (E2 - E1) / pow((npoints - 1.),gamma);
1635//
1636// Int_t npoints_added = 0;
1637//
1638// for (int i = 0; npoints_added < npoints; i++)
1639// {
1640//
1641// Double_t E = E1 + dE*pow(i,gamma);
1642//
1643// Double_t Eres = 0.0;
1644// dEDet->Clear();
1645// ErDet->Clear();
1646// part.SetEnergy(E);
1647// dEDet->DetectParticle(&part);
1648// ErDet->DetectParticle(&part);
1649// Eres = ErDet->GetEnergy();
1650//
1651// line->SetPoint(npoints_added, Eres, dEDet->GetEnergy());
1652// npoints_added++;
1653// }
1654// }
1655// //if this grid has scaling factors, we need to apply them to the result
1656// if (x_scale != 1)
1657// SetXScaleFactor(x_scale);
1658// if (y_scale != 1)
1659// SetYScaleFactor(y_scale);
1660// }
1661
1662
1670
1672{
1673 // Create a new graph/grid using the subset of lines of this grid contained in TList 'lines'.
1674 // By default the new graph/grid will be of the same class as this one, unless graph_class !=0,
1675 // in which case it must contain the address of a TClass object representing a class which
1676 // derives from KVIDGraph.
1677 // A clone of each line will be made and added to the new graph, which will have the same
1678 // name and be associated with the same ID telescopes as this one.
1679
1680 if (!graph_class) graph_class = IsA();
1681 if (!graph_class->InheritsFrom("KVIDGraph")) {
1682 Error("MakeSubsetGraph", "Called with graph class %s, does not derive from KVIDGraph",
1683 graph_class->GetName());
1684 return 0;
1685 }
1686 KVIDGraph* new_graph = (KVIDGraph*)graph_class->New();
1687 new_graph->AddIDTelescopes(&fTelescopes);
1688 new_graph->SetOnlyZId(IsOnlyZId());
1689 new_graph->SetRuns(GetRuns());
1690 new_graph->SetVarX(GetVarX());
1691 new_graph->SetVarY(GetVarY());
1692 if (IsOnlyZId()) {
1693 new_graph->SetMassFormula(GetMassFormula());
1694 }
1695 // loop over lines in list, make clones and add to graph
1696 TIter next(lines);
1698 while ((id = (KVIDentifier*)next())) {
1699 KVIDentifier* idd = (KVIDentifier*)id->Clone();
1700 //id->Copy(*idd);
1701 //idd->ResetBit(kCanDelete);
1702 new_graph->AddIdentifier(idd);
1703 }
1704 return new_graph;
1705}
1706
1707
1708
1715
1717{
1718 // Create a new graph/grid using the subset of lines of this grid with Zmin <= Z <= Zmax.
1719 // By default the new graph/grid will be of the same class as this one, unless graph_class !="",
1720 // in which case it must contain the name of a class which derives from KVIDGraph.
1721 // A clone of each line will be made and added to the new graph, which will have the same
1722 // name and be associated with the same ID telescopes as this one.
1723
1724 TList* lines = new TList; // subset of lines to clone
1725 TIter next(&fIdentifiers);
1726 KVIDentifier* l;
1727 while ((l = (KVIDentifier*)next())) {
1728 if (l->GetZ() >= Zmin && l->GetZ() <= Zmax) lines->Add(l);
1729 }
1730 TClass* cl = 0;
1731 if (strcmp(graph_class, "")) cl = TClass::GetClass(graph_class);
1732 KVIDGraph* gr = MakeSubsetGraph(lines, cl);
1733 lines->Clear();
1734 delete lines;
1735 return gr;
1736}
1737
1738
1740
1742
1743
1744// This class is for backwards compatibility only
1745// and must not be used.
1747
1748
1749
1751
1752void KVIDZGrid::Streamer(TBuffer& R__b)
1753{
1754 // Stream an object of class KVIDZGrid.
1755
1756 UInt_t R__s, R__c;
1757 if (R__b.IsReading()) {
1758 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
1759 if (R__v != 1) {
1760 Warning("Streamer", "Reading KVIDZGrid with version=%d", R__v);
1761 }
1762 KVIDGrid::Streamer(R__b);
1763 R__b >> fZMax;
1764 }
1765}
1766
1767
int Int_t
unsigned int UInt_t
#define e(i)
bool Bool_t
short Version_t
char Char_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t TPoint TPoint const char y1
#define gROOT
char * Form(const char *fmt,...)
#define gPad
Base class for particle identification in a 2D map.
Definition KVIDGraph.h:32
const KVNameValueList * GetParameters() const
Definition KVIDGraph.h:288
Axis_t GetYmax() const
Definition KVIDGraph.h:397
virtual void SetVarX(const char *v)
Definition KVIDGraph.h:525
void RemoveIdentifier(KVIDentifier *)
Remove and destroy identifier.
KVList fIdentifiers
list of identification objects
Definition KVIDGraph.h:40
Axis_t GetXmax() const
Definition KVIDGraph.h:393
void Draw(Option_t *opt="")
Int_t GetNumberOfIdentifiers() const
Definition KVIDGraph.h:328
Bool_t IsOnlyZId() const
Definition KVIDGraph.h:57
Int_t GetMassFormula() const
Definition KVIDGraph.h:438
const KVNumberList & GetRuns() const
Definition KVIDGraph.h:261
void FindAxisLimits()
Calculate X/Y min/max of all objects in graph.
Axis_t GetYmin() const
Definition KVIDGraph.h:389
const KVList * GetIdentifiers() const
Definition KVIDGraph.h:298
virtual void SetVarY(const char *v)
Definition KVIDGraph.h:529
void SetMassFormula(Int_t)
const Char_t * GetName() const
TList fTelescopes
ID telescopes for which grid is valid.
Definition KVIDGraph.h:50
void AddIDTelescopes(const TList *)
Associate this graph with all ID telescopes in list.
virtual void AddIdentifier(KVIDentifier *id)
Definition KVIDGraph.h:340
virtual void SetInfos(Double_t, Double_t, KVIdentificationResult *) const
loop over KVIDGraph::fInfoZones to set flags in KVIdentificationResult
Axis_t GetXmin() const
Definition KVIDGraph.h:385
const KVList * GetCuts() const
Definition KVIDGraph.h:308
void SetRuns(const KVNumberList &nl)
Set list of runs for which grid is valid.
virtual void SetOnlyZId(Bool_t yes=kTRUE)
KVIDentifier * GetIdentifierAt(Int_t index) const
Definition KVIDGraph.h:271
KVIDLine * FindNearestEmbracingIDLine(Double_t x, Double_t y, const Char_t *position, const Char_t *axis, Int_t &idx, Int_t &idx_min, Int_t &idx_max, Double_t &dist, Double_t &dist_min, Double_t &dist_max) const
Definition KVIDGrid.h:163
KVIDLine * FindNextEmbracingLine(Int_t &index, Int_t inc_index, Double_t x, Double_t y, const Char_t *axis) const
Definition KVIDGrid.h:236
void Initialize()
Definition KVIDGrid.cpp:218
Base class for lines/cuts used for particle identification in 2D data maps.
Definition KVIDLine.h:143
Double_t DistanceToLine(Double_t px, Double_t py, Int_t &)
Definition KVIDLine.h:246
void GetStartPoint(Double_t &x, Double_t &y) const
Bool_t IsBetweenEndPoints(Double_t x, Double_t y, const Char_t *axis="") const
void GetEndPoint(Double_t &x, Double_t &y) const
Identification grid with lines corresponding to different nuclear isotopes (KVIDZALine)
Definition KVIDZAGrid.h:66
Double_t dsups
Definition KVIDZAGrid.h:88
Double_t fDistanceClosest
distance from point to closest line
Definition KVIDZAGrid.h:83
Int_t Zsups
Definition KVIDZAGrid.h:90
KVIDLine * fLsup
Definition KVIDZAGrid.h:80
Double_t wsup
Definition KVIDZAGrid.h:89
virtual void CalculateLineWidths()
Int_t Zinf
Definition KVIDZAGrid.h:90
void init()
initialisation
Int_t Ainfi
Definition KVIDZAGrid.h:91
KVIDLine * fClosest
closest line to last-identified point
Definition KVIDZAGrid.h:78
Int_t Ainf
Definition KVIDZAGrid.h:91
void ReCheckQuality(Int_t &Z, Double_t &A)
virtual KVIDZALine * GetZLine(Int_t z, Int_t &) const
virtual void Copy(TObject &) const
Copy this to 'obj'.
KVIDLine * fLinf
Definition KVIDZAGrid.h:81
Int_t Zsup
Definition KVIDZAGrid.h:90
Int_t Asups
Definition KVIDZAGrid.h:91
void DrawLinesWithWidth()
void RemoveZLines(const Char_t *ZList)
Remove and destroy identifiers.
Int_t kinfi
Definition KVIDZAGrid.h:87
virtual void IdentZ(Double_t x, Double_t y, Double_t &Z)
virtual void Identify(Double_t x, Double_t y, KVIdentificationResult *) const
Int_t Asup
Definition KVIDZAGrid.h:91
Int_t ksup
Definition KVIDZAGrid.h:87
KVIDZALine * fZMaxLine
line with biggest Z and A
Definition KVIDZAGrid.h:71
Int_t ksups
used by IdentZA and IdentZ
Definition KVIDZAGrid.h:87
Double_t winf
Definition KVIDZAGrid.h:89
Double_t dinf
Definition KVIDZAGrid.h:88
Int_t kinf
Definition KVIDZAGrid.h:87
virtual void Initialize()
KVIDLine * fLsups
Definition KVIDZAGrid.h:79
Double_t wsups
Definition KVIDZAGrid.h:89
UShort_t fZMax
largest Z of lines in grid
Definition KVIDZAGrid.h:70
Double_t dsup
Definition KVIDZAGrid.h:88
KVIDZAGrid()
default ctor.
virtual void IdentZA(Double_t x, Double_t y, Int_t &Z, Double_t &A)
Int_t fIdxClosest
index of closest line in main list fIdentifiers
Definition KVIDZAGrid.h:84
Int_t Zinfi
Definition KVIDZAGrid.h:90
Int_t fICode
code de retour
Definition KVIDZAGrid.h:85
Double_t winfi
Definition KVIDZAGrid.h:89
KVIDLine * fLinfi
Definition KVIDZAGrid.h:82
Int_t Zint
Z of line used to identify particle.
Definition KVIDZAGrid.h:94
void SetManualWidth(Double_t manual_width=.3, Double_t manual_width_scaling=0.05)
KVIDGraph * MakeSubsetGraph(Int_t Zmin, Int_t Zmax, const Char_t *="")
virtual void MakeEDeltaEZGrid(Int_t Zmin, Int_t Zmax, Int_t npoints=20, Double_t gamma = 2);//*MENU*
Double_t dinfi
Definition KVIDZAGrid.h:88
virtual Bool_t FindFourEmbracingLines(Double_t x, Double_t y, const Char_t *position)
Int_t Aint
mass of line used to identify particle
Definition KVIDZAGrid.h:93
void RemoveLine(Int_t Z, Int_t A=-1)
Remove and destroy identifier.
virtual ~KVIDZAGrid()
default dtor.
virtual KVIDZALine * GetZALine(Int_t z, Int_t a, Int_t &) const
Base class for identification ridge lines corresponding to different nuclear species.
Definition KVIDZALine.h:33
virtual void SetAsymWidth(Double_t d_l, Double_t d_r)
void SetWidth(Double_t w)
Definition KVIDZALine.h:65
Base class for graphical cuts used in particle identification.
virtual Int_t GetA() const
virtual Int_t GetZ() const
Full result of one attempted particle identification.
Bool_t IDOK
general quality of identification, =kTRUE if acceptable identification made
void SetComment(const Char_t *c)
Bool_t Aident
= kTRUE if A of particle established
Double_t PID
= "real" Z if Zident==kTRUE and Aident==kFALSE, "real" A if Zident==Aident==kTRUE
Int_t A
A of particle found (if Aident==kTRUE)
Int_t Z
Z of particle found (if Zident==kTRUE)
Int_t IDquality
specific quality code returned by identification procedure
Bool_t Zident
=kTRUE if Z of particle established
Extended TList class which owns its objects by default.
Definition KVList.h:28
Double_t GetDoubleValue(const Char_t *name) const
void SetValue(const Char_t *name, value_type value)
Description of properties and kinematics of atomic nuclei.
Definition KVNucleus.h:126
Double_t GetLifeTime(Int_t z=-1, Int_t a=-1) const
Strings used to represent a set of ranges of values.
Bool_t End(void) const
void Begin(void) const
Int_t Next(void) const
KVSeqCollection * GetSubListWithMethod(const Char_t *retvalue, const Char_t *method) const
virtual TObject * Last() const
virtual void Streamer(TBuffer &)
void Copy(TAttFill &attfill) const
static TClass * Class()
virtual Version_t ReadVersion(UInt_t *start=nullptr, UInt_t *bcnt=nullptr, const TClass *cl=nullptr)=0
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=nullptr)=0
Bool_t IsReading() const
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Bool_t InheritsFrom(const char *cl) const override
const char * GetVarX() const
TClass * IsA() const override
const char * GetVarY() const
void Clear(Option_t *option="") override
void Add(TObject *obj) override
const char * GetName() const override
virtual Bool_t InheritsFrom(const char *classname) const
virtual void Error(const char *method, const char *msgfmt,...) const
virtual void Draw(Option_t *option="")
TLine * line
Double_t y[n]
Double_t x[n]
TGraphErrors * gr
double dist(AxisAngle const &r1, AxisAngle const &r2)
void init()
Double_t Min(Double_t a, Double_t b)
Int_t Nint(T x)
Double_t Log(Double_t x)
Double_t Sqrt(Double_t x)
Double_t Abs(Double_t d)
Double_t Max(Double_t a, Double_t b)
TLine l
TArc a
ClassImp(TPyArg)