KaliVeda
Toolkit for HIC analysis
KVNumberList.cpp
1 #include "KVNumberList.h"
2 #include "KVString.h"
3 #include <TObjArray.h>
4 #include <TObjString.h>
5 #include <Riostream.h>
6 #include "KVError.h"
7 #include "TMath.h"
8 #include "TRandom.h"
9 
11 
12 //____________________________________________________________________________________________//
13 
14 
15 
18 void KVNumberList::init_numberlist()
19 {
20  //Default initialisation used by ctors
21  fMaxNLimits = 0;
22  fNLimits = 0;
23  fFirstValue = 99999999;
24  fLastValue = -99999999;
25  fNValues = 0;
26  fName = ClassName();
27  fIsParsed = kTRUE;
28 }
29 
30 
31 
32 
35 
37 {
38  //Default constructor
39  init_numberlist();
40 }
41 
42 
43 
44 
47 
49 {
50  //Copy constructor
51  init_numberlist();
52  orig.Copy(*this);
53 }
54 
55 
56 
57 
61 
62 KVNumberList::KVNumberList(const Char_t* list): fString(list)
63 {
64  //Initialise number list using string and parse it to fill limits arrays
65  //Any number will only appear once.
66  init_numberlist();
67  fIsParsed = kFALSE;
68 }
69 
70 
71 
74 
76 {
77  //Initialise number list using single number
78 
79  init_numberlist();
80  Add(x);
81 }
82 
83 
84 
88 
89 KVNumberList::KVNumberList(Int_t deb, Int_t fin, Int_t pas): fString()
90 {
91  //Initialise number list using numbers from deb to fin with a step=pas
92  //i.e. deb,deb+pas,deb+2*pas,...,fin
93  init_numberlist();
94  SetMinMax(deb, fin, pas);
95 }
96 
97 
98 #ifdef WITH_CPP11
99 
102 
103 KVNumberList::KVNumberList(std::initializer_list<int> L)
104 {
105  // Use an initializer list of integers to set up number list
106 
107  init_numberlist();
108  for (auto i : L) Add(i);
109 }
110 
111 #endif
112 
113 
114 
118 
119 void KVNumberList::ParseList()
120 {
121  //PRIVATE METHOD
122  //Breaks string containing list down and fills limits arrays accordingly
123 
124  if (fIsParsed) return;
125  clear();
126  ParseAndFindLimits(fString, ' ');
127  fIsParsed = kTRUE;
128 }
129 
130 
131 
132 
135 
137 {
138  //Empty number list, reset it to initial state.
139  clear();
140  fString = "";
141 }
142 
143 
144 
147 
148 void KVNumberList::clear()
149 {
150  // private method called by ParseList()
151  fNLimits = 0;
152  fLowerBounds.Reset();
153  fUpperBounds.Reset();
154  fFirstValue = 99999999;
155  fLastValue = -99999999;
156  fNValues = 0;
157  fIsParsed = kTRUE;
158 }
159 
160 
161 
162 
168 
169 void KVNumberList::SetName(const char* name)
170 {
171  // Change (i.e. set) the name of the KVNumberList.
172  // WARNING: if the object is a member of a THashTable or THashList container
173  // the container must be Rehash()'ed after SetName(). For example the list
174  // of objects in the current directory is a THashList.
175  fName = name;
176 }
177 
178 
179 
180 
185 
186 void KVNumberList::ParseAndFindLimits(const TString& string, const Char_t delim)
187 {
188  //Takes a string and breaks it up into its constituent parts,
189  //which were initially separated by white space or a comma.
190  //Any part which contains "-" will be sent to AddLimits().
191  std::unique_ptr<TObjArray> toks1(string.Tokenize(delim));
192  Int_t n_toks = toks1->GetEntries();
193  for (int i = 0; i < n_toks; i++) {
194  TString tok = ((TObjString*)(*toks1)[i])->GetString();
195  KVString kvtok(tok);
196  if (tok.Contains(','))
197  ParseAndFindLimits(tok, ',');
198  else if (tok.Contains(' '))
199  ParseAndFindLimits(tok, ' ');
200  else if (tok.Contains('-')) {
201  AddLimits(tok);
202  }
203  else if (kvtok.IsDigit()) {
204  Int_t val = kvtok.Atoi();
205  AddLimits(val, val);
206  }
207  }
208 }
209 
210 
211 
212 
217 
218 void KVNumberList::AddLimits(TString& string)
219 {
220  //'string' should contain something like "34-59" i.e. two integers separated by a '-'.
221  //these two numbers are taken for new lower and upper limits, fNLimits is increased by one,
222  //if necessary the arrays' size is increased.
223  std::unique_ptr<TObjArray> toks1(string.Tokenize('-'));
224  Int_t n_toks = toks1->GetEntries();
225  if (n_toks != 2) return;
226  KVString lower(((TObjString*)(*toks1)[0])->GetString());
227  KVString upper(((TObjString*)(*toks1)[1])->GetString());
228  Int_t ilow = lower.Atoi();
229  Int_t iupp = upper.Atoi();
230  AddLimits(ilow, iupp);
231 }
232 
233 
234 
235 
239 
240 void KVNumberList::AddLimits(Int_t min, Int_t max)
241 {
242  //The numbers contained in the range [min,max]
243  //are added to the list.
244 
245  if (++fNLimits > fMaxNLimits) {
246  fMaxNLimits += 10;
247  fLowerBounds.Set(fMaxNLimits);
248  fUpperBounds.Set(fMaxNLimits);
249  }
250  fLowerBounds[fNLimits - 1] = min;
251  fUpperBounds[fNLimits - 1] = max;
252  if (min < fFirstValue)
253  fFirstValue = min;
254  if (max > fLastValue)
255  fLastValue = max;
256  fNValues += (max - min + 1);
257 }
258 
259 
260 
261 
265 
267 {
268  //Print detailed break-down of list
269 
270  //remove duplicate entries, correct fList, then re-parse
271  GetList();
272  fIsParsed = kFALSE; // force re-parse
273  const_cast<KVNumberList*>(this)->ParseList();
274 
275  std::cout << "KVNumberList::" << GetName() << std::endl;
276  std::cout << "There are " << fNLimits << " limits in the string : " <<
277  fString.Data() << std::endl;
278  std::cout << "MIN = ";
279  for (int i = 0; i < fNLimits; i++) {
280  std::cout << Form("%5d", fLowerBounds[i]);
281  if (i < fNLimits - 1)
282  std::cout << ",";
283  }
284  std::cout << std::endl;
285  std::cout << "MAX = ";
286  for (int i = 0; i < fNLimits; i++) {
287  std::cout << Form("%5d", fUpperBounds[i]);
288  if (i < fNLimits - 1)
289  std::cout << ",";
290  }
291  std::cout << std::endl;
292  std::cout << "First value = " << fFirstValue << " Last value = " <<
293  fLastValue << std::endl;
294 }
295 
296 
297 
300 
301 bool KVNumberList::operator==(const KVNumberList& other) const
302 {
303  // Equality test for number lists
304 
305  return (TString(GetList()) == TString(other.GetList()));
306 }
307 
308 
309 
312 
313 bool KVNumberList::operator!=(const KVNumberList& other) const
314 {
315  // Inequality test for number lists
316 
317  return !((*this) == other);
318 }
319 
320 
321 
330 
332 {
333  // Make a new list in which all values are divided by the factor 'div'.
334  //
335  // Note that this is integer division only!
336  //
337  // - if list is "1000-7999 16000-18999" GetDividedBy(1000) gives "1-7 16-18"
338  // - if list is "1-12" GetDividedBy(4) gives "0-3"
339  // - if list is "1-12" GetDividedBy(2) gives "0-6"
340 
341  KVString str = AsString();
342  str.Begin(", ");
343  KVString new_list;
344  while(!str.End())
345  {
346  auto tok = str.Next();
347  tok.Begin("-");
348  bool add_dash = false;
349  while(!tok.End())
350  {
351  if(add_dash) new_list +="-";
352  auto dig = tok.Next().Atoi()/div;
353  new_list += Form("%d",dig);
354  add_dash=true;
355  }
356  new_list += " ";
357  }
358  return KVNumberList(new_list);
359 }
360 
361 
362 
370 
371 std::optional<int> KVNumberList::FindOffset(const KVNumberList& other)
372 {
373  // \return the common offset between each member of 'this' list and each corresponding member of 'other'
374  //
375  // \note both lists must contain the same number of elements
376  //
377  // If it is possible to make this list identical to 'other' by adding the same integer value to
378  // each member of this list, we return this offset.
379 
380  if(other.GetEntries()!=GetEntries())
381  {
382  KVError::Warning(this, "FindOffset(const KVNumberList&)", "Lists must have same size/length");
383  return {};
384  }
385  std::optional<int> offset;
386  for(int i=0; i<GetEntries(); ++i)
387  {
388  if(offset && other[i]!=((*this)[i]+*offset))
389  return {};
390  offset = other[i] - (*this)[i];
391  }
392  return offset;
393 }
394 
395 
396 
397 
401 
403 {
404  // Replace internal string representation of number list
405  // List will be parsed before any subsequent operations
406  fString = list;
407  fIsParsed = kFALSE;
408 }
409 
410 
411 
412 
415 
417 {
418  //returns kTRUE if the value 'val' is contained in the ranges defined by the number list
419  if (!fIsParsed) const_cast<KVNumberList*>(this)->ParseList();
420  for (int i = 0; i < fNLimits; i++) {
421  if (val >= fLowerBounds[i] && val <= fUpperBounds[i])
422  return kTRUE;
423  }
424  return kFALSE;
425 }
426 
427 
428 
429 
432 
434 {
435  //Returns smallest number included in list
436  if (!fIsParsed) const_cast<KVNumberList*>(this)->ParseList();
437  return fFirstValue;
438 }
439 
440 
441 
442 
445 
447 {
448  //Returns largest number included in list
449  if (!fIsParsed) const_cast<KVNumberList*>(this)->ParseList();
450  return fLastValue;
451 }
452 
453 
454 
455 
460 
461 IntArray KVNumberList::GetArray() const
462 {
463  // Creates and fills a sorted array with all the unique
464  // values compatible with the ranges defined in the list.
465  // (Sorting is in increasing order).
466 
467  if (IsEmpty())
468  return IntArray();
469 
470  if (!fIsParsed) const_cast<KVNumberList*>(this)->ParseList();
471 
472  IntArray temp(fNValues);
473  Int_t index = 0;
474  for (int i = 0; i < fNLimits; i++) {
475  Int_t min = fLowerBounds[i];
476  Int_t max = fUpperBounds[i];
477  for (int j = min; j <= max; j++) {
478  temp[index++] = j;
479  }
480  }
481  //now check for duplicate entries
482  //we sort the array in increasing order
483  //any duplicate entries will then be adjacent
484  IntArrayIter beg = temp.begin();
485  std::sort(beg, temp.end());
486  IntArrayIter end = std::unique(beg, temp.end());
487  Int_t n_uniq = std::distance(beg, end); //number of unique values
488 
489  if (n_uniq < fNValues) {
490  // duplicates were removed
491  // reduce the size of the vector
492  temp.resize(n_uniq);
493  // we reconstruct a string containing all unique values & reparse it
494  fString.Form("%d", (*(beg++)));
495  while (beg != end) {
496  fString += Form(" %d", (*(beg++)));
497  }
498  fNValues = n_uniq;
499  fIsParsed = kFALSE; // force re-parsing
500  const_cast<KVNumberList*>(this)->ParseList();
501  }
502  return temp;
503 }
504 
505 
506 
507 
510 
512 {
513  //Add value 'n' to the list
514  TString tmp = (fString != "" ? fString + " " : fString);
515  tmp += n;
516  SetList(tmp);
517 }
518 
519 
520 
521 
524 
526 {
527  //Remove value 'n' from the list
528  TString tmp = " " + TString(GetExpandedList()) + " ";
529  tmp.ReplaceAll(Form(" %d ", n), " ");
530  SetList(tmp);
531 }
532 
533 
534 
535 
538 
540 {
541  //Add values in 'list' to this list
542  TString tmp = (fString != "" ? fString + " " : fString);
543  tmp += list.fString;
544  SetList(tmp);
545 }
546 
547 
548 
549 
552 
554 {
555  //Remove values in 'list' from this list
556  TString tmp = " " + TString(GetExpandedList()) + " ";
557  KVNumberList tampon(list);
558  if (!tampon.IsEmpty()) {
559  tampon.Begin();
560  while (!tampon.End()) tmp.ReplaceAll(Form(" %d ", tampon.Next()), " ");
561  }
562  SetList(tmp);
563 }
564 
565 
566 
567 
570 
571 void KVNumberList::Remove(const Char_t* list)
572 {
573  //Remove values in 'list' to this list
574  KVNumberList tmp(list);
575  Remove(tmp);
576 }
577 
578 
579 
580 
583 
585 {
586  //Add n values from array arr to the list
587 
588  TString tmp = (fString != "" ? fString + " " : fString);
589  for (int i = 0; i < n; i++) {
590  tmp += arr[i];
591  tmp += " ";
592  }
593  SetList(tmp);
594 }
595 
596 
597 
600 
601 void KVNumberList::Add(const IntArray& v)
602 {
603  // Add all values in IntArray (=std::vector<int>) to the list
604 
605  TString tmp = (fString != "" ? fString + " " : fString);
606  for (IntArrayCIter it = v.begin(); it != v.end(); ++it) {
607  tmp += *it;
608  tmp += " ";
609  }
610  SetList(tmp);
611 }
612 
613 
614 
617 
619 {
620  // Return sum of this list and the other one
621 
622  KVNumberList tmp(*this);
623  tmp.Add(other);
624  return tmp;
625 }
626 
627 
628 
629 
632 
634 {
635  //Remove n values from array arr to the list
636  TString tmp = " ";
637  for (int i = 0; i < n; i++) {
638  tmp += arr[i];
639  tmp += " ";
640  }
641  Remove(tmp);
642 }
643 
644 
645 
646 
649 
651 {
652  //Set list with all values from 'min' to 'max'
653  TString tmp;
654  for (int i = min; i <= max; i += pas) {
655  tmp += i;
656  tmp += " ";
657  }
658  SetList(tmp);
659 }
660 
661 
662 
663 
667 
669 {
670  //keep the AND logic operation result between 'list' and this list
671  //i.e. keep only numbers which appear in both lists
672 
673  KVNumberList tampon(list);
674  if (tampon.IsEmpty() || IsEmpty()) {
675  SetList("");
676  }
677  else {
678  TString tmp = "";
679  tampon.Begin();
680  while (!tampon.End()) {
681  Int_t n = tampon.Next();
682  if (!Contains(n)) tmp += n;
683  tmp += " ";
684  }
685  Begin();
686  while (!End()) {
687  Int_t n = Next();
688  if (!tampon.Contains(n)) tmp += n;
689  tmp += " ";
690  }
691  Remove(tmp);
692  }
693 }
694 
695 
696 
697 
703 
705 {
706  //Get string containing list. This is most compact representation possible,
707  //i.e. all continuous ranges are represented as "minval-maxval"
708  //This string will become the new internal representation of the list.
709  //Returns empty string if list is empty.
710 
711  if (!fIsParsed) const_cast<KVNumberList*>(this)->ParseList();
712 
713  //no numbers in list ?
714  if (!fNValues) {
715  fString = "";
716  return fString.Data();
717  }
718  //get array of all values
719  IntArray arr = GetArray();
720  IntArrayIter it = arr.begin();
721  Int_t min, max;
722  min = max = *it; //put min & max = smallest (first) value to start with
723  fString = "";
724  for (++it; it != arr.end(); ++it) {
725 
726  Int_t val = *it; // loop over values in increasing order
727 
728  if (val - * (it - 1) > 1) {
729  //cout << "end of continuous range ?" << endl;
730  if (min != max) {
731  fString += Form("%d-%d ", min, max);
732  }
733  else {
734  fString += Form("%d ", min);
735  }
736  min = max = val;
737  }
738  else {
739  //cout << "continuous range" << endl;
740  max = val;
741  }
742 
743  }
744  if (min != max) {
745  fString += Form("%d-%d", min, max);
746  }
747  else {
748  fString += Form("%d", min);
749  }
750  return fString.Data();
751 }
752 
753 
754 
755 
760 
762 {
763  // Get string containing list. Every unique value contained
764  // in the list will be represented.
765  // Returns empty string if list is empty.
766 
767  if (!fIsParsed) const_cast<KVNumberList*>(this)->ParseList();
768 
769  static TString tmp = "";
770 
771  //no numbers in list ?
772  if (!fNValues) {
773  fString = "";
774  return fString.Data();
775  }
776  //get array of all values
777  IntArray arr = GetArray();
778  tmp = "";
779  IntArrayIter it = arr.begin();
780  for (; it != arr.end() - 1; ++it) {
781 
782  Int_t val = *it; // loop over values in increasing order
783  tmp += Form("%d ", val);
784  }
785  Int_t val = *it; //last value
786  tmp += Form("%d", val);
787  return tmp.Data();
788 }
789 
790 
791 
792 
798 
799 TString KVNumberList::GetLogical(const Char_t* observable) const
800 {
801  // Get logical expression of 'this' list in the TTree:Draw condition format
802  // observable is one of the leaf of the TTree
803  // 12-15 20 --> ( 12<=observable&&observable<=15 || observable==20 )
804  // return "" if 'this' list is empty
805 
806  if (IsEmpty()) return "";
807  GetList();
808  TString tmp = fString;
809  tmp.ReplaceAll(" ", "||");
810  std::unique_ptr<TObjArray> toks(tmp.Tokenize("||"));
811  static TString cond;
812  cond = "( ";
813  Int_t nt = toks->GetEntries();
814  for (Int_t ii = 0; ii < nt; ii += 1) {
815  TString line = ((TObjString*)(*toks)[ii])->GetString();
816  if (line.Contains("-")) {
817  line.ReplaceAll("-", Form("<=%s&&%s<=", observable, observable));
818  cond += line;
819  }
820  else {
821  cond += Form("%s==", observable) + line;
822  }
823  if (ii != nt - 1) cond += "||";
824  }
825  cond += " )";
826  return cond;
827 }
828 
829 
830 
836 
837 TString KVNumberList::GetSQL(const Char_t* column) const
838 {
839  // Get equivalent for SQL 'WHERE' clause
840  // e.g. 12-15 20 --> column BETWEEN 12 AND 15 OR column=20
841  // (column name will be correctly quoted in case it contains spaces)
842  // return "" if 'this' list is empty
843 
844  if (IsEmpty()) return "";
845  GetList();
846  TString qcol = Form("\"%s\"", column);
847  KVString tmp = fString;
848  static TString cond;
849  cond = "";
850  tmp.Begin(" ");
851  while (!tmp.End()) {
852  if (cond != "") cond += " OR ";
853  KVString tmp2 = tmp.Next();
854  if (tmp2.Contains("-")) {
855  cond += (qcol + " BETWEEN ");
856  tmp2.Begin("-");
857  cond += tmp2.Next();
858  cond += " AND ";
859  cond += tmp2.Next();
860  }
861  else {
862  cond += (qcol + "=");
863  cond += tmp2;
864  }
865  }
866  return cond;
867 }
868 
869 
870 
873 
875 {
876  // Copy content of this number list into 'o'
877 
878  ((KVNumberList&)o).Set(fString);
879 }
880 
881 
882 
883 
889 
891 {
892  // Returns total number of unique entries in list
893  // Note that this calls GetArray() just in order to remove
894  // any duplicate entries in the list and make sure fNValues
895  // is the number of unique entries.
896 
897  GetArray();//will remove any duplicates and correct fNValues
898  return fNValues;
899 }
900 
901 
902 
903 
915 
917 {
918  //Use this method to iterate over all numbers in the list
919  //Initialise first by calling Begin(), then loop until End() returns kTRUE:
920  //
921  // KVNumberList r("1-10");
922  // r.Begin();
923  // while( !r.End() ){
924  // Int_t next_val = r.Next();
925  // ...
926  // }
927  //If list is empty, End() always returns kTRUE and Next() returns -1.
928 
929  if (fValues.empty()) {
930  KVError::Warning(this,"Next", "List is empty. -1 returned.");
931  return -1;
932  }
933  if (fIterIndex >= fEndList) {
934  KVError::Warning(this,"Next", "Attempt to iterate beyond end of list. -1 returned.");
935  return -1;
936  }
937  Int_t val = *(fIterIndex++);
938  return val;
939 }
940 
941 
942 
943 
947 
949 {
950  // Call before using Next(). Resets iterator to beginning of list.
951  // If list is empty, End() always returns kTRUE and Next() returns -1.
952 
953  fValues = GetArray();
954  fIterIndex = fValues.begin();
955  fEndList = fValues.end();
956 }
957 
958 
959 
971 
972 IntArrayIter KVNumberList::begin() const
973 {
974  // Returns a std::iterator over all unique values in the list, ordered from smallest to largest.
975  // Allows use in range-based for loops:
976  //
977  //~~~~~~~~~{.cpp}
978  // KVNumberList pl("1-3,6");
979  // for(auto i : pl) cout << i << " ";
980  //
981  // //output:
982  // //1 2 3 6
983  //~~~~~~~~~
984 
985  fValues = GetArray();
986  fIterIndex = fValues.begin();
987  fEndList = fValues.end();
988  return fIterIndex;
989 }
990 
991 
992 
998 
999 IntArrayIter KVNumberList::end() const
1000 {
1001  // Returns a std::iterator to element after end of list.
1002  // Allows use in range-based for loops.
1003  //
1004  // \sa begin()
1005  return fEndList;
1006 }
1007 
1008 
1009 
1010 
1017 
1019 {
1020  // Returns value of number in list at position 'index' (index = 0, 1, .., GetNValues()-1)
1021  // We check that 'index' is neither too big nor too small (otherwise we return -1).
1022  // WARNING: the list is first sorted into ascending order (and any duplicate entries are
1023  // removed), so the index does not necessarily correspond to the order in which numbers
1024  // are added to the list.
1025 
1026  IntArray arr = GetArray();
1027  Int_t n = -1;
1028  try {
1029  n = arr.at(index);
1030  }
1031  catch (std::exception& e) {
1032  KVError::Warning(this, "At(int)", "Index out of bounds. -1 returned.");
1033  }
1034  return n;
1035 }
1036 
1037 
1038 
1039 
1046 
1048 {
1049  // Returns value of number in list at position 'index' (index = 0, 1, .., GetNValues()-1)
1050  // We check that 'index' is neither too big nor too small (otherwise we return -1).
1051  // WARNING: the list is first sorted into ascending order (and any duplicate entries are
1052  // removed), so the index does not necessarily correspond to the order in which numbers
1053  // are added to the list.
1054 
1055  return At(index);
1056 }
1057 
1058 
1059 
1060 
1069 
1071 {
1072  //Get string containing list. This is most compact representation possible,
1073  //i.e. all continuous ranges are represented as "minval-maxval".
1074  //If maxlen>0, and if length of resulting string is longer than maxlen,
1075  //we truncate the list to show only the beginning and the end of the list,
1076  //with "..." in between, i.e. "6000-...-8910". Note that the minimum size of
1077  //the resulting string is 5 i.e. "6...0".
1078  //Returns empty string if list is empty.
1079 
1080  fTMPSTR = GetList();
1081  if (maxlen) {
1082  maxlen = TMath::Max(maxlen, 5);
1083  if (fTMPSTR.Length() > maxlen) {
1084  Int_t len_left = maxlen - 3; // 3 for "..."
1085  Int_t len_start = len_left / 2;
1086  Int_t len_end = len_left - len_start;
1087  TString tmp2 = fTMPSTR(0, len_start);
1088  tmp2 += "...";
1089  tmp2 += fTMPSTR(fTMPSTR.Length() - len_end, fTMPSTR.Length() - 1);
1090  fTMPSTR = tmp2;
1091  }
1092  }
1093  return fTMPSTR.Data();
1094 }
1095 
1096 
1097 
1102 
1104 {
1105  // Get a string containing the compact representation of the list, enclosed
1106  // by single quotes, i.e. if AsString() returns "1 3 5-7", this method will
1107  // return "'1 3 5-7'"
1108 
1109  KVString tmp = AsString();
1110  fTMPSTR = "'";
1111  fTMPSTR.Append(tmp);
1112  fTMPSTR.Append("'");
1113  return fTMPSTR.Data();
1114 }
1115 
1116 
1117 
1119 
1121 {
1122  KVString tmp = AsString();
1123  int nws = tmp.GetNValues(" ");
1124  fTMPSTR = "";
1125 
1126  if (nws == 1) fTMPSTR = tmp;
1127  else {
1128  tmp.Begin(" ");
1129  for (int ii = 0; ii < nws - 1; ii++) fTMPSTR += Form("%s%s", tmp.Next().Data(), (ii == nws - 2) ? "" : ", ");
1130  fTMPSTR += Form(" and %s", tmp.Next().Data());
1131  }
1132  fTMPSTR.ReplaceAll("-", " to ");
1133  return fTMPSTR.Data();
1134 }
1135 
1136 
1137 
1138 
1145 
1147 {
1148  // Draw number at random from list
1149  //
1150  // Warning: this method is slow as each time it is called the number list will be sorted.
1151  //
1152  // For a more efficient method, see GetRandomFast().
1153  return At(gRandom->Integer(GetEntries()));
1154 }
1155 
1156 
1157 
1167 
1169 {
1170  // Draw number at random from list
1171  //
1172  // Unlike GetRandom(), the list is not sorted every time the method is called.
1173  // Rather, this must be done once by calling PrepareRandomFast() first before calling
1174  // this method.
1175  //
1176  // Check that PrepareRandomFast() returns kTRUE: if not, the list is empty and
1177  // calling GetRandomFast() will lead to segmentation violation...
1178  return fRandomFastArray.at(gRandom->Integer(fNValues));
1179 }
1180 
1181 
1182 
1188 
1190 {
1191  // Call once before using GetRandomFast() in order to generate random numbers from the list.
1192  //
1193  // If this method returns kFALSE, do not use GetRandomFast() as the list is empty
1194  // (seg fault will occur).
1195  fRandomFastArray = GetArray();
1196  assert((IntArray::size_type)fNValues == fRandomFastArray.size());
1197  return fRandomFastArray.size() > 0;
1198 }
1199 
1200 
1201 
1202 
1215 
1217 {
1218  //Return kTRUE if the list is in fact a continuous list of number
1219  // ie "123-126" or "1,2,3,4" etc ...
1220  //Use vinf et vsup if you want to test only a sub part
1221  //of the list by default vinf=vsup=-1 and the whole list is considered
1222  //in the test
1223  // ie :
1224  // for "123-127 129" it will be returned kFALSE
1225  // for "123-127 129",-1,-1 it will be returned kFALSE
1226  // for "123-127 129",123,127 it will be returned kTRUE
1227  // for "123-127 129",-1,127 it will be returned kTRUE
1228  // for "123-127 129",127,-1 it will be returned kFALSE
1229 
1230  if ((vinf == -1) && (vsup == -1)) {
1231  Int_t total = Last() - First() + 1;
1232  return (total == GetNValues());
1233  }
1234  else {
1235  return GetSubList(vinf, vsup).IsFull();
1236  }
1237 }
1238 
1239 
1240 
1241 
1245 
1247 {
1248  //Return the complementary of the list
1249  // ie for "123-127 129" it will be returned "128"
1250 
1251  KVNumberList nl("");
1252  if (IsFull()) return nl;
1253  nl.SetMinMax(this->First(), this->Last());
1254  nl.Remove(*this);
1255  return nl;
1256 
1257 }
1258 
1259 
1260 
1268 
1270 {
1271  //Return the sublist of numbers between vinf and vsup
1272  // i.e. put in the sublist val if vinf <= val <= vsup
1273  // if vinf=-1, put no lower limit
1274  // if vsup=-1, put no upper limit
1275  // if vinf = vsup = -1, just clone the list
1276  // i.e. "123-135 145-456",130,400 it will be returned "130-135 145-400"
1277 
1278  KVNumberList nl("");
1279  if (vinf > vsup) return nl;
1280  if (vinf == -1) vinf = First();
1281  if (vsup == -1) vsup = Last();
1282  Begin();
1283  while (!End()) {
1284  Int_t val = Next();
1285  if (val >= vinf && val <= vsup) nl.Add(val);
1286  else if (val > vsup) return nl;
1287  }
1288  return nl;
1289 
1290 }
1291 
1292 
1293 
1294 
1298 
1300 {
1301  // Returns difference between 'this' and 'other'
1302  // i.e. 'this' list with any values in 'other' removed
1303  KVNumberList tmp(*this);
1304  tmp.Remove(other);
1305  return tmp;
1306 }
1307 
1308 
1309 
1310 
1312 
1314 {
1315  PrintLimits();
1316 }
1317 
1318 
1319 
1320 
1324 
1326 {
1327  //Create sublist of KVNumberList with "number" values
1328  //TList object has to be deleted after use by the user
1329  TList* list = new TList();
1330  list->SetOwner(kTRUE);
1331 
1332  KVNumberList* nl = 0;
1333  Begin();
1334  while (!End()) {
1335  Int_t vv = Next();
1336  if (!nl) {
1337  nl = new KVNumberList();
1338  list->Add(nl);
1339  }
1340  else if (nl->GetNValues() >= number) {
1341  nl = new KVNumberList();
1342  list->Add(nl);
1343  }
1344  nl->Add(vv);
1345  }
1346 
1347  return list;
1348 
1349 }
1350 
1351 
int Int_t
#define e(i)
bool Bool_t
char Char_t
constexpr Bool_t kFALSE
constexpr Bool_t kTRUE
const char Option_t
winID h TVirtualViewer3D vv
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
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
char name[80]
R__EXTERN TRandom * gRandom
char * Form(const char *fmt,...)
Strings used to represent a set of ranges of values.
Definition: KVNumberList.h:86
TList * CutInSubList(Int_t number)
Int_t GetRandomFast() const
bool operator!=(const KVNumberList &) const
Inequality test for number lists.
void Inter(const KVNumberList &list)
virtual void SetName(const char *name)
const Char_t * AsQuotedString() const
void Copy(TObject &) const override
Copy content of this number list into 'o'.
const Char_t * GetList() const
IntArrayIter end() const
Bool_t Contains(Int_t val) const
returns kTRUE if the value 'val' is contained in the ranges defined by the number list
KVNumberList()
Default constructor.
Int_t First() const
Returns smallest number included in list.
void SetMinMax(Int_t min, Int_t max, Int_t pas=1)
Set list with all values from 'min' to 'max'.
KVNumberList GetListDividedBy(Int_t) const
KVNumberList operator+(const KVNumberList &) const
Return sum of this list and the other one.
void Clear(Option_t *="") override
Empty number list, reset it to initial state.
const Char_t * AsString(Int_t maxchars=0) const
Bool_t End(void) const
Definition: KVNumberList.h:200
void Remove(Int_t)
Remove value 'n' from the list.
const char * GetName() const override
Definition: KVNumberList.h:129
IntArrayIter begin() const
Int_t GetNValues() const
const Char_t * AsHumanReadableString() const
const Char_t * GetExpandedList() const
void Begin(void) const
KVNumberList operator-(const KVNumberList &) const
Bool_t IsFull(Int_t vinf=-1, Int_t vsup=-1) const
Int_t GetEntries() const
Definition: KVNumberList.h:172
void SetList(const TString &)
void Add(Int_t)
Add value 'n' to the list.
void PrintLimits() const
bool operator==(const KVNumberList &) const
Equality test for number lists.
void Print(Option_t *="") const override
Bool_t IsEmpty() const
Definition: KVNumberList.h:176
Int_t GetRandom() const
IntArray GetArray() const
TString GetSQL(const Char_t *column) const
std::optional< int > FindOffset(const KVNumberList &other)
Int_t At(Int_t index) const
Bool_t PrepareRandomFast() const
KVNumberList GetSubList(Int_t vinf, Int_t vsup) const
Int_t operator[](Int_t index) const
KVNumberList GetComplementaryList() const
Int_t Last() const
Returns largest number included in list.
TString GetLogical(const Char_t *observable) const
Int_t Next(void) const
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:73
void Begin(TString delim) const
Definition: KVString.cpp:565
Bool_t End() const
Definition: KVString.cpp:634
KVString Next(Bool_t strip_whitespace=kFALSE) const
Definition: KVString.cpp:695
Int_t GetNValues(TString delim) const
Definition: KVString.cpp:886
void Set(Int_t n) override
void Reset()
virtual void SetOwner(Bool_t enable=kTRUE)
void Add(TObject *obj) override
virtual const char * ClassName() const
virtual UInt_t Integer(UInt_t imax)
Ssiz_t Length() const
Int_t Atoi() const
const char * Data() const
TObjArray * Tokenize(const TString &delim) const
TString & Append(char c, Ssiz_t rep=1)
void Form(const char *fmt,...)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
TString & ReplaceAll(const char *s1, const char *s2)
TLine * line
Double_t x[n]
const Int_t n
void Warning(UserClass p, const char *location, const char *va_(fmt),...)
Definition: KVError.h:125
RooArgList L(Args_t &&... args)
double min(double x, double y)
double max(double x, double y)
Double_t Max(Double_t a, Double_t b)
v
ClassImp(TPyArg)