| 1288 | |
| 1289 | == Theta-Square Plot == |
| 1290 | |
| 1291 | There are several ways ot prepare a theta-square plot. If you want to change the cuts later on, you will have to download all the data and do it offline. However, this is time- and bandwidth-hungry. If you know your cuts already, an easy easy solution is to let mysql create the plot for you and just use a local program to plot it. It significantly decreases bandwidth and space requirement (maybe from several GB to just a few byte) and it significantly increase CPU requirement (because data does not have to be converted to ascii representation and back and compressed for the transfer but it fully processed in memory). |
| 1292 | |
| 1293 | Assuming you produce a root file which contains three branches '''Bin''' (the number of the bin), '''Weight''' (-0.2 for background and 1 for signal) and '''Counts''' for the number of bin entries. You can for example run the following query using rootifysql (see DatabaseBasedAnalysis/rootifysql). Note that you might want to adapt the theta-sq cut your are going to use and the number of bins into which you sort the data up to the theta-square cut. |
| 1294 | |
| 1295 | {{{!Spoiler |
| 1296 | {{{#!sql |
| 1297 | WITH Table7 AS |
| 1298 | ( |
| 1299 | WITH Table6 AS |
| 1300 | ( |
| 1301 | WITH Table5 AS |
| 1302 | ( |
| 1303 | WITH Table4 AS |
| 1304 | ( |
| 1305 | WITH Table3 AS |
| 1306 | ( |
| 1307 | WITH Table2 AS |
| 1308 | ( |
| 1309 | WITH Table1 AS |
| 1310 | ( |
| 1311 | WITH Table0 AS |
| 1312 | ( |
| 1313 | SELECT -- 0 |
| 1314 | Weight, |
| 1315 | Size, |
| 1316 | NumUsedPixels, |
| 1317 | NumIslands, |
| 1318 | Leakage1, |
| 1319 | MeanX, |
| 1320 | MeanY, |
| 1321 | CosDelta, |
| 1322 | SinDelta, |
| 1323 | M3Long, |
| 1324 | SlopeLong, |
| 1325 | Width/Length AS WdivL, |
| 1326 | PI()*Width*Length AS Area, |
| 1327 | cosa*X - sina*Y AS PX, |
| 1328 | cosa*Y + sina*X AS PY |
| 1329 | FROM RunInfo |
| 1330 | LEFT JOIN Images USING (FileId) |
| 1331 | LEFT JOIN Position USING (FileId, EvtNumber) |
| 1332 | CROSS JOIN Wobble |
| 1333 | WHERE |
| 1334 | FileId BETWEEN 131101000 AND 131107000 |
| 1335 | AND |
| 1336 | fSourceKey=5 |
| 1337 | AND |
| 1338 | fRunTypeKey=1 |
| 1339 | AND |
| 1340 | fZenithDistanceMax<35 |
| 1341 | AND |
| 1342 | fR750Cor>0.9e0*fR750Ref |
| 1343 | AND |
| 1344 | NumUsedPixels>5.5 |
| 1345 | AND |
| 1346 | Leakage1<0.1 |
| 1347 | |
| 1348 | ) -- AS Table0 |
| 1349 | |
| 1350 | SELECT -- 1 |
| 1351 | Weight, CosDelta, SinDelta, M3Long, SlopeLong, Leakage1, WdivL, |
| 1352 | MeanX - PX*1.02e0 AS DX, |
| 1353 | MeanY - PY*1.02e0 AS DY |
| 1354 | FROM |
| 1355 | Table0 |
| 1356 | WHERE |
| 1357 | Area < LOG10(Size)*898-1535 |
| 1358 | |
| 1359 | ) -- AS Table1 |
| 1360 | |
| 1361 | SELECT -- 2 |
| 1362 | Weight, CosDelta, SinDelta, DX, DY, M3Long, SlopeLong, Leakage1, WdivL, |
| 1363 | SQRT(DX*DX + DY*DY) AS Norm |
| 1364 | FROM |
| 1365 | Table1 |
| 1366 | |
| 1367 | ) -- AS Table2 |
| 1368 | |
| 1369 | SELECT -- 3 |
| 1370 | Weight, M3Long, SlopeLong, Leakage1, WdivL, Norm, |
| 1371 | LEAST(GREATEST((CosDelta*DY - SinDelta*DX)/Norm, -1), 1) AS LX, |
| 1372 | SIGN(CosDelta*DX + SinDelta*DY) AS Sign |
| 1373 | FROM |
| 1374 | Table2 |
| 1375 | |
| 1376 | ) -- AS Table3 |
| 1377 | |
| 1378 | SELECT -- 4 |
| 1379 | Weight, Leakage1, WdivL, LX, |
| 1380 | Norm *0.0117193246260285378e0 AS Dist, |
| 1381 | M3Long *Sign*0.0117193246260285378e0 AS M3L, |
| 1382 | SlopeLong*Sign/0.0117193246260285378e0 AS Slope |
| 1383 | FROM |
| 1384 | Table3 |
| 1385 | |
| 1386 | ) -- AS Table4 |
| 1387 | |
| 1388 | SELECT -- 5 |
| 1389 | Weight, WdivL, Dist, LX, M3L, Slope, |
| 1390 | 1.299e0 + 0.0632e0*Slope + 1.67972e0*(1-1/(1+4.86232e0*Leakage1)) AS Xi |
| 1391 | FROM |
| 1392 | Table4 |
| 1393 | |
| 1394 | ) -- AS Table5 |
| 1395 | |
| 1396 | SELECT -- 6 |
| 1397 | Weight, Dist, LX, |
| 1398 | IF (M3L<-0.07 || (Dist-0.5e0)*7.2e0-Slope<0, -Xi, Xi) * (1-WdivL) AS Disp |
| 1399 | FROM |
| 1400 | Table5 |
| 1401 | |
| 1402 | ) -- AS Table6 |
| 1403 | |
| 1404 | SELECT -- 7 |
| 1405 | Weight, |
| 1406 | (Disp*Disp + Dist*Dist - 2*Disp*Dist*SQRT(1-LX*LX)) AS ThetaSq |
| 1407 | FROM |
| 1408 | Table6 |
| 1409 | |
| 1410 | ) -- AS Table8 |
| 1411 | |
| 1412 | SELECT -- 9 |
| 1413 | |
| 1414 | /* The number 0.024 corresponds to the theta-sq cut you want to apply. */ |
| 1415 | /* The number 3 is the number of bins into which the values smaller */ |
| 1416 | /* the theta-sq cut are divide. We are basically calculating the bin- */ |
| 1417 | /* number into which the event is sorted later. 0.024/3 is the bin- */ |
| 1418 | /* width. */ |
| 1419 | |
| 1420 | FLOOR(ThetaSq/(0.024/3)) AS Bin, |
| 1421 | Weight, |
| 1422 | COUNT(*) AS `Count` |
| 1423 | FROM |
| 1424 | Table7 |
| 1425 | GROUP BY |
| 1426 | Bin, Weight |
| 1427 | |
| 1428 | /* If no printed on the console, strictly speaking, this is not necessary */ |
| 1429 | ORDER BY |
| 1430 | Bin, Weight |
| 1431 | }}} |
| 1432 | }}} |
| 1433 | |
| 1434 | In a second step, you might want to produce a theta-square plot with your preferred language (here: root/C++). '''It is very important that you ensure that your plotting routine is consistent with the the histogram data produced by the former SQL query in terms of bin-width!''' Here is an example root macro to plot the data: |
| 1435 | |
| 1436 | {{{#!Spoiler |
| 1437 | {{{#!C++ |
| 1438 | // ============= Significance according to Li&Ma =============== |
| 1439 | Double_t LiMa(Double_t s, Double_t b, Double_t alpha) |
| 1440 | { |
| 1441 | const Double_t sum = s+b; |
| 1442 | |
| 1443 | if (s<0 || b<0 || alpha<=0) |
| 1444 | return -1; |
| 1445 | |
| 1446 | const Double_t l = s==0 ? 0 : s*TMath::Log(s/sum*(alpha+1)/alpha); |
| 1447 | const Double_t m = b==0 ? 0 : b*TMath::Log(b/sum*(alpha+1) ); |
| 1448 | |
| 1449 | return l+m<0 ? -1 : TMath::Sqrt((l+m)*2); |
| 1450 | } |
| 1451 | |
| 1452 | void plot_thetasq() |
| 1453 | { |
| 1454 | // ====================== Setup the plot =================== |
| 1455 | |
| 1456 | double cut = 0.024; // Theta-square cut |
| 1457 | int icut = 3; // Number of bins at which the theta-square cut should be displayed |
| 1458 | double max = 0.98; // maximum to be displayed on the x-axis (in degree^2) |
| 1459 | double width = cut/icut; // width of a single bin (here: a third of the theta-square cut) |
| 1460 | |
| 1461 | const char *title = "FACT"; |
| 1462 | const char *watermark = "preliminary"; |
| 1463 | |
| 1464 | // ================= Initialize root chain ================= |
| 1465 | |
| 1466 | TChain chain("Result"); |
| 1467 | chain.AddFile("thetasq-hist.root"); |
| 1468 | |
| 1469 | // Define variables for all leaves to be accessed |
| 1470 | // By definition rootifysql writes only doubles |
| 1471 | double Bin, Weight, Count; |
| 1472 | |
| 1473 | // Connect the variables to the cordesponding leaves |
| 1474 | chain.SetBranchAddress("Bin", &Bin); |
| 1475 | chain.SetBranchAddress("Weight", &Weight); |
| 1476 | chain.SetBranchAddress("Count", &Count); |
| 1477 | |
| 1478 | // ==================== Setting up Histogram =============== |
| 1479 | |
| 1480 | int num = floor(max/width); |
| 1481 | |
| 1482 | // Create a histogram for on- and off-data |
| 1483 | TH1F hon ("on", "", num, 0, num*width); |
| 1484 | TH1F hoff("off", "", num, 0, num*width); |
| 1485 | |
| 1486 | hon.Sumw2(); |
| 1487 | hoff.Sumw2(); |
| 1488 | |
| 1489 | // Loop over all events |
| 1490 | for (int i=0; i<chain.GetEntries(); i++) |
| 1491 | { |
| 1492 | // read the i-th event from the file |
| 1493 | chain.GetEntry(i); |
| 1494 | |
| 1495 | if (Weight>0) |
| 1496 | { |
| 1497 | hon.SetBinContent((int)Bin+1, Count); |
| 1498 | hon.SetBinError( (int)Bin+1, sqrt(Count)); |
| 1499 | } |
| 1500 | else |
| 1501 | { |
| 1502 | hoff.SetBinContent((int)Bin+1, -Weight*Count); |
| 1503 | hoff.SetBinError( (int)Bin+1, sqrt(-Weight*Count)); |
| 1504 | } |
| 1505 | } |
| 1506 | |
| 1507 | // ========================= Result ======================== |
| 1508 | |
| 1509 | double signal = hon.Integral(1, icut); |
| 1510 | double background = hoff.Integral(1, icut); |
| 1511 | |
| 1512 | double significance = LiMa(signal, background*5, 0.2); |
| 1513 | |
| 1514 | cout << "Signal: " << signal << endl; |
| 1515 | cout << "Backgr: " << background << endl; |
| 1516 | cout << "Signif: " << significance << endl; |
| 1517 | |
| 1518 | // ======================= Plotting ======================== |
| 1519 | |
| 1520 | TCanvas *c = new TCanvas; |
| 1521 | |
| 1522 | c->SetBorderMode(0); |
| 1523 | c->SetFrameBorderMode(0); |
| 1524 | c->SetFillColor(kWhite); |
| 1525 | |
| 1526 | c->SetLeftMargin(0.12); |
| 1527 | c->SetRightMargin(0.01); |
| 1528 | c->SetBottomMargin(0.16); |
| 1529 | c->SetTopMargin(0.18); |
| 1530 | |
| 1531 | c->SetGridy(); |
| 1532 | |
| 1533 | hon.SetStats(kFALSE); |
| 1534 | hon.SetMinimum(0); |
| 1535 | hon.SetLineColor(kBlack); |
| 1536 | hon.SetMarkerColor(kBlack); |
| 1537 | hon.SetLineWidth(2); |
| 1538 | |
| 1539 | hoff.GetXaxis()->SetLabelSize(0.06); |
| 1540 | hoff.GetXaxis()->SetTitleSize(0.06); |
| 1541 | hoff.GetXaxis()->SetTitleOffset(0.95); |
| 1542 | hoff.GetYaxis()->SetLabelSize(0.06); |
| 1543 | hoff.GetYaxis()->SetTitleSize(0.06); |
| 1544 | hoff.GetYaxis()->CenterTitle(); |
| 1545 | hoff.SetXTitle("#vartheta^2"); |
| 1546 | hoff.SetYTitle("Counts"); |
| 1547 | hoff.SetTitleSize(0.07); |
| 1548 | hoff.SetTitle(""); |
| 1549 | |
| 1550 | hoff.SetStats(kFALSE); |
| 1551 | hoff.SetLineWidth(2); |
| 1552 | hoff.SetLineColor(kBlack); |
| 1553 | hoff.SetMarkerColor(kBlack); |
| 1554 | hoff.SetFillColor(17); |
| 1555 | |
| 1556 | hoff.SetMinimum(0); |
| 1557 | hoff.SetMaximum(TMath::Max(hon.GetMaximum(), hoff.GetMaximum())*1.1); |
| 1558 | |
| 1559 | hoff.DrawCopy("bar"); |
| 1560 | hon.DrawCopy("same"); |
| 1561 | |
| 1562 | // draw a preliminary tag |
| 1563 | TLatex text; |
| 1564 | text.SetTextColor(kWhite); |
| 1565 | text.SetBit(TLatex::kTextNDC); |
| 1566 | text.SetTextSize(0.07); |
| 1567 | text.SetTextAngle(2.5); |
| 1568 | |
| 1569 | TString wm(watermark); |
| 1570 | text.DrawLatex(0.45, 0.2, wm); |
| 1571 | |
| 1572 | // draw line showing cut |
| 1573 | TLine line; |
| 1574 | line.SetLineColor(14); |
| 1575 | line.SetLineStyle(7); |
| 1576 | line.DrawLine(icut*width, 0, icut*width, hoff.GetMaximum()); |
| 1577 | |
| 1578 | // Add a title above the plot |
| 1579 | TPaveText *pave=new TPaveText(0.12, 0.83, 0.99, 0.975, "blNDC"); |
| 1580 | pave->SetBorderSize(1); |
| 1581 | pave->SetLabel(title); |
| 1582 | |
| 1583 | TText *ptxt = pave->AddText(" "); |
| 1584 | ptxt->SetTextAlign(20); |
| 1585 | |
| 1586 | ptxt = pave->AddText(Form("Significance %.1f#sigma, off-scale 0.2", |
| 1587 | significance)); |
| 1588 | ptxt->SetTextAlign(21); |
| 1589 | |
| 1590 | ptxt = pave->AddText(Form("%.1f excess events, %.1f background events", |
| 1591 | signal-background, background)); |
| 1592 | ptxt->SetTextAlign(21); |
| 1593 | |
| 1594 | pave->SetBit(kCanDelete); |
| 1595 | pave->Draw("br"); |
| 1596 | } |
| 1597 | }}} |
| 1598 | }}} |
| 1599 | |
| 1600 | This is how the result will look like: |
| 1601 | |
| 1602 | [[Image(ThetaSquare.png)]] |
| 1603 | |
| 1604 | |
| 1605 | |