3 #include "AliHighMultiplicitySelector.h"
11 #include <TParticle.h>
14 #include <TGeoManager.h>
23 #include <AliRunLoader.h>
26 #include <AliITSgeom.h>
27 #include <AliITSLoader.h>
28 #include <AliITSdigitSPD.h>
29 #include <AliITSRecPoint.h>
31 #include "AliPWG0Helper.h"
34 // Selector that produces plots needed for the high multiplicity analysis with the
39 ClassImp(AliHighMultiplicitySelector)
41 AliHighMultiplicitySelector::AliHighMultiplicitySelector() :
55 fCentralRegion(kFALSE)
58 // Constructor. Initialization of pointers
62 AliHighMultiplicitySelector::~AliHighMultiplicitySelector()
68 // histograms are in the output list and deleted when the output
69 // list is deleted by the TSelector dtor
72 void AliHighMultiplicitySelector::SlaveBegin(TTree *tree)
76 AliSelectorRL::SlaveBegin(tree);
78 fChipsFired = new TH2F("fChipsFired", ";Module;Chip;Count", 240, -0.5, 239.5, 5, -0.5, 4.5);
80 fPrimaryL1 = new TNtuple("fPrimaryL1", "", "multiplicity:firedChips:chipsByPrimaries:clusters");
81 fPrimaryL2 = new TNtuple("fPrimaryL2", "", "multiplicity:firedChips:chipsByPrimaries:clusters");
83 fClusterZL1 = new TH1F("fClusterZL1", ";z", 400, -20, 20);
84 fClusterZL2 = new TH1F("fClusterZL2", ";z", 400, -20, 20);
87 void AliHighMultiplicitySelector::Init(TTree* tree)
89 // read the user objects
91 AliSelectorRL::Init(tree);
93 // enable only the needed branches
96 tree->SetBranchStatus("*", 0);
97 tree->SetBranchStatus("fTriggerMask", 1);
99 /*if (fTree->GetCurrentFile())
101 TString fileName(fTree->GetCurrentFile()->GetName());
102 fileName.ReplaceAll("AliESDs", "geometry");
105 TGeoManager::Import(fileName);
110 Bool_t AliHighMultiplicitySelector::Process(Long64_t entry)
116 if (AliSelectorRL::Process(entry) == kFALSE)
119 // Check prerequisites
122 AliDebug(AliLog::kError, "ESD branch not available");
126 Bool_t eventTriggered = AliPWG0Helper::IsEventTriggered(fESD, AliPWG0Helper::kMB1);
130 AliDebug(AliLog::kDebug, "Event not triggered. Skipping.");
134 AliStack* stack = GetStack();
137 AliDebug(AliLog::kError, "Stack not available");
141 Int_t nPrim = stack->GetNprimary();
142 Int_t multiplicity21 = 0;
143 Int_t multiplicity16 = 0;
145 for (Int_t iMc = 0; iMc < nPrim; ++iMc)
147 AliDebug(AliLog::kDebug+1, Form("MC Loop: Processing particle %d.", iMc));
149 TParticle* particle = stack->Particle(iMc);
153 AliDebug(AliLog::kError, Form("UNEXPECTED: particle with label %d not found in stack (mc loop).", iMc));
157 if (AliPWG0Helper::IsPrimaryCharged(particle, nPrim) == kFALSE)
162 if (TMath::Abs(particle->Eta()) < 1.05)
164 if (TMath::Abs(particle->Eta()) < 0.8)
169 if (TMath::Abs(particle->Eta()) < 2.1)
171 if (TMath::Abs(particle->Eta()) < 1.6)
174 }// end of mc particle
176 AliRunLoader* runLoader = GetRunLoader();
179 AliDebug(AliLog::kError, "runloader not available");
183 // TDirectory::TContext restores the current directory is restored when the scope ends.
184 // This helps around ROOT bug #26025 and is good behaviour anyway
185 TDirectory::TContext context(0);
186 AliITSLoader* loader = (AliITSLoader*) runLoader->GetLoader( "ITSLoader" );
187 loader->LoadDigits("READ");
188 TTree* treeD = loader->TreeD();
191 AliDebug(AliLog::kError, "Could not retrieve TreeD of ITS");
195 treeD->SetBranchStatus("*", 0);
196 treeD->SetBranchStatus("ITSDigitsSPD.fTracks*", 1);
197 treeD->SetBranchStatus("ITSDigitsSPD.fCoord1", 1);
199 TClonesArray* digits = 0;
200 treeD->SetBranchAddress("ITSDigitsSPD", &digits);
204 // each value for both layers
205 Int_t totalNumberOfFO[2];
206 Int_t chipsHitByPrimaries[2];
207 //Int_t chipsHitBySecondaries[2];
209 for (Int_t i=0; i<2; ++i)
211 totalNumberOfFO[i] = 0;
212 chipsHitByPrimaries[i] = 0;
213 //chipsHitBySecondaries[i] = 0;
216 Int_t startSPD = 0; //geom->GetStartSPD();
217 Int_t lastSPD = 239; //geom->GetLastSPD();
219 //printf("%d %d\n", startSPD, lastSPD);
220 // for (Int_t l=0; l<240; ++l) { AliITSgeomTGeo::GetModuleId(l, i, j, k); printf("%d --> %d\n", l, i); }
222 // loop over modules (ladders)
223 for (Int_t moduleIndex=startSPD; moduleIndex<lastSPD+1; moduleIndex++)
227 if ((moduleIndex % 4) == 0 || (moduleIndex % 4) == 3)
231 Int_t currentLayer = 0;
232 if (moduleIndex >= 80)
235 treeD->GetEvent(moduleIndex);
237 // get number of digits in this module
238 Int_t ndigitsInModule = digits->GetEntriesFast();
240 // get number of digits in each chip of the module
241 Int_t ndigitsInChip[5];
242 Bool_t hitByPrimary[5];
243 for( Int_t iChip=0; iChip<5; iChip++)
245 ndigitsInChip[iChip]=0;
246 hitByPrimary[iChip] = kFALSE;
249 // loop over digits in this module
250 for (Int_t iDig=0; iDig<ndigitsInModule; iDig++)
252 AliITSdigitSPD* dp = (AliITSdigitSPD*) digits->At(iDig);
253 Int_t column = dp->GetCoord1();
254 Int_t isChip = column / 32;
256 //printf("Digit %d has column %d which translates to chip %d\n", iDig, column, isChip);
258 fChipsFired->Fill(moduleIndex, isChip);
260 ndigitsInChip[isChip]++;
262 Bool_t debug = kFALSE;
264 // find out which particle caused this chip to fire
265 // if we find at least one primary we consider this chip being fired by a primary
266 for (Int_t track=0; track<10; ++track)
268 Int_t label = dp->GetTrack(track);
274 printf("track %d contains label %d\n", track, label);
276 TParticle* particle = stack->Particle(label);
280 AliDebug(AliLog::kError, Form("UNEXPECTED: particle with label %d not found in stack (digit loop).", label));
287 printf("statuscode = %d, p = %f, m = %d\n", particle->GetStatusCode(), particle->P(), particle->GetFirstMother());
290 // TODO delta electrons should be traced back to their mother. this is e.g. solved in AliITSClusterFinderV2::CheckLabels2
291 while (particle->P() < 0.02 && particle->GetStatusCode() == 0 && particle->GetFirstMother() >= 0)
293 label = particle->GetFirstMother();
294 particle = stack->Particle(label);
302 printf("statuscode = %d, p = %f, m = %d\n", particle->GetStatusCode(), particle->P(), particle->GetFirstMother());
309 AliDebug(AliLog::kError, Form("UNEXPECTED: particle with label %d not found in stack (digit loop, finding delta electrons).", label));
316 if (AliPWG0Helper::IsPrimaryCharged(particle, nPrim) == kFALSE)
320 printf("This was a primary (or delta-electron of a primary)!\n");
322 hitByPrimary[isChip] = kTRUE;
326 // get number of FOs in the module
327 for (Int_t ifChip=0; ifChip<5; ifChip++)
328 if( ndigitsInChip[ifChip] >= 1 )
330 totalNumberOfFO[currentLayer]++;
331 if (hitByPrimary[ifChip])
333 chipsHitByPrimaries[currentLayer]++;
336 // chipsHitBySecondaries[currentLayer]++;
340 //printf("Fired chips: %d %d\n", totalNumberOfFOLayer1, totalNumberOfFOLayer2);
343 Int_t clustersLayer[2];
344 clustersLayer[0] = 0;
345 clustersLayer[1] = 0;
347 loader->LoadRecPoints("READ");
348 TTree* treeR = loader->TreeR();
351 AliDebug(AliLog::kError, "Could not retrieve TreeR of ITS");
356 //treeR->SetBranchStatus("*", 0);
358 TClonesArray* itsClusters = 0;
359 treeR->SetBranchAddress("ITSRecPoints", &itsClusters);
361 Int_t nTreeEntries = treeR->GetEntries();
362 for (Int_t iEntry = 0; iEntry < nTreeEntries; ++iEntry)
364 if (!treeR->GetEvent(iEntry))
367 Int_t nClusters = itsClusters->GetEntriesFast();
371 AliITSRecPoint* cluster = (AliITSRecPoint*) itsClusters->UncheckedAt(nClusters);
373 if (cluster->GetLayer() == 0)
376 fClusterZL1->Fill(cluster->GetZ());
378 else if (cluster->GetLayer() == 1)
381 fClusterZL2->Fill(cluster->GetZ());
386 fPrimaryL1->Fill(multiplicity21, totalNumberOfFO[0], chipsHitByPrimaries[0], clustersLayer[0]);
387 fPrimaryL2->Fill(multiplicity16, totalNumberOfFO[1], chipsHitByPrimaries[1], clustersLayer[1]);
392 Bool_t AliHighMultiplicitySelector::Notify()
394 // get next ITS runloader
396 AliRunLoader* runLoader = GetRunLoader();
400 AliITSLoader* loader = (AliITSLoader* )runLoader->GetLoader( "ITSLoader" );
403 loader->UnloadDigits();
404 loader->UnloadRecPoints();
408 return AliSelectorRL::Notify();
411 void AliHighMultiplicitySelector::SlaveTerminate()
413 // The SlaveTerminate() function is called after all entries or objects
414 // have been processed. When running with PROOF SlaveTerminate() is called
415 // on each slave server.
417 AliSelectorRL::SlaveTerminate();
419 // Add the histograms to the output on each slave server
422 AliDebug(AliLog::kError, "ERROR: Output list not initialized.");
426 fOutput->Add(fChipsFired);
427 fOutput->Add(fPrimaryL1);
428 fOutput->Add(fPrimaryL2);
429 fOutput->Add(fClusterZL1);
430 fOutput->Add(fClusterZL2);
433 void AliHighMultiplicitySelector::Terminate()
435 // The Terminate() function is the last function to be called during
436 // a query. It always runs on the client, it can be used to present
437 // the results graphically or save the results to file.
439 AliSelectorRL::Terminate();
441 fChipsFired = dynamic_cast<TH2F*> (fOutput->FindObject("fChipsFired"));
442 fPrimaryL1 = dynamic_cast<TNtuple*> (fOutput->FindObject("fPrimaryL1"));
443 fPrimaryL2 = dynamic_cast<TNtuple*> (fOutput->FindObject("fPrimaryL2"));
444 fClusterZL1 = dynamic_cast<TH1F*> (fOutput->FindObject("fClusterZL1"));
445 fClusterZL2 = dynamic_cast<TH1F*> (fOutput->FindObject("fClusterZL2"));
447 if (!fClusterZL1 || !fClusterZL2 || !fChipsFired || !fPrimaryL1 || !fPrimaryL2)
449 AliError("Histograms not available");
456 void AliHighMultiplicitySelector::WriteHistograms(const char* filename)
458 // write the histograms to a file
460 TFile* file = TFile::Open(filename, "RECREATE");
462 fChipsFired->Write();
465 fClusterZL1->Write();
466 fClusterZL2->Write();
471 void AliHighMultiplicitySelector::ReadHistograms(const char* filename)
473 // read the data from a file and fill histograms
475 TFile* file = TFile::Open(filename);
480 fPrimaryL1 = dynamic_cast<TNtuple*> (file->Get("fPrimaryL1"));
481 fPrimaryL2 = dynamic_cast<TNtuple*> (file->Get("fPrimaryL2"));
482 fChipsFired = dynamic_cast<TH2F*> (file->Get("fChipsFired"));
483 fClusterZL1 = dynamic_cast<TH1F*> (file->Get("fClusterZL1"));
484 fClusterZL2 = dynamic_cast<TH1F*> (file->Get("fClusterZL2"));
486 #define MULT 1001, -0.5, 1000.5
487 #define BINNING_LAYER1 401, -0.5, 400.5
488 #define BINNING_LAYER2 801, -0.5, 800.5
490 fChipsLayer1 = new TH1F("fChipsLayer1", "Layer 1;Fired Chips;Count", BINNING_LAYER1);
491 fChipsLayer2 = new TH1F("fChipsLayer2", "Layer 2;Fired Chips;Count", BINNING_LAYER2);
493 fL1vsL2 = new TH2F("fL1vsL2", ";Fired Chips Layer 1;Fired Chips Layer 2", BINNING_LAYER1, BINNING_LAYER2);
494 fMvsL1 = new TH2F("fMvsL1", ";true multiplicity;fired chips layer1", MULT, BINNING_LAYER1);
495 fMvsL2 = new TH2F("fMvsL2", ";true multiplicity;fired chips layer2", MULT, BINNING_LAYER2);
497 fClvsL1 = new TH2F("fClvsL1", ";clusters layer1;fired chips layer1", MULT, BINNING_LAYER1);
498 fClvsL2 = new TH2F("fClvsL2", ";clusters layer2;fired chips layer2", MULT, BINNING_LAYER2);
500 for (Int_t i = 0; i < fPrimaryL1->GetEntries(); i++)
502 fPrimaryL1->GetEvent(i);
503 fPrimaryL2->GetEvent(i);
505 Int_t multiplicity21 = (Int_t) fPrimaryL1->GetArgs()[0];
506 Int_t multiplicity16 = (Int_t) fPrimaryL2->GetArgs()[0];
508 Int_t totalNumberOfFO[2];
509 totalNumberOfFO[0] = (Int_t) fPrimaryL1->GetArgs()[1];
510 totalNumberOfFO[1] = (Int_t) fPrimaryL2->GetArgs()[1];
512 Int_t chipsHitByPrimaries[2];
513 chipsHitByPrimaries[0] = (Int_t) fPrimaryL1->GetArgs()[2];
514 chipsHitByPrimaries[1] = (Int_t) fPrimaryL2->GetArgs()[2];
516 Int_t clustersLayer[2];
517 clustersLayer[0] = (Int_t) fPrimaryL1->GetArgs()[3];
518 clustersLayer[1] = (Int_t) fPrimaryL2->GetArgs()[3];
520 fChipsLayer1->Fill(totalNumberOfFO[0]);
521 fChipsLayer2->Fill(totalNumberOfFO[1]);
523 fL1vsL2->Fill(totalNumberOfFO[0], totalNumberOfFO[1]);
525 fMvsL1->Fill(multiplicity21, totalNumberOfFO[0]);
526 fMvsL2->Fill(multiplicity16, totalNumberOfFO[1]);
528 fClvsL1->Fill(clustersLayer[0], totalNumberOfFO[0]);
529 fClvsL2->Fill(clustersLayer[1], totalNumberOfFO[1]);
533 TH1* AliHighMultiplicitySelector::GetTriggerEfficiency(TH2* multVsLayer, Int_t cut)
536 // returns the trigger efficiency as function of multiplicity with a given cut
539 //cut and multiply with x-section
540 TH1* allEvents = multVsLayer->ProjectionX("fMvsL_x_total", 1, 1001);
541 //allEvents->Sumw2();
543 //cut and multiply with x-section
544 TH1* proj = multVsLayer->ProjectionX(Form("%s_x", multVsLayer->GetName()), cut, 1001);
547 //new TCanvas; allEvents->DrawCopy(); gPad->SetLogy();
548 //new TCanvas; proj->DrawCopy(); gPad->SetLogy();
550 // make probability distribution out of it
551 // TODO binomial errors do not work??? weird...
552 proj->Divide(proj, allEvents, 1, 1, "B");
557 TH1* AliHighMultiplicitySelector::GetXSectionCut(TH1* xSection, TH2* multVsLayer, Int_t cut)
559 // returns the rel. cross section of the true spectrum that is measured when a cut at <cut> is performed
561 TH1* proj = GetTriggerEfficiency(multVsLayer, cut);
563 //new TCanvas; proj->DrawCopy(); gPad->SetLogy();
565 for (Int_t i=1; i<=proj->GetNbinsX(); i++)
567 if (i <= xSection->GetNbinsX())
569 Double_t value = proj->GetBinContent(i) * xSection->GetBinContent(i);
573 error = value * (proj->GetBinError(i) / proj->GetBinContent(i) + xSection->GetBinError(i) / xSection->GetBinContent(i));
575 proj->SetBinContent(i, value);
576 proj->SetBinError(i, error);
580 proj->SetBinContent(i, 0);
581 proj->SetBinError(i, 0);
585 //new TCanvas; proj->DrawCopy(); gPad->SetLogy();
590 void AliHighMultiplicitySelector::MakeGraphs2(const char* title, TH1* xSection, TH2* fMvsL)
594 TGraph* effGraph = new TGraph;
595 effGraph->SetTitle(Form("%s;Cut on fired chips;mult. where eff. >50%%", title));
596 TGraph* ratioGraph = new TGraph;
597 ratioGraph->SetTitle(Form("%s;Cut on fired chips;x-section_(>=eff. limit) / x-section_(total)", title));
598 TGraph* totalGraph = new TGraph;
599 totalGraph->SetTitle(Form("%s;Cut on fired chips;rel x-section_(>=eff. limit)", title));
601 for (Int_t cut = 0; cut <= 300; cut+=50)
603 TH1* proj = (TH1*) GetTriggerEfficiency(fMvsL, cut)->Clone("clone");
606 //proj->Scale(1.0 / 3);
608 new TCanvas; proj->DrawCopy();
610 Int_t limitBin = proj->GetNbinsX()+1;
611 while (limitBin > 1 && proj->GetBinContent(limitBin-1) > 0.5)
614 Float_t limit = proj->GetXaxis()->GetBinCenter(limitBin);
616 effGraph->SetPoint(effGraph->GetN(), cut, limit);
618 proj = GetXSectionCut(xSection, fMvsL, cut);
622 if (proj->Integral(1, 1001) > 0)
624 ratio = proj->Integral(proj->FindBin(limit), 1001) / proj->Integral(1, 1001);
625 total = proj->Integral(proj->FindBin(limit), 1001);
628 ratioGraph->SetPoint(ratioGraph->GetN(), cut, ratio);
629 totalGraph->SetPoint(totalGraph->GetN(), cut, total);
631 Printf("Cut at %d --> trigger eff. is > 0.5 for mult. >= %.2f. That is the case for %f of the triggered, %e of all events", cut, limit, ratio, total);
634 TCanvas* canvas = new TCanvas(Form("%s_Efficiency", title), Form("%s_Efficiency", title), 1200, 800);
635 canvas->Divide(2, 2);
638 effGraph->Draw("A*");
640 for (Int_t i=8; i<=10; ++i)
642 TLine* line = new TLine(0, xSection->GetMean() * i, 300, xSection->GetMean() * i);
646 canvas->cd(2); ratioGraph->Draw("A*");
647 canvas->cd(3); gPad->SetLogy(); totalGraph->Draw("A*");
649 canvas->SaveAs(Form("%s.gif", canvas->GetName()));
652 void AliHighMultiplicitySelector::MakeGraphs(const char* title, TH1* xSection, TH2* fMvsL, Int_t limit)
654 // relative x-section, once we have a collision
656 xSection->Scale(1.0 / xSection->Integral());
658 TGraph* ratioGraph = new TGraph;
659 ratioGraph->SetTitle(Form("%s;Cut on fired chips;x-section_(>=%d) / x-section_(total)", title, limit));
660 TGraph* totalGraph = new TGraph;
661 totalGraph->SetTitle(Form("%s;Cut on fired chips;rel x-section_(>=%d)", title, limit));
665 Double_t bestRatio = -1;
666 Double_t bestTotal = -1;
668 Double_t fullRatio = -1;
669 Double_t fullTotal = -1;
673 for (Int_t cut = 50; cut <= 300; cut+=2)
675 TH1* proj = GetXSectionCut(xSection, fMvsL, cut);
679 if (proj->Integral(1, 1000) > 0)
681 ratio = proj->Integral(limit, 1000) / proj->Integral(1, 1000);
682 total = proj->Integral(limit, 1000);
685 max = TMath::Max(max, total);
687 //printf("Cut at %d: rel. x-section_(>=%d) = %e; x-section_(>=%d) / x-section_(total) = %f\n", cut, limit, total, limit, ratio);
689 if (total < max * 0.9 && bestCut == -1)
696 if (ratio == 1 && fullCut == -1)
703 ratioGraph->SetPoint(ratioGraph->GetN(), cut, ratio);
704 totalGraph->SetPoint(totalGraph->GetN(), cut, total);
708 printf("Best cut at %d: rel. x-section_(>=%d) = %e %%; x-section_(>=%d) / x-section_(total) = %f %%\n", bestCut, limit, bestTotal, limit, bestRatio);
710 printf("100%% cut at %d: rel. x-section_(>=%d) = %e %%; x-section_(>=%d) / x-section_(total) = %f %%\n", fullCut, limit, fullTotal, limit, fullRatio);
712 TCanvas* canvas = new TCanvas(Form("%s_RatioXSection_%d", title, limit), Form("%s_RatioXSection_%d", title, limit), 600, 400);
713 ratioGraph->Draw("A*");
714 canvas->SaveAs(Form("%s.gif", canvas->GetName()));
716 canvas = new TCanvas(Form("%s_TotalXSection_%d", title, limit), Form("%s_TotalXSection_%d", title, limit), 600, 400);
717 totalGraph->Draw("A*");
718 canvas->SaveAs(Form("%s.gif", canvas->GetName()));
721 void AliHighMultiplicitySelector::JPRPlots()
727 gSystem->Load("libPWG0base");
728 .L AliHighMultiplicitySelector.cxx+
729 x = new AliHighMultiplicitySelector();
730 x->ReadHistograms("highmult_hijing100k.root");
736 TFile* file = TFile::Open("crosssectionEx.root");
741 xSections[0] = dynamic_cast<TH1*> (gFile->Get("xSection2Ex"));
742 xSections[1] = dynamic_cast<TH1*> (gFile->Get("xSection15Ex"));
744 for (Int_t i=0; i<2; ++i)
749 TH1* xSection = xSections[i];
750 TH2* fMvsL = (i == 0) ? fMvsL1: fMvsL2;
751 //Int_t cut = (i == 0) ? 164 : 150; // 8 times the mean
752 //Int_t cut = (i == 0) ? 178 : 166; // 9 times the mean
753 Int_t cut = (i == 0) ? 190 : 182; // 10 times the mean
755 // limit is N times the mean
756 Int_t limit = (Int_t) (xSection->GetMean() * 10);
758 // 10^28 lum --> 1.2 kHz
759 // 10^31 lum --> 1200 kHz
760 Float_t rate = 1200e3;
763 Float_t lengthRun = 1e6;
765 xSection->SetStats(kFALSE);
766 xSection->SetTitle(""); //(i == 0) ? "SPD Layer 1" : "SPD Layer 2");
767 xSection->GetXaxis()->SetTitle(Form("true multiplicity in |#eta| < %.1f", (i == 0) ? 2.0 : 1.5));
768 xSection->GetXaxis()->SetRangeUser(0, (i == 0) ? 400 : 350);
769 //xSection->GetYaxis()->SetTitle("relative cross section");
770 xSection->GetYaxis()->SetTitleOffset(1.2);
772 // relative x-section, once we have a collision
773 xSection->Scale(1.0 / xSection->Integral());
775 TH1* proj = GetXSectionCut(xSection, fMvsL, cut);
779 if (proj->Integral(1, 1000) > 0)
781 ratio = proj->Integral(limit, 1000) / proj->Integral(1, 1000);
782 total = proj->Integral(limit, 1000);
785 printf("Cut at %d: rel. x-section_(>=%d) = %e; x-section_(>=%d) / x-section_(total) = %f\n", cut, limit, total, limit, ratio);
787 TCanvas* canvas = new TCanvas(Form("HMPlots_%d", i), Form("HMPlots_%d", i), 800, 600);
789 xSection->DrawCopy();
790 proj->SetLineColor(2);
791 proj->SetStats(kFALSE);
792 proj->DrawCopy("SAME");
794 TLegend* legend = new TLegend(0.15, 0.15, 0.45, 0.3);
795 legend->SetFillColor(0);
796 legend->AddEntry(xSection, "no trigger");
797 legend->AddEntry(proj, Form("FO trigger > %d chips", cut));
800 TLine* line = new TLine(limit, xSection->GetMinimum() * 0.5, limit, xSection->GetMaximum() * 2);
801 line->SetLineWidth(2);
804 canvas->SaveAs(Form("%s.gif", canvas->GetName()));
806 TCanvas* canvas2 = new TCanvas(Form("HMPlots_%d_Random", i), Form("HMPlots_%d_Random", i), 800, 600);
807 //canvas2->SetTopMargin(0.05);
808 //canvas2->SetRightMargin(0.05);
810 xSection->DrawCopy("HIST");
812 TLegend* legend2 = new TLegend(0.15, 0.15, 0.6, 0.3);
813 legend2->SetFillColor(0);
814 legend2->AddEntry(xSection, "no trigger");
816 TH1* proj2 = (TH1*) proj->Clone("random");
818 // MB lengthRun s 100 Hz
819 Int_t nTrigger = (Int_t) (100 * lengthRun * proj->Integral(1, 1000));
820 proj2->FillRandom(proj, nTrigger);
822 TH1* proj3 = (TH1*) proj2->Clone("random_clone");
824 proj3->Fit("pol0", "0", "");
825 proj2->Scale(1.0 / proj3->GetFunction("pol0")->GetParameter(0));
828 proj2->DrawCopy("SAME");
829 legend2->AddEntry(proj2, Form("%d evts, FO > %d chips (%d evts)", nTrigger, cut, (Int_t) (nTrigger * ratio)));
832 proj2 = (TH1*) proj->Clone("random2");
834 // 10^31 lum --> 1200 kHz; lengthRun s
835 nTrigger = (Int_t) (rate * proj->Integral(1, 1000) * lengthRun);
836 proj2->FillRandom(proj, nTrigger);
838 proj3 = (TH1*) proj2->Clone("random_clone2");
840 proj3->Fit("pol0", "0", "");
841 proj2->Scale(1.0 / proj3->GetFunction("pol0")->GetParameter(0));
843 proj2->SetLineColor(4);
844 proj2->SetMarkerStyle(7);
845 proj2->SetMarkerColor(4);
846 proj2->DrawCopy("SAME P");
847 //legend2->AddEntry(proj2, Form("%d evts, FO > %d chips (%d evts)", nTrigger, cut, (Int_t) (nTrigger * ratio)));
848 legend2->AddEntry(proj2, Form("FO trigger > %d chips", cut));
853 canvas2->SaveAs(Form("%s.gif", canvas2->GetName()));
854 canvas2->SaveAs(Form("%s.eps", canvas2->GetName()));
858 void AliHighMultiplicitySelector::Ntrigger(Bool_t relative)
861 // produces a spectrum created with N triggers
862 // number of triggers and thresholds for the moment fixed
867 gSystem->Load("libANALYSIS");
868 gSystem->Load("libPWG0base");
869 .L AliHighMultiplicitySelector.cxx+g
870 x = new AliHighMultiplicitySelector();
871 x->ReadHistograms("highmult_hijing100k.root");
874 gSystem->Load("libPWG0base");
875 .L AliHighMultiplicitySelector.cxx+g
876 x = new AliHighMultiplicitySelector();
877 x->ReadHistograms("highmult_hijing100k.root");
883 TFile* file = TFile::Open("crosssectionEx.root");
888 xSections[0] = dynamic_cast<TH1*> (gFile->Get("xSection2Ex"));
889 xSections[1] = dynamic_cast<TH1*> (gFile->Get("xSection15Ex"));
891 // 10^28 lum --> 1.2 kHz
892 // 10^31 lum --> 1200 kHz
893 //Float_t rate = 1200e3;
894 Float_t rate = 250e3;
897 Float_t lengthRun = 1e6;
899 Int_t colors[] = { 2, 3, 4, 6, 7, 8 };
900 Int_t markers[] = { 7, 2, 4, 5, 6, 27 };
902 // put to 2 for second layer
903 for (Int_t i=0; i<1; ++i)
908 TH1* xSection = xSections[i];
909 TH2* fMvsL = (i == 0) ? fMvsL1: fMvsL2;
912 //Int_t cuts[] = { 0, 164, 178, 190, 204, 216 };
914 //Int_t cuts[] = { 0, 164, 190, 216 };
917 //Int_t cuts[] = { 0, 114, 145, 165 };
918 //Float_t ratePerTrigger[] = { 60, 13.3, 13.3, 13.3 };
921 Int_t cuts[] = { 0, 126, 162 };
922 Float_t ratePerTrigger[] = { 60, 20.0, 20.0 };
924 // desired trigger rate in Hz
925 //Float_t ratePerTrigger[] = { 100, 1, 1, 1, 1, 1 };
927 xSection->SetStats(kFALSE);
928 xSection->SetTitle(""); //(i == 0) ? "SPD Layer 1" : "SPD Layer 2");
929 xSection->GetXaxis()->SetTitle(Form("true multiplicity in |#eta| < %.1f", (i == 0) ? 2.0 : 1.5));
930 xSection->GetXaxis()->SetRangeUser(0, (i == 0) ? 450 : 350);
931 //xSection->GetYaxis()->SetTitle("relative cross section");
932 xSection->GetYaxis()->SetTitleOffset(1.2);
934 // relative x-section, once we have a collision
935 xSection->Scale(1.0 / xSection->Integral());
937 TCanvas* canvas2 = new TCanvas(Form("HMPlots2_%d_Random", i), Form("HMPlots2_%d_Random", i), 800, 600);
938 canvas2->SetTopMargin(0.05);
939 canvas2->SetRightMargin(0.05);
943 xSection->DrawCopy("HIST");
945 TLegend* legend2 = new TLegend(0.15, 0.15, 0.6, 0.4);
946 legend2->SetFillColor(0);
947 legend2->AddEntry(xSection, "cross-section");
949 for (Int_t currentCut = 0; currentCut<nCuts; ++currentCut)
951 Int_t cut = cuts[currentCut];
953 TH1* triggerEff = (TH1*) GetTriggerEfficiency(fMvsL, cut)->Clone("triggerEff");
955 TH1* proj = GetXSectionCut(xSection, fMvsL, cut);
957 Float_t triggerLimit = 0;
958 for (Int_t bin = 1; bin <= triggerEff->GetNbinsX(); bin++)
959 if (triggerEff->GetBinContent(bin) < 0.5)
960 triggerLimit = triggerEff->GetXaxis()->GetBinCenter(bin);
962 Printf("Efficiency limit (50%%) is at multiplicity %f", triggerLimit);
965 if (proj->Integral(1, 1000) > 0)
966 total = proj->Integral(1, 1000);
968 printf("Cut at %d: rel. x-section = %e\n", cut, total);
970 TH1* proj2 = (TH1*) proj->Clone("random2");
973 // calculate downscale factor
974 Float_t normalRate = rate * proj->Integral(1, 1000);
975 Float_t downScale = normalRate / ratePerTrigger[currentCut];
978 Long64_t nTrigger = (Long64_t) (normalRate / downScale * lengthRun);
979 nTrigger = TMath::Nint(((Float_t) nTrigger) / 1000) * 1000;
981 Printf("Normal rate is %f, downscale: %f, Simulating %lld triggers", normalRate, downScale, nTrigger);
982 proj2->FillRandom(proj, nTrigger);
985 for (Int_t bin=1; bin<proj2->GetNbinsX(); ++bin)
986 if (proj2->GetBinContent(bin) < 5)
988 removed += (Int_t) proj2->GetBinContent(bin);
989 proj2->SetBinContent(bin, 0);
992 Printf("Removed %d events", removed);
995 proj2->Scale(1.0 / nTrigger * proj->Integral(1, 1000));
997 proj2->SetLineColor(colors[currentCut]);
998 proj2->SetMarkerStyle(markers[currentCut]);
999 proj2->SetMarkerColor(colors[currentCut]);
1001 if (relative || currentCut > 0) {
1002 proj2->DrawCopy("SAME P");
1004 proj2->DrawCopy(" P");
1009 eventStr.Form("%lld M", nTrigger / 1000 / 1000);
1011 else if (nTrigger > 1e3)
1013 eventStr.Form("%lld K", nTrigger / 1000);
1016 eventStr.Form("%lld", nTrigger);
1021 triggerStr = "minimum bias";
1024 triggerStr.Form("FO > %d chips", cut);
1026 legend2->AddEntry(proj2, Form("%s evts, %s", eventStr.Data(), triggerStr.Data()));
1028 if (triggerLimit > 1)
1030 TLine* line = new TLine(triggerLimit, proj2->GetMinimum(), triggerLimit, proj2->GetMaximum());
1031 line->SetLineColor(colors[currentCut]);
1038 canvas2->SaveAs(Form("%s.gif", canvas2->GetName()));
1039 canvas2->SaveAs(Form("%s.eps", canvas2->GetName()));
1043 void AliHighMultiplicitySelector::Contamination()
1046 // produces a spectrum created with N triggers
1047 // number of triggers and thresholds for the moment fixed
1052 gSystem->Load("libANALYSIS");
1053 gSystem->Load("libPWG0base");
1054 .L AliHighMultiplicitySelector.cxx+g
1055 x = new AliHighMultiplicitySelector();
1056 x->ReadHistograms("highmult_hijing100k.root");
1062 TFile* file = TFile::Open("crosssectionEx.root");
1067 xSections[0] = dynamic_cast<TH1*> (gFile->Get("xSection2Ex"));
1068 xSections[1] = dynamic_cast<TH1*> (gFile->Get("xSection15Ex"));
1071 // sigma ~ 80 mb (Pythia 14 TeV)
1072 // 10^28 lum --> 8e2 Hz
1073 // 10^31 lum --> 8e5 Hz
1074 Double_t rates[] = { 8e2, 8e3, 8e4, 8e5 };
1077 Int_t cuts[] = { 104, 134, 154, 170 };
1079 // put to 2 for second layer
1080 for (Int_t i=0; i<1; ++i)
1085 // relative x-section, once we have a collision
1086 xSections[i]->Scale(1.0 / xSections[i]->Integral());
1088 Int_t max = xSections[i]->GetNbinsX();
1091 Float_t* xSection = new Float_t[max];
1092 for (Int_t mult = 0; mult < max; mult++)
1093 xSection[mult] = xSections[i]->GetBinContent(mult+1);
1095 TH2* fMvsL = (i == 0) ? fMvsL1: fMvsL2;
1097 TGraph* graph = new TGraph;
1099 for (Int_t currentCut = 0; currentCut<nCuts; ++currentCut)
1101 Int_t cut = cuts[currentCut];
1102 Double_t rate = rates[currentCut];
1103 //Double_t rate = rates[3];
1105 // coll. in 100 ns window
1106 //Double_t windowSize = 100e-9;
1107 Double_t windowSize = 25e-9;
1108 Double_t collPerWindow = windowSize * rate;
1109 Printf("coll/window = %f", collPerWindow);
1110 Double_t windowsPerSecond = 1.0 / windowSize;
1112 TH1* triggerEffHist = (TH1*) GetTriggerEfficiency(fMvsL, cut)->Clone("triggerEff");
1113 Float_t* triggerEff = new Float_t[max];
1114 for (Int_t mult = 0; mult < max; mult++)
1115 triggerEff[mult] = triggerEffHist->GetBinContent(mult+1);
1117 Double_t triggerRate = 0;
1118 for (Int_t mult = 0; mult < max; mult++)
1119 triggerRate += xSection[mult] * triggerEff[mult];
1121 triggerRate *= TMath::Poisson(1, collPerWindow) * windowsPerSecond;
1123 Printf("Rate for 1 collision is %f Hz", triggerRate);
1125 Double_t triggerRate2 = 0;
1126 for (Int_t mult = 0; mult < max; mult++)
1127 for (Int_t mult2 = mult; mult2 < max; mult2++)
1128 if (mult+mult2 < max)
1129 triggerRate2 += ((mult2 > mult) ? 2. : 1.) * xSection[mult] * xSection[mult2] * triggerEff[mult+mult2];
1131 triggerRate2 *= TMath::Poisson(2, collPerWindow) * windowsPerSecond;
1133 Printf("Rate for 2 collisions is %f Hz --> %.1f%%", triggerRate2, triggerRate2 / triggerRate * 100);
1135 Double_t triggerRate3 = 0;
1137 for (Int_t mult = 0; mult < max; mult++)
1138 for (Int_t mult2 = mult; mult2 < max-mult; mult2++)
1139 for (Int_t mult3 = 0; mult3 < max-mult-mult2; mult3++)
1140 //if (mult+mult2+mult3 < max)
1141 triggerRate3 += ((mult2 > mult) ? 2. : 1.) * xSection[mult] * xSection[mult2] * xSection[mult3] * triggerEff[mult+mult2+mult3];
1143 triggerRate3 *= TMath::Poisson(3, collPerWindow) * windowsPerSecond;
1144 //triggerRate3 *= collPerWindow * collPerWindow * rate;
1146 Printf("Rate for 3 collisions is %f Hz --> %.1f%%", triggerRate3, triggerRate3 / triggerRate * 100);
1148 Float_t totalContamination = (triggerRate2 + triggerRate3) / (triggerRate + triggerRate2 + triggerRate3);
1150 Printf("Total contamination is %.1f%%", totalContamination * 100);
1152 graph->SetPoint(graph->GetN(), cut, totalContamination);
1156 Double_t triggerRate4 = 0;
1157 for (Int_t mult = 0; mult < max; mult++)
1158 for (Int_t mult2 = mult; mult2 < max-mult; mult2++)
1159 for (Int_t mult3 = 0; mult3 < max-mult-mult2; mult3++)
1160 for (Int_t mult4 = 0; mult4 < max-mult-mult2-mult3; mult4++)
1161 //if (mult+mult2+mult3+mult4 < max)
1162 triggerRate4 += ((mult2 > mult) ? 2. : 1.) * xSection[mult] * xSection[mult2] * xSection[mult3] * xSection[mult4] * triggerEff[mult+mult2+mult3+mult4];
1164 //triggerRate4 *= collPerWindow * collPerWindow * collPerWindow * rate;
1165 triggerRate4 *= TMath::Poisson(4, collPerWindow) * windowsPerSecond;
1167 Printf("Rate for 4 collisions is %f Hz --> %.1f%%", triggerRate4, triggerRate4 / triggerRate * 100);
1169 // general code for n collisions follows, however much slower...
1171 const Int_t maxdepth = 4;
1172 for (Int_t depth = 1; depth <= maxdepth; depth++) {
1173 Double_t triggerRate = 0;
1176 for (Int_t d=0; d<maxdepth; d++)
1179 while (m[0] < max) {
1182 for (Int_t d=0; d<depth; d++) {
1183 value *= xSection[m[d]];
1188 value *= triggerEff[sum];
1189 triggerRate += value;
1192 Int_t increase = depth-1;
1194 while (m[increase] == max && increase > 0) {
1201 triggerRate *= rate * TMath::Power(collPerWindow, depth - 1);
1203 Printf("Rate for %d collisions is %f Hz", depth, triggerRate);
1207 new TCanvas; graph->Draw("AP*");
1211 void AliHighMultiplicitySelector::Contamination2()
1214 // produces a spectrum created with N triggers
1215 // number of triggers and thresholds for the moment fixed
1220 gSystem->Load("libANALYSIS");
1221 gSystem->Load("libPWG0base");
1222 .L AliHighMultiplicitySelector.cxx+g
1223 x = new AliHighMultiplicitySelector();
1224 x->ReadHistograms("highmult_hijing100k.root");
1225 x->Contamination2();
1230 TFile* file = TFile::Open("crosssectionEx.root");
1235 xSections[0] = dynamic_cast<TH1*> (gFile->Get("xSection2Ex"));
1236 xSections[1] = dynamic_cast<TH1*> (gFile->Get("xSection15Ex"));
1239 Int_t cuts[] = { 104, 134, 154, 170 };
1243 Int_t colors[] = { 2, 3, 4, 6, 7, 8 };
1244 Int_t markers[] = { 7, 2, 4, 5, 6, 27 };
1246 // put to 2 for second layer
1247 for (Int_t i=0; i<1; ++i)
1252 // relative x-section, once we have a collision
1253 xSections[i]->Scale(1.0 / xSections[i]->Integral());
1255 Int_t max = xSections[i]->GetNbinsX();
1258 Float_t* xSection = new Float_t[max];
1259 for (Int_t mult = 0; mult < max; mult++)
1260 xSection[mult] = xSections[i]->GetBinContent(mult+1);
1262 TH2* fMvsL = (i == 0) ? fMvsL1: fMvsL2;
1264 for (Int_t currentCut = 0; currentCut<nCuts; ++currentCut)
1266 TGraph* graph = new TGraph;
1267 graph->SetMarkerColor(colors[currentCut]);
1268 graph->SetMarkerStyle(markers[currentCut]);
1270 Int_t cut = cuts[currentCut];
1272 TH1* triggerEffHist = (TH1*) GetTriggerEfficiency(fMvsL, cut)->Clone("triggerEff");
1273 Float_t* triggerEff = new Float_t[max];
1274 for (Int_t mult = 0; mult < max; mult++)
1275 triggerEff[mult] = triggerEffHist->GetBinContent(mult+1);
1277 Double_t triggerRate = 0;
1278 for (Int_t mult = 0; mult < max; mult++)
1279 triggerRate += xSection[mult] * triggerEff[mult];
1281 Printf("Raw value for 1 collision is %e", triggerRate);
1283 Double_t triggerRate2 = 0;
1284 for (Int_t mult = 0; mult < max; mult++)
1285 for (Int_t mult2 = mult; mult2 < max; mult2++)
1286 if (mult+mult2 < max)
1287 triggerRate2 += ((mult2 > mult) ? 2. : 1.) * xSection[mult] * xSection[mult2] * triggerEff[mult+mult2];
1289 Printf("Raw value for 2 collisions is %e", triggerRate2);
1291 for (Double_t doubleRate = 0; doubleRate <= 0.2; doubleRate += 0.005)
1293 Float_t totalContamination = (triggerRate2 * doubleRate) / (triggerRate + triggerRate2 * doubleRate);
1295 //Printf("Total contamination is %.1f%%", totalContamination * 100);
1297 graph->SetPoint(graph->GetN(), doubleRate, totalContamination);
1300 graph->Draw((currentCut == 0) ? "A*" : "* SAME");
1301 graph->GetXaxis()->SetRangeUser(0, 1);
1306 void AliHighMultiplicitySelector::DrawHistograms()
1308 // draws the histograms
1312 gSystem->Load("libPWG0base");
1313 .L AliHighMultiplicitySelector.cxx+
1314 x = new AliHighMultiplicitySelector();
1315 x->ReadHistograms("highmult_pythia.root");
1316 x->DrawHistograms();
1319 gSystem->Load("libPWG0base");
1320 .L AliHighMultiplicitySelector.cxx+
1321 x = new AliHighMultiplicitySelector();
1322 x->ReadHistograms("highmult_hijing.root");
1323 x->DrawHistograms();
1325 gSystem->Load("libPWG0base");
1326 .L AliHighMultiplicitySelector.cxx+
1327 x = new AliHighMultiplicitySelector();
1328 x->ReadHistograms("highmult_central.root");
1329 x->DrawHistograms();
1331 gSystem->Load("libANALYSIS");
1332 gSystem->Load("libPWG0base");
1333 .L AliHighMultiplicitySelector.cxx+
1334 x = new AliHighMultiplicitySelector();
1335 x->ReadHistograms("highmult_hijing100k.root");
1336 x->DrawHistograms();
1340 /*TCanvas* canvas = new TCanvas("chips", "chips", 600, 400);
1342 fChipsLayer2->SetLineColor(2);
1343 fChipsLayer2->SetStats(kFALSE);
1344 fChipsLayer1->SetStats(kFALSE);
1345 fChipsLayer2->SetTitle("");
1346 fChipsLayer2->DrawCopy();
1347 fChipsLayer1->DrawCopy("SAME");
1348 canvas->SaveAs("chips.gif");
1350 canvas = new TCanvas("L1vsL2", "L1vsL2", 600, 400);
1351 fL1vsL2->SetStats(kFALSE);
1352 fL1vsL2->DrawCopy("COLZ");
1354 canvas->SaveAs("L1vsL2.gif");*/
1356 TCanvas *canvas = new TCanvas("L1", "L1", 800, 600);
1357 canvas->SetTopMargin(0.05);
1358 canvas->SetRightMargin(0.12);
1359 fMvsL1->SetStats(kFALSE);
1360 fMvsL1->DrawCopy("COLZ");
1363 canvas->SaveAs("L1NoCurve.gif");
1364 canvas->SaveAs("L1NoCurve.eps");
1366 TLine* line = new TLine(fMvsL1->GetXaxis()->GetXmin(), 150, fMvsL1->GetXaxis()->GetXmax(), 150);
1367 line->SetLineWidth(2);
1368 line->SetLineColor(kRed);
1371 canvas->SaveAs("L1NoCurveCut.gif");
1372 canvas->SaveAs("L1NoCurveCut.eps");
1376 // draw corresponding theoretical curve
1377 TF1* func = new TF1("func", "[0]*(1-(1-1/[0])**x)", 1, 1000);
1378 func->SetParameter(0, 400-5*2);
1379 func->DrawCopy("SAME");
1381 canvas->SaveAs("L1.gif");
1383 canvas = new TCanvas("L2", "L2", 600, 400);
1384 //fMvsL2->GetYaxis()->SetRangeUser(0, 150);
1385 fMvsL2->SetStats(kFALSE);
1386 fMvsL2->DrawCopy("COLZ");
1388 func->SetParameter(0, 800-5*4);
1389 func->DrawCopy("SAME");
1390 canvas->SaveAs("L2.gif");
1393 TFile* file = TFile::Open("crosssectionEx.root");
1396 TH1* xSection2 = dynamic_cast<TH1*> (gFile->Get("xSection2Ex"));
1397 TH1* xSection15 = dynamic_cast<TH1*> (gFile->Get("xSection15Ex"));
1399 MakeGraphs2("Layer1", xSection2, fMvsL1);
1403 //MakeGraphs("Layer1", xSection2, fMvsL1, (Int_t) (xSection2->GetMean() * 5)); //75 * 2 * 2);
1404 //MakeGraphs("Layer2", xSection15, fMvsL2, (Int_t) (xSection15->GetMean() * 5)); //(Int_t) (75 * 1.5 * 2));
1406 MakeGraphs("Layer1", xSection2, fMvsL1, (Int_t) (xSection2->GetMean() * 8));
1407 MakeGraphs("Layer2", xSection15, fMvsL2, (Int_t) (xSection15->GetMean() * 8));
1408 MakeGraphs("Layer1", xSection2, fMvsL1, (Int_t) (xSection2->GetMean() * 9));
1409 MakeGraphs("Layer2", xSection15, fMvsL2, (Int_t) (xSection15->GetMean() * 9));
1410 MakeGraphs("Layer1", xSection2, fMvsL1, (Int_t) (xSection2->GetMean() * 10));
1411 MakeGraphs("Layer2", xSection15, fMvsL2, (Int_t) (xSection15->GetMean() * 10));
1416 // make spread hists
1417 TGraph* spread = new TGraph;
1418 spread->SetTitle("Spread L1;true multiplicity;RMS");
1420 for (Int_t i=1; i<=fMvsL1->GetNbinsX(); ++i)
1422 TH1* proj = fMvsL1->ProjectionY("proj", i, i);
1423 spread->SetPoint(spread->GetN(), i, proj->GetRMS());
1426 canvas = new TCanvas("SpreadL1", "SpreadL1", 600, 400);
1428 canvas->SaveAs(Form("%s.gif", canvas->GetName()));
1430 TF1* log = new TF1("log", "[0]*log([1]*x)", 1, 150);
1431 log->SetParLimits(0, 0, 10);
1432 log->SetParLimits(1, 1e-5, 10);
1434 spread->Fit(log, "", "", 1, 150);
1435 log->DrawCopy("SAME");
1437 TGraph* spread2 = new TGraph;
1438 spread2->SetTitle("Spread L2;true multiplicity;RMS");
1440 for (Int_t i=1; i<=fMvsL1->GetNbinsX(); ++i)
1442 TH1* proj = fMvsL2->ProjectionY("proj", i, i);
1443 spread2->SetPoint(spread2->GetN(), i, proj->GetRMS());
1446 canvas = new TCanvas("SpreadL2", "SpreadL2", 600, 400);
1447 spread2->Draw("A*");
1448 canvas->SaveAs(Form("%s.gif", canvas->GetName()));
1450 spread2->Fit(log, "", "", 1, 150);
1451 log->DrawCopy("SAME");
1453 canvas = new TCanvas("Clusters_L1", "Clusters_L1", 600, 400);
1454 fClvsL1->SetStats(kFALSE);
1455 fClvsL1->DrawCopy("COLZ");
1458 func->SetParameter(0, 400-5*2);
1459 func->DrawCopy("SAME");
1461 canvas->SaveAs("Clusters_L1.gif");
1463 canvas = new TCanvas("Clusters_L2", "Clusters_L2", 600, 400);
1464 fClvsL2->SetStats(kFALSE);
1465 fClvsL2->DrawCopy("COLZ");
1467 func->SetParameter(0, 800-5*4);
1468 func->DrawCopy("SAME");
1469 canvas->SaveAs("Clusters_L2.gif");
1471 canvas = new TCanvas("ChipsFired", "ChipsFired", 600, 400);
1472 //fChipsFired->GetYaxis()->SetRangeUser(0, 150);
1473 fChipsFired->SetStats(kFALSE);
1474 fChipsFired->DrawCopy("COLZ");
1475 canvas->SaveAs("ChipsFired.gif");
1477 /*TH1F* tresholdHistL1 = new TH1F("tresholdHistL1", ";chip treshold;<n>", BINNING_LAYER1);
1478 TH1F* tresholdHistL2 = new TH1F("tresholdHistL2", ";chip treshold;<n>", BINNING_LAYER2);
1480 for (Int_t treshold = 0; treshold < 800; treshold++)
1482 if (fPrimaryL1->Draw("multiplicity>>mult", Form("firedChips>%d", treshold), "goff") > 0)
1484 TH1F* mult = dynamic_cast<TH1F*> (fPrimaryL1->GetHistogram());
1486 tresholdHistL1->Fill(treshold, mult->GetMean());
1488 if (fPrimaryL2->Draw("multiplicity>>mult", Form("firedChips>%d", treshold), "goff") > 0)
1490 TH1F* mult = dynamic_cast<TH1F*> (fPrimaryL2->GetHistogram());
1492 tresholdHistL2->Fill(treshold, mult->GetMean());
1496 canvas = new TCanvas("TresholdL1", "TresholdL1", 600, 400);
1497 tresholdHistL1->Draw();
1498 canvas->SaveAs(Form("%s.gif", canvas->GetName()));
1500 canvas = new TCanvas("TresholdL2", "TresholdL2", 600, 400);
1501 tresholdHistL2->Draw();
1502 canvas->SaveAs(Form("%s.gif", canvas->GetName()));*/
1504 fPrimaryL1->Draw("(chipsByPrimaries/firedChips):multiplicity>>eff1", "", "prof goff");
1505 fPrimaryL2->Draw("(chipsByPrimaries/firedChips):multiplicity>>eff2", "", "prof goff");
1507 canvas = new TCanvas("Efficiency", "Efficiency", 600, 400);
1508 fPrimaryL1->GetHistogram()->SetStats(kFALSE);
1509 fPrimaryL1->GetHistogram()->Draw();
1510 fPrimaryL2->GetHistogram()->SetLineColor(2);
1511 fPrimaryL2->GetHistogram()->SetStats(kFALSE);
1512 fPrimaryL2->GetHistogram()->Draw("SAME");
1513 canvas->SaveAs(Form("%s.gif", canvas->GetName()));
1515 canvas = new TCanvas("ClustersZL1", "ClustersZL1", 600, 400);
1516 fClusterZL1->Rebin(2);
1517 fClusterZL1->Draw();
1518 canvas->SaveAs(Form("%s.gif", canvas->GetName()));
1520 canvas = new TCanvas("ClustersZL2", "ClustersZL2", 600, 400);
1521 fClusterZL2->Draw();
1522 fClusterZL2->Rebin(2);
1523 canvas->SaveAs(Form("%s.gif", canvas->GetName()));
1526 TGraph* AliHighMultiplicitySelector::IntFractRate()
1528 // A plot which shows the fractional rate above any threshold
1529 // as function of threshold (i.e. the integral of dSigma/dN as function of
1530 // N, normalised to 1 for N=0)
1533 gSystem->Load("libANALYSIS");
1534 gSystem->Load("libPWG0base");
1535 .L AliHighMultiplicitySelector.cxx+
1536 x = new AliHighMultiplicitySelector();
1537 x->ReadHistograms("highmult_hijing100k.root");
1542 TFile* file = TFile::Open("crosssectionEx.root");
1547 xSection = dynamic_cast<TH1*> (gFile->Get("xSection2Ex"));
1549 TGraph* result = new TGraph;
1551 for (Int_t threshold = 0; threshold < 300; threshold += 2)
1553 TH1* proj = GetXSectionCut(xSection, fMvsL1, threshold);
1555 //new TCanvas; proj->DrawCopy();
1557 Double_t integral = proj->Integral();
1559 Printf("Cut at %d, integral is %e", threshold, integral);
1561 result->SetPoint(result->GetN(), threshold, integral);
1564 TCanvas* canvas = new TCanvas("IntFractRate", "IntFractRate", 600, 400);
1568 result->GetXaxis()->SetTitle("threshold");
1569 result->GetYaxis()->SetTitle("integrated fractional rate above threshold");
1571 canvas->SaveAs(Form("%s.gif", canvas->GetName()));
1576 void AliHighMultiplicitySelector::MBComparison()
1579 // finds the threshold from which onwards the number of found events above N times the mean
1580 // is higher using a high mult. trigger than just triggering with MB
1585 gSystem->Load("libANALYSIS");
1586 gSystem->Load("libPWG0base");
1587 .L AliHighMultiplicitySelector.cxx+g
1588 x = new AliHighMultiplicitySelector();
1589 x->ReadHistograms("highmult_hijing100k.root");
1595 TFile* file = TFile::Open("crosssectionEx.root");
1600 xSections[0] = dynamic_cast<TH1*> (gFile->Get("xSection2Ex"));
1601 xSections[1] = dynamic_cast<TH1*> (gFile->Get("xSection15Ex"));
1604 // sigma ~ 80 mb (Pythia 14 TeV)
1605 // 10^28 lum --> 8e2 Hz
1606 // 10^31 lum --> 8e5 Hz
1608 Double_t rates[] = { 8e2, 8e3, 8e4, 8e5 };
1610 // threshold in number of fired chips for corresponding rate
1611 //Int_t cuts[] = { 104, 134, 154, 170 }; // values for 20 Hz
1612 Int_t cuts[] = { 82, 124, 147, 164 }; // values for 50 Hz
1614 // bandwidth, fractions (for MB, high mult.)
1615 Float_t bandwidth = 1e3;
1616 Float_t fractionMB = 0.5;
1617 Float_t fractionHM = 0.05;
1619 // different limits to define "interesting events"
1621 Int_t limits[] = { 0, 1, 2, 4, 6, 7, 8, 9, 10 };
1623 // put to 2 for second layer
1624 for (Int_t i=0; i<1; ++i)
1629 TH1* xSection = xSections[i];
1630 TH2* fMvsL = (i == 0) ? fMvsL1: fMvsL2;
1632 // relative x-section, once we have a collision
1633 xSection->Scale(1.0 / xSection->Integral());
1635 xSection->SetStats(kFALSE);
1636 xSection->SetTitle(""); //(i == 0) ? "SPD Layer 1" : "SPD Layer 2");
1637 xSection->GetXaxis()->SetTitle(Form("true multiplicity in |#eta| < %.1f", (i == 0) ? 2.0 : 1.5));
1638 xSection->GetXaxis()->SetRangeUser(0, (i == 0) ? 450 : 350);
1639 xSection->GetYaxis()->SetTitleOffset(1.2);
1641 TCanvas* canvas = new TCanvas("MBComparison", "MBComparison", 1000, 800);
1642 canvas->Divide(3, 3);
1644 for (Int_t currentLimit = 0; currentLimit<nLimits; currentLimit++)
1646 // limit is N times the mean
1647 Int_t limit = (Int_t) (xSection->GetMean() * limits[currentLimit]);
1651 TGraph* graphMB = new TGraph;
1652 graphMB->SetTitle(Form("Events with %d times above <n> (i.e. n >= %d)", limits[currentLimit], limit));
1653 graphMB->SetMarkerStyle(20);
1655 TGraph* graphBoth = new TGraph;
1656 graphBoth->SetMarkerStyle(21);
1658 Float_t min = bandwidth;
1661 for (Int_t current = 0; current<nRates; ++current)
1663 Float_t rate = rates[current];
1664 Int_t cut = cuts[current];
1666 TH1* triggerEff = (TH1*) GetTriggerEfficiency(fMvsL, cut)->Clone("triggerEff");
1667 TH1* proj = GetXSectionCut(xSection, fMvsL, cut);
1669 Float_t downScaleMB1 = rate / bandwidth;
1670 if (downScaleMB1 < 1)
1673 Float_t downScaleMB2 = rate / (bandwidth * fractionMB);
1674 if (downScaleMB2 < 1)
1677 Float_t downScaleHM = rate * proj->Integral(1, xSection->GetNbinsX()) / (bandwidth * fractionHM);
1678 if (downScaleHM < 1)
1681 Float_t rateMB1 = rate / downScaleMB1 * xSection->Integral(limit, xSection->GetNbinsX());
1682 Float_t rateMB2 = rate / downScaleMB2 * xSection->Integral(limit, xSection->GetNbinsX());
1683 Float_t rateHM = rate / downScaleHM * proj->Integral(limit, xSection->GetNbinsX());
1684 Float_t combinedRate = rateMB2 + rateHM;
1686 graphMB->SetPoint(graphMB->GetN(), rate, rateMB1);
1687 graphBoth->SetPoint(graphBoth->GetN(), rate, combinedRate);
1689 min = TMath::Min(min, TMath::Min(rateMB1, combinedRate));
1690 max = TMath::Max(min, TMath::Max(rateMB1, combinedRate));
1692 Printf("The rates for events with %d times above <n> (i.e. n >= %d) at a rate of %.2e Hz is:", limits[currentLimit], limit, rate);
1693 Printf(" %.2e Hz in MB-only mode", rateMB1);
1694 Printf(" %.2e Hz = %.2e Hz + %.2e Hz in MB + high mult. mode", combinedRate, rateMB2, rateHM);
1696 Printf(" The downscale factors are: %.2f %.2f %.2f", downScaleMB1, downScaleMB2, downScaleHM);
1698 Int_t triggerLimit = 0;
1699 for (Int_t bin = 1; bin <= triggerEff->GetNbinsX(); bin++)
1700 if (triggerEff->GetBinContent(bin) < 0.5)
1701 triggerLimit = (Int_t) triggerEff->GetXaxis()->GetBinCenter(bin);
1703 Printf(" Efficiency limit (50%%) is at multiplicity %d", triggerLimit);
1704 Float_t fractionGood = proj->Integral(triggerLimit, proj->GetNbinsX()) / proj->Integral();
1705 Printf(" %.2f %% of the events are above the trigger limit", fractionGood * 100);
1707 if (triggerLimit > limit)
1708 Printf(" WARNING: interesting events also counted inside the trigger limit");
1713 canvas->cd(currentLimit+1)->SetLogx();
1714 canvas->cd(currentLimit+1)->SetLogy();
1716 graphMB->Draw("AP");
1717 graphBoth->Draw("P SAME");
1719 graphMB->GetYaxis()->SetRangeUser(0.5 * min, 2 * max);
1720 graphMB->GetXaxis()->SetTitle("Raw rate in Hz");
1721 graphMB->GetYaxis()->SetTitle("Event rate in Hz");