CbmL1.cxx 79.93 KiB
/* Copyright (C) 2006-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: Ivan Kisel, Sergey Gorbunov [committer], Valentina Akishina, Igor Kulakov, Maksym Zyzak */
/*
*====================================================================
*
* CBM Level 1 Reconstruction
*
* Authors: I.Kisel, S.Gorbunov
*
* e-mail : ikisel@kip.uni-heidelberg.de
*
*====================================================================
*
* L1 main program
*
*====================================================================
*/
#include "CbmL1.h"
#include "CbmKF.h"
#include "CbmKFVertex.h"
#include "CbmL1PFFitter.h"
#include "CbmMCDataManager.h"
#include "CbmMuchGeoScheme.h"
#include "CbmMuchModuleGem.h"
#include "CbmMuchPad.h"
#include "CbmMuchStation.h"
#include "CbmMvdDetector.h"
#include "CbmMvdStationPar.h"
// TODO: include of CbmSetup.h creates problems on Mac
// #include "CbmSetup.h"
#include "CbmMCDataObject.h"
#include "CbmStsFindTracks.h"
#include "CbmStsHit.h"
#include "CbmStsParSetModule.h"
#include "CbmStsParSetSensor.h"
#include "CbmStsParSetSensorCond.h"
#include "CbmStsSetup.h"
#include "CbmStsStation.h"
#include "CbmTofCell.h"
#include "CbmTofDigiBdfPar.h"
#include "CbmTofDigiPar.h" // in tof/TofParam
#include "CbmTrdParModDigi.h" // for CbmTrdModule
#include "CbmTrdParSetDigi.h" // for CbmTrdParSetDigi
#include "FairEventHeader.h"
#include "FairRunAna.h"
#include "TGeoArb8.h"
#include "TGeoBoolNode.h"
#include "TGeoCompositeShape.h"
#include "TGeoManager.h"
#include "TGeoNode.h"
#include "TMatrixD.h"
#include "TProfile2D.h"
#include "TROOT.h"
#include "TRandom3.h"
#include "TVector3.h"
#include "TVectorD.h"
#include <TFile.h>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <list>
#include "L1Algo/L1Algo.h"
#include "L1Algo/L1Branch.h"
#include "L1Algo/L1Field.h"
#include "L1Algo/L1Hit.h"
#include "L1AlgoInputData.h"
#include "L1Event.h"
using std::cout;
using std::endl;
using std::ios;
#include "KFTopoPerformance.h"
ClassImp(CbmL1)
static L1Algo algo_static _fvecalignment;
//L1AlgoInputData* fData_static _fvecalignment;
CbmL1* CbmL1::fInstance = 0;
CbmL1::CbmL1() : FairTask("L1")
{
if (!fInstance) fInstance = this;
}
CbmL1::CbmL1(const char* name, Int_t iVerbose, Int_t _fPerformance, int fSTAPDataMode_, TString fSTAPDataDir_,
int findParticleMode_)
: FairTask(name, iVerbose)
, fPerformance(_fPerformance)
, fSTAPDataMode(fSTAPDataMode_)
, fSTAPDataDir(fSTAPDataDir_)
, fFindParticlesMode(findParticleMode_)
{
if (!fInstance) fInstance = this;
}
CbmL1::~CbmL1()
{
if (fInstance == this) fInstance = nullptr;
}
void CbmL1::SetParContainers()
{
FairRunAna* ana = FairRunAna::Instance();
FairRuntimeDb* rtdb = ana->GetRuntimeDb();
fDigiPar = (CbmTofDigiPar*) (rtdb->getContainer("CbmTofDigiPar"));
// fTrdDigiPar = (CbmTrdDigiPar*)(FairRunAna::Instance()->GetRuntimeDb()->getContainer("CbmTrdDigiPar"));
fTrdDigiPar = (CbmTrdParSetDigi*) (rtdb->getContainer("CbmTrdParSetDigi"));
// Trigger loading of STS parameters
// If L1 runs standalone the parameters are not required by any STS task
// but they are needed by CbmStsSetup
fStsParSetModule = dynamic_cast<CbmStsParSetModule*>(rtdb->getContainer("CbmStsParSetModule"));
fStsParSetSensor = dynamic_cast<CbmStsParSetSensor*>(rtdb->getContainer("CbmStsParSetSensor"));
fStsParSetSensorCond = dynamic_cast<CbmStsParSetSensorCond*>(rtdb->getContainer("CbmStsParSetSensorCond"));
fTofDigiBdfPar = (CbmTofDigiBdfPar*) (rtdb->getContainer("CbmTofDigiBdfPar"));
rtdb->initContainers(ana->GetRunId()); // needed to get tracking stations for ToF hits
}
InitStatus CbmL1::ReInit()
{
SetParContainers();
return Init();
}
InitStatus CbmL1::Init()
{
fData = new L1AlgoInputData();
if (fVerbose > 1) {
char y[20] = " [0;33;44m"; // yellow
char Y[20] = " [1;33;44m"; // yellow bold
char W[20] = " [1;37;44m"; // white bold
char o[20] = " [0m\n"; // color off
Y[0] = y[0] = W[0] = o[0] = 0x1B; // escape character
cout << endl << endl;
cout << " " << W << " " << o;
cout << " " << W << " ===////====================================================== " << o;
cout << " " << W << " = = " << o;
cout << " " << W << " = " << Y << "L1 on-line finder" << W << " = " << o;
cout << " " << W << " = = " << o;
cout << " " << W << " = " << W << "Cellular Automaton 3.1 Vector" << y << " with " << W << "KF Quadro" << y
<< " technology" << W << " = " << o;
cout << " " << W << " = = " << o;
cout << " " << W << " = " << y << "Designed for CBM collaboration" << W << " = " << o;
cout << " " << W << " = " << y << "All rights reserved" << W << " = " << o;
cout << " " << W << " = = " << o;
cout << " " << W << " ========================================================////= " << o;
cout << " " << W << " " << o;
cout << endl << endl;
}
if (fVerbose > 1) {
#ifdef _OPENMP
LOG(info) << "L1 is running with OpenMP" << endl;
#else
LOG(info) << "L1 is running without OpenMP" << endl;
#endif
}
FairRootManager* fManger = FairRootManager::Instance();
FairRunAna* Run = FairRunAna::Instance();
{
fUseMVD = 1;
CbmStsFindTracks* FindTask = L1_DYNAMIC_CAST<CbmStsFindTracks*>(Run->GetTask("STSFindTracks"));
if (FindTask) fUseMVD = FindTask->MvdUsage();
// TODO: include of CbmSetup.h creates problems on Mac
// if (!CbmSetup::Instance()->IsActive(ECbmModuleId::kMvd)) { fUseMVD = false; }
// N Mvd stations is read from the KF material
if (CbmKF::Instance()->vMvdMaterial.size() == 0) { fUseMVD = false; }
}
fHistoDir = gROOT->mkdir("L1");
// turn on reconstruction in sub-detectors
fUseMUCH = 0;
fUseTRD = 0;
fUseTOF = 0;
if (fTrackingMode == L1Algo::TrackingMode::kMcbm) {
fUseMUCH = 0;
fUseTRD = 1;
fUseTOF = 1;
}
if (fTrackingMode == L1Algo::TrackingMode::kGlobal) {
fUseMUCH = 0;
fUseTRD = 1;
fUseTOF = 0;
}
fStsPoints = 0;
fMvdPoints = 0;
fMuchPoints = 0;
fTrdPoints = 0;
fTofPoints = 0;
fMCTracks = 0;
listMvdHitMatches = 0;
fTrdHitMatches = 0;
listMuchHitMatches = 0;
fTofHitDigiMatches = 0;
listStsClusters = 0;
vFileEvent.clear();
if (!fLegacyEventMode) { // Time-slice mode selected
LOG(info) << GetName() << ": running in time-slice mode.";
fTimeSlice = NULL;
fTimeSlice = (CbmTimeSlice*) fManger->GetObject("TimeSlice.");
if (fTimeSlice == NULL) LOG(fatal) << GetName() << ": No time slice branch in the tree!";
} //? time-slice mode
else // event mode
LOG(info) << GetName() << ": running in event mode.";
listStsClusters = L1_DYNAMIC_CAST<TClonesArray*>(fManger->GetObject("StsCluster"));
listStsHitMatch = L1_DYNAMIC_CAST<TClonesArray*>(fManger->GetObject("StsHitMatch"));
listStsClusterMatch = L1_DYNAMIC_CAST<TClonesArray*>(fManger->GetObject("StsClusterMatch"));
listStsHits = L1_DYNAMIC_CAST<TClonesArray*>(fManger->GetObject("StsHit"));
if (!fUseMUCH) {
fMuchPixelHits = 0;
fDigisMuch = 0;
fDigiMatchesMuch = 0;
fClustersMuch = 0;
fMuchPoints = 0;
listMuchHitMatches = 0;
}
else {
fMuchPixelHits = (TClonesArray*) fManger->GetObject("MuchPixelHit");
}
if (!fUseTRD) {
fTrdPoints = 0;
fTrdHitMatches = 0;
fTrdPoints = 0;
listTrdHits = 0;
}
else {
listTrdHits = L1_DYNAMIC_CAST<TClonesArray*>(fManger->GetObject("TrdHit"));
}
if (!fUseTOF) {
fTofPoints = 0;
fTofHitDigiMatches = 0;
fTofHits = 0;
}
else {
fTofHits = (TClonesArray*) fManger->GetObject("TofHit");
}
if (fPerformance) {
CbmMCDataManager* mcManager = (CbmMCDataManager*) fManger->GetObject("MCDataManager");
if (NULL == mcManager) LOG(fatal) << GetName() << ": No CbmMCDataManager!";
fStsPoints = mcManager->InitBranch("StsPoint");
fMcEventHeader = mcManager->GetObject("MCEventHeader.");
fMCTracks = mcManager->InitBranch("MCTrack");
if (NULL == fStsPoints) LOG(fatal) << GetName() << ": No StsPoint data!";
if (NULL == fMCTracks) LOG(fatal) << GetName() << ": No MCTrack data!";
if (NULL == fMcEventHeader) LOG(fatal) << GetName() << ": No MC event header data!";
if (!fLegacyEventMode) {
fEventList = (CbmMCEventList*) fManger->GetObject("MCEventList.");
if (NULL == fEventList) LOG(fatal) << GetName() << ": No MCEventList data!";
}
if (fUseMVD) {
fMvdPoints = mcManager->InitBranch("MvdPoint");
listMvdDigiMatches = L1_DYNAMIC_CAST<TClonesArray*>(fManger->GetObject("MvdDigiMatch"));
listMvdHitMatches = L1_DYNAMIC_CAST<TClonesArray*>(fManger->GetObject("MvdHitMatch"));
if (!listMvdHitMatches) { LOG(error) << "No listMvdHitMatches provided, performance is not done correctly"; }
}
if (!fUseTRD) {
fTrdPoints = 0;
fTrdHitMatches = 0;
fTrdPoints = 0;
}
else {
fTrdHitMatches = (TClonesArray*) fManger->GetObject("TrdHitMatch");
fTrdPoints = mcManager->InitBranch("TrdPoint");
}
if (!fUseMUCH) {
fMuchPoints = 0;
listMuchHitMatches = 0;
}
else {
fDigisMuch = (TClonesArray*) fManger->GetObject("MuchDigi");
fDigiMatchesMuch = (TClonesArray*) fManger->GetObject("MuchDigiMatch");
fClustersMuch = (TClonesArray*) fManger->GetObject("MuchCluster");
fMuchPoints = mcManager->InitBranch("MuchPoint");
listMuchHitMatches = L1_DYNAMIC_CAST<TClonesArray*>(fManger->GetObject("MuchPixelHitMatch"));
}
if (!fUseTOF) {
fTofPoints = 0;
fTofHitDigiMatches = 0;
}
else {
fTofPoints = mcManager->InitBranch("TofPoint");
fTofHitDigiMatches = static_cast<TClonesArray*>(fManger->GetObject("TofHitMatch"));
}
}
else {
}
if (!fUseMVD) { listMvdHits = 0; }
else {
listMvdHits = L1_DYNAMIC_CAST<TClonesArray*>(fManger->GetObject("MvdHit"));
}
NMvdStations = 0;
NStsStations = 0;
NMuchStations = 0;
NTrdStations = 0;
NTOFStation = 0;
NStation = 0;
algo = &algo_static;
L1Vector<fscal> geo("geo");
geo.reserve(10000);
{ // initialize field in the target region
assert(CbmKF::Instance()->vTargets.size() > 0);
auto& target = CbmKF::Instance()->vTargets[0];
algo->fCbmTargetX = target.x;
algo->fCbmTargetY = target.y;
algo->fCbmTargetZ = target.z;
for (int i = 0; i < 3; i++) {
Double_t point[3] = {0., 0., target.z + 2.5 * i};
Double_t B[3] = {0., 0., 0.};
if (CbmKF::Instance()->GetMagneticField()) { CbmKF::Instance()->GetMagneticField()->GetFieldValue(point, B); }
geo.push_back(point[2]);
geo.push_back(B[0]);
geo.push_back(B[1]);
geo.push_back(B[2]);
}
}
CbmMuchGeoScheme* fGeoScheme = CbmMuchGeoScheme::Instance();
if (fUseMUCH) {
/// Save old global file and folder pointer to avoid messing with FairRoot
TFile* oldFile = gFile;
TDirectory* oldDir = gDirectory;
TFile* file = new TFile(fMuchDigiFile, "READ");
TObjArray* stations = (TObjArray*) file->Get("stations");
fGeoScheme->Init(stations, 0);
for (int iStation = 0; iStation < fGeoScheme->GetNStations(); iStation++) {
const CbmMuchStation* station = fGeoScheme->GetStation(iStation);
int nLayers = station->GetNLayers();
NMuchStations += nLayers;
}
/// Restore old global file and folder pointer to avoid messing with FairRoot
gFile = oldFile;
gDirectory = oldDir;
}
// count TRD stations
if (fUseTRD) {
Int_t layerCounter = 0;
TObjArray* topNodes = gGeoManager->GetTopNode()->GetNodes();
for (Int_t iTopNode = 0; iTopNode < topNodes->GetEntriesFast(); iTopNode++) {
TGeoNode* topNode = static_cast<TGeoNode*>(topNodes->At(iTopNode));
if (TString(topNode->GetName()).Contains("trd")) {
TObjArray* layers = topNode->GetNodes();
for (Int_t iLayer = 0; iLayer < layers->GetEntriesFast(); iLayer++) {
TGeoNode* layer = static_cast<TGeoNode*>(layers->At(iLayer));
if (TString(layer->GetName()).Contains("layer")) { layerCounter++; }
}
}
}
NTrdStations = layerCounter;
if ((fTrackingMode == L1Algo::TrackingMode::kMcbm) && (fMissingHits)) { NTrdStations = NTrdStations - 1; }
}
vector<float> TofStationZ;
vector<int> TofStationN;
if (fUseTOF) {
NTOFStation = fTofDigiBdfPar->GetNbTrackingStations();
TofStationZ.resize(NTOFStation, 0);
TofStationN.resize(NTOFStation, 0);
for (int iSmType = 0; iSmType < fTofDigiBdfPar->GetNbSmTypes(); iSmType++) {
for (int iSm = 0; iSm < fTofDigiBdfPar->GetNbSm(iSmType); iSm++) {
for (int iRpc = 0; iRpc < fTofDigiBdfPar->GetNbRpc(iSmType); iRpc++) {
int iAddr = CbmTofAddress::GetUniqueAddress(iSm, iRpc, 0, 0, iSmType);
int station = fTofDigiBdfPar->GetTrackingStation(iSmType, iSm, iRpc);
CbmTofCell* fChannelInfo = fDigiPar->GetCell(iAddr);
if (NULL == fChannelInfo) break;
float z = fChannelInfo->GetZ();
float x = fChannelInfo->GetX();
if (fMissingHits) {
if ((x > 20) && (z > 270) && (station == 1)) station = 2;
if (z > 400) continue;
}
TofStationZ[station] += z;
TofStationN[station] += 1;
}
}
}
for (Int_t i = 0; i < NTOFStation; i++)
TofStationZ[i] = TofStationZ[i] / TofStationN[i];
}
CbmStsSetup* stsSetup = CbmStsSetup::Instance();
if (!stsSetup->IsInit()) { stsSetup->Init(nullptr); }
if (!stsSetup->IsModuleParsInit()) { stsSetup->SetModuleParameters(fStsParSetModule); }
if (!stsSetup->IsSensorParsInit()) { stsSetup->SetSensorParameters(fStsParSetSensor); }
if (!stsSetup->IsSensorCondInit()) { stsSetup->SetSensorConditions(fStsParSetSensorCond); }
NMvdStations = (fUseMVD) ? CbmKF::Instance()->vMvdMaterial.size() : 0;
NStsStations = CbmStsSetup::Instance()->GetNofStations();
NStation = NMvdStations + NStsStations + NMuchStations + NTrdStations + NTOFStation;
geo.push_back(NStation);
geo.push_back(NMvdStations);
geo.push_back(NStsStations);
// field
const int M = 5; // polinom order
const int N = 21; //(M+1)*(M+2)/2;
// { // field at the z=0 plane
// const double Xmax = 10, Ymax = 10;
// const double z = 0.;
// double dx = 1.; // step for the field approximation
// double dy = 1.;
// if( dx > Xmax/N/2 ) dx = Xmax/N/4.;
// if( dy > Ymax/N/2 ) dy = Ymax/N/4.;
//
// TMatrixD A(N,N);
// TVectorD b0(N), b1(N), b2(N);
// for( int i=0; i<N; i++){
// for( int j=0; j<N; j++) A(i,j)==0.;
// b0(i)=b1(i)=b2(i) = 0.;
// }
// for( double x=-Xmax; x<=Xmax; x+=dx )
// for( double y=-Ymax; y<=Ymax; y+=dy )
// {
// double r = sqrt(fabs(x*x/Xmax/Xmax+y/Ymax*y/Ymax));
// if( r>1. ) continue;
// Double_t w = 1./(r*r+1);
// Double_t p[3] = { x, y, z};
// Double_t B[3] = {0.,0.,0.};
// CbmKF::Instance()->GetMagneticField()->GetFieldValue(p, B);
// TVectorD m(N);
// m(0)=1;
// for( int i=1; i<=M; i++){
// int k = (i-1)*(i)/2;
// int l = i*(i+1)/2;
// for( int j=0; j<i; j++ ) m(l+j) = x*m(k+j);
// m(l+i) = y*m(k+i-1);
// }
//
// TVectorD mt = m;
// for( int i=0; i<N; i++){
// for( int j=0; j<N;j++) A(i,j)+=w*m(i)*m(j);
// b0(i)+=w*B[0]*m(i);
// b1(i)+=w*B[1]*m(i);
// b2(i)+=w*B[2]*m(i);
// }
// }
// double det;
// A.Invert(&det);
// TVectorD c0 = A*b0, c1 = A*b1, c2 = A*b2;
//
// targetFieldSlice = new L1FieldSlice;
// for(int i=0; i<N; i++){
// targetFieldSlice->cx[i] = c0(i);
// targetFieldSlice->cy[i] = c1(i);
// targetFieldSlice->cz[i] = c2(i);
// }
//
// } // target field
for (Int_t ist = 0; ist < NStation; ist++) {
double z = 0;
double Xmax = 0, Ymax = 0;
if (ist < NMvdStations) {
CbmMvdDetector* mvdDetector = CbmMvdDetector::Instance();
CbmMvdStationPar* mvdStationPar = mvdDetector->GetParameterFile();
CbmKFTube& t = CbmKF::Instance()->vMvdMaterial[ist];
geo.push_back(1);
geo.push_back(t.z);
geo.push_back(t.dz);
geo.push_back(t.r);
geo.push_back(t.R);
geo.push_back(t.RadLength);
fscal f_phi = 0, f_sigma = mvdStationPar->GetXRes(ist) / 10000, b_phi = 3.14159265358 / 2.,
b_sigma = mvdStationPar->GetYRes(ist) / 10000;
geo.push_back(f_phi);
geo.push_back(f_sigma);
geo.push_back(b_phi);
geo.push_back(b_sigma);
z = t.z;
Xmax = Ymax = t.R;
LOG(info) << "L1: Mvd station " << ist << " at z " << t.z;
}
if (ist >= NMvdStations && ist < (NMvdStations + NStsStations)) {
CbmStsStation* station = CbmStsSetup::Instance()->GetStation(ist - NMvdStations);
geo.push_back(0);
geo.push_back(station->GetZ());
geo.push_back(station->GetSensorD());
geo.push_back(0);
geo.push_back(station->GetYmax() < station->GetXmax() ? station->GetXmax() : station->GetYmax());
geo.push_back(station->GetRadLength());
double Pi = 3.14159265358;
fscal f_phi, f_sigma, b_phi, b_sigma; // angle and sigma front/back side
f_phi = station->GetSensorRotation();
b_phi = f_phi;
f_phi += station->GetSensorStereoAngle(0) * Pi / 180.;
b_phi += station->GetSensorStereoAngle(1) * Pi / 180.;
f_sigma = station->GetSensorPitch(0) / TMath::Sqrt(12);
b_sigma = f_sigma;
//f_sigma *= cos(f_phi); // TODO: think about this
//b_sigma *= cos(b_phi);
geo.push_back(f_phi);
geo.push_back(f_sigma);
geo.push_back(b_phi);
geo.push_back(b_sigma);
z = station->GetZ();
Xmax = station->GetXmax();
Ymax = station->GetYmax();
LOG(info) << "L1: Sts station " << ist - NMvdStations << " at z " << station->GetZ();
}
if ((ist < (NMvdStations + NStsStations + NMuchStations)) && (ist >= (NMvdStations + NStsStations))) {
int iStation = (ist - NMvdStations - NStsStations) / 3;
CbmMuchStation* station = (CbmMuchStation*) fGeoScheme->GetStation(iStation);
CbmMuchLayer* layer = station->GetLayer((ist - NMvdStations - NStsStations) % 3);
// CbmMuchModuleGem* module = (CbmMuchModuleGem*) CbmMuchGeoScheme::Instance()->GetModule(0,0,0,0);
// vector<CbmMuchPad*> pads = module->GetPads();
z = layer->GetZ();
geo.push_back(2);
geo.push_back(z);
geo.push_back(layer->GetDz());
geo.push_back(0);
geo.push_back(100); //station->GetRmax()
geo.push_back(0);
fscal f_phi = 0, f_sigma = 0.1, b_phi = 3.14159265358 / 2., b_sigma = 0.1;
geo.push_back(f_phi);
geo.push_back(f_sigma);
geo.push_back(b_phi);
geo.push_back(b_sigma);
Xmax = 100; //station->GetRmax();
Ymax = 100; //station->GetRmax();
LOG(info) << "L1: Much station " << iStation << " at z " << z << endl;
}
// int num = 0;
if ((ist < (NMvdStations + NStsStations + NTrdStations + NMuchStations))
&& (ist >= (NMvdStations + NStsStations + NMuchStations))) {
int num = ist - NMvdStations - NStsStations - NMuchStations;
// if (num == 0) continue;//true_station = 0;
// if (!true_station) continue;
// Int_t nrModules = fTrdDigiPar->GetNrOfModules();
int skip = num;
if ((fTrackingMode == L1Algo::TrackingMode::kMcbm) && (fMissingHits))
if (num > 0) skip++;
int ModuleId = fTrdDigiPar->GetModuleId(skip);
CbmTrdParModDigi* module = (CbmTrdParModDigi*) fTrdDigiPar->GetModulePar(ModuleId);
// if (!true_station[ist]) continue;
if (num == 0 || num == 2 || num == 4) geo.push_back(3);
if (num == 1 || num == 3) geo.push_back(6);
float stationZ = module->GetZ();
geo.push_back(stationZ);
geo.push_back(2 * module->GetSizeZ());
geo.push_back(0);
geo.push_back(2 * module->GetSizeX());
geo.push_back(10);
fscal f_phi = 0, f_sigma = 1., b_phi = 3.14159265358 / 2., b_sigma = 1.;
geo.push_back(f_phi);
geo.push_back(f_sigma);
geo.push_back(b_phi);
geo.push_back(b_sigma);
Xmax = module->GetSizeX();
Ymax = module->GetSizeY();
LOG(info) << "L1: Trd station " << num << " at z " << stationZ << endl;
}
if ((ist < (NMvdStations + NStsStations + NTrdStations + NMuchStations + NTOFStation))
&& (ist >= (NMvdStations + NStsStations + NMuchStations + NTrdStations))) {
geo.push_back(4);
int num = ist - (NMvdStations + NStsStations + NTrdStations + NMuchStations);
geo.push_back(TofStationZ[num]);
geo.push_back(10); /// TODO: add Tof width dz
geo.push_back(0);
geo.push_back(150); /// TODO: add Tof max radius
geo.push_back(10);
fscal f_phi = 0, f_sigma = 1 / 10000, b_phi = 3.14159265358 / 2., b_sigma = 1 / 10000;
geo.push_back(f_phi);
geo.push_back(f_sigma);
geo.push_back(b_phi);
geo.push_back(b_sigma);
Xmax = Ymax = 20;
LOG(info) << "L1: Tof station " << num << " at z " << z << endl;
}
double dx = 1.; // step for the field approximation
double dy = 1.;
if (dx > Xmax / N / 2) dx = Xmax / N / 4.;
if (dy > Ymax / N / 2) dy = Ymax / N / 4.;
double C[3][N];
for (int i = 0; i < 3; i++)
for (int k = 0; k < N; k++)
C[i][k] = 0;
TMatrixD A(N, N);
TVectorD b0(N), b1(N), b2(N);
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++)
A(i, j) = 0.;
b0(i) = b1(i) = b2(i) = 0.;
}
if (CbmKF::Instance()->GetMagneticField()) {
for (double x = -Xmax; x <= Xmax; x += dx)
for (double y = -Ymax; y <= Ymax; y += dy) {
double r = sqrt(fabs(x * x / Xmax / Xmax + y / Ymax * y / Ymax));
if (r > 1.) continue;
Double_t w = 1. / (r * r + 1);
Double_t p[3] = {x, y, z};
Double_t B[3] = {0., 0., 0.};
CbmKF::Instance()->GetMagneticField()->GetFieldValue(p, B);
TVectorD m(N);
m(0) = 1;
for (int i = 1; i <= M; i++) {
int k = (i - 1) * (i) / 2;
int l = i * (i + 1) / 2;
for (int j = 0; j < i; j++)
m(l + j) = x * m(k + j);
m(l + i) = y * m(k + i - 1);
}
TVectorD mt = m;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++)
A(i, j) += w * m(i) * m(j);
b0(i) += w * B[0] * m(i);
b1(i) += w * B[1] * m(i);
b2(i) += w * B[2] * m(i);
}
}
<<<<<<< HEAD
=======
// Solve SLE
>>>>>>> tmp modifications
double det;
A.Invert(&det);
TVectorD c0 = A * b0, c1 = A * b1, c2 = A * b2;
for (int i = 0; i < N; i++) {
C[0][i] = c0(i);
C[1][i] = c1(i);
C[2][i] = c2(i);
}
}
geo.push_back(N);
for (int k = 0; k < 3; k++) {
for (int j = 0; j < N; j++) {
geo.push_back(C[k][j]);
}
}
}
geo.push_back(fTrackingLevel);
geo.push_back(fMomentumCutOff);
geo.push_back(fGhostSuppression);
{
if (fSTAPDataMode % 2 == 1) { // 1,3
WriteSTAPGeoData(geo);
};
//if(fSTAPDataMode >= 2){ // 2,3
// int ind2, ind = geo.size();
// ReadSTAPGeoData(geo, ind2);
// if (ind2 != ind) LOG(error) << "-E- CbmL1: Read geometry from file " << fSTAPDataDir + "geo_algo.txt was NOT successful.";
//};
}
if (fSTAPDataMode >= 2) { // 2,3
int ind2, ind = geo.size();
ReadSTAPGeoData(geo, ind2);
if (ind2 != ind)
LOG(error) << "-E- CbmL1: Read geometry from file " << fSTAPDataDir + "geo_algo.txt was NOT successful.";
}
algo->SetL1Parameters(fL1Parameters);
/********************************************************************************************************************
* *
* EXPERIMENTAL FEATURE: usage of L1InitManager for L1Algo initialization *
* *
* Stage 1: Repeat initialization steps in parallel to the original code *
* Stage 2: Compare two initialization procedures *
* Stage 3: Remove old initialization *
* *
********************************************************************************************************************/
// Get reference to the L1Algo initialization manager
L1InitManager * initMan = algo->GetL1InitManager();
constexpr double PI = 3.14159265358; // TODO: why cmath is not used?
// Fill STS info:
for (int iSt = 0; iSt < NStsStations; ++iSt) {
auto cbmSts = CbmStsSetup::Instance()->GetStation(iSt);
auto stsStation = new L1BaseStationInfo();
stsStation->SetStationID(iSt);
stsStation->SetStationType(0); // STS
// Setup station geometry and material
stsStation->SetZ(cbmSts->GetZ());
double stsXmax = cbmSts->GetXmax();
double stsYmax = cbmSts->GetYmax();
stsStation->SetXmax(stsXmax);
stsStation->SetYmax(stsYmax);
stsStation->SetRmin(0);
stsStation->SetRmax(stsXmax > stsYmax ? stsXmax : stsYmax);
stsStation->SetMaterial(cbmSts->GetSensorD(), cbmSts->GetRadLength());
// Setup strips geometry
// TODO: why fscal instead of double in initialization?
fscal stsFrontPhi = cbmSts->GetSensorRotation() + cbmSts->GetSensorStereoAngle(0) * PI / 180.;
fscal stsBackPhi = cbmSts->GetSensorRotation() + cbmSts->GetSensorStereoAngle(1) * PI / 180.;
fscal stsFrontSigma = cbmSts->GetSensorPitch(0) / sqrt(12);
fscal stsBackSigma = stsFrontSigma;
stsStation->SetFrontBackStripsGeometry(stsFrontPhi, stsFrontSigma, stsBackPhi, stsBackSigma);
// Setup magnetic field
// NOTE: Such solution is needed to prevent L1Algo from FairRoot dependencies
auto getFieldValueFcn = [](const double (&inXYZ)[3], double (&outB)[3]) {
CbmKF::Instance()->GetMagneticField()->GetFieldValue(inXYZ, outB);
};
stsStation->SetFieldSlice(getFieldValueFcn);
initMan->AddStation(stsStation);
delete stsStation;
}
initMan->PrintStations(/*vebosity = */ 1);
/********************************************************************************************************************
********************************************************************************************************************/
algo->Init(geo, fUseHitErrors, fTrackingMode, fMissingHits);
geo.clear();
algo->fRadThick.reset(algo->NStations);
// Read STS MVD TRD MuCh ToF Radiation Thickness table
TString stationName = "Radiation Thickness [%], Station";
if (fUseMVD) {
if (fMvdMatBudgetFileName != "") {
/// Save old global file and folder pointer to avoid messing with FairRoot
TFile* oldFile = gFile;
TDirectory* oldDir = gDirectory;
TFile* rlFile = new TFile(fMvdMatBudgetFileName);
cout << "MVD Material budget file is " << fMvdMatBudgetFileName << ".\n";
for (int j = 0, iSta = 0; iSta < algo->NMvdStations; iSta++, j++) {
TString stationNameMvd = stationName;
stationNameMvd += j;
TProfile2D* hStaRadLen = (TProfile2D*) rlFile->Get(stationNameMvd);
if (!hStaRadLen) {
cout << "L1: incorrect " << fMvdMatBudgetFileName << " file. No " << stationNameMvd << "\n";
exit(1);
}
const int NBins = hStaRadLen->GetNbinsX(); // should be same in Y
const float RMax = hStaRadLen->GetXaxis()->GetXmax(); // should be same as min
algo->fRadThick[iSta].SetBins(NBins, RMax);
algo->fRadThick[iSta].table.resize(NBins);
double sumRF = 0., nRF = 0.;
for (int iB = 0; iB < NBins; iB++) {
algo->fRadThick[iSta].table[iB].resize(NBins);
for (int iB2 = 0; iB2 < NBins; iB2++) {
algo->fRadThick[iSta].table[iB][iB2] = 0.01 * hStaRadLen->GetBinContent(iB, iB2);
// Correction for holes in material map
if (algo->fRadThick[iSta].table[iB][iB2] < algo->vStations[iSta].materialInfo.RadThick[0])
if (iB2 > 0 && iB2 < NBins - 1)
algo->fRadThick[iSta].table[iB][iB2] = TMath::Min(0.01 * hStaRadLen->GetBinContent(iB, iB2 - 1),
0.01 * hStaRadLen->GetBinContent(iB, iB2 + 1));
// Correction for the incorrect harcoded value of RadThick of MVD stations
if (algo->fRadThick[iSta].table[iB][iB2] < 0.0015) algo->fRadThick[iSta].table[iB][iB2] = 0.0015;
// algo->fRadThick[iSta].table[iB][iB2] = algo->vStations[iSta].materialInfo.RadThick[0];
sumRF += algo->fRadThick[iSta].table[iB][iB2];
nRF++;
}
}
cout << " iSta " << iSta << " average RadThick in the material map " << sumRF / nRF << endl;
}
rlFile->Close();
rlFile->Delete();
/// Restore old global file and folder pointer to avoid messing with FairRoot
gFile = oldFile;
gDirectory = oldDir;
}
else {
LOG(warn) << "No MVD material budget file is found. Homogenious budget "
"will be used";
for (int iSta = 0; iSta < algo->NMvdStations; iSta++) {
algo->fRadThick[iSta].SetBins(1,
100); // mvd should be in +-100 cm square
algo->fRadThick[iSta].table.resize(1);
algo->fRadThick[iSta].table[0].resize(1);
algo->fRadThick[iSta].table[0][0] = algo->vStations[iSta].materialInfo.RadThick[0];
}
}
}
if (fStsMatBudgetFileName != "") {
/// Save old global file and folder pointer to avoid messing with FairRoot
TFile* oldFile = gFile;
TDirectory* oldDir = gDirectory;
TFile* rlFile = new TFile(fStsMatBudgetFileName);
cout << "STS Material budget file is " << fStsMatBudgetFileName << ".\n";
for (int j = 1, iSta = algo->NMvdStations; iSta < (algo->NMvdStations + NStsStations); iSta++, j++) {
TString stationNameSts = stationName;
stationNameSts += j;
TProfile2D* hStaRadLen = (TProfile2D*) rlFile->Get(stationNameSts);
if (!hStaRadLen) {
cout << "L1: incorrect " << fStsMatBudgetFileName << " file. No " << stationNameSts << "\n";
exit(1);
}
const int NBins = hStaRadLen->GetNbinsX(); // should be same in Y
const float RMax = hStaRadLen->GetXaxis()->GetXmax(); // should be same as min
algo->fRadThick[iSta].SetBins(NBins, RMax);
algo->fRadThick[iSta].table.resize(NBins);
double sumRF = 0., nRF = 0.;
for (int iB = 0; iB < NBins; iB++) {
algo->fRadThick[iSta].table[iB].resize(NBins);
for (int iB2 = 0; iB2 < NBins; iB2++) {
algo->fRadThick[iSta].table[iB][iB2] = 0.01 * hStaRadLen->GetBinContent(iB, iB2);
if (algo->fRadThick[iSta].table[iB][iB2] < algo->vStations[iSta].materialInfo.RadThick[0])
algo->fRadThick[iSta].table[iB][iB2] = algo->vStations[iSta].materialInfo.RadThick[0];
// cout << " iSta " << iSta << " iB " << iB << "iB2 " << iB2 << " RadThick " << algo->fRadThick[iSta].table[iB][iB2] << endl;
sumRF += algo->fRadThick[iSta].table[iB][iB2];
nRF++;
}
}
cout << " iSta " << iSta << " average RadThick in the material map " << sumRF / nRF << endl;
}
rlFile->Close();
rlFile->Delete();
/// Restore old global file and folder pointer to avoid messing with FairRoot
gFile = oldFile;
gDirectory = oldDir;
}
else {
LOG(warn) << "No STS material budget file is found. Homogenious budget "
"will be used";
for (int iSta = algo->NMvdStations; iSta < (algo->NMvdStations + NStsStations); iSta++) {
algo->fRadThick[iSta].SetBins(1, 100);
algo->fRadThick[iSta].table.resize(1);
algo->fRadThick[iSta].table[0].resize(1);
algo->fRadThick[iSta].table[0][0] = algo->vStations[iSta].materialInfo.RadThick[0];
}
}
if (fUseMUCH)
if (fMuchMatBudgetFileName != "") {
/// Save old global file and folder pointer to avoid messing with FairRoot
TFile* oldFile = gFile;
TDirectory* oldDir = gDirectory;
TFile* rlFile = new TFile(fMuchMatBudgetFileName);
cout << "Much Material budget file is " << fMuchMatBudgetFileName << ".\n";
for (int j = 1, iSta = (NStsStations + NMvdStations); iSta < (NStsStations + NMvdStations + NMuchStations);
iSta++, j++) {
TString stationNameSts = stationName;
stationNameSts += j;
TProfile2D* hStaRadLen = (TProfile2D*) rlFile->Get(stationNameSts);
if (!hStaRadLen) {
cout << "L1: incorrect " << fMuchMatBudgetFileName << " file. No " << stationNameSts << "\n";
exit(1);
}
const int NBins = hStaRadLen->GetNbinsX(); // should be same in Y
const float RMax = hStaRadLen->GetXaxis()->GetXmax(); // should be same as min
algo->fRadThick[iSta].SetBins(NBins, RMax);
algo->fRadThick[iSta].table.resize(NBins);
for (int iB = 0; iB < NBins; iB++) {
algo->fRadThick[iSta].table[iB].resize(NBins);
float hole = 0.15;
for (int iB2 = 0; iB2 < NBins; iB2++) {
algo->fRadThick[iSta].table[iB][iB2] = 0.01 * hStaRadLen->GetBinContent(iB, iB2);
// Correction for holes in material map
//if(algo->fRadThick[iSta].table[iB][iB2] < algo->vStations[iSta].materialInfo.RadThick[0])
if (iB2 > 0 && iB2 < NBins - 1)
algo->fRadThick[iSta].table[iB][iB2] = TMath::Min(0.01 * hStaRadLen->GetBinContent(iB, iB2 - 1),
0.01 * hStaRadLen->GetBinContent(iB, iB2 + 1));
// Correction for the incorrect harcoded value of RadThick of MVD stations
if (algo->fRadThick[iSta].table[iB][iB2] > 0.0015) hole = algo->fRadThick[iSta].table[iB][iB2];
if (algo->fRadThick[iSta].table[iB][iB2] < 0.0015) algo->fRadThick[iSta].table[iB][iB2] = hole;
// algo->fRadThick[iSta].table[iB][iB2] = algo->vStations[iSta].materialInfo.RadThick[0];
}
}
}
rlFile->Close();
rlFile->Delete();
/// Restore old global file and folder pointer to avoid messing with FairRoot
gFile = oldFile;
gDirectory = oldDir;
}
else {
LOG(warn) << "No Much material budget file is found. Homogenious budget "
"will be used";
for (int iSta = (NStsStations + NMvdStations); iSta < (NStsStations + NMvdStations + NMuchStations); iSta++) {
algo->fRadThick[iSta].SetBins(1, 100);
algo->fRadThick[iSta].table.resize(1);
algo->fRadThick[iSta].table[0].resize(1);
algo->fRadThick[iSta].table[0][0] = algo->vStations[iSta].materialInfo.RadThick[0];
}
}
if (fUseTRD)
if (fTrdMatBudgetFileName != "") {
/// Save old global file and folder pointer to avoid messing with FairRoot
TFile* oldFile = gFile;
TDirectory* oldDir = gDirectory;
TFile* rlFile = new TFile(fTrdMatBudgetFileName);
cout << "TRD Material budget file is " << fTrdMatBudgetFileName << ".\n";
for (int j = 1, iSta = (NStsStations + NMvdStations + NMuchStations);
iSta < (NStsStations + NMvdStations + NMuchStations + NTrdStations); iSta++, j++) {
TString stationNameSts = stationName;
int skipStation = j;
if (fMissingHits)
if (skipStation == 2) skipStation = 3;
if (fMissingHits)
if (skipStation == 3) skipStation = 4;
stationNameSts += skipStation;
TProfile2D* hStaRadLen = (TProfile2D*) rlFile->Get(stationNameSts);
if (!hStaRadLen) {
cout << "L1: incorrect " << fTrdMatBudgetFileName << " file. No " << stationNameSts << "\n";
exit(1);
}
const int NBins = hStaRadLen->GetNbinsX(); // should be same in Y
const float RMax = hStaRadLen->GetXaxis()->GetXmax(); // should be same as min
algo->fRadThick[iSta].SetBins(NBins, RMax);
algo->fRadThick[iSta].table.resize(NBins);
for (int iB = 0; iB < NBins; iB++) {
algo->fRadThick[iSta].table[iB].resize(NBins);
float hole = 0.15;
for (int iB2 = 0; iB2 < NBins; iB2++) {
algo->fRadThick[iSta].table[iB][iB2] = 0.01 * hStaRadLen->GetBinContent(iB, iB2);
// Correction for holes in material map
//if(algo->fRadThick[iSta].table[iB][iB2] < algo->vStations[iSta].materialInfo.RadThick[0])
if (iB2 > 0 && iB2 < NBins - 1)
algo->fRadThick[iSta].table[iB][iB2] = TMath::Min(0.01 * hStaRadLen->GetBinContent(iB, iB2 - 1),
0.01 * hStaRadLen->GetBinContent(iB, iB2 + 1));
// Correction for the incorrect harcoded value of RadThick of MVD stations
if (algo->fRadThick[iSta].table[iB][iB2] > 0.0015) hole = algo->fRadThick[iSta].table[iB][iB2];
if (algo->fRadThick[iSta].table[iB][iB2] < 0.0015) algo->fRadThick[iSta].table[iB][iB2] = hole;
// algo->fRadThick[iSta].table[iB][iB2] = algo->vStations[iSta].materialInfo.RadThick[0];
}
}
}
rlFile->Close();
rlFile->Delete();
/// Restore old global file and folder pointer to avoid messing with FairRoot
gFile = oldFile;
gDirectory = oldDir;
}
else {
LOG(warn) << "No TRD material budget file is found. Homogenious budget "
"will be used";
for (int iSta = (NStsStations + NMvdStations + NMuchStations);
iSta < (NStsStations + NMvdStations + NMuchStations + NTrdStations); iSta++) {
algo->fRadThick[iSta].SetBins(1, 100);
algo->fRadThick[iSta].table.resize(1);
algo->fRadThick[iSta].table[0].resize(1);
algo->fRadThick[iSta].table[0][0] = algo->vStations[iSta].materialInfo.RadThick[0];
cout << "TRD material: " << algo->vStations[iSta].materialInfo.RadThick[0] << endl;
}
}
if (fUseTOF)
if (fTofMatBudgetFileName != "") {
/// Save old global file and folder pointer to avoid messing with FairRoot
TFile* oldFile = gFile;
TDirectory* oldDir = gDirectory;
TFile* rlFile = new TFile(fTofMatBudgetFileName);
cout << "TOF Material budget file is " << fTofMatBudgetFileName << ".\n";
for (int j = 1, iSta = (NStsStations + NMvdStations + NMuchStations + NTrdStations);
iSta < (NStsStations + NMvdStations + NMuchStations + NTrdStations + NTOFStation); iSta++, j++) {
TString stationNameSts = stationName;
stationNameSts += j;
TProfile2D* hStaRadLen = (TProfile2D*) rlFile->Get(stationNameSts);
if (!hStaRadLen) {
cout << "L1: incorrect " << fTofMatBudgetFileName << " file. No " << stationNameSts << "\n";
exit(1);
}
const int NBins = hStaRadLen->GetNbinsX(); // should be same in Y
const float RMax = hStaRadLen->GetXaxis()->GetXmax(); // should be same as min
algo->fRadThick[iSta].SetBins(NBins, RMax);
algo->fRadThick[iSta].table.resize(NBins);
for (int iB = 0; iB < NBins; iB++) {
algo->fRadThick[iSta].table[iB].resize(NBins);
float hole = 0.0015;
for (int iB2 = 0; iB2 < NBins; iB2++) {
algo->fRadThick[iSta].table[iB][iB2] = 0.01 * hStaRadLen->GetBinContent(iB, iB2);
// Correction for holes in material map
//if(algo->fRadThick[iSta].table[iB][iB2] < algo->vStations[iSta].materialInfo.RadThick[0])
if (iB2 > 0 && iB2 < NBins - 1)
algo->fRadThick[iSta].table[iB][iB2] = TMath::Min(0.01 * hStaRadLen->GetBinContent(iB, iB2 - 1),
0.01 * hStaRadLen->GetBinContent(iB, iB2 + 1));
// Correction for the incorrect harcoded value of RadThick of MVD stations
if (algo->fRadThick[iSta].table[iB][iB2] > 0.0015) hole = algo->fRadThick[iSta].table[iB][iB2];
if (algo->fRadThick[iSta].table[iB][iB2] < 0.0015) algo->fRadThick[iSta].table[iB][iB2] = hole;
// algo->fRadThick[iSta].table[iB][iB2] = algo->vStations[iSta].materialInfo.RadThick[0];
}
}
}
rlFile->Close();
rlFile->Delete();
/// Restore old global file and folder pointer to avoid messing with FairRoot
gFile = oldFile;
gDirectory = oldDir;
}
else {
LOG(warn) << "No TOF material budget file is found. Homogenious budget "
"will be used";
for (int iSta = (NStsStations + NMvdStations + NMuchStations + NTrdStations);
iSta < (NStsStations + NMvdStations + NMuchStations + NTrdStations + NTOFStation); iSta++) {
algo->fRadThick[iSta].SetBins(1, 100);
algo->fRadThick[iSta].table.resize(1);
algo->fRadThick[iSta].table[0].resize(1);
algo->fRadThick[iSta].table[0][0] = algo->vStations[iSta].materialInfo.RadThick[0];
}
}
return kSUCCESS;
}
void CbmL1::Exec(Option_t* /*option*/) {}
void CbmL1::Reconstruct(CbmEvent* event)
{
static int nevent = 0;
vFileEvent.clear();
L1Vector<std::pair<double, int>> SortStsHits("CbmL1::SortStsHits");
SortStsHits.reserve(listStsHits->GetEntriesFast());
float start_t = 10000000000;
bool areDataLeft = true; // whole TS processed?
float TsStart = 0; // starting time of sub-TS
float TsLength = 10000; // length of sub-TS
float TsOverlap = 15; // min length of overlap region
int FstHitinTs = 0; // 1st hit index in TS
/// sort input hits by time
for (Int_t j = 0; j < listStsHits->GetEntriesFast(); j++) {
CbmStsHit* sh = L1_DYNAMIC_CAST<CbmStsHit*>(listStsHits->At(j));
double t = sh->GetTime();
if (t < start_t) start_t = t;
SortStsHits.push_back(std::pair<double, int>(t, j));
}
TsStart = start_t; ///reco TS start time is set to smallest hit time
std::sort(SortStsHits.begin(), SortStsHits.end());
StsIndex.clear();
StsIndex.reserve(SortStsHits.size());
for (unsigned int i = 0; i < SortStsHits.size(); i++) {
int j = SortStsHits[i].second;
StsIndex.push_back(j);
};
if (!fLegacyEventMode && fPerformance) {
int nofEvents = fEventList->GetNofEvents();
for (int iE = 0; iE < nofEvents; iE++) {
int fileId = fEventList->GetFileIdByIndex(iE);
int eventId = fEventList->GetEventIdByIndex(iE);
vFileEvent.insert(DFSET::value_type(fileId, eventId));
}
}
else {
Int_t iFile = FairRunAna::Instance()->GetEventHeader()->GetInputFileId();
Int_t iEvent = FairRunAna::Instance()->GetEventHeader()->GetMCEntryNumber();
vFileEvent.insert(DFSET::value_type(iFile, iEvent));
}
if (fVerbose > 1) { cout << endl << "CbmL1::Exec event " << ++nevent << " ..." << endl << endl; }
#ifdef _OPENMP
omp_set_num_threads(1);
#endif
// repack data
L1Vector<CbmL1Track> vRTracksCur("CbmL1::vRTracksCur"); // reconstructed tracks
{
int nHits = 0;
int nSta = 1;
if (listMvdHits) {
nHits += listMvdHits->GetEntriesFast();
nSta += NMvdStations;
}
if (listStsHits) {
nHits += listStsHits->GetEntriesFast();
nSta += NStsStations;
}
vRTracksCur.reserve(10 + (2 * nHits) / nSta);
}
fTrackingTime = 0;
while (areDataLeft) {
fData->Clear();
if (event) {
fData->fStripFlag.clear();
areDataLeft = false;
TsStart = 0;
TsLength = 2000000000;
TsOverlap = 0;
FstHitinTs = 0;
}
if (fSTAPDataMode >= 2) { // 2,3
fData->ReadHitsFromFile(fSTAPDataDir.Data(), 1, fVerbose);
algo->SetData(fData->GetStsHits(), fData->GetNStsStrips(), fData->GetSFlag(), fData->GetStsHitsStartIndex(),
fData->GetStsHitsStopIndex());
}
else {
ReadEvent(fData, TsStart, TsLength, TsOverlap, FstHitinTs, areDataLeft, event);
}
if (0) { // correct hits on MC // dbg
TRandom3 random;
L1Vector<int> strips("CbmL1::strips");
for (unsigned int iH = 0; iH < (*algo->vStsHits).size(); ++iH) {
L1Hit& h = const_cast<L1Hit&>((*algo->vStsHits)[iH]);
#ifdef USE_EVENT_NUMBER
h.n = -1;
#endif
if (vStsHits[iH].mcPointIds.size() == 0) continue;
const CbmL1MCPoint& mcp = vMCPoints[vStsHits[iH].mcPointIds[0]];
#ifdef USE_EVENT_NUMBER
h.n = mcp.event;
#endif
const int ista = (*algo->fStripFlag)[h.f] / 4;
const L1Station& sta = algo->vStations[ista];
if (std::find(strips.begin(), strips.end(), h.f) != strips.end()) { // separate strips
(*algo->fStripFlag).push_back((*algo->fStripFlag)[h.f]);
h.f = algo->NStsStrips;
algo->NStsStrips++;
}
strips.push_back(h.f);
if (std::find(strips.begin(), strips.end(), h.b) != strips.end()) {
(*algo->fStripFlag).push_back((*algo->fStripFlag)[h.b]);
h.b = algo->NStsStrips;
algo->NStsStrips++;
}
strips.push_back(h.b);
double u = mcp.x * sta.frontInfo.cos_phi[0] + mcp.y * sta.frontInfo.sin_phi[0];
double v = mcp.x * sta.backInfo.cos_phi[0] + mcp.y * sta.backInfo.sin_phi[0];
#if 1 // GAUSS
u += random.Gaus(0, sqrt(sta.frontInfo.sigma2)[0]);
v += random.Gaus(0, sqrt(sta.backInfo.sigma2)[0]);
#else // UNIFORM
u += 3.5 * sqrt(sta.frontInfo.sigma2)[0] * random.Uniform(-1, 1);
v += 3.5 * sqrt(sta.backInfo.sigma2)[0] * random.Uniform(-1, 1);
#endif
h.u = u;
h.v = v;
h.z = mcp.z;
}
}
if (fPerformance) {
HitMatch();
// calculate the max number of Hits\mcPoints on continuous(consecutive) stations
for (L1Vector<CbmL1MCTrack>::iterator it = vMCTracks.begin(); it != vMCTracks.end(); ++it)
it->Init();
}
if (fSTAPDataMode % 2 == 1) { // 1,3
WriteSTAPAlgoData();
WriteSTAPPerfData();
};
if (fSTAPDataMode >= 2) { // 2,3
//ReadSTAPAlgoData();
ReadSTAPPerfData();
};
if ((fPerformance) && (fSTAPDataMode < 2)) { InputPerformance(); }
// FieldApproxCheck();
// FieldIntegralCheck();
for (unsigned int iH = 0; iH < (*algo->vStsHits).size(); ++iH) {
#ifdef USE_EVENT_NUMBER
L1Hit& h = const_cast<L1Hit&>((*algo->vStsHits)[iH]);
h.n = -1;
#endif
if (vStsHits[iH].mcPointIds.size() == 0) continue;
#ifdef USE_EVENT_NUMBER
const CbmL1MCPoint& mcp = vMCPoints[vStsHits[iH].mcPointIds[0]];
h.n = mcp.event;
#endif
}
if (fVerbose > 1) { cout << "L1 Track finder..." << endl; }
algo->CATrackFinder();
// IdealTrackFinder();
fTrackingTime += algo->fCATime;
if (fVerbose > 1) { cout << "L1 Track finder ok" << endl; }
// algo->L1KFTrackFitter( fExtrapolateToTheEndOfSTS );
{ // track fit
L1FieldValue b = algo->GetVtxFieldValue();
if ((fabs(b.x[0]) < 0.0000001) && (fabs(b.y[0]) < 0.0000001) && (fabs(b.z[0]) < 0.0000001)) {
algo->KFTrackFitter_simple();
}
else {
if (fTrackingMode == L1Algo::TrackingMode::kGlobal || fTrackingMode == L1Algo::TrackingMode::kMcbm) {
algo->L1KFTrackFitterMuch();
}
else {
algo->L1KFTrackFitter();
}
}
}
if (fVerbose > 1) { cout << "L1 Track fitter ok" << endl; }
// save recontstructed tracks
if (fLegacyEventMode) vRTracksCur.clear();
int start_hit = 0;
float TsStart_new = TsStart + TsLength - TsOverlap;
for (L1Vector<L1Track>::iterator it = algo->fTracks.begin(); it != algo->fTracks.end(); it++) {
CbmL1Track t;
for (int i = 0; i < 7; i++)
t.T[i] = it->TFirst[i];
for (int i = 0; i < 21; i++)
t.C[i] = it->CFirst[i];
for (int i = 0; i < 7; i++)
t.TLast[i] = it->TLast[i];
for (int i = 0; i < 21; i++)
t.CLast[i] = it->CLast[i];
for (int k = 0; k < 7; k++)
t.Tpv[k] = it->Tpv[k];
for (int k = 0; k < 21; k++)
t.Cpv[k] = it->Cpv[k];
t.chi2 = it->chi2;
t.NDF = it->NDF;
//t.T[4] = it->Momentum;
t.StsHits.clear();
t.fTrackTime = it->fTrackTime;
L1Vector<int> StsHitsLocal("CbmL1::StsHitsLocal");
StsHitsLocal.reserve(it->NHits);
for (int i = 0; i < it->NHits; i++) {
int start_hit1 = start_hit;
if (algo->fRecoHits[start_hit1] > vStsHits.size() - 1) start_hit++;
else if (!fLegacyEventMode) {
t.StsHits.push_back(((*algo->vStsHits)[algo->fRecoHits[start_hit]]).ID);
}
else {
t.StsHits.push_back(algo->fRecoHits[start_hit]);
}
StsHitsLocal.push_back(algo->fRecoHits[start_hit++]);
}
t.mass = algo->fDefaultMass; // pion mass
t.is_electron = 0;
t.SetId(vRTracksCur.size());
// CbmL1Track* prtra = &t;
int indd = 0;
bool isInOverlap = 0;
for (unsigned int i = 0; i < StsHitsLocal.size(); i++) {
// if ((*ih) > int(vStsHits.size() - 1)) {
// indd = 1;
// break;
// }
if (vStsHits[StsHitsLocal[i]].t >= (TsStart + TsLength - TsOverlap)) {
isInOverlap = 1;
if (TsStart_new > vStsHits[StsHitsLocal[i]].t) TsStart_new = vStsHits[StsHitsLocal[i]].t;
}
int nMCPoints = vStsHits[StsHitsLocal[i]].mcPointIds.size();
for (int iP = 0; iP < nMCPoints; iP++) {
int iMC = vStsHits[StsHitsLocal[i]].mcPointIds[iP];
if (iMC > int(vMCPoints.size() - 1)) {
// cout << " iMC " << iMC << " vMCPoints.size() " << vMCPoints.size() << endl;
indd = 1;
}
}
}
if (indd == 1) continue;
if ((!fLegacyEventMode) && (isInOverlap == 1)) {
continue; ///Discard tracks from overlap region
/// set strips as unused
for (unsigned int i = 0; i < StsHitsLocal.size(); i++) {
algo->SetFUnUsed(const_cast<unsigned char&>((*algo->fStripFlag)[vStsHits[StsHitsLocal[i]].f]));
algo->SetFUnUsed(const_cast<unsigned char&>((*algo->fStripFlag)[vStsHits[StsHitsLocal[i]].b]));
}
}
vRTracksCur.push_back(t);
}
for (int i = 0; i < listStsHits->GetEntriesFast(); i++) {
CbmStsHit* sh = L1_DYNAMIC_CAST<CbmStsHit*>(listStsHits->At(StsIndex[i]));
float time = sh->GetTime();
if (TsStart_new <= time) {
FstHitinTs = i;
break;
}
};
if (!fLegacyEventMode) TsStart = TsStart_new; ///Set new TS strat to earliest discarted track
if (!fLegacyEventMode) cout << "CA Track Finder: " << algo->fCATime << " s/sub-ts" << endl << endl;
}
if (fPerformance) {
float start = 0;
float end = 10000000000.f;
int fHit = 0;
bool stop = 0;
ReadEvent(fData, start, end, start, fHit, stop, event);
HitMatch();
// calculate the max number of Hits\mcPoints on continuous(consecutive) stations
for (L1Vector<CbmL1MCTrack>::iterator it = vMCTracks.begin(); it != vMCTracks.end(); ++it)
it->Init();
}
//
// if (fSTAPDataMode % 2 == 1) { // 1,3
// WriteSTAPAlgoData();
// WriteSTAPPerfData();
// };
// if (fSTAPDataMode >= 2) { // 2,3
// //ReadSTAPAlgoData();
//
// ReadSTAPPerfData();
// };
vRTracks.clear();
vRTracks.reserve(vRTracksCur.size());
for (unsigned int iTrack = 0; iTrack < vRTracksCur.size(); iTrack++) {
for (unsigned int iHit = 0; iHit < vRTracksCur[iTrack].StsHits.size(); iHit++)
if (!fLegacyEventMode) vRTracksCur[iTrack].StsHits[iHit] = SortedIndex[vRTracksCur[iTrack].StsHits[iHit]];
vRTracks.push_back(vRTracksCur[iTrack]);
}
if ((fPerformance) && (fSTAPDataMode < 2)) { InputPerformance(); }
for (unsigned int iH = 0; iH < (*algo->vStsHits).size(); ++iH) {
#ifdef USE_EVENT_NUMBER
L1Hit& h = const_cast<L1Hit&>((*algo->vStsHits)[iH]);
h.n = -1;
#endif
if (vStsHits[iH].mcPointIds.size() == 0) continue;
#ifdef USE_EVENT_NUMBER
const CbmL1MCPoint& mcp = vMCPoints[vStsHits[iH].mcPointIds[0]];
h.n = mcp.event;
#endif
}
// output performance
if (fPerformance) {
if (fVerbose > 1) { cout << "Performance..." << endl; }
//HitMatch();
TrackMatch();
}
if (fPerformance) {
EfficienciesPerformance();
HistoPerformance();
TrackFitPerformance();
// TimeHist();
/// WriteSIMDKFData();
}
if (fVerbose > 1) { cout << "End of L1" << endl; }
static bool ask = 0;
char symbol;
if (ask) {
std::cout << std::endl << "L1 run (any/r/q) > ";
do {
std::cin.get(symbol);
if (symbol == 'r') ask = false;
if ((symbol == 'e') || (symbol == 'q')) exit(0);
} while (symbol != '\n');
}
// }
}
// ----- Finish CbmStsFitPerformanceTask task -----------------------------
void CbmL1::Finish()
{
TDirectory* curr = gDirectory;
TFile* currentFile = gFile;
// Open output file and write histograms
TFile* outfile = new TFile("L1_histo.root", "RECREATE");
outfile->cd();
writedir2current(fHistoDir);
outfile->Close();
outfile->Delete();
gFile = currentFile;
gDirectory = curr;
}
void CbmL1::writedir2current(TObject* obj)
{
if (!obj->IsFolder()) obj->Write();
else {
TDirectory* cur = gDirectory;
TDirectory* sub = cur->mkdir(obj->GetName());
sub->cd();
TList* listSub = (L1_DYNAMIC_CAST<TDirectory*>(obj))->GetList();
TIter it(listSub);
while (TObject* obj1 = it())
writedir2current(obj1);
cur->cd();
}
}
/// ----- Ideal Tracking -----------------------------
void CbmL1::IdealTrackFinder()
{
algo->fTracks.clear();
algo->fRecoHits.clear();
for (L1Vector<CbmL1MCTrack>::iterator i = vMCTracks.begin(); i != vMCTracks.end(); ++i) {
CbmL1MCTrack& MC = *i;
if (!MC.IsReconstructable()) continue;
if (!(MC.ID >= 0)) continue;
if (MC.StsHits.size() < 4) continue;
L1Track algoTr;
algoTr.NHits = 0;
L1Vector<int> hitIndices("CbmL1::hitIndices", algo->NStations, -1);
for (unsigned int iH = 0; iH < MC.StsHits.size(); iH++) {
const int hitI = MC.StsHits[iH];
const CbmL1Hit& hit = vStsHits[hitI];
const int iStation = vMCPoints[hit.mcPointIds[0]].iStation;
if (iStation >= 0) hitIndices[iStation] = hitI;
}
for (int iH = 0; iH < algo->NStations; iH++) {
const int hitI = hitIndices[iH];
if (hitI < 0) continue;
// algo->fRecoHits.push_back(hitI);
algoTr.NHits++;
}
if (algoTr.NHits < 3) continue;
for (int iH = 0; iH < algo->NStations; iH++) {
const int hitI = hitIndices[iH];
if (hitI < 0) continue;
algo->fRecoHits.push_back(hitI);
}
algoTr.Momentum = MC.p;
algoTr.TFirst[0] = MC.x;
algoTr.TFirst[1] = MC.y;
algoTr.TFirst[2] = MC.px / MC.pz;
algoTr.TFirst[3] = MC.py / MC.pz;
algoTr.TFirst[4] = MC.q / MC.p;
algoTr.TFirst[5] = MC.z;
algo->fTracks.push_back(algoTr);
}
} // void CbmL1::IdealTrackFinder()
/// ----- STandAlone Package service-functions -----------------------------
void CbmL1::WriteSTAPGeoData(const L1Vector<float>& geo_)
{
// write geo in file
TString fgeo_name = fSTAPDataDir + "geo_algo.txt";
std::ofstream fgeo(fgeo_name);
fgeo.setf(ios::scientific, ios::floatfield);
fgeo.precision(20);
int size = geo_.size();
for (int i = 0; i < size; i++) {
fgeo << geo_[i] << endl;
};
fgeo.close();
cout << "-I- CbmL1: Geometry data has been written in " << fgeo_name << endl;
} // void CbmL1::WriteSTAPGeoData(void* geo_, int size)
void CbmL1::WriteSTAPAlgoData() // must be called after ReadEvent
{
// write algo data in file
static int vNEvent = 1;
std::fstream fadata;
TString fadata_name = fSTAPDataDir + "data_algo.txt";
// if ( vNEvent <= maxNEvent ) {
if (1) {
if (vNEvent == 1) fadata.open(fadata_name, std::fstream::out); // begin new file
else
fadata.open(fadata_name, std::fstream::out | std::fstream::app);
fadata << "Event:"
<< " ";
fadata << vNEvent << endl;
// write vStsStrips
int n = algo->NStsStrips;
fadata << n << endl;
if (fVerbose >= 4) {
cout << "vStsStrips[" << n << "]"
<< " have been written." << endl;
}
// write fStripFlag
n = (*algo->fStripFlag).size();
fadata << n << endl;
unsigned char element;
for (int i = 0; i < n; i++) {
element = (*algo->fStripFlag)[i];
fadata << static_cast<int>(element) << endl;
};
if (fVerbose >= 4) {
cout << "fStripFlag[" << n << "]"
<< " have been written." << endl;
}
if (fVerbose >= 4) {
cout << "fStripFlagB[" << n << "]"
<< " have been written." << endl;
}
// write vStsHits
n = (*algo->vStsHits).size();
fadata << n << endl;
for (int i = 0; i < n; i++) {
const L1Hit& h = (*algo->vStsHits)[i];
fadata << static_cast<int>(h.f) << " ";
fadata << static_cast<int>(h.b) << " ";
#ifdef USE_EVENT_NUMBER
fadata << static_cast<unsigned short int>(h.n) << " ";
#endif
fadata << h.z << " ";
fadata << h.u << " ";
fadata << h.v << " ";
// fadata << (*algo->vStsHits)[i].time << endl;
fadata << h.t << endl;
};
if (fVerbose >= 4) {
cout << "vStsHits[" << n << "]"
<< " have been written." << endl;
}
// write StsHitsStartIndex and StsHitsStopIndex
n = 20;
for (int i = 0; i < n; i++) {
if (int(L1Parameters::kMaxNstations) + 1 > i) { fadata << algo->StsHitsStartIndex[i] << endl; }
else {
fadata << 0 << endl;
}
};
for (int i = 0; i < n; i++) {
if (int(L1Parameters::kMaxNstations) + 1 > i) fadata << algo->StsHitsStopIndex[i] << endl;
else
fadata << 0 << endl;
};
fadata.close();
}
cout << "-I- CbmL1: CATrackFinder data for event number " << vNEvent << " have been written in file " << fadata_name
<< endl;
vNEvent++;
} // void CbmL1::WriteSTAPAlgoData()
void CbmL1::WriteSTAPPerfData() // must be called after ReadEvent
{
std::fstream fpdata;
fpdata << std::setprecision(8);
static int vNEvent = 1;
TString fpdata_name = fSTAPDataDir + "data_perfo.txt";
// write data for performance in file
// if ( vNEvent <= maxNEvent ) {
if (1) {
if (vNEvent == 1) fpdata.open(fpdata_name, std::fstream::out); // begin new file
else
fpdata.open(fpdata_name, std::fstream::out | std::fstream::app);
fpdata << "Event: ";
fpdata << vNEvent << endl;
// write vMCPoints
Int_t n = vMCPoints.size(); // number of elements
fpdata << n << endl;
for (int i = 0; i < n; i++) {
fpdata << vMCPoints[i].xIn << " ";
fpdata << vMCPoints[i].yIn << " ";
fpdata << vMCPoints[i].zIn << " ";
fpdata << vMCPoints[i].pxIn << " ";
fpdata << vMCPoints[i].pyIn << " ";
fpdata << vMCPoints[i].pzIn << " " << endl;
fpdata << vMCPoints[i].xOut << " ";
fpdata << vMCPoints[i].yOut << " ";
fpdata << vMCPoints[i].zOut << " ";
fpdata << vMCPoints[i].pxOut << " ";
fpdata << vMCPoints[i].pyOut << " ";
fpdata << vMCPoints[i].pzOut << " " << endl;
fpdata << vMCPoints[i].p << " ";
fpdata << vMCPoints[i].q << " ";
fpdata << vMCPoints[i].mass << " ";
fpdata << vMCPoints[i].time << " ";
fpdata << vMCPoints[i].pdg << " ";
fpdata << vMCPoints[i].ID << " ";
fpdata << vMCPoints[i].mother_ID << " ";
fpdata << vMCPoints[i].iStation << endl;
const int nhits = vMCPoints[i].hitIds.size();
fpdata << nhits << endl << " ";
for (int k = 0; k < nhits; k++) {
fpdata << vMCPoints[i].hitIds[k] << " ";
};
fpdata << endl;
};
if (fVerbose >= 4) {
cout << "vMCPoints[" << n << "]"
<< " have been written." << endl;
}
// write vMCTracks . without Points
n = vMCTracks.size(); // number of elements
fpdata << n << endl;
for (int i = 0; i < n; i++) {
fpdata << vMCTracks[i].x << " ";
fpdata << vMCTracks[i].y << " ";
fpdata << vMCTracks[i].z << " ";
fpdata << vMCTracks[i].px << " ";
fpdata << vMCTracks[i].py << " ";
fpdata << vMCTracks[i].pz << " ";
fpdata << vMCTracks[i].p << " ";
fpdata << vMCTracks[i].q << " ";
fpdata << vMCTracks[i].mass << " ";
fpdata << vMCTracks[i].time << " ";
fpdata << vMCTracks[i].pdg << " ";
fpdata << vMCTracks[i].ID << " ";
fpdata << vMCTracks[i].mother_ID << endl;
int nhits = vMCTracks[i].StsHits.size();
fpdata << " " << nhits << endl << " ";
for (int k = 0; k < nhits; k++) {
fpdata << vMCTracks[i].StsHits[k] << " ";
};
fpdata << endl;
const int nPoints = vMCTracks[i].Points.size();
fpdata << nPoints << endl << " ";
for (int k = 0; k < nPoints; k++) {
fpdata << vMCTracks[i].Points[k] << " ";
};
fpdata << endl;
fpdata << vMCTracks[i].nMCContStations << " ";
fpdata << vMCTracks[i].nHitContStations << " ";
fpdata << vMCTracks[i].maxNStaMC << " ";
fpdata << vMCTracks[i].maxNSensorMC << " ";
fpdata << vMCTracks[i].maxNStaHits << " ";
fpdata << vMCTracks[i].nStations << endl;
};
if (fVerbose >= 4) {
cout << "vMCTracks[" << n << "]"
<< " have been written." << endl;
}
// write vHitMCRef
n = vHitMCRef.size(); // number of elements
fpdata << n << endl;
for (int i = 0; i < n; i++) {
fpdata << vHitMCRef[i] << endl;
};
if (fVerbose >= 4) {
cout << "vHitMCRef[" << n << "]"
<< " have been written." << endl;
}
// write vHitStore
n = vHitStore.size(); // number of elements
fpdata << n << endl;
for (int i = 0; i < n; i++) {
fpdata << vHitStore[i].ExtIndex << " ";
fpdata << vHitStore[i].iStation << " ";
fpdata << vHitStore[i].x << " ";
fpdata << vHitStore[i].y << endl;
};
if (fVerbose >= 4) {
cout << "vHitStore[" << n << "]"
<< " have been written." << endl;
}
// write vStsHits
n = vStsHits.size(); // number of elements
fpdata << n << endl;
for (int i = 0; i < n; i++) {
fpdata << vStsHits[i].hitId << " ";
fpdata << vStsHits[i].extIndex << endl;
const int nPoints = vStsHits[i].mcPointIds.size();
fpdata << nPoints << endl << " ";
for (int k = 0; k < nPoints; k++) {
fpdata << vStsHits[i].mcPointIds[k] << " ";
};
fpdata << endl;
};
if (fVerbose >= 4) {
cout << "vStsHits[" << n << "]"
<< " have been written." << endl;
}
fpdata.close();
}
cout << "-I- CbmL1: Data for performance of event number " << vNEvent << " have been written in file " << fpdata_name
<< endl;
vNEvent++;
} // void CbmL1::WriteSTAPPerfData()
std::istream& CbmL1::eatwhite(std::istream& is) // skip spaces
{
char c;
while (is.get(c)) {
if (isspace(c) == 0) {
is.putback(c);
break;
}
}
return is;
}
//void CbmL1::ReadSTAPGeoData(L1Vector<float> geo_, int &size)
//void CbmL1::ReadSTAPGeoData(L1Vector<fscal> geo_, int &size)
void CbmL1::ReadSTAPGeoData(L1Vector<fscal>& geo_, int& size)
{
TString fgeo_name = fSTAPDataDir + "geo_algo.txt";
std::ifstream fgeo(fgeo_name);
cout << "-I- CbmL1: Read geometry from file " << fgeo_name << endl;
int i;
for (i = 0; !fgeo.eof(); i++) {
fscal tmp;
fgeo >> tmp >> eatwhite;
cout << " geo_[" << i << "]=" << geo_[i] << " tmp= " << tmp << endl;
geo_[i] = tmp;
};
size = i;
fgeo.close();
} // void CbmL1::ReadSTAPGeoData(void* geo_, int &size)
void CbmL1::ReadSTAPAlgoData()
{
static int nEvent = 1;
static std::fstream fadata;
TString fadata_name = fSTAPDataDir + "data_algo.txt";
// if (nEvent <= maxNEvent){
if (1) {
if (nEvent == 1) fadata.open(fadata_name, std::fstream::in);
if (algo->vStsHits) algo->vStsHits->clear();
algo->NStsStrips = 0;
if (algo->fStripFlag) algo->fStripFlag->clear();
// check correct position in file
char s[] = "Event: ";
int nEv;
fadata >> s;
fadata >> nEv;
if (nEv != nEvent) cout << "-E- CbmL1: Can't read event number " << nEvent << " from file " << fadata_name << endl;
int n; // number of elements
// read algo->vStsStrips
fadata >> n;
cout << " n " << n << endl;
algo->NStsStrips = n;
if (fVerbose >= 4) {
cout << "vStsStrips[" << n << "]"
<< " have been read." << endl;
}
// read algo->fStripFlag
fadata >> n;
for (int i = 0; i < n; i++) {
int element;
fadata >> element;
algo->fStripFlag->push_back(static_cast<unsigned char>(element));
}
if (fVerbose >= 4) {
cout << "fStripFlag[" << n << "]"
<< " have been read." << endl;
}
// read algo->vStsHits
fadata >> n;
int element_f; // for convert
int element_b;
int element_n;
for (int i = 0; i < n; i++) {
L1Hit element;
fadata >> element_f >> element_b >> element_n >> element.z >> element.u >> element.v >> element.t;
element.f = static_cast<THitI>(element_f);
element.b = static_cast<THitI>(element_b);
algo->vStsHits->push_back(element);
}
if (fVerbose >= 4) {
cout << "vStsHits[" << n << "]"
<< " have been read." << endl;
}
// read StsHitsStartIndex and StsHitsStopIndex
n = 20; // TODO: Why 20?
for (int i = 0; i < n; i++) {
int tmp;
fadata >> tmp;
if (int(L1Parameters::kMaxNstations) + 1 > i) (const_cast<unsigned int&>(algo->StsHitsStartIndex[i]) = tmp);
}
for (int i = 0; i < n; i++) {
int tmp;
fadata >> tmp;
if (int(L1Parameters::kMaxNstations) + 1 > i) (const_cast<unsigned int&>(algo->StsHitsStopIndex[i]) = tmp);
}
cout << "-I- CbmL1: CATrackFinder data for event " << nEvent << " has been read from file " << fadata_name
<< " successfully." << endl;
}
nEvent++;
} // void CbmL1::ReadSTAPAlgoData()
void CbmL1::ReadSTAPPerfData()
{
static int nEvent = 1;
static std::fstream fpdata;
TString fpdata_name = fSTAPDataDir + "data_perfo.txt";
// if (nEvent <= maxNEvent){
if (1) {
if (nEvent == 1) { fpdata.open(fpdata_name, std::fstream::in); };
vMCPoints.clear();
vMCTracks.clear();
vHitMCRef.clear();
vHitStore.clear();
vStsHits.clear();
dFEI2vMCPoints.clear();
dFEI2vMCTracks.clear();
// check if it is right position in file
char s[] = "EVENT: "; // buffer
int nEv = 0; // event number
fpdata >> s;
fpdata >> nEv;
if (nEv != nEvent)
cout << "-E- CbmL1: Performance: can't read event number " << nEvent << " from file "
<< "data_perfo.txt" << endl;
// vMCPoints
int n; // number of elements
fpdata >> n;
for (int i = 0; i < n; i++) {
CbmL1MCPoint element;
fpdata >> element.xIn;
fpdata >> element.yIn;
fpdata >> element.zIn;
fpdata >> element.pxIn;
fpdata >> element.pyIn;
fpdata >> element.pzIn;
fpdata >> element.xOut;
fpdata >> element.yOut;
fpdata >> element.zOut;
fpdata >> element.pxOut;
fpdata >> element.pyOut;
fpdata >> element.pzOut;
fpdata >> element.p;
fpdata >> element.q;
fpdata >> element.mass;
fpdata >> element.time;
fpdata >> element.pdg;
fpdata >> element.ID;
fpdata >> element.mother_ID;
fpdata >> element.iStation;
int nhits;
fpdata >> nhits;
for (int k = 0; k < nhits; k++) {
int helement;
fpdata >> helement;
element.hitIds.push_back(helement);
};
vMCPoints.push_back(element);
};
if (fVerbose >= 4) {
cout << "vMCPoints[" << n << "]"
<< " have been read." << endl;
}
// vMCTracks . without Points
fpdata >> n;
for (int i = 0; i < n; i++) {
CbmL1MCTrack element;
fpdata >> element.x;
fpdata >> element.y;
fpdata >> element.z;
fpdata >> element.px;
fpdata >> element.py;
fpdata >> element.pz;
fpdata >> element.p;
fpdata >> element.q;
fpdata >> element.mass;
fpdata >> element.time;
fpdata >> element.pdg;
fpdata >> element.ID;
fpdata >> element.mother_ID;
int nhits;
fpdata >> nhits;
for (int k = 0; k < nhits; k++) {
int helement;
fpdata >> helement;
element.StsHits.push_back(helement);
};
fpdata >> nhits;
for (int k = 0; k < nhits; k++) {
int helement;
fpdata >> helement;
element.Points.push_back(helement);
};
fpdata >> element.nMCContStations;
fpdata >> element.nHitContStations;
fpdata >> element.maxNStaMC;
fpdata >> element.maxNSensorMC;
fpdata >> element.maxNStaHits;
fpdata >> element.nStations;
element.CalculateIsReconstructable();
vMCTracks.push_back(element);
};
if (fVerbose >= 4) {
cout << "vMCTracks[" << n << "]"
<< " have been read." << endl;
}
// vHitMCRef
fpdata >> n;
vHitMCRef.reserve(n);
for (int i = 0; i < n; i++) {
int element;
fpdata >> element;
vHitMCRef.push_back(element);
};
if (fVerbose >= 4) {
cout << "vHitMCRef[" << n << "]"
<< " have been read." << endl;
}
// vHitStore
fpdata >> n;
vHitStore.reserve(n);
for (int i = 0; i < n; i++) {
CbmL1HitStore element;
fpdata >> element.ExtIndex;
fpdata >> element.iStation;
fpdata >> element.x;
fpdata >> element.y;
vHitStore.push_back(element);
};
if (fVerbose >= 4) {
cout << "vHitStore[" << n << "]"
<< " have been read." << endl;
}
// vStsHits
fpdata >> n;
for (int i = 0; i < n; i++) {
CbmL1Hit element;
fpdata >> element.hitId;
fpdata >> element.extIndex;
int nPoints;
fpdata >> nPoints;
for (int k = 0; k < nPoints; k++) {
int id;
fpdata >> id;
element.mcPointIds.push_back(id);
};
vStsHits.push_back(element);
};
if (fVerbose >= 4) {
cout << "vStsHits[" << n << "]"
<< " have been read." << endl;
}
// if (nEvent == maxNEvent) { // file open on begin of all work class and close at end
// fpdata.close();
// cout << " -I- Performance: data read from file " << "data_perfo.txt" << " successfully"<< endl;
// }
cout << "-I- CbmL1: L1Performance data for event " << nEvent << " has been read from file " << fpdata_name
<< " successfully." << endl;
} // if (nEvent <= maxNEvent)
nEvent++;
} // void CbmL1::ReadSTAPPerfData()
void CbmL1::WriteSIMDKFData()
{
static bool first = 1;
/// Write geometry info
if (first) {
FairField* dMF = CbmKF::Instance()->GetMagneticField();
std::fstream FileGeo;
FileGeo.open("geo.dat", ios::out);
std::fstream FieldCheck;
FieldCheck.open("field.dat", ios::out);
Double_t bfg[3], rfg[3];
rfg[0] = 0.;
rfg[1] = 0.;
rfg[2] = 0.;
dMF->GetFieldValue(rfg, bfg);
FileGeo << rfg[2] << " " << bfg[0] << " " << bfg[1] << " " << bfg[2] << " " << endl;
rfg[0] = 0.;
rfg[1] = 0.;
rfg[2] = 2.5;
dMF->GetFieldValue(rfg, bfg);
FileGeo << rfg[2] << " " << bfg[0] << " " << bfg[1] << " " << bfg[2] << " " << endl;
rfg[0] = 0.;
rfg[1] = 0.;
rfg[2] = 5.0;
dMF->GetFieldValue(rfg, bfg);
FileGeo << rfg[2] << " " << bfg[0] << " " << bfg[1] << " " << bfg[2] << " " << endl << endl;
FileGeo << NStation << endl;
const int M = 5; // polinom order
const int N = (M + 1) * (M + 2) / 2;
for (Int_t ist = 0; ist < NStation; ist++) {
fscal f_phi, f_sigma, b_phi, b_sigma;
double C[3][N];
double z = 0;
double Xmax, Ymax;
if (ist < NMvdStations) {
CbmKFTube& t = CbmKF::Instance()->vMvdMaterial[ist];
f_phi = 0;
f_sigma = 5.e-4;
b_phi = 3.14159265358 / 2.;
b_sigma = 5.e-4;
z = t.z;
Xmax = Ymax = t.R;
}
else {
CbmStsStation* station = CbmStsSetup::Instance()->GetStation(ist - NMvdStations);
f_phi = station->GetSensorRotation();
b_phi = f_phi;
double Pi = 3.14159265358;
f_phi += station->GetSensorStereoAngle(0) * Pi / 180.;
b_phi += station->GetSensorStereoAngle(1) * Pi / 180.;
f_sigma = station->GetSensorPitch(0) / TMath::Sqrt(12);
b_sigma = f_sigma;
//f_sigma *= cos(f_phi); // TODO: think about this
//b_sigma *= cos(b_phi);
z = station->GetZ();
Xmax = station->GetXmax();
Ymax = station->GetYmax();
}
double dx = 1.; // step for the field approximation
double dy = 1.;
if (dx > Xmax / N / 2) dx = Xmax / N / 4.;
if (dy > Ymax / N / 2) dy = Ymax / N / 4.;
for (int i = 0; i < 3; i++)
for (int k = 0; k < N; k++)
C[i][k] = 0;
TMatrixD A(N, N);
TVectorD b0(N), b1(N), b2(N);
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++)
A(i, j) = 0.;
b0(i) = b1(i) = b2(i) = 0.;
}
for (double x = -Xmax; x <= Xmax; x += dx)
for (double y = -Ymax; y <= Ymax; y += dy) {
double r = sqrt(fabs(x * x / Xmax / Xmax + y / Ymax * y / Ymax));
if (r > 1.) continue;
Double_t w = 1. / (r * r + 1);
Double_t p[3] = {x, y, z};
Double_t B[3] = {0., 0., 0.};
CbmKF::Instance()->GetMagneticField()->GetFieldValue(p, B);
TVectorD m(N);
m(0) = 1;
for (int i = 1; i <= M; i++) {
int k = (i - 1) * (i) / 2;
int l = i * (i + 1) / 2;
for (int j = 0; j < i; j++)
m(l + j) = x * m(k + j);
m(l + i) = y * m(k + i - 1);
}
TVectorD mt = m;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++)
A(i, j) += w * m(i) * m(j);
b0(i) += w * B[0] * m(i);
b1(i) += w * B[1] * m(i);
b2(i) += w * B[2] * m(i);
}
}
double det;
A.Invert(&det);
TVectorD c0 = A * b0, c1 = A * b1, c2 = A * b2;
for (int i = 0; i < N; i++) {
C[0][i] = c0(i);
C[1][i] = c1(i);
C[2][i] = c2(i);
}
double c_f = cos(f_phi);
double s_f = sin(f_phi);
double c_b = cos(b_phi);
double s_b = sin(b_phi);
double det_m = c_f * s_b - s_f * c_b;
det_m *= det_m;
// double C00 = ( s_b*s_b*f_sigma*f_sigma + s_f*s_f*b_sigma*b_sigma )/det_m;
// double C10 =-( s_b*c_b*f_sigma*f_sigma + s_f*c_f*b_sigma*b_sigma )/det_m;
// double C11 = ( c_b*c_b*f_sigma*f_sigma + c_f*c_f*b_sigma*b_sigma )/det_m;
// float delta_x = sqrt(C00);
// float delta_y = sqrt(C11);
FileGeo << " " << ist << " ";
if (ist < NMvdStations) {
CbmKFTube& t = CbmKF::Instance()->vMvdMaterial[ist];
FileGeo << t.z << " ";
FileGeo << t.dz << " ";
FileGeo << t.RadLength << " ";
}
else if (ist < (NStsStations + NMvdStations)) {
CbmStsStation* station = CbmStsSetup::Instance()->GetStation(ist - NMvdStations);
FileGeo << station->GetZ() << " ";
FileGeo << station->GetSensorD() << " ";
FileGeo << station->GetRadLength() << " ";
}
FileGeo << f_sigma << " ";
FileGeo << b_sigma << " ";
FileGeo << f_phi << " ";
FileGeo << b_phi << endl;
FileGeo << " " << N << endl;
FileGeo << " ";
for (int ik = 0; ik < N; ik++)
FileGeo << C[0][ik] << " ";
FileGeo << endl;
FileGeo << " ";
for (int ik = 0; ik < N; ik++)
FileGeo << C[1][ik] << " ";
FileGeo << endl;
FileGeo << " ";
for (int ik = 0; ik < N; ik++)
FileGeo << C[2][ik] << " ";
FileGeo << endl;
}
FileGeo.close();
}
///Write Tracks and MC Tracks
static int TrNumber = 0;
std::fstream Tracks, McTracksCentr, McTracksIn, McTracksOut;
if (first) {
Tracks.open("tracks.dat", std::fstream::out);
McTracksCentr.open("mctrackscentr.dat", std::fstream::out);
McTracksIn.open("mctracksin.dat", std::fstream::out);
McTracksOut.open("mctracksout.dat", std::fstream::out);
first = 0;
}
else {
Tracks.open("tracks.dat", std::fstream::out | std::fstream::app);
McTracksCentr.open("mctrackscentr.dat", std::fstream::out | std::fstream::app);
McTracksIn.open("mctracksin.dat", std::fstream::out | std::fstream::app);
McTracksOut.open("mctracksout.dat", std::fstream::out | std::fstream::app);
}
for (L1Vector<CbmL1Track>::iterator RecTrack = vRTracks.begin(); RecTrack != vRTracks.end(); ++RecTrack) {
if (RecTrack->IsGhost()) continue;
CbmL1MCTrack* MCTrack = RecTrack->GetMCTrack();
if (!(MCTrack->IsPrimary())) continue;
int NHits = (RecTrack->StsHits).size();
float x[20], y[20], z[20];
int st[20];
int jHit = 0;
for (int iHit = 0; iHit < NHits; iHit++) {
CbmL1HitStore& h = vHitStore[RecTrack->StsHits[iHit]];
st[jHit] = h.iStation;
if (h.ExtIndex < 0) {
CbmMvdHit* MvdH = (CbmMvdHit*) listMvdHits->At(-h.ExtIndex - 1);
x[jHit] = MvdH->GetX();
y[jHit] = MvdH->GetY();
z[jHit] = MvdH->GetZ();
jHit++;
}
else {
CbmStsHit* StsH = (CbmStsHit*) listStsHits->At(h.ExtIndex);
x[jHit] = StsH->GetX();
y[jHit] = StsH->GetY();
z[jHit] = StsH->GetZ();
jHit++;
}
}
Tracks << TrNumber << " " << MCTrack->x << " " << MCTrack->y << " " << MCTrack->z << " " << MCTrack->px << " "
<< MCTrack->py << " " << MCTrack->pz << " " << MCTrack->q << " " << NHits << endl;
float AngleXAxis = 0, AngleYAxis = 0;
for (int i = 0; i < NHits; i++)
Tracks << " " << st[i] << " " << x[i] << " " << y[i] << " " << z[i] << " " << AngleXAxis << " " << AngleYAxis
<< endl;
Tracks << endl;
int NMCPoints = (MCTrack->Points).size();
McTracksIn << TrNumber << " " << MCTrack->x << " " << MCTrack->y << " " << MCTrack->z << " " << MCTrack->px << " "
<< MCTrack->py << " " << MCTrack->pz << " " << MCTrack->q << " " << NMCPoints << endl;
McTracksOut << TrNumber << " " << MCTrack->x << " " << MCTrack->y << " " << MCTrack->z << " " << MCTrack->px << " "
<< MCTrack->py << " " << MCTrack->pz << " " << MCTrack->q << " " << NMCPoints << endl;
McTracksCentr << TrNumber << " " << MCTrack->x << " " << MCTrack->y << " " << MCTrack->z << " " << MCTrack->px
<< " " << MCTrack->py << " " << MCTrack->pz << " " << MCTrack->q << " " << NMCPoints << endl;
for (int iPoint = 0; iPoint < NMCPoints; iPoint++) {
CbmL1MCPoint& MCPoint = vMCPoints[MCTrack->Points[iPoint]];
McTracksIn << " " << MCPoint.iStation << " " << MCPoint.xIn << " " << MCPoint.yIn << " " << MCPoint.zIn << " "
<< MCPoint.pxIn << " " << MCPoint.pyIn << " " << MCPoint.pzIn << endl;
McTracksOut << " " << MCPoint.iStation << " " << MCPoint.xOut << " " << MCPoint.yOut << " " << MCPoint.zOut
<< " " << MCPoint.pxOut << " " << MCPoint.pyOut << " " << MCPoint.pzOut << endl;
McTracksCentr << " " << MCPoint.iStation << " " << MCPoint.x << " " << MCPoint.y << " " << MCPoint.z << " "
<< MCPoint.px << " " << MCPoint.py << " " << MCPoint.pz << endl;
}
McTracksIn << endl;
McTracksOut << endl;
McTracksCentr << endl;
TrNumber++;
}
}