Page MenuHomeHEPForge

04_Simple_Cylindrical_Detector.html
No OneTemporary

04_Simple_Cylindrical_Detector.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>FROG Tutotial</title>
<style type="text/css">
<!--
.Style2 {color: #0000FF}
-->
</style>
<link href="../Tutorial_style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h1 align="left">How to Display a Basic Event comming from <u><strong>Your</strong></u> Experimental Data ? </h1>
<p> This project contains 3 functions + the main :<br />
Build_Geometry() method will create the geom file associated to our detector.<br />
In this example, we'll build a more realistic appartus.<br />
Our experiment will be composed of 10 tracking planes. </p>
<p> The Build_1Event() method will fill the myEvents objects with all data related to 1 Event.<br />
In our cases, random variables will be used inside this function to simulate a particle gun.</p>
<p>The myEvents will be created by the third function Build_Events(). This method will also call Build_1Event() N Times.<br />
Where N is the number of events we want to store/display.</p>
<p> Finally the main() function will first call the GeometryBuilder, then initialise the MyEvents objects <br />
After that, it will enter in the events loop. And call the Build_1_Events function at each loop.<br />
Finally, we'll store events data in a .vis file which can be read by FROG.</p>
<h2>1. The Includes</h2>
<p>Includes are basically the same than in the previous tutorial. Except that FROG_Events.h and FROG_Element_Event_Track.h have been added. The first one, will do exactly same thing that FROG_Element_Geometry. It contains the Load/Save functions. The second one will store our event data. Which will be a track in this example. </p>
<pre class="codebox">#ifdef linux
#include &lt;GL/gl.h&gt;
#include &lt;GL/glu.h&gt;
#include &quot;../../Includes/GLUT/glut.h&quot;
#else
#define _CRT_SECURE_NO_DEPRECATE 1
#include &lt;windows.h&gt;
#include &lt;gl/gl.h&gt;
#include &lt;gl/glu.h&gt;
#include &lt;gl/glut.h&gt;
#pragma comment (lib,&quot;glaux.lib&quot;)
#pragma comment (lib,&quot;glu32.lib&quot;)
#pragma comment (lib,&quot;opengl32.lib&quot;)
#pragma comment (lib,&quot;glut.lib&quot;)
#pragma comment (lib,&quot;glut32.lib&quot;)
#endif
#include &lt;stdio.h&gt;
#include &lt;iostream&gt;
#include &lt;math.h&gt;
#include &quot;../../Includes/FROG/FROG_DetId.h&quot;
#include &quot;../../Includes/FROG/FROG_Geometry.h&quot;
#include &quot;../../Includes/FROG/FROG_Events.h&quot;
#include &quot;../../Includes/FROG/FROG_Element_Tools.h&quot;
#include &quot;../../Includes/FROG/FROG_Element_Event_Track.h&quot;</pre>
<pre>&nbsp;
</pre>
<h2> 2. The Four Functions</h2>
<p>Now we can define the three functions (in addition of the main) we will use : </p>
<pre class="codebox">void Build_Geometry();
void Build_Events();
void Build_1Event(FROG_Element_Event* event);</pre>
<h2>3. Build the Geometry</h2>
<p>This I will note comment because it is the topic of the previous tutorial. We use exactly the same Idea. The Geometry is composed of 10 tracking layer. Orthogonal to the Z axis. Each layer are square plane with a dimention of 100 x 100 (cm). The layers are positioned on (0,0,50*i) where i = 0, 1, 2, ..., 10 (so actually we have 11 layers ;) ) <br />
We create also 2 others geometry objects : the particle gun (at 0,0,-300) and what I call a mirror wall (at 0,0,600). This object is just a cube. That will reflect our beam, exactly as a mirror does with the light. Add the end of the fucntion I save the geometry into the file &quot;MyCustomTracker.geom&quot;.</p>
<pre class="codebox">void Build_Geometry()
{
<span class="Style2"> // This element is the root of the &quot;file&quot; tree. (don't change this line)</span>
ROG_Element_Base* prim = new FROG_Element_Base(C_PRIMARY);
<span class="Style2"> // This element is the geometry branch of the tree. (don't change this line)
// When the element have been created, we have to attach it to the root (or more generally to the mother branch).</span>
FROG_Element_Base* mygeom = new FROG_Element_Base(C_GEOMETRY);
prim-&gt;addDaughter(mygeom);
<span class="Style2"> // This a particular geometry branch : this allow us to group all the detectors attached to this branch.
// Moreover, this group of detector as a detId, which allow us to easily &quot;call&quot; this group (e.g. for the display).
// Warning : be sure that the detId is not already use by an other detecor. (detId should be bigger than 1000000).
// Warning : an empty group (containing 0 elements) can not be save.</span>
FROG_Element_Base_With_DetId* tracker = new FROG_Element_Base_With_DetId_And_Name(9000000,&quot;Tracker&quot;);
mygeom-&gt;addDaughter(tracker);
<span class="Style2">
// This variable will allow us to do not use twice the same detId.</span>
unsigned int DetIdCount = 1;<br /><span class="Style2"><br /> // We'll fill the tracker group with 10 primitive objects. A lots of primitive objects can be use in FROG.
// You can find all the primitive header files in &lt;FROGDIR&gt;/soft/Includes/FROG/FROG_Element_Primitive_*.h
// There is also some CMS oriented dataformat : &lt;FROGDIR&gt;/soft/Includes/FROG/FROG_Element_Geom_*.h
// Do not hesitate to add your own primitive objects. There are really easy to do (takes an existing primitive as example
// and copy/paste to build your own).</span>
for(int i=0;i&lt;=10;i++){
FROG_Element_Primitive_Rectangle* layer = new FROG_Element_Primitive_Rectangle(400000000+DetIdCount,
0 ,0 ,50*i, //Position
50 ,0 ,0 , //Width
0 ,50 ,0 ); //Length
tracker-&gt;addDaughter(layer);
DetIdCount++;
}
<span class="Style2"> // This group will contains all no realistic objects. For Instance, a cube will symbolised the Particle Gun.
// And an other cube will symbolise the mirror wall.</span>
FROG_Element_Base_With_DetId* others = new FROG_Element_Base_With_DetId_And_Name(8000000,&quot;Others&quot;);
mygeom-&gt;addDaughter(others);
FROG_Element_Primitive_Cube* End = new FROG_Element_Primitive_Cube(400000000+DetIdCount,
0 ,0 ,600, //Position
50 ,0 ,0 , //Width
0 ,50 ,0 , //Length
0 ,0 ,50 ); //Thickness
others-&gt;addDaughter(End); DetIdCount++;
FROG_Element_Primitive_Cube* PG = new FROG_Element_Primitive_Cube(400000000+DetIdCount,
0 ,0 ,-300, //Position
5 ,0 ,0 , //Width
0 ,5 ,0 , //Length
0 ,0 ,50 ); //Thickness
others-&gt;addDaughter(PG); DetIdCount++;
<span class="Style2"> // Now that the geometry tree is build. We can create the geometry objects with this tree. The geometry Object
// will handle the writting/reading of geometry files. It has also a very useful function to get a branch or a leaf of the tree
// from his detId (Geometry::FindByDetId).</span>
FROG_Geometry* CustomGeom = new FROG_Geometry(prim);
CustomGeom-&gt;Save(&quot;MyCustomTracker.geom&quot;);
<span class="Style2">
// Last but not least, the FROG_ELEMENT::PrintTree function will print on the screen the tree arborecence.
// Check this print out to see if your groups are done as you want, and to see if no modules are missing.</span>
FROG_ELEMENT::PrintTree(prim);
<span class="Style2"> // If everything works fine, You just have to update the FROG's config.txt to load your geometry.
// You can for instance replace
// InputTrackerGeom = ../test/Tracker.geom;
// by
// InputTrackerGeom = &lt;FROGDIR&gt;/soft/Examples/02_Display_Basics_Events/MyCustomTracker.geom;</span>
return;
}</pre>
<h2>4. Build the Event Tree </h2>
<p>Now, we can create the Event Tree. As it is done for the geometry, first we need a root of type FROG_Element_Base with a chunkId of type C_PRIMARY.<br />
Then we can add event branch on this root. Each branch should be of type FROG_Element_Event. The constructor of this method can take the EventNumber and the RunNumber as parameter. Default values are 0. Then we shoudl fill the Event branch with the data of the particular event. This is the job of the Build_1Event function. This function take a pointer of the event branch in argument. These operation are repeated N(=10) times. In order to simulate/store 10 events. Of course you can increase this Number in order to display more events (there is no limitation on the number of events). Finally, When the tree is complete, we can create a FROG_Events object, which will allow us to save the tree on the disk. Thanks to the function save. Let's call the events file : &quot;SimulatedEvents.vis&quot; </p>
<pre class="codebox">void Build_Events()
{
<span class="Style2"> // This element is the root of the &quot;file&quot; tree. (don't change this line)</span>
FROG_Element_Base* prim = new FROG_Element_Base(C_PRIMARY);
<span class="Style2"> // Prepare to simulate 10 events.</span>
for(unsigned int i=0;i&lt;10;i++){
<span class="Style2"> // Create a new event</span>
FROG_Element_Event* event = new FROG_Element_Event(1,i);
<span class="Style2"> // Fill the event with monte carlo</span>
Build_1Event(event);
<span class="Style2"> // Store the event</span>
prim-&gt;addDaughter(event);
}
<span class="Style2"> // Save the event tree on disk</span>
FROG_Events* events = new FROG_Events(prim);
events-&gt;Save(&quot;SimulatedEvents.vis&quot;);
<span class="Style2"> // print the tree of all elements
// FROG_ELEMENT::PrintTree(prim); </span>
}</pre>
<h2>5. Build One Event</h2>
<p>This is the most important function. (and basically the only one you have to change). In this particular example, we need to simulate the event and to store it at the same time. So first, I define a large number of variables that are used to define the particle gun direction and position, particle direction and Pt. </p>
<p>Then I create 2 FORG_Objects. The first one is a FROG_Element_Base_With_DetId it will contains all the reco tracks in the event. (we will have only one track... but we want to put this track in a &quot;group&quot; in order to give it a name). The &quot;name&quot; of this group is no more a DetId, but and EvtId which is actually the same that the DetId but for event.<br />
The second object is the track itself. This object is of the type FROG_Element_Event_Track. There is a lot of predefine Event_Object that you can use to store and display your events. Some of them are listed bellow (and an other tutorial will explains you how to create your own Objects) : </p>
<ul>
<li>Frog_Element_Event_CaloHit</li>
<li>Frog_Element_Event_Hit</li>
<li>Frog_Element_Event_Segment</li>
<li>Frog_Element_Event_Sim_Hit</li>
<li>Frog_Element_Event_Sim_Track</li>
<li>Frog_Element_Event_Sim_Vertex</li>
<li>Frog_Element_Event_Track</li>
</ul>
<p>The constructor of the FROG_Element_Event_Track takes the P, Pt and Chi2 as input. The first parameter should be 0 (this argument will be remove soon... it is there only for back-portability). This object will take the Hits on the tracker layer as daughters/leaves. </p>
<p>So we have to create the hits on all the layers... So the following is basically the particle propagation in the detector (this step can be done with Geant4). When the particle cross a layer, I just create a new hit. Which is define by the DetId of the layer that produce the Hit, a X,Y,Z position (in the global frame) and an energyLoss (always equal to 0 in this tutorial). Also, if the particle reach the &quot;mirrow wall&quot; I just flip the Z component of the particle momentum. <br>
</p>
<p>Finally, I just plug the track branch on the trackCollection branch. And the trackCollection branch on the Event branch. </p>
<pre class="codebox">void Build_1Event(FROG_Element_Event* event)
{
<span class="Style2"> // Define particle Gun direction and strength (8&deg; in theta, 360&deg; in phi and 10GeV)</span>
double phi = (rand()%360)*0.01745;
ouble theta = (rand()%8) *0.01745;
ouble P = 10;
<span class="Style2"> // Define the particle gun position (starting point of particles)</span>
double pos_x = 0;
double pos_y = 0;
double pos_z = -300;
<span class="Style2">
// Define the particle cartesian direction</span>
double dir_x = P*cos(phi)*sin(theta);
double dir_y = P*sin(phi)*sin(theta);
double dir_z = P*cos(theta);
<span class="Style2">
// Create the track to be stored in the event</span>s.
float Pt = sqrt(dir_x*dir_x + dir_y*dir_y);
FROG_Element_Base_With_DetId* trackCollection = new FROG_Element_Base_With_DetId_And_Name(EVTID_TRK,&quot;Tracks&quot;);
FROG_Element_Event_Track* track= new FROG_Element_Event_Track(0,P,Pt,0);
<span class="Style2"> // Begin the propagation loop</span>
double dt = 0.1;
for(unsigned int i=0;i&lt;10000;i++){
pos_x += dir_x * dt;
pos_y += dir_y * dt;
pos_z += dir_z * dt;
<span class="Style2"> // There is no detector in the z&lt;0 region, so continue the propagation until
// the particle arrive in a detector region</span>.
if(pos_z&lt;0 ) continue;
<span class="Style2"> // This means the particle is hitting the mirror wall. So we inverse the particle Z direction</span>
if(pos_z&gt;=600-25){
dir_z = -1*dir_z;
}
<span class="Style2"> // Check if we are crossing a tracker layer
// If we are, create a hit with the detId of the crossed layer
// and the position of the particle. Charge can be used to set a dE/dx</span>
if(((int)pos_z)%50==0){
if(fabs(pos_x)&gt;50)continue;
if(fabs(pos_y)&gt;50)continue;
FROG_Element_Event_Hit* hit = new FROG_Element_Event_Hit(400000001 + ((int)pos_z)/50, pos_x, pos_y, pos_z, -1);
track-&gt;addDaughter(hit);
}
}
<span class="Style2"> // Store the built track in the event</span>s
trackCollection-&gt;addDaughter(track);
event-&gt;addDaughter(trackCollection);
}</pre>
<p>&nbsp;</p>
<h2>6. Putting Everything Together into the main() </h2>
<p>Finally, we only need to call Build_Geometry and Build_Events. That's all.<br />
You can also to be sure that everything is correct read the Events file you saved.<br />
If something is wrong, you will have some error messages at the reading. You can also display the Events tree (this can be a huge print out !!!).</p>
<p>&nbsp;</p>
<pre class="codebox">int main()
{
<span class="Style2">// Build and Save the geome</span>try
Build_Geometry();<br />
<span class="Style2">// Build and Save the event collection</span>
Build_Events();
<span class="Style2">// The following lines are used to check if the output .vis file can be read correctl</span>y:
std::cout &lt;&lt; &quot;--------- check output file ---------&quot; &lt;&lt; std::endl;
FROG_Events* evt = new FROG_Events();
evt-&gt;Load(&quot;SimulatedEvents.vis&quot;);
FROG_ELEMENT::PrintTree(evt-&gt;prim);
}</pre>
<p>&nbsp;</p>
<h2>7. The Frog config file</h2>
<p>Now, as usual, we have to setup the FROG config file in order to display what we want.We can specify the geometry file, the events file.<br />
But also the Geometry we want to display (9000000=Tracker &amp; 8000000=MirrorWall+ParticleGun) and Event data we want to display (23100000) = RecoTracks.</p>
<p>Then we can set up views. It can be nice to have 3 views for this experiment : The standard 3D view, a longitudinal 2D view and a transversal 2D view (not so usefull!).<br />
Finally we can set the style (color, thicknes, marker ans so on) of the recoTracks. The full config file can be found <a href="config.txt">here</a>. </p>
<pre class="codebox2"><span class="Style2">//It is possible to load other config file from this one.</span>
<br /><span class="Style2">// input event file </span>
InputVisFile = {Examples/02_Display_Basics_Events/SimulatedEvents.vis};
<br /><span class="Style2">// input geometry file </span>
InputGeom = {Examples/02_Display_Basics_Events/MyCustomTracker.geom};
GeomToDisplay = {9000000, 8000000};
EventToDisplay = {23100000}; // All RecoTracks
ActiveViews = {View3D, View2DZ, View2DR};
View3D_Type = 3D;
View3D_Viewport_X = 0.0;
View3D_Viewport_Y = 0.3;
View3D_Viewport_W = 1.0;
View3D_Viewport_H = 0.8;
View3D_Cam_Pos_Theta = 0.3;
View3D_Cam_Pos_Phi = 0;
View3D_Cam_Pos_R = 500;
View3D_Animate_Rotate = false;
View3D_Animate_dphi = 0.005;
View3D_Geom = {9000000, 8000000};
View2DZ_Type = 2D;
View2DZ_Viewport_X = 0.4;
View2DZ_Viewport_Y = 0.0;
View2DZ_Viewport_W = 0.6;
View2DZ_Viewport_H = 0.2;
View2DZ_Cam_Pos_Phi = 0.01;
View2DZ_Cam_Pos_R = 600;
View2DZ_Slice_Depth = 800;
View2DZ_Geom = {9000000, 8000000};
View2DR_Type = 2D;
View2DR_Viewport_X = 0.1;
View2DR_Viewport_Y = 0.0;
View2DR_Viewport_W = 0.2;
View2DR_Viewport_H = 0.2;
View2DR_Cam_Pos_Phi = 1.57;
View2DR_Cam_Pos_R = 100;
View2DR_Slice_Depth = 1000;
View2DR_Geom = {9000000, 8000000};
<span class="Style2">// The Extension of File Containing ScreenShots
// PNG, PS, EPS, TEX, PDF, SVG and PGF(Experimental) Can be used</span>
Screenshot_Format = png;
Id_23100000_Color = { 1.0 , 0.0 , 0.0 , 1.0 }; // ALL RecoTracks
Id_23100000_Thickness = 4.0; // ALL RecoTracks
Id_23100000_Marker = 100; // ALL RecoTracks
Id_23100000_MarkerSize = 5; // ALL RecoTracks
<span class="Style2">// WARNING : TABULATION CREATES BUGS &amp; ERRORS
// SO PLEASE, USE WHITE SPACE INSTEAD OF TABULATION.</span>
</pre>
<p>&nbsp;</p>
<h2>8. The Results </h2>
<p>The full code, with the makefile and the visual c++ project can be found in &quot;/Examples/02_Display_Basics_Events&quot;.<br />
Have fun, and please send me a screenshot of your geometries and events data. </p>
<p align="center"><img src="Pictures/02_Display_Basics_Events_1.png" width="800" height="600" /></p>
<p align="center"><img src="Pictures/02_Display_Basics_Events_2.png" width="800" height="600" /></p>
<p>&nbsp;</p>
<h1 align="center"><a href="../Tutorial.html">Back to Turorial</a> </h1>
</body>
</html>

File Metadata

Mime Type
text/html
Expires
Mon, Jan 20, 8:49 PM (22 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4017779
Default Alt Text
04_Simple_Cylindrical_Detector.html (17 KB)

Event Timeline