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

Last change on this file since 1208 was 1208, checked in by garnier, 16 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.