37#define PEAK_WINDOW 1024
64 :
TNamed(
"Spectrum",
"Miroslav Morhac peak finder")
148 if (
h ==
nullptr)
return nullptr;
149 Int_t dimension =
h->GetDimension();
151 Error(
"Search",
"Only implemented for 1-d histograms");
176 Int_t first =
h->GetXaxis()->GetFirst();
177 Int_t last =
h->GetXaxis()->GetLast();
181 for (i = 0; i <
size; i++) source[i] =
h->GetBinContent(i + first);
184 Background(source,
size,numberIterations, direction, filterOrder,smoothing,
185 smoothWindow,compton);
189 Int_t nch = strlen(
h->GetName());
190 char *
hbname =
new char[nch+20];
214 printf(
"\nNumber of positions = %d\n",
fNPeaks);
262 if (hin ==
nullptr)
return 0;
265 Error(
"Search",
"Only implemented for 1-d and 2-d histograms");
268 if (threshold <=0 || threshold >= 1) {
269 Warning(
"Search",
"threshold must 0<threshold<1, threshold=0.05 assumed");
289 if (dimension == 1) {
293 Int_t i, bin, npeaks;
305 for (i = 0; i < npeaks; i++) {
315 if (!npeaks)
return 0;
506 Int_t numberIterations,
508 bool smoothing,
Int_t smoothWindow,
511 int i, j,
w, bw, b1, b2, priz;
512 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;
514 return "Wrong Parameters";
515 if (numberIterations < 1)
516 return "Width of Clipping Window Must Be Positive";
517 if (ssize < 2 * numberIterations + 1)
518 return "Too Large Clipping Window";
520 return "Incorrect width of smoothing window";
522 for (i = 0; i < ssize; i++){
523 working_space[i] = spectrum[i];
524 working_space[i + ssize] = spectrum[i];
526 bw=(smoothWindow-1)/2;
530 i = numberIterations;
533 for (j = i; j < ssize - i; j++) {
535 a = working_space[ssize + j];
536 b = (working_space[ssize + j - i] + working_space[ssize + j + i]) / 2.0;
539 working_space[j] =
a;
542 else if (smoothing ==
kTRUE){
543 a = working_space[ssize + j];
546 for (
w = j - bw;
w <= j + bw;
w++){
547 if (
w >= 0 &&
w < ssize){
548 av += working_space[ssize +
w];
555 for (
w = j - i - bw;
w <= j - i + bw;
w++){
556 if (
w >= 0 &&
w < ssize){
557 b += working_space[ssize +
w];
564 for (
w = j + i - bw;
w <= j + i + bw;
w++){
565 if (
w >= 0 &&
w < ssize){
566 c += working_space[ssize +
w];
577 for (j = i; j < ssize - i; j++)
578 working_space[ssize + j] = working_space[j];
588 for (j = i; j < ssize - i; j++) {
590 a = working_space[ssize + j];
591 b = (working_space[ssize + j - i] + working_space[ssize + j + i]) / 2.0;
594 c -= working_space[ssize + j - (
Int_t) (2 * ai)] / 6;
595 c += 4 * working_space[ssize + j - (
Int_t) ai] / 6;
596 c += 4 * working_space[ssize + j + (
Int_t) ai] / 6;
597 c -= working_space[ssize + j + (
Int_t) (2 * ai)] / 6;
602 working_space[j] =
a;
605 else if (smoothing ==
kTRUE){
606 a = working_space[ssize + j];
609 for (
w = j - bw;
w <= j + bw;
w++){
610 if (
w >= 0 &&
w < ssize){
611 av += working_space[ssize +
w];
618 for (
w = j - i - bw;
w <= j - i + bw;
w++){
619 if (
w >= 0 &&
w < ssize){
620 b += working_space[ssize +
w];
627 for (
w = j + i - bw;
w <= j + i + bw;
w++){
628 if (
w >= 0 &&
w < ssize){
629 c += working_space[ssize +
w];
637 for (
w = j - (
Int_t)(2 * ai) - bw;
w <= j - (
Int_t)(2 * ai) + bw;
w++){
638 if (
w >= 0 &&
w < ssize){
639 b4 += working_space[ssize +
w];
646 if (
w >= 0 &&
w < ssize){
647 c4 += working_space[ssize +
w];
654 if (
w >= 0 &&
w < ssize){
655 d4 += working_space[ssize +
w];
661 for (
w = j + (
Int_t)(2 * ai) - bw;
w <= j + (
Int_t)(2 * ai) + bw;
w++){
662 if (
w >= 0 &&
w < ssize){
663 e4 += working_space[ssize +
w];
668 b4 = (-b4 + 4 * c4 + 4 * d4 - e4) / 6;
676 for (j = i; j < ssize - i; j++)
677 working_space[ssize + j] = working_space[j];
687 for (j = i; j < ssize - i; j++) {
689 a = working_space[ssize + j];
690 b = (working_space[ssize + j - i] + working_space[ssize + j + i]) / 2.0;
693 c -= working_space[ssize + j - (
Int_t) (2 * ai)] / 6;
694 c += 4 * working_space[ssize + j - (
Int_t) ai] / 6;
695 c += 4 * working_space[ssize + j + (
Int_t) ai] / 6;
696 c -= working_space[ssize + j + (
Int_t) (2 * ai)] / 6;
699 d += working_space[ssize + j - (
Int_t) (3 * ai)] / 20;
700 d -= 6 * working_space[ssize + j - (
Int_t) (2 * ai)] / 20;
701 d += 15 * working_space[ssize + j - (
Int_t) ai] / 20;
702 d += 15 * working_space[ssize + j + (
Int_t) ai] / 20;
703 d -= 6 * working_space[ssize + j + (
Int_t) (2 * ai)] / 20;
704 d += working_space[ssize + j + (
Int_t) (3 * ai)] / 20;
711 working_space[j] =
a;
714 else if (smoothing ==
kTRUE){
715 a = working_space[ssize + j];
718 for (
w = j - bw;
w <= j + bw;
w++){
719 if (
w >= 0 &&
w < ssize){
720 av += working_space[ssize +
w];
727 for (
w = j - i - bw;
w <= j - i + bw;
w++){
728 if (
w >= 0 &&
w < ssize){
729 b += working_space[ssize +
w];
736 for (
w = j + i - bw;
w <= j + i + bw;
w++){
737 if (
w >= 0 &&
w < ssize){
738 c += working_space[ssize +
w];
746 for (
w = j - (
Int_t)(2 * ai) - bw;
w <= j - (
Int_t)(2 * ai) + bw;
w++){
747 if (
w >= 0 &&
w < ssize){
748 b4 += working_space[ssize +
w];
755 if (
w >= 0 &&
w < ssize){
756 c4 += working_space[ssize +
w];
763 if (
w >= 0 &&
w < ssize){
764 d4 += working_space[ssize +
w];
770 for (
w = j + (
Int_t)(2 * ai) - bw;
w <= j + (
Int_t)(2 * ai) + bw;
w++){
771 if (
w >= 0 &&
w < ssize){
772 e4 += working_space[ssize +
w];
777 b4 = (-b4 + 4 * c4 + 4 * d4 - e4) / 6;
780 for (
w = j - (
Int_t)(3 * ai) - bw;
w <= j - (
Int_t)(3 * ai) + bw;
w++){
781 if (
w >= 0 &&
w < ssize){
782 b6 += working_space[ssize +
w];
788 for (
w = j - (
Int_t)(2 * ai) - bw;
w <= j - (
Int_t)(2 * ai) + bw;
w++){
789 if (
w >= 0 &&
w < ssize){
790 c6 += working_space[ssize +
w];
797 if (
w >= 0 &&
w < ssize){
798 d6 += working_space[ssize +
w];
805 if (
w >= 0 &&
w < ssize){
806 e6 += working_space[ssize +
w];
812 for (
w = j + (
Int_t)(2 * ai) - bw;
w <= j + (
Int_t)(2 * ai) + bw;
w++){
813 if (
w >= 0 &&
w < ssize){
814 f6 += working_space[ssize +
w];
820 for (
w = j + (
Int_t)(3 * ai) - bw;
w <= j + (
Int_t)(3 * ai) + bw;
w++){
821 if (
w >= 0 &&
w < ssize){
822 g6 += working_space[ssize +
w];
827 b6 = (b6 - 6 * c6 + 15 * d6 + 15 * e6 - 6 * f6 + g6) / 20;
837 for (j = i; j < ssize - i; j++)
838 working_space[ssize + j] = working_space[j];
848 for (j = i; j < ssize - i; j++) {
850 a = working_space[ssize + j];
851 b = (working_space[ssize + j - i] + working_space[ssize + j + i]) / 2.0;
854 c -= working_space[ssize + j - (
Int_t) (2 * ai)] / 6;
855 c += 4 * working_space[ssize + j - (
Int_t) ai] / 6;
856 c += 4 * working_space[ssize + j + (
Int_t) ai] / 6;
857 c -= working_space[ssize + j + (
Int_t) (2 * ai)] / 6;
860 d += working_space[ssize + j - (
Int_t) (3 * ai)] / 20;
861 d -= 6 * working_space[ssize + j - (
Int_t) (2 * ai)] / 20;
862 d += 15 * working_space[ssize + j - (
Int_t) ai] / 20;
863 d += 15 * working_space[ssize + j + (
Int_t) ai] / 20;
864 d -= 6 * working_space[ssize + j + (
Int_t) (2 * ai)] / 20;
865 d += working_space[ssize + j + (
Int_t) (3 * ai)] / 20;
868 e -= working_space[ssize + j - (
Int_t) (4 * ai)] / 70;
869 e += 8 * working_space[ssize + j - (
Int_t) (3 * ai)] / 70;
870 e -= 28 * working_space[ssize + j - (
Int_t) (2 * ai)] / 70;
871 e += 56 * working_space[ssize + j - (
Int_t) ai] / 70;
872 e += 56 * working_space[ssize + j + (
Int_t) ai] / 70;
873 e -= 28 * working_space[ssize + j + (
Int_t) (2 * ai)] / 70;
874 e += 8 * working_space[ssize + j + (
Int_t) (3 * ai)] / 70;
875 e -= working_space[ssize + j + (
Int_t) (4 * ai)] / 70;
884 working_space[j] =
a;
887 else if (smoothing ==
kTRUE){
888 a = working_space[ssize + j];
891 for (
w = j - bw;
w <= j + bw;
w++){
892 if (
w >= 0 &&
w < ssize){
893 av += working_space[ssize +
w];
900 for (
w = j - i - bw;
w <= j - i + bw;
w++){
901 if (
w >= 0 &&
w < ssize){
902 b += working_space[ssize +
w];
909 for (
w = j + i - bw;
w <= j + i + bw;
w++){
910 if (
w >= 0 &&
w < ssize){
911 c += working_space[ssize +
w];
919 for (
w = j - (
Int_t)(2 * ai) - bw;
w <= j - (
Int_t)(2 * ai) + bw;
w++){
920 if (
w >= 0 &&
w < ssize){
921 b4 += working_space[ssize +
w];
928 if (
w >= 0 &&
w < ssize){
929 c4 += working_space[ssize +
w];
936 if (
w >= 0 &&
w < ssize){
937 d4 += working_space[ssize +
w];
943 for (
w = j + (
Int_t)(2 * ai) - bw;
w <= j + (
Int_t)(2 * ai) + bw;
w++){
944 if (
w >= 0 &&
w < ssize){
945 e4 += working_space[ssize +
w];
950 b4 = (-b4 + 4 * c4 + 4 * d4 - e4) / 6;
953 for (
w = j - (
Int_t)(3 * ai) - bw;
w <= j - (
Int_t)(3 * ai) + bw;
w++){
954 if (
w >= 0 &&
w < ssize){
955 b6 += working_space[ssize +
w];
961 for (
w = j - (
Int_t)(2 * ai) - bw;
w <= j - (
Int_t)(2 * ai) + bw;
w++){
962 if (
w >= 0 &&
w < ssize){
963 c6 += working_space[ssize +
w];
970 if (
w >= 0 &&
w < ssize){
971 d6 += working_space[ssize +
w];
978 if (
w >= 0 &&
w < ssize){
979 e6 += working_space[ssize +
w];
985 for (
w = j + (
Int_t)(2 * ai) - bw;
w <= j + (
Int_t)(2 * ai) + bw;
w++){
986 if (
w >= 0 &&
w < ssize){
987 f6 += working_space[ssize +
w];
993 for (
w = j + (
Int_t)(3 * ai) - bw;
w <= j + (
Int_t)(3 * ai) + bw;
w++){
994 if (
w >= 0 &&
w < ssize){
995 g6 += working_space[ssize +
w];
1000 b6 = (b6 - 6 * c6 + 15 * d6 + 15 * e6 - 6 * f6 + g6) / 20;
1003 for (
w = j - (
Int_t)(4 * ai) - bw;
w <= j - (
Int_t)(4 * ai) + bw;
w++){
1004 if (
w >= 0 &&
w < ssize){
1005 b8 += working_space[ssize +
w];
1011 for (
w = j - (
Int_t)(3 * ai) - bw;
w <= j - (
Int_t)(3 * ai) + bw;
w++){
1012 if (
w >= 0 &&
w < ssize){
1013 c8 += working_space[ssize +
w];
1019 for (
w = j - (
Int_t)(2 * ai) - bw;
w <= j - (
Int_t)(2 * ai) + bw;
w++){
1020 if (
w >= 0 &&
w < ssize){
1021 d8 += working_space[ssize +
w];
1028 if (
w >= 0 &&
w < ssize){
1029 e8 += working_space[ssize +
w];
1036 if (
w >= 0 &&
w < ssize){
1037 f8 += working_space[ssize +
w];
1043 for (
w = j + (
Int_t)(2 * ai) - bw;
w <= j + (
Int_t)(2 * ai) + bw;
w++){
1044 if (
w >= 0 &&
w < ssize){
1045 g8 += working_space[ssize +
w];
1051 for (
w = j + (
Int_t)(3 * ai) - bw;
w <= j + (
Int_t)(3 * ai) + bw;
w++){
1052 if (
w >= 0 &&
w < ssize){
1053 h8 += working_space[ssize +
w];
1059 for (
w = j + (
Int_t)(4 * ai) - bw;
w <= j + (
Int_t)(4 * ai) + bw;
w++){
1060 if (
w >= 0 &&
w < ssize){
1061 i8 += working_space[ssize +
w];
1066 b8 = ( -b8 + 8 * c8 - 28 * d8 + 56 * e8 - 56 * f8 - 28 * g8 + 8 * h8 - i8)/70;
1075 working_space[j]=av;
1078 for (j = i; j < ssize - i; j++)
1079 working_space[ssize + j] = working_space[j];
1087 if (compton ==
kTRUE) {
1088 for (i = 0, b2 = 0; i < ssize; i++){
1090 a = working_space[i],
b = spectrum[i];
1096 yb1 = working_space[b1];
1097 for (b2 = b1 + 1,
c = 0, priz = 0; priz == 0 && b2 < ssize; b2++){
1098 a = working_space[b2],
b = spectrum[b2];
1107 yb2 = working_space[b2];
1109 for (j = b1,
c = 0; j <= b2; j++){
1114 c = (yb2 - yb1) /
c;
1115 for (j = b1,
d = 0; j <= b2 && j < ssize; j++){
1119 working_space[ssize + j] =
a;
1125 for (j = b2,
c = 0; j >= b1; j--){
1130 c = (yb1 - yb2) /
c;
1131 for (j = b2,
d = 0;j >= b1 && j >= 0; j--){
1135 working_space[ssize + j] =
a;
1144 for (j = 0; j < ssize; j++)
1145 spectrum[j] = working_space[ssize + j];
1146 delete[]working_space;
1192 Double_t nom, nip, nim, sp, sm, area = 0;
1194 return "Averaging Window must be positive";
1197 for(i = 0, maxch = 0; i < ssize; i++){
1199 if(maxch < source[i])
1205 delete [] working_space;
1210 working_space[
xmin] = 1;
1212 nip = source[i] / maxch;
1213 nim = source[i + 1] / maxch;
1215 for(
l = 1;
l <= averWindow;
l++){
1217 a = source[
xmax] / maxch;
1220 a = source[i +
l] / maxch;
1230 if((i -
l + 1) <
xmin)
1231 a = source[
xmin] / maxch;
1234 a = source[i -
l + 1] / maxch;
1245 a = working_space[i + 1] = working_space[i] *
a;
1249 working_space[i] = working_space[i] / nom;
1251 for(i = 0; i < ssize; i++)
1252 source[i] = working_space[i] * area;
1253 delete[]working_space;
1453 int ssize,
int numberIterations,
1454 int numberRepetitions,
Double_t boost )
1457 return "Wrong Parameters";
1459 if (numberRepetitions <= 0)
1460 return "Wrong Parameters";
1465 int i, j, k, lindex, posit, lh_gold,
l, repet;
1466 Double_t lda, ldb, ldc, area, maximum;
1473 for (i = 0; i < ssize; i++) {
1477 working_space[i] = lda;
1479 if (lda > maximum) {
1484 if (lh_gold == -1) {
1485 delete [] working_space;
1486 return "ZERO RESPONSE VECTOR";
1490 for (i = 0; i < ssize; i++)
1491 working_space[2 * ssize + i] = source[i];
1494 for (i = 0; i < ssize; i++){
1496 for (j = 0; j < ssize; j++){
1497 ldb = working_space[j];
1500 ldc = working_space[k];
1501 lda = lda + ldb * ldc;
1504 working_space[ssize + i] = lda;
1506 for (k = 0; k < ssize; k++){
1509 ldb = working_space[
l];
1510 ldc = working_space[2 * ssize + k];
1511 lda = lda + ldb * ldc;
1514 working_space[3 * ssize + i]=lda;
1518 for (i = 0; i < ssize; i++){
1519 working_space[2 * ssize + i] = working_space[3 * ssize + i];
1523 for (i = 0; i < ssize; i++)
1524 working_space[i] = 1;
1527 for (repet = 0; repet < numberRepetitions; repet++) {
1529 for (i = 0; i < ssize; i++)
1530 working_space[i] =
TMath::Power(working_space[i], boost);
1532 for (lindex = 0; lindex < numberIterations; lindex++) {
1533 for (i = 0; i < ssize; i++) {
1534 if (working_space[2 * ssize + i] > 0.000001
1535 && working_space[i] > 0.000001) {
1537 for (j = 0; j < lh_gold; j++) {
1538 ldb = working_space[j + ssize];
1543 ldc = working_space[k];
1546 ldc += working_space[k];
1550 ldc = working_space[i];
1551 lda = lda + ldb * ldc;
1553 ldb = working_space[2 * ssize + i];
1559 ldb = working_space[i];
1561 working_space[3 * ssize + i] = lda;
1564 for (i = 0; i < ssize; i++)
1565 working_space[i] = working_space[3 * ssize + i];
1570 for (i = 0; i < ssize; i++) {
1571 lda = working_space[i];
1574 working_space[ssize + j] = lda;
1578 for (i = 0; i < ssize; i++)
1579 source[i] = area * working_space[ssize + i];
1580 delete[]working_space;
1659 int ssize,
int numberIterations,
1660 int numberRepetitions,
Double_t boost )
1663 return "Wrong Parameters";
1665 if (numberRepetitions <= 0)
1666 return "Wrong Parameters";
1671 int i, j, k, lindex, posit, lh_gold, repet, kmin, kmax;
1678 for (i = 0; i < ssize; i++) {
1682 working_space[ssize + i] = lda;
1683 if (lda > maximum) {
1688 if (lh_gold == -1) {
1689 delete [] working_space;
1690 return "ZERO RESPONSE VECTOR";
1694 for (i = 0; i < ssize; i++)
1695 working_space[2 * ssize + i] = source[i];
1698 for (i = 0; i < ssize; i++){
1699 if (i <= ssize - lh_gold)
1700 working_space[i] = 1;
1703 working_space[i] = 0;
1707 for (repet = 0; repet < numberRepetitions; repet++) {
1709 for (i = 0; i < ssize; i++)
1710 working_space[i] =
TMath::Power(working_space[i], boost);
1712 for (lindex = 0; lindex < numberIterations; lindex++) {
1713 for (i = 0; i <= ssize - lh_gold; i++){
1715 if (working_space[i] > 0){
1716 for (j = i; j < i + lh_gold; j++){
1717 ldb = working_space[2 * ssize + j];
1721 if (kmax > lh_gold - 1)
1723 kmin = j + lh_gold - ssize;
1727 for (k = kmax; k >= kmin; k--){
1728 ldc += working_space[ssize + k] * working_space[j - k];
1736 ldb = ldb * working_space[ssize + j - i];
1740 lda = lda * working_space[i];
1742 working_space[3 * ssize + i] = lda;
1744 for (i = 0; i < ssize; i++)
1745 working_space[i] = working_space[3 * ssize + i];
1750 for (i = 0; i < ssize; i++) {
1751 lda = working_space[i];
1754 working_space[ssize + j] = lda;
1758 for (i = 0; i < ssize; i++)
1759 source[i] = working_space[ssize + i];
1760 delete[]working_space;
1884 int ssizex,
int ssizey,
1885 int numberIterations,
1886 int numberRepetitions,
Double_t boost)
1888 int i, j, k, lindex, lhx = 0, repet;
1890 if (ssizex <= 0 || ssizey <= 0)
1891 return "Wrong Parameters";
1892 if (ssizex < ssizey)
1893 return "Sizex must be greater than sizey)";
1894 if (numberIterations <= 0)
1895 return "Number of iterations must be positive";
1897 new Double_t[ssizex * ssizey + 2 * ssizey * ssizey + 4 * ssizex];
1900 for (j = 0; j < ssizey && lhx != -1; j++) {
1903 for (i = 0; i < ssizex; i++) {
1904 lda = respMatrix[j][i];
1908 working_space[j * ssizex + i] = lda;
1912 for (i = 0; i < ssizex; i++)
1913 working_space[j * ssizex + i] /= area;
1917 delete [] working_space;
1918 return (
"ZERO COLUMN IN RESPONSE MATRIX");
1922 for (i = 0; i < ssizex; i++)
1923 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 2 * ssizex + i] =
1927 for (i = 0; i < ssizey; i++) {
1928 for (j = 0; j < ssizey; j++) {
1930 for (k = 0; k < ssizex; k++) {
1931 ldb = working_space[ssizex * i + k];
1932 ldc = working_space[ssizex * j + k];
1933 lda = lda + ldb * ldc;
1935 working_space[ssizex * ssizey + ssizey * i + j] = lda;
1938 for (k = 0; k < ssizex; k++) {
1939 ldb = working_space[ssizex * i + k];
1941 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 2 * ssizex +
1943 lda = lda + ldb * ldc;
1945 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 3 * ssizex + i] =
1950 for (i = 0; i < ssizey; i++)
1951 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 2 * ssizex + i] =
1952 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 3 * ssizex + i];
1955 for (i = 0; i < ssizey; i++) {
1956 for (j = 0; j < ssizey; j++) {
1958 for (k = 0; k < ssizey; k++) {
1959 ldb = working_space[ssizex * ssizey + ssizey * i + k];
1960 ldc = working_space[ssizex * ssizey + ssizey * j + k];
1961 lda = lda + ldb * ldc;
1963 working_space[ssizex * ssizey + ssizey * ssizey + ssizey * i + j] =
1967 for (k = 0; k < ssizey; k++) {
1968 ldb = working_space[ssizex * ssizey + ssizey * i + k];
1970 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 2 * ssizex +
1972 lda = lda + ldb * ldc;
1974 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 3 * ssizex + i] =
1979 for (i = 0; i < ssizey; i++)
1980 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 2 * ssizex + i] =
1981 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 3 * ssizex + i];
1984 for (i = 0; i < ssizey; i++)
1985 working_space[ssizex * ssizey + 2 * ssizey * ssizey + i] = 1;
1988 for (repet = 0; repet < numberRepetitions; repet++) {
1990 for (i = 0; i < ssizey; i++)
1991 working_space[ssizex * ssizey + 2 * ssizey * ssizey + i] =
TMath::Power(working_space[ssizex * ssizey + 2 * ssizey * ssizey + i], boost);
1993 for (lindex = 0; lindex < numberIterations; lindex++) {
1994 for (i = 0; i < ssizey; i++) {
1996 for (j = 0; j < ssizey; j++) {
1998 working_space[ssizex * ssizey + ssizey * ssizey + ssizey * i + j];
1999 ldc = working_space[ssizex * ssizey + 2 * ssizey * ssizey + j];
2000 lda = lda + ldb * ldc;
2003 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 2 * ssizex + i];
2010 ldb = working_space[ssizex * ssizey + 2 * ssizey * ssizey + i];
2012 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 3 * ssizex + i] = lda;
2014 for (i = 0; i < ssizey; i++)
2015 working_space[ssizex * ssizey + 2 * ssizey * ssizey + i] =
2016 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 3 * ssizex + i];
2021 for (i = 0; i < ssizex; i++) {
2023 source[i] = working_space[ssizex * ssizey + 2 * ssizey * ssizey + i];
2028 delete[]working_space;
2121 bool backgroundRemove,
int deconIterations,
2122 bool markov,
int averWindow)
2124 int i, j, numberIterations = (
Int_t)(7 *
sigma + 0.5);
2126 int k, lindex, posit, imin, imax, jmin, jmax, lh_gold, priz;
2127 Double_t lda, ldb, ldc, area, maximum, maximum_decon;
2128 int xmin,
xmax,
l, peak_index = 0, size_ext = ssize + 2 * numberIterations, shift = numberIterations, bw = 2,
w;
2130 Double_t nom, nip, nim, sp, sm, plocha = 0;
2131 Double_t m0low=0,m1low=0,m2low=0,l0low=0,l1low=0,detlow,av,men;
2133 Error(
"SearchHighRes",
"Invalid sigma, must be greater than or equal to 1");
2137 if(threshold<=0 || threshold>=100){
2138 Error(
"SearchHighRes",
"Invalid threshold, must be positive and less than 100");
2144 Error(
"SearchHighRes",
"Too large sigma");
2148 if (markov ==
true) {
2149 if (averWindow <= 0) {
2150 Error(
"SearchHighRes",
"Averaging window must be positive");
2155 if(backgroundRemove ==
true){
2156 if(ssize < 2 * numberIterations + 1){
2157 Error(
"SearchHighRes",
"Too large clipping window");
2164 for(i = 0;i < k;i++){
2165 a = i,
b = source[i];
2166 m0low += 1,m1low +=
a,m2low +=
a *
a,l0low +=
b,l1low +=
a *
b;
2168 detlow = m0low * m2low - m1low * m1low;
2170 l1low = (-l0low * m1low + l1low * m0low) / detlow;
2185 for (j=0;j<7 * (ssize + i);j++) working_space[j] = 0;
2186 for(i = 0; i < size_ext; i++){
2189 working_space[i + size_ext] = source[0] + l1low *
a;
2190 if(working_space[i + size_ext] < 0)
2191 working_space[i + size_ext]=0;
2194 else if(i >= ssize + shift){
2195 a = i - (ssize - 1 + shift);
2196 working_space[i + size_ext] = source[ssize - 1];
2197 if(working_space[i + size_ext] < 0)
2198 working_space[i + size_ext]=0;
2202 working_space[i + size_ext] = source[i - shift];
2205 if(backgroundRemove ==
true){
2206 for(i = 1; i <= numberIterations; i++){
2207 for(j = i; j < size_ext - i; j++){
2208 if(markov ==
false){
2209 a = working_space[size_ext + j];
2210 b = (working_space[size_ext + j - i] + working_space[size_ext + j + i]) / 2.0;
2218 a = working_space[size_ext + j];
2221 for (
w = j - bw;
w <= j + bw;
w++){
2222 if (
w >= 0 &&
w < size_ext){
2223 av += working_space[size_ext +
w];
2230 for (
w = j - i - bw;
w <= j - i + bw;
w++){
2231 if (
w >= 0 &&
w < size_ext){
2232 b += working_space[size_ext +
w];
2239 for (
w = j + i - bw;
w <= j + i + bw;
w++){
2240 if (
w >= 0 &&
w < size_ext){
2241 c += working_space[size_ext +
w];
2249 working_space[j]=av;
2252 for(j = i; j < size_ext - i; j++)
2253 working_space[size_ext + j] = working_space[j];
2255 for(j = 0;j < size_ext; j++){
2258 b = source[0] + l1low *
a;
2260 working_space[size_ext + j] =
b - working_space[size_ext + j];
2263 else if(j >= ssize + shift){
2264 a = j - (ssize - 1 + shift);
2265 b = source[ssize - 1];
2267 working_space[size_ext + j] =
b - working_space[size_ext + j];
2271 working_space[size_ext + j] = source[j - shift] - working_space[size_ext + j];
2274 for(j = 0;j < size_ext; j++){
2275 if(working_space[size_ext + j] < 0) working_space[size_ext + j] = 0;
2279 for(i = 0; i < size_ext; i++){
2280 working_space[i + 6*size_ext] = working_space[i + size_ext];
2284 for(j = 0; j < size_ext; j++)
2285 working_space[2 * size_ext + j] = working_space[size_ext + j];
2287 for(i = 0, maxch = 0; i < size_ext; i++){
2288 working_space[i] = 0;
2289 if(maxch < working_space[2 * size_ext + i])
2290 maxch = working_space[2 * size_ext + i];
2291 plocha += working_space[2 * size_ext + i];
2294 delete [] working_space;
2299 working_space[
xmin] = 1;
2301 nip = working_space[2 * size_ext + i] / maxch;
2302 nim = working_space[2 * size_ext + i + 1] / maxch;
2304 for(
l = 1;
l <= averWindow;
l++){
2306 a = working_space[2 * size_ext +
xmax] / maxch;
2309 a = working_space[2 * size_ext + i +
l] / maxch;
2321 if((i -
l + 1) <
xmin)
2322 a = working_space[2 * size_ext +
xmin] / maxch;
2325 a = working_space[2 * size_ext + i -
l + 1] / maxch;
2339 a = working_space[i + 1] = working_space[i] *
a;
2343 working_space[i] = working_space[i] / nom;
2345 for(j = 0; j < size_ext; j++)
2346 working_space[size_ext + j] = working_space[j] * plocha;
2347 for(j = 0; j < size_ext; j++){
2348 working_space[2 * size_ext + j] = working_space[size_ext + j];
2350 if(backgroundRemove ==
true){
2351 for(i = 1; i <= numberIterations; i++){
2352 for(j = i; j < size_ext - i; j++){
2353 a = working_space[size_ext + j];
2354 b = (working_space[size_ext + j - i] + working_space[size_ext + j + i]) / 2.0;
2357 working_space[j] =
a;
2359 for(j = i; j < size_ext - i; j++)
2360 working_space[size_ext + j] = working_space[j];
2362 for(j = 0; j < size_ext; j++){
2363 working_space[size_ext + j] = working_space[2 * size_ext + j] - working_space[size_ext + j];
2373 for(i = 0; i < size_ext; i++){
2381 working_space[i] = lda;
2389 for(i = 0; i < size_ext; i++)
2390 working_space[2 * size_ext + i] =
TMath::Abs(working_space[size_ext + i]);
2397 for(i = imin; i <= imax; i++){
2402 jmax = lh_gold - 1 - i;
2403 if(jmax > (lh_gold - 1))
2406 for(j = jmin;j <= jmax; j++){
2407 ldb = working_space[j];
2408 ldc = working_space[i + j];
2409 lda = lda + ldb * ldc;
2411 working_space[size_ext + i - imin] = lda;
2415 imin = -i,imax = size_ext + i - 1;
2416 for(i = imin; i <= imax; i++){
2418 for(j = 0; j <= (lh_gold - 1); j++){
2419 ldb = working_space[j];
2421 if(k >= 0 && k < size_ext){
2422 ldc = working_space[2 * size_ext + k];
2423 lda = lda + ldb * ldc;
2427 working_space[4 * size_ext + i - imin] = lda;
2430 for(i = imin; i <= imax; i++)
2431 working_space[2 * size_ext + i - imin] = working_space[4 * size_ext + i - imin];
2433 for(i = 0; i < size_ext; i++)
2434 working_space[i] = 1;
2436 for(lindex = 0; lindex < deconIterations; lindex++){
2437 for(i = 0; i < size_ext; i++){
2438 if(
TMath::Abs(working_space[2 * size_ext + i]) > 0.00001 &&
TMath::Abs(working_space[i]) > 0.00001){
2446 if(jmax > (size_ext - 1 - i))
2449 for(j = jmin; j <= jmax; j++){
2450 ldb = working_space[j + lh_gold - 1 + size_ext];
2451 ldc = working_space[i + j];
2452 lda = lda + ldb * ldc;
2454 ldb = working_space[2 * size_ext + i];
2461 ldb = working_space[i];
2463 working_space[3 * size_ext + i] = lda;
2466 for(i = 0; i < size_ext; i++){
2467 working_space[i] = working_space[3 * size_ext + i];
2471 for(i=0;i<size_ext;i++){
2472 lda = working_space[i];
2475 working_space[size_ext + j] = lda;
2478 maximum = 0, maximum_decon = 0;
2480 for(i = 0; i < size_ext - j; i++){
2481 if(i >= shift && i < ssize + shift){
2482 working_space[i] = area * working_space[size_ext + i + j];
2483 if(maximum_decon < working_space[i])
2484 maximum_decon = working_space[i];
2485 if(maximum < working_space[6 * size_ext + i])
2486 maximum = working_space[6 * size_ext + i];
2490 working_space[i] = 0;
2498 for(i = 1; i < size_ext - 1; i++){
2499 if(working_space[i] > working_space[i - 1] && working_space[i] > working_space[i + 1]){
2500 if(i >= shift && i < ssize + shift){
2501 if(working_space[i] > lda*maximum_decon && working_space[6 * size_ext + i] > threshold * maximum / 100.0){
2502 for(j = i - 1,
a = 0,
b = 0; j <= i + 1; j++){
2503 a += (
Double_t)(j - shift) * working_space[j];
2504 b += working_space[j];
2512 if(peak_index == 0){
2518 for(j = 0, priz = 0; j < peak_index && priz == 0; j++){
2519 if(working_space[6 * size_ext + shift + (
Int_t)
a] > working_space[6 * size_ext + shift + (
Int_t)
fPositionX[j]])
2529 for(k = peak_index; k >= j; k--){
2544 for(i = 0; i < ssize; i++) destVector[i] = working_space[i + shift];
2545 delete [] working_space;
2548 Warning(
"SearchHighRes",
"Peak buffer full");
2558 bool backgroundRemove,
int deconIterations,
2559 bool markov,
int averWindow)
2564 deconIterations,markov,averWindow);
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t dest
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.
TObject * Clone(const char *newname="") const override
Make a complete copy of the underlying object.
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.
The TNamed class is the base class for all named ROOT classes.
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.
Advanced Spectra Processing.
Double_t fResolution
NOT USED resolution of the neighboring peaks
static TH1 * StaticBackground(const TH1 *hist, Int_t niter=20, Option_t *option="")
Static function, interface to TSpectrum::Background.
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)
One-dimensional markov spectrum smoothing function.
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)
One-dimensional unfolding function.
void SetResolution(Double_t resolution=1)
NOT USED resolution: determines resolution of the neighbouring peaks default value is 1 correspond to...
virtual TH1 * Background(const TH1 *hist, Int_t niter=20, Option_t *option="")
One-dimensional background estimation function.
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)
One-dimensional high-resolution peak search function.
virtual Int_t Search(const TH1 *hist, Double_t sigma=2, Option_t *option="", Double_t threshold=0.05)
One-dimensional peak search function.
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)
Old name of SearcHighRes introduced for back compatibility.
const char * Deconvolution(Double_t *source, const Double_t *response, Int_t ssize, Int_t numberIterations, Int_t numberRepetitions, Double_t boost)
One-dimensional deconvolution function.
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)
One-dimensional deconvolution function.
static Int_t fgIterations
Maximum number of decon iterations (default=3)
TH1 * fHistogram
resulting histogram
~TSpectrum() override
Destructor.
static Int_t StaticSearch(const TH1 *hist, Double_t sigma=2, Option_t *option="goff", Double_t threshold=0.05)
Static function, interface to TSpectrum::Search.
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.