[1208] | 1 | <html> |
---|
| 2 | <head> |
---|
| 3 | <title>ADG: Geometry</title> |
---|
| 4 | </head> |
---|
| 5 | |
---|
| 6 | <!-- Changed by: Gabriele Cosmo, 18-Apr-2005 --> |
---|
| 7 | <!-- $Id: geomPhysical.html,v 1.6 2006/06/09 13:58:03 gcosmo Exp $ --> |
---|
| 8 | <!-- $Name: $ --> |
---|
| 9 | <body> |
---|
| 10 | <table WIDTH="100%"><TR> |
---|
| 11 | <td> |
---|
| 12 | <a href="../../../../Overview/html/index.html"> |
---|
| 13 | <IMG SRC="../../../../resources/html/IconsGIF/Overview.gif" ALT="Overview"></a> |
---|
| 14 | <a href="geometry.html"> |
---|
| 15 | <IMG SRC="../../../../resources/html/IconsGIF/Contents.gif" ALT="Contents"></a> |
---|
| 16 | <a href="geomLogical.html"> |
---|
| 17 | <IMG SRC="../../../../resources/html/IconsGIF/Previous.gif" ALT="Previous"></a> |
---|
| 18 | <a href="geomTouch.html"> |
---|
| 19 | <IMG SRC="../../../../resources/html/IconsGIF/Next.gif" ALT="Next"></a> |
---|
| 20 | </td> |
---|
| 21 | <td ALIGN="Right"> |
---|
| 22 | <font SIZE="-1" COLOR="#238E23"> |
---|
| 23 | <b>Geant4 User's Guide</b> |
---|
| 24 | <br> |
---|
| 25 | <b>For Application Developers</b> |
---|
| 26 | <br> |
---|
| 27 | <b>Geometry</b> |
---|
| 28 | </font> |
---|
| 29 | </td> |
---|
| 30 | </tr></table> |
---|
| 31 | <br><br> |
---|
| 32 | |
---|
| 33 | <a name="4.1.4"> |
---|
| 34 | <h2>4.1.4 Physical Volumes</h2></a> |
---|
| 35 | |
---|
| 36 | <p> |
---|
| 37 | Physical volumes represent the spatial positioning of the volumes describing |
---|
| 38 | the detector elements. Several techniques can be used. They range from |
---|
| 39 | the simple placement of a single copy to the repeated positioning using |
---|
| 40 | either a simple linear formula or a user specified function. |
---|
| 41 | </p> |
---|
| 42 | <p> |
---|
| 43 | The simple placement involves the definition of a transformation matrix for |
---|
| 44 | the volume to be positioned. Repeated positioning is defined using the |
---|
| 45 | number of times a volume should be replicated at a given distance along a given |
---|
| 46 | direction. Finally it is possible to define a parameterised formula to specify |
---|
| 47 | the position of multiple copies of a volume. Details about these methods are |
---|
| 48 | given below. |
---|
| 49 | </p> |
---|
| 50 | <p> |
---|
| 51 | <b>Note</b> - For geometries which vary between runs and for which components |
---|
| 52 | of the old geometry setup are explicitely -deleted-, it is required to |
---|
| 53 | consider the proper order of deletion (which is the exact inverse of the |
---|
| 54 | actual construction, i.e., first delete physical volumes and then logical |
---|
| 55 | volumes). Deleting a logical volume does NOT delete its daughter volumes.<BR> |
---|
| 56 | It is not necessary to delete the geometry setup at the end of a job, the |
---|
| 57 | system will take care to free the volume and solid stores at the end of |
---|
| 58 | the job. The user has to take care of the deletion of any additional |
---|
| 59 | transformation or rotation matrices allocated dinamically in his/her own |
---|
| 60 | application. |
---|
| 61 | </p> |
---|
| 62 | <P> </P> |
---|
| 63 | |
---|
| 64 | <a name="4.1.4.1"> |
---|
| 65 | <H4>4.1.4.1 Placements: single positioned copy</H4></a> |
---|
| 66 | |
---|
| 67 | In this case, the Physical Volume is created by associating a Logical Volume |
---|
| 68 | with a Rotation Matrix and a Translation vector. |
---|
| 69 | The Rotation Matrix represents the rotation of the reference frame of the |
---|
| 70 | considered volume relatively to its mother volume's reference frame. |
---|
| 71 | The Translation Vector represents the translation of the current volume in the |
---|
| 72 | reference frame of its mother volume.<BR> |
---|
| 73 | Transformations including reflections are not allowed. |
---|
| 74 | <P> |
---|
| 75 | To create a Placement one must construct it using: |
---|
| 76 | <PRE> |
---|
| 77 | G4PVPlacement( G4RotationMatrix* pRot, |
---|
| 78 | const G4ThreeVector& tlate, |
---|
| 79 | G4LogicalVolume* pCurrentLogical, |
---|
| 80 | const G4String& pName, |
---|
| 81 | G4LogicalVolume* pMotherLogical, |
---|
| 82 | G4bool pMany, |
---|
| 83 | G4int pCopyNo, |
---|
| 84 | G4bool pSurfChk=false )</PRE> |
---|
| 85 | where: |
---|
| 86 | <p> |
---|
| 87 | <table border=1 cellpadding=8> |
---|
| 88 | <tr> |
---|
| 89 | <td><tt>pRot</tt> <td>Rotation with respect to its mother volume |
---|
| 90 | <tr> |
---|
| 91 | <td><tt>tlate</tt> <td>Translation with respect to its mother volume |
---|
| 92 | <tr> |
---|
| 93 | <td><tt>pCurrentLogical</tt> <td>The associated Logical Volume |
---|
| 94 | <tr> |
---|
| 95 | <td><tt>pName</tt> <td>String identifier for this placement |
---|
| 96 | <tr> |
---|
| 97 | <td><tt>pMotherLogical</tt> <td>The associated mother volume |
---|
| 98 | <tr> |
---|
| 99 | <td><tt>pMany</tt> <td>For future use. Can be set to false |
---|
| 100 | <tr> |
---|
| 101 | <td><tt>pCopyNo</tt> <td>Integer which identifies this placement |
---|
| 102 | <tr> |
---|
| 103 | <td><tt>pSurfChk</tt> <td>if true activates check for overlaps with existing volumes |
---|
| 104 | </table></P> |
---|
| 105 | <P> |
---|
| 106 | Care must be taken because the rotation matrix is not copied by a |
---|
| 107 | <tt>G4PVPlacement</tt>. So the user must not modify it after creating a |
---|
| 108 | Placement that uses it. |
---|
| 109 | However the same rotation matrix can be re-used for many volumes. |
---|
| 110 | </p> |
---|
| 111 | <p> |
---|
| 112 | Currently boolean operations are not implemented at the level of |
---|
| 113 | physical volume. So <tt>pMany</tt> must be false. |
---|
| 114 | However, an alternative implementation of boolean operations exists. |
---|
| 115 | In this approach a solid can be created from the union, intersection |
---|
| 116 | or subtraction of two solids. See <a href="geomSolids.html#4.1.2.2">Section 4.1.2.2</a> |
---|
| 117 | above for an explanation of this. |
---|
| 118 | </p> |
---|
| 119 | <P> |
---|
| 120 | The mother volume must be specified for all volumes <I>except</I> the world volume.</P> |
---|
| 121 | <P> |
---|
| 122 | An alternative way to specify a Placement utilizes a different |
---|
| 123 | method to place the volume. The solid itself is moved by rotating and |
---|
| 124 | translating it to bring it into the system of coordinates of the |
---|
| 125 | mother volume. This <I>active</I> method can be utilized using the |
---|
| 126 | following constructor: |
---|
| 127 | |
---|
| 128 | <PRE> |
---|
| 129 | G4PVPlacement( G4Transform3D solidTransform, |
---|
| 130 | G4LogicalVolume* pCurrentLogical, |
---|
| 131 | const G4String& pName, |
---|
| 132 | G4LogicalVolume* pMotherLogical, |
---|
| 133 | G4bool pMany, |
---|
| 134 | G4int pCopyNo, |
---|
| 135 | G4bool pSurfChk=false )</PRE></P> |
---|
| 136 | <P> |
---|
| 137 | An alternative method to specify the mother volume is to specify its |
---|
| 138 | placed physical volume. It can be used in either of the above methods |
---|
| 139 | of specifying the placement's position and rotation. The effect will be |
---|
| 140 | exactly the same as for using the mother logical volume.</P> |
---|
| 141 | <P> |
---|
| 142 | Note that a Placement Volume can still represent multiple detector elements. |
---|
| 143 | This can happen if several copies exist of the mother logical volume. |
---|
| 144 | Then different detector elements will belong to different branches of |
---|
| 145 | the tree of the hierarchy of geometrical volumes.</P> |
---|
| 146 | <P> </P> |
---|
| 147 | |
---|
| 148 | <a name="4.1.4.2"> |
---|
| 149 | <H4>4.1.4.2 Repeated volumes</H4></a> |
---|
| 150 | |
---|
| 151 | In this case, a single Physical Volume represents multiple copies of a volume |
---|
| 152 | within its mother volume, allowing to save memory. This is normally done when |
---|
| 153 | the volumes to be positioned follow a well defined rotational or translational |
---|
| 154 | symmetry along a Cartesian or cylindrical coordinate. The Repeated Volumes |
---|
| 155 | technique is available for volumes described by CSG solids. |
---|
| 156 | |
---|
| 157 | <P> </P> |
---|
| 158 | |
---|
| 159 | <b>Replicas</b> |
---|
| 160 | <P> |
---|
| 161 | Replicas are <i>repeated volumes</i> in the case when the multiple copies of |
---|
| 162 | the volume are all identical. The coordinate axis and the number of replicas |
---|
| 163 | need to be specified for the program to compute at run time the transformation |
---|
| 164 | matrix corresponding to each copy.</P> |
---|
| 165 | <P> |
---|
| 166 | <PRE> |
---|
| 167 | G4PVReplica( const G4String& pName, |
---|
| 168 | G4LogicalVolume* pCurrentLogical, |
---|
| 169 | G4LogicalVolume* pMotherLogical, // OR G4VPhysicalVolume* |
---|
| 170 | const EAxis pAxis, |
---|
| 171 | const G4int nReplicas, |
---|
| 172 | const G4double width, |
---|
| 173 | const G4double offset=0 )</PRE> |
---|
| 174 | where:</P> |
---|
| 175 | <P> |
---|
| 176 | <table border=1 cellpadding=8> |
---|
| 177 | <tr> |
---|
| 178 | <td><tt>pName</tt> <td>String identifier for the replicated volume |
---|
| 179 | <tr> |
---|
| 180 | <td><tt>pCurrentLogical</tt> <td>The associated Logical Volume |
---|
| 181 | <tr> |
---|
| 182 | <td><tt>pMotherLogical</tt> <td>The associated mother volume |
---|
| 183 | <tr> |
---|
| 184 | <td><tt>pAxis</tt> <td>The axis along with the replication is applied |
---|
| 185 | <tr> |
---|
| 186 | <td><tt>nReplicas</tt> <td>The number of replicated volumes |
---|
| 187 | <tr> |
---|
| 188 | <td><tt>width</tt> <td>The width of a single replica along the axis of |
---|
| 189 | replication |
---|
| 190 | <tr> |
---|
| 191 | <td><tt>offset</tt> <td>Possible offset associated to mother offset along |
---|
| 192 | the axis of replication |
---|
| 193 | </table></P> |
---|
| 194 | <P> |
---|
| 195 | <tt>G4PVReplica</tt> represents <tt>nReplicas</tt> volumes differing only in |
---|
| 196 | their positioning, and completely <b>filling</b> the containing mother volume. |
---|
| 197 | Consequently if a <tt>G4PVReplica</tt> is 'positioned' inside a given mother it |
---|
| 198 | <b>MUST</b> be the mother's only daughter volume. Replica's correspond |
---|
| 199 | to divisions or slices that completely fill the mother volume and have no |
---|
| 200 | offsets. For Cartesian axes, slices are considered perpendicular to the axis |
---|
| 201 | of replication.</P> |
---|
| 202 | <P> |
---|
| 203 | The replica's positions are calculated by means of a linear formula. |
---|
| 204 | Replication may occur along: |
---|
| 205 | <UL> |
---|
| 206 | <LI><i>Cartesian axes <tt>(kXAxis,kYAxis,kZAxis)</tt></i> |
---|
| 207 | <BR> |
---|
| 208 | The replications, of specified width have coordinates of |
---|
| 209 | form <tt>(-width*(nReplicas-1)*0.5+n*width,0,0)</tt><BR> |
---|
| 210 | where <tt>n=0.. nReplicas-1</tt> for the case of <tt>kXAxis</tt>, |
---|
| 211 | and are unrotated. |
---|
| 212 | </LI> |
---|
| 213 | <LI><i>Radial axis (cylindrical polar) <tt>(kRho)</tt></i> |
---|
| 214 | <BR> |
---|
| 215 | The replications are cons/tubs sections, centred on the origin |
---|
| 216 | and are unrotated.<BR> |
---|
| 217 | They have radii of <tt>width*n+offset</tt> to <tt>width*(n+1)+offset</tt> |
---|
| 218 | where <tt>n=0..nReplicas-1</tt> |
---|
| 219 | </LI> |
---|
| 220 | <LI><i>Phi axis (cylindrical polar) <tt>(kPhi)</tt></i> |
---|
| 221 | <BR> |
---|
| 222 | The replications are <i>phi sections</i> or <i>wedges</i>, and of cons/tubs |
---|
| 223 | form.<BR> |
---|
| 224 | They have <tt>phi</tt> of <tt>offset+n*width</tt> |
---|
| 225 | to <tt>offset+(n+1)*width</tt> where <tt>n=0..nReplicas-1</tt> |
---|
| 226 | </LI> |
---|
| 227 | </UL> |
---|
| 228 | |
---|
| 229 | The coordinate system of the replicas is at the centre of each replica |
---|
| 230 | for the cartesian axis. For the radial case, the coordinate system is |
---|
| 231 | unchanged from the mother. For the <tt>phi</tt> axis, the new coordinate system |
---|
| 232 | is rotated such that the X axis bisects the angle made by each wedge, |
---|
| 233 | and Z remains parallel to the mother's Z axis.</P> |
---|
| 234 | <P> |
---|
| 235 | The solid associated via the replicas' logical volume should have the |
---|
| 236 | dimensions of the first volume created and must be of the correct |
---|
| 237 | symmetry/type, in order to assist in good visualisation.<BR> |
---|
| 238 | ex. For X axis replicas in a box, the solid should be |
---|
| 239 | another box with the dimensions of the replications. (same Y & Z |
---|
| 240 | dimensions as mother box, X dimension = mother's X dimension/nReplicas).</P> |
---|
| 241 | <P> |
---|
| 242 | Replicas may be placed inside other replicas, provided the above rule |
---|
| 243 | is observed. Normal placement volumes may be placed inside replicas, |
---|
| 244 | provided that they do not intersect the mother's or any previous replica's |
---|
| 245 | boundaries. Parameterised volumes may not be placed inside.<BR> |
---|
| 246 | Because of these rules, it is not possible to place any other volume inside |
---|
| 247 | a replication in <tt>radius</tt>.<BR> |
---|
| 248 | The world volume <I>cannot</I> act as a replica, therefore it cannot be sliced.</P> |
---|
| 249 | <P> |
---|
| 250 | During tracking, the translation + rotation associated with each |
---|
| 251 | <tt>G4PVReplica</tt> object is modified according to the currently 'active' |
---|
| 252 | replication. The solid is not modified and consequently has the |
---|
| 253 | wrong parameters for the cases of <tt>phi</tt> and <tt>r</tt> replication |
---|
| 254 | and for when the cross-section of the mother is not constant along the |
---|
| 255 | replication.</P> |
---|
| 256 | <P> |
---|
| 257 | Example: |
---|
| 258 | <center><table border=1 cellpadding=8> |
---|
| 259 | <tr><td> |
---|
| 260 | <PRE> |
---|
| 261 | G4PVReplica repX("Linear Array", |
---|
| 262 | pRepLogical, |
---|
| 263 | pContainingMother, |
---|
| 264 | kXAxis, 5, 10*mm); |
---|
| 265 | |
---|
| 266 | G4PVReplica repR("RSlices", |
---|
| 267 | pRepRLogical, |
---|
| 268 | pContainingMother, |
---|
| 269 | kRho, 5, 10*mm, 0); |
---|
| 270 | |
---|
| 271 | G4PVReplica repRZ("RZSlices", |
---|
| 272 | pRepRZLogical, |
---|
| 273 | &repR, |
---|
| 274 | kZAxis, 5, 10*mm); |
---|
| 275 | |
---|
| 276 | G4PVReplica repRZPhi("RZPhiSlices", |
---|
| 277 | pRepRZPhiLogical, |
---|
| 278 | &repRZ, |
---|
| 279 | kPhi, 4, M_PI*0.5*rad, 0); |
---|
| 280 | </PRE> |
---|
| 281 | <tr> |
---|
| 282 | <td align=center> |
---|
| 283 | Source listing 4.1.2<BR> |
---|
| 284 | An example of simple replicated volumes with <tt>G4PVReplica</tt>. |
---|
| 285 | </table></center></P> |
---|
| 286 | <P> |
---|
| 287 | <tt>RepX</tt> is an array of 5 replicas of width 10*mm, positioned inside and |
---|
| 288 | completely filling the volume pointed by <tt>pContainingMother</tt>. |
---|
| 289 | The mother's X length must be 5*10*mm=50*mm (for example, if the mother's |
---|
| 290 | solid were a Box of half lengths [25,25,25] then the replica's solid must |
---|
| 291 | be a box of half lengths [25,25,5]).</P> |
---|
| 292 | <P> |
---|
| 293 | If the containing mother's solid is a tube of radius 50*mm and half Z length |
---|
| 294 | of 25*mm, <tt>RepR</tt> divides the mother tube into 5 cylinders (hence the |
---|
| 295 | solid associated with <tt>pRepRLogical</tt> must be a tube of radius 10*mm, and |
---|
| 296 | half Z length 25*mm); <tt>repRZ</tt> divides it into 5 shorter cylinders |
---|
| 297 | (the solid associated with <tt>pRepRZLogical</tt> must be a tube of radius |
---|
| 298 | 10*mm, and half Z length 5*mm); finally, <tt>repRZPhi</tt> divides it into 4 |
---|
| 299 | tube segments with full angle of 90 degrees (the solid associated with |
---|
| 300 | <tt>pRepRZPhiLogical</tt> must be a tube segment of |
---|
| 301 | radius 10*mm, half Z length 5*mm and delta phi of M_PI*0.5*rad).<BR> |
---|
| 302 | No further volumes may be placed inside these replicas. To do so would |
---|
| 303 | result in intersecting boundaries due to the <tt>r</tt> replications.</P> |
---|
| 304 | |
---|
| 305 | <P> </P> |
---|
| 306 | |
---|
| 307 | <b>Parameterised Volumes</b> |
---|
| 308 | <P> |
---|
| 309 | Parameterised Volumes are <i>repeated volumes</i> in the case in which the |
---|
| 310 | multiple copies of a volume can be different in size, solid type, or material. |
---|
| 311 | The solid's type, its dimensions, the material and the transformation matrix |
---|
| 312 | can all be parameterised in function of the copy number, both when a strong |
---|
| 313 | symmetry exist and when it does not. The user implements the desired |
---|
| 314 | parameterisation function and the program computes and updates automatically |
---|
| 315 | at run time the information associated to the Physical Volume.</P> |
---|
| 316 | <P> |
---|
| 317 | An example of creating a parameterised volume (by dimension and position) exists in novice |
---|
| 318 | example N02. The implementation is provided in the two classes <tt>ExN02DetectorConstruction</tt> |
---|
| 319 | and <tt>ExN02ChamberParameterisation</tt>.</P> |
---|
| 320 | <P> |
---|
| 321 | To create a parameterised volume, one must first create its logical volume |
---|
| 322 | like <tt>trackerChamberLV</tt> below. |
---|
| 323 | Then one must create his own parameterisation class |
---|
| 324 | (<i>ExN02ChamberParameterisation</i>) and instantiate an object of this class |
---|
| 325 | (<tt>chamberParam</tt>). We will see how to create the parameterisation below.</P> |
---|
| 326 | <P> |
---|
| 327 | <center><table border=1 cellpadding=8> |
---|
| 328 | <tr><td> |
---|
| 329 | <PRE> |
---|
| 330 | //------------------------------ |
---|
| 331 | // Tracker segments |
---|
| 332 | //------------------------------ |
---|
| 333 | // An example of Parameterised volumes |
---|
| 334 | // dummy values for G4Box -- modified by parameterised volume |
---|
| 335 | G4VSolid * solidChamber = |
---|
| 336 | new G4Box("chamberBox", 10.*cm, 10.*cm, 10.*cm); |
---|
| 337 | |
---|
| 338 | G4LogicalVolume * trackerChamberLV |
---|
| 339 | = new G4LogicalVolume(solidChamber, Aluminum, "trackerChamberLV"); |
---|
| 340 | G4VPVParameterisation * chamberParam |
---|
| 341 | = new ExN02ChamberParameterisation( |
---|
| 342 | 6, // NoChambers, |
---|
| 343 | -240.*cm, // Z of centre of first |
---|
| 344 | 80*cm, // Z spacing of centres |
---|
| 345 | 20*cm, // Width Chamber, |
---|
| 346 | 50*cm, // lengthInitial, |
---|
| 347 | trackerSize*2.); // lengthFinal |
---|
| 348 | |
---|
| 349 | G4VPhysicalVolume *trackerChamber_phys |
---|
| 350 | = new G4PVParameterised("TrackerChamber_parameterisedPV", |
---|
| 351 | trackerChamberLV, // Its logical volume |
---|
| 352 | logicTracker, // Mother logical volume |
---|
| 353 | kUndefined, // Allow default voxelising -- no axis |
---|
| 354 | 6, // Number of chambers |
---|
| 355 | chamberParam); // The parameterisation |
---|
| 356 | // "kUndefined" is the suggested choice, giving 3D voxelisation (i.e. along the three |
---|
| 357 | // cartesian axes, as is applied for placements. |
---|
| 358 | // |
---|
| 359 | // Note: In some cases where volume have clear separation along a single axis, |
---|
| 360 | // this axis (eg kZAxis) can be used to choose (force) optimisation only along |
---|
| 361 | // this axis in geometrical calculations. |
---|
| 362 | // When an axis is given it forces the use of one-dimensional voxelisation.</PRE> |
---|
| 363 | <tr> |
---|
| 364 | <td align=center> |
---|
| 365 | Source listing 4.1.3<BR> |
---|
| 366 | An example of Parameterised volumes. |
---|
| 367 | </table></center> |
---|
| 368 | |
---|
| 369 | The general constructor is: |
---|
| 370 | <PRE> |
---|
| 371 | G4PVParameterised( const G4String& pName, |
---|
| 372 | G4LogicalVolume* pCurrentLogical, |
---|
| 373 | G4LogicalVolume* pMotherLogical, // OR G4VPhysicalVolume* |
---|
| 374 | const EAxis pAxis, |
---|
| 375 | const G4int nReplicas, |
---|
| 376 | G4VPVParameterisation* pParam, |
---|
| 377 | G4bool pSurfChk=false ) |
---|
| 378 | </PRE></P> |
---|
| 379 | <P> |
---|
| 380 | Note that for a parameterised volume the user must always specify a mother |
---|
| 381 | volume. So the world volume can <I>never</I> be a parameterised volume, nor it can be sliced. |
---|
| 382 | The mother volume can be specified either as a physical or a logical volume.</P> |
---|
| 383 | <P> |
---|
| 384 | <tt>pAxis</tt> specifies the tracking optimisation algorithm to apply: if a valid axis |
---|
| 385 | (the axis along which the parameterisation is performed) is specified, a simple |
---|
| 386 | one-dimensional voxelisation algorithm is applied; if "kUndefined" is specified instead, |
---|
| 387 | the default three-dimensional voxelisation algorithm applied for normal placements |
---|
| 388 | will be activated. In the latter case, more voxels will be generated, therefore a |
---|
| 389 | greater amount of memory will be consumed by the optimisation algorithm.</P> |
---|
| 390 | <P> |
---|
| 391 | <tt>pSurfChk</tt> if <tt>true</tt> activates a check for overlaps with |
---|
| 392 | existing volumes or paramaterised instances.</P> |
---|
| 393 | <P> |
---|
| 394 | The parameterisation mechanism associated to a parameterised volume is defined |
---|
| 395 | in the parameterisation class and its methods. Every parameterisation must |
---|
| 396 | create two methods: |
---|
| 397 | |
---|
| 398 | <UL> |
---|
| 399 | <LI><tt>ComputeTransformation</tt> defines where one of the copies is placed, |
---|
| 400 | <LI><tt>ComputeDimensions</tt> defines the size of one copy, and |
---|
| 401 | <LI>a constructor that initializes any member variables that are required. |
---|
| 402 | </UL></P> |
---|
| 403 | <P> |
---|
| 404 | An example is <tt>ExN02ChamberParameterisation</tt> that parameterises a |
---|
| 405 | series of boxes of different sizes |
---|
| 406 | |
---|
| 407 | <center><table border=1 cellpadding=8> |
---|
| 408 | <tr><td> |
---|
| 409 | <PRE> |
---|
| 410 | class ExN02ChamberParameterisation : public G4VPVParameterisation |
---|
| 411 | { |
---|
| 412 | ... |
---|
| 413 | void ComputeTransformation(const G4int copyNo, |
---|
| 414 | G4VPhysicalVolume *physVol) const; |
---|
| 415 | |
---|
| 416 | void ComputeDimensions(G4Box& trackerLayer, |
---|
| 417 | const G4int copyNo, |
---|
| 418 | const G4VPhysicalVolume *physVol) const; |
---|
| 419 | ... |
---|
| 420 | } |
---|
| 421 | </PRE> |
---|
| 422 | <tr> |
---|
| 423 | <td align=center> |
---|
| 424 | Source listing 4.1.4<BR> |
---|
| 425 | An example of Parameterised boxes of different sizes. |
---|
| 426 | </table></center></P> |
---|
| 427 | <P> |
---|
| 428 | These methods works as follows:</P> |
---|
| 429 | <P> |
---|
| 430 | The <tt>ComputeTransformation</tt> method is called with a copy number for |
---|
| 431 | the instance of the parameterisation under consideration. It must |
---|
| 432 | compute the transformation for this copy, and set the physical volume to |
---|
| 433 | utilize this transformation: |
---|
| 434 | |
---|
| 435 | <PRE> |
---|
| 436 | void ExN02ChamberParameterisation::ComputeTransformation |
---|
| 437 | (const G4int copyNo,G4VPhysicalVolume *physVol) const |
---|
| 438 | { |
---|
| 439 | G4double Zposition= fStartZ + copyNo * fSpacing; |
---|
| 440 | G4ThreeVector origin(0,0,Zposition); |
---|
| 441 | physVol->SetTranslation(origin); |
---|
| 442 | physVol->SetRotation(0); |
---|
| 443 | } |
---|
| 444 | </PRE> |
---|
| 445 | Note that the translation and rotation given in this scheme are those for |
---|
| 446 | the frame of coordinates (the <I>passive</I> method). They are <b>not</b> |
---|
| 447 | for the <I>active</I> method, in which the solid is rotated into the mother |
---|
| 448 | frame of coordinates.</P> |
---|
| 449 | <P> |
---|
| 450 | Similarly the <tt>ComputeDimensions</tt> method is used to set the size of that copy. |
---|
| 451 | <PRE> |
---|
| 452 | void ExN02ChamberParameterisation::ComputeDimensions |
---|
| 453 | (G4Box & trackerChamber, const G4int copyNo, |
---|
| 454 | const G4VPhysicalVolume * physVol) const |
---|
| 455 | { |
---|
| 456 | G4double halfLength= fHalfLengthFirst + (copyNo-1) * fHalfLengthIncr; |
---|
| 457 | trackerChamber.SetXHalfLength(halfLength); |
---|
| 458 | trackerChamber.SetYHalfLength(halfLength); |
---|
| 459 | trackerChamber.SetZHalfLength(fHalfWidth); |
---|
| 460 | } |
---|
| 461 | </PRE> |
---|
| 462 | The user must ensure that the type of the first argument of this method (in this |
---|
| 463 | example <tt>G4Box &</tt>) corresponds to the type of object the user give to |
---|
| 464 | the logical volume of parameterised physical volume.</P> |
---|
| 465 | <P> |
---|
| 466 | More advanced usage allows the user: |
---|
| 467 | <UL> |
---|
| 468 | <LI>to change the type of solid by creating a <tt>ComputeSolid</tt> method, or |
---|
| 469 | <LI>to change the material of the volume by creating a <tt>ComputeMaterial</tt> method. |
---|
| 470 | This method can also utilise information from a parent or other ancestor |
---|
| 471 | volume (see the Nested Parameterisation below.) |
---|
| 472 | </UL> |
---|
| 473 | for the parameterisation.<BR> |
---|
| 474 | Example N07 shows a simple parameterisation by material. A more complex example |
---|
| 475 | is provided in <TT>examples/extended/medical/DICOM</TT>, where a phantom grid |
---|
| 476 | of cells is built using a parameterisation by material defined through a map.</P> |
---|
| 477 | <P> |
---|
| 478 | <B>Note</B> - Currently for many cases it is not possible to add daughter |
---|
| 479 | volumes to a parameterised volume. Only parameterised volumes |
---|
| 480 | all of whose solids have the same size are allowed |
---|
| 481 | to contain daughter volumes. When the size or type of solid varies, adding |
---|
| 482 | daughters is not supported. <BR> |
---|
| 483 | So the full power of parameterised volumes can be used only for "leaf" |
---|
| 484 | volumes, which contain no other volumes.</P> |
---|
| 485 | |
---|
| 486 | <P> </P> |
---|
| 487 | <b>Advanced parameterisations for 'nested' parameterised volumes </b> |
---|
| 488 | <p> |
---|
| 489 | A new type of parameterisation enables a user to have the daughter's material |
---|
| 490 | also depend on the copy number of the parent when a parameterised volume (daughter) |
---|
| 491 | is located inside another (parent) repeated volume. The parent volume can be a |
---|
| 492 | replica, a parameterised volume, or a division if the key feature of modifying |
---|
| 493 | its contents is utilised. (Note: a 'nested' parameterisation inside a placement |
---|
| 494 | volume is not supported, because all copies of a placement volume must be identical |
---|
| 495 | at all levels.) |
---|
| 496 | </p> |
---|
| 497 | <p> |
---|
| 498 | In such a " nested" parameterisation , the user must provide a |
---|
| 499 | <tt>ComputeMaterial</tt> method that utilises the new argument that represents |
---|
| 500 | the touchable history of the parent volume: |
---|
| 501 | </p> |
---|
| 502 | <pre> |
---|
| 503 | // Sample Parameterisation |
---|
| 504 | class SampleNestedParameterisation : public G4VNestedParameterisation |
---|
| 505 | { |
---|
| 506 | public: |
---|
| 507 | // .. other methods ... |
---|
| 508 | // Mandatory method, required and reason for this class |
---|
| 509 | virtual G4Material* ComputeMaterial(G4VPhysicalVolume *currentVol, |
---|
| 510 | const G4int no_lev, |
---|
| 511 | const G4VTouchable *parentTouch); |
---|
| 512 | private: |
---|
| 513 | G4Material *material1, *material2; |
---|
| 514 | }; |
---|
| 515 | </pre> |
---|
| 516 | <p> |
---|
| 517 | The implementation of the method can utilise any information |
---|
| 518 | from a parent or other ancestor volume of its parameterised physical volume, |
---|
| 519 | but typically it will use only the copy number: |
---|
| 520 | </p> |
---|
| 521 | <pre> |
---|
| 522 | G4Material* |
---|
| 523 | SampleNestedParameterisation::ComputeMaterial(G4VPhysicalVolume *currentVol, |
---|
| 524 | const G4int no_lev, |
---|
| 525 | const G4VTouchable *parentTouchable) |
---|
| 526 | { |
---|
| 527 | G4Material *material=0; |
---|
| 528 | |
---|
| 529 | // Get the information about the parent volume |
---|
| 530 | G4int no_parent= parentTouchable->GetReplicaNumber(); |
---|
| 531 | G4int no_total= no_parent + no_lev; |
---|
| 532 | // A simple 'checkerboard' pattern of two materials |
---|
| 533 | if( no_total / 2 == 1 ) material= material1; |
---|
| 534 | else material= material2; |
---|
| 535 | // Set the material to the current logical volume |
---|
| 536 | G4LogicalVolume* currentLogVol= currentVol->GetLogicalVolume(); |
---|
| 537 | currentLogVol->SetMaterial( material ); |
---|
| 538 | return material; |
---|
| 539 | } |
---|
| 540 | </pre> |
---|
| 541 | <p> |
---|
| 542 | Nested parameterisations are suitable for the case of regular, 'voxel' |
---|
| 543 | geometries in which a large number of 'equal' volumes are required, |
---|
| 544 | and their only difference is in their material. By creating two (or more) |
---|
| 545 | levels of parameterised physical volumes it is possible to divide space, |
---|
| 546 | while requiring only limited additional memory for very fine-level |
---|
| 547 | optimisation. This provides fast navigation. Alternative implementations, |
---|
| 548 | taking into account the regular structure of such geometries in |
---|
| 549 | navigation are under study. |
---|
| 550 | </p> |
---|
| 551 | |
---|
| 552 | <P></P> |
---|
| 553 | <b>Divisions of Volumes</b> |
---|
| 554 | <P> |
---|
| 555 | Divisions in Geant4 are implemented as a specialized type of parameterised volumes. |
---|
| 556 | <br> |
---|
| 557 | They serve to divide a volume into identical copies along one of its axes, |
---|
| 558 | providing the possibility to define an <i>offset</i>, and without the |
---|
| 559 | limitation that the daugthers have to fill the mother volume as it is the |
---|
| 560 | case for the replicas. |
---|
| 561 | In the case, for example, of a tube divided along its radial axis, |
---|
| 562 | the copies are not strictly identical, but have increasing radii, although |
---|
| 563 | their widths are constant. |
---|
| 564 | </p> |
---|
| 565 | <p> |
---|
| 566 | To divide a volume it will be necessary to provide: |
---|
| 567 | <OL> |
---|
| 568 | <LI>the axis of division, and</LI> |
---|
| 569 | <LI>either |
---|
| 570 | <UL> |
---|
| 571 | <LI>the number of divisions (so that the width of each division will be automatically |
---|
| 572 | calculated), or</LI> |
---|
| 573 | <LI>the division width (so that the number of divisions will be automatically calculated |
---|
| 574 | to fill as much of the mother as possible), or</LI> |
---|
| 575 | <LI>both the number of divisions and the division width (this is especially designed for |
---|
| 576 | the case where the copies do not fully fill the mother).</LI> |
---|
| 577 | </UL></LI> |
---|
| 578 | </OL></P> |
---|
| 579 | <P> |
---|
| 580 | An <i>offset</i> can be defined so that the first copy will start at some |
---|
| 581 | distance from the mother wall. The dividing copies will be then distributed to occupy the rest |
---|
| 582 | of the volume.</P> |
---|
| 583 | <P> |
---|
| 584 | There are three constructors, corresponding to the three input possibilities described above: |
---|
| 585 | <UL> |
---|
| 586 | <LI>Giving only the number of divisions: |
---|
| 587 | <PRE> |
---|
| 588 | G4PVDivision( const G4String& pName, |
---|
| 589 | G4LogicalVolume* pCurrentLogical, |
---|
| 590 | G4LogicalVolume* pMotherLogical, |
---|
| 591 | const EAxis pAxis, |
---|
| 592 | const G4int nDivisions, |
---|
| 593 | const G4double offset ) |
---|
| 594 | </PRE></LI> |
---|
| 595 | <LI>Giving only the division width: |
---|
| 596 | <PRE> |
---|
| 597 | G4PVDivision( const G4String& pName, |
---|
| 598 | G4LogicalVolume* pCurrentLogical, |
---|
| 599 | G4LogicalVolume* pMotherLogical, |
---|
| 600 | const EAxis pAxis, |
---|
| 601 | const G4double width, |
---|
| 602 | const G4double offset ) |
---|
| 603 | </PRE></LI> |
---|
| 604 | <LI>Giving the number of divisions and the division width: |
---|
| 605 | <PRE> |
---|
| 606 | G4PVDivision( const G4String& pName, |
---|
| 607 | G4LogicalVolume* pCurrentLogical, |
---|
| 608 | G4LogicalVolume* pMotherLogical, |
---|
| 609 | const EAxis pAxis, |
---|
| 610 | const G4int nDivisions, |
---|
| 611 | const G4double width, |
---|
| 612 | const G4double offset ) |
---|
| 613 | </PRE></LI> |
---|
| 614 | </UL></P> |
---|
| 615 | <P> |
---|
| 616 | where:</P> |
---|
| 617 | <P> |
---|
| 618 | <table border=1 cellpadding=8> |
---|
| 619 | <tr> |
---|
| 620 | <td><tt>pName</tt> <td>String identifier for the replicated volume |
---|
| 621 | <tr> |
---|
| 622 | <td><tt>pCurrentLogical</tt> <td>The associated Logical Volume |
---|
| 623 | <tr> |
---|
| 624 | <td><tt>pMotherLogical</tt> <td>The associated mother Logical Volume |
---|
| 625 | <tr> |
---|
| 626 | <td><tt>pAxis</tt> <td>The axis along which the division is applied |
---|
| 627 | <tr> |
---|
| 628 | <td><tt>nDivisions</tt> <td>The number of divisions |
---|
| 629 | <tr> |
---|
| 630 | <td><tt>width</tt> <td>The width of a single division along the axis |
---|
| 631 | <tr> |
---|
| 632 | <td><tt>offset</tt> <td>Possible offset associated to the mother along |
---|
| 633 | the axis of division |
---|
| 634 | </table></P> |
---|
| 635 | <P> |
---|
| 636 | The parameterisation is calculated automatically using the values provided in input. |
---|
| 637 | Therefore the dimensions of the solid associated with <tt>pCurrentLogical</tt> will not be used, |
---|
| 638 | but recomputed through the <tt>G4VParameterisation::ComputeDimension()</tt> method.</P> |
---|
| 639 | <P> |
---|
| 640 | Since <tt>G4VPVParameterisation</tt> may have different <tt>ComputeDimension()</tt> methods for |
---|
| 641 | each solid type, the user must provide a solid that is of the same type as of the one |
---|
| 642 | associated to the mother volume.</P> |
---|
| 643 | <P> |
---|
| 644 | As for any replica, the coordinate system of the divisions is related to the centre of each division |
---|
| 645 | for the cartesian axis. For the radial axis, the coordinate system is the same of the mother volume. |
---|
| 646 | For the phi axis, the new coordinate system is rotated such that the X axis bisects the angle |
---|
| 647 | made by each wedge, and Z remains parallel to the mother's Z axis.</P> |
---|
| 648 | <P> |
---|
| 649 | As divisions are parameterised volumes with constant dimensions, they may be placed inside |
---|
| 650 | other divisions, except in the case of divisions along the radial axis.<BR> |
---|
| 651 | It is also possible to place other volumes inside a volume where a division is placed.</P> |
---|
| 652 | <p> |
---|
| 653 | The list of volumes that currently support divisioning and the possible division axis |
---|
| 654 | are summarised below:</P> |
---|
| 655 | <P> |
---|
| 656 | <table border=1 cellpadding=8> |
---|
| 657 | <tr> |
---|
| 658 | <td><tt>G4Box</tt> <td><tt>kXAxis</tt>, <tt>kYAxis</tt>, <tt>kZAxis</tt> |
---|
| 659 | <tr> |
---|
| 660 | <td><tt>G4Tubs</tt> <td><tt>kRho</tt>, <tt>kPhi</tt>, <tt>kZAxis</tt> |
---|
| 661 | <tr> |
---|
| 662 | <td><tt>G4Cons</tt> <td><tt>kRho</tt>, <tt>kPhi</tt>, <tt>kZAxis</tt> |
---|
| 663 | <tr> |
---|
| 664 | <td><tt>G4Trd</tt> <td><tt>kXAxis</tt>, <tt>kYAxis</tt>, <tt>kZAxis</tt> |
---|
| 665 | <tr> |
---|
| 666 | <td><tt>G4Para</tt> <td><tt>kXAxis</tt>, <tt>kYAxis</tt>, <tt>kZAxis</tt> |
---|
| 667 | <tr> |
---|
| 668 | <td><tt>G4Polycone</tt> <td><tt>kRho</tt>, <tt>kPhi</tt>, <tt>kZAxis</tt> (*) |
---|
| 669 | <tr> |
---|
| 670 | <td><tt>G4Polyhedra</tt> <td><tt>kRho</tt>, <tt>kPhi</tt>, <tt>kZAxis</tt> (**) |
---|
| 671 | </table></P> |
---|
| 672 | <P> |
---|
| 673 | (*) - <tt>G4Polycone</tt>: |
---|
| 674 | <UL> |
---|
| 675 | <LI><tt>kZAxis</tt> - the number of divisions has to be the same as solid sections, |
---|
| 676 | (i.e. <tt>numZPlanes-1</tt>), the width will <i>not</i> be taken into account.</LI> |
---|
| 677 | </UL> |
---|
| 678 | (**) - <tt>G4Polyhedra</tt>: |
---|
| 679 | <UL> |
---|
| 680 | <LI><tt>kPhi</tt> - the number of divisions has to be the same as solid sides, |
---|
| 681 | (i.e. <tt>numSides</tt>), the width will <i>not</i> be taken into account.</LI> |
---|
| 682 | <LI><tt>kZAxis</tt> - the number of divisions has to be the same as solid sections, |
---|
| 683 | (i.e. <tt>numZPlanes-1</tt>), the width will <i>not</i> be taken into account.</LI> |
---|
| 684 | </UL></P> |
---|
| 685 | |
---|
| 686 | <P> |
---|
| 687 | In the case of division along <tt>kRho</tt> of <tt>G4Cons</tt>, <tt>G4Polycone</tt>, |
---|
| 688 | <tt>G4Polyhedra</tt>, if width is provided, it is taken as the width at the <tt>-Z</tt> |
---|
| 689 | radius; the width at other radii will be scaled to this one.<BR> |
---|
| 690 | |
---|
| 691 | Examples are given below in listings 4.1.4 and 4.1.5.</P> |
---|
| 692 | <P> |
---|
| 693 | <center><table border=1 cellpadding=8> |
---|
| 694 | <tr><td> |
---|
| 695 | <PRE> |
---|
| 696 | G4Box* motherSolid = new G4Box("motherSolid", 0.5*m, 0.5*m, 0.5*m); |
---|
| 697 | G4LogicalVolume* motherLog = new G4LogicalVolume(motherSolid, material, "mother",0,0,0); |
---|
| 698 | G4Para* divSolid = new G4Para("divSolid", 0.512*m, 1.21*m, 1.43*m); |
---|
| 699 | G4LogicalVolume* childLog = new G4LogicalVolume(divSolid, material, "child",0,0,0); |
---|
| 700 | |
---|
| 701 | G4PVDivision divBox1("division along X giving nDiv", |
---|
| 702 | childLog, motherLog, kXAxis, 5, 0.); |
---|
| 703 | |
---|
| 704 | G4PVDivision divBox2("division along X giving width and offset", |
---|
| 705 | childLog, motherLog, kXAxis, 0.1*m, 0.45*m); |
---|
| 706 | |
---|
| 707 | G4PVDivision divBox3("division along X giving nDiv, width and offset", |
---|
| 708 | childLog, motherLog, kXAxis, 3, 0.1*m, 0.5*m); |
---|
| 709 | </PRE> |
---|
| 710 | <tr> |
---|
| 711 | <td align=center> |
---|
| 712 | Source listing 4.1.5<BR> |
---|
| 713 | An example of a box division along different axes, with or without offset. |
---|
| 714 | </table></center></P> |
---|
| 715 | <P> |
---|
| 716 | <ul> |
---|
| 717 | <li><tt>divBox1</tt> is a division of a box along its <tt>X</tt> axis in 5 equal copies. |
---|
| 718 | Each copy will have a dimension in meters of <tt>[0.2, 1., 1.]</tt>.</li> |
---|
| 719 | <li><tt>divBox2</tt> is a division of the same box along its <tt>X</tt> axis with a width of |
---|
| 720 | <tt>0.1</tt> meters and an offset of <tt>0.5</tt> meters. As the mother dimension along |
---|
| 721 | <tt>X</tt> of <tt>1</tt> meter (<tt>0.5*m</tt> of halflength), the division will be sized |
---|
| 722 | in total <tt>1 - 0.45 = 0.55</tt> meters. Therefore, there's space for 5 copies, |
---|
| 723 | the first extending from <tt>-0.05</tt> to <tt>0.05</tt> meters in the mother's frame and |
---|
| 724 | the last from <tt>0.35</tt> to <tt>0.45</tt> meters.</li> |
---|
| 725 | <li><tt>divBox3</tt> is a division of the same box along its <tt>X</tt> axis in 3 equal copies of width |
---|
| 726 | <tt>0.1</tt> meters and an offset of <tt>0.5</tt> meters. The first copy will extend from |
---|
| 727 | <tt>0.</tt> to <tt>0.1</tt> meters in the mother's frame and the last from <tt>0.2</tt> |
---|
| 728 | to <tt>0.3</tt> meters.</li> |
---|
| 729 | </ul></P> |
---|
| 730 | <P> |
---|
| 731 | <center><table border=1 cellpadding=8> |
---|
| 732 | <tr><td> |
---|
| 733 | <PRE> |
---|
| 734 | G4double* zPlanem = new G4double[3]; |
---|
| 735 | zPlanem[0]= -1.*m; |
---|
| 736 | zPlanem[1]= -0.25*m; |
---|
| 737 | zPlanem[2]= 1.*m; |
---|
| 738 | G4double* rInnerm = new G4double[3]; |
---|
| 739 | rInnerm[0]=0.; |
---|
| 740 | rInnerm[1]=0.1*m; |
---|
| 741 | rInnerm[2]=0.5*m; |
---|
| 742 | G4double* rOuterm = new G4double[3]; |
---|
| 743 | rOuterm[0]=0.2*m; |
---|
| 744 | rOuterm[1]=0.4*m; |
---|
| 745 | rOuterm[2]=1.*m; |
---|
| 746 | G4Polycone* motherSolid = new G4Polycone("motherSolid", 20.*deg, 180.*deg, |
---|
| 747 | 3, zPlanem, rInnerm, rOuterm); |
---|
| 748 | G4LogicalVolume* motherLog = new G4LogicalVolume(motherSolid, material, "mother",0,0,0); |
---|
| 749 | |
---|
| 750 | G4double* zPlaned = new G4double[3]; |
---|
| 751 | zPlaned[0]= -3.*m; |
---|
| 752 | zPlaned[1]= -0.*m; |
---|
| 753 | zPlaned[2]= 1.*m; |
---|
| 754 | G4double* rInnerd = new G4double[3]; |
---|
| 755 | rInnerd[0]=0.2; |
---|
| 756 | rInnerd[1]=0.4*m; |
---|
| 757 | rInnerd[2]=0.5*m; |
---|
| 758 | G4double* rOuterd = new G4double[3]; |
---|
| 759 | rOuterd[0]=0.5*m; |
---|
| 760 | rOuterd[1]=0.8*m; |
---|
| 761 | rOuterd[2]=2.*m; |
---|
| 762 | G4Polycone* divSolid = new G4Polycone("divSolid", 0.*deg, 10.*deg, |
---|
| 763 | 3, zPlaned, rInnerd, rOuterd); |
---|
| 764 | G4LogicalVolume* childLog = new G4LogicalVolume(divSolid, material, "child",0,0,0); |
---|
| 765 | |
---|
| 766 | G4PVDivision divPconePhiW("division along phi giving width and offset", |
---|
| 767 | childLog, motherLog, kPhi, 30.*deg, 60.*deg); |
---|
| 768 | |
---|
| 769 | G4PVDivision divPconeZN("division along Z giving nDiv and offset", |
---|
| 770 | childLog, motherLog, kZAxis, 2, 0.1*m); |
---|
| 771 | </PRE> |
---|
| 772 | <tr> |
---|
| 773 | <td align=center> |
---|
| 774 | Source listing 4.1.6<BR> |
---|
| 775 | An example of division of a polycone. |
---|
| 776 | </table></center></P> |
---|
| 777 | <P> |
---|
| 778 | <ul> |
---|
| 779 | <li><tt>divPconePhiW</tt> is a division of a polycone along its <tt>phi</tt> axis in equal |
---|
| 780 | copies of width 30 degrees with an offset of 60 degrees. As the mother extends from |
---|
| 781 | 0 to 180 degrees, there's space for 4 copies. All the copies have a starting angle |
---|
| 782 | of 20 degrees (as for the mother) and a <tt>phi</tt> extension of 30 degrees. |
---|
| 783 | They are rotated around the <tt>Z</tt> axis by 60 and 30 degrees, |
---|
| 784 | so that the first copy will extend from 80 to 110 and the last from 170 to 200 degrees.</li> |
---|
| 785 | <li><tt>divPconeZN</tt> is a division of the same polycone along its <tt>Z</tt> axis. As the mother |
---|
| 786 | polycone has two sections, it will be divided in two one-section polycones, the first |
---|
| 787 | one extending from -1 to -0.25 meters, the second from -0.25 to 1 meters. |
---|
| 788 | Although specified, the offset will not be used.</li> |
---|
| 789 | </ul></p> |
---|
| 790 | |
---|
| 791 | <hr><a href="../../../../Authors/html/subjectsToAuthors.html"> |
---|
| 792 | <i>About the authors</a></i> </P> |
---|
| 793 | |
---|
| 794 | </body> |
---|
| 795 | </html> |
---|