37#define PEAK_WINDOW 1024
63 :
TNamed(
"Spectrum",
"Miroslav Morhac peak finder")
147 if (
h ==
nullptr)
return nullptr;
148 Int_t dimension =
h->GetDimension();
149 if (dimension != 1) {
150 Error(
"Background",
"Only implemented for 1-d histograms");
175 Int_t first =
h->GetXaxis()->GetFirst();
176 Int_t last =
h->GetXaxis()->GetLast();
180 for (i = 0; i <
size; i++) source[i] =
h->GetBinContent(i + first);
184 smoothWindow,compton);
188 Int_t nch = strlen(
h->GetName());
189 char *
hbname =
new char[nch+20];
213 printf(
"\nNumber of positions = %d\n",
fNPeaks);
261 if (hin ==
nullptr)
return 0;
264 Error(
"Search",
"Only implemented for 1-d and 2-d histograms");
267 if (threshold <=0 || threshold >= 1) {
268 Warning(
"Search",
"threshold must 0<threshold<1, threshold=0.05 assumed");
288 if (dimension == 1) {
292 Int_t i, bin, npeaks;
304 for (i = 0; i < npeaks; i++) {
314 if (!npeaks)
return 0;
505 Int_t numberIterations,
507 bool smoothing,
Int_t smoothWindow,
510 int i, j, w, bw, b1, b2, priz;
511 Double_t a,
b,
c,
d,
e, yb1, yb2, ai, av, men, b4, c4, d4, e4, b6, c6, d6, e6, f6, g6, b8, c8, d8, e8, f8, g8, h8, i8;
513 return "Wrong Parameters";
514 if (numberIterations < 1)
515 return "Width of Clipping Window Must Be Positive";
516 if (ssize < 2 * numberIterations + 1)
517 return "Too Large Clipping Window";
519 return "Incorrect width of smoothing window";
521 for (i = 0; i < ssize; i++){
522 working_space[i] = spectrum[i];
523 working_space[i + ssize] = spectrum[i];
525 bw=(smoothWindow-1)/2;
529 i = numberIterations;
532 for (j = i; j < ssize - i; j++) {
534 a = working_space[ssize + j];
535 b = (working_space[ssize + j - i] + working_space[ssize + j + i]) / 2.0;
538 working_space[j] =
a;
541 else if (smoothing ==
kTRUE){
542 a = working_space[ssize + j];
545 for (w = j - bw; w <= j + bw;
w++){
546 if ( w >= 0 && w < ssize){
547 av += working_space[ssize + w];
554 for (w = j - i - bw; w <= j - i + bw;
w++){
555 if ( w >= 0 && w < ssize){
556 b += working_space[ssize + w];
563 for (w = j + i - bw; w <= j + i + bw;
w++){
564 if ( w >= 0 && w < ssize){
565 c += working_space[ssize + w];
576 for (j = i; j < ssize - i; j++)
577 working_space[ssize + j] = working_space[j];
587 for (j = i; j < ssize - i; j++) {
589 a = working_space[ssize + j];
590 b = (working_space[ssize + j - i] + working_space[ssize + j + i]) / 2.0;
593 c -= working_space[ssize + j - (
Int_t) (2 * ai)] / 6;
594 c += 4 * working_space[ssize + j - (
Int_t) ai] / 6;
595 c += 4 * working_space[ssize + j + (
Int_t) ai] / 6;
596 c -= working_space[ssize + j + (
Int_t) (2 * ai)] / 6;
601 working_space[j] =
a;
604 else if (smoothing ==
kTRUE){
605 a = working_space[ssize + j];
608 for (w = j - bw; w <= j + bw;
w++){
609 if ( w >= 0 && w < ssize){
610 av += working_space[ssize + w];
617 for (w = j - i - bw; w <= j - i + bw;
w++){
618 if ( w >= 0 && w < ssize){
619 b += working_space[ssize + w];
626 for (w = j + i - bw; w <= j + i + bw;
w++){
627 if ( w >= 0 && w < ssize){
628 c += working_space[ssize + w];
636 for (w = j - (
Int_t)(2 * ai) - bw; w <= j - (
Int_t)(2 * ai) + bw;
w++){
637 if (w >= 0 && w < ssize){
638 b4 += working_space[ssize + w];
645 if (w >= 0 && w < ssize){
646 c4 += working_space[ssize + w];
653 if (w >= 0 && w < ssize){
654 d4 += working_space[ssize + w];
660 for (w = j + (
Int_t)(2 * ai) - bw; w <= j + (
Int_t)(2 * ai) + bw;
w++){
661 if (w >= 0 && w < ssize){
662 e4 += working_space[ssize + w];
667 b4 = (-b4 + 4 * c4 + 4 * d4 - e4) / 6;
675 for (j = i; j < ssize - i; j++)
676 working_space[ssize + j] = working_space[j];
686 for (j = i; j < ssize - i; j++) {
688 a = working_space[ssize + j];
689 b = (working_space[ssize + j - i] + working_space[ssize + j + i]) / 2.0;
692 c -= working_space[ssize + j - (
Int_t) (2 * ai)] / 6;
693 c += 4 * working_space[ssize + j - (
Int_t) ai] / 6;
694 c += 4 * working_space[ssize + j + (
Int_t) ai] / 6;
695 c -= working_space[ssize + j + (
Int_t) (2 * ai)] / 6;
698 d += working_space[ssize + j - (
Int_t) (3 * ai)] / 20;
699 d -= 6 * working_space[ssize + j - (
Int_t) (2 * ai)] / 20;
700 d += 15 * working_space[ssize + j - (
Int_t) ai] / 20;
701 d += 15 * working_space[ssize + j + (
Int_t) ai] / 20;
702 d -= 6 * working_space[ssize + j + (
Int_t) (2 * ai)] / 20;
703 d += working_space[ssize + j + (
Int_t) (3 * ai)] / 20;
710 working_space[j] =
a;
713 else if (smoothing ==
kTRUE){
714 a = working_space[ssize + j];
717 for (w = j - bw; w <= j + bw;
w++){
718 if ( w >= 0 && w < ssize){
719 av += working_space[ssize + w];
726 for (w = j - i - bw; w <= j - i + bw;
w++){
727 if ( w >= 0 && w < ssize){
728 b += working_space[ssize + w];
735 for (w = j + i - bw; w <= j + i + bw;
w++){
736 if ( w >= 0 && w < ssize){
737 c += working_space[ssize + w];
745 for (w = j - (
Int_t)(2 * ai) - bw; w <= j - (
Int_t)(2 * ai) + bw;
w++){
746 if (w >= 0 && w < ssize){
747 b4 += working_space[ssize + w];
754 if (w >= 0 && w < ssize){
755 c4 += working_space[ssize + w];
762 if (w >= 0 && w < ssize){
763 d4 += working_space[ssize + w];
769 for (w = j + (
Int_t)(2 * ai) - bw; w <= j + (
Int_t)(2 * ai) + bw;
w++){
770 if (w >= 0 && w < ssize){
771 e4 += working_space[ssize + w];
776 b4 = (-b4 + 4 * c4 + 4 * d4 - e4) / 6;
779 for (w = j - (
Int_t)(3 * ai) - bw; w <= j - (
Int_t)(3 * ai) + bw;
w++){
780 if (w >= 0 && w < ssize){
781 b6 += working_space[ssize + w];
787 for (w = j - (
Int_t)(2 * ai) - bw; w <= j - (
Int_t)(2 * ai) + bw;
w++){
788 if (w >= 0 && w < ssize){
789 c6 += working_space[ssize + w];
796 if (w >= 0 && w < ssize){
797 d6 += working_space[ssize + w];
804 if (w >= 0 && w < ssize){
805 e6 += working_space[ssize + w];
811 for (w = j + (
Int_t)(2 * ai) - bw; w <= j + (
Int_t)(2 * ai) + bw;
w++){
812 if (w >= 0 && w < ssize){
813 f6 += working_space[ssize + w];
819 for (w = j + (
Int_t)(3 * ai) - bw; w <= j + (
Int_t)(3 * ai) + bw;
w++){
820 if (w >= 0 && w < ssize){
821 g6 += working_space[ssize + w];
826 b6 = (b6 - 6 * c6 + 15 * d6 + 15 * e6 - 6 * f6 + g6) / 20;
836 for (j = i; j < ssize - i; j++)
837 working_space[ssize + j] = working_space[j];
847 for (j = i; j < ssize - i; j++) {
849 a = working_space[ssize + j];
850 b = (working_space[ssize + j - i] + working_space[ssize + j + i]) / 2.0;
853 c -= working_space[ssize + j - (
Int_t) (2 * ai)] / 6;
854 c += 4 * working_space[ssize + j - (
Int_t) ai] / 6;
855 c += 4 * working_space[ssize + j + (
Int_t) ai] / 6;
856 c -= working_space[ssize + j + (
Int_t) (2 * ai)] / 6;
859 d += working_space[ssize + j - (
Int_t) (3 * ai)] / 20;
860 d -= 6 * working_space[ssize + j - (
Int_t) (2 * ai)] / 20;
861 d += 15 * working_space[ssize + j - (
Int_t) ai] / 20;
862 d += 15 * working_space[ssize + j + (
Int_t) ai] / 20;
863 d -= 6 * working_space[ssize + j + (
Int_t) (2 * ai)] / 20;
864 d += working_space[ssize + j + (
Int_t) (3 * ai)] / 20;
867 e -= working_space[ssize + j - (
Int_t) (4 * ai)] / 70;
868 e += 8 * working_space[ssize + j - (
Int_t) (3 * ai)] / 70;
869 e -= 28 * working_space[ssize + j - (
Int_t) (2 * ai)] / 70;
870 e += 56 * working_space[ssize + j - (
Int_t) ai] / 70;
871 e += 56 * working_space[ssize + j + (
Int_t) ai] / 70;
872 e -= 28 * working_space[ssize + j + (
Int_t) (2 * ai)] / 70;
873 e += 8 * working_space[ssize + j + (
Int_t) (3 * ai)] / 70;
874 e -= working_space[ssize + j + (
Int_t) (4 * ai)] / 70;
883 working_space[j] =
a;
886 else if (smoothing ==
kTRUE){
887 a = working_space[ssize + j];
890 for (w = j - bw; w <= j + bw;
w++){
891 if ( w >= 0 && w < ssize){
892 av += working_space[ssize + w];
899 for (w = j - i - bw; w <= j - i + bw;
w++){
900 if ( w >= 0 && w < ssize){
901 b += working_space[ssize + w];
908 for (w = j + i - bw; w <= j + i + bw;
w++){
909 if ( w >= 0 && w < ssize){
910 c += working_space[ssize + w];
918 for (w = j - (
Int_t)(2 * ai) - bw; w <= j - (
Int_t)(2 * ai) + bw;
w++){
919 if (w >= 0 && w < ssize){
920 b4 += working_space[ssize + w];
927 if (w >= 0 && w < ssize){
928 c4 += working_space[ssize + w];
935 if (w >= 0 && w < ssize){
936 d4 += working_space[ssize + w];
942 for (w = j + (
Int_t)(2 * ai) - bw; w <= j + (
Int_t)(2 * ai) + bw;
w++){
943 if (w >= 0 && w < ssize){
944 e4 += working_space[ssize + w];
949 b4 = (-b4 + 4 * c4 + 4 * d4 - e4) / 6;
952 for (w = j - (
Int_t)(3 * ai) - bw; w <= j - (
Int_t)(3 * ai) + bw;
w++){
953 if (w >= 0 && w < ssize){
954 b6 += working_space[ssize + w];
960 for (w = j - (
Int_t)(2 * ai) - bw; w <= j - (
Int_t)(2 * ai) + bw;
w++){
961 if (w >= 0 && w < ssize){
962 c6 += working_space[ssize + w];
969 if (w >= 0 && w < ssize){
970 d6 += working_space[ssize + w];
977 if (w >= 0 && w < ssize){
978 e6 += working_space[ssize + w];
984 for (w = j + (
Int_t)(2 * ai) - bw; w <= j + (
Int_t)(2 * ai) + bw;
w++){
985 if (w >= 0 && w < ssize){
986 f6 += working_space[ssize + w];
992 for (w = j + (
Int_t)(3 * ai) - bw; w <= j + (
Int_t)(3 * ai) + bw;
w++){
993 if (w >= 0 && w < ssize){
994 g6 += working_space[ssize + w];
999 b6 = (b6 - 6 * c6 + 15 * d6 + 15 * e6 - 6 * f6 + g6) / 20;
1002 for (w = j - (
Int_t)(4 * ai) - bw; w <= j - (
Int_t)(4 * ai) + bw;
w++){
1003 if (w >= 0 && w < ssize){
1004 b8 += working_space[ssize + w];
1010 for (w = j - (
Int_t)(3 * ai) - bw; w <= j - (
Int_t)(3 * ai) + bw;
w++){
1011 if (w >= 0 && w < ssize){
1012 c8 += working_space[ssize + w];
1018 for (w = j - (
Int_t)(2 * ai) - bw; w <= j - (
Int_t)(2 * ai) + bw;
w++){
1019 if (w >= 0 && w < ssize){
1020 d8 += working_space[ssize + w];
1027 if (w >= 0 && w < ssize){
1028 e8 += working_space[ssize + w];
1035 if (w >= 0 && w < ssize){
1036 f8 += working_space[ssize + w];
1042 for (w = j + (
Int_t)(2 * ai) - bw; w <= j + (
Int_t)(2 * ai) + bw;
w++){
1043 if (w >= 0 && w < ssize){
1044 g8 += working_space[ssize + w];
1050 for (w = j + (
Int_t)(3 * ai) - bw; w <= j + (
Int_t)(3 * ai) + bw;
w++){
1051 if (w >= 0 && w < ssize){
1052 h8 += working_space[ssize + w];
1058 for (w = j + (
Int_t)(4 * ai) - bw; w <= j + (
Int_t)(4 * ai) + bw;
w++){
1059 if (w >= 0 && w < ssize){
1060 i8 += working_space[ssize + w];
1065 b8 = ( -b8 + 8 * c8 - 28 * d8 + 56 * e8 - 56 * f8 - 28 * g8 + 8 * h8 - i8)/70;
1074 working_space[j]=av;
1077 for (j = i; j < ssize - i; j++)
1078 working_space[ssize + j] = working_space[j];
1086 if (compton ==
kTRUE) {
1087 for (i = 0, b2 = 0; i < ssize; i++){
1089 a = working_space[i],
b = spectrum[i];
1095 yb1 = working_space[b1];
1096 for (b2 = b1 + 1,
c = 0, priz = 0; priz == 0 && b2 < ssize; b2++){
1097 a = working_space[b2],
b = spectrum[b2];
1106 yb2 = working_space[b2];
1108 for (j = b1,
c = 0; j <= b2; j++){
1113 c = (yb2 - yb1) /
c;
1114 for (j = b1,
d = 0; j <= b2 && j < ssize; j++){
1118 working_space[ssize + j] =
a;
1124 for (j = b2,
c = 0; j >= b1; j--){
1129 c = (yb1 - yb2) /
c;
1130 for (j = b2,
d = 0;j >= b1 && j >= 0; j--){
1134 working_space[ssize + j] =
a;
1143 for (j = 0; j < ssize; j++)
1144 spectrum[j] = working_space[ssize + j];
1145 delete[]working_space;
1191 Double_t nom, nip, nim, sp, sm, area = 0;
1193 return "Averaging Window must be positive";
1196 for(i = 0, maxch = 0; i < ssize; i++){
1198 if(maxch < source[i])
1204 delete [] working_space;
1209 working_space[
xmin] = 1;
1211 nip = source[i] / maxch;
1212 nim = source[i + 1] / maxch;
1214 for(
l = 1;
l <= averWindow;
l++){
1216 a = source[
xmax] / maxch;
1219 a = source[i +
l] / maxch;
1229 if((i -
l + 1) <
xmin)
1230 a = source[
xmin] / maxch;
1233 a = source[i -
l + 1] / maxch;
1244 a = working_space[i + 1] = working_space[i] *
a;
1248 working_space[i] = working_space[i] / nom;
1250 for(i = 0; i < ssize; i++)
1251 source[i] = working_space[i] * area;
1252 delete[]working_space;
1452 int ssize,
int numberIterations,
1453 int numberRepetitions,
Double_t boost )
1456 return "Wrong Parameters";
1458 if (numberRepetitions <= 0)
1459 return "Wrong Parameters";
1464 int i, j, k, lindex, posit, lh_gold,
l, repet;
1465 Double_t lda, ldb, ldc, area, maximum;
1472 for (i = 0; i < ssize; i++) {
1476 working_space[i] = lda;
1478 if (lda > maximum) {
1483 if (lh_gold == -1) {
1484 delete [] working_space;
1485 return "ZERO RESPONSE VECTOR";
1489 for (i = 0; i < ssize; i++)
1490 working_space[2 * ssize + i] = source[i];
1493 for (i = 0; i < ssize; i++){
1495 for (j = 0; j < ssize; j++){
1496 ldb = working_space[j];
1499 ldc = working_space[k];
1500 lda = lda + ldb * ldc;
1503 working_space[ssize + i] = lda;
1505 for (k = 0; k < ssize; k++){
1508 ldb = working_space[
l];
1509 ldc = working_space[2 * ssize + k];
1510 lda = lda + ldb * ldc;
1513 working_space[3 * ssize + i]=lda;
1517 for (i = 0; i < ssize; i++){
1518 working_space[2 * ssize + i] = working_space[3 * ssize + i];
1522 for (i = 0; i < ssize; i++)
1523 working_space[i] = 1;
1526 for (repet = 0; repet < numberRepetitions; repet++) {
1528 for (i = 0; i < ssize; i++)
1529 working_space[i] =
TMath::Power(working_space[i], boost);
1531 for (lindex = 0; lindex < numberIterations; lindex++) {
1532 for (i = 0; i < ssize; i++) {
1533 if (working_space[2 * ssize + i] > 0.000001
1534 && working_space[i] > 0.000001) {
1536 for (j = 0; j < lh_gold; j++) {
1537 ldb = working_space[j + ssize];
1542 ldc = working_space[k];
1545 ldc += working_space[k];
1549 ldc = working_space[i];
1550 lda = lda + ldb * ldc;
1552 ldb = working_space[2 * ssize + i];
1558 ldb = working_space[i];
1560 working_space[3 * ssize + i] = lda;
1563 for (i = 0; i < ssize; i++)
1564 working_space[i] = working_space[3 * ssize + i];
1569 for (i = 0; i < ssize; i++) {
1570 lda = working_space[i];
1573 working_space[ssize + j] = lda;
1577 for (i = 0; i < ssize; i++)
1578 source[i] = area * working_space[ssize + i];
1579 delete[]working_space;
1658 int ssize,
int numberIterations,
1659 int numberRepetitions,
Double_t boost )
1662 return "Wrong Parameters";
1664 if (numberRepetitions <= 0)
1665 return "Wrong Parameters";
1670 int i, j, k, lindex, posit, lh_gold, repet, kmin, kmax;
1677 for (i = 0; i < ssize; i++) {
1681 working_space[ssize + i] = lda;
1682 if (lda > maximum) {
1687 if (lh_gold == -1) {
1688 delete [] working_space;
1689 return "ZERO RESPONSE VECTOR";
1693 for (i = 0; i < ssize; i++)
1694 working_space[2 * ssize + i] = source[i];
1697 for (i = 0; i < ssize; i++){
1698 if (i <= ssize - lh_gold)
1699 working_space[i] = 1;
1702 working_space[i] = 0;
1706 for (repet = 0; repet < numberRepetitions; repet++) {
1708 for (i = 0; i < ssize; i++)
1709 working_space[i] =
TMath::Power(working_space[i], boost);
1711 for (lindex = 0; lindex < numberIterations; lindex++) {
1712 for (i = 0; i <= ssize - lh_gold; i++){
1714 if (working_space[i] > 0){
1715 for (j = i; j < i + lh_gold; j++){
1716 ldb = working_space[2 * ssize + j];
1720 if (kmax > lh_gold - 1)
1722 kmin = j + lh_gold - ssize;
1726 for (k = kmax; k >= kmin; k--){
1727 ldc += working_space[ssize + k] * working_space[j - k];
1735 ldb = ldb * working_space[ssize + j - i];
1739 lda = lda * working_space[i];
1741 working_space[3 * ssize + i] = lda;
1743 for (i = 0; i < ssize; i++)
1744 working_space[i] = working_space[3 * ssize + i];
1749 for (i = 0; i < ssize; i++) {
1750 lda = working_space[i];
1753 working_space[ssize + j] = lda;
1757 for (i = 0; i < ssize; i++)
1758 source[i] = working_space[ssize + i];
1759 delete[]working_space;
1883 int ssizex,
int ssizey,
1884 int numberIterations,
1885 int numberRepetitions,
Double_t boost)
1887 int i, j, k, lindex, lhx = 0, repet;
1889 if (ssizex <= 0 || ssizey <= 0)
1890 return "Wrong Parameters";
1891 if (ssizex < ssizey)
1892 return "Sizex must be greater than sizey)";
1893 if (numberIterations <= 0)
1894 return "Number of iterations must be positive";
1896 new Double_t[ssizex * ssizey + 2 * ssizey * ssizey + 4 * ssizex];
1899 for (j = 0; j < ssizey && lhx != -1; j++) {
1902 for (i = 0; i < ssizex; i++) {
1903 lda = respMatrix[j][i];
1907 working_space[j * ssizex + i] = lda;
1911 for (i = 0; i < ssizex; i++)
1912 working_space[j * ssizex + i] /= area;
1916 delete [] working_space;
1917 return (
"ZERO COLUMN IN RESPONSE MATRIX");
1921 for (i = 0; i < ssizex; i++)
1922 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 2 * ssizex + i] =
1926 for (i = 0; i < ssizey; i++) {
1927 for (j = 0; j < ssizey; j++) {
1929 for (k = 0; k < ssizex; k++) {
1930 ldb = working_space[ssizex * i + k];
1931 ldc = working_space[ssizex * j + k];
1932 lda = lda + ldb * ldc;
1934 working_space[ssizex * ssizey + ssizey * i + j] = lda;
1937 for (k = 0; k < ssizex; k++) {
1938 ldb = working_space[ssizex * i + k];
1940 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 2 * ssizex +
1942 lda = lda + ldb * ldc;
1944 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 3 * ssizex + i] =
1949 for (i = 0; i < ssizey; i++)
1950 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 2 * ssizex + i] =
1951 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 3 * ssizex + i];
1954 for (i = 0; i < ssizey; i++) {
1955 for (j = 0; j < ssizey; j++) {
1957 for (k = 0; k < ssizey; k++) {
1958 ldb = working_space[ssizex * ssizey + ssizey * i + k];
1959 ldc = working_space[ssizex * ssizey + ssizey * j + k];
1960 lda = lda + ldb * ldc;
1962 working_space[ssizex * ssizey + ssizey * ssizey + ssizey * i + j] =
1966 for (k = 0; k < ssizey; k++) {
1967 ldb = working_space[ssizex * ssizey + ssizey * i + k];
1969 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 2 * ssizex +
1971 lda = lda + ldb * ldc;
1973 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 3 * ssizex + i] =
1978 for (i = 0; i < ssizey; i++)
1979 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 2 * ssizex + i] =
1980 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 3 * ssizex + i];
1983 for (i = 0; i < ssizey; i++)
1984 working_space[ssizex * ssizey + 2 * ssizey * ssizey + i] = 1;
1987 for (repet = 0; repet < numberRepetitions; repet++) {
1989 for (i = 0; i < ssizey; i++)
1990 working_space[ssizex * ssizey + 2 * ssizey * ssizey + i] =
TMath::Power(working_space[ssizex * ssizey + 2 * ssizey * ssizey + i], boost);
1992 for (lindex = 0; lindex < numberIterations; lindex++) {
1993 for (i = 0; i < ssizey; i++) {
1995 for (j = 0; j < ssizey; j++) {
1997 working_space[ssizex * ssizey + ssizey * ssizey + ssizey * i + j];
1998 ldc = working_space[ssizex * ssizey + 2 * ssizey * ssizey + j];
1999 lda = lda + ldb * ldc;
2002 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 2 * ssizex + i];
2009 ldb = working_space[ssizex * ssizey + 2 * ssizey * ssizey + i];
2011 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 3 * ssizex + i] = lda;
2013 for (i = 0; i < ssizey; i++)
2014 working_space[ssizex * ssizey + 2 * ssizey * ssizey + i] =
2015 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 3 * ssizex + i];
2020 for (i = 0; i < ssizex; i++) {
2022 source[i] = working_space[ssizex * ssizey + 2 * ssizey * ssizey + i];
2027 delete[]working_space;
2120 bool backgroundRemove,
int deconIterations,
2121 bool markov,
int averWindow)
2123 int i, j, numberIterations = (
Int_t)(7 *
sigma + 0.5);
2125 int k, lindex, posit, imin, imax, jmin, jmax, lh_gold, priz;
2126 Double_t lda, ldb, ldc, area, maximum, maximum_decon;
2127 int xmin,
xmax,
l, peak_index = 0, size_ext = ssize + 2 * numberIterations, shift = numberIterations, bw = 2, w;
2129 Double_t nom, nip, nim, sp, sm, plocha = 0;
2130 Double_t m0low=0,m1low=0,m2low=0,l0low=0,l1low=0,detlow,av,men;
2132 Error(
"SearchHighRes",
"Invalid sigma, must be greater than or equal to 1");
2136 if(threshold<=0 || threshold>=100){
2137 Error(
"SearchHighRes",
"Invalid threshold, must be positive and less than 100");
2143 Error(
"SearchHighRes",
"Too large sigma");
2147 if (markov ==
true) {
2148 if (averWindow <= 0) {
2149 Error(
"SearchHighRes",
"Averaging window must be positive");
2154 if(backgroundRemove ==
true){
2155 if(ssize < 2 * numberIterations + 1){
2156 Error(
"SearchHighRes",
"Too large clipping window");
2161 k = int(2 *
sigma+0.5);
2163 for(i = 0;i < k;i++){
2164 a = i,
b = source[i];
2165 m0low += 1,m1low +=
a,m2low +=
a *
a,l0low +=
b,l1low +=
a *
b;
2167 detlow = m0low * m2low - m1low * m1low;
2169 l1low = (-l0low * m1low + l1low * m0low) / detlow;
2184 for (j=0;j<7 * (ssize + i);j++) working_space[j] = 0;
2185 for(i = 0; i < size_ext; i++){
2188 working_space[i + size_ext] = source[0] + l1low *
a;
2189 if(working_space[i + size_ext] < 0)
2190 working_space[i + size_ext]=0;
2193 else if(i >= ssize + shift){
2194 a = i - (ssize - 1 + shift);
2195 working_space[i + size_ext] = source[ssize - 1];
2196 if(working_space[i + size_ext] < 0)
2197 working_space[i + size_ext]=0;
2201 working_space[i + size_ext] = source[i - shift];
2204 if(backgroundRemove ==
true){
2205 for(i = 1; i <= numberIterations; i++){
2206 for(j = i; j < size_ext - i; j++){
2207 if(markov ==
false){
2208 a = working_space[size_ext + j];
2209 b = (working_space[size_ext + j - i] + working_space[size_ext + j + i]) / 2.0;
2217 a = working_space[size_ext + j];
2220 for (w = j - bw; w <= j + bw;
w++){
2221 if ( w >= 0 && w < size_ext){
2222 av += working_space[size_ext + w];
2229 for (w = j - i - bw; w <= j - i + bw;
w++){
2230 if ( w >= 0 && w < size_ext){
2231 b += working_space[size_ext + w];
2238 for (w = j + i - bw; w <= j + i + bw;
w++){
2239 if ( w >= 0 && w < size_ext){
2240 c += working_space[size_ext + w];
2248 working_space[j]=av;
2251 for(j = i; j < size_ext - i; j++)
2252 working_space[size_ext + j] = working_space[j];
2254 for(j = 0;j < size_ext; j++){
2257 b = source[0] + l1low *
a;
2259 working_space[size_ext + j] =
b - working_space[size_ext + j];
2262 else if(j >= ssize + shift){
2263 a = j - (ssize - 1 + shift);
2264 b = source[ssize - 1];
2266 working_space[size_ext + j] =
b - working_space[size_ext + j];
2270 working_space[size_ext + j] = source[j - shift] - working_space[size_ext + j];
2273 for(j = 0;j < size_ext; j++){
2274 if(working_space[size_ext + j] < 0) working_space[size_ext + j] = 0;
2278 for(i = 0; i < size_ext; i++){
2279 working_space[i + 6*size_ext] = working_space[i + size_ext];
2283 for(j = 0; j < size_ext; j++)
2284 working_space[2 * size_ext + j] = working_space[size_ext + j];
2286 for(i = 0, maxch = 0; i < size_ext; i++){
2287 working_space[i] = 0;
2288 if(maxch < working_space[2 * size_ext + i])
2289 maxch = working_space[2 * size_ext + i];
2290 plocha += working_space[2 * size_ext + i];
2293 delete [] working_space;
2298 working_space[
xmin] = 1;
2300 nip = working_space[2 * size_ext + i] / maxch;
2301 nim = working_space[2 * size_ext + i + 1] / maxch;
2303 for(
l = 1;
l <= averWindow;
l++){
2305 a = working_space[2 * size_ext +
xmax] / maxch;
2308 a = working_space[2 * size_ext + i +
l] / maxch;
2320 if((i -
l + 1) <
xmin)
2321 a = working_space[2 * size_ext +
xmin] / maxch;
2324 a = working_space[2 * size_ext + i -
l + 1] / maxch;
2338 a = working_space[i + 1] = working_space[i] *
a;
2342 working_space[i] = working_space[i] / nom;
2344 for(j = 0; j < size_ext; j++)
2345 working_space[size_ext + j] = working_space[j] * plocha;
2346 for(j = 0; j < size_ext; j++){
2347 working_space[2 * size_ext + j] = working_space[size_ext + j];
2349 if(backgroundRemove ==
true){
2350 for(i = 1; i <= numberIterations; i++){
2351 for(j = i; j < size_ext - i; j++){
2352 a = working_space[size_ext + j];
2353 b = (working_space[size_ext + j - i] + working_space[size_ext + j + i]) / 2.0;
2356 working_space[j] =
a;
2358 for(j = i; j < size_ext - i; j++)
2359 working_space[size_ext + j] = working_space[j];
2361 for(j = 0; j < size_ext; j++){
2362 working_space[size_ext + j] = working_space[2 * size_ext + j] - working_space[size_ext + j];
2372 for(i = 0; i < size_ext; i++){
2380 working_space[i] = lda;
2388 for(i = 0; i < size_ext; i++)
2389 working_space[2 * size_ext + i] =
TMath::Abs(working_space[size_ext + i]);
2396 for(i = imin; i <= imax; i++){
2401 jmax = lh_gold - 1 - i;
2402 if(jmax > (lh_gold - 1))
2405 for(j = jmin;j <= jmax; j++){
2406 ldb = working_space[j];
2407 ldc = working_space[i + j];
2408 lda = lda + ldb * ldc;
2410 working_space[size_ext + i - imin] = lda;
2414 imin = -i,imax = size_ext + i - 1;
2415 for(i = imin; i <= imax; i++){
2417 for(j = 0; j <= (lh_gold - 1); j++){
2418 ldb = working_space[j];
2420 if(k >= 0 && k < size_ext){
2421 ldc = working_space[2 * size_ext + k];
2422 lda = lda + ldb * ldc;
2426 working_space[4 * size_ext + i - imin] = lda;
2429 for(i = imin; i <= imax; i++)
2430 working_space[2 * size_ext + i - imin] = working_space[4 * size_ext + i - imin];
2432 for(i = 0; i < size_ext; i++)
2433 working_space[i] = 1;
2435 for(lindex = 0; lindex < deconIterations; lindex++){
2436 for(i = 0; i < size_ext; i++){
2437 if(
TMath::Abs(working_space[2 * size_ext + i]) > 0.00001 &&
TMath::Abs(working_space[i]) > 0.00001){
2445 if(jmax > (size_ext - 1 - i))
2448 for(j = jmin; j <= jmax; j++){
2449 ldb = working_space[j + lh_gold - 1 + size_ext];
2450 ldc = working_space[i + j];
2451 lda = lda + ldb * ldc;
2453 ldb = working_space[2 * size_ext + i];
2460 ldb = working_space[i];
2462 working_space[3 * size_ext + i] = lda;
2465 for(i = 0; i < size_ext; i++){
2466 working_space[i] = working_space[3 * size_ext + i];
2470 for(i=0;i<size_ext;i++){
2471 lda = working_space[i];
2474 working_space[size_ext + j] = lda;
2477 maximum = 0, maximum_decon = 0;
2479 for(i = 0; i < size_ext - j; i++){
2480 if(i >= shift && i < ssize + shift){
2481 working_space[i] = area * working_space[size_ext + i + j];
2482 if(maximum_decon < working_space[i])
2483 maximum_decon = working_space[i];
2484 if(maximum < working_space[6 * size_ext + i])
2485 maximum = working_space[6 * size_ext + i];
2489 working_space[i] = 0;
2497 for(i = 1; i < size_ext - 1; i++){
2498 if(working_space[i] > working_space[i - 1] && working_space[i] > working_space[i + 1]){
2499 if(i >= shift && i < ssize + shift){
2500 if(working_space[i] > lda*maximum_decon && working_space[6 * size_ext + i] > threshold * maximum / 100.0){
2501 for(j = i - 1,
a = 0,
b = 0; j <= i + 1; j++){
2502 a += (
Double_t)(j - shift) * working_space[j];
2503 b += working_space[j];
2511 if(peak_index == 0){
2517 for(j = 0, priz = 0; j < peak_index && priz == 0; j++){
2518 if(working_space[6 * size_ext + shift + (
Int_t)
a] > working_space[6 * size_ext + shift + (
Int_t)
fPositionX[j]])
2528 for(k = peak_index; k >= j; k--){
2543 for(i = 0; i < ssize; i++) destVector[i] = working_space[i + shift];
2544 delete [] working_space;
2547 Warning(
"SearchHighRes",
"Peak buffer full");
2557 bool backgroundRemove,
int deconIterations,
2558 bool markov,
int averWindow)
2563 deconIterations,markov,averWindow);
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
int Int_t
Signed integer 4 bytes (int).
bool Bool_t
Boolean (0=false, 1=true) (bool).
double Double_t
Double 8 bytes.
const char Option_t
Option string (const char).
virtual void SetLineColor(Color_t lcolor)
Set the line color.
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
Int_t GetLast() const
Return last bin on the axis i.e.
Int_t GetFirst() const
Return first bin on the axis i.e.
TH1 is the base class of all histogram classes in ROOT.
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
virtual Int_t GetDimension() const
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
void Draw(Option_t *option="") override
Draw this histogram with options.
virtual void SetBinContent(Int_t bin, Double_t content)
Set bin content see convention for numbering bins in TH1::GetBin In case the bin number is greater th...
TList * GetListOfFunctions() const
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
virtual void SetEntries(Double_t n)
TObject * FindObject(const char *name) const override
Find an object in this list using its name.
void Add(TObject *obj) override
TObject * Remove(TObject *obj) override
Remove object from the list.
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
A PolyMarker is defined by an array on N points in a 2-D space.
Double_t fResolution
NOT USED resolution of the neighboring peaks
Int_t fMaxPeaks
Maximum number of peaks to be found.
Double_t * fPositionX
[fNPeaks] X position of peaks
const char * SmoothMarkov(Double_t *source, Int_t ssize, Int_t averWindow)
const char * Unfolding(Double_t *source, const Double_t **respMatrix, Int_t ssizex, Int_t ssizey, Int_t numberIterations, Int_t numberRepetitions, Double_t boost)
void SetResolution(Double_t resolution=1)
NOT USED resolution: determines resolution of the neighbouring peaks default value is 1 correspond to...
Int_t SearchHighRes(Double_t *source, Double_t *destVector, Int_t ssize, Double_t sigma, Double_t threshold, bool backgroundRemove, Int_t deconIterations, bool markov, Int_t averWindow)
virtual Int_t Search(const TH1 *hist, Double_t sigma=2, Option_t *option="", Double_t threshold=0.05)
One-dimensional peak search function.
static Int_t StaticSearch(const TH1 *hist, Double_t sigma=2, Option_t *option="goff", Double_t threshold=0.05)
Int_t fNPeaks
number of peaks found
Int_t Search1HighRes(Double_t *source, Double_t *destVector, Int_t ssize, Double_t sigma, Double_t threshold, bool backgroundRemove, Int_t deconIterations, bool markov, Int_t averWindow)
const char * Deconvolution(Double_t *source, const Double_t *response, Int_t ssize, Int_t numberIterations, Int_t numberRepetitions, Double_t boost)
static TH1 * StaticBackground(const TH1 *hist, Int_t niter=20, Option_t *option="")
static Int_t fgAverageWindow
Average window of searched peaks.
static void SetDeconIterations(Int_t n=3)
Static function: Set max number of decon iterations in deconvolution operation (see TSpectrum::Search...
Double_t * fPosition
[fNPeaks] array of current peak positions
void Print(Option_t *option="") const override
Print the array of positions.
static void SetAverageWindow(Int_t w=3)
Static function: Set average window of searched peaks (see TSpectrum::SearchHighRes).
const char * DeconvolutionRL(Double_t *source, const Double_t *response, Int_t ssize, Int_t numberIterations, Int_t numberRepetitions, Double_t boost)
static Int_t fgIterations
Maximum number of decon iterations (default=3).
TSpectrum(const TSpectrum &)
TH1 * fHistogram
resulting histogram
~TSpectrum() override
Destructor.
virtual TH1 * Background(const TH1 *hist, Int_t nIter=20, Option_t *option="")
One-dimensional background estimation function.
Double_t * fPositionY
[fNPeaks] Y position of peaks
void ToLower()
Change string to lower-case.
const char * Data() const
TString & ReplaceAll(const TString &s1, const TString &s2)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Double_t Exp(Double_t x)
Returns the base-e exponential function of x, which is e raised to the power x.
Double_t Sqrt(Double_t x)
Returns the square root of x.
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.