diff --git a/Armory/ClassAnasen.h b/Armory/ClassAnasen.h index 90585b7..db892b7 100644 --- a/Armory/ClassAnasen.h +++ b/Armory/ClassAnasen.h @@ -41,6 +41,8 @@ public: PW * GetPW() {return pw;} SX3 * GetSX3() {return sx3;} + TGeoManager * GetGeoManager() {return geom;} + TGeoVolume * GetWorldBox() {return worldBox;} private: diff --git a/Armory/anasenMS.cpp b/Armory/anasenMS.cpp index af0427b..9e5c91c 100644 --- a/Armory/anasenMS.cpp +++ b/Armory/anasenMS.cpp @@ -86,6 +86,10 @@ int main(int argc, char **argv){ app = new TApplication("anasenVis", &argc, argv); } + // storage for tracks during simulation (for visualization) + std::vector visTrackVertex, visTrackDir, visTrackHitPos; + std::vector> visTrackWires; // {anodeID, cathodeID} + // create detector representation in memory ANASEN * anasen = new ANASEN(); // top-level detector object SX3 * sx3 = anasen->GetSX3(); // silicon array part @@ -257,6 +261,14 @@ int main(int argc, char **argv){ sx3Y = hitPos.Y(); sx3Z = hitPos.Z(); + // store track data for visualization if enabled + if(enableVis){ + visTrackVertex.push_back(vertex); + visTrackDir.push_back(dir); + visTrackHitPos.push_back(hitPos); + visTrackWires.push_back({anodeID[0], cathodeID[0]}); + } + // fill tree with original data before energy loss tree->Fill(); @@ -340,9 +352,57 @@ int main(int argc, char **argv){ printf("=============== done. saved as %s. tree entries: %d, tree2 entries: %d\n", saveFileName.Data(), count, count2); if(enableVis){ - printf("Displaying geometry via ANASEN::DrawAnasen()\n"); - anasen->DrawAnasen(); - anasen->DrawDeducedTrack(TVector3(sx3X, sx3Y, sx3Z), anodeID[0], cathodeID[0]); + printf("Displaying geometry with %zu tracks from simulation\n", visTrackVertex.size()); + + // Build full geometry with all wires + anasen->DrawAnasen(0, 23, 0, 23, -1, true); + + // Add all stored tracks to the geometry + TGeoManager *geom = anasen->GetGeoManager(); + TGeoVolume *worldBox = anasen->GetWorldBox(); + + if(geom && worldBox && visTrackVertex.size() > 0){ + int trackNodeID = 500; // start node IDs for tracks + + for(size_t iTrack = 0; iTrack < visTrackVertex.size(); ++iTrack){ + TVector3 vertex = visTrackVertex[iTrack]; + TVector3 dir = visTrackDir[iTrack]; + TVector3 hitPos = visTrackHitPos[iTrack]; + + double theta = dir.Theta() * TMath::RadToDeg(); + double phi = dir.Phi() * TMath::RadToDeg(); + + // Add a line marker at the vertex + TGeoVolume *startMarker = geom->MakeSphere("startMarker", 0, 0, 2.0); + startMarker->SetLineColor(kBlack); + worldBox->AddNode(startMarker, trackNodeID, + new TGeoCombiTrans(vertex.X(), vertex.Y(), vertex.Z(), + new TGeoRotation("rot", 0, 0, 0))); + trackNodeID++; + + // Add track line from vertex toward hit position + TGeoVolume *trackLine = geom->MakeTube("trackLine", 0, 0, 0.08, 150.0); + trackLine->SetLineColor(kBlue); + worldBox->AddNode(trackLine, trackNodeID, + new TGeoCombiTrans(vertex.X(), vertex.Y(), vertex.Z(), + new TGeoRotation("rotTrack", phi + 90, theta, 0))); + trackNodeID++; + + // Add hit position marker + TGeoVolume *hitMarker = geom->MakeSphere("hitMarker", 0, 0, 2.0); + hitMarker->SetLineColor(kRed); + worldBox->AddNode(hitMarker, trackNodeID, + new TGeoCombiTrans(hitPos.X(), hitPos.Y(), hitPos.Z(), + new TGeoRotation("rotHit", 0, 0, 0))); + trackNodeID++; + } + + // Redraw geometry with all tracks + geom->CloseGeometry(); + geom->SetVisLevel(4); + worldBox->Draw("ogle"); + } + if(app){ app->Run(); }