From d547d69a5142a1da1dd3c108c064498f879ace5e Mon Sep 17 00:00:00 2001 From: Adrian Weber <adrian.a.weber@physik.uni-giessen.de> Date: Wed, 16 Feb 2022 11:14:30 +0100 Subject: [PATCH] add data reconstruction macro for 2021, analysis macro for alignment + alignment matrix generator --- .../beamtime/mcbm2021/create_alignment_file.C | 67 + macro/beamtime/mcbm2021/mcbm_event_reco.C | 969 +++++++++++++ .../mcbm2021/mcbm_inspect_alignment.C | 1214 +++++++++++++++++ reco/detectors/tof/CbmTofFindTracks.cxx | 1 + 4 files changed, 2251 insertions(+) create mode 100644 macro/beamtime/mcbm2021/create_alignment_file.C create mode 100644 macro/beamtime/mcbm2021/mcbm_event_reco.C create mode 100644 macro/beamtime/mcbm2021/mcbm_inspect_alignment.C diff --git a/macro/beamtime/mcbm2021/create_alignment_file.C b/macro/beamtime/mcbm2021/create_alignment_file.C new file mode 100644 index 0000000000..72803fcacc --- /dev/null +++ b/macro/beamtime/mcbm2021/create_alignment_file.C @@ -0,0 +1,67 @@ +/* Copyright (C) 2022 UGiessen, Giessen + SPDX-License-Identifier: GPL-3.0-only + Authors: Florian Uhlig, Adrian Weber [committer]*/ + +#include <TFile.h> +#include <TGeoMatrix.h> + +#include <map> +#include <string> + +std::pair<std::string, TGeoHMatrix> AlignNode(std::string path, double shiftX, double shiftY, double shiftZ, + double rotX, double rotY, double rotZ) +{ + + TGeoHMatrix result; + result.SetDx(shiftX); + result.SetDy(shiftY); + result.SetDz(shiftZ); + result.RotateX(rotX); + result.RotateY(rotY); + result.RotateZ(rotZ); + + std::cout << "Alignment matrix for node " << path << " is: " << std::endl; + result.Print(); + std::cout << std::endl; + + return std::pair<std::string, TGeoHMatrix>(path, result); +} + + +int create_alignment_file() +{ + // Define the basic structure which needs to be filled with information + // This structure is stored in the output file and later passed to the + // FairRoot framework to do the (miss)alignment + std::map<std::string, TGeoHMatrix> matrices; + + // ---------------- STS ----------------------------// + // Align full STS + matrices.insert(AlignNode("/cave_1/sts_v22c_mcbm_0", 0.275, -0.89, -.5, 0., 0., 0.)); + + // Align individual STS Units + // Station 1 + // Unit 0 + matrices.insert(AlignNode("/cave_1/sts_v22c_mcbm_0/Station01_1/Ladder09_1", 0.0, 0.045, 0., 0., 0., 0.)); + // Unit 1 + matrices.insert(AlignNode("/cave_1/sts_v22c_mcbm_0/Station01_1/Ladder09_2", -0.04, 0.06, 0., 0., 0., 0.)); + + // Station 2 + // Unit 2 + matrices.insert(AlignNode("/cave_1/sts_v22c_mcbm_0/Station02_2/Ladder10_2", 0.0, -0.11, 0., 0., 0., 0.)); + + // ---------------- TOF ----------------------------// + // Align full Tof + matrices.insert(AlignNode("/cave_1/tof_v21d_mcbm_0/tof_v21d_mcbmStand_1", 0.85, -1.05, 0.0, 0., 0.5, 0.)); + + + // save matrices to disk + TFile* misalignmentMatrixRootfile = new TFile("AlignmentMatrices.root", "RECREATE"); + if (misalignmentMatrixRootfile->IsOpen()) { + gDirectory->WriteObject(&matrices, "MisalignMatrices"); + misalignmentMatrixRootfile->Write(); + misalignmentMatrixRootfile->Close(); + } + + return 0; +} diff --git a/macro/beamtime/mcbm2021/mcbm_event_reco.C b/macro/beamtime/mcbm2021/mcbm_event_reco.C new file mode 100644 index 0000000000..d44e297085 --- /dev/null +++ b/macro/beamtime/mcbm2021/mcbm_event_reco.C @@ -0,0 +1,969 @@ +/* Copyright (C) 2020 Facility for Antiproton and Ion Research in Europe, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Pierre-Alain Loizeau, Adrian Weber [committer] */ + +// -------------------------------------------------------------------------- +// +// Macro for reconstruction of mcbm data (2021) +// Combined reconstruction (cluster + hit finder) for different subsystems. +// +// -------------------------------------------------------------------------- + +#include <math.h> +#include <stdio.h> +#include <string.h> + +/// FIXME: Disable clang formatting to keep easy parameters overview +/* clang-format off */ +Bool_t mcbm_event_reco(UInt_t uRunId = 1588, + Int_t nTimeslices = 20, + TString sInpDir = "/data/cbmroot/files/mTofCriPar2", + TString sOutDir = "rec/tofPar2_noAlign_L1/", + TString alignmentMatrixFileName = "AlignmentMatrices.root", + Int_t iUnpFileIndex = -1) +{ + /// FIXME: Re-enable clang formatting after parameters initial values setting + /* clang-format on */ + + // --- Logger settings ---------------------------------------------------- + TString logLevel = "INFO"; + TString logVerbosity = "LOW"; + // ------------------------------------------------------------------------ + + + // ----- Environment -------------------------------------------------- + TString myName = "mcbm_event_reco"; // this macro's name for screen output + TString srcDir = gSystem->Getenv("VMCWORKDIR"); // top source directory + // ------------------------------------------------------------------------ + + + // ----- In- and output file names ------------------------------------ + /// Standardized RUN ID + TString sRunId = TString::Format("%04u", uRunId); + + /// Initial pattern + TString inFile = sInpDir + "/" + sRunId + ".digi"; + + //TString parFileIn = sInpDir + "/unp_mcbm_params_" + sRunId; + TString parFileOut = sOutDir + "/reco_event_mcbm_params_" + sRunId; + TString outFile = sOutDir + "/reco_event_mcbm_" + sRunId; + + // Your folder with the Tof Calibration files; + TString TofFileFolder = "/data/cbmroot/files/tofCal/mTofCriPar2/"; + + + /// Add index of splitting at unpacking level if needed + if (0 <= iUnpFileIndex) { + inFile += TString::Format("_%02u", iUnpFileIndex); + // the input par file is not split during unpacking! + parFileOut += TString::Format("_%02u", iUnpFileIndex); + outFile += TString::Format("_%02u", iUnpFileIndex); + } // if ( 0 <= uUnpFileIndex ) + /// Add ROOT file suffix + inFile += ".root"; + // parFileIn += ".root"; + parFileOut += ".root"; + outFile += ".root"; + // --------------------------------------------- + + // ----- EventBuilder Settings---------------- + const Int_t eb_TriggerMinNumberT0 {0}; + const Int_t eb_TriggerMinNumberSts {0}; + const Int_t eb_TriggerMinNumberMuch {0}; + const Int_t eb_TriggerMinNumberTof {2}; + const Int_t eb_TriggerMinNumberRich {5}; + + // ----- TOF defaults ------------------------ + Int_t calMode = 93; + Int_t calSel = 1; + Int_t calSm = 0; + Int_t RefSel = 0; + Double_t dDeadtime = 50.; + Int_t iSel2 = 20; //500; + + // Tracking + Int_t iSel = 1; //500;//910041; + Int_t iTrackingSetup = 2; + Int_t iGenCor = 1; + Double_t dScalFac = 1.; + Double_t dChi2Lim2 = 500.; + Bool_t bUseSigCalib = kFALSE; + Int_t iCalOpt = 0; + Int_t iTrkPar = 3; + // ------------------------------------------------------------------------ + + // ----- TOF Calibration Settings --------------------------------------- + TString cCalId = "490.100.5.0"; + if (uRunId >= 759) cCalId = "759.100.4.0"; + if (uRunId >= 812) cCalId = "831.100.4.0"; + if (uRunId >= 1588) cCalId = "1588.50.6.0"; + Int_t iCalSet = 30040500; // calibration settings + if (uRunId >= 759) iCalSet = 10020500; + if (uRunId >= 812) iCalSet = 10020500; + if (uRunId >= 1588) iCalSet = 12002002; + + Double_t Tint = 100.; // coincidence time interval + Int_t iTrackMode = 2; // 2 for TofTracker + const Int_t iTofCluMode = 1; + // ------------------------------------------------------------------------ + + // --- Load the geometry setup ---- + // This is currently only required by the TRD (parameters) + TString geoSetupTag = "mcbm_beam_2021_07_surveyed"; + TString geoFile = srcDir + "/macro/mcbm/data/" + geoSetupTag + ".geo.root"; + CbmSetup* geoSetup = CbmSetup::Instance(); + geoSetup->LoadSetup(geoSetupTag); + + // You can modify the pre-defined setup by using + geoSetup->SetActive(ECbmModuleId::kMvd, kFALSE); + geoSetup->SetActive(ECbmModuleId::kSts, kTRUE); + geoSetup->SetActive(ECbmModuleId::kMuch, kFALSE); + geoSetup->SetActive(ECbmModuleId::kRich, kFALSE); + geoSetup->SetActive(ECbmModuleId::kTrd, kTRUE); + geoSetup->SetActive(ECbmModuleId::kTof, kTRUE); + geoSetup->SetActive(ECbmModuleId::kPsd, kFALSE); + + //----- Load Parameters -------------------------------------------------- + TList* parFileList = new TList(); + TofFileFolder = Form("%s/%s", TofFileFolder.Data(), cCalId.Data()); + + // ----- TRD digitisation parameters ------------------------------------- + TString geoTagTrd; + if (geoSetup->IsActive(ECbmModuleId::kTrd)) { + if (geoSetup->GetGeoTag(ECbmModuleId::kTrd, geoTagTrd)) { + TString paramFilesTrd(Form("%s/parameters/trd/trd_%s", srcDir.Data(), geoTagTrd.Data())); + std::vector<TString> paramFilesVecTrd = {"asic", "digi", "gas", "gain"}; + for (auto parIt : paramFilesVecTrd) { + parFileList->Add(new TObjString(Form("%s.%s.par", paramFilesTrd.Data(), parIt.Data()))); + } + } + for (auto parFileVecIt : *parFileList) { + LOG(debug) << Form("TrdParams - %s - added to parameter file list\n", parFileVecIt->GetName()); + } + } + // ----- TOF digitisation parameters ------------------------------------- + TString geoTag; + if (geoSetup->IsActive(ECbmModuleId::kTof)) { + geoSetup->GetGeoTag(ECbmModuleId::kTof, geoTag); + TObjString* tofBdfFile = new TObjString(srcDir + "/parameters/tof/tof_" + geoTag + ".digibdf.par"); + parFileList->Add(tofBdfFile); + std::cout << "-I- " << myName << ": Using parameter file " << tofBdfFile->GetString() << std::endl; + } + // ------------------------------------------------------------------------ + + // ----- Timer -------------------------------------------------------- + TStopwatch timer; + timer.Start(); + // ------------------------------------------------------------------------ + + + // ----- FairRunAna --------------------------------------------------- + FairRunAna* run = new FairRunAna(); + FairFileSource* inputSource = new FairFileSource(inFile); + run->SetSource(inputSource); + + FairRootFileSink* outputSink = new FairRootFileSink(outFile); + run->SetSink(outputSink); + run->SetGeomFile(geoFile); + + // Define output file for FairMonitor histograms + TString monitorFile {outFile}; + monitorFile.ReplaceAll("reco", "reco.monitor"); + FairMonitor::GetMonitor()->EnableMonitor(kTRUE, monitorFile); + // ------------------------------------------------------------------------ + + + // ----- Logger settings ---------------------------------------------- + FairLogger::GetLogger()->SetLogScreenLevel(logLevel.Data()); + FairLogger::GetLogger()->SetLogVerbosityLevel(logVerbosity.Data()); + //FairLogger::GetLogger()->SetLogScreenLevel("DEBUG"); + // ------------------------------------------------------------------------ + + + // ========================================================================= + // === Alignment Correction === + // ========================================================================= + // (Fairsoft Apr21p2 or newer is needed) + + if (alignmentMatrixFileName.Length() != 0) { + std::cout << "-I- " << myName << ": Applying alignment for file " << alignmentMatrixFileName << std::endl; + + // Define the basic structure which needs to be filled with information + // This structure is stored in the output file and later passed to the + // FairRoot framework to do the (miss)alignment + std::map<std::string, TGeoHMatrix>* matrices {nullptr}; + + // read matrices from disk + LOG(info) << "Filename: " << alignmentMatrixFileName; + TFile* misalignmentMatrixRootfile = new TFile(alignmentMatrixFileName, "READ"); + if (misalignmentMatrixRootfile->IsOpen()) { + gDirectory->GetObject("MisalignMatrices", matrices); + misalignmentMatrixRootfile->Close(); + } + else { + LOG(error) << "Could not open file " << alignmentMatrixFileName << "\n Exiting"; + exit(1); + } + + if (matrices) { run->AddAlignmentMatrices(*matrices); } + else { + LOG(error) << "Alignment required but no matrices found." + << "\n Exiting"; + exit(1); + } + } + // ------------------------------------------------------------------------ + + + // --------------------event builder--------------------------------------- + CbmTaskBuildRawEvents* evBuildRaw = new CbmTaskBuildRawEvents(); + + //Choose between NoOverlap, MergeOverlap, AllowOverlap + evBuildRaw->SetEventOverlapMode(EOverlapModeRaw::AllowOverlap); + + // Remove detectors where digis not found + if (!geoSetup->IsActive(ECbmModuleId::kRich)) evBuildRaw->RemoveDetector(kRawEventBuilderDetRich); + if (!geoSetup->IsActive(ECbmModuleId::kMuch)) evBuildRaw->RemoveDetector(kRawEventBuilderDetMuch); + if (!geoSetup->IsActive(ECbmModuleId::kPsd)) evBuildRaw->RemoveDetector(kRawEventBuilderDetPsd); + if (!geoSetup->IsActive(ECbmModuleId::kTrd)) evBuildRaw->RemoveDetector(kRawEventBuilderDetTrd); + if (!geoSetup->IsActive(ECbmModuleId::kSts)) evBuildRaw->RemoveDetector(kRawEventBuilderDetSts); + if (!geoSetup->IsActive(ECbmModuleId::kTof)) evBuildRaw->RemoveDetector(kRawEventBuilderDetTof); + + // Set TOF as reference detector + evBuildRaw->SetReferenceDetector(kRawEventBuilderDetTof); + + // void SetTsParameters(double TsStartTime, double TsLength, double TsOverLength): TsStartTime=0, TsLength=256ms in 2021, TsOverLength=TS overlap, not used in mCBM2021 + evBuildRaw->SetTsParameters(0.0, 2.56e8, 0.0); + + if (geoSetup->IsActive(ECbmModuleId::kTof)) + evBuildRaw->SetTriggerMinNumber(ECbmModuleId::kTof, eb_TriggerMinNumberTof); + + if (geoSetup->IsActive(ECbmModuleId::kTof)) evBuildRaw->SetTriggerMaxNumber(ECbmModuleId::kTof, -1); + + //evBuildRaw->SetTriggerMinNumber(ECbmModuleId::kSts, eb_TriggerMinNumberSts); + //evBuildRaw->SetTriggerMaxNumber(ECbmModuleId::kSts, -1); + + //evBuildRaw->SetTriggerMinNumber(ECbmModuleId::kRich, eb_TriggerMinNumberRich); + //evBuildRaw->SetTriggerMaxNumber(ECbmModuleId::kRich, -1); + + if (geoSetup->IsActive(ECbmModuleId::kTof)) evBuildRaw->SetTriggerWindow(ECbmModuleId::kTof, -50, 50); + if (geoSetup->IsActive(ECbmModuleId::kSts)) evBuildRaw->SetTriggerWindow(ECbmModuleId::kSts, -50, 50); + if (geoSetup->IsActive(ECbmModuleId::kTrd)) evBuildRaw->SetTriggerWindow(ECbmModuleId::kTrd, -200, 200); + if (geoSetup->IsActive(ECbmModuleId::kRich)) evBuildRaw->SetTriggerWindow(ECbmModuleId::kRich, -50, 50); + + run->AddTask(evBuildRaw); + // ------------------------------------------------------------------------ + + + // ----- Reconstruction tasks ----------------------------------------- + + + // ========================================================================= + // === local STS Reconstruction === + // ========================================================================= + + if (geoSetup->IsActive(ECbmModuleId::kSts)) { + CbmRecoSts* recoSts = new CbmRecoSts(); + recoSts->SetMode(kCbmRecoEvent); + + recoSts->SetTimeCutDigisAbs(20.0); // cluster finder: time cut in ns + recoSts->SetTimeCutClustersAbs(20.0); // hit finder: time cut in ns + + // Sensor params + CbmStsParSensor sensor6cm(CbmStsSensorClass::kDssdStereo); + sensor6cm.SetPar(0, 6.2092); // Extension in x + sensor6cm.SetPar(1, 6.2); // Extension in y + sensor6cm.SetPar(2, 0.03); // Extension in z + sensor6cm.SetPar(3, 5.9692); // Active size in y + sensor6cm.SetPar(4, 1024.); // Number of strips front side + sensor6cm.SetPar(5, 1024.); // Number of strips back side + sensor6cm.SetPar(6, 0.0058); // Strip pitch front side + sensor6cm.SetPar(7, 0.0058); // Strip pitch back side + sensor6cm.SetPar(8, 0.0); // Stereo angle front side + sensor6cm.SetPar(9, 7.5); // Stereo angle back side + + CbmStsParSensor sensor12cm(sensor6cm); // copy all parameters, change then only the y size + sensor12cm.SetPar(1, 12.4); // Extension in y + sensor12cm.SetPar(3, 12.1692); // Active size in y + + // --- Addresses for sensors + // --- They are defined in each station as sensor 1, module 1, halfladderD (2), ladder 1 + // Int_t GetAddress(UInt_t unit = 0, UInt_t ladder = 0, UInt_t halfladder = 0, UInt_t module = 0, UInt_t sensor = 0, + // UInt_t side = 0, UInt_t version = kCurrentVersion); + + Int_t stsAddress01 = CbmStsAddress::GetAddress(0, 0, 1, 0, 0, 0); // U0 L0 M0 6 cm + Int_t stsAddress02 = CbmStsAddress::GetAddress(0, 0, 1, 1, 0, 0); // U0 L0 M1 6 cm + Int_t stsAddress03 = CbmStsAddress::GetAddress(0, 1, 1, 0, 0, 0); // U0 L1 M0 6 cm + Int_t stsAddress04 = CbmStsAddress::GetAddress(0, 1, 1, 1, 0, 0); // U0 L1 M1 6 cm + Int_t stsAddress05 = CbmStsAddress::GetAddress(1, 0, 1, 0, 0, 0); // U1 L0 M0 6 cm + Int_t stsAddress06 = CbmStsAddress::GetAddress(1, 0, 1, 1, 0, 0); // U1 L0 M1 12 cm + Int_t stsAddress07 = CbmStsAddress::GetAddress(1, 1, 1, 0, 0, 0); // U1 L1 M0 6 cm + Int_t stsAddress08 = CbmStsAddress::GetAddress(1, 1, 1, 1, 0, 0); // U1 L1 M1 12 cm + Int_t stsAddress09 = CbmStsAddress::GetAddress(1, 2, 1, 0, 0, 0); // U1 L2 M0 6 cm + Int_t stsAddress10 = CbmStsAddress::GetAddress(1, 2, 1, 1, 0, 0); // U1 L2 M1 6 cm + Int_t stsAddress11 = CbmStsAddress::GetAddress(1, 2, 1, 2, 0, 0); // U1 L2 M2 6 cm + + + std::cout << "STS address01 " << std::dec << stsAddress01 << " " << std::hex << stsAddress01 << std::endl; + std::cout << "STS address02 " << std::dec << stsAddress02 << " " << std::hex << stsAddress02 << std::endl; + std::cout << "STS address03 " << std::dec << stsAddress03 << " " << std::hex << stsAddress03 << std::endl; + std::cout << "STS address04 " << std::dec << stsAddress04 << " " << std::hex << stsAddress04 << std::endl; + std::cout << "STS address05 " << std::dec << stsAddress05 << " " << std::hex << stsAddress05 << std::endl; + std::cout << "STS address06 " << std::dec << stsAddress06 << " " << std::hex << stsAddress06 << std::endl; + std::cout << "STS address07 " << std::dec << stsAddress07 << " " << std::hex << stsAddress07 << std::endl; + std::cout << "STS address08 " << std::dec << stsAddress08 << " " << std::hex << stsAddress08 << std::endl; + std::cout << "STS address09 " << std::dec << stsAddress09 << " " << std::hex << stsAddress09 << std::endl; + std::cout << "STS address10 " << std::dec << stsAddress10 << " " << std::hex << stsAddress10 << std::endl; + std::cout << "STS address11 " << std::dec << stsAddress11 << " " << std::hex << stsAddress11 << std::endl; + + // --- Now we can define the sensor parameter set and tell recoSts to use it + auto sensorParSet = new CbmStsParSetSensor("CbmStsParSetSensor", "STS sensor parameters" + "mcbm2021"); + sensorParSet->SetParSensor(stsAddress01, sensor6cm); + sensorParSet->SetParSensor(stsAddress02, sensor6cm); + sensorParSet->SetParSensor(stsAddress03, sensor6cm); + sensorParSet->SetParSensor(stsAddress04, sensor6cm); + sensorParSet->SetParSensor(stsAddress05, sensor6cm); + sensorParSet->SetParSensor(stsAddress06, sensor12cm); + sensorParSet->SetParSensor(stsAddress07, sensor6cm); + sensorParSet->SetParSensor(stsAddress08, sensor12cm); + sensorParSet->SetParSensor(stsAddress09, sensor6cm); + sensorParSet->SetParSensor(stsAddress10, sensor6cm); + sensorParSet->SetParSensor(stsAddress11, sensor6cm); + + recoSts->UseSensorParSet(sensorParSet); + + // ASIC params: #ADC channels, dyn. range, threshold, time resol., dead time, + // noise RMS, zero-threshold crossing rate + auto parAsic = new CbmStsParAsic(128, 32, 75000., 3000., 5., 800., 1000., 3.9789e-3); + + // Module params: number of channels, number of channels per ASIC + auto parMod = new CbmStsParModule(2048, 128); + parMod->SetAllAsics(*parAsic); + recoSts->UseModulePar(parMod); + + // Sensor conditions: full depletion voltage, bias voltage, temperature, + // coupling capacitance, inter-strip capacitance + auto sensorCond = new CbmStsParSensorCond(70., 140., 268., 17.5, 1.); + recoSts->UseSensorCond(sensorCond); + + run->AddTask(recoSts); + std::cout << "-I- : Added task " << recoSts->GetName() << std::endl; + // ------------------------------------------------------------------------ + } + + // ========================================================================= + // === local TRD Reconstruction === + // ========================================================================= + + CbmTrdClusterFinder* trdCluster; + if (geoSetup->IsActive(ECbmModuleId::kTrd)) { + Double_t triggerThreshold = 0.5e-6; // SIS100 + + trdCluster = new CbmTrdClusterFinder(); + trdCluster->SetNeighbourEnable(true, false); + trdCluster->SetMinimumChargeTH(triggerThreshold); + trdCluster->SetRowMerger(true); + run->AddTask(trdCluster); + std::cout << "-I- : Added task " << trdCluster->GetName() << std::endl; + + CbmTrdHitProducer* trdHit = new CbmTrdHitProducer(); + run->AddTask(trdHit); + std::cout << "-I- : Added task " << trdHit->GetName() << std::endl; + } + + + // ========================================================================= + // === RICH Reconstruction === + // ========================================================================= + + if (geoSetup->IsActive(ECbmModuleId::kRich)) { + // ----- Local reconstruction of RICH Hits ------------------------------ + CbmRichMCbmHitProducer* hitProd = new CbmRichMCbmHitProducer(); + hitProd->setToTLimits(23.7, 30.0); + hitProd->applyToTCut(); + run->AddTask(hitProd); + // ------------------------------------------------------------------------ + + + // ----- Local reconstruction in RICh -> Finding of Rings --------------- + CbmRichReconstruction* richReco = new CbmRichReconstruction(); + richReco->UseMCbmSetup(); + run->AddTask(richReco); + // ------------------------------------------------------------------------ + } + + // ========================================================================= + // === TOF Hitfinding === + // ========================================================================= + + if (geoSetup->IsActive(ECbmModuleId::kTof)) { + TString cFname; + switch (iTofCluMode) { + case 1: { + CbmTofEventClusterizer* tofCluster = new CbmTofEventClusterizer("TOF Event Clusterizer", 0, 1); + cFname = Form("/%s_set%09d_%02d_%01dtofClust.hst.root", cCalId.Data(), iCalSet, calMode, calSel); + tofCluster->SetCalParFileName(TofFileFolder + cFname); + tofCluster->SetCalMode(calMode); + tofCluster->SetCalSel(calSel); + tofCluster->SetCaldXdYMax(300.); // geometrical matching window in cm + tofCluster->SetCalCluMulMax(3.); // Max Counter Cluster Multiplicity for filling calib histos + tofCluster->SetCalRpc(calSm); // select detector for calibration update + tofCluster->SetTRefId(RefSel); // reference trigger for offset calculation + tofCluster->SetTotMax(20.); // Tot upper limit for walk corection + tofCluster->SetTotMin(0.); //(12000.); // Tot lower limit for walk correction + tofCluster->SetTotPreRange(5.); // effective lower Tot limit in ns from peak position + tofCluster->SetTotMean(5.); // Tot calibration target value in ns + tofCluster->SetMaxTimeDist(1.0); // default cluster range in ns + tofCluster->SetDelTofMax(50.); // acceptance range for cluster distance in ns (!) + tofCluster->SetSel2MulMax(3); // limit Multiplicity in 2nd selector + tofCluster->SetChannelDeadtime(dDeadtime); // artificial deadtime in ns + tofCluster->SetEnableAvWalk(kFALSE); + //tofCluster->SetEnableMatchPosScaling(kFALSE); // turn off projection to nominal target + tofCluster->SetYFitMin(1.E4); + tofCluster->SetToDAv(0.04); + tofCluster->SetIdMode(1); // calibrate on module level + tofCluster->SetTRefDifMax(2.0); // in ns + tofCluster->PosYMaxScal(0.75); //in % of length + Int_t iBRef = iCalSet % 1000; + Int_t iSet = (iCalSet - iBRef) / 1000; + Int_t iRSel = 0; + Int_t iRSelTyp = 0; + Int_t iRSelSm = 0; + Int_t iRSelRpc = 0; + iRSel = iBRef; // use diamond + Int_t iRSelin = iRSel; + iRSelRpc = iRSel % 10; + iRSelTyp = (iRSel - iRSelRpc) / 10; + iRSelSm = iRSelTyp % 10; + iRSelTyp = (iRSelTyp - iRSelSm) / 10; + tofCluster->SetBeamRefId(iRSelTyp); // define Beam reference counter + tofCluster->SetBeamRefSm(iRSelSm); + tofCluster->SetBeamRefDet(iRSelRpc); + tofCluster->SetBeamAddRefMul(-1); + tofCluster->SetBeamRefMulMax(3); + Int_t iSel2in = iSel2; + Int_t iSel2Rpc = iSel2 % 10; + iSel2 = (iSel2 - iSel2Rpc) / 10; + Int_t iSel2Sm = iSel2 % 10; + iSel2 = (iSel2 - iSel2Sm) / 10; + if (iSel2 > -1) { + tofCluster->SetSel2Id(iSel2); + tofCluster->SetSel2Sm(iSel2Sm); + tofCluster->SetSel2Rpc(iSel2Rpc); + } + Int_t iRef = iSet % 1000; + Int_t iDut = (iSet - iRef) / 1000; + Int_t iDutRpc = iDut % 10; + iDut = (iDut - iDutRpc) / 10; + Int_t iDutSm = iDut % 10; + iDut = (iDut - iDutSm) / 10; + tofCluster->SetDutId(iDut); + tofCluster->SetDutSm(iDutSm); + tofCluster->SetDutRpc(iDutRpc); + + Int_t iRefRpc = iRef % 10; + iRef = (iRef - iRefRpc) / 10; + Int_t iRefSm = iRef % 10; + iRef = (iRef - iRefSm) / 10; + + tofCluster->SetSelId(iRef); + tofCluster->SetSelSm(iRefSm); + tofCluster->SetSelRpc(iRefRpc); + + run->AddTask(tofCluster); + std::cout << "-I- " << myName << ": Added task " << tofCluster->GetName() << std::endl; + } break; + + default: { + ; + } + } + // ------------------------------------------------------------------------- + + + // ========================================================================= + // === Tof Tracking === + // ========================================================================= + + cout << "<I> Initialize Tof tracker by ini_trks" << endl; + TString cTrkFile = Form("%s/%s_tofFindTracks.hst.root", TofFileFolder.Data(), cCalId.Data()); + + // ----- Local selection variables -------------------------------------- + + Int_t iRef = iSel % 1000; + Int_t iDut = (iSel - iRef) / 1000; + Int_t iDutRpc = iDut % 10; + iDut = (iDut - iDutRpc) / 10; + Int_t iDutSm = iDut % 10; + iDut = (iDut - iDutSm) / 10; + Int_t iBucRpc = 0; + + // ========================================================================= + // === Tracking === + // ========================================================================= + + CbmTofTrackFinder* tofTrackFinder = new CbmTofTrackFinderNN(); + tofTrackFinder->SetMaxTofTimeDifference(0.2); // in ns/cm + Int_t TrackerPar = 0; + switch (TrackerPar) { + case 0: // for full mTof setup + tofTrackFinder->SetTxLIM(0.3); // max slope dx/dz + tofTrackFinder->SetTyLIM(0.3); // max dev from mean slope dy/dz + tofTrackFinder->SetTxMean(0.); // mean slope dy/dz + tofTrackFinder->SetTyMean(0.); // mean slope dy/dz + break; + case 1: // for double stack test counters + tofTrackFinder->SetTxMean(0.21); // mean slope dy/dz + tofTrackFinder->SetTyMean(0.18); // mean slope dy/dz + tofTrackFinder->SetTxLIM(0.15); // max slope dx/dz + tofTrackFinder->SetTyLIM(0.18); // max dev from mean slope dy/dz + break; + } + + CbmTofTrackFitter* tofTrackFitter = new CbmTofTrackFitterKF(0, 211); + TFitter* MyFit = new TFitter(1); // initialize Minuit + tofTrackFinder->SetFitter(tofTrackFitter); + CbmTofFindTracks* tofFindTracks = new CbmTofFindTracks("TOF Track Finder"); + tofFindTracks->UseFinder(tofTrackFinder); + tofFindTracks->UseFitter(tofTrackFitter); + tofFindTracks->SetCalOpt(iCalOpt); // 1 - update offsets, 2 - update walk, 0 - bypass + tofFindTracks->SetCorMode(iGenCor); // valid options: 0,1,2,3,4,5,6, 10 - 19 + tofFindTracks->SetTtTarg(0.042); // target value Mar2021, after T0 fix (double stack run 1058) + tofFindTracks->SetCalParFileName(cTrkFile); // Tracker parameter value file name + tofFindTracks->SetBeamCounter(5, 0, 0); // default beam counter + tofFindTracks->SetR0Lim(20.); + tofFindTracks->SetStationMaxHMul(30); // Max Hit Multiplicity in any used station + + tofFindTracks->SetT0MAX(dScalFac); // in ns + tofFindTracks->SetSIGT(0.08); // default in ns + tofFindTracks->SetSIGX(0.3); // default in cm + tofFindTracks->SetSIGY(0.45); // default in cm + tofFindTracks->SetSIGZ(0.05); // default in cm + tofFindTracks->SetUseSigCalib(bUseSigCalib); // ignore resolutions in CalPar file + tofTrackFinder->SetSIGLIM(dChi2Lim2 * 2.); // matching window in multiples of chi2 + tofTrackFinder->SetChiMaxAccept(dChi2Lim2); // max tracklet chi2 + + Int_t iMinNofHits = -1; + Int_t iNStations = 0; + Int_t iNReqStations = 3; + + switch (iTrackingSetup) { + case 0: // bypass mode + iMinNofHits = -1; + iNStations = 1; + tofFindTracks->SetStation(0, 5, 0, 0); // Diamond + break; + + case 1: // for calibration mode of full setup + { + Double_t dTsig = dScalFac * 0.03; + tofFindTracks->SetSIGT(dTsig); // allow for variable deviations in ns + } + iMinNofHits = 3; + iNStations = 32; + iNReqStations = 4; + tofFindTracks->SetStation(0, 5, 0, 0); + tofFindTracks->SetStation(1, 0, 2, 2); + tofFindTracks->SetStation(2, 0, 1, 2); + tofFindTracks->SetStation(3, 0, 0, 2); + tofFindTracks->SetStation(4, 0, 2, 1); + tofFindTracks->SetStation(5, 0, 1, 1); + tofFindTracks->SetStation(6, 0, 0, 1); + tofFindTracks->SetStation(7, 0, 2, 3); + tofFindTracks->SetStation(8, 0, 1, 3); + tofFindTracks->SetStation(9, 0, 0, 3); + tofFindTracks->SetStation(10, 0, 2, 0); + tofFindTracks->SetStation(11, 0, 1, 0); + tofFindTracks->SetStation(12, 0, 0, 0); + tofFindTracks->SetStation(13, 0, 2, 4); + tofFindTracks->SetStation(14, 0, 1, 4); + tofFindTracks->SetStation(15, 0, 0, 4); + tofFindTracks->SetStation(16, 0, 4, 0); + tofFindTracks->SetStation(17, 0, 3, 0); + tofFindTracks->SetStation(18, 0, 4, 1); + tofFindTracks->SetStation(19, 0, 3, 1); + tofFindTracks->SetStation(20, 0, 4, 2); + tofFindTracks->SetStation(21, 0, 3, 2); + tofFindTracks->SetStation(22, 0, 4, 3); + tofFindTracks->SetStation(23, 0, 3, 3); + tofFindTracks->SetStation(24, 0, 4, 4); + tofFindTracks->SetStation(25, 0, 3, 4); + tofFindTracks->SetStation(26, 9, 0, 0); + tofFindTracks->SetStation(27, 9, 1, 0); + tofFindTracks->SetStation(28, 9, 0, 1); + tofFindTracks->SetStation(29, 9, 1, 1); + tofFindTracks->SetStation(30, 6, 0, 0); + tofFindTracks->SetStation(31, 6, 0, 1); + break; + + case 11: // for calibration mode of 2-stack & test counters + iMinNofHits = 4; + iNStations = 9; + iNReqStations = 5; + tofFindTracks->SetStation(0, 0, 4, 1); + tofFindTracks->SetStation(1, 9, 0, 0); + tofFindTracks->SetStation(2, 9, 1, 0); + tofFindTracks->SetStation(3, 9, 0, 1); + tofFindTracks->SetStation(4, 9, 1, 1); + tofFindTracks->SetStation(5, 0, 3, 1); + tofFindTracks->SetStation(6, 0, 4, 0); + tofFindTracks->SetStation(7, 0, 3, 2); + tofFindTracks->SetStation(8, 5, 0, 0); + break; + + case 2: + iMinNofHits = 5; + iNStations = 28; + iNReqStations = 5; + tofFindTracks->SetStation(0, 0, 2, 2); + tofFindTracks->SetStation(1, 0, 0, 2); + tofFindTracks->SetStation(2, 0, 1, 2); + tofFindTracks->SetStation(3, 0, 2, 1); + tofFindTracks->SetStation(4, 0, 0, 1); + tofFindTracks->SetStation(5, 0, 1, 1); + tofFindTracks->SetStation(6, 0, 2, 3); + tofFindTracks->SetStation(7, 0, 0, 3); + tofFindTracks->SetStation(8, 0, 1, 3); + tofFindTracks->SetStation(9, 0, 2, 0); + tofFindTracks->SetStation(10, 0, 0, 0); + tofFindTracks->SetStation(11, 0, 1, 0); + tofFindTracks->SetStation(12, 0, 2, 4); + tofFindTracks->SetStation(13, 0, 0, 4); + tofFindTracks->SetStation(14, 0, 1, 4); + tofFindTracks->SetStation(15, 0, 4, 0); + tofFindTracks->SetStation(16, 0, 3, 0); + tofFindTracks->SetStation(17, 0, 4, 1); + tofFindTracks->SetStation(18, 0, 3, 1); + tofFindTracks->SetStation(19, 0, 4, 2); + tofFindTracks->SetStation(20, 0, 3, 2); + tofFindTracks->SetStation(21, 0, 4, 3); + tofFindTracks->SetStation(22, 0, 3, 3); + tofFindTracks->SetStation(23, 0, 4, 4); + tofFindTracks->SetStation(24, 0, 3, 4); + tofFindTracks->SetStation(25, 9, 0, 0); + tofFindTracks->SetStation(26, 9, 0, 1); + tofFindTracks->SetStation(27, 5, 0, 0); + break; + + case 3: + iMinNofHits = 3; + iNStations = 16; + iNReqStations = 4; + tofFindTracks->SetStation(0, 5, 0, 0); + tofFindTracks->SetStation(1, 0, 2, 2); + tofFindTracks->SetStation(2, 0, 1, 2); + tofFindTracks->SetStation(3, 0, 0, 2); + + tofFindTracks->SetStation(4, 0, 2, 1); + tofFindTracks->SetStation(5, 0, 1, 1); + tofFindTracks->SetStation(6, 0, 0, 1); + + tofFindTracks->SetStation(7, 0, 2, 3); + tofFindTracks->SetStation(8, 0, 1, 3); + tofFindTracks->SetStation(9, 0, 0, 3); + + tofFindTracks->SetStation(10, 0, 2, 0); + tofFindTracks->SetStation(11, 0, 1, 0); + tofFindTracks->SetStation(12, 0, 0, 0); + + tofFindTracks->SetStation(13, 0, 2, 4); + tofFindTracks->SetStation(14, 0, 1, 4); + tofFindTracks->SetStation(15, 0, 0, 4); + + /* + tofFindTracks->SetStation(16, 0, 3, 2); + tofFindTracks->SetStation(17, 0, 4, 2); + tofFindTracks->SetStation(18, 0, 3, 1); + tofFindTracks->SetStation(19, 0, 4, 1); + tofFindTracks->SetStation(20, 0, 3, 3); + tofFindTracks->SetStation(21, 0, 4, 3); + tofFindTracks->SetStation(22, 0, 3, 0); + tofFindTracks->SetStation(23, 0, 4, 0); + tofFindTracks->SetStation(24, 0, 3, 4); + tofFindTracks->SetStation(25, 0, 4, 4); + */ + break; + + case 4: // for USTC evaluation (dut=910,911) + iMinNofHits = 4; + iNStations = 6; + iNReqStations = 6; + tofFindTracks->SetStation(0, 0, 4, 1); + tofFindTracks->SetStation(1, 0, 3, 1); + tofFindTracks->SetStation(2, 9, 0, 1); + tofFindTracks->SetStation(3, 9, 0, 0); + tofFindTracks->SetStation(4, 5, 0, 0); + tofFindTracks->SetStation(5, iDut, iDutSm, iDutRpc); + break; + + case 14: + iMinNofHits = 3; + iNStations = 15; + iNReqStations = 4; + tofFindTracks->SetStation(0, 0, 2, 2); + tofFindTracks->SetStation(1, 0, 1, 2); + tofFindTracks->SetStation(2, 0, 0, 2); + tofFindTracks->SetStation(0, 0, 2, 1); + tofFindTracks->SetStation(1, 0, 1, 1); + tofFindTracks->SetStation(2, 0, 0, 1); + tofFindTracks->SetStation(0, 0, 2, 0); + tofFindTracks->SetStation(1, 0, 1, 0); + tofFindTracks->SetStation(2, 0, 0, 0); + tofFindTracks->SetStation(0, 0, 2, 3); + tofFindTracks->SetStation(1, 0, 1, 3); + tofFindTracks->SetStation(2, 0, 0, 3); + tofFindTracks->SetStation(0, 0, 2, 4); + tofFindTracks->SetStation(1, 0, 1, 4); + tofFindTracks->SetStation(2, 0, 0, 4); + break; + + case 5: // for calibration of 2-stack and add-on counters (STAR2, BUC) + iMinNofHits = 3; + iNStations = 7; + iNReqStations = 4; + tofFindTracks->SetStation(6, 0, 4, 1); + tofFindTracks->SetStation(1, 6, 0, 1); + tofFindTracks->SetStation(2, 9, 0, 0); + tofFindTracks->SetStation(3, 9, 0, 1); + tofFindTracks->SetStation(4, 6, 0, 0); + tofFindTracks->SetStation(5, 0, 3, 1); + tofFindTracks->SetStation(0, 5, 0, 0); + break; + + case 6: // for double stack USTC counter evaluation + iMinNofHits = 5; + iNStations = 6; + iNReqStations = 6; + tofFindTracks->SetStation(0, 5, 0, 0); + tofFindTracks->SetStation(1, 6, 0, 1); + tofFindTracks->SetStation(2, 0, 4, 1); + tofFindTracks->SetStation(3, 6, 0, 0); + tofFindTracks->SetStation(4, 0, 3, 1); + tofFindTracks->SetStation(5, iDut, iDutSm, iDutRpc); + break; + + case 7: // for double stack USTC counter evaluation + iMinNofHits = 3; + iNStations = 4; + iNReqStations = 4; + tofFindTracks->SetStation(0, 0, 4, 1); + tofFindTracks->SetStation(1, 6, 0, 1); + tofFindTracks->SetStation(2, 6, 0, 0); + tofFindTracks->SetStation(3, iDut, iDutSm, iDutRpc); + break; + + case 8: // evaluation of add-on counters (BUC) + iMinNofHits = 5; + iNStations = 6; + iNReqStations = 6; + tofFindTracks->SetStation(0, 5, 0, 0); + tofFindTracks->SetStation(1, 9, 0, 1); + tofFindTracks->SetStation(2, 0, 4, 1); + tofFindTracks->SetStation(3, 9, 0, 0); + tofFindTracks->SetStation(4, 0, 3, 1); + tofFindTracks->SetStation(5, iDut, iDutSm, iDutRpc); + break; + + case 9: // calibration of Star2 + iMinNofHits = 4; + iNStations = 5; + iNReqStations = 5; + tofFindTracks->SetStation(0, 5, 0, 0); + tofFindTracks->SetStation(2, 9, 0, 1); + tofFindTracks->SetStation(1, 0, 4, 1); + tofFindTracks->SetStation(3, 9, 0, 0); + tofFindTracks->SetStation(4, 0, 3, 1); + break; + + case 10: + iMinNofHits = 3; + iNStations = 4; + iNReqStations = 4; + tofFindTracks->SetStation(0, 5, 0, 0); + tofFindTracks->SetStation(3, 0, 1, 2); + tofFindTracks->SetStation(2, 0, 0, 2); + tofFindTracks->SetStation(1, 0, 2, 2); + break; + + default: + cout << "Tracking setup " << iTrackingSetup << " not implemented " << endl; + return 1; + ; + } + tofFindTracks->SetMinNofHits(iMinNofHits); + tofFindTracks->SetNStations(iNStations); + tofFindTracks->SetNReqStations(iNReqStations); + tofFindTracks->PrintSetup(); + std::cout << "MinNofHitsPerTrack: " << iMinNofHits << std::endl; + run->AddTask(tofFindTracks); + } + + + // ========================================================================= + // === L1 === + // ========================================================================= + + // CbmKF* kalman = new CbmKF(); + // run->AddTask(kalman); + // CbmL1* l1 = new CbmL1(); + // l1->SetLegacyEventMode(1); + // l1->SetMcbmMode(); + // l1->SetUseHitErrors(1); + // if (strcmp(geoSetupTag.data(), "mcbm_beam_2021_07_surveyed") == 0) l1->SetMissingHits(1); + // + // // --- Material budget file names + // TString mvdGeoTag; + // if (geoSetup->GetGeoTag(ECbmModuleId::kMvd, mvdGeoTag)) { + // TString parFile = gSystem->Getenv("VMCWORKDIR"); + // parFile = parFile + "/parameters/mvd/mvd_matbudget_" + mvdGeoTag + ".root"; + // std::cout << "Using material budget file " << parFile << std::endl; + // l1->SetMvdMaterialBudgetFileName(parFile.Data()); + // } + // TString stsGeoTag; + // if (geoSetup->GetGeoTag(ECbmModuleId::kSts, stsGeoTag)) { + // TString parFile = gSystem->Getenv("VMCWORKDIR"); + // parFile = parFile + "/parameters/sts/sts_matbudget_v19a.root"; + // std::cout << "Using material budget file " << parFile << std::endl; + // l1->SetStsMaterialBudgetFileName(parFile.Data()); + // } + // + // TString muchGeoTag; + // if (geoSetup->GetGeoTag(ECbmModuleId::kMuch, muchGeoTag)) { + // + // // --- Parameter file name + // TString geoTag; + // geoSetup->GetGeoTag(ECbmModuleId::kMuch, geoTag); + // Int_t muchFlag = 0; + // if (geoTag.Contains("mcbm")) muchFlag = 1; + // + // TString parFile = gSystem->Getenv("VMCWORKDIR"); + // parFile = parFile + "/parameters/much/much_" + geoTag(0, 4) + "_digi_sector.root"; + // std::cout << "L1: Using parameter file " << parFile << std::endl; + // l1->SetMuchPar(parFile); + // + // TString parFile2 = gSystem->Getenv("VMCWORKDIR"); + // parFile2 = parFile2 + "/parameters/much/much_matbudget_" + geoTag + ".root "; + // std::cout << "Using material budget file " << parFile2 << std::endl; + // l1->SetMuchMaterialBudgetFileName(parFile2.Data()); + // } + // + // TString trdGeoTag; + // if (geoSetup->GetGeoTag(ECbmModuleId::kTrd, trdGeoTag)) { + // TString parFile = gSystem->Getenv("VMCWORKDIR"); + // parFile = parFile + "/parameters/trd/trd_matbudget_" + trdGeoTag + ".root "; + // std::cout << "Using material budget file " << parFile << std::endl; + // l1->SetTrdMaterialBudgetFileName(parFile.Data()); + // } + // + // TString tofGeoTag; + // if (geoSetup->GetGeoTag(ECbmModuleId::kTof, tofGeoTag)) { + // TString parFile = gSystem->Getenv("VMCWORKDIR"); + // parFile = parFile + "/parameters/tof/tof_matbudget_" + tofGeoTag + ".root "; + // std::cout << "Using material budget file " << parFile << std::endl; + // l1->SetTofMaterialBudgetFileName(parFile.Data()); + // } + // + + // Workaround to get it running: + // 1) Change fUseGlobal in line 129 of CbmStsParSetModule.h to + // Bool_t fUseGlobal = kTRUE; + // 2) Change fUseGlobal in line 114 of CbmStsParSetSensor.h to + // Bool_t fUseGlobal = kTRUE; + //run->AddTask(l1); + + // CbmL1GlobalTrackFinder* globalTrackFinder = new CbmL1GlobalTrackFinder(); + // FairTask* globalFindTracks = new CbmL1GlobalFindTracksEvents(globalTrackFinder); + //run->AddTask(globalFindTracks); + + + // ----- Parameter database -------------------------------------------- + std::cout << std::endl << std::endl; + std::cout << "-I- " << myName << ": Set runtime DB" << std::endl; + FairRuntimeDb* rtdb = run->GetRuntimeDb(); + FairParRootFileIo* parIo1 = new FairParRootFileIo(); + FairParAsciiFileIo* parIo2 = new FairParAsciiFileIo(); + FairParRootFileIo* parIo3 = new FairParRootFileIo(); + //parIo1->open(parFileIn.Data(), "READ"); + //rtdb->setFirstInput(parIo1); + parIo2->open(parFileList, "in"); + rtdb->setSecondInput(parIo2); + parIo3->open(parFileOut.Data(), "RECREATE"); + // ------------------------------------------------------------------------ + rtdb->setOutput(parIo3); + rtdb->saveOutput(); + rtdb->print(); + + // ----- Run initialisation ------------------------------------------- + std::cout << std::endl; + std::cout << "-I- " << myName << ": Initialise run" << std::endl; + run->Init(); + + // ------------------------------------------------------------------------ + + // ========================================================================= + // === QA === + // ========================================================================= + + // e.g for RICH: + // CbmRichMCbmQaReal* qaTask = new CbmRichMCbmQaReal(); + // if (taskId < 0) { qaTask->SetOutputDir(Form("result_run%d", uRunId)); } + // else { + // qaTask->SetOutputDir(Form("result_run%d_%05d", uRunId, taskId)); + // } + // qaTask->XOffsetHistos(+25.3); + // qaTask->SetMaxNofDrawnEvents(100); + // qaTask->SetTotRich(23.7, 30.0); + // qaTask->SetTriggerRichHits(eb_TriggerMinNumberRich); + // qaTask->SetTriggerTofHits(1); + // run->AddTask(qaTask); + // ------------------------------------------------------------------------ + + + // ----- Start run ---------------------------------------------------- + std::cout << std::endl << std::endl; + std::cout << "-I- " << myName << ": Starting run" << std::endl; + run->Run(0, nTimeslices); + // ------------------------------------------------------------------------ + + + // ----- Finish ------------------------------------------------------- + timer.Stop(); + FairMonitor::GetMonitor()->Print(); + Double_t rtime = timer.RealTime(); + Double_t ctime = timer.CpuTime(); + std::cout << std::endl << std::endl; + std::cout << "Macro finished successfully." << std::endl; + std::cout << "Output file is " << outFile << std::endl; + std::cout << "Parameter file is " << parFileOut << std::endl; + std::cout << "Real time " << rtime << " s, CPU time " << ctime << " s" << std::endl; + std::cout << std::endl; + // ------------------------------------------------------------------------ + + + // ----- Resource monitoring ------------------------------------------ + // Extract the maximal used memory an add is as Dart measurement + // This line is filtered by CTest and the value send to CDash + FairSystemInfo sysInfo; + Float_t maxMemory = sysInfo.GetMaxMemory(); + std::cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">"; + std::cout << maxMemory; + std::cout << "</DartMeasurement>" << std::endl; + + Float_t cpuUsage = ctime / rtime; + std::cout << "<DartMeasurement name=\"CpuLoad\" type=\"numeric/double\">"; + std::cout << cpuUsage; + std::cout << "</DartMeasurement>" << std::endl; + // ------------------------------------------------------------------------ + + + // ----- Function needed for CTest runtime dependency ----------------- + // RemoveGeoManager(); + // ------------------------------------------------------------------------ + + /// --- Screen output for automatic tests + std::cout << " Test passed" << std::endl; + std::cout << " All ok " << std::endl; + + return kTRUE; +} diff --git a/macro/beamtime/mcbm2021/mcbm_inspect_alignment.C b/macro/beamtime/mcbm2021/mcbm_inspect_alignment.C new file mode 100644 index 0000000000..d05efabe7f --- /dev/null +++ b/macro/beamtime/mcbm2021/mcbm_inspect_alignment.C @@ -0,0 +1,1214 @@ +/* Copyright (C) 2022 UGiessen, Giessen + SPDX-License-Identifier: GPL-3.0-only + Authors: Adrian Weber [committer]*/ + +void initHists(CbmHistManager* fHM, Int_t nofEvents); +void drawHists(CbmHistManager* fHM); +TVector3 extrpolate(CbmTofHit* tofHit, TVector3* vertex, Double_t Z); + +void ProjectXY(std::string name, CbmHistManager* fHM, std::vector<TH1*>* HistoX, std::vector<std::string>* stringX, + std::vector<TH1*>* HistoY, std::vector<std::string>* stringY); + +void ProjectAxis(std::string name, CbmHistManager* fHM, char axis, std::vector<TH1*>* Histo, + std::vector<std::string>* string); + +std::string FitTimeOffset(TH1* hist); + +struct ClosestCbmHit { + Bool_t Existing = false; + Double_t X = 10000.0; + Double_t Y = 10000.0; + Double_t Z = 10000.0; + Double_t Dist = 10000.0; + size_t Indx = -1; + Double_t X_pos = 10000.0; + Double_t Y_pos = 10000.0; +}; + +char outdir[256]; + +void mcbm_inspect_alignment(Int_t runId = 1588, Int_t nofEvents = 200) +{ + + CbmHistManager* fHM = new CbmHistManager(); + + TTree* InputTreeRECO; + TFile* fRECO; + + TVector3 vertexPoint(-0.0, 0.0, 0.0); + Double_t CutCloseDistStsTrack = 60.0; // cm + + char name[256], dir[256]; + + //sprintf(dir, "/data/cbmroot/cbmsource/macro/beamtime/mcbm2021/rec/digi5"); + //sprintf(dir, "/data/cbmroot/cbmsource/macro/beamtime/mcbm2021/rec/aligndigi5"); + //sprintf(dir, "/data/cbmroot/cbmsource/macro/beamtime/mcbm2021/rec/aligndigi5_2HitTrack"); + //sprintf(dir, "/data/cbmroot/cbmsource/macro/beamtime/mcbm2021/rec/aligndigi2_2HitTrack"); + //sprintf(dir, "/data/cbmroot/cbmsource/macro/beamtime/mcbm2021/rec/tofPar0"); + sprintf(dir, "/data/cbmroot/cbmsource/macro/beamtime/mcbm2021/rec/tofPar2_noAlign_L1"); + //sprintf(dir, "/data/cbmroot/cbmsource/macro/beamtime/mcbm2021/rec/tofPar0_noAlign_5hits"); + + sprintf(name, "%s/reco_event_mcbm_%u.root", dir, runId); + + sprintf(outdir, "./results_mTofPar2_AlignmentMacro"); + + std::cout << name << std::endl; + + initHists(fHM, nofEvents); + + auto tofHitYMin = 5000.0; + auto tofHitYMax = -5000.0; + + fRECO = new TFile(name); + if (!fRECO || fRECO->IsZombie() || fRECO->GetNkeys() < 1 || fRECO->TestBit(TFile::kRecovered)) { fRECO->Close(); } + + InputTreeRECO = (TTree*) fRECO->Get("cbmsim"); + if (InputTreeRECO == nullptr) std::cout << "No cbmsim found" << std::endl; + + TClonesArray* fTofHit = nullptr; + TClonesArray* fTofTrack = nullptr; + TClonesArray* fStsHit = nullptr; + TClonesArray* fCbmEvent = nullptr; + InputTreeRECO->SetBranchAddress("TofHit", &fTofHit); + InputTreeRECO->SetBranchAddress("TofTracks", &fTofTrack); + InputTreeRECO->SetBranchAddress("StsHit", &fStsHit); + InputTreeRECO->SetBranchAddress("CbmEvent", &fCbmEvent); + + auto nTS = InputTreeRECO->GetEntries(); + if (nofEvents > 0 && nTS >= nofEvents) { nTS = nofEvents; } + std::cout << "Entries: " << InputTreeRECO->GetEntries() << std::endl; + + TFile* oldFileLin = gFile; + TDirectory* oldirLin = gDirectory; + + std::string s = Form("%s/GraphFitsLinear.root", outdir); + TFile* outFileLin = new TFile(s.c_str(), "RECREATE"); + + + for (int iTS = 0; iTS < nTS; iTS++) { + fHM->H1("fhNofTimeslices")->Fill(1); + InputTreeRECO->GetEntry(iTS); + std::cout << "Timeslice No. " << iTS << std::endl; + Int_t nTParts = fTofHit->GetEntriesFast(); + Int_t nEv = fCbmEvent->GetEntriesFast(); + + std::cout << "Events in TS: " << nEv << std::endl; + fHM->H1("fhEventsPerTS")->Fill(iTS, nEv); + + for (auto iEv = 0; iEv < nEv; iEv++) { + CbmEvent* ev = static_cast<CbmEvent*>(fCbmEvent->At(iEv)); + auto eventStartTime = ev->GetStartTime(); + + // Hit-Multiplicty Cuts: + if (ev->GetNofData(ECbmDataType::kTofHit) < 2) continue; + + // Fill Hit Multiplicity: + fHM->H1("fhMultiplicityStsHits")->Fill(ev->GetNofData(ECbmDataType::kStsHit)); + fHM->H1("fhMultiplicityTofHits")->Fill(ev->GetNofData(ECbmDataType::kTofHit)); + + + //Correct the TofHits + std::vector<size_t> tofIndxStation[2]; + for (int j = 0; j < ev->GetNofData(ECbmDataType::kTofHit); j++) { + auto iTofHit = ev->GetIndex(ECbmDataType::kTofHit, j); + CbmTofHit* tofHit = static_cast<CbmTofHit*>(fTofHit->At(iTofHit)); + auto TofStationNo = (tofHit->GetAddress() >> 4) & 0xf; + + if (TofStationNo == 0) { tofIndxStation[0].push_back(iTofHit); } + else { + tofIndxStation[1].push_back(iTofHit); + } + } // TofHits + + for (int j = 0; j < tofIndxStation[1].size(); j++) { + CbmTofHit* tofHit_stat1 = static_cast<CbmTofHit*>(fTofHit->At(tofIndxStation[1].at(j))); + + ClosestCbmHit closestTofHits; // Station 0 + for (int k = 0; k < tofIndxStation[0].size(); k++) { + CbmTofHit* tofHit_stat0 = static_cast<CbmTofHit*>(fTofHit->At(tofIndxStation[0].at(k))); + TVector3 vExtr = extrpolate(tofHit_stat1, &vertexPoint, tofHit_stat0->GetZ()); + + auto Xextr = vExtr.X(); //tofHit->GetX()* stsHit->GetZ() / tofHit->GetZ(); + auto Yextr = vExtr.Y(); //tofHit->GetY()* stsHit->GetZ() / tofHit->GetZ(); + + auto Xdiff = Xextr - tofHit_stat0->GetX(); + auto Ydiff = Yextr - tofHit_stat0->GetY(); + + Double_t distTof = TMath::Sqrt(Xdiff * Xdiff + Ydiff * Ydiff); + + if (distTof < closestTofHits.Dist && 0.5 > distTof) { + closestTofHits.Existing = true; + closestTofHits.X = Xdiff; + closestTofHits.Y = Ydiff; + closestTofHits.Z = tofHit_stat0->GetZ(); + closestTofHits.Dist = distTof; + closestTofHits.Indx = tofIndxStation[0].at(k); + closestTofHits.X_pos = tofHit_stat0->GetX(); + closestTofHits.Y_pos = tofHit_stat0->GetY(); + } + } // TofHits + + ClosestCbmHit closestStsHitArray[3]; + ClosestCbmHit closestStsHitStations[2]; + + auto nofStsHitsEv = ev->GetNofData(ECbmDataType::kStsHit); + for (int jSts = 0; jSts < nofStsHitsEv; jSts++) { + auto iStsHit = ev->GetIndex(ECbmDataType::kStsHit, jSts); + CbmStsHit* stsHit = static_cast<CbmStsHit*>(fStsHit->At(iStsHit)); + + TVector3 vExtr = extrpolate(tofHit_stat1, &vertexPoint, stsHit->GetZ()); + + auto Xextr = vExtr.X(); //tofHit->GetX()* stsHit->GetZ() / tofHit->GetZ(); + auto Yextr = vExtr.Y(); //tofHit->GetY()* stsHit->GetZ() / tofHit->GetZ(); + + auto stsUnit = 0; + auto stsStation = (stsHit->GetAddress() >> 4) & 0xF; + auto stsUnitAdd = (stsHit->GetAddress() >> 8) & 0x4; + + // if (stsHit->GetZ() < 28.0+8.5){ + if (stsStation == 0 && stsUnitAdd == 0) { stsUnit = 0; } + else if (stsStation == 0 && stsUnitAdd != 0) { + stsUnit = 1; + } + else { + stsStation = 1; + stsUnit = 2; + } + + auto Xdiff = Xextr - stsHit->GetX(); + auto Ydiff = Yextr - stsHit->GetY(); + + Double_t distSts = TMath::Sqrt(Xdiff * Xdiff + Ydiff * Ydiff); + + if (distSts < closestStsHitArray[stsUnit].Dist) { + closestStsHitArray[stsUnit].Existing = true; + closestStsHitArray[stsUnit].X = Xdiff; + closestStsHitArray[stsUnit].Y = Ydiff; + closestStsHitArray[stsUnit].Z = stsHit->GetZ(); + closestStsHitArray[stsUnit].Dist = distSts; + closestStsHitArray[stsUnit].Indx = iStsHit; + closestStsHitArray[stsUnit].X_pos = stsHit->GetX(); + closestStsHitArray[stsUnit].Y_pos = stsHit->GetY(); + } + + if (distSts < closestStsHitStations[stsStation].Dist) { + closestStsHitStations[stsStation].Existing = true; + closestStsHitStations[stsStation].X = Xdiff; + closestStsHitStations[stsStation].Y = Ydiff; + closestStsHitStations[stsStation].Z = stsHit->GetZ(); + closestStsHitStations[stsStation].Dist = distSts; + closestStsHitStations[stsStation].Indx = iStsHit; + closestStsHitStations[stsStation].X_pos = stsHit->GetX(); + closestStsHitStations[stsStation].Y_pos = stsHit->GetY(); + } + } //STS Loop + + std::vector<Double_t> ZArray, XArray, YArray, IndexArray; + ZArray.push_back(tofHit_stat1->GetZ()); + XArray.push_back(tofHit_stat1->GetX()); + YArray.push_back(tofHit_stat1->GetY()); + IndexArray.push_back(tofIndxStation[1].at(j)); + if (closestTofHits.Existing) { + ZArray.push_back(closestTofHits.Z); + XArray.push_back(closestTofHits.X_pos); + YArray.push_back(closestTofHits.Y_pos); + IndexArray.push_back(closestTofHits.Indx); + } + if (closestStsHitStations[0].Existing) { + ZArray.push_back(closestStsHitStations[0].Z); + XArray.push_back(closestStsHitStations[0].X_pos); + YArray.push_back(closestStsHitStations[0].Y_pos); + IndexArray.push_back(closestStsHitStations[0].Indx); + } + if (closestStsHitStations[1].Existing) { + ZArray.push_back(closestStsHitStations[1].Z); + XArray.push_back(closestStsHitStations[1].X_pos); + YArray.push_back(closestStsHitStations[1].Y_pos); + IndexArray.push_back(closestStsHitStations[1].Indx); + } + + if (ZArray.size() > 3) { + //std::cout << "Event # " << iEv << std::endl; + //std::cout << "Xpos: "<< closestTofHits.X_pos<< std::endl; + TGraph* grX = new TGraph(ZArray.size(), &ZArray[0], &XArray[0]); + TF1* linFitX = new TF1("f1", "[0]+[1]*x", 0, 0.1); + grX->Fit(linFitX, "Q"); + + TGraph* grY = new TGraph(ZArray.size(), &ZArray[0], &YArray[0]); + TF1* linFitY = new TF1("f2", "[0]+[1]*x", 0, 0.1); + grY->Fit(linFitY, "Q"); + + fHM->H1("fhLinearFitChi2X")->Fill(linFitX->GetChisquare()); + fHM->H1("fhLinearFitChi2Y")->Fill(linFitY->GetChisquare()); + + if (linFitX->GetChisquare() < 0.5 && linFitY->GetChisquare() < 0.5) { + fHM->H2("fhLinearFitXY")->Fill(linFitX->GetParameter(0), linFitY->GetParameter(0)); + fHM->H1("fhLinearFitZX")->Fill(linFitX->GetParameter(0)); + fHM->H1("fhLinearFitZY")->Fill(linFitY->GetParameter(0)); + + fHM->H2("fhLinearFitXY_.25") + ->Fill(linFitX->GetParameter(0) + (.25) * linFitX->GetParameter(1), + linFitY->GetParameter(0) + (.25) * linFitY->GetParameter(1)); + fHM->H2("fhLinearFitXY_.50") + ->Fill(linFitX->GetParameter(0) + (.50) * linFitX->GetParameter(1), + linFitY->GetParameter(0) + (.50) * linFitY->GetParameter(1)); + fHM->H2("fhLinearFitXY_.75") + ->Fill(linFitX->GetParameter(0) + (.75) * linFitX->GetParameter(1), + linFitY->GetParameter(0) + (.75) * linFitY->GetParameter(1)); + fHM->H2("fhLinearFitXY_1") + ->Fill(linFitX->GetParameter(0) + (1) * linFitX->GetParameter(1), + linFitY->GetParameter(0) + (1) * linFitY->GetParameter(1)); + fHM->H2("fhLinearFitXY_2") + ->Fill(linFitX->GetParameter(0) + (2) * linFitX->GetParameter(1), + linFitY->GetParameter(0) + (2) * linFitY->GetParameter(1)); + fHM->H2("fhLinearFitXY_4") + ->Fill(linFitX->GetParameter(0) + (4) * linFitX->GetParameter(1), + linFitY->GetParameter(0) + (4) * linFitY->GetParameter(1)); + fHM->H2("fhLinearFitXY_6") + ->Fill(linFitX->GetParameter(0) + (6) * linFitX->GetParameter(1), + linFitY->GetParameter(0) + (6) * linFitY->GetParameter(1)); + + fHM->H2("fhLinearFitXY_-.5") + ->Fill(linFitX->GetParameter(0) + (-.5) * linFitX->GetParameter(1), + linFitY->GetParameter(0) + (-.5) * linFitY->GetParameter(1)); + fHM->H2("fhLinearFitXY_-1") + ->Fill(linFitX->GetParameter(0) + (-1) * linFitX->GetParameter(1), + linFitY->GetParameter(0) + (-1) * linFitY->GetParameter(1)); + fHM->H2("fhLinearFitXY_-2") + ->Fill(linFitX->GetParameter(0) + (-2) * linFitX->GetParameter(1), + linFitY->GetParameter(0) + (-2) * linFitY->GetParameter(1)); + fHM->H2("fhLinearFitXY_-4") + ->Fill(linFitX->GetParameter(0) + (-4) * linFitX->GetParameter(1), + linFitY->GetParameter(0) + (-4) * linFitY->GetParameter(1)); + fHM->H2("fhLinearFitXY_-6") + ->Fill(linFitX->GetParameter(0) + (-6) * linFitX->GetParameter(1), + linFitY->GetParameter(0) + (-6) * linFitY->GetParameter(1)); + + // Good Fit!: Extract informations of this kind of tracks + const CbmTofHit* tofHit_sel_0 = static_cast<CbmTofHit*>(fTofHit->At(IndexArray.at(0))); + const CbmTofHit* tofHit_sel_1 = static_cast<CbmTofHit*>(fTofHit->At(IndexArray.at(1))); + + auto selectedTrackTime = tofHit_sel_0->GetTime() - tofHit_sel_1->GetTime(); + auto selectedTrackXdiff = tofHit_sel_0->GetX() - tofHit_sel_1->GetX(); + auto selectedTrackYdiff = tofHit_sel_0->GetY() - tofHit_sel_1->GetY(); + auto selectedTrackZdiff = tofHit_sel_0->GetZ() - tofHit_sel_1->GetZ(); + auto Rdiff = TMath::Sqrt(selectedTrackXdiff * selectedTrackXdiff + selectedTrackYdiff * selectedTrackYdiff + + selectedTrackZdiff * selectedTrackZdiff); + auto selectedTrackBeta = (1e7 / (selectedTrackTime / Rdiff)) / TMath::C(); + + fHM->H1("fhSimpleTrackTofTime")->Fill(selectedTrackTime); + fHM->H1("fhSimpleTrackTofDist")->Fill(Rdiff); + fHM->H1("fhSimpleTrackTofBeta")->Fill(selectedTrackBeta); + } + + //linFitX->Print(); + if (outFileLin->IsOpen()) { + if (iEv < 1000 && linFitX->GetChisquare() < .5) grX->Write(); + } + } + } // TofHits + + + std::vector<size_t> stsIndxStation[2]; + for (int jSts = 0; jSts < ev->GetNofData(ECbmDataType::kStsHit); jSts++) { + + auto iStsHit = ev->GetIndex(ECbmDataType::kStsHit, jSts); + CbmStsHit* stsHit = static_cast<CbmStsHit*>(fStsHit->At(iStsHit)); + auto x = stsHit->GetX(); + auto y = stsHit->GetY(); + auto z = stsHit->GetZ(); + + fHM->H1("fhStsHitsZ")->Fill(z); + + auto stsStation = (stsHit->GetAddress() >> 4) & 0xF; + auto stsUnit = (stsHit->GetAddress() >> 8) & 0x4; + + if (stsStation == 0 && stsUnit == 0) { + fHM->H2("fhStsUnit0Hits")->Fill(stsHit->GetX(), stsHit->GetY()); + fHM->H2("fhStsStation0Hits")->Fill(stsHit->GetX(), stsHit->GetY()); + stsIndxStation[0].push_back(iStsHit); + } + else if (stsStation == 0 && stsUnit != 0) { + fHM->H2("fhStsUnit1Hits")->Fill(stsHit->GetX(), stsHit->GetY()); + fHM->H2("fhStsStation0Hits")->Fill(stsHit->GetX(), stsHit->GetY()); + stsIndxStation[0].push_back(iStsHit); + } + else { + fHM->H2("fhStsUnit2Hits")->Fill(stsHit->GetX(), stsHit->GetY()); + stsIndxStation[1].push_back(iStsHit); + } + } // StsHits + + + auto nofTofHitsEv = ev->GetNofData(ECbmDataType::kTofHit); + for (int j = 0; j < nofTofHitsEv; j++) { + auto iTofHit = ev->GetIndex(ECbmDataType::kTofHit, j); + CbmTofHit* tofHit = static_cast<CbmTofHit*>(fTofHit->At(iTofHit)); + + fHM->H1("fhTofHitsTime")->Fill(tofHit->GetTime() - eventStartTime); + + auto TofStationNo = (tofHit->GetAddress() >> 4) & 0xf; + auto modPos = (tofHit->GetAddress() >> 15) & 0x1; // 0 is closer to vertex + auto modPosY = (tofHit->GetAddress() >> 16) & 0xf; // ModPos 0: 0,1,2 ModPos 1: 0,1 + + fHM->H1("fhTofHitsZ")->Fill(tofHit->GetZ()); + fHM->H2("fhTofHitsXY")->Fill(tofHit->GetX(), tofHit->GetY()); + + + if (TofStationNo == 0 && modPos == 0 && modPosY == 1) { + fHM->H2("fhTofHitsXY_001")->Fill(tofHit->GetX(), tofHit->GetY()); + fHM->H1("fhTofHitsTime_001")->Fill(tofHit->GetTime() - eventStartTime); + if (tofHitYMin > tofHit->GetY()) tofHitYMin = tofHit->GetY(); + if (tofHitYMax < tofHit->GetY()) tofHitYMax = tofHit->GetY(); + } + + if (TofStationNo == 0) { fHM->H1("fhTofHitsTimeLayer0")->Fill(tofHit->GetTime() - eventStartTime); } + + if (TofStationNo == 1) { fHM->H1("fhTofHitsTimeLayer1")->Fill(tofHit->GetTime() - eventStartTime); } + + ClosestCbmHit closestStsHitArray[3]; + ClosestCbmHit closestStsHitStations[2]; + + auto nofStsHitsEv = ev->GetNofData(ECbmDataType::kStsHit); + for (int jSts = 0; jSts < nofStsHitsEv; jSts++) { + auto iStsHit = ev->GetIndex(ECbmDataType::kStsHit, jSts); + CbmStsHit* stsHit = static_cast<CbmStsHit*>(fStsHit->At(iStsHit)); + + TVector3 vExtr = extrpolate(tofHit, &vertexPoint, stsHit->GetZ()); + + auto Xextr = vExtr.X(); //tofHit->GetX()* stsHit->GetZ() / tofHit->GetZ(); + auto Yextr = vExtr.Y(); //tofHit->GetY()* stsHit->GetZ() / tofHit->GetZ(); + + auto stsUnit = 0; + + auto stsStation = (stsHit->GetAddress() >> 4) & 0xF; + auto stsUnitAdd = (stsHit->GetAddress() >> 8) & 0x4; + + if (stsStation == 0 && stsUnitAdd == 0) { stsUnit = 0; } + else if (stsStation == 0 && stsUnitAdd != 0) { + stsUnit = 1; + } + else { + stsStation = 1; + stsUnit = 2; + } + + auto Xdiff = Xextr - stsHit->GetX(); + auto Ydiff = Yextr - stsHit->GetY(); + + Double_t distSts = TMath::Sqrt(Xdiff * Xdiff + Ydiff * Ydiff); + + if (distSts < closestStsHitArray[stsUnit].Dist) { + closestStsHitArray[stsUnit].Existing = true; + closestStsHitArray[stsUnit].X = Xdiff; + closestStsHitArray[stsUnit].Y = Ydiff; + closestStsHitArray[stsUnit].Z = stsHit->GetZ(); + closestStsHitArray[stsUnit].Dist = distSts; + closestStsHitArray[stsUnit].Indx = iStsHit; + closestStsHitArray[stsUnit].X_pos = stsHit->GetX(); + closestStsHitArray[stsUnit].Y_pos = stsHit->GetY(); + } + + if (distSts < closestStsHitStations[stsStation].Dist) { + closestStsHitStations[stsStation].Existing = true; + closestStsHitStations[stsStation].X = Xdiff; + closestStsHitStations[stsStation].Y = Ydiff; + closestStsHitStations[stsStation].Z = stsHit->GetZ(); + closestStsHitStations[stsStation].Dist = distSts; + closestStsHitStations[stsStation].Indx = iStsHit; + closestStsHitStations[stsStation].X_pos = stsHit->GetX(); + closestStsHitStations[stsStation].Y_pos = stsHit->GetY(); + } + + + fHM->H2(Form("fhTofSts%uXYdiff", stsUnit))->Fill(Xdiff, Ydiff); + + if (TMath::Abs(Xdiff) < 0.2 && TMath::Abs(Ydiff) < 0.2) { + vExtr = extrpolate(tofHit, &vertexPoint, 8.5); + fHM->H2(Form("fhTofSts%uXY_8.5cm", stsUnit))->Fill(vExtr.X(), vExtr.Y()); + } + } //STS Loop + + for (auto o = 0; o < 3; ++o) { + if (closestStsHitArray[o].Existing == true && (closestStsHitStations[0].Existing == true) + && (closestStsHitStations[1].Existing == true)) { + TVector3 vExtr_tof = extrpolate(tofHit, &vertexPoint, closestStsHitArray[o].Z); + fHM->H2(Form("fhTof%u%u%uSts%uextr", TofStationNo, modPos, modPosY, o))->Fill(vExtr_tof.X(), vExtr_tof.Y()); + fHM->H2(Form("fhTof%u%u%uSts%uXYdiff", TofStationNo, modPos, modPosY, o)) + ->Fill(closestStsHitArray[o].X, closestStsHitArray[o].Y); + if (!(modPos == 0 && modPosY == 0)) + fHM->H2(Form("fhTofSts%uXYdiff_close", o))->Fill(closestStsHitArray[o].X, closestStsHitArray[o].Y); + } + } + + if ((closestStsHitStations[0].Existing == true) && (closestStsHitStations[1].Existing == true)) { + fHM->H2(Form("fhTof%u%u%uDiffStation01", TofStationNo, modPos, modPosY)) + ->Fill(closestStsHitStations[0].Dist, closestStsHitStations[1].Dist); + fHM->H2(Form("fhTof%u%u%uXDiffStation01", TofStationNo, modPos, modPosY)) + ->Fill(closestStsHitStations[0].X, closestStsHitStations[1].X); + fHM->H2(Form("fhTof%u%u%uYDiffStation01", TofStationNo, modPos, modPosY)) + ->Fill(closestStsHitStations[0].Y, closestStsHitStations[1].Y); + + if (TofStationNo == 0 && modPos == 1 && modPosY == 0) { + Double_t Y_new = closestStsHitStations[1].Y - closestStsHitStations[0].Y; + fHM->H2("fhTof010YDiffStation01_pro")->Fill(closestStsHitStations[0].Y, Y_new); + Double_t Y_ratio = closestStsHitStations[1].Y / closestStsHitStations[0].Y; + fHM->H2("fhTof010YDiffStation01_ratio")->Fill(closestStsHitStations[0].Y, Y_ratio); + } + } + + } // TofHit Loop + + + // Tof Tracks + ClosestCbmHit closestTrackStsHitStations[2]; + + auto nofTofTracksEv = ev->GetNofData(ECbmDataType::kTofTrack); + fHM->H1("fhTofTrackMulti")->Fill(nofTofTracksEv); + + Int_t Multipl_2hit_Tracks = 0; + + for (int j = 0; j < nofTofTracksEv; j++) { + auto iTofTrack = ev->GetIndex(ECbmDataType::kTofTrack, j); + CbmTofTracklet* tofTrack = static_cast<CbmTofTracklet*>(fTofTrack->At(iTofTrack)); + + if (tofTrack->GetNofHits() == 2) Multipl_2hit_Tracks++; + + //Sts Loop + auto nofStsHitsEv = ev->GetNofData(ECbmDataType::kStsHit); + for (int jSts = 0; jSts < nofStsHitsEv; jSts++) { + auto iStsHit = ev->GetIndex(ECbmDataType::kStsHit, jSts); + CbmStsHit* stsHit = static_cast<CbmStsHit*>(fStsHit->At(iStsHit)); + + auto stsUnit = 0; + auto stsStation = (stsHit->GetAddress() >> 4) & 0xF; + auto stsUnitAdd = (stsHit->GetAddress() >> 8) & 0x4; + if (stsStation == 0 && stsUnitAdd == 0) { stsUnit = 0; } + else if (stsStation == 0 && stsUnitAdd != 0) { + stsUnit = 1; + } + else { + stsStation = 1; + stsUnit = 2; + } + + auto Xdiff = tofTrack->GetFitX(stsHit->GetZ()) - stsHit->GetX(); + auto Ydiff = tofTrack->GetFitY(stsHit->GetZ()) - stsHit->GetY(); + Double_t distSts = TMath::Sqrt(Xdiff * Xdiff + Ydiff * Ydiff); + + if (distSts < closestTrackStsHitStations[stsStation].Dist) { + closestTrackStsHitStations[stsStation].Existing = true; + closestTrackStsHitStations[stsStation].X = Xdiff; + closestTrackStsHitStations[stsStation].Y = Ydiff; + closestTrackStsHitStations[stsStation].Z = stsHit->GetZ(); + closestTrackStsHitStations[stsStation].Dist = distSts; + closestTrackStsHitStations[stsStation].Indx = iStsHit; + closestTrackStsHitStations[stsStation].X_pos = stsHit->GetX(); + closestTrackStsHitStations[stsStation].Y_pos = stsHit->GetY(); + } + } // End Sts Loop + + if ((closestTrackStsHitStations[0].Existing == true) && (closestTrackStsHitStations[1].Existing == true) + && tofTrack->GetNofHits() == 2) { + //std::cout<<"Station0: " << closestStsHitStations[0].Dist << " Station1: "<< closestStsHitStations[1].Dist << std::endl; + fHM->H2("fhTofTrackDiffStation01") + ->Fill(closestTrackStsHitStations[0].Dist, closestTrackStsHitStations[1].Dist); + fHM->H2("fhTofTrackXDiffStation01")->Fill(closestTrackStsHitStations[0].X, closestTrackStsHitStations[1].X); + fHM->H2("fhTofTrackYDiffStation01")->Fill(closestTrackStsHitStations[0].Y, closestTrackStsHitStations[1].Y); + + fHM->H2("fhTofTrackXYDiffStation0")->Fill(closestTrackStsHitStations[0].X, closestTrackStsHitStations[0].Y); + fHM->H2("fhTofTrackXYDiffStation1")->Fill(closestTrackStsHitStations[1].X, closestTrackStsHitStations[1].Y); + + + fHM->H2("fhTofTrackXY520cm_2Hits")->Fill(tofTrack->GetFitX(520.0), tofTrack->GetFitY(520.0)); + fHM->H2("fhTofTrackXYVertex_2Hits")->Fill(tofTrack->GetFitX(0.0), tofTrack->GetFitY(0.0)); + + // Time Offset Calculation + for (auto cntStation = 0; cntStation < 2; ++cntStation) { + for (auto kTrackHits = 0; kTrackHits < tofTrack->GetNofHits(); ++kTrackHits) { + auto trackHitInd = tofTrack->GetHitIndex(kTrackHits); + CbmTofHit* tofHit = static_cast<CbmTofHit*>(fTofHit->At(trackHitInd)); + + if (tofHit == nullptr) continue; + + auto diffX = tofHit->GetX() - closestTrackStsHitStations[cntStation].X_pos; + auto diffY = tofHit->GetY() - closestTrackStsHitStations[cntStation].Y_pos; + auto diffZ = tofHit->GetZ() - closestTrackStsHitStations[cntStation].Z; + + auto distance = TMath::Sqrt(diffX * diffX + diffY * diffY + diffZ * diffZ); + Double_t TimeOfFlight = distance * tofTrack->GetTt(); // ns + if (tofTrack->GetTt() < 0) continue; + fHM->H1("fhTimeOfFlight")->Fill(TimeOfFlight); + + auto TofStationNo = (tofHit->GetAddress() >> 4) & 0xf; + fHM->H1(Form("fhTimeOfFlight_%u", TofStationNo))->Fill(TimeOfFlight); + + fHM->H1(Form("fhTimeOfFlight_%u_%u", TofStationNo, cntStation))->Fill(TimeOfFlight); + + fHM->H2(Form("fhTimeOfFlight_%u_diffZ", TofStationNo))->Fill(diffZ, TimeOfFlight); + + // tof hit - TimeOfFlight - stshittime + CbmStsHit* stsHit = static_cast<CbmStsHit*>(fStsHit->At(closestTrackStsHitStations[cntStation].Indx)); + if (nullptr == stsHit) continue; + + auto timeoffset = tofHit->GetTime() - TimeOfFlight - stsHit->GetTime(); + fHM->H1(Form("fhTimeOffset"))->Fill(timeoffset); + } + } + } + + fHM->H1("fhTofHitsPerTrack")->Fill(tofTrack->GetNofHits()); + //std::cout<< tofTrack->GetT0() << " " << tofTrack->GetTt() << " " << tofTrack->GetT0()-tofTrack->GetTt() <<std::endl; + fHM->H1("fhTofTracksT0")->Fill(tofTrack->GetT0() - eventStartTime); + fHM->H1("fhTofTracksTt")->Fill(tofTrack->GetTt()); // invers velocity + fHM->H1("fhTofTracksVelocity")->Fill(1. / tofTrack->GetTt()); // invers velocity + fHM->H1("fhTofTracksTdiff")->Fill(tofTrack->GetTime() - eventStartTime); + fHM->H1("fhTofTracksTdiff2")->Fill(tofTrack->GetTime() - tofTrack->GetT0()); + fHM->H1("fhTofTracksTime")->Fill(tofTrack->GetTime()); + fHM->H1("fhTofTracksDistance")->Fill(tofTrack->GetDistance()); + fHM->H2("fhTofTrackXY_basic")->Fill(tofTrack->GetTrackX(), tofTrack->GetTrackY()); + Double_t inVel = 1e7 / (tofTrack->GetTt()); // in m/s + auto beta = inVel / TMath::C(); + fHM->H1("fhTofBeta")->Fill(beta); + + fHM->H2("fhTofTrackXYVertex")->Fill(tofTrack->GetFitX(0.0), tofTrack->GetFitY(0.0)); + fHM->H2("fhTofTrackXY520cm")->Fill(tofTrack->GetFitX(520.0), tofTrack->GetFitY(520.0)); + fHM->H2("fhTofTrackXY")->Fill(tofTrack->GetFitX(260.), tofTrack->GetFitY(260.)); + + auto nofTrackHits = tofTrack->GetNofHits(); + for (auto kTrackHits = 0; kTrackHits < nofTrackHits; ++kTrackHits) { + auto trackHitInd = tofTrack->GetHitIndex(kTrackHits); + CbmTofHit* tofHit = static_cast<CbmTofHit*>(fTofHit->At(trackHitInd)); + + fHM->H1("fhTofTrackHitsTimeDiff")->Fill(tofHit->GetTime() - tofTrack->GetT0()); + fHM->H1("fhTofTrackHitsTime")->Fill(tofHit->GetTime() - eventStartTime); + } + + Double_t closestStsR = 100000.0; + Int_t closestStsIndx = -1; + + for (int jSts = 0; jSts < nofStsHitsEv; jSts++) { + auto iStsHit = ev->GetIndex(ECbmDataType::kStsHit, jSts); + CbmStsHit* stsHit = static_cast<CbmStsHit*>(fStsHit->At(iStsHit)); + + auto Xdiff = tofTrack->GetFitX(stsHit->GetZ()) - stsHit->GetX(); + auto Ydiff = tofTrack->GetFitY(stsHit->GetZ()) - stsHit->GetY(); + + fHM->H2("fhTofTrackStsXYdiff")->Fill(Xdiff, Ydiff); + + auto rStsTofTrack = TMath::Sqrt(Xdiff * Xdiff + Ydiff * Ydiff); + if (rStsTofTrack < closestStsR) { + closestStsR = rStsTofTrack; + closestStsIndx = iStsHit; + } + } // Sts Hit Loop + + if (closestStsIndx > -1 && closestStsR < CutCloseDistStsTrack) { + CbmStsHit* closeStsHit = static_cast<CbmStsHit*>(fStsHit->At(closestStsIndx)); + fHM->H1("fhTofTrackStsR")->Fill(closestStsR); + + // 1.) calculate length from T0 to Sts Hit + auto stsT0Length = std::sqrt(std::pow((closeStsHit->GetX() - tofTrack->GetTrackX()), 2) + + std::pow((closeStsHit->GetY() - tofTrack->GetTrackY()), 2) + + std::pow((closeStsHit->GetZ() - 0.0), 2)); + fHM->H1("fhTofTracksLength")->Fill(stsT0Length); + + // 2.) calculate time in Tof system with length and velocity + auto stsTrackTime = stsT0Length * tofTrack->GetTt(); // time (of flight) in ns + fHM->H1("fhStsTrackTime")->Fill(stsTrackTime); + + // 3.) compare to Sts hit Time + auto diffStsTimes = (tofTrack->GetT0() + stsTrackTime) - closeStsHit->GetTime(); + fHM->H1("fhStsHitStsTrackTimeDiff")->Fill(diffStsTimes); + } + } // Track Loop + + fHM->H1("fhMultiplicityTof2HitsTracks")->Fill(Multipl_2hit_Tracks); + } // Event Loop + } // TS loop + + outFileLin->Close(); + /// Restore old global file and folder pointer to avoid messing with FairRoot + gFile = oldFileLin; + gDirectory->cd(oldirLin->GetPath()); + + fRECO->Close(); + + std::cout << "tofHitYMin: " << tofHitYMin << " tofHitYMax: " << tofHitYMax << std::endl; + + { + ofstream XY_differences; + XY_differences.open(Form("%s/XY_differences.dat", outdir)); + // Alignments: + for (auto l = 0; l < 3; ++l) { + for (auto i = 0; i < 2; ++i) { + for (auto m = 0; m < 5; ++m) { + auto j = 0; + auto k = 0; + + if (m == 0) { + j = 0; + k = 0; + } + if (m == 1) { + j = 1; + k = 0; + } + if (m == 2) { + j = 0; + k = 1; + } + if (m == 3) { + j = 1; + k = 1; + } + if (m == 4) { + j = 0; + k = 2; + } + + auto x = fHM->H2(Form("fhTof%u%u%uSts%uXYdiff", i, j, k, l))->GetMean(1); + auto y = fHM->H2(Form("fhTof%u%u%uSts%uXYdiff", i, j, k, l))->GetMean(2); + std::cout << " Tof:" << i << j << k << " StS:" << l << " X:" << x << " Y:" << y << std::endl; + XY_differences << " Tof:" << i << j << k << " StS:" << l << " X:" << x << " Y:" << y << std::endl; + } + } + std::cout << std::endl; + XY_differences << std::endl; + } + XY_differences.close(); + } + + + std::vector<TH1*> fitHistsX, fitHistsY; + std::vector<std::string> XFitstring, YFitstring; + + for (auto p = 0; p < 3; ++p) { + ProjectXY(Form("fhTofSts%uXYdiff_close", p), fHM, &fitHistsX, &XFitstring, &fitHistsY, &YFitstring); + } + + { + std::vector<std::string> strTofStsHistX, strTofStsHistY; + ProjectXY("fhTof010Sts0XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + ProjectXY("fhTof001Sts0XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + ProjectXY("fhTof011Sts0XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + ProjectXY("fhTof002Sts0XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + + ProjectXY("fhTof110Sts0XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + ProjectXY("fhTof101Sts0XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + ProjectXY("fhTof111Sts0XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + ProjectXY("fhTof102Sts0XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + + + ProjectXY("fhTof010Sts1XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + ProjectXY("fhTof001Sts1XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + ProjectXY("fhTof011Sts1XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + ProjectXY("fhTof002Sts1XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + + ProjectXY("fhTof110Sts1XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + ProjectXY("fhTof101Sts1XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + ProjectXY("fhTof111Sts1XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + ProjectXY("fhTof102Sts1XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + + + ProjectXY("fhTof010Sts2XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + ProjectXY("fhTof001Sts2XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + ProjectXY("fhTof011Sts2XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + ProjectXY("fhTof002Sts2XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + + ProjectXY("fhTof110Sts2XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + ProjectXY("fhTof101Sts2XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + ProjectXY("fhTof111Sts2XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + ProjectXY("fhTof102Sts2XYdiff", fHM, &fitHistsX, &strTofStsHistX, &fitHistsY, &strTofStsHistY); + + std::cout << "--------------------------------------------------------------------" << std::endl; + std::cout << "fhTof*10Sts0XYdiff : " << strTofStsHistX.at(0) << " | " << strTofStsHistY.at(0) << " || " + << strTofStsHistX.at(4) << " | " << strTofStsHistY.at(4) << std::endl; + std::cout << "fhTof*01Sts0XYdiff : " << strTofStsHistX.at(1) << " | " << strTofStsHistY.at(1) << " || " + << strTofStsHistX.at(5) << " | " << strTofStsHistY.at(5) << std::endl; + std::cout << "fhTof*11Sts0XYdiff : " << strTofStsHistX.at(2) << " | " << strTofStsHistY.at(2) << " || " + << strTofStsHistX.at(6) << " | " << strTofStsHistY.at(6) << std::endl; + std::cout << "fhTof*02Sts0XYdiff : " << strTofStsHistX.at(3) << " | " << strTofStsHistY.at(3) << " || " + << strTofStsHistX.at(7) << " | " << strTofStsHistY.at(7) << std::endl; + std::cout << "--------------------------------------------------------------------" << std::endl; + + std::cout << "--------------------------------------------------------------------" << std::endl; + std::cout << "fhTof*10Sts1XYdiff : " << strTofStsHistX.at(8) << " | " << strTofStsHistY.at(8) << " || " + << strTofStsHistX.at(12) << " | " << strTofStsHistY.at(12) << std::endl; + std::cout << "fhTof*01Sts1XYdiff : " << strTofStsHistX.at(9) << " | " << strTofStsHistY.at(9) << " || " + << strTofStsHistX.at(13) << " | " << strTofStsHistY.at(13) << std::endl; + std::cout << "fhTof*11Sts1XYdiff : " << strTofStsHistX.at(10) << " | " << strTofStsHistY.at(10) << " || " + << strTofStsHistX.at(14) << " | " << strTofStsHistY.at(14) << std::endl; + std::cout << "fhTof*02Sts1XYdiff : " << strTofStsHistX.at(11) << " | " << strTofStsHistY.at(11) << " || " + << strTofStsHistX.at(15) << " | " << strTofStsHistY.at(15) << std::endl; + std::cout << "--------------------------------------------------------------------" << std::endl; + + std::cout << "--------------------------------------------------------------------" << std::endl; + std::cout << "fhTof*10Sts2XYdiff : " << strTofStsHistX.at(16) << " | " << strTofStsHistY.at(16) << " || " + << strTofStsHistX.at(20) << " | " << strTofStsHistY.at(20) << std::endl; + std::cout << "fhTof*01Sts2XYdiff : " << strTofStsHistX.at(17) << " | " << strTofStsHistY.at(17) << " || " + << strTofStsHistX.at(21) << " | " << strTofStsHistY.at(21) << std::endl; + std::cout << "fhTof*11Sts2XYdiff : " << strTofStsHistX.at(18) << " | " << strTofStsHistY.at(18) << " || " + << strTofStsHistX.at(22) << " | " << strTofStsHistY.at(22) << std::endl; + std::cout << "fhTof*02Sts2XYdiff : " << strTofStsHistX.at(19) << " | " << strTofStsHistY.at(19) << " || " + << strTofStsHistX.at(23) << " | " << strTofStsHistY.at(23) << std::endl; + std::cout << "--------------------------------------------------------------------" << std::endl; + } + drawHists(fHM); + + std::cout << "TimeOffset Fit: " << FitTimeOffset(fHM->H1("fhTimeOffset")) << std::endl; + + if (true) { + /// Save old global file and folder pointer to avoid messing with FairRoot + TFile* oldFile = gFile; + TDirectory* oldir = gDirectory; + + std::string s = Form("%s/RecoInspectAlignHists.root", outdir); + TFile* outFile = new TFile(s.c_str(), "RECREATE"); + if (outFile->IsOpen()) { + fHM->WriteToFile(); + for (auto xhists = 0; xhists < fitHistsX.size(); xhists++) + fitHistsX.at(xhists)->Write(); + for (auto yhists = 0; yhists < fitHistsY.size(); yhists++) + fitHistsY.at(yhists)->Write(); + std::cout << "Written to Root-file \"" << s << "\" ..."; + outFile->Close(); + std::cout << "Done!" << std::endl; + } + /// Restore old global file and folder pointer to avoid messing with FairRoot + gFile = oldFile; + gDirectory->cd(oldir->GetPath()); + } + + std::cout << " --------------------------------------------" << std::endl; + std::cout << "0 | " << XFitstring.at(0) << " | " << YFitstring.at(0) << std::endl; + std::cout << "1 | " << XFitstring.at(1) << " | " << YFitstring.at(1) << std::endl; + std::cout << "2 | " << XFitstring.at(2) << " | " << YFitstring.at(2) << std::endl; +} + + +void initHists(CbmHistManager* fHM, Int_t nofEvents) +{ + fHM->Create1<TH1D>("fhNofTimeslices", "fhNofTimeslices;Entries", 1, 0.5, 1.5); + + fHM->Create2<TH2D>("fhTofHitsXY", "fhTofHitsXY;X [cm];Y [cm];Entries", 200, -100., 100., 200, -100., 100.); + fHM->Create1<TH1D>("fhTofTrackMulti", "fhTofTrackMulti;Tracks/Event;Entries", 20, -0.5, 19.5); + fHM->Create1<TH1D>("fhTofHitsZ", "fhTofHitsZ;Z[cm];Entries", 100, 250, 300); + fHM->Create1<TH1D>("fhTofHitsPerTrack", "fhTofHitsPerTrack;Hits/Track;Entries", 11, -0.5, 10.5); + fHM->Create1<TH1D>("fhTofTracksT0", "fhTofTracksT0;T0 time [ns];Entries", 100, -50, 50); + fHM->Create1<TH1D>("fhTofTracksTime", "fhTofTracksTime;Track time [ns];Entries", 30000, -50, 3.0e8); + fHM->Create1<TH1D>("fhTofTracksTt", "fhTofTracksTt;inv. velocity [ns/cm];Entries", 100, -50, 50); + fHM->Create1<TH1D>("fhTofTracksVelocity", "fhTofTracksVelocity;velocity [cm/ns];Entries", 100, -50, 50); + fHM->Create1<TH1D>("fhTofTracksTdiff", "fhTofTracksTdiff;Time [ns];Entries", 100, -50, 50); + fHM->Create1<TH1D>("fhTofTracksTdiff2", "fhTofTracksTdiff2;Time [ns];Entries", 100, -50, 50); + fHM->Create1<TH1D>("fhTofTracksLength", "fhTofTracksLength;length [cm];Entries", 400, -50, 350); + + fHM->Create1<TH1D>("fhTofTrackHitsTimeDiff", "fhTofTrackHitsTimeDiff;time [ns];Entries", 100, -50.0, 50.0); + fHM->Create1<TH1D>("fhTofHitsTime", "fhTofHitsTime;time [ns];Entries", 100, -50.0, 50.0); + fHM->Create1<TH1D>("fhTofHitsTimeLayer0", "fhTofHitsTimeLayer0;time [ns];Entries", 100, -50.0, 50.0); + fHM->Create1<TH1D>("fhTofHitsTimeLayer1", "fhTofHitsTimeLayer1;time [ns];Entries", 100, -50.0, 50.0); + fHM->Create1<TH1D>("fhTofHitsTime_001", "fhTofHitsTime_001;time [ns];Entries", 100, -50.0, 50.0); + + fHM->Create1<TH1D>("fhTofTrackHitsTime", "fhTofTrackHitsTime;time [ns];Entries", 100, -50.0, 50.0); + + fHM->Create1<TH1D>("fhTofBeta", "fhTofBeta;#beta;Entries", 2200, -1.1, 1.1); + fHM->Create1<TH1D>("fhTofTracksDistance", "fhTofTracksDistance;distance [cm];Entries", 100, -5, 5); + + fHM->Create2<TH2D>("fhTofTrackXYVertex", "fhTofTrackXYVertex;X [cm];Y [cm];Entries", 200, -100, 100, 200, -100, 100); + fHM->Create2<TH2D>("fhTofTrackXYVertex_2Hits", "fhTofTrackXYVertex_2Hits;X [cm];Y [cm];Entries", 200, -100, 100, 200, + -100, 100); + fHM->Create2<TH2D>("fhTofTrackXY520cm", "fhTofTrackXY520cm;X [cm];Y [cm];Entries", 200, -100, 100, 200, -100, 100); + fHM->Create2<TH2D>("fhTofTrackXY520cm_2Hits", "fhTofTrackXY520cm_2Hits;X [cm];Y [cm];Entries", 200, -100, 100, 200, + -100, 100); + fHM->Create2<TH2D>("fhTofTrackXY", "fhTofTrackXY;X [cm];Y [cm];Entries", 200, -100, 100, 200, -100, 100); + fHM->Create2<TH2D>("fhTofTrackXY_basic", "fhTofTrackXY_basic;X [cm];Y [cm];Entries", 200, -100, 100, 200, -100, 100); + + + fHM->Create1<TH1D>("fhTofTrackStsR", "fhTofTrackStsR;distance [cm];Entries", 600, 0.0, 60.0); + fHM->Create1<TH1D>("fhStsHitStsTrackTimeDiff", "fhStsHitStsTrackTimeDiff;time diff [ns];Entries", 1200, -60.0, 60.0); + fHM->Create1<TH1D>("fhStsTrackTime", "fhStsTrackTime;time from track [ns];Entries", 1200, -60.0, 60.0); + fHM->Create1<TH1D>("fhStsHitsZ", "fhStsHitsZ; Z [cm];Entries", 400, 20.0, 60.0); + + fHM->Create2<TH2D>("fhTofTrackStsXYdiff", "fhTofTrackStsXYdiff;X_tof-X_Sts [cm];Y_tof-Y_Sts [cm];Entries", 600, -2.95, + 2.95, 600, -2.95, 2.95); + + for (auto i = 0; i < 2; ++i) { + for (auto j = 0; j < 2; ++j) { + for (auto k = 0; k < 3; ++k) { + if (k == 2 && j == 1) continue; + fHM->Create2<TH2D>(Form("fhTof%u%u%uDiffStation01", i, j, k), + Form("fhTof%u%u%uDiffStation01;Station 0 [cm];Station1 [cm];Entries", i, j, k), 200, -0.5, + 19.5, 200, -0.5, 19.5); + fHM->Create2<TH2D>(Form("fhTof%u%u%uXDiffStation01", i, j, k), + Form("fhTof%u%u%uXDiffStation01;Station 0 [cm];Station1 [cm];Entries", i, j, k), 110, -5.5, + 5.5, 110, -5.5, 5.5); + fHM->Create2<TH2D>(Form("fhTof%u%u%uYDiffStation01", i, j, k), + Form("fhTof%u%u%uYDiffStation01;Station 0 [cm];Station1 [cm];Entries", i, j, k), 110, -5.5, + 5.5, 110, -5.5, 5.5); + for (auto l = 0; l < 3; ++l) { + fHM->Create2<TH2D>(Form("fhTof%u%u%uSts%uXYdiff", i, j, k, l), + Form("fhTof%u%u%uSts%uXYdiff;X_tof-X_Sts [cm];Y_tof-Y_Sts [cm];Entries", i, j, k, l), 300, + -2.95, 2.95, 300, -2.95, 2.95); + fHM->Create2<TH2D>(Form("fhTof%u%u%uSts%uextr", i, j, k, l), + Form("fhTof%u%u%uSts%uextr;X_tof [cm];Y_tof [cm];Entries", i, j, k, l), 600, -29.5, 29.5, + 600, -29.5, 29.5); + } + } + } + } + + + fHM->Create2<TH2D>("fhTof010YDiffStation01_pro", "fhTof010YDiffStation01_pro;Station 0 [cm];Station1 [cm];Entries", + 110, -5.5, 5.5, 110, -5.5, 5.5); + fHM->Create2<TH2D>("fhTof010YDiffStation01_ratio", + "fhTof010YDiffStation01_ratio;Station 0 [cm];Station1 [cm];Entries", 110, -5.5, 5.5, 110, -5.5, + 5.5); + + fHM->Create2<TH2D>("fhTofTrackDiffStation01", "fhTofTrackDiffStation01;Station 0 [cm];Station1 [cm];Entries", 400, + -0.5, 39.5, 400, -0.5, 39.5); + fHM->Create2<TH2D>("fhTofTrackXDiffStation01", "fhTofTrackXDiffStation01;Station 0 [cm];Station1 [cm];Entries", 790, + -39.5, 39.5, 790, -39.5, 39.5); + fHM->Create2<TH2D>("fhTofTrackYDiffStation01", "fhTofTrackYDiffStation01;Station 0 [cm];Station1 [cm];Entries", 790, + -39.5, 39.5, 790, -39.5, 39.5); + fHM->Create2<TH2D>("fhTofTrackXYDiffStation0", "fhTofTrackXYDiffStation0;Xdiff [cm];Ydiff [cm];Entries", 790, -79.5, + 79.5, 790, -79.5, 79.5); + fHM->Create2<TH2D>("fhTofTrackXYDiffStation1", "fhTofTrackXYDiffStation1;Xdiff [cm];Ydiff [cm];Entries", 790, -79.5, + 79.5, 790, -79.5, 79.5); + + + fHM->Create2<TH2D>("fhTofSts0XYdiff", "fhTofSts0XYdiff;X_tof-X_Sts [cm];Y_tof-Y_Sts [cm];Entries", 600, -2.95, 2.95, + 600, -2.95, 2.95); + fHM->Create2<TH2D>("fhTofSts1XYdiff", "fhTofSts1XYdiff;X_tof-X_Sts [cm];Y_tof-Y_Sts [cm];Entries", 600, -2.95, 2.95, + 600, -2.95, 2.95); + fHM->Create2<TH2D>("fhTofSts2XYdiff", "fhTofSts2XYdiff;X_tof-X_Sts [cm];Y_tof-Y_Sts [cm];Entries", 600, -2.95, 2.95, + 600, -2.95, 2.95); + + fHM->Create2<TH2D>("fhTofSts0XYdiff_close", "fhTofSts0XYdiff_close;X_tof-X_Sts [cm];Y_tof-Y_Sts [cm];Entries", 600, + -2.95, 2.95, 600, -2.95, 2.95); + fHM->Create2<TH2D>("fhTofSts1XYdiff_close", "fhTofSts1XYdiff_close;X_tof-X_Sts [cm];Y_tof-Y_Sts [cm];Entries", 600, + -2.95, 2.95, 600, -2.95, 2.95); + fHM->Create2<TH2D>("fhTofSts2XYdiff_close", "fhTofSts2XYdiff_close;X_tof-X_Sts [cm];Y_tof-Y_Sts [cm];Entries", 600, + -2.95, 2.95, 600, -2.95, 2.95); + + fHM->Create2<TH2D>("fhTofSts0XY_8.5cm", "fhTofSts0XY_8.5cm;X [cm];Y [cm];Entries", 100, -1.0, 1.0, 100, -2.5, 2.5); + fHM->Create2<TH2D>("fhTofSts1XY_8.5cm", "fhTofSts1XY_8.5cm;X [cm];Y [cm];Entries", 100, -1.0, 1.0, 100, -2.5, 2.5); + fHM->Create2<TH2D>("fhTofSts2XY_8.5cm", "fhTofSts2XY_8.5cm;X [cm];Y [cm];Entries", 100, -1.0, 1.0, 100, -2.5, 2.5); + + + fHM->Create2<TH2D>("fhStsUnit0Hits", "fhStsUnit0Hits;X_Sts [cm];Y_Sts [cm];Entries", 600, -30, 30, 600, -30, 30); + fHM->Create2<TH2D>("fhStsUnit1Hits", "fhStsUnit1Hits;X_Sts [cm];Y_Sts [cm];Entries", 600, -30, 30, 600, -30, 30); + fHM->Create2<TH2D>("fhStsUnit2Hits", "fhStsUnit2Hits;X_Sts [cm];Y_Sts [cm];Entries", 600, -30, 30, 600, -30, 30); + + fHM->Create2<TH2D>("fhStsStation0Hits", "fhStsStation0Hits;X_Sts [cm];Y_Sts [cm];Entries", 600, -30, 30, 600, -30, + 30); + + fHM->Create2<TH2D>("fhTofHitsXY_001", "fhTofHitsXY_001;X_tof [cm];Y_tof [cm];Entries", 80, -20, 20, 80, -20, 20); + + fHM->Create1<TH1D>("fhLinearFitZX", "fhLinearFitZX;X@0 [cm];Entries", 400, -2, 2); + fHM->Create1<TH1D>("fhLinearFitZY", "fhLinearFitZY;Y@0 [cm];Entries", 400, -2, 2); + fHM->Create2<TH2D>("fhLinearFitXY", "fhLinearFitXY;X@0 [cm];Y@0 [cm];Entries", 400, -2, 2, 400, -2, 2); + fHM->Create1<TH1D>("fhLinearFitChi2X", "fhLinearFitChi2X;Chi2 X-Fit;Entries", 200, 0, 2); + fHM->Create1<TH1D>("fhLinearFitChi2Y", "fhLinearFitChi2Y;Chi2 Y-Fit;Entries", 200, 0, 2); + + fHM->Create2<TH2D>("fhLinearFitXY_.25", "fhLinearFitXY_.25;X@0 [cm];Y@0 [cm];Entries", 400, -2, 2, 400, -2, 2); + fHM->Create2<TH2D>("fhLinearFitXY_.50", "fhLinearFitXY_.50;X@0 [cm];Y@0 [cm];Entries", 400, -2, 2, 400, -2, 2); + fHM->Create2<TH2D>("fhLinearFitXY_.75", "fhLinearFitXY_.75;X@0 [cm];Y@0 [cm];Entries", 400, -2, 2, 400, -2, 2); + fHM->Create2<TH2D>("fhLinearFitXY_1", "fhLinearFitXY_2;X@0 [cm];Y@0 [cm];Entries", 400, -2, 2, 400, -2, 2); + fHM->Create2<TH2D>("fhLinearFitXY_2", "fhLinearFitXY_2;X@0 [cm];Y@0 [cm];Entries", 400, -2, 2, 400, -2, 2); + fHM->Create2<TH2D>("fhLinearFitXY_4", "fhLinearFitXY_4;X@0 [cm];Y@0 [cm];Entries", 400, -2, 2, 400, -2, 2); + fHM->Create2<TH2D>("fhLinearFitXY_6", "fhLinearFitXY_6;X@0 [cm];Y@0 [cm];Entries", 400, -2, 2, 400, -2, 2); + + fHM->Create2<TH2D>("fhLinearFitXY_-.5", "fhLinearFitXY_-.5;X@0 [cm];Y@0 [cm];Entries", 400, -2, 2, 400, -2, 2); + fHM->Create2<TH2D>("fhLinearFitXY_-1", "fhLinearFitXY_-1;X@0 [cm];Y@0 [cm];Entries", 400, -2, 2, 400, -2, 2); + fHM->Create2<TH2D>("fhLinearFitXY_-2", "fhLinearFitXY_-2;X@0 [cm];Y@0 [cm];Entries", 400, -2, 2, 400, -2, 2); + fHM->Create2<TH2D>("fhLinearFitXY_-4", "fhLinearFitXY_-4;X@0 [cm];Y@0 [cm];Entries", 400, -2, 2, 400, -2, 2); + fHM->Create2<TH2D>("fhLinearFitXY_-6", "fhLinearFitXY_-6;X@0 [cm];Y@0 [cm];Entries", 400, -2, 2, 400, -2, 2); + + fHM->Create1<TH1D>("fhTimeOffset", "fhTimeOffset;time [ns];Entries", 800, -40.0, 40.0); + fHM->Create1<TH1D>("fhTimeOfFlight", "fhTimeOfFlight;time [ns];Entries", 800, -40.0, 40.0); + fHM->Create1<TH1D>("fhTimeOfFlight_0", "fhTimeOfFlight_0;time [ns];Entries", 800, -40.0, 40.0); + fHM->Create1<TH1D>("fhTimeOfFlight_1", "fhTimeOfFlight_1;time [ns];Entries", 800, -40.0, 40.0); + + fHM->Create1<TH1D>("fhTimeOfFlight_0_0", "fhTimeOfFlight_0_0;time [ns];Entries", 800, -40.0, 40.0); + fHM->Create1<TH1D>("fhTimeOfFlight_0_1", "fhTimeOfFlight_0_1;time [ns];Entries", 800, -40.0, 40.0); + fHM->Create1<TH1D>("fhTimeOfFlight_1_0", "fhTimeOfFlight_1_0;time [ns];Entries", 800, -40.0, 40.0); + fHM->Create1<TH1D>("fhTimeOfFlight_1_1", "fhTimeOfFlight_1_1;time [ns];Entries", 800, -40.0, 40.0); + + fHM->Create2<TH2D>("fhTimeOfFlight_0_diffZ", "fhTimeOfFlight_0_diffZ;time [ns];Entries", 300, 0., 300., 800, -40.0, + 40.0); + fHM->Create2<TH2D>("fhTimeOfFlight_1_diffZ", "fhTimeOfFlight_1_diffZ;time [ns];Entries", 300, 0., 300., 800, -40.0, + 40.0); + + fHM->Create1<TH1D>("fhSimpleTrackTofTime", "fhSimpleTrackTofTime;time [ns];Entries", 400, -2.0, 2.0); + fHM->Create1<TH1D>("fhSimpleTrackTofDist", "fhSimpleTrackTofDist;distance [cm];Entries", 150, 10.0, 25.0); + fHM->Create1<TH1D>("fhSimpleTrackTofBeta", "fhSimpleTrackTofBeta;#beta;Entries", 600, -3.0, 3.0); + + fHM->Create1<TH1D>("fhMultiplicityStsHits", "fhMultiplicityStsHits;Hits/Event;Entries", 20, 0.0, 20.0); + fHM->Create1<TH1D>("fhMultiplicityTofHits", "fhMultiplicityTofHits;Hits/Event;Entries", 20, 0.0, 20.0); + fHM->Create1<TH1D>("fhMultiplicityTof2HitsTracks", "fhMultiplicityTof2HitsTracks;2-hit Tracks/Event;Entries", 20, 0.0, + 20.0); + + auto EventsPerTSBinning = (nofEvents < 200) ? nofEvents : 200; + fHM->Create1<TH1D>("fhEventsPerTS", "fhEventsPerTS;TS;#Events", EventsPerTSBinning, 0, EventsPerTSBinning); +} + +void drawHists(CbmHistManager* fHM) +{ + + { + TCanvas* c = fHM->CreateCanvas("EventsPerTS", "EventsPerTS", 2000, 2000); + fHM->H1("fhEventsPerTS")->Draw("HIST"); + + c->SaveAs(Form("%s/EventsPerTS.png", outdir)); + } + + { + TCanvas* c = fHM->CreateCanvas("StsUnit0_TofXYDiff", "StsUnit0_TofXYDiff", 2000, 2000); + c->Divide(4, 5); + c->cd(1); + fHM->H2("fhTof000Sts0XYdiff")->Draw("colz"); + c->cd(3); + fHM->H2("fhTof100Sts0XYdiff")->Draw("colz"); + + c->cd(6); + fHM->H2("fhTof010Sts0XYdiff")->Draw("colz"); + c->cd(8); + fHM->H2("fhTof110Sts0XYdiff")->Draw("colz"); + + c->cd(9); + fHM->H2("fhTof001Sts0XYdiff")->Draw("colz"); + c->cd(11); + fHM->H2("fhTof101Sts0XYdiff")->Draw("colz"); + + c->cd(14); + fHM->H2("fhTof011Sts0XYdiff")->Draw("colz"); + c->cd(16); + fHM->H2("fhTof111Sts0XYdiff")->Draw("colz"); + + c->cd(17); + fHM->H2("fhTof002Sts0XYdiff")->Draw("colz"); + + c->cd(19); + fHM->H2("fhTof102Sts0XYdiff")->Draw("colz"); + + c->SaveAs(Form("%s/StsUnit0_TofXYDiff.png", outdir)); + } + + { + TCanvas* c = fHM->CreateCanvas("StsUnit1_TofXYDiff", "StsUnit1_TofXYDiff", 2000, 2000); + c->Divide(4, 5); + c->cd(1); + fHM->H2("fhTof000Sts1XYdiff")->Draw("colz"); + c->cd(3); + fHM->H2("fhTof100Sts1XYdiff")->Draw("colz"); + + c->cd(6); + fHM->H2("fhTof010Sts1XYdiff")->Draw("colz"); + c->cd(8); + fHM->H2("fhTof110Sts1XYdiff")->Draw("colz"); + + c->cd(9); + fHM->H2("fhTof001Sts1XYdiff")->Draw("colz"); + c->cd(11); + fHM->H2("fhTof101Sts1XYdiff")->Draw("colz"); + + c->cd(14); + fHM->H2("fhTof011Sts1XYdiff")->Draw("colz"); + c->cd(16); + fHM->H2("fhTof111Sts1XYdiff")->Draw("colz"); + + c->cd(17); + fHM->H2("fhTof002Sts1XYdiff")->Draw("colz"); + + c->cd(19); + fHM->H2("fhTof102Sts1XYdiff")->Draw("colz"); + + c->SaveAs(Form("%s/StsUnit1_TofXYDiff.png", outdir)); + } + + { + TCanvas* c = fHM->CreateCanvas("StsUnit2_TofXYDiff", "StsUnit2_TofXYDiff", 2000, 2000); + c->Divide(4, 5); + c->cd(1); + fHM->H2("fhTof000Sts2XYdiff")->Draw("colz"); + c->cd(3); + fHM->H2("fhTof100Sts2XYdiff")->Draw("colz"); + + c->cd(6); + fHM->H2("fhTof010Sts2XYdiff")->Draw("colz"); + c->cd(8); + fHM->H2("fhTof110Sts2XYdiff")->Draw("colz"); + + c->cd(9); + fHM->H2("fhTof001Sts2XYdiff")->Draw("colz"); + c->cd(11); + fHM->H2("fhTof101Sts2XYdiff")->Draw("colz"); + + c->cd(14); + fHM->H2("fhTof011Sts2XYdiff")->Draw("colz"); + c->cd(16); + fHM->H2("fhTof111Sts2XYdiff")->Draw("colz"); + + c->cd(17); + fHM->H2("fhTof002Sts2XYdiff")->Draw("colz"); + + c->cd(19); + fHM->H2("fhTof102Sts2XYdiff")->Draw("colz"); + + c->SaveAs(Form("%s/StsUnit2_TofXYDiff.png", outdir)); + } + + { + TCanvas* c = fHM->CreateCanvas("StsUnits_TofXYDiff", "StsUnits_TofXYDiff", 3000, 1000); + c->Divide(3, 1); + c->cd(1); + fHM->H2("fhTofSts0XYdiff")->Draw("colz"); + c->cd(2); + fHM->H2("fhTofSts1XYdiff")->Draw("colz"); + c->cd(3); + fHM->H2("fhTofSts2XYdiff")->Draw("colz"); + + c->SaveAs(Form("%s/StsUnits_TofXYDiff.png", outdir)); + } + + { + TCanvas* c = fHM->CreateCanvas("Multiplicities", "Multiplicities", 3000, 1000); + c->Divide(3, 1); + c->cd(1); + fHM->H1("fhMultiplicityStsHits")->Draw("Hist"); + c->cd(2); + fHM->H1("fhMultiplicityTofHits")->Draw("Hist"); + c->cd(3); + fHM->H1("fhMultiplicityTof2HitsTracks")->Draw("Hist"); + + c->SaveAs(Form("%s/Multiplicities_Sts_Tof.png", outdir)); + } + + { + TCanvas* c = fHM->CreateCanvas("StsUnits_TofXYDiff_Close", "StsUnits_TofXYDiff_Close", 3000, 1000); + c->Divide(3, 1); + c->cd(1); + fHM->H2("fhTofSts0XYdiff_close")->Draw("colz"); + c->cd(2); + fHM->H2("fhTofSts1XYdiff_close")->Draw("colz"); + c->cd(3); + fHM->H2("fhTofSts2XYdiff_close")->Draw("colz"); + + c->SaveAs(Form("%s/StsUnits_TofXYDiff_Close.png", outdir)); + } + + { + TCanvas* c = fHM->CreateCanvas("StsZ", "StsZ", 1000, 1000); + fHM->H1("fhStsHitsZ")->Draw("HIST"); + + c->SaveAs(Form("%s/StsHitsZ.png", outdir)); + } +} + +TVector3 extrpolate(CbmTofHit* tofHit, TVector3* vertex, Double_t Z) +{ + TVector3 extVec(0, 0, 0); + + Double_t factor = (Z - vertex->Z()) / (tofHit->GetZ() - vertex->Z()); + Double_t x = vertex->X() + factor * (tofHit->GetX() - vertex->X()); + Double_t y = vertex->Y() + factor * (tofHit->GetY() - vertex->Y()); + extVec.SetXYZ(x, y, Z); + + return extVec; +} + +void ProjectXY(std::string name, CbmHistManager* fHM, std::vector<TH1*>* HistoX, std::vector<std::string>* stringX, + std::vector<TH1*>* HistoY, std::vector<std::string>* stringY) +{ + ProjectAxis(name, fHM, 'X', HistoX, stringX); + ProjectAxis(name, fHM, 'Y', HistoY, stringY); +} + +void ProjectAxis(std::string name, CbmHistManager* fHM, char axis, std::vector<TH1*>* Histo, + std::vector<std::string>* string) +{ + std::cout << "start Fitting procedure" << std::endl; + + TH1* hist = nullptr; + if (axis == 'x' || axis == 'X') hist = fHM->H2(name)->ProjectionX(); + if (axis == 'y' || axis == 'Y') hist = fHM->H2(name)->ProjectionY(); + + // Find Peak position: + Int_t binmax = hist->GetMaximumBin(); + Double_t max_x = hist->GetXaxis()->GetBinCenter(binmax); + + TF1* g1s = new TF1("gS", "gaus(0)", max_x - 0.3, max_x + 0.3); + TF1* g1b = nullptr; + + if (hist->GetMean() > max_x) { g1b = new TF1("gB", "gaus(0)", max_x + 1, 3); } + else { + g1b = new TF1("gB", "gaus(0)", -3, max_x - 1); + } + TF1* total1 = new TF1("total", "gaus(0)+gaus(3)", -3, 3); + + Double_t par[6]; + Double_t partotal[6]; + hist->Fit(g1s, "QR"); + hist->Fit(g1b, "QR+"); + + g1s->GetParameters(&par[0]); + g1b->GetParameters(&par[3]); + total1->SetParameters(par); + + hist->Fit(total1, "QR+"); + total1->GetParameters(&partotal[0]); + + // std::cout << " Mean1: " << partotal[1] << " DEV: " << partotal[2] << " Mean2: " << partotal[4] + // << " DEV: " << partotal[5] << std::endl; + // std::cout << " MeanSig: " << par[1] << " DEV: " << par[2] << " MeanBG: " << par[4] + // << " DEV: " << par[5] << std::endl; + if (std::abs(partotal[2]) < std::abs(partotal[5])) { + string->emplace_back(Form("%+.4f +- %.4f cm", partotal[1], partotal[2])); + } + else { + string->emplace_back(Form("%+.4f +- %.4f cm", partotal[4], partotal[5])); + } + + TCanvas* c = nullptr; + if (axis == 'x' || axis == 'X') + c = fHM->CreateCanvas(Form("%s_projX", name.c_str()), Form("%s_projX", name.c_str()), 2000, 2000); + if (axis == 'y' || axis == 'Y') + c = fHM->CreateCanvas(Form("%s_projY", name.c_str()), Form("%s_projY", name.c_str()), 2000, 2000); + hist->Draw("HIST"); + total1->Draw("SAME"); + + if (axis == 'x' || axis == 'X') c->SaveAs(Form("%s/%s_projX.png", outdir, name.c_str())); + if (axis == 'y' || axis == 'Y') c->SaveAs(Form("%s/%s_projY.png", outdir, name.c_str())); + + Histo->push_back(hist); +} + + +std::string FitTimeOffset(TH1* hist) +{ + TF1* g1s = new TF1("gS", "gaus(0)", -20, -4); + TF1* g1b = new TF1("gB", "gaus(0)", -40, -24); + + TF1* total1 = new TF1("total", "gaus(0)+gaus(3)", -40, 40); + + Double_t par[6]; + Double_t partotal[6]; + hist->Fit(g1s, "QR"); + hist->Fit(g1b, "QR+"); + + g1s->GetParameters(&par[0]); + g1b->GetParameters(&par[3]); + total1->SetParameters(par); + + hist->Fit(total1, "QR+"); + total1->GetParameters(&partotal[0]); + + //std::string FitResult = Form("%+.4f +- %.4f ns", partotal[1], partotal[2]); + + TCanvas* c = new TCanvas("TimeOffset_Fit", "TimeOffset_Fit", 2000, 2000); + hist->Draw("HIST"); + total1->Draw("SAME"); + c->SaveAs(Form("%s/TimeOffset_Fit.png", outdir)); + + return Form("%+.4f +- %.4f ns", partotal[1], partotal[2]); +} diff --git a/reco/detectors/tof/CbmTofFindTracks.cxx b/reco/detectors/tof/CbmTofFindTracks.cxx index 2b441568b1..9ffac3e5e7 100644 --- a/reco/detectors/tof/CbmTofFindTracks.cxx +++ b/reco/detectors/tof/CbmTofFindTracks.cxx @@ -990,6 +990,7 @@ void CbmTofFindTracks::Exec(Option_t* opt) for (Int_t iEvent = 0; iEvent < fEventsColl->GetEntriesFast(); iEvent++) { CbmEvent* tEvent = dynamic_cast<CbmEvent*>(fEventsColl->At(iEvent)); LOG(debug) << "Process event " << iEvent << " with " << tEvent->GetNofData(ECbmDataType::kTofHit) << " hits"; + if ((tEvent->GetNofData(ECbmDataType::kTofHit)) < 1) continue; if (fTofHitArray) fTofHitArray->Clear("C"); Int_t iNbHits = 0; -- GitLab