source: trunk/documents/UserDoc/UsersGuides/ForApplicationDeveloper/html/Visualization/compiledcontrol.html @ 1231

Last change on this file since 1231 was 1208, checked in by garnier, 15 years ago

CVS update

File size: 20.1 KB
Line 
1<HTML>
2<TITLE>Controlling Visualization from Compiled Code
3</TITLE>
4<!-- Changed by: Katsuya Dosanjh, 15-Jul-2000 -->
5<!-- Changed by: Dennis Wright, 27-Nov-2001 -->
6
7
8<!-- Proof read by: Joe Chuma,  6-Jul-1999 -->
9
10<!--  -->
11<!-- *spell, *tag, *contents, *s -->
12<BODY>
13
14<TABLE WIDTH="100%" >
15<TR>
16<TD>
17</A>
18<A HREF="index.html">
19<IMG SRC="../../../../resources/html/IconsGIF/Contents.gif" ALT="Contents" HEIGHT=16 WIDTH=59></A>
20<A HREF="commandcontrol.html">
21<IMG SRC="../../../../resources/html/IconsGIF/Previous.gif" ALT="Previous" HEIGHT=16 WIDTH=59></A>
22<a href="attributes.html">
23<IMG SRC="../../../../resources/html/IconsGIF/Next.gif" ALT="Next" HEIGHT=16 WIDTH=59></a>
24</TD>
25
26<TD ALIGN="Right"><FONT COLOR="#238E23"><FONT SIZE=-1>
27<B>Geant4 User's Guide</B> <BR>
28<B>For Application Developers</B> <BR>
29<B>Visualization</B> </FONT></FONT> </TD>
30</TR>
31</TABLE>
32
33<CENTER><FONT COLOR="#238E23"><FONT SIZE=+3>
34<b>8.5 Controlling Visualization from Compiled Code</b><BR>
35</FONT></FONT></CENTER>
36<BR>
37
38<HR ALIGN="Center" SIZE="7%"><BR>
39
40While a Geant4 simulation is running, visualization can be performed without
41user intervention.  This is accomplished by calling methods of the
42Visualization Manager from methods of the user action classes
43(<i>G4UserRunAction</i> and <i>G4UserEventAction</i>, for example). 
44In this section methods of the class <i>G4VVisManager</i>, which is part of
45the <tt>graphics_reps</tt> category, are described and examples of their use are
46given.
47
48
49<h4>8.5.1 Class <i>G4VVisManager</i></h4>
50
51The Visualization Manager is implemented by classes <i>G4VisManager</i> and
52<i>G4VisExecutive</i>.  See Section 8.2 "<b>Making a Visualization Executable</b>".
53In order that your Geant4 be compilable either with or without the visualization
54 category, you should not use these classes directly in your C++ source code,
55 other than in the <tt>main()</tt> function.
56 Instead, you should use their abstract base class <i>G4VVisManager</i>, defined in
57 the <tt>intercoms</tt> category.
58<P>
59 The pointer to the concrete instance of the real
60 Visualization Manager can be obtained as follows:
61 <PRE>
62  //----- Getting a pointer to the concrete Visualization Manager instance
63  G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
64 </PRE>
65<P>
66 The method <tt>G4VVisManager::GetConcreteInstance()</tt> returns <tt>NULL</tt> if Geant4 is
67 not ready for visualization.  Thus your C++ source code should be protected as follows:
68 <PRE>
69  //----- How to protect your C++ source codes in visualization
70  if (pVVisManager) {
71      ....
72      pVVisManager ->Draw (...);
73      ....
74  }
75 </PRE>
76<P>
77
78<P>
79
80<h4>8.5.2 Visualization of detector components</h4>
81
82 If you have already constructed detector components  with logical volumes
83 to which visualization attributes are properly assigned, you are almost ready
84 for visualizing detector components. 
85 All you have to do is to describe proper visualization commands
86 within your C++ codes, using the <tt>ApplyCommand()</tt> method.
87
88 <P>
89 For example,
90 the following is sample C++ source codes
91 to visualize the detector components:
92<PRE>
93  //----- C++ source code: How to visualize detector components (2)
94  //                       ... using visualization commands in source codes
95 
96  G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance() ;
97
98  if(pVVisManager)
99  {
100      ... (camera setting etc) ...
101      G4UImanager::GetUIpointer()->ApplyCommand("/vis/drawVolume");
102      G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/flush");
103  }
104
105  //-----  end of C++ source code
106 </PRE>
107In the above, you should also describe
108<tt>/vis/open</tt> command somewhere in your C++ codes or
109execute the command from (G)UI at the executing stage.
110<P>
111
112<h4>8.5.3 Visualization of trajectories</h4>
113
114 In order to visualize trajectories, you can use the method
115 <tt>void G4Trajectory::DrawTrajectory()</tt> defined in the tracking
116 category.
117 In the implementation of this method, the following drawing method of
118 <i>G4VVisManager</i> is used:
119 <PRE>
120    //----- A drawing method of G4Polyline
121    virtual void G4VVisManager::Draw (const G4Polyline&, ...) ;
122 </PRE>
123 The real implementation of this method is described in the class <i>G4VisManager</i>.
124<P>
125 At the end of one event, a set of trajectories can be stored as a list of
126 <i>G4Trajectory</i> objects.
127 Therefore you can visualize trajectories, for example, at the end of each event,
128 by implementing the method <tt>MyEventAction::EndOfEventAction()</tt> as follows:
129 <PRE>
130  //----- C++ source codes
131  void ExN03EventAction::EndOfEventAction(const G4Event* evt)
132  {
133    ..... 
134    // extract the trajectories and draw them
135    if (G4VVisManager::GetConcreteInstance())
136      {
137       G4TrajectoryContainer* trajectoryContainer = evt->GetTrajectoryContainer();
138       G4int n_trajectories = 0;
139       if (trajectoryContainer) n_trajectories = trajectoryContainer->entries();
140 
141       for (G4int i=0; i < n_trajectories; i++) 
142          { G4Trajectory* trj=(G4Trajectory*)((*(evt->GetTrajectoryContainer()))[i]);
143            if (drawFlag == "all") trj->DrawTrajectory(50);
144            else if ((drawFlag == "charged")&&(trj->GetCharge() != 0.))
145                                    trj->DrawTrajectory(50);
146            else if ((drawFlag == "neutral")&&(trj->GetCharge() == 0.))
147                                    trj->DrawTrajectory(50);
148          }
149    }
150  } 
151  //----- end of C++ source codes
152</PRE>
153
154<P>
155<h4>8.5.4 Enhanced trajectory drawing</h4>
156  It is possible to use the enhanced trajectory drawing functionality in compiled code as well as from commands.
157  Multiple trajectory models can be instantiated, configured and registered with G4VisManager.
158  For details, see the section on <A HREF="enhanceddrawing.html#compiledcontrol">Enhanced Trajectory Drawing</a>.
159
160<h4>8.5.5 HepRep Attributes for Trajectories</h4>
161The HepRep file formats, HepRepFile and HepRepXML, attach various attributes to trajectories
162such that you can view these attributes, label trajectories by these attributes
163or make visibility cuts based on these attributes.
164If you use the default Geant4 trajectory class, from /tracking/src/G4Trajectory.cc,
165available attributes will be:
166<UL>
167<LI>Track ID</li>
168<LI>Parent ID</li>
169<LI>Particle Name</li>
170<LI>Charge</li>
171<LI>PDG Encoding</li>
172<LI>Momentum 3-Vector</li>
173<LI>Momentum magnitude</li>
174<LI>Number of points</li>
175</UL>
176You can add additional attributes of your choosing by modifying the relevant part of G4Trajectory
177(look for the methods GetAttDefs and CreateAttValues).
178If you are using your own trajectory class,
179you may want to consider copying these methods from G4Trajectory.
180
181<h4>8.5.6 Visualization of hits</h4>
182
183 Hits are visualized with classes <i>G4Square</i> or <i>G4Circle</i>, or other
184 user-defined classes inheriting the abstract base class <i>G4VMarker</i>.
185 Drawing methods for hits are not supported by default. 
186 Instead, ways of their implementation are guided by virtual methods,
187 <tt>G4VHit::Draw()</tt> and  <tt>G4VHitsCollection::DrawAllHits()</tt>, of the
188 abstract base classes <i>G4VHit</i> and <i>G4VHitsCollection</i>.
189 These methods are defined as empty functions in the <tt>digits+hits</tt> category.
190 You can overload these methods, using the following drawing methods of class
191 <i>G4VVisManager</i>, in order to visualize hits:
192 <PRE>
193  //----- Drawing methods of G4Square and G4Circle
194  virtual void G4VVisManager::Draw (const G4Circle&, ...) ;
195  virtual void G4VVisManager::Draw (const G4Square&, ...) ;
196 </PRE>
197 The real implementations of these <tt>Draw()</tt> methods are described in class
198 <i>G4VisManager</i>.
199<P>
200 The overloaded implementation of <tt>G4VHits::Draw()</tt> will be held by, for example, 
201 class <i>MyTrackerHits</i> inheriting <i>G4VHit</i> as follows:
202 <PRE>
203  //----- C++ source codes: An example of giving concrete implementation of
204  //       G4VHit::Draw(), using  class MyTrackerHit : public G4VHit {...}
205  //     
206 void MyTrackerHit::Draw()
207 {
208    G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
209    if(pVVisManager)
210    {
211      // define a circle in a 3D space
212      G4Circle circle(pos);
213      circle.SetScreenSize(0.3);
214      circle.SetFillStyle(G4Circle::filled);
215
216      // make the circle red
217      G4Colour colour(1.,0.,0.);
218      G4VisAttributes attribs(colour);
219      circle.SetVisAttributes(attribs);
220
221      // make a 3D data for visualization
222      pVVisManager->Draw(circle);
223    }
224  }
225
226  //----- end of C++ source codes
227 </PRE>
228<P>
229 The overloaded implementation of <tt>G4VHitsCollection::DrawAllHits()</tt> will be held
230 by, for example, class <i>MyTrackerHitsCollection</i> inheriting class
231 <i>G4VHitsCollection</i> as follows:
232 <PRE>
233  //----- C++ source codes: An example of giving concrete implementation of
234  //       G4VHitsCollection::Draw(),
235  //       using  class MyTrackerHit : public G4VHitsCollection{...}
236  //     
237  void MyTrackerHitsCollection::DrawAllHits()
238  {
239    G4int n_hit = theCollection.entries();
240    for(G4int i=0;i < n_hit;i++)
241    { 
242      theCollection[i].Draw(); 
243    }
244  }
245
246  //----- end of C++ source codes
247 </PRE>
248<P>
249 Thus, you can visualize hits as well as trajectories, for example,
250 at the end of each event by implementing the method
251 <tt>MyEventAction::EndOfEventAction()</tt> as follows:
252 <PRE>
253  void MyEventAction::EndOfEventAction()
254  {
255    const G4Event* evt = fpEventManager->get_const_currentEvent();
256
257    G4SDManager * SDman = G4SDManager::get_SDMpointer();
258    G4String colNam;
259    G4int trackerCollID = SDman->get_collectionID(colNam="TrackerCollection");
260    G4int calorimeterCollID = SDman->get_collectionID(colNam="CalCollection");
261
262    G4TrajectoryContainer * trajectoryContainer = evt->get_trajectoryContainer();
263    G4int n_trajectories = 0;
264    if(trajectoryContainer)
265    { n_trajectories = trajectoryContainer->entries(); }
266
267    G4HCofThisEvent * HCE = evt->get_HCofThisEvent();
268    G4int n_hitCollection = 0;
269    if(HCE)
270    { n_hitCollection = HCE->get_capacity(); }
271 
272    G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
273
274    if(pVVisManager)
275    {
276 
277      // Declare begininng of visualization
278      G4UImanager::GetUIpointer()->ApplyCommand("/vis/scene/notifyHandlers");
279
280      // Draw trajectories
281      for(G4int i=0; i < n_trajectories; i++)
282      { 
283          (*(evt->get_trajectoryContainer()))[i]->DrawTrajectory();
284      }
285
286      // Construct 3D data for hits
287      MyTrackerHitsCollection* THC
288        = (MyTrackerHitsCollection*)(HCE->get_HC(trackerCollID));
289      if(THC) THC->DrawAllHits();
290      MyCalorimeterHitsCollection* CHC
291        = (MyCalorimeterHitsCollection*)(HCE->get_HC(calorimeterCollID));
292      if(CHC) CHC->DrawAllHits();
293
294      // Declare end of visualization
295      G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/update");
296   
297    }
298
299  }
300
301  //----- end of C++ codes
302 </PRE>
303<P>
304 You can re-visualize a physical volume, where a hit is detected, with a highlight
305 color, in addition to the whole set of detector components.  It is done by calling a
306 drawing method of a physical volume directly.  The method is:
307 <PRE>
308  //----- Drawing methods of a physical volume
309  virtual void Draw (const G4VPhysicalVolume&, ...) ;
310 </PRE>
311<P>
312 This method is, for example, called in a method <tt>MyXXXHit::Draw()</tt>, describing
313 the visualization of hits with markers.  The following is an example for this:
314 <PRE>
315  //----- C++ source codes: An example of visualizing hits with
316  void MyCalorimeterHit::Draw()
317  {
318    G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
319    if(pVVisManager)
320    {
321      G4Transform3D trans(rot,pos);
322      G4VisAttributes attribs;
323      G4LogicalVolume* logVol = pPhys->GetLogicalVolume();
324      const G4VisAttributes* pVA = logVol->GetVisAttributes();
325      if(pVA) attribs = *pVA;
326      G4Colour colour(1.,0.,0.);
327      attribs.SetColour(colour);
328      attribs.SetForceSolid(true);
329
330      //----- Re-visualization of a selected physical volume with red color
331      pVVisManager->Draw(*pPhys,attribs,trans);
332
333    }
334  }
335
336  //----- end of C++ codes
337 </PRE>
338<P>
339
340<h4>8.5.7 HepRep Attributes for Hits</h4>
341The HepRep file formats, HepRepFile and HepRepXML, attach various attributes to hits
342such that you can view these attributes, label trajectories by these attributes
343or make visibility cuts based on these attributes.
344Examples of adding HepRep attributes to hit classes can be found in examples
345/extended/analysis/A01 and /extended/runAndEvent/RE01.
346<P>
347For example, in example RE01's class RE01CalorimeterHit.cc,
348available attributes will be:
349<UL>
350<LI>Hit Type</li>
351<LI>Track ID</li>
352<LI>Z Cell ID</li>
353<LI>Phi Cell ID</li>
354<LI>Energy Deposited</li>
355<LI>Energy Deposited by Track</li>
356<LI>Position</li>
357<LI>Logical Volume</li>
358</UL>
359You can add additional attributes of your choosing by modifying the relevant part of the hit class
360(look for the methods GetAttDefs and CreateAttValues).
361
362<h4>8.5.8 Visualization of text</h4>
363
364 In Geant4 Visualization, a text, i.e., a character string, is described by class
365 <i>G4Text</i> inheriting <i>G4VMarker</i> as well as <i>G4Square</i> and <i>G4Circle</i>.
366 Therefore, the way to visualize text is the same as for hits.
367 The corresponding drawing method of <i>G4VVisManager</i> is:
368 <PRE>
369  //----- Drawing methods of G4Text
370  virtual void G4VVisManager::Draw (const G4Text&, ...);
371 </PRE>
372 The real implementation of this method is described in class <i>G4VisManager</i>.
373<P>
374
375<h4>8.5.9 Visualization of polylines and tracking steps</h4>
376
377 Polylines, i.e., sets of successive line segments, are described by class
378 <i>G4Polyline</i>. For <i>G4Polyline</i>, the following drawing method of
379 class <i>G4VVisManager</i> is prepared:
380 <PRE>
381   //----- A drawing method of G4Polyline
382    virtual void G4VVisManager::Draw (const G4Polyline&, ...) ;
383 </PRE>
384 The real implementation of this method is described in class <i>G4VisManager</i>.
385<P>
386 Using this method, C++ source codes to visualize <i>G4Polyline</i> are described
387 as follows:
388 <PRE>
389 //----- C++ source code: How to visualize a polyline
390  G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
391 
392  if (pVVisManager) {
393      G4Polyline polyline ;
394   
395      ..... (C++ source codes to set vertex positions, color, etc)
396 
397      pVVisManager -> Draw(polyline);
398   
399  }
400 
401  //----- end of C++ source codes
402 </PRE>     
403<P>
404 Tracking steps are able to be visualized based on the above visualization of
405 <i>G4Polyline</i>.  You can visualize tracking steps at each step automatically
406 by writing a proper implementation of class <i>MySteppingAction</i> inheriting
407 <i>G4UserSteppingAction</i>, and also with the help of the Run Manager. 
408<P>
409 First, you must implement a method, <tt>MySteppingAction::UserSteppingAction()</tt>.
410 A typical implementation of this method is as follows:
411 <PRE>
412  //----- C++ source code: An example of visualizing tracking steps
413  void MySteppingAction::UserSteppingAction()
414  {
415      G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
416
417      if (pVVisManager) {
418
419        //----- Get the Stepping Manager
420        const G4SteppingManager* pSM = GetSteppingManager();
421
422        //----- Define a line segment
423        G4Polyline polyline;
424        G4double charge = pSM->GetTrack()->GetDefinition()->GetPDGCharge();
425        G4Colour colour;
426        if      (charge < 0.) colour = G4Colour(1., 0., 0.);
427        else if (charge < 0.) colour = G4Colour(0., 0., 1.);
428        else                  colour = G4Colour(0., 1., 0.);
429        G4VisAttributes attribs(colour);
430        polyline.SetVisAttributes(attribs);
431        polyline.push_back(pSM->GetStep()->GetPreStepPoint()->GetPosition());
432        polyline.push_back(pSM->GetStep()->GetPostStepPoint()->GetPosition());
433
434        //----- Call a drawing method for G4Polyline
435        pVVisManager -> Draw(polyline);
436     
437      }
438  }
439
440  //----- end of C++ source code
441 </PRE> 
442<P>
443 Next, in order that the above C++ source code works, you have to pass
444 the information of the <i>MySteppingAction</i> to the Run Manager in the <tt>main()</tt> function:
445 <PRE> 
446  //----- C++ source code: Passing what to do at each step to the Run Manager
447
448  int main()
449  {
450     ...
451 
452     // Run Manager
453     G4RunManager * runManager = new G4RunManager;
454
455     // User initialization classes
456     ...
457     runManager->SetUserAction(new MySteppingAction);
458     ...
459  }
460
461  //----- end of C++ source code
462 </PRE> 
463<P>
464 Thus you can visualize tracking steps with various visualization attributes,
465 e.g., color, at each step, automatically.
466<P>
467 As well as tracking steps, you can visualize any kind 3D object made of
468 line segments, using class <i>G4Polyline</i> and its drawing method, defined in class
469 <i>G4VVisManager</i>.
470 See, for example, the implementation of the <tt>/vis/scene/add/axes</tt> command.
471<P>
472
473<h4>8.5.10 Visualization User Action</h4>
474
475You can implement the <tt>Draw</tt> method of <tt>G4VUserVisAction</tt>, e.g., the class definition could be:
476<PRE>
477class StandaloneVisAction: public G4VUserVisAction {
478  void Draw();
479};
480</PRE>
481and the implementation:
482<PRE>
483void StandaloneVisAction::Draw() {
484  G4VVisManager* pVisManager = G4VVisManager::GetConcreteInstance();
485  if (pVisManager) {
486
487    // Simple box...
488    pVisManager->Draw(G4Box("box",2*m,2*m,2*m),
489                      G4VisAttributes(G4Colour(1,1,0)));
490
491    // Boolean solid...
492    G4Box boxA("boxA",3*m,3*m,3*m);
493    G4Box boxB("boxB",1*m,1*m,1*m);
494    G4SubtractionSolid subtracted("subtracted_boxes",&boxA,&boxB,
495                       G4Translate3D(3*m,3*m,3*m));
496    pVisManager->Draw(subtracted,
497                      G4VisAttributes(G4Colour(0,1,1)),
498                      G4Translate3D(6*m,6*m,6*m));
499  }
500}
501</PRE>
502Explicit use of polyhedron objects is equivalent, e.g.:
503<PRE>
504    // Same, but explicit polyhedron...
505    G4Polyhedron* pA = G4Box("boxA",3*m,3*m,3*m).CreatePolyhedron();
506    G4Polyhedron* pB = G4Box("boxB",1*m,1*m,1*m).CreatePolyhedron();
507    pB->Transform(G4Translate3D(3*m,3*m,3*m));
508    G4Polyhedron* pSubtracted = new G4Polyhedron(pA->subtract(*pB));
509    G4VisAttributes subVisAtts(G4Colour(0,1,1));
510    pSubtracted->SetVisAttributes(&subVisAtts);
511    pVisManager->Draw(*pSubtracted,G4Translate3D(6*m,6*m,6*m));
512    delete pA;
513    delete pB;
514    delete pSubtracted;
515</PRE>
516If efficiency is an issue, create the objects in the constructor,
517delete them in the destructor and draw them in your <tt>Draw</tt>
518method.  Anyway, an instance of your class needs to be registered with
519the vis manager, e.g.:
520<PRE>
521  ...
522  G4VisManager* visManager = new G4VisExecutive;
523  visManager->Initialize ();
524
525  visManager->SetUserAction
526    (new StandaloneVisAction,
527     G4VisExtent(-5*m,5*m,-5*m,5*m,-5*m,5*m));  // 2nd argument optional.
528  ...
529</PRE>
530then activate by adding to a scene, e.g:
531<PRE>
532/control/verbose 2
533/vis/verbose c
534/vis/open OGLSXm
535/vis/scene/create
536#/vis/scene/add/userAction
537/vis/scene/add/userAction -10 10 -10 10 -10 10 m
538#/vis/scene/add/axes 0 0 0 10 m
539#/vis/scene/add/scale 10 m
540/vis/sceneHandler/attach
541/vis/viewer/refresh
542</PRE>
543The extent can be added on registration or on the command line or
544neither (if the extent of the scene is set by other components).  Your
545<tt>Draw</tt> method will be called whenever needed to refresh the
546screen or rebuild a graphics database, for any chosen viewer.  The
547scene can be attached to any scene handler and your drawing will be
548shown.
549
550<h4>8.5.11 Standalone Visualization</h4>
551
552The above raises the possibility of using Geant4 as a "standalone"
553graphics package without invoking the run manager.  The following main
554program, together with a user visualization action and a macro file,
555will allow you to view your drawing interactively on any of the
556supported graphics systems.
557<PRE>
558#include "globals.hh"
559#include "G4VisExecutive.hh"
560#include "G4VisExtent.hh"
561#include "G4UImanager.hh"
562#include "G4UIterminal.hh"
563#include "G4UItcsh.hh"
564
565#include "StandaloneVisAction.hh"
566
567int main() {
568
569  G4VisManager* visManager = new G4VisExecutive;
570  visManager->Initialize ();
571
572  visManager->SetUserAction
573    (new StandaloneVisAction,
574     G4VisExtent(-5*m,5*m,-5*m,5*m,-5*m,5*m));  // 2nd argument optional.
575
576  G4UImanager* UI = G4UImanager::GetUIpointer ();
577  UI->ApplyCommand ("/control/execute standalone.g4m");
578
579  G4UIsession* session = new G4UIterminal(new G4UItcsh);
580  session->SessionStart();
581
582  delete session;
583  delete visManager;
584}
585</PRE>
586
587<HR>
588 <A HREF="attributes.html">Next section</A><BR>
589 <A HREF="index.html">Back to contents</A>
590</BODY>
591</HTML>
Note: See TracBrowser for help on using the repository browser.