29 TString GetFileNameBaseFromPath(
const TString& path);
39 const Int_t binAmount,
const TString& runId =
"");
53 void SetNoiseThreshold(
const Int_t noiseThreshold) {fNoiseThreshold = noiseThreshold;}
54 void SetDeadLayersPerStrip(
const std::vector<Double_t> &deadLayers);
56 void ReadThresholds();
59 TString fThresholdFilePath;
60 TString fCalibFilePath;
61 Int_t fStripAmount = 16;
62 Int_t fBinAmount = 1024;
64 Int_t fNoiseThreshold = 0;
66 Bool_t fIsDeadLayerPerStripsSet =
false;
67 std::vector<Double_t> fDeadLayers = std::vector<Double_t>();
70 SensorRunInfo::SensorRunInfo(
const TString& name,
const Int_t stripAmount,
71 const Int_t binAmount,
const TString& runId =
""):
73 fStripAmount(stripAmount),
74 fBinAmount(binAmount),
75 fRunId(GetFileNameBaseFromPath(runId)) {
78 void SensorRunInfo::SetDeadLayersPerStrip(
const std::vector<Double_t> &deadLayersPerStrip) {
79 if (deadLayersPerStrip.size() != this->fStripAmount) {
81 "SensorRunInfo::SetDeadLayersPerStrip",
82 "Dead thickness amount set by user (%ld) doesn't equal strips amount (%d)",
83 deadLayersPerStrip.size(), this->fStripAmount);
86 fIsDeadLayerPerStripsSet =
true;
87 fDeadLayers = deadLayersPerStrip;
95 Double_t CalculateAvg(T values) {
97 Int_t counterNotNaN = 0;
98 for (
const auto& value: values) {
99 if (!std::isnan(value)) {
104 return sum / counterNotNaN;
116 void DrawSensorSpectraByStrip(TTree* tree,
118 const std::vector<UShort_t>& thresholds) {
119 const auto canvas =
new TCanvas(Form(
"canvas_%s", sensor->fName.Data()));
121 Int_t canvFirtsDim = std::round(std::sqrt(sensor->fStripAmount));
122 Int_t canvSecondDim = 1;
123 for (; canvSecondDim*canvFirtsDim < sensor->fStripAmount; canvSecondDim++) {}
124 canvas->Divide(canvFirtsDim, canvSecondDim);
126 for (Int_t iStrip = 0; iStrip < sensor->fStripAmount; iStrip++) {
127 const TString histParams = Form(
"(%d,%d,%d)", sensor->fBinAmount, 0, sensor->fBinAmount);
128 const TString histName = Form(
"strip_%d", iStrip);
129 const TString drawExpression = Form(
130 "%s[%d]>>%s%s", sensor->fName.Data(), iStrip, histName.Data(), histParams.Data()
132 const TString cutExpression = Form(
133 "%s[%d]>%d", sensor->fName.Data(), iStrip, thresholds[iStrip]
135 canvas->cd(iStrip + 1);
136 tree->Draw(drawExpression, cutExpression,
"");
137 const auto hist =
static_cast<TH1D*
>(gDirectory->Get(histName));
156 void DrawSensorSpectraByPixel(TTree* tree,
159 const std::vector<UShort_t>& thresholdsDraw,
160 const std::vector<UShort_t>& thresholdsSelect) {
162 Int_t canvFirtsDim = std::round(std::sqrt(sensorDraw->fStripAmount));
163 Int_t canvSecondDim = 1;
164 for (; canvSecondDim*canvFirtsDim < sensorDraw->fStripAmount; canvSecondDim++) {}
166 for (Int_t iStripDraw = 0; iStripDraw < sensorDraw->fStripAmount; iStripDraw++) {
167 const auto canvasName = Form(
"canvas_%s[%d]", sensorDraw->fName.Data(), iStripDraw);
168 const auto canvas =
new TCanvas(canvasName);
169 canvas->Divide(canvFirtsDim, canvSecondDim);
170 for (Int_t iStripSelect = 0; iStripSelect < sensorSelect->fStripAmount; iStripSelect++) {
171 Info(
"DrawSensorSpectraByPixel",
"Pixel %s[%d]-%s[%d] in progress",
172 sensorDraw->fName.Data(), iStripDraw,
173 sensorSelect->fName.Data(), iStripSelect);
174 const auto histParams = Form(
"(%d,%d,%d)",
175 sensorDraw->fBinAmount, 0, sensorDraw->fBinAmount);
176 const auto histName = Form(
"pixel_%s[%d]_%s[%d]", sensorDraw->fName.Data(), iStripDraw,
177 sensorSelect->fName.Data(), iStripSelect);
178 const auto drawExpression = Form(
"%s[%d]>>%s%s", sensorDraw->fName.Data(), iStripDraw,
179 histName, histParams);
180 const auto cutExpression = Form(
"%s[%d]>%d&&%s[%d]>%d",
181 sensorDraw->fName.Data(), iStripDraw,
182 thresholdsDraw[iStripDraw],
183 sensorSelect->fName.Data(), iStripSelect,
184 thresholdsSelect[iStripSelect]);
185 canvas->cd(iStripSelect + 1);
186 tree->Draw(drawExpression, cutExpression,
"");
187 const auto hist =
static_cast<TH1D*
>(gDirectory->Get(histName));
201 int CheckDataMultiplicity(
const std::vector<UShort_t>& data,
202 const std::vector<UShort_t>& thresholds) {
203 int multiplicity = 0;
204 for (Int_t i = 0; i < data.size(); i++) {
205 if (data[i] > thresholds[i]) {
207 if (multiplicity > 1) {
220 Bool_t CheckIfSingleMultiplicity(
const std::vector<SensorRunInfo*>* sensors,
221 const std::vector<std::vector<UShort_t>>* data,
222 const std::vector<std::vector<UShort_t>>* thresholds) {
223 Bool_t ifSingleMult =
true;
224 for (Int_t i = 0; i < sensors->size(); i++) {
225 const int multiplicity = CheckDataMultiplicity(data->at(i), thresholds->at(i));
226 if (multiplicity != 1) {
227 ifSingleMult =
false;
241 TObject* GetObjectFromRootFile(
const TString& filePath,
const TString& objName =
"") {
242 auto file = TFile::Open(filePath.Data());
243 auto obj = (objName.Length())
245 : file->Get(file->GetListOfKeys()->At(0)->GetName());
255 TObject* GetObjectFromRootFile(TFile* file,
const unsigned object_ind) {
256 auto obj = file->Get(file->GetListOfKeys()->At(object_ind)->GetName());
257 Info(
"Info",
"%s", obj->GetName());
268 TObject* GetObjectFromRootFile(TFile* file,
const TString& objName =
"") {
270 auto obj = (objName.Length())
272 : file->Get(file->GetListOfKeys()->At(0)->GetName());
281 TString GetFileNameBaseFromPath(
const TString& path) {
282 TString fileName = gSystem->BaseName(path);
284 Int_t lastDotPos = fileName.Last(
'.');
285 if (lastDotPos > 0) {
286 fileName.Remove(lastDotPos, fileName.Length());
299 void DumpVector(
const std::vector<T>& vec, ofstream& file,
const TString& delimiter =
"\n") {
300 for (
const auto &itVec : vec) {
301 file << itVec << delimiter;
312 void Dump2DVector(
const T& vec2d, ofstream& file,
313 const TString& delimiter =
" ") {
314 for (
const auto &vec: vec2d) {
315 for (
const auto &elem: vec) {
316 file << elem << delimiter;
328 void Dump2DVector(
const T& vec2d,
const TString& delimiter =
" ") {
329 for (
const auto &vec: vec2d) {
330 for (
const auto &elem: vec) {
331 std::cout << elem << delimiter;
333 std::cout << std::endl;
343 std::vector<T> ReadVectorFromFile(
const TString& filePath) {
344 std::ifstream file(filePath);
345 if (!file.is_open()) {
346 Error(
"ReadVectorFromFile",
"Failed to open file: %s", filePath.Data());
350 while (file >> value) {
351 vec.push_back(value);
361 std::vector<std::vector<T>> Read2DVectorFromFile(
const TString& filePath) {
362 std::ifstream file(filePath);
363 if (!file.is_open()) {
364 Error(
"Read2DVectorFromFile",
"Failed to open file: %s", filePath.Data());
366 std::vector<std::vector<T>> vec2d;
369 while (std::getline(file, line)) {
371 std::istringstream iss(line);
373 while (iss >> value) {
374 vec.push_back(value);
376 vec2d.push_back(vec);
386 std::vector<Double_t> ReadDoubleVectorFromFile(
const TString& filePath) {
387 std::ifstream file(filePath);
388 if (!file.is_open()) {
389 Error(
"ReadDoubleVectorFromFile",
"Failed to open file: %s", filePath.Data());
391 std::vector<Double_t> vec;
393 while (file >> str_val) {
394 vec.push_back(std::stod(str_val));
406 std::vector<std::vector<Double_t>> Read2DDoubleVectorFromFile(
const TString& filePath) {
407 std::ifstream file(filePath);
408 if (!file.is_open()) {
409 Error(
"Read2DDoubleVectorFromFile",
"Failed to open file: %s", filePath.Data());
411 std::vector<std::vector<Double_t>> vec2d;
413 while (std::getline(file, line)) {
414 std::vector<Double_t> vec;
415 std::istringstream iss(line);
417 while (iss >> str_val) {
418 vec.push_back(std::stod(str_val));
420 vec2d.push_back(vec);
439 IOManager(
const TString& workdir) =
delete;
448 TFile* CreateRootFile(
const TString& filePath);
454 TFile* OpenRootFile(
const TString& filePath);
461 std::ofstream CreateTextFile(
const TString& filePath);
467 std::ifstream OpenTextFile(
const TString& filePath);
474 void Write(
const TObjArray* arr);
480 void Write(TObject* obj);
486 void MakeDir(
const TString& dirname);
492 void ChangeDir(
const TString& dirname);
494 TString fWorkDir =
".";
495 Bool_t fRecreate =
true;
499 const TString dirPath = gSystem->DirName(filePath);
500 this->MakeDir(dirPath);
501 auto file = TFile::Open(filePath,
"RECREATE");
503 Info(
"IOManager::CreateRootFile",
"Created ROOT file: %s", filePath.Data());
505 Error(
"IOManager::CreateRootFile",
"Failed to create ROOT file: %s", filePath.Data());
511 auto file = TFile::Open(filePath);
512 if (!file->IsOpen()) {
513 Error(
"IOManager::OpenRootFile",
"Failed open ROOT file: %s", filePath.Data());
519 const TString dirPath = gSystem->DirName(filePath);
520 this->MakeDir(dirPath);
521 std::ofstream file(filePath, ios::trunc);
522 if (file.is_open()) {
523 Info(
"IOManager::CreateTextFile",
"Created ASCII file: %s", filePath.Data());
525 Error(
"IOManager::CreateTextFile",
"Failed to create ASCII file: %s", filePath.Data());
531 std::ifstream file(filePath);
532 if (!file.is_open()) {
533 Error(
"IOManager::OpenTextFile",
"Failed open ASCII file: %s", filePath.Data());
541 "IOManager::Write",
"save to a directory %s the following objects:",
542 gDirectory->GetPath()
544 for (
const auto *obj: *arr) {
545 Info(
"",
"%s", obj->GetName());
551 auto arr =
new TObjArray();
558 std::vector<TString> endSym= {
".",
"/",
"~"};
559 TString dirPath = dirname;
560 std::vector<TString> subdirs;
563 subdirs.push_back(gSystem->BaseName(dirPath));
564 dirPath = gSystem->DirName(dirPath);
565 }
while (dirPath !=
"." && dirPath !=
"/" && dirPath !=
"~");
568 for (
auto subdirIter = subdirs.rbegin(); subdirIter != subdirs.rend(); subdirIter++) {
569 TString subdirName = *subdirIter;
570 dirPath = gSystem->PrependPathName(dirPath, subdirName);
571 gSystem->MakeDirectory(dirPath);
576 TString dirPath = dirname;
577 fWorkDir = gSystem->PrependPathName(fWorkDir, dirPath);
581 ROOT_INPUT_REDUCED_TREE_PATH,
582 ROOT_MULT_SELECTED_PATH,
583 ROOT_HIST_SPECTRA_PATH,
584 ROOT_HIST_PEAKS_PATH,
585 ROOT_HIST_PIXEL_PATH,
586 ROOT_HIST_NON_UNIFORM_MAP_PATH,
590 TXT_CALIB_COEFF_PATH,
592 TXT_HIGH_E_PEAK_PATH,
593 TXT_HIST_NON_UNIFORM_MAP_PATH
606 TString ConstructSensorFilePath(
const std::set<TString>& subdirs,
607 const TString& prefix,
608 const TString& nameRoot,
609 const std::vector<SensorRunInfo*>* sensors,
610 const TString& extension =
"root");
616 TString ConstructFilePath(
const std::set<TString>& subdirs,
617 const TString& prefix,
618 const TString& nameRoot,
619 const std::vector<SensorRunInfo*>* sensors,
620 const TString& extension =
"root");
628 TString GetPath(
const Int_t fileType,
const TString& nameRoot,
629 const std::vector<SensorRunInfo*>* sensors =
nullptr);
636 TString GetPath(
const Int_t fileType,
const TString& nameRoot,
646 std::vector<T> GetSensorThresholds(
const SensorRunInfo* sensor,
647 const TString& runId);
650 std::vector<std::vector<T>> GetCalibCoefficients(
const SensorRunInfo* sensor,
651 const TString& runId);
660 const TString& prefix,
661 const TString& nameRoot,
662 const std::vector<SensorRunInfo*>* sensors,
663 const TString& extension =
"root") {
664 TString fileName = prefix +
"_" + nameRoot;
665 for (
const auto *sensor: *sensors) {
666 fileName += Form(
"_%s", sensor->fName.Data());
668 fileName += Form(
".%s", extension.Data());
669 TString dirPath = fWorkDir;
670 TString runId = nameRoot;
671 dirPath = gSystem->PrependPathName(dirPath, runId);
672 for (
auto subdir: subdirs) {
673 dirPath = gSystem->PrependPathName(dirPath, subdir);
675 const TString filePath = gSystem->PrependPathName(dirPath, fileName);
680 const TString& prefix,
681 const TString& nameRoot,
682 const std::vector<SensorRunInfo*>* sensors,
683 const TString& extension =
"root") {
684 TString fileName = prefix +
"_" + nameRoot;
685 TString sensorNames =
"";
686 for (
const auto *sensor: *sensors) {
687 sensorNames += Form(
"_%s", sensor->fName.Data());
689 TString sensorSubdir = sensorNames(1, sensorNames.Length());
690 fileName += Form(
"%s.%s", sensorNames.Data(), extension.Data());
691 TString dirPath = fWorkDir;
692 TString runId = nameRoot;
693 dirPath = gSystem->PrependPathName(dirPath, runId);
694 dirPath = gSystem->PrependPathName(dirPath, sensorSubdir);
695 for (
auto subdir: subdirs) {
696 dirPath = gSystem->PrependPathName(dirPath, subdir);
698 const TString filePath = gSystem->PrependPathName(dirPath, fileName);
703 const TString& nameRoot,
704 const std::vector<SensorRunInfo*>* sensors =
nullptr) {
707 case ROOT_INPUT_REDUCED_TREE_PATH:
708 path = this->ConstructFilePath({
"input"},
"input", nameRoot, sensors);
710 case ROOT_MULT_SELECTED_PATH:
711 path = this->ConstructFilePath({
"input"},
"mult_one", nameRoot, sensors);
713 case ROOT_HIST_SPECTRA_PATH:
714 path = this->ConstructSensorFilePath(
715 {
"draw"},
"spectra", nameRoot, sensors,
"root" 718 case ROOT_HIST_PEAKS_PATH:
719 path = this->ConstructSensorFilePath(
720 {
"draw"},
"peaks", nameRoot, sensors,
"root" 723 case ROOT_HIST_PIXEL_PATH:
724 path = this->ConstructSensorFilePath(
725 {
"draw"},
"pixels", nameRoot, sensors,
"root" 728 case ROOT_HIST_NON_UNIFORM_MAP_PATH:
729 path = this->ConstructSensorFilePath(
730 {
"draw"},
"map", nameRoot, sensors,
"root" 733 case TXT_PEAK_DATA_PATH:
734 path = this->ConstructSensorFilePath(
735 {
"txt"},
"peakpos", nameRoot, sensors,
"txt" 738 case TXT_THRESHOLD_PATH:
739 path = this->ConstructSensorFilePath(
740 {
"txt"},
"threshold", nameRoot, sensors,
"txt" 743 case TXT_DEAD_LAYER_PATH:
744 path = this->ConstructSensorFilePath(
745 {
"txt"},
"dead", nameRoot, sensors,
"txt" 748 case TXT_CALIB_COEFF_PATH:
749 path = this->ConstructSensorFilePath(
750 {
"txt"},
"coeff", nameRoot, sensors,
"txt" 753 case TXT_REPORT_PATH:
754 path = this->ConstructSensorFilePath(
755 {
""},
"report", nameRoot, sensors,
"txt" 758 case TXT_HIGH_E_PEAK_PATH:
759 path = this->ConstructSensorFilePath(
760 {
"txt"},
"high_map", nameRoot, sensors,
"txt" 763 case TXT_HIST_NON_UNIFORM_MAP_PATH:
764 path = this->ConstructSensorFilePath(
765 {
"txt"},
"map", nameRoot, sensors,
"txt" 773 const TString& nameRoot,
775 std::vector<SensorRunInfo*>* sensors;
776 if (sensor ==
nullptr) {
779 sensors =
new std::vector<SensorRunInfo*>(1,
const_cast<SensorRunInfo*
>(sensor));
781 TString path = GetPath(fileType, nameRoot, sensors);
788 const TString& runId) {
789 const TString filePath = (sensor->fThresholdFilePath ==
"")
790 ? this->GetPath(TXT_THRESHOLD_PATH, runId, sensor)
791 : sensor->fThresholdFilePath;
792 auto thresholds = ReadVectorFromFile<T>(filePath);
797 std::vector<std::vector<T>>
798 CalibIOManager::GetCalibCoefficients(
const SensorRunInfo* sensor,
799 const TString& runId)
801 const TString filePath = (sensor->fCalibFilePath ==
"")
802 ? this->GetPath(TXT_CALIB_COEFF_PATH, runId, sensor)
803 : sensor->fCalibFilePath;
804 auto coeffs = Read2DVectorFromFile<T>(filePath);
824 TString fWorkDir =
"result";
826 TString fRawDataPath =
"";
829 TaskManager::TaskManager(
const TString& rawDataPath)
831 TString rawFileNameBase = GetFileNameBaseFromPath(fRawDataPath);
832 fRunId = GetFileNameBaseFromPath(fRawDataPath);
833 fIOManager->ChangeDir(fWorkDir);
868 void ConvertTree(
const TString& option =
"neevent");
880 void FindThresholds(
const TString& opt =
"draw_off");
889 void MultiplicitySelection(
const SensorRunInfo* sensor, std::vector<SensorRunInfo*> sensorsZeroSignal = std::vector<SensorRunInfo*>());
897 void MultiplicitySelection(std::vector<SensorRunInfo*> sensors, std::vector<SensorRunInfo*> sensorsZeroSignal = std::vector<SensorRunInfo*>());
908 std::vector<SensorRunInfo*> *fSensors =
nullptr;
911 Preprocessing::Preprocessing(
const TString& rawDataPath) :
TaskManager(rawDataPath) {
912 fSensors =
new std::vector<SensorRunInfo*>();
916 if (option ==
"neevent") {
917 auto inFile = fIOManager->OpenRootFile(fRawDataPath);
918 const auto tree =
static_cast<TTree*
>(GetObjectFromRootFile(inFile));
920 "Preprocessing::ConvertTree",
"Converting a tree '%s' from the file '%s'",
921 tree->GetName(), fRawDataPath.Data()
924 tree->SetBranchStatus(
"*", 0);
925 for (
const auto *sensor: *fSensors) {
926 const TString brName = Form(
"NeEvent.%s[%d]", sensor->fName.Data(), sensor->fStripAmount);
927 tree->SetBranchStatus(brName, 1);
928 tree->SetAlias(sensor->fName, brName);
930 const TString outFilePath = fIOManager->GetPath(ROOT_INPUT_REDUCED_TREE_PATH, fRunId, fSensors);
931 const auto outFile = fIOManager->CreateRootFile(outFilePath);
932 const auto *newtree = tree->CloneTree();
938 if (option ==
"aqqdaq") {
944 for (
const auto *sensor: *fSensors) {
945 std::vector<Double_t> thersholdArray;
946 if (sensor->fNoiseThreshold > 0) {
947 thersholdArray = std::vector<Double_t>(sensor->fStripAmount, sensor->fNoiseThreshold);
949 thersholdArray.resize(sensor->fStripAmount);
951 const TString filePath = fIOManager->GetPath(ROOT_INPUT_REDUCED_TREE_PATH, fRunId, fSensors);
952 auto inFile = fIOManager->OpenRootFile(filePath);
953 const auto tree =
static_cast<TTree*
>(GetObjectFromRootFile(inFile));
954 Info(
"Preprocessing::FindThresholds",
"Tree entries: %lld", tree->GetEntries());
957 const Int_t excludeBins = 1;
958 const TString histParams = Form(
959 "(%d,%d,%d)", sensor->fBinAmount - excludeBins, excludeBins, sensor->fBinAmount
961 for (Int_t iStrip = 0; iStrip < sensor->fStripAmount; iStrip++) {
962 const TString histName = Form(
"threshold_strip_%d", iStrip);
963 const TString drawExpression = Form(
964 "%s[%d]>>%s%s", sensor->fName.Data(), iStrip, histName.Data(), histParams.Data()
966 tree->Draw(drawExpression,
"",
"");
967 const TH1F *histThreshold =
static_cast<TH1F*
>(gDirectory->Get(histName));
968 const Int_t binsAmount = histThreshold->GetXaxis()->GetNbins();
970 const Int_t maxBinNb = histThreshold->GetMaximumBin();
971 Bool_t minBinObtained =
false;
972 Int_t thresholdBinNb = 0;
973 Int_t prevBinContent = histThreshold->GetBinContent(maxBinNb);
975 for (Int_t binNb = maxBinNb + 1; binNb < binsAmount && !minBinObtained; binNb++) {
976 const Int_t binContent = histThreshold->GetBinContent(binNb);
977 if (prevBinContent <= binContent) {
978 minBinObtained =
true;
979 thresholdBinNb = binNb;
981 prevBinContent = binContent;
983 thersholdArray[iStrip] = --thresholdBinNb;
987 const TString thresholdsPath = fIOManager->GetPath(TXT_THRESHOLD_PATH, fRunId, sensor);
988 auto file = fIOManager->CreateTextFile(thresholdsPath);
989 DumpVector(thersholdArray, file);
995 const SensorRunInfo* sensor, std::vector<SensorRunInfo*> sensorsZeroSignal = std::vector<SensorRunInfo*>()) {
997 const TString inFilePath = fIOManager->GetPath(ROOT_INPUT_REDUCED_TREE_PATH, fRunId, fSensors);
998 auto inFile = fIOManager->OpenRootFile(inFilePath);
999 const auto inTree =
static_cast<TTree*
>(GetObjectFromRootFile(inFile));
1001 const TString outFilePath = fIOManager->GetPath(ROOT_MULT_SELECTED_PATH, fRunId, fSensors);
1002 auto outFile = fIOManager->CreateRootFile(outFilePath);
1003 TTree *outTree =
new TTree(inTree->GetName(),
"Tree with a single multiplicity");
1005 inTree->SetMakeClass(1);
1006 std::vector<UShort_t> sensorData = std::vector<UShort_t>(sensor->fStripAmount);
1007 std::vector<UShort_t> sensorThresholds = fIOManager->GetSensorThresholds<UShort_t>(sensor, fRunId);
1008 TString brName = inTree->GetAlias(sensor->fName);
1009 inTree->SetBranchAddress(brName, &(sensorData[0]));
1010 outTree->Branch(sensor->fName, &(sensorData[0]), brName +
"/s");
1012 auto *zeroSignalSensorData =
new std::vector<std::vector<UShort_t>>();
1013 auto *zeroSignalSensorThresholds =
new std::vector<std::vector<UShort_t>>();
1014 for (
const auto *zeroSignalSensor: sensorsZeroSignal) {
1015 zeroSignalSensorData->push_back(std::vector<UShort_t>(zeroSignalSensor->fStripAmount));
1016 TString branchName = inTree->GetAlias(zeroSignalSensor->fName);
1017 inTree->SetBranchAddress(branchName, &(zeroSignalSensorData->back()[0]));
1019 outTree->Branch(zeroSignalSensor->fName, &(zeroSignalSensorData->back()[0]), branchName +
"/s");
1021 auto sensorThresholds = fIOManager->GetSensorThresholds<UShort_t>(zeroSignalSensor, fRunId);
1022 zeroSignalSensorThresholds->push_back(sensorThresholds);
1024 Info(
"Preprocessing::MultiplicitySelection",
"Begin multiplicity selection");
1025 Info(
"Preprocessing::MultiplicitySelection",
"Input tree entries: %lld", inTree->GetEntries());
1026 for (Long64_t eventNb = 0; eventNb < inTree->GetEntries(); eventNb++) {
1027 inTree->GetEntry(eventNb);
1028 bool saveEvent =
true;
1029 const int sensorMult = CheckDataMultiplicity(sensorData, sensorThresholds);
1030 if (sensorMult != 1) {
1034 for (
int j = 0; j < sensorsZeroSignal.size(); j++) {
1035 int multiplicityNoSignalSensor = CheckDataMultiplicity(zeroSignalSensorData->at(j), zeroSignalSensorThresholds->at(j));
1036 if (multiplicityNoSignalSensor != 0) {
1046 Info(
"Preprocessing::MultiplicitySelection",
"Output tree entries: %lld", outTree->GetEntries());
1051 CreateSpectraHists(sensor);
1055 std::vector<SensorRunInfo*> sensorsZeroSignal = std::vector<SensorRunInfo*>()) {
1057 const TString inFilePath = fIOManager->GetPath(ROOT_INPUT_REDUCED_TREE_PATH, fRunId, fSensors);
1058 auto inFile = fIOManager->OpenRootFile(inFilePath);
1059 const auto inTree =
static_cast<TTree*
>(GetObjectFromRootFile(inFile));
1061 const TString outFilePath = fIOManager->GetPath(ROOT_MULT_SELECTED_PATH, fRunId, fSensors);
1062 auto outFile = fIOManager->CreateRootFile(outFilePath);
1063 TTree *outTree =
new TTree(inTree->GetName(),
"Tree with a single multiplicity");
1065 inTree->SetMakeClass(1);
1067 std::vector<std::vector<UShort_t>> sensorsData;
1068 std::vector<std::vector<UShort_t>> sensorsThresholds;
1070 for (
const auto &sensor: sensors) {
1071 sensorsData.push_back(std::vector<UShort_t>(sensor->fStripAmount));
1072 sensorsThresholds.push_back(fIOManager->GetSensorThresholds<UShort_t>(sensor, fRunId));
1073 TString brName = inTree->GetAlias(sensor->fName);
1074 inTree->SetBranchAddress(brName, &(sensorsData.back()[0]));
1075 outTree->Branch(sensor->fName, &(sensorsData.back()[0]), brName +
"/s");
1079 auto *zeroSignalSensorData =
new std::vector<std::vector<UShort_t>>();
1080 auto *zeroSignalSensorThresholds =
new std::vector<std::vector<UShort_t>>();
1081 for (
const auto *zeroSignalSensor: sensorsZeroSignal) {
1082 zeroSignalSensorData->push_back(std::vector<UShort_t>(zeroSignalSensor->fStripAmount));
1083 TString branchName = inTree->GetAlias(zeroSignalSensor->fName);
1084 inTree->SetBranchAddress(branchName, &(zeroSignalSensorData->back()[0]));
1086 outTree->Branch(zeroSignalSensor->fName, &(zeroSignalSensorData->back()[0]), branchName +
"/s");
1088 auto sensorThresholds = fIOManager->GetSensorThresholds<UShort_t>(zeroSignalSensor, fRunId);
1089 zeroSignalSensorThresholds->push_back(sensorThresholds);
1091 Info(
"Preprocessing::MultiplicitySelection",
"Begin multiplicity selection");
1092 Info(
"Preprocessing::MultiplicitySelection",
"Input tree entries: %lld", inTree->GetEntries());
1093 for (Long64_t eventNb = 0; eventNb < inTree->GetEntries(); eventNb++) {
1094 inTree->GetEntry(eventNb);
1095 bool saveEvent =
true;
1096 if (!(eventNb % 100000)) {
1097 std::cout <<
"Event number " << eventNb << std::endl;
1099 for (
int sensorNb = 0; sensorNb < sensors.size(); sensorNb++) {
1100 const int sensorMult = CheckDataMultiplicity(sensorsData[sensorNb], sensorsThresholds[sensorNb]);
1101 if (sensorMult != 1) {
1105 for (
int j = 0; j < sensorsZeroSignal.size(); j++) {
1106 int multiplicityNoSignalSensor = CheckDataMultiplicity(zeroSignalSensorData->at(j), zeroSignalSensorThresholds->at(j));
1107 if (multiplicityNoSignalSensor != 0) {
1119 Info(
"Preprocessing::MultiplicitySelection",
"Output tree entries: %lld", outTree->GetEntries());
1124 for (
int sensorNb = 0; sensorNb < sensors.size(); sensorNb++) {
1125 CreateSpectraHists(sensors[sensorNb]);
1131 const TString multSelectPath = fIOManager->GetPath(ROOT_MULT_SELECTED_PATH, fRunId, fSensors);
1132 auto inFile = fIOManager->OpenRootFile(multSelectPath);
1133 const auto tree =
static_cast<TTree*
>(GetObjectFromRootFile(inFile));
1134 auto thresholds = fIOManager->GetSensorThresholds<UShort_t>(sensor, fRunId);
1135 const TString histSpectraPath = fIOManager->GetPath(ROOT_HIST_SPECTRA_PATH, fRunId, sensor);
1136 auto histSpectraFile = fIOManager->CreateRootFile(histSpectraPath);
1137 DrawSensorSpectraByStrip(tree, sensor, thresholds);
1138 histSpectraFile->Close();
1142 void Preprocessing::Exec() {
1144 Error(
"Preprocessing::Exec",
"Method is obsolete, please use the sequence:");
1145 Error(
"Preprocessing::Exec",
" ConvertTree() -> FindThresholds() -> MultiplicitySelection()");
1152 enum PeakSearchAlgorithm {
1160 void SetPeakSearchMethod(
const TString& peakSearchAlgorithm);
1161 void SetFitMinSigma(
const Double_t value) {fFitMinSigma = value;}
1162 void SetFitPeakThreshold(
const Double_t value) {fFitPeakThreshold = value;}
1163 void SetSearchRadius(
const Int_t value) {fSearchRadius = value;}
1164 void SetSlideWindowWidth(
const Int_t value) {fSlideWindowWidth = value;}
1169 std::list<Double_t> GetPeaksTSpectrum(TH1* hist,
1170 const Double_t fitMinSigma,
1171 const Double_t fitPeakThreshold);
1194 std::list<Double_t> SlidingWindowPeakSearch(TH1* hist,
const std::list<Double_t>& initGuess,
1195 const Int_t windowWidth,
1196 const Int_t searchRadius);
1213 std::list<Double_t> GaussPeakSearch(TH1* hist,
const std::list<Double_t>& initGuess,
1214 const Int_t searchRadius);
1222 std::list<Double_t> GetPeaks(TH1* hist,
const std::list<Double_t>& initGuess);
1225 Int_t fPeakSearchMethod = SLIDING_WINDOW;
1227 Double_t fFitMinSigma = 6.;
1228 Double_t fFitPeakThreshold = 0.7;
1230 Int_t fSearchRadius = 10;
1231 Int_t fSlideWindowWidth = 10;
1233 std::vector<std::vector<float>> fIntegralInWindow;
1236 void PeakSearch::SetPeakSearchMethod(
const TString& peakSearchAlgorithm) {
1237 if (peakSearchAlgorithm ==
"sliding_window") {
1238 fPeakSearchMethod = SLIDING_WINDOW;
1240 if (peakSearchAlgorithm ==
"gauss") {
1241 fPeakSearchMethod = GAUSS;
1247 const Double_t fitMinSigma,
1248 const Double_t fitPeakThreshold)
1251 sc.Search(hist, fitMinSigma,
"", fitPeakThreshold);
1252 const Int_t peaksAmount = sc.GetNPeaks();
1253 Info(
"PeakSearch::GetPeaksTSpectrum",
"Occured peaks amount is %d", peaksAmount);
1254 Double_t* peaksPos = sc.GetPositionX();
1255 std::list<Double_t> peaks(peaksPos, peaksPos + peaksAmount);
1267 const Int_t windowWidth,
1268 const Int_t searchRadius)
1270 std::list<Double_t> peaks;
1271 std::vector<float> peaksIntegral;
1272 for (
const auto& guessPos: initGuess) {
1274 const Int_t peakBinNb = hist->GetXaxis()->FindBin(guessPos);
1275 Int_t maxIntegral = numeric_limits<Int_t>::min();
1278 for (Int_t i = peakBinNb - searchRadius; i < peakBinNb + searchRadius - windowWidth; i++) {
1279 hist->GetXaxis()->SetRange(i, i + windowWidth - 1 );
1280 const Int_t integral = hist->Integral();
1281 if (maxIntegral < integral) {
1282 maxIntegral = integral;
1283 peakMean = hist->GetMean();
1287 peaksIntegral.push_back(maxIntegral);
1288 peaks.push_back(peakMean);
1290 fIntegralInWindow.push_back(peaksIntegral);
1296 const Int_t searchRadius)
1298 std::list<Double_t> peaks;
1299 for (
const auto& guessPos: initGuess) {
1301 const Int_t peakBinNb = hist->GetXaxis()->FindBin(guessPos);
1303 auto gausInit =
new TF1(
"gausInit",
"gaus", peakBinNb - searchRadius,
1304 peakBinNb + searchRadius);
1305 auto fitRes = hist->Fit(
"gausInit",
"RS");
1307 auto gausPol =
new TF1(
"gausPol",
"gaus(0) + pol1(3)", peakBinNb - searchRadius,
1308 peakBinNb + searchRadius);
1309 gausPol->SetParameter(0, fitRes->Parameter(0));
1310 gausPol->SetParameter(1, fitRes->Parameter(1));
1311 gausPol->SetParameter(2, fitRes->Parameter(2));
1312 fitRes = hist->Fit(
"gausPol",
"RS+");
1313 peaks.push_back(fitRes->Parameter(1));
1319 std::list<Double_t> peaks;
1320 switch (fPeakSearchMethod) {
1321 case SLIDING_WINDOW:
1322 peaks = SlidingWindowPeakSearch(hist, initGuess, fSlideWindowWidth, fSearchRadius);
1325 peaks = GaussPeakSearch(hist, initGuess, fSearchRadius);
1328 Error(
"PeakSearch::SearchPeaks",
"Unknown peak search method is set");
1331 hist->GetXaxis()->SetRange(0, hist->GetXaxis()->GetNbins());
1336 for (
const auto &peak: peaks) {
1337 std::cout << peak <<
" ";
1339 std::cout << std::endl;
1346 const static std::vector<Double_t> fAlphaE = {4.7844, 6.0024, 7.6869};
1351 const static std::vector<std::vector<Double_t>> fElossApprox = {{0.0010319, 0.146954, 0.00181655},
1352 {0.0004273, 0.127711, 0.00106127},
1353 {0.0001624, 0.108467, 0.000589357}};
1376 void DeadLayerEstimation();
1377 void CalcCalibrationCoefficients(Bool_t fitLastTwoPoints =
false);
1382 void SetPathToCustomSpectra(
const TString& path) {fSpectraHistPath = path;}
1398 void PrintReport(
const std::vector<std::vector<Double_t>>& peaks,
1399 const std::vector<Double_t>& deadVec,
1400 const Double_t avgDead,
1401 const std::vector<std::vector<Double_t>>& coeffsAB);
1403 std::vector<Double_t> GetAlphaEnergiesAfterDeadLayer (
const Double_t dead);
1412 Double_t GetDeadLayerByEta (
const Double_t eta);
1415 TString fSpectraHistPath =
"";
1419 Calibration::Calibration(
const TString& rawDataPath) :
TaskManager(rawDataPath) {
1423 void Calibration::SearchPeaks() {
1424 if (fSpectraHistPath ==
"") {
1425 fSpectraHistPath = fIOManager->GetPath(ROOT_HIST_SPECTRA_PATH, fRunId, fSensor);
1427 const auto histFile = fIOManager->OpenRootFile(fSpectraHistPath);
1429 const TString peaksHistPath = fIOManager->GetPath(ROOT_HIST_PEAKS_PATH, fRunId, fSensor);
1430 const auto peakHists = fIOManager->CreateRootFile(peaksHistPath);
1432 std::vector<std::list<Double_t>> peaks;
1433 for (Int_t iStrip = 0; iStrip < fSensor->fStripAmount; iStrip++) {
1434 const TString histName = Form(
"strip_%d", iStrip);
1437 const auto hist =
static_cast<TH1D*
>(GetObjectFromRootFile(histFile, iStrip));
1438 if (fSensor->fNoiseThreshold > 0) {
1439 hist->GetXaxis()->SetRange(fSensor->fNoiseThreshold, fSensor->fBinAmount);
1441 const auto peaksTSpec = GetPeaksTSpectrum(hist, fFitMinSigma, fFitPeakThreshold);
1442 auto stripPeaks = GetPeaks(hist, peaksTSpec);
1443 if (stripPeaks.size() == 4) {
1445 auto itDelete = stripPeaks.begin();
1446 std::advance(itDelete, 1);
1447 stripPeaks.erase(itDelete);
1450 "Calibration::SearchPeaks",
"Found peaks amount doesn't equal 4 (%zu)", stripPeaks.size()
1452 Warning(
"Calibration::SearchPeaks",
"By default values are set to Nan");
1454 stripPeaks = std::list<Double_t>(3, std::numeric_limits<double>::quiet_NaN());
1456 peaks.push_back(stripPeaks);
1460 const TString peakDataPath = fIOManager->GetPath(TXT_PEAK_DATA_PATH, fRunId, fSensor);
1462 auto peaksFile = fIOManager->CreateTextFile(peakDataPath);
1463 Dump2DVector(peaks, peaksFile);
1470 return (-5272.9763 + 19011.5041 * eta - 17102.8129 * eta * eta);
1474 void Calibration::DeadLayerEstimation() {
1476 const TString peakDataPath = fIOManager->GetPath(TXT_PEAK_DATA_PATH, fRunId, fSensor);
1477 auto peaksFile = fIOManager->OpenTextFile(peakDataPath);
1478 auto peaks = Read2DDoubleVectorFromFile(peakDataPath);
1480 vector<Double_t> deadVec;
1481 for (
const auto stripPeaks: peaks) {
1482 const Double_t eta = (stripPeaks[2] - stripPeaks[1]) / (stripPeaks[2] - stripPeaks[0]);
1483 const Double_t deadLayer = GetDeadLayerByEta(eta);
1484 deadVec.push_back(deadLayer);
1487 const TString deadPath = fIOManager->GetPath(TXT_DEAD_LAYER_PATH, fRunId, fSensor);
1488 auto file = fIOManager->CreateTextFile(deadPath);
1489 DumpVector(deadVec, file);
1492 std::vector<Double_t> Calibration::GetAlphaEnergiesAfterDeadLayer (
const Double_t dead) {
1493 std::vector<Double_t> energies;
1494 for (Int_t i = 0; i < fElossApprox.size(); i++) {
1495 const Double_t energy = fAlphaE[i]
1496 - fElossApprox[i][2] * pow(dead, 2)
1497 - fElossApprox[i][1] * dead
1498 - fElossApprox[i][0];
1499 energies.push_back(energy);
1504 void Calibration::CalcCalibrationCoefficients(Bool_t fitOnlyLastTwoPointsNvsE =
false) {
1506 const TString peakDataPath = fIOManager->GetPath(TXT_PEAK_DATA_PATH, fRunId, fSensor);
1507 auto peaks = Read2DDoubleVectorFromFile(peakDataPath);
1508 std::vector<Double_t> deadVec;
1509 std::vector<std::vector<Double_t>> energies;
1511 if (fSensor->fIsDeadLayerPerStripsSet) {
1512 for (Int_t iStrip = 0; iStrip < fSensor->fStripAmount; iStrip++) {
1513 energies.push_back(GetAlphaEnergiesAfterDeadLayer(fSensor->fDeadLayers[iStrip]));
1514 deadVec = fSensor->fDeadLayers;
1515 avgDead = CalculateAvg(deadVec);
1519 const TString deadDataPath = fIOManager->GetPath(TXT_DEAD_LAYER_PATH, fRunId, fSensor);
1520 deadVec = ReadDoubleVectorFromFile(deadDataPath);
1521 avgDead = CalculateAvg(deadVec);
1522 auto energies_avg = GetAlphaEnergiesAfterDeadLayer(avgDead);
1523 for (Int_t iStrip = 0; iStrip < fSensor->fStripAmount; iStrip++) {
1524 energies.push_back(energies_avg);
1528 std::vector<std::vector<Double_t>> coeffsAB;
1529 for (Int_t iStrip = 0; iStrip < peaks.size(); iStrip++) {
1530 TGraph* gr = (fitOnlyLastTwoPointsNvsE)
1531 ?
new TGraph(energies[0].size() - 1, &peaks[iStrip][1], &energies[iStrip][1])
1532 :
new TGraph(energies[0].size(), &peaks[iStrip][0], &energies[iStrip][0]);
1533 TFitResultPtr fitRes = gr->Fit(
"pol1",
"S");
1534 const Double_t a = fitRes->Parameter(1);
1535 const Double_t b = fitRes->Parameter(0);
1536 std::vector<Double_t> coeffs = {a, b};
1537 coeffsAB.push_back(coeffs);
1540 const TString calibPath = fIOManager->GetPath(TXT_CALIB_COEFF_PATH, fRunId, fSensor);
1541 auto fileCalib = fIOManager->CreateTextFile(calibPath);
1542 Dump2DVector(coeffsAB, fileCalib);
1545 PrintReport(peaks, deadVec, avgDead, coeffsAB);
1549 const std::vector<Double_t>& deadVec,
1550 const Double_t avgDead,
1551 const std::vector<std::vector<Double_t>>& coeffsAB) {
1552 const TString reportPath = fIOManager->GetPath(TXT_REPORT_PATH, fRunId, fSensor);
1553 auto report = fIOManager->CreateTextFile(reportPath);
1554 report << std::right;
1555 report <<
"Calibration results. " << endl << endl;
1556 report <<
"File ID is " << fRunId << endl;
1557 if (fPeakSearchMethod == SLIDING_WINDOW) {
1558 report <<
"Peak search method: SLIDING_WINDOW" << endl;
1559 report <<
"Sliding window algorithm parameters: " << endl;
1560 report <<
" window width: " << fSlideWindowWidth << endl;
1561 report <<
" search region around TSpectrum peak: +-" << fSearchRadius << endl;
1562 report <<
" peak RMS: " << fFitMinSigma << endl;
1563 report <<
" peak amplitude threshold (with respect to maximal): " 1564 << fFitPeakThreshold << endl;
1566 if (fPeakSearchMethod == GAUSS) {
1567 report <<
"Peak search method: GAUSS (gaus + pol1)" << endl;
1568 report <<
"Algorithm parameters: " << endl;
1569 report <<
" search region around TSpectrum peak: +-" << fSearchRadius << endl;
1570 report <<
" peak RMS: " << fFitMinSigma << endl;
1571 report <<
" peak amplitude threshold (with respect to maximal): " 1572 << fFitPeakThreshold << endl;
1575 report <<
"Determined peak positions (in [ADC-channels]):" << endl;
1576 report <<
"StripNb" << std::right
1577 << setw(20) <<
"E_low" 1578 << setw(20) <<
"E_middle" 1579 << setw(20) <<
"E_high" << endl;
1581 for (
const auto& stripPeaks: peaks) {
1582 report << iStrip++ << std::right
1583 << setw(20) << stripPeaks[0]
1584 << setw(20) << stripPeaks[1]
1585 << setw(20) << stripPeaks[2] << endl;
1589 report <<
"Integral over the window ([Counts]):" << endl;
1590 report <<
"StripNb" << std::right
1591 << setw(20) <<
"E_low" 1592 << setw(20) <<
"E_middle" 1593 << setw(20) <<
"E_high" << endl;
1595 for (
const auto& integral: fIntegralInWindow) {
1596 report << iStrip++ << std::right
1597 << setw(20) << integral[0]
1598 << setw(20) << integral[1]
1599 << setw(20) << integral[2] << endl;
1603 report <<
"Dead layer estimation [um] by strips: " << endl;
1604 report <<
"StripNb" << setw(20) <<
"Dead layer"<< endl;
1606 for (
const auto& dead: deadVec) {
1607 report << iStrip++ << std::right
1608 << setw(20) << dead << endl;
1610 report <<
"Avg:" << setw(20) << avgDead << endl;
1611 report <<
"Max-Min:" << setw(20)
1612 << *std::max_element(deadVec.begin(), deadVec.end()) - *std::min_element(deadVec.begin(), deadVec.end()) << endl;
1614 report <<
"Calibration coefficients: " << endl;
1615 report <<
"StripNb" << std::right
1617 << setw(20) <<
"b"<< endl;
1619 for (
const auto& stripCoeffsAB: coeffsAB) {
1620 report << iStrip++ << std::right
1621 << setw(20) << stripCoeffsAB[0]
1622 << setw(20) << stripCoeffsAB[1] << endl;
1629 DeadLayerEstimation();
1630 CalcCalibrationCoefficients();
1639 void SetThickSensor(
SensorRunInfo* sensor) {fMapSensors->at(0) = sensor;}
1640 void SetThinSensor(
SensorRunInfo* sensor) {fMapSensors->at(1) = sensor;}
1641 void SetThickCalibSensor(
SensorRunInfo* sensor) {fSensorCalib = sensor;}
1649 void DrawPixelSpectra();
1650 void SearchPixelHighEnergyPeak();
1651 void CreateThinSensorMap();
1655 std::vector<SensorRunInfo*>* fMapSensors =
new std::vector<SensorRunInfo*>(2,
nullptr);
1659 NonUniformityMapBuilder::NonUniformityMapBuilder(
const TString& mapRunDataPath)
1664 void NonUniformityMapBuilder::Exec() {
1666 SearchPixelHighEnergyPeak();
1667 CreateThinSensorMap();
1677 const std::vector<double> quad_coeffs = {0.159428, 0.0837999, 0.0014907};
1684 const std::vector<double> cube_coeffs = {0.00805579, 9.18781, -0.401229, -0.0044059};
1693 double GetThicknessByHighElossQuad(
double dE) {
1694 return (-quad_coeffs[1] + sqrt(pow(quad_coeffs[1], 2)
1695 - 4*quad_coeffs[2]*(quad_coeffs[0] - dE)))
1696 / (2 * quad_coeffs[2]);
1706 double GetThicknessByHighElossCubic (
double dE) {
1707 return cube_coeffs[0] + cube_coeffs[1]*dE
1708 + cube_coeffs[2] * pow(dE, 2)
1709 + cube_coeffs[3] * pow(dE, 3);
1715 const TString multSelectPath = fIOManager->GetPath(
1716 ROOT_MULT_SELECTED_PATH, fMapSensors->at(0)->fRunId, fMapSensors
1718 auto multSelectFile = fIOManager->OpenRootFile(multSelectPath);
1719 auto tree =
static_cast<TTree*
>(GetObjectFromRootFile(multSelectFile));
1721 const TString pixelSpectraPath = fIOManager->GetPath(
1722 ROOT_HIST_PIXEL_PATH, fMapSensors->at(0)->fRunId, fMapSensors
1724 auto outFile = fIOManager->CreateRootFile(pixelSpectraPath);
1726 const TString thresholdThickPath = fIOManager->GetPath(
1727 TXT_THRESHOLD_PATH, fMapSensors->at(0)->fRunId, fMapSensors->at(0)
1729 const TString thresholdThinPath = fIOManager->GetPath(
1730 TXT_THRESHOLD_PATH, fMapSensors->at(1)->fRunId, fMapSensors->at(1)
1732 const auto thresholdThick = ReadVectorFromFile<UShort_t>(thresholdThickPath);
1733 const auto thresholdThin = ReadVectorFromFile<UShort_t>(thresholdThinPath);
1735 DrawSensorSpectraByPixel(tree, fMapSensors->at(0), fMapSensors->at(1),
1736 thresholdThick, thresholdThin);
1737 multSelectFile->Close();
1741 void NonUniformityMapBuilder::SearchPixelHighEnergyPeak() {
1742 const TString pixelSpectraPath = fIOManager->GetPath(
1743 ROOT_HIST_PIXEL_PATH, fMapSensors->at(0)->fRunId, fMapSensors
1745 auto histFile = fIOManager->OpenRootFile(pixelSpectraPath);
1747 const TString peaksHistPath = fIOManager->GetPath(
1748 ROOT_HIST_PEAKS_PATH, fMapSensors->at(0)->fRunId, fMapSensors
1750 const auto peakHists = fIOManager->CreateRootFile(peaksHistPath);
1752 std::vector<std::vector<Double_t>> peaks;
1753 for (Int_t iStripThick = 0; iStripThick < fMapSensors->at(0)->fStripAmount; iStripThick++) {
1754 std::vector<Double_t> stripPeaks;
1755 for (Int_t iStripThin = 0; iStripThin < fMapSensors->at(1)->fStripAmount; iStripThin++) {
1756 const auto pixelName = Form(
"%s[%d]_%s[%d]", fMapSensors->at(0)->fName.Data(),
1758 fMapSensors->at(1)->fName.Data(),
1760 Info(
"SearchPixelHighEnergyPeak",
"Search high energy peak in pixel %s", pixelName);
1761 const auto histName = Form(
"pixel_%s", pixelName);
1762 const auto hist =
static_cast<TH1D*
>(GetObjectFromRootFile(histFile, histName));
1763 const auto peaksTSpec = GetPeaksTSpectrum(hist, fFitMinSigma, fFitPeakThreshold);
1764 auto pixelPeaks = GetPeaks(hist, peaksTSpec);
1766 if (pixelPeaks.size()) {
1767 peakPos = pixelPeaks.back();
1769 Warning(
"Calibration::SearchPeaks",
"Peaks are not found");
1770 Warning(
"Calibration::SearchPeaks",
"By default value is set to Nan");
1771 peakPos = std::numeric_limits<double>::quiet_NaN();
1773 stripPeaks.push_back(peakPos);
1776 peaks.push_back(stripPeaks);
1778 const TString highEPeaksPath = fIOManager->GetPath(
1779 TXT_HIGH_E_PEAK_PATH, fMapSensors->at(0)->fRunId, fMapSensors
1781 auto peaksFile = fIOManager->CreateTextFile(highEPeaksPath);
1782 Dump2DVector(peaks, peaksFile);
1788 void NonUniformityMapBuilder::CreateThinSensorMap() {
1790 const TString pixelPeakMapPath = fIOManager->GetPath(
1791 TXT_HIGH_E_PEAK_PATH, fMapSensors->at(0)->fRunId, fMapSensors
1793 const TString peaksThickCalibPath = fIOManager->GetPath(
1794 TXT_PEAK_DATA_PATH, fSensorCalib->fRunId, fSensorCalib
1796 const TString thickCalibCoeffsPath = fIOManager->GetPath(
1797 TXT_CALIB_COEFF_PATH, fSensorCalib->fRunId, fSensorCalib
1799 const TString deadLayerThickPath = fIOManager->GetPath(
1800 TXT_DEAD_LAYER_PATH, fSensorCalib->fRunId, fSensorCalib
1802 auto peaksPixelHighEMap = Read2DDoubleVectorFromFile(pixelPeakMapPath);
1803 auto peaksThickCalib = Read2DDoubleVectorFromFile(peaksThickCalibPath);
1804 auto calibCoeffsThick = Read2DDoubleVectorFromFile(thickCalibCoeffsPath);
1805 auto deadLayerThickVec = ReadDoubleVectorFromFile(deadLayerThickPath);
1806 const Int_t thickStripAmount = fMapSensors->at(0)->fStripAmount;
1807 const Int_t thinStripAmount = fMapSensors->at(1)->fStripAmount;
1809 const TString mapRootPath = fIOManager->GetPath(
1810 ROOT_HIST_NON_UNIFORM_MAP_PATH, fMapSensors->at(0)->fRunId, fMapSensors
1812 auto outFile = fIOManager->CreateRootFile(mapRootPath);
1813 auto hist =
new TH2D(
"map", Form(
"Map of the sensor %s effective",
1814 fMapSensors->at(1)->fName.Data()),
1815 thickStripAmount, 0, thickStripAmount,
1816 thinStripAmount, 0, thinStripAmount);
1817 std::vector<std::vector<Double_t>> sensorMap;
1818 const Double_t deadLayerThick = CalculateAvg(deadLayerThickVec);
1819 for (Int_t iStripThick = 0; iStripThick < thickStripAmount; iStripThick++) {
1820 std::vector<Double_t> stripMap;
1821 for (Int_t iStripThin = 0; iStripThin < thinStripAmount; iStripThin++) {
1822 const Double_t N2 = peaksThickCalib[iStripThick][2];
1823 const Double_t N1 = peaksPixelHighEMap[iStripThick][iStripThin];
1824 const Double_t dE = (N2 - N1) * calibCoeffsThick[iStripThick][0];
1825 const Double_t pixelThickness = GetThicknessByHighElossCubic(dE) - deadLayerThick;
1826 hist->SetBinContent(iStripThick + 1, iStripThin + 1, pixelThickness);
1827 stripMap.push_back(pixelThickness);
1829 sensorMap.push_back(stripMap);
1832 const TString mapTxtPath = fIOManager->GetPath(
1833 TXT_HIST_NON_UNIFORM_MAP_PATH, fMapSensors->at(0)->fRunId, fMapSensors
1835 auto mapFile = fIOManager->CreateTextFile(mapTxtPath);
1836 Dump2DVector(sensorMap, mapFile);
Double_t GetDeadLayerByEta(const Double_t eta)
Returns dead layer thickness [um] by eta parameter value. d(eta) is a qudratic approximation // in fo...
std::ifstream OpenTextFile(const TString &filePath)
Opens output text file.
void Write(const TObjArray *arr)
Serilizes list of objects to a current opened ROOT file directory.
TString ConstructSensorFilePath(const std::set< TString > &subdirs, const TString &prefix, const TString &nameRoot, const std::vector< SensorRunInfo * > *sensors, const TString &extension="root")
Returns file path according to sensor names, prefix and extension by scheme [WORK_DIR]/(sensor_name_1...
std::list< Double_t > GetPeaks(TH1 *hist, const std::list< Double_t > &initGuess)
Returns peaks according to set options. Restores histogram bin range (0, Nbins) after search by any m...
std::ofstream CreateTextFile(const TString &filePath)
Creates output text file Creates a file and all the needed subdirectories.
void MultiplicitySelection(const SensorRunInfo *sensor, std::vector< SensorRunInfo * > sensorsZeroSignal=std::vector< SensorRunInfo * >())
Performs multiplicity selection of a data. Method creates a tree where in each event analyzed sensors...
void FindThresholds(const TString &opt="draw_off")
Finds noise thresholds, saves results to a file. Algorithm: 1) Find bin number with maximal amplitude...
TFile * OpenRootFile(const TString &filePath)
Opens ROOT file.
TFile * CreateRootFile(const TString &filePath)
Creates output ROOT-file Creates a file and all the needed subdirectories.
TString ConstructFilePath(const std::set< TString > &subdirs, const TString &prefix, const TString &nameRoot, const std::vector< SensorRunInfo * > *sensors, const TString &extension="root")
Returns file path according to subdirs list, prefix and extension by scheme [WORK_DIR]/(subdirs)/(pre...
std::list< Double_t > GaussPeakSearch(TH1 *hist, const std::list< Double_t > &initGuess, const Int_t searchRadius)
Searchs peaks on a histogram by the 'gaus + pol1' fit. Algorithm:
std::list< Double_t > SlidingWindowPeakSearch(TH1 *hist, const std::list< Double_t > &initGuess, const Int_t windowWidth, const Int_t searchRadius)
Searchs peaks on a histogram by the "sliding window" algorithm. Algorithm:
void ChangeDir(const TString &dirname)
Changes working directory.
void SetThresholdFile(const TString &path)
Sets threshold file path. Threshold integer values for each strip are listed in a file in ascending s...
void AddSensor(SensorRunInfo *sensor)
Adds sensor to a current preprocessing. Sensors are form common file.
void Exec()
Executes all calibration steps 1) Peaks position determination. 2) Dead layer estimation. 3) Calibration coefficients calculation. 4) Report file printing.
void CreateSpectraHists(const SensorRunInfo *sensor)
Creates strips spectra for the further analysis analysis. Saves resulting hists for each sensor by pa...
TString GetPath(const Int_t fileType, const TString &nameRoot, const std::vector< SensorRunInfo * > *sensors=nullptr)
Returns a path to a desired file File storing structure is fixed for the calibrations procedure...
std::list< Double_t > GetPeaksTSpectrum(TH1 *hist, const Double_t fitMinSigma, const Double_t fitPeakThreshold)
void PrintReport(const std::vector< std::vector< Double_t >> &peaks, const std::vector< Double_t > &deadVec, const Double_t avgDead, const std::vector< std::vector< Double_t >> &coeffsAB)
Finds peaks with a set algorithm method. Stores statistic files in the directory [WORK_DIR]/run_id/se...
std::vector< T > GetSensorThresholds(const SensorRunInfo *sensor, const TString &runId)
Returns a std::vector of sensor noise threshold. If user defined file was set for sensor...
void ConvertTree(const TString &option="neevent")
Prepares raw input tree by leaving only leaves needed for the further analysis. As a result file [WOR...
void MakeDir(const TString &dirname)
Creates directory in a current working directory.