75#define PEAK_WINDOW 1024
104 :TNamed(
"Spectrum",
"Miroslav Morhac peak finder")
117 Int_t n = maxpositions;
216 if (h == 0)
return 0;
217 Int_t dimension = h->GetDimension();
219 Error(
"Search",
"Only implemented for 1-d histograms");
222 TString opt = option;
229 if (opt.Contains(
"backorder4")) filterOrder =
kBackOrder4;
230 if (opt.Contains(
"backorder6")) filterOrder =
kBackOrder6;
231 if (opt.Contains(
"backorder8")) filterOrder =
kBackOrder8;
232 Bool_t smoothing = kTRUE;
233 if (opt.Contains(
"nosmoothing")) smoothing = kFALSE;
241 Bool_t compton = kFALSE;
242 if (opt.Contains(
"compton")) compton = kTRUE;
244 Int_t first = h->GetXaxis()->GetFirst();
245 Int_t last = h->GetXaxis()->GetLast();
246 Int_t size = last-first+1;
248 Float_t * source =
new float[size];
249 for (i = 0; i < size; i++) source[i] = h->GetBinContent(i + first);
252 Background(source,size,numberIterations, direction, filterOrder,smoothing,
253 smoothWindow,compton);
257 Int_t nch = strlen(h->GetName());
258 char *hbname =
new char[nch+20];
259 snprintf(hbname,nch+20,
"%s_background",h->GetName());
260 TH1 *hb = (TH1*)h->Clone(hbname);
262 hb->GetListOfFunctions()->Delete();
264 for (i=0; i< size; i++) hb->SetBinContent(i+first,source[i]);
265 hb->SetEntries(size);
268 if (opt.Contains(
"same")) {
269 if (gPad)
delete gPad->GetPrimitive(hbname);
287 printf(
"\nNumber of positions = %d\n",
fNPeaks);
288 for (Int_t i=0;i<
fNPeaks;i++) {
338 if (hin == 0)
return 0;
339 Int_t dimension = hin->GetDimension();
341 Error(
"Search",
"Only implemented for 1-d and 2-d histograms");
344 if (threshold <=0 || threshold >= 1) {
345 Warning(
"Search",
"threshold must 0<threshold<1, threshol=0.05 assumed");
348 TString opt = option;
350 Bool_t background = kTRUE;
351 if (opt.Contains(
"nobackground")) {
353 opt.ReplaceAll(
"nobackground",
"");
355 Bool_t markov = kTRUE;
356 if (opt.Contains(
"nomarkov")) {
358 opt.ReplaceAll(
"nomarkov",
"");
361 if (opt.Contains(
"nodraw")) {
363 opt.ReplaceAll(
"nodraw",
"");
365 if (dimension == 1) {
366 Int_t first = hin->GetXaxis()->GetFirst();
367 Int_t last = hin->GetXaxis()->GetLast();
368 Int_t size = last-first+1;
369 Int_t i, bin, npeaks;
370 Float_t * source =
new float[size];
371 Float_t * dest =
new float[size];
372 for (i = 0; i < size; i++) source[i] = hin->GetBinContent(i + first);
375 if (sigma < 1) sigma = 1;
376 if (sigma > 8) sigma = 8;
378 npeaks =
SearchHighRes(source, dest, size, sigma, 100*threshold,
381 for (i = 0; i < npeaks; i++) {
389 if (opt.Contains(
"goff"))
391 if (!npeaks)
return 0;
393 (TPolyMarker*)hin->GetListOfFunctions()->FindObject(
"TPolyMarker");
395 hin->GetListOfFunctions()->Remove(pm);
399 hin->GetListOfFunctions()->Add(pm);
400 pm->SetMarkerStyle(23);
401 pm->SetMarkerColor(kRed);
402 pm->SetMarkerSize(1.3);
403 opt.ReplaceAll(
" ",
"");
404 opt.ReplaceAll(
",",
"");
406 ((TH1*)hin)->Draw(opt.Data());
435 int numberIterations,
436 int direction,
int filterOrder,
437 bool smoothing,
int smoothWindow,
875 int i, j, w, bw, b1, b2, priz;
876 float 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;
878 return "Wrong Parameters";
879 if (numberIterations < 1)
880 return "Width of Clipping Window Must Be Positive";
881 if (ssize < 2 * numberIterations + 1)
882 return "Too Large Clipping Window";
884 return "Incorrect width of smoothing window";
885 float *working_space =
new float[2 * ssize];
886 for (i = 0; i < ssize; i++){
887 working_space[i] = spectrum[i];
888 working_space[i + ssize] = spectrum[i];
890 bw=(smoothWindow-1)/2;
894 i = numberIterations;
897 for (j = i; j < ssize - i; j++) {
898 if (smoothing == kFALSE){
899 a = working_space[ssize + j];
900 b = (working_space[ssize + j - i] + working_space[ssize + j + i]) / 2.0;
903 working_space[j] = a;
906 else if (smoothing == kTRUE){
907 a = working_space[ssize + j];
910 for (w = j - bw; w <= j + bw; w++){
911 if ( w >= 0 && w < ssize){
912 av += working_space[ssize + w];
919 for (w = j - i - bw; w <= j - i + bw; w++){
920 if ( w >= 0 && w < ssize){
921 b += working_space[ssize + w];
928 for (w = j + i - bw; w <= j + i + bw; w++){
929 if ( w >= 0 && w < ssize){
930 c += working_space[ssize + w];
941 for (j = i; j < ssize - i; j++)
942 working_space[ssize + j] = working_space[j];
952 for (j = i; j < ssize - i; j++) {
953 if (smoothing == kFALSE){
954 a = working_space[ssize + j];
955 b = (working_space[ssize + j - i] + working_space[ssize + j + i]) / 2.0;
958 c -= working_space[ssize + j - (int) (2 * ai)] / 6;
959 c += 4 * working_space[ssize + j - (int) ai] / 6;
960 c += 4 * working_space[ssize + j + (int) ai] / 6;
961 c -= working_space[ssize + j + (int) (2 * ai)] / 6;
966 working_space[j] = a;
969 else if (smoothing == kTRUE){
970 a = working_space[ssize + j];
973 for (w = j - bw; w <= j + bw; w++){
974 if ( w >= 0 && w < ssize){
975 av += working_space[ssize + w];
982 for (w = j - i - bw; w <= j - i + bw; w++){
983 if ( w >= 0 && w < ssize){
984 b += working_space[ssize + w];
991 for (w = j + i - bw; w <= j + i + bw; w++){
992 if ( w >= 0 && w < ssize){
993 c += working_space[ssize + w];
1001 for (w = j - (
int)(2 * ai) - bw; w <= j - (int)(2 * ai) + bw; w++){
1002 if (w >= 0 && w < ssize){
1003 b4 += working_space[ssize + w];
1009 for (w = j - (
int)ai - bw; w <= j - (int)ai + bw; w++){
1010 if (w >= 0 && w < ssize){
1011 c4 += working_space[ssize + w];
1017 for (w = j + (
int)ai - bw; w <= j + (int)ai + bw; w++){
1018 if (w >= 0 && w < ssize){
1019 d4 += working_space[ssize + w];
1025 for (w = j + (
int)(2 * ai) - bw; w <= j + (int)(2 * ai) + bw; w++){
1026 if (w >= 0 && w < ssize){
1027 e4 += working_space[ssize + w];
1032 b4 = (-b4 + 4 * c4 + 4 * d4 - e4) / 6;
1037 working_space[j]=av;
1040 for (j = i; j < ssize - i; j++)
1041 working_space[ssize + j] = working_space[j];
1051 for (j = i; j < ssize - i; j++) {
1052 if (smoothing == kFALSE){
1053 a = working_space[ssize + j];
1054 b = (working_space[ssize + j - i] + working_space[ssize + j + i]) / 2.0;
1057 c -= working_space[ssize + j - (int) (2 * ai)] / 6;
1058 c += 4 * working_space[ssize + j - (int) ai] / 6;
1059 c += 4 * working_space[ssize + j + (int) ai] / 6;
1060 c -= working_space[ssize + j + (int) (2 * ai)] / 6;
1063 d += working_space[ssize + j - (int) (3 * ai)] / 20;
1064 d -= 6 * working_space[ssize + j - (int) (2 * ai)] / 20;
1065 d += 15 * working_space[ssize + j - (int) ai] / 20;
1066 d += 15 * working_space[ssize + j + (int) ai] / 20;
1067 d -= 6 * working_space[ssize + j + (int) (2 * ai)] / 20;
1068 d += working_space[ssize + j + (int) (3 * ai)] / 20;
1075 working_space[j] = a;
1078 else if (smoothing == kTRUE){
1079 a = working_space[ssize + j];
1082 for (w = j - bw; w <= j + bw; w++){
1083 if ( w >= 0 && w < ssize){
1084 av += working_space[ssize + w];
1091 for (w = j - i - bw; w <= j - i + bw; w++){
1092 if ( w >= 0 && w < ssize){
1093 b += working_space[ssize + w];
1100 for (w = j + i - bw; w <= j + i + bw; w++){
1101 if ( w >= 0 && w < ssize){
1102 c += working_space[ssize + w];
1110 for (w = j - (
int)(2 * ai) - bw; w <= j - (int)(2 * ai) + bw; w++){
1111 if (w >= 0 && w < ssize){
1112 b4 += working_space[ssize + w];
1118 for (w = j - (
int)ai - bw; w <= j - (int)ai + bw; w++){
1119 if (w >= 0 && w < ssize){
1120 c4 += working_space[ssize + w];
1126 for (w = j + (
int)ai - bw; w <= j + (int)ai + bw; w++){
1127 if (w >= 0 && w < ssize){
1128 d4 += working_space[ssize + w];
1134 for (w = j + (
int)(2 * ai) - bw; w <= j + (int)(2 * ai) + bw; w++){
1135 if (w >= 0 && w < ssize){
1136 e4 += working_space[ssize + w];
1141 b4 = (-b4 + 4 * c4 + 4 * d4 - e4) / 6;
1144 for (w = j - (
int)(3 * ai) - bw; w <= j - (int)(3 * ai) + bw; w++){
1145 if (w >= 0 && w < ssize){
1146 b6 += working_space[ssize + w];
1152 for (w = j - (
int)(2 * ai) - bw; w <= j - (int)(2 * ai) + bw; w++){
1153 if (w >= 0 && w < ssize){
1154 c6 += working_space[ssize + w];
1160 for (w = j - (
int)ai - bw; w <= j - (int)ai + bw; w++){
1161 if (w >= 0 && w < ssize){
1162 d6 += working_space[ssize + w];
1168 for (w = j + (
int)ai - bw; w <= j + (int)ai + bw; w++){
1169 if (w >= 0 && w < ssize){
1170 e6 += working_space[ssize + w];
1176 for (w = j + (
int)(2 * ai) - bw; w <= j + (int)(2 * ai) + bw; w++){
1177 if (w >= 0 && w < ssize){
1178 f6 += working_space[ssize + w];
1184 for (w = j + (
int)(3 * ai) - bw; w <= j + (int)(3 * ai) + bw; w++){
1185 if (w >= 0 && w < ssize){
1186 g6 += working_space[ssize + w];
1191 b6 = (b6 - 6 * c6 + 15 * d6 + 15 * e6 - 6 * f6 + g6) / 20;
1198 working_space[j]=av;
1201 for (j = i; j < ssize - i; j++)
1202 working_space[ssize + j] = working_space[j];
1212 for (j = i; j < ssize - i; j++) {
1213 if (smoothing == kFALSE){
1214 a = working_space[ssize + j];
1215 b = (working_space[ssize + j - i] + working_space[ssize + j + i]) / 2.0;
1218 c -= working_space[ssize + j - (int) (2 * ai)] / 6;
1219 c += 4 * working_space[ssize + j - (int) ai] / 6;
1220 c += 4 * working_space[ssize + j + (int) ai] / 6;
1221 c -= working_space[ssize + j + (int) (2 * ai)] / 6;
1224 d += working_space[ssize + j - (int) (3 * ai)] / 20;
1225 d -= 6 * working_space[ssize + j - (int) (2 * ai)] / 20;
1226 d += 15 * working_space[ssize + j - (int) ai] / 20;
1227 d += 15 * working_space[ssize + j + (int) ai] / 20;
1228 d -= 6 * working_space[ssize + j + (int) (2 * ai)] / 20;
1229 d += working_space[ssize + j + (int) (3 * ai)] / 20;
1232 e -= working_space[ssize + j - (int) (4 * ai)] / 70;
1233 e += 8 * working_space[ssize + j - (int) (3 * ai)] / 70;
1234 e -= 28 * working_space[ssize + j - (int) (2 * ai)] / 70;
1235 e += 56 * working_space[ssize + j - (int) ai] / 70;
1236 e += 56 * working_space[ssize + j + (int) ai] / 70;
1237 e -= 28 * working_space[ssize + j + (int) (2 * ai)] / 70;
1238 e += 8 * working_space[ssize + j + (int) (3 * ai)] / 70;
1239 e -= working_space[ssize + j + (int) (4 * ai)] / 70;
1248 working_space[j] = a;
1251 else if (smoothing == kTRUE){
1252 a = working_space[ssize + j];
1255 for (w = j - bw; w <= j + bw; w++){
1256 if ( w >= 0 && w < ssize){
1257 av += working_space[ssize + w];
1264 for (w = j - i - bw; w <= j - i + bw; w++){
1265 if ( w >= 0 && w < ssize){
1266 b += working_space[ssize + w];
1273 for (w = j + i - bw; w <= j + i + bw; w++){
1274 if ( w >= 0 && w < ssize){
1275 c += working_space[ssize + w];
1283 for (w = j - (
int)(2 * ai) - bw; w <= j - (int)(2 * ai) + bw; w++){
1284 if (w >= 0 && w < ssize){
1285 b4 += working_space[ssize + w];
1291 for (w = j - (
int)ai - bw; w <= j - (int)ai + bw; w++){
1292 if (w >= 0 && w < ssize){
1293 c4 += working_space[ssize + w];
1299 for (w = j + (
int)ai - bw; w <= j + (int)ai + bw; w++){
1300 if (w >= 0 && w < ssize){
1301 d4 += working_space[ssize + w];
1307 for (w = j + (
int)(2 * ai) - bw; w <= j + (int)(2 * ai) + bw; w++){
1308 if (w >= 0 && w < ssize){
1309 e4 += working_space[ssize + w];
1314 b4 = (-b4 + 4 * c4 + 4 * d4 - e4) / 6;
1317 for (w = j - (
int)(3 * ai) - bw; w <= j - (int)(3 * ai) + bw; w++){
1318 if (w >= 0 && w < ssize){
1319 b6 += working_space[ssize + w];
1325 for (w = j - (
int)(2 * ai) - bw; w <= j - (int)(2 * ai) + bw; w++){
1326 if (w >= 0 && w < ssize){
1327 c6 += working_space[ssize + w];
1333 for (w = j - (
int)ai - bw; w <= j - (int)ai + bw; w++){
1334 if (w >= 0 && w < ssize){
1335 d6 += working_space[ssize + w];
1341 for (w = j + (
int)ai - bw; w <= j + (int)ai + bw; w++){
1342 if (w >= 0 && w < ssize){
1343 e6 += working_space[ssize + w];
1349 for (w = j + (
int)(2 * ai) - bw; w <= j + (int)(2 * ai) + bw; w++){
1350 if (w >= 0 && w < ssize){
1351 f6 += working_space[ssize + w];
1357 for (w = j + (
int)(3 * ai) - bw; w <= j + (int)(3 * ai) + bw; w++){
1358 if (w >= 0 && w < ssize){
1359 g6 += working_space[ssize + w];
1364 b6 = (b6 - 6 * c6 + 15 * d6 + 15 * e6 - 6 * f6 + g6) / 20;
1367 for (w = j - (
int)(4 * ai) - bw; w <= j - (int)(4 * ai) + bw; w++){
1368 if (w >= 0 && w < ssize){
1369 b8 += working_space[ssize + w];
1375 for (w = j - (
int)(3 * ai) - bw; w <= j - (int)(3 * ai) + bw; w++){
1376 if (w >= 0 && w < ssize){
1377 c8 += working_space[ssize + w];
1383 for (w = j - (
int)(2 * ai) - bw; w <= j - (int)(2 * ai) + bw; w++){
1384 if (w >= 0 && w < ssize){
1385 d8 += working_space[ssize + w];
1391 for (w = j - (
int)ai - bw; w <= j - (int)ai + bw; w++){
1392 if (w >= 0 && w < ssize){
1393 e8 += working_space[ssize + w];
1399 for (w = j + (
int)ai - bw; w <= j + (int)ai + bw; w++){
1400 if (w >= 0 && w < ssize){
1401 f8 += working_space[ssize + w];
1407 for (w = j + (
int)(2 * ai) - bw; w <= j + (int)(2 * ai) + bw; w++){
1408 if (w >= 0 && w < ssize){
1409 g8 += working_space[ssize + w];
1415 for (w = j + (
int)(3 * ai) - bw; w <= j + (int)(3 * ai) + bw; w++){
1416 if (w >= 0 && w < ssize){
1417 h8 += working_space[ssize + w];
1423 for (w = j + (
int)(4 * ai) - bw; w <= j + (int)(4 * ai) + bw; w++){
1424 if (w >= 0 && w < ssize){
1425 i8 += working_space[ssize + w];
1430 b8 = ( -b8 + 8 * c8 - 28 * d8 + 56 * e8 - 56 * f8 - 28 * g8 + 8 * h8 - i8)/70;
1439 working_space[j]=av;
1442 for (j = i; j < ssize - i; j++)
1443 working_space[ssize + j] = working_space[j];
1451 if (compton == kTRUE) {
1452 for (i = 0, b2 = 0; i < ssize; i++){
1454 a = working_space[i], b = spectrum[i];
1456 if (TMath::Abs(a - b) >= 1) {
1460 yb1 = working_space[b1];
1461 for (b2 = b1 + 1, c = 0, priz = 0; priz == 0 && b2 < ssize; b2++){
1462 a = working_space[b2], b = spectrum[b2];
1464 if (TMath::Abs(a - b) < 1) {
1471 yb2 = working_space[b2];
1473 for (j = b1, c = 0; j <= b2; j++){
1478 c = (yb2 - yb1) / c;
1479 for (j = b1, d = 0; j <= b2 && j < ssize; j++){
1483 working_space[ssize + j] = a;
1489 for (j = b2, c = 0; j >= b1; j--){
1494 c = (yb1 - yb2) / c;
1495 for (j = b2, d = 0;j >= b1 && j >= 0; j--){
1499 working_space[ssize + j] = a;
1508 for (j = 0; j < ssize; j++)
1509 spectrum[j] = working_space[ssize + j];
1510 delete[]working_space;
1590 int xmin, xmax, i, l;
1592 float nom, nip, nim, sp, sm, area = 0;
1594 return "Averaging Window must be positive";
1595 float *working_space =
new float[ssize];
1596 xmin = 0,xmax = ssize - 1;
1597 for(i = 0, maxch = 0; i < ssize; i++){
1599 if(maxch < source[i])
1605 delete [] working_space;
1610 working_space[xmin] = 1;
1611 for(i = xmin; i < xmax; i++){
1612 nip = source[i] / maxch;
1613 nim = source[i + 1] / maxch;
1615 for(l = 1; l <= averWindow; l++){
1617 a = source[xmax] / maxch;
1620 a = source[i + l] / maxch;
1626 a = TMath::Sqrt(a + nip);
1630 if((i - l + 1) < xmin)
1631 a = source[xmin] / maxch;
1634 a = source[i - l + 1] / maxch;
1639 a = TMath::Sqrt(a + nim);
1645 a = working_space[i + 1] = working_space[i] * a;
1648 for(i = xmin; i <= xmax; i++){
1649 working_space[i] = working_space[i] / nom;
1651 for(i = 0; i < ssize; i++)
1652 source[i] = working_space[i] * area;
1653 delete[]working_space;
1660 int ssize,
int numberIterations,
1661 int numberRepetitions,
double boost )
1934 return "Wrong Parameters";
1936 if (numberRepetitions <= 0)
1937 return "Wrong Parameters";
1941 double *working_space =
new double[4 * ssize];
1942 int i, j, k, lindex, posit, lh_gold, l, repet;
1943 double lda, ldb, ldc, area, maximum;
1950 for (i = 0; i < ssize; i++) {
1954 working_space[i] = lda;
1956 if (lda > maximum) {
1961 if (lh_gold == -1) {
1962 delete [] working_space;
1963 return "ZERO RESPONSE VECTOR";
1967 for (i = 0; i < ssize; i++)
1968 working_space[2 * ssize + i] = source[i];
1971 for (i = 0; i < ssize; i++){
1973 for (j = 0; j < ssize; j++){
1974 ldb = working_space[j];
1977 ldc = working_space[k];
1978 lda = lda + ldb * ldc;
1981 working_space[ssize + i] = lda;
1983 for (k = 0; k < ssize; k++){
1986 ldb = working_space[l];
1987 ldc = working_space[2 * ssize + k];
1988 lda = lda + ldb * ldc;
1991 working_space[3 * ssize + i]=lda;
1995 for (i = 0; i < ssize; i++){
1996 working_space[2 * ssize + i] = working_space[3 * ssize + i];
2000 for (i = 0; i < ssize; i++)
2001 working_space[i] = 1;
2004 for (repet = 0; repet < numberRepetitions; repet++) {
2006 for (i = 0; i < ssize; i++)
2007 working_space[i] = TMath::Power(working_space[i], boost);
2009 for (lindex = 0; lindex < numberIterations; lindex++) {
2010 for (i = 0; i < ssize; i++) {
2011 if (working_space[2 * ssize + i] > 0.000001
2012 && working_space[i] > 0.000001) {
2014 for (j = 0; j < lh_gold; j++) {
2015 ldb = working_space[j + ssize];
2020 ldc = working_space[k];
2023 ldc += working_space[k];
2027 ldc = working_space[i];
2028 lda = lda + ldb * ldc;
2030 ldb = working_space[2 * ssize + i];
2036 ldb = working_space[i];
2038 working_space[3 * ssize + i] = lda;
2041 for (i = 0; i < ssize; i++)
2042 working_space[i] = working_space[3 * ssize + i];
2047 for (i = 0; i < ssize; i++) {
2048 lda = working_space[i];
2051 working_space[ssize + j] = lda;
2055 for (i = 0; i < ssize; i++)
2056 source[i] = area * working_space[ssize + i];
2057 delete[]working_space;
2064 int ssize,
int numberIterations,
2065 int numberRepetitions,
double boost )
2209 return "Wrong Parameters";
2211 if (numberRepetitions <= 0)
2212 return "Wrong Parameters";
2216 double *working_space =
new double[4 * ssize];
2217 int i, j, k, lindex, posit, lh_gold, repet, kmin, kmax;
2218 double lda, ldb, ldc, maximum;
2224 for (i = 0; i < ssize; i++) {
2228 working_space[ssize + i] = lda;
2229 if (lda > maximum) {
2234 if (lh_gold == -1) {
2235 delete [] working_space;
2236 return "ZERO RESPONSE VECTOR";
2240 for (i = 0; i < ssize; i++)
2241 working_space[2 * ssize + i] = source[i];
2244 for (i = 0; i < ssize; i++){
2245 if (i <= ssize - lh_gold)
2246 working_space[i] = 1;
2249 working_space[i] = 0;
2253 for (repet = 0; repet < numberRepetitions; repet++) {
2255 for (i = 0; i < ssize; i++)
2256 working_space[i] = TMath::Power(working_space[i], boost);
2258 for (lindex = 0; lindex < numberIterations; lindex++) {
2259 for (i = 0; i <= ssize - lh_gold; i++){
2261 if (working_space[i] > 0){
2262 for (j = i; j < i + lh_gold; j++){
2263 ldb = working_space[2 * ssize + j];
2267 if (kmax > lh_gold - 1)
2269 kmin = j + lh_gold - ssize;
2273 for (k = kmax; k >= kmin; k--){
2274 ldc += working_space[ssize + k] * working_space[j - k];
2282 ldb = ldb * working_space[ssize + j - i];
2286 lda = lda * working_space[i];
2288 working_space[3 * ssize + i] = lda;
2290 for (i = 0; i < ssize; i++)
2291 working_space[i] = working_space[3 * ssize + i];
2296 for (i = 0; i < ssize; i++) {
2297 lda = working_space[i];
2300 working_space[ssize + j] = lda;
2304 for (i = 0; i < ssize; i++)
2305 source[i] = working_space[ssize + i];
2306 delete[]working_space;
2313 const float **respMatrix,
2314 int ssizex,
int ssizey,
2315 int numberIterations,
2316 int numberRepetitions,
double boost)
2418 int i, j, k, lindex, lhx = 0, repet;
2419 double lda, ldb, ldc, area;
2420 if (ssizex <= 0 || ssizey <= 0)
2421 return "Wrong Parameters";
2422 if (ssizex < ssizey)
2423 return "Sizex must be greater than sizey)";
2424 if (numberIterations <= 0)
2425 return "Number of iterations must be positive";
2426 double *working_space =
2427 new double[ssizex * ssizey + 2 * ssizey * ssizey + 4 * ssizex];
2430 for (j = 0; j < ssizey && lhx != -1; j++) {
2433 for (i = 0; i < ssizex; i++) {
2434 lda = respMatrix[j][i];
2438 working_space[j * ssizex + i] = lda;
2442 for (i = 0; i < ssizex; i++)
2443 working_space[j * ssizex + i] /= area;
2447 delete [] working_space;
2448 return (
"ZERO COLUMN IN RESPONSE MATRIX");
2452 for (i = 0; i < ssizex; i++)
2453 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 2 * ssizex + i] =
2457 for (i = 0; i < ssizey; i++) {
2458 for (j = 0; j < ssizey; j++) {
2460 for (k = 0; k < ssizex; k++) {
2461 ldb = working_space[ssizex * i + k];
2462 ldc = working_space[ssizex * j + k];
2463 lda = lda + ldb * ldc;
2465 working_space[ssizex * ssizey + ssizey * i + j] = lda;
2468 for (k = 0; k < ssizex; k++) {
2469 ldb = working_space[ssizex * i + k];
2471 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 2 * ssizex +
2473 lda = lda + ldb * ldc;
2475 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 3 * ssizex + i] =
2480 for (i = 0; i < ssizey; i++)
2481 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 2 * ssizex + i] =
2482 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 3 * ssizex + i];
2485 for (i = 0; i < ssizey; i++) {
2486 for (j = 0; j < ssizey; j++) {
2488 for (k = 0; k < ssizey; k++) {
2489 ldb = working_space[ssizex * ssizey + ssizey * i + k];
2490 ldc = working_space[ssizex * ssizey + ssizey * j + k];
2491 lda = lda + ldb * ldc;
2493 working_space[ssizex * ssizey + ssizey * ssizey + ssizey * i + j] =
2497 for (k = 0; k < ssizey; k++) {
2498 ldb = working_space[ssizex * ssizey + ssizey * i + k];
2500 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 2 * ssizex +
2502 lda = lda + ldb * ldc;
2504 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 3 * ssizex + i] =
2509 for (i = 0; i < ssizey; i++)
2510 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 2 * ssizex + i] =
2511 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 3 * ssizex + i];
2514 for (i = 0; i < ssizey; i++)
2515 working_space[ssizex * ssizey + 2 * ssizey * ssizey + i] = 1;
2518 for (repet = 0; repet < numberRepetitions; repet++) {
2520 for (i = 0; i < ssizey; i++)
2521 working_space[ssizex * ssizey + 2 * ssizey * ssizey + i] = TMath::Power(working_space[ssizex * ssizey + 2 * ssizey * ssizey + i], boost);
2523 for (lindex = 0; lindex < numberIterations; lindex++) {
2524 for (i = 0; i < ssizey; i++) {
2526 for (j = 0; j < ssizey; j++) {
2528 working_space[ssizex * ssizey + ssizey * ssizey + ssizey * i + j];
2529 ldc = working_space[ssizex * ssizey + 2 * ssizey * ssizey + j];
2530 lda = lda + ldb * ldc;
2533 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 2 * ssizex + i];
2540 ldb = working_space[ssizex * ssizey + 2 * ssizey * ssizey + i];
2542 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 3 * ssizex + i] = lda;
2544 for (i = 0; i < ssizey; i++)
2545 working_space[ssizex * ssizey + 2 * ssizey * ssizey + i] =
2546 working_space[ssizex * ssizey + 2 * ssizey * ssizey + 3 * ssizex + i];
2551 for (i = 0; i < ssizex; i++) {
2553 source[i] = working_space[ssizex * ssizey + 2 * ssizey * ssizey + i];
2558 delete[]working_space;
2565 float sigma,
double threshold,
2566 bool backgroundRemove,
int deconIterations,
2567 bool markov,
int averWindow)
2785 int i, j, numberIterations = (int)(7 * sigma + 0.5);
2787 int k, lindex, posit, imin, imax, jmin, jmax, lh_gold, priz;
2788 double lda, ldb, ldc, area, maximum, maximum_decon;
2789 int xmin, xmax, l, peak_index = 0, size_ext = ssize + 2 * numberIterations, shift = numberIterations, bw = 2, w;
2791 double nom, nip, nim, sp, sm, plocha = 0;
2792 double m0low=0,m1low=0,m2low=0,l0low=0,l1low=0,detlow,av,men;
2794 Error(
"SearchHighRes",
"Invalid sigma, must be greater than or equal to 1");
2798 if(threshold<=0 || threshold>=100){
2799 Error(
"SearchHighRes",
"Invalid threshold, must be positive and less than 100");
2803 j = (int) (5.0 * sigma + 0.5);
2805 Error(
"SearchHighRes",
"Too large sigma");
2809 if (markov ==
true) {
2810 if (averWindow <= 0) {
2811 Error(
"SearchHighRes",
"Averanging window must be positive");
2816 if(backgroundRemove ==
true){
2817 if(ssize < 2 * numberIterations + 1){
2818 Error(
"SearchHighRes",
"Too large clipping window");
2823 k = int(2 * sigma+0.5);
2825 for(i = 0;i < k;i++){
2826 a = i,b = source[i];
2827 m0low += 1,m1low += a,m2low += a * a,l0low += b,l1low += a * b;
2829 detlow = m0low * m2low - m1low * m1low;
2831 l1low = (-l0low * m1low + l1low * m0low) / detlow;
2843 i = (int)(7 * sigma + 0.5);
2845 double *working_space =
new double [7 * (ssize + i)];
2846 for (j=0;j<7 * (ssize + i);j++) working_space[j] = 0;
2847 for(i = 0; i < size_ext; i++){
2850 working_space[i + size_ext] = source[0] + l1low * a;
2851 if(working_space[i + size_ext] < 0)
2852 working_space[i + size_ext]=0;
2855 else if(i >= ssize + shift){
2856 a = i - (ssize - 1 + shift);
2857 working_space[i + size_ext] = source[ssize - 1];
2858 if(working_space[i + size_ext] < 0)
2859 working_space[i + size_ext]=0;
2863 working_space[i + size_ext] = source[i - shift];
2866 if(backgroundRemove ==
true){
2867 for(i = 1; i <= numberIterations; i++){
2868 for(j = i; j < size_ext - i; j++){
2869 if(markov ==
false){
2870 a = working_space[size_ext + j];
2871 b = (working_space[size_ext + j - i] + working_space[size_ext + j + i]) / 2.0;
2879 a = working_space[size_ext + j];
2882 for (w = j - bw; w <= j + bw; w++){
2883 if ( w >= 0 && w < size_ext){
2884 av += working_space[size_ext + w];
2891 for (w = j - i - bw; w <= j - i + bw; w++){
2892 if ( w >= 0 && w < size_ext){
2893 b += working_space[size_ext + w];
2900 for (w = j + i - bw; w <= j + i + bw; w++){
2901 if ( w >= 0 && w < size_ext){
2902 c += working_space[size_ext + w];
2910 working_space[j]=av;
2913 for(j = i; j < size_ext - i; j++)
2914 working_space[size_ext + j] = working_space[j];
2916 for(j = 0;j < size_ext; j++){
2919 b = source[0] + l1low * a;
2921 working_space[size_ext + j] = b - working_space[size_ext + j];
2924 else if(j >= ssize + shift){
2925 a = j - (ssize - 1 + shift);
2926 b = source[ssize - 1];
2928 working_space[size_ext + j] = b - working_space[size_ext + j];
2932 working_space[size_ext + j] = source[j - shift] - working_space[size_ext + j];
2935 for(j = 0;j < size_ext; j++){
2936 if(working_space[size_ext + j] < 0) working_space[size_ext + j] = 0;
2940 for(i = 0; i < size_ext; i++){
2941 working_space[i + 6*size_ext] = working_space[i + size_ext];
2945 for(j = 0; j < size_ext; j++)
2946 working_space[2 * size_ext + j] = working_space[size_ext + j];
2947 xmin = 0,xmax = size_ext - 1;
2948 for(i = 0, maxch = 0; i < size_ext; i++){
2949 working_space[i] = 0;
2950 if(maxch < working_space[2 * size_ext + i])
2951 maxch = working_space[2 * size_ext + i];
2952 plocha += working_space[2 * size_ext + i];
2955 delete [] working_space;
2960 working_space[xmin] = 1;
2961 for(i = xmin; i < xmax; i++){
2962 nip = working_space[2 * size_ext + i] / maxch;
2963 nim = working_space[2 * size_ext + i + 1] / maxch;
2965 for(l = 1; l <= averWindow; l++){
2967 a = working_space[2 * size_ext + xmax] / maxch;
2970 a = working_space[2 * size_ext + i + l] / maxch;
2977 a = TMath::Sqrt(a + nip);
2982 if((i - l + 1) < xmin)
2983 a = working_space[2 * size_ext + xmin] / maxch;
2986 a = working_space[2 * size_ext + i - l + 1] / maxch;
2993 a = TMath::Sqrt(a + nim);
3000 a = working_space[i + 1] = working_space[i] * a;
3003 for(i = xmin; i <= xmax; i++){
3004 working_space[i] = working_space[i] / nom;
3006 for(j = 0; j < size_ext; j++)
3007 working_space[size_ext + j] = working_space[j] * plocha;
3008 for(j = 0; j < size_ext; j++){
3009 working_space[2 * size_ext + j] = working_space[size_ext + j];
3011 if(backgroundRemove ==
true){
3012 for(i = 1; i <= numberIterations; i++){
3013 for(j = i; j < size_ext - i; j++){
3014 a = working_space[size_ext + j];
3015 b = (working_space[size_ext + j - i] + working_space[size_ext + j + i]) / 2.0;
3018 working_space[j] = a;
3020 for(j = i; j < size_ext - i; j++)
3021 working_space[size_ext + j] = working_space[j];
3023 for(j = 0; j < size_ext; j++){
3024 working_space[size_ext + j] = working_space[2 * size_ext + j] - working_space[size_ext + j];
3034 for(i = 0; i < size_ext; i++){
3035 lda = (double)i - 3 * sigma;
3036 lda = lda * lda / (2 * sigma * sigma);
3037 j = (int)(1000 * TMath::Exp(-lda));
3042 working_space[i] = lda;
3050 for(i = 0; i < size_ext; i++)
3051 working_space[2 * size_ext + i] = TMath::Abs(working_space[size_ext + i]);
3058 for(i = imin; i <= imax; i++){
3063 jmax = lh_gold - 1 - i;
3064 if(jmax > (lh_gold - 1))
3067 for(j = jmin;j <= jmax; j++){
3068 ldb = working_space[j];
3069 ldc = working_space[i + j];
3070 lda = lda + ldb * ldc;
3072 working_space[size_ext + i - imin] = lda;
3076 imin = -i,imax = size_ext + i - 1;
3077 for(i = imin; i <= imax; i++){
3079 for(j = 0; j <= (lh_gold - 1); j++){
3080 ldb = working_space[j];
3082 if(k >= 0 && k < size_ext){
3083 ldc = working_space[2 * size_ext + k];
3084 lda = lda + ldb * ldc;
3088 working_space[4 * size_ext + i - imin] = lda;
3091 for(i = imin; i <= imax; i++)
3092 working_space[2 * size_ext + i - imin] = working_space[4 * size_ext + i - imin];
3094 for(i = 0; i < size_ext; i++)
3095 working_space[i] = 1;
3097 for(lindex = 0; lindex < deconIterations; lindex++){
3098 for(i = 0; i < size_ext; i++){
3099 if(TMath::Abs(working_space[2 * size_ext + i]) > 0.00001 && TMath::Abs(working_space[i]) > 0.00001){
3107 if(jmax > (size_ext - 1 - i))
3110 for(j = jmin; j <= jmax; j++){
3111 ldb = working_space[j + lh_gold - 1 + size_ext];
3112 ldc = working_space[i + j];
3113 lda = lda + ldb * ldc;
3115 ldb = working_space[2 * size_ext + i];
3122 ldb = working_space[i];
3124 working_space[3 * size_ext + i] = lda;
3127 for(i = 0; i < size_ext; i++){
3128 working_space[i] = working_space[3 * size_ext + i];
3132 for(i=0;i<size_ext;i++){
3133 lda = working_space[i];
3136 working_space[size_ext + j] = lda;
3139 maximum = 0, maximum_decon = 0;
3141 for(i = 0; i < size_ext - j; i++){
3142 if(i >= shift && i < ssize + shift){
3143 working_space[i] = area * working_space[size_ext + i + j];
3144 if(maximum_decon < working_space[i])
3145 maximum_decon = working_space[i];
3146 if(maximum < working_space[6 * size_ext + i])
3147 maximum = working_space[6 * size_ext + i];
3151 working_space[i] = 0;
3159 for(i = 1; i < size_ext - 1; i++){
3160 if(working_space[i] > working_space[i - 1] && working_space[i] > working_space[i + 1]){
3161 if(i >= shift && i < ssize + shift){
3162 if(working_space[i] > lda*maximum_decon && working_space[6 * size_ext + i] > threshold * maximum / 100.0){
3163 for(j = i - 1, a = 0, b = 0; j <= i + 1; j++){
3164 a += (double)(j - shift) * working_space[j];
3165 b += working_space[j];
3173 if(peak_index == 0){
3179 for(j = 0, priz = 0; j < peak_index && priz == 0; j++){
3180 if(working_space[6 * size_ext + shift + (
int)a] > working_space[6 * size_ext + shift + (
int)
fPositionX[j]])
3190 for(k = peak_index; k >= j; k--){
3205 for(i = 0; i < ssize; i++) destVector[i] = working_space[i + shift];
3206 delete [] working_space;
3209 Warning(
"SearchHighRes",
"Peak buffer full");
3216 float sigma,
double threshold,
3217 bool backgroundRemove,
int deconIterations,
3218 bool markov,
int averWindow)
3227 return SearchHighRes(source,destVector,ssize,sigma,threshold,backgroundRemove,
3228 deconIterations,markov,averWindow);
3242 return s.
Search(hist,sigma,option,threshold);
Facilities for advanced spectral analysis.
static TH1 * StaticBackground(const TH1 *hist, Int_t niter=20, Option_t *option="")
static Int_t StaticSearch(const TH1 *hist, Double_t sigma=2, Option_t *option="goff", Double_t threshold=0.05)
virtual Int_t Search(const TH1 *hist, Double_t sigma=2, Option_t *option="", Double_t threshold=0.05)
static Int_t fgAverageWindow
static void SetDeconIterations(Int_t n=3)
const char * Deconvolution(float *source, const float *response, Int_t ssize, Int_t numberIterations, Int_t numberRepetitions, Double_t boost)
static Int_t fgIterations
Int_t Search1HighRes(float *source, float *destVector, Int_t ssize, float sigma, Double_t threshold, bool backgroundRemove, Int_t deconIterations, bool markov, Int_t averWindow)
Int_t SearchHighRes(float *source, float *destVector, Int_t ssize, float sigma, Double_t threshold, bool backgroundRemove, Int_t deconIterations, bool markov, Int_t averWindow)
NcSpectrum(const NcSpectrum &)
virtual void Print(Option_t *option="") const
static void SetAverageWindow(Int_t w=3)
const char * SmoothMarkov(float *source, Int_t ssize, Int_t averWindow)
void SetResolution(Float_t resolution=1)
const char * Unfolding(float *source, const float **respMatrix, Int_t ssizex, Int_t ssizey, Int_t numberIterations, Int_t numberRepetitions, Double_t boost)
const char * DeconvolutionRL(float *source, const float *response, Int_t ssize, Int_t numberIterations, Int_t numberRepetitions, Double_t boost)
virtual TH1 * Background(const TH1 *hist, Int_t niter=20, Option_t *option="")