15#include "TRestGeant4EventViewer.h" 
   17#include <TRestStringOutput.h> 
   23TRestGeant4EventViewer::TRestGeant4EventViewer() { Initialize(); }
 
   25TRestGeant4EventViewer::~TRestGeant4EventViewer() {
 
   29void TRestGeant4EventViewer::Initialize() {
 
   33    fHitConnectors.clear();
 
   34    fHitConnectors.push_back(
nullptr);
 
   37void TRestGeant4EventViewer::DeleteCurrentEvent() {
 
   38    TRestEveEventViewer::DeleteCurrentEvent();
 
   39    fG4Metadata = 
nullptr;
 
   41    fHitConnectors.clear();
 
   42    fHitConnectors.push_back(
nullptr);
 
   46    Color_t fColor = kWhite;
 
   47    Style_t fLineStyle = 1;
 
   48    Width_t fLineWidth = 4.0;
 
 
   54    const auto particleName = track.GetParticleName();
 
   55    if (particleName == 
"geantino") {
 
   57        config.fLineStyle = 9;
 
   58        config.fLineWidth = 2;
 
   62    if (particleName.Contains(
'-')) {
 
   63        config.fColor = kMagenta;  
 
   64    } 
else if (particleName.Contains(
'+')) {
 
   65        config.fColor = kAzure;
 
   68    if (particleName == 
"neutron") {
 
   69        config.fColor = kOrange;  
 
   70    } 
else if (particleName == 
"gamma") {
 
   71        config.fColor = kGreen;  
 
   72    } 
else if (particleName == 
"e-") {
 
   74    } 
else if (particleName == 
"mu-") {
 
   75        config.fColor = kGray;  
 
   76    } 
else if (particleName == 
"alpha") {
 
   77        config.fColor = kYellow;  
 
   81    Width_t width = TMath::Log10(track.GetInitialKineticEnergy() / 100);
 
   82    width = (width > 10 ? 10 : width);
 
   83    width = (width < 1 ? 1 : width);
 
   84    config.fLineWidth = TMath::Log10(track.GetInitialKineticEnergy() / 10);
 
   88    if (track.GetCreatorProcess() == 
"nCapture") {
 
   89        config.fLineStyle = 2;
 
   95TEveStraightLineSet* TRestGeant4EventViewer::GetTrackEveDrawable(
const TRestGeant4Track& track) {
 
   96    auto lineSet = 
new TEveStraightLineSet(
 
   97        TString::Format(
"ID %d | %s | Created by %s | KE: %s",  
 
   98                        track.GetTrackID(), track.GetParticleName().Data(), track.GetCreatorProcess().Data(),
 
   99                        ToEnergyString(track.GetInitialKineticEnergy()).c_str()));
 
  101    const auto& hits = track.GetHits();
 
  102    for (
unsigned int i = 0; i < hits.GetNumberOfHits() - 1; i++) {
 
  103        lineSet->AddLine({
static_cast<float>(fGeomScale * hits.GetPosition(i).x()),
 
  104                          static_cast<float>(fGeomScale * hits.GetPosition(i).y()),
 
  105                          static_cast<float>(fGeomScale * hits.GetPosition(i).z())},  
 
  106                         {
static_cast<float>(fGeomScale * hits.GetPosition(i + 1).x()),
 
  107                          static_cast<float>(fGeomScale * hits.GetPosition(i + 1).y()),
 
  108                          static_cast<float>(fGeomScale * hits.GetPosition(i + 1).z())});
 
  110        const auto config = GetTrackVisualConfiguration(track);
 
  111        lineSet->SetMainColor(config.fColor);
 
  112        lineSet->SetLineColor(config.fColor);
 
  113        lineSet->SetLineStyle(config.fLineStyle);
 
  114        lineSet->SetLineWidth(config.fLineWidth);
 
  121    Color_t fColor = kBlack;
 
  122    Style_t fMarkerStyle = 1;
 
  123    Size_t fMarkerSize = 1.0;
 
 
  129    if (processNameOrType.EqualTo(
"Electromagnetic")) {
 
  130        config.fColor = kRed;
 
  131    } 
else if (processNameOrType.EqualTo(
"Init")) {
 
  133        config.fColor = kWhite;
 
  137    if (processNameOrType.EqualTo(
"Transportation")) {
 
  138        config.fColor = kWhite;
 
  139    } 
else if (processNameOrType.EqualTo(
"Init")) {
 
  141        config.fColor = kWhite;
 
  142    } 
else if (processNameOrType.EqualTo(
"hadElastic")) {
 
  143        config.fColor = kOrange;
 
  144    } 
else if (processNameOrType.EqualTo(
"neutronInelastic")) {
 
  145        config.fColor = kGreen;
 
  146        config.fMarkerStyle = 4;
 
  147    } 
else if (processNameOrType.EqualTo(
"nCapture")) {
 
  148        config.fColor = kBlue;
 
  149        config.fMarkerStyle = 2;
 
  150        config.fMarkerSize = 4.0;
 
  155void TRestGeant4EventViewer::AddEvent(
TRestEvent* event) {
 
  156    DeleteCurrentEvent();
 
  159    fG4Metadata = fG4Event->GetGeant4Metadata();
 
  160    if (fG4Metadata == 
nullptr) {
 
  161        cerr << 
"TRestGeant4EventViewer::Initialize. No TRestGeant4Metadata found in TRestGeant4Event" 
  166    size_t trackCounter = 0;
 
  167    size_t hitsCounter = 0;
 
  169    map<Int_t, TEveStraightLineSet*> linesSet;
 
  170    map<TString, TEvePointSet*> hitsPoints;
 
  171    map<TString, TEveElementList*> hitsType;
 
  173    auto trackList = 
new TEveElementList(
"Tracks");
 
  174    gEve->AddElement(trackList);
 
  175    auto hitsList = 
new TEveElementList(
"Hits");
 
  176    gEve->AddElement(hitsList);
 
  180    for (
const auto& track : fG4Event->GetTracks()) {
 
  181        if (track.GetInitialKineticEnergy() < 1.0 || track.GetLength() < 0.1) {
 
  185        auto line = GetTrackEveDrawable(track);
 
  186        linesSet[track.GetTrackID()] = line;
 
  187        TEveElement* parentLine = trackList;
 
  188        if (linesSet.count(track.GetParentID())) {
 
  189            parentLine = linesSet.at(track.GetParentID());
 
  191        gEve->AddElement(line, parentLine);
 
  194        const auto& hits = track.GetHits();
 
  195        for (
unsigned int i = 0; i < hits.GetNumberOfHits(); i++) {
 
  196            const auto& processName = physicsInfo.GetProcessName(hits.GetProcess(i));
 
  197            const auto& processType = physicsInfo.GetProcessType(processName);
 
  198            const auto& position = hits.GetPosition(i);
 
  200            if (hitsType.count(processType) == 0) {
 
  201                hitsType[processType] = 
new TEveElementList(processType);
 
  202                gEve->AddElement(hitsType[processType], hitsList);
 
  204            if (hitsPoints.count(processName) == 0) {
 
  205                hitsPoints[processName] = 
new TEvePointSet(processName);
 
  206                auto hitPoints = hitsPoints.at(processName);
 
  207                auto hitsVisualConfig = GetHitsVisualConfiguration(processName);
 
  208                hitPoints->SetMarkerColor(hitsVisualConfig.fColor);
 
  209                hitPoints->SetMarkerStyle(hitsVisualConfig.fMarkerStyle);
 
  210                hitPoints->SetMarkerSize(hitsVisualConfig.fMarkerSize);
 
  212                gEve->AddElement(hitPoints, hitsType[processType]);
 
  214            hitsPoints.at(processName)
 
  215                ->SetNextPoint(fGeomScale * position.X(), fGeomScale * position.Y(),
 
  216                               fGeomScale * position.Z());
 
  222    const auto& firstTrack = fG4Event->GetTracks().front();
 
  223    TVector3 position = {firstTrack.GetInitialPosition().X(), firstTrack.GetInitialPosition().Y(),
 
  224                         firstTrack.GetInitialPosition().Z()};
 
  227            "Event ID: %d%s | Primary origin: (%4.2lf, %4.2lf, %4.2lf) mm", fG4Event->GetID(),
 
  228            (fG4Event->GetSubID() > 0 ? TString::Format(
" (SubID: %d)", fG4Event->GetSubID()) : 
"").Data(),
 
  229            position.X(), position.Y(), position.Z()),
 
  235void TRestGeant4EventViewer::AddText(TString text, TVector3 at) {
 
  236    TEveText* evText = 
new TEveText(text);
 
  237    evText->SetName(
"Event title");
 
  238    evText->SetFontSize(12);
 
  239    evText->RefMainTrans().SetPos((at.X() + 15) * fGeomScale, (at.Y() + 15) * fGeomScale,
 
  240                                  (at.Z() + 15) * fGeomScale);
 
  242    gEve->AddElement(evText);
 
  245void TRestGeant4EventViewer::AddMarker(Int_t trkID, TVector3 at, TString name) {
 
  246    TEvePointSet* marker = 
new TEvePointSet(1);
 
  247    marker->SetName(name);
 
  248    marker->SetMarkerColor(kMagenta);
 
  249    marker->SetMarkerStyle(3);
 
  250    marker->SetPoint(0, at.X() * fGeomScale, at.Y() * fGeomScale, at.Z() * fGeomScale);
 
  251    marker->SetMarkerSize(0.4);
 
  252    fHitConnectors[trkID]->AddElement(marker);
 
  255void TRestGeant4EventViewer::NextTrackVertex(Int_t trkID, TVector3 to) {
 
  256    fHitConnectors[trkID]->SetNextPoint(to.X() * fGeomScale, to.Y() * fGeomScale, to.Z() * fGeomScale);
 
  259void TRestGeant4EventViewer::AddTrack(Int_t trkID, Int_t parentID, TVector3 from, TString name) {
 
  260    TEveLine* evLine = 
new TEveLine();
 
  261    evLine->SetName(name);
 
  262    fHitConnectors.push_back(evLine);
 
  264    fHitConnectors[trkID]->SetMainColor(kWhite);
 
  265    fHitConnectors[trkID]->SetLineWidth(4);
 
  267    if (name.Contains(
"gamma")) fHitConnectors[trkID]->SetMainColor(kGreen);
 
  268    if (name.Contains(
"e-")) fHitConnectors[trkID]->SetMainColor(kRed);
 
  269    if (name.Contains(
"mu-")) fHitConnectors[trkID]->SetMainColor(kGray);
 
  270    if (name.Contains(
"alpha")) fHitConnectors[trkID]->SetMainColor(kYellow);
 
  271    if (name.Contains(
"neutron")) fHitConnectors[trkID]->SetMainColor(kBlue);
 
  273    fHitConnectors[trkID]->SetNextPoint(from.X() * fGeomScale, from.Y() * fGeomScale, from.Z() * fGeomScale);
 
  275    if (parentID >= 0 && fHitConnectors.size() > (
unsigned int)parentID)
 
  276        fHitConnectors[parentID]->AddElement(fHitConnectors[trkID]);
 
  278        RESTWarning << 
"Parent ID: " << parentID << 
" of track " << trkID << 
" was not found!" << RESTendl;
 
  279        RESTWarning << 
"This might be solved by enabling TRestGeant4Metadata::fRegisterEmptyTracks" 
  284void TRestGeant4EventViewer::AddParentTrack(Int_t trkID, TVector3 from, TString name) {
 
  285    TEveLine* evLine = 
new TEveLine();
 
  286    evLine->SetName(name);
 
  287    fHitConnectors.push_back(evLine);
 
  289    fHitConnectors[trkID]->SetMainColor(kWhite);
 
  290    fHitConnectors[trkID]->SetLineWidth(4);
 
  291    fHitConnectors[trkID]->SetNextPoint(from.X() * fGeomScale, from.Y() * fGeomScale, from.Z() * fGeomScale);
 
  293    gEve->AddElement(fHitConnectors[trkID]);
 
A base class for any REST event.
 
An event class to store geant4 generated event information.