|
| 1 | +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. |
| 2 | +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. |
| 3 | +// All rights not expressly granted are reserved. |
| 4 | +// |
| 5 | +// This software is distributed under the terms of the GNU General Public |
| 6 | +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". |
| 7 | +// |
| 8 | +// In applying this license CERN does not waive the privileges and immunities |
| 9 | +// granted to it by virtue of its status as an Intergovernmental Organization |
| 10 | +// or submit itself to any jurisdiction. |
| 11 | + |
| 12 | +/// \file CheckChipResponseFile.C |
| 13 | +/// \brief Simple macro to check the chip response files |
| 14 | + |
| 15 | +#if !defined(__CLING__) || defined(__ROOTCLING__) |
| 16 | +#include <TFile.h> |
| 17 | +#include <TGraph.h> |
| 18 | +#include <TCanvas.h> |
| 19 | +#include <TH1.h> |
| 20 | +#include <TLegend.h> |
| 21 | +#include <iostream> |
| 22 | +#include <vector> |
| 23 | +#include <string> |
| 24 | + |
| 25 | +#define ENABLE_UPGRADES |
| 26 | +#include "ITSMFTSimulation/AlpideSimResponse.h" |
| 27 | + |
| 28 | +#include "ITS3Base/SegmentationMosaix.h" |
| 29 | +#include "fairlogger/Logger.h" |
| 30 | +#endif |
| 31 | + |
| 32 | +using SegmentationMosaix = o2::its3::SegmentationMosaix; |
| 33 | + |
| 34 | +double um2cm(double um) { return um * 1e-4; } |
| 35 | +double cm2um(double cm) { return cm * 1e+4; } |
| 36 | + |
| 37 | +o2::itsmft::AlpideSimResponse *mAlpSimResp0 = nullptr, |
| 38 | + *mAlpSimResp1 = nullptr, |
| 39 | + *mAptSimResp1 = nullptr; |
| 40 | + |
| 41 | +o2::itsmft::AlpideSimResponse* loadResponse(const std::string& fileName, const std::string& respName) |
| 42 | +{ |
| 43 | + TFile* f = TFile::Open(fileName.data()); |
| 44 | + if (!f) { |
| 45 | + std::cerr << fileName << " not found" << std::endl; |
| 46 | + return nullptr; |
| 47 | + } |
| 48 | + auto resp = (o2::itsmft::AlpideSimResponse*)f->Get(respName.data()); |
| 49 | + if (!resp) |
| 50 | + std::cerr << respName << " not found in " << fileName << std::endl; |
| 51 | + return resp; |
| 52 | +} |
| 53 | + |
| 54 | +void LoadRespFunc() |
| 55 | +{ |
| 56 | + std::string AptsFile = "$(O2_ROOT)/share/Detectors/Upgrades/ITS3/data/ITS3ChipResponseData/APTSResponseData.root"; |
| 57 | + std::string AlpideFile = "$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root"; |
| 58 | + |
| 59 | + mAlpSimResp0 = loadResponse(AlpideFile, "response0"); // Vbb=0V |
| 60 | + LOG(info) << "ALPIDE Vbb=0V response" << std::endl; |
| 61 | + mAlpSimResp0->print(); |
| 62 | + mAlpSimResp1 = loadResponse(AlpideFile, "response1"); // Vbb=-3V |
| 63 | + LOG(info) << "ALPIDE Vbb=-3V response" << std::endl; |
| 64 | + mAlpSimResp1->print(); |
| 65 | + mAptSimResp1 = loadResponse(AptsFile, "response1"); // APTS |
| 66 | + LOG(info) << "APTS response" << std::endl; |
| 67 | + mAptSimResp1->print(); |
| 68 | +} |
| 69 | + |
| 70 | +std::vector<float> getCollectionSeediciencies(o2::itsmft::AlpideSimResponse* resp, |
| 71 | + const std::vector<float>& depths) |
| 72 | +{ |
| 73 | + std::vector<float> seed; |
| 74 | + bool flipRow = false, flipCol = false; |
| 75 | + for (auto depth : depths) { |
| 76 | + auto rspmat = resp->getResponse(0.0, 0.0, |
| 77 | + um2cm(depth) + resp->getDepthMin() + 1.e-9, |
| 78 | + flipRow, flipCol); |
| 79 | + seed.push_back(rspmat ? rspmat->getValue(2, 2) : 0.f); |
| 80 | + } |
| 81 | + return seed; |
| 82 | +} |
| 83 | + |
| 84 | +std::vector<float> getShareValues(o2::itsmft::AlpideSimResponse* resp, |
| 85 | + const std::vector<float>& depths) |
| 86 | +{ |
| 87 | + std::vector<float> share; |
| 88 | + bool flipRow = false, flipCol = false; |
| 89 | + for (auto depth : depths) { |
| 90 | + auto rspmat = resp->getResponse(0.0, 0.0, |
| 91 | + um2cm(depth) + resp->getDepthMin() + 1.e-9, |
| 92 | + flipRow, flipCol); |
| 93 | + float s = 0; |
| 94 | + int npix = resp->getNPix(); |
| 95 | + if (rspmat) { |
| 96 | + for (int i = 0; i < npix; ++i) |
| 97 | + for (int j = 0; j < npix; ++j) |
| 98 | + if (!(i == npix / 2 && j == npix / 2)) |
| 99 | + s += rspmat->getValue(i, j); |
| 100 | + } |
| 101 | + share.push_back(s); |
| 102 | + } |
| 103 | + return share; |
| 104 | +} |
| 105 | + |
| 106 | +std::vector<float> getEffValues(o2::itsmft::AlpideSimResponse* resp, |
| 107 | + const std::vector<float>& depths) |
| 108 | +{ |
| 109 | + std::vector<float> all; |
| 110 | + bool flipRow = false, flipCol = false; |
| 111 | + for (auto depth : depths) { |
| 112 | + auto rspmat = resp->getResponse(0.0, 0.0, |
| 113 | + um2cm(depth) + resp->getDepthMin() + 1.e-9, |
| 114 | + flipRow, flipCol); |
| 115 | + float s = 0; |
| 116 | + int npix = resp->getNPix(); |
| 117 | + if (rspmat) { |
| 118 | + for (int i = 0; i < npix; ++i) |
| 119 | + for (int j = 0; j < npix; ++j) |
| 120 | + s += rspmat->getValue(i, j); |
| 121 | + } |
| 122 | + all.push_back(s); |
| 123 | + } |
| 124 | + return all; |
| 125 | +} |
| 126 | + |
| 127 | +void CheckChipResponseFile() |
| 128 | +{ |
| 129 | + LoadRespFunc(); |
| 130 | + LOG(info) << "Response function loaded" << std::endl; |
| 131 | + |
| 132 | + std::vector<float> vecDepth(50); |
| 133 | + for (int i = 0; i < 50; ++i) |
| 134 | + vecDepth[i] = i; |
| 135 | + |
| 136 | + int colors[] = {kOrange + 7, kRed + 1, kAzure + 4}; |
| 137 | + struct RespInfo { |
| 138 | + o2::itsmft::AlpideSimResponse* resp; |
| 139 | + std::string title; |
| 140 | + int color; |
| 141 | + }; |
| 142 | + std::vector<RespInfo> responses = { |
| 143 | + {mAptSimResp1, "APTS", colors[0]}, |
| 144 | + {mAlpSimResp0, "ALPIDE Vbb=0V", colors[1]}, |
| 145 | + {mAlpSimResp1, "ALPIDE Vbb=-3V", colors[2]}}; |
| 146 | + |
| 147 | + TCanvas* c1 = new TCanvas("c1", "c1", 800, 600); |
| 148 | + TH1* frame = c1->DrawFrame(-1, -0.049, 50, 1.049); |
| 149 | + frame->SetTitle(";Depth(um);Charge Collection Seed / Share / Eff"); |
| 150 | + TLegend* leg = new TLegend(0.15, 0.5, 0.4, 0.85); |
| 151 | + leg->SetFillStyle(0); |
| 152 | + leg->SetBorderSize(0); |
| 153 | + |
| 154 | + for (auto& r : responses) { |
| 155 | + if (!r.resp) |
| 156 | + continue; |
| 157 | + auto seed = getCollectionSeediciencies(r.resp, vecDepth); |
| 158 | + auto shr = getShareValues(r.resp, vecDepth); |
| 159 | + auto all = getEffValues(r.resp, vecDepth); |
| 160 | + |
| 161 | + TGraph* grSeed = new TGraph(vecDepth.size(), vecDepth.data(), seed.data()); |
| 162 | + grSeed->SetTitle(Form("%s seed", r.title.c_str())); |
| 163 | + grSeed->SetLineColor(r.color); |
| 164 | + grSeed->SetLineWidth(2); |
| 165 | + grSeed->SetMarkerColor(r.color); |
| 166 | + grSeed->SetMarkerStyle(kFullCircle); |
| 167 | + grSeed->SetMarkerSize(0.8); |
| 168 | + grSeed->Draw("SAME LP"); |
| 169 | + leg->AddEntry(grSeed, Form("%s seed", r.title.c_str()), "lp"); |
| 170 | + |
| 171 | + TGraph* grShare = new TGraph(vecDepth.size(), vecDepth.data(), shr.data()); |
| 172 | + grShare->SetLineColor(r.color); |
| 173 | + grShare->SetLineWidth(2); |
| 174 | + grShare->SetMarkerColor(r.color); |
| 175 | + grShare->SetMarkerStyle(kOpenSquare); |
| 176 | + grShare->SetMarkerSize(1); |
| 177 | + grShare->Draw("SAME LP"); |
| 178 | + leg->AddEntry(grShare, Form("%s share", r.title.c_str()), "p"); |
| 179 | + |
| 180 | + TGraph* grEff = new TGraph(vecDepth.size(), vecDepth.data(), all.data()); |
| 181 | + grEff->SetLineColor(r.color); |
| 182 | + grEff->SetLineWidth(2); |
| 183 | + grEff->SetMarkerColor(r.color); |
| 184 | + grEff->SetMarkerStyle(kFullDiamond); |
| 185 | + grEff->SetMarkerSize(1); |
| 186 | + grEff->Draw("SAME LP"); |
| 187 | + leg->AddEntry(grEff, Form("%s eff", r.title.c_str()), "p"); |
| 188 | + } |
| 189 | + leg->Draw(); |
| 190 | + |
| 191 | + c1->SaveAs("ChipResponse.pdf"); |
| 192 | +} |
0 commit comments