|
|
|||
File indexing completed on 2026-04-01 08:18:57
0001 //========================================================================== 0002 // AIDA Detector description implementation 0003 //-------------------------------------------------------------------------- 0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) 0005 // All rights reserved. 0006 // 0007 // For the licensing terms see $DD4hepINSTALL/LICENSE. 0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS. 0009 // 0010 // Author : M.Frank 0011 // 0012 //========================================================================== 0013 #ifndef DDG4_GEANT4SENSDETACTION_H 0014 #define DDG4_GEANT4SENSDETACTION_H 0015 0016 // Framework include files 0017 #include <DD4hep/Detector.h> 0018 #include <DDG4/Geant4Action.h> 0019 #include <DDG4/Geant4HitCollection.h> 0020 0021 // Geant4 include files 0022 #include <G4ThreeVector.hh> 0023 #include <G4VTouchable.hh> 0024 0025 // C/C++ include files 0026 #include <vector> 0027 0028 // Forward declarations 0029 class G4HCofThisEvent; 0030 class G4Step; 0031 class G4Event; 0032 class G4TouchableHistory; 0033 class G4VHitsCollection; 0034 class G4VReadOutGeometry; 0035 0036 /// Namespace for the AIDA detector description toolkit 0037 namespace dd4hep { 0038 0039 // Forward declarations 0040 class Detector; 0041 class DetElement; 0042 class SensitiveDetector; 0043 0044 /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit 0045 namespace sim { 0046 0047 // Forward declarations 0048 class Geant4Sensitive; 0049 class Geant4FastSimSpot; 0050 class Geant4StepHandler; 0051 class Geant4HitCollection; 0052 class Geant4SensDetActionSequence; 0053 class Geant4SensDetSequences; 0054 0055 /// Interface class to access properties of the underlying Geant4 sensitive detector structure 0056 /** 0057 * \author M.Frank 0058 * \version 1.0 0059 * \ingroup DD4HEP_SIMULATION 0060 */ 0061 class Geant4ActionSD: virtual public Geant4Action { 0062 protected: 0063 /// Define standard assignments and constructors 0064 DDG4_DEFINE_ACTION_CONSTRUCTORS(Geant4ActionSD); 0065 /// Standard action constructor 0066 Geant4ActionSD(const std::string& name); 0067 /// Default destructor 0068 virtual ~Geant4ActionSD(); 0069 public: 0070 /// Initialize the usage of a hit collection. Returns the collection identifier 0071 virtual std::size_t defineCollection(const std::string& name) = 0; 0072 /// Access to the readout geometry of the sensitive detector 0073 virtual G4VReadOutGeometry* readoutGeometry() const = 0; 0074 /// This is a utility method which returns the hits collection ID 0075 virtual G4int GetCollectionID(G4int i) = 0; 0076 /// Is the detector active? 0077 virtual bool isActive() const = 0; 0078 /// Access to the Detector sensitive detector handle 0079 virtual SensitiveDetector sensitiveDetector() const = 0; 0080 /// G4VSensitiveDetector internals: Access to the detector path name 0081 virtual std::string path() const = 0; 0082 /// G4VSensitiveDetector internals: Access to the detector path name 0083 virtual std::string fullPath() const = 0; 0084 /// Access to the sensitive type of the detector 0085 virtual const std::string& sensitiveType() const = 0; 0086 /// Access the DDG4 action sequence 0087 virtual Geant4SensDetActionSequence* sequence() const = 0; 0088 }; 0089 0090 /// Base class to construct filters for Geant4 sensitive detectors 0091 /** 0092 * \author M.Frank 0093 * \version 1.0 0094 * \ingroup DD4HEP_SIMULATION 0095 */ 0096 class Geant4Filter: public Geant4Action { 0097 protected: 0098 /// Define standard assignments and constructors 0099 DDG4_DEFINE_ACTION_CONSTRUCTORS(Geant4Filter); 0100 0101 public: 0102 /// Standard constructor 0103 Geant4Filter(Geant4Context* context, const std::string& name); 0104 /// Standard destructor 0105 virtual ~Geant4Filter(); 0106 0107 /// Filter action. Return true if hits should be processed. Default returns true 0108 virtual bool operator()(const G4Step* step) const; 0109 0110 /// GFLASH/FastSim interface: Filter action. Return true if hits should be processed. 0111 /** The default implementation throws an exception that the 0112 * GFLASH / FastSim interface is not implemented. 0113 */ 0114 virtual bool operator()(const Geant4FastSimSpot* spot) const; 0115 }; 0116 0117 /// The base class for Geant4 sensitive detector actions implemented by users 0118 /** 0119 * \author M.Frank 0120 * \version 1.0 0121 * \ingroup DD4HEP_SIMULATION 0122 */ 0123 class Geant4Sensitive: public Geant4Action { 0124 public: 0125 enum HitCreationFlags { 0126 SIMPLE_MODE = 0, 0127 MEDIUM_MODE = 1<<0, 0128 DETAILED_MODE = 1<<1 0129 }; 0130 0131 private: 0132 /// Reference to G4 sensitive detector 0133 Geant4ActionSD* m_sensitiveDetector { nullptr }; 0134 /// Reference to the containing action sequence 0135 Geant4SensDetActionSequence* m_sequence { nullptr }; 0136 0137 protected: 0138 /// Property: Hit creation mode. Maybe one of the enum HitCreationFlags 0139 int m_hitCreationMode { 0 }; 0140 /// Property: Use the volume manager to access CellID and VolumeID 0141 bool m_useVolumeManager { true }; 0142 0143 #if defined(G__ROOT) || defined(__CLING__) || defined(__ROOTCLING__) 0144 /// Reference to the detector description object 0145 Detector* m_detDesc { nullptr }; 0146 #else 0147 /// Reference to the detector description object 0148 Detector& m_detDesc; 0149 #endif 0150 /// Reference to the detector element describing this sensitive element 0151 DetElement m_detector { }; 0152 /// Reference to the sensitive detector element 0153 SensitiveDetector m_sensitive { }; 0154 /// Reference to the readout structure 0155 Readout m_readout { }; 0156 /// Reference to segmentation 0157 Segmentation m_segmentation { }; 0158 /// The list of sensitive detector filter objects 0159 Actors<Geant4Filter> m_filters; 0160 0161 /// Define standard assignments and constructors 0162 DDG4_DEFINE_ACTION_CONSTRUCTORS(Geant4Sensitive); 0163 0164 public: 0165 /// Constructor. The sensitive detector element is identified by the detector name 0166 Geant4Sensitive(Geant4Context* context, const std::string& name, DetElement det, Detector& description); 0167 0168 /// Standard destructor 0169 virtual ~Geant4Sensitive(); 0170 0171 /// Get the detector identifier (DetElement::id()) 0172 int id() const; 0173 0174 /// Access to the sensitive detector object 0175 Geant4ActionSD& detector() const; 0176 0177 /// Access to the sensitive detector object 0178 void setDetector(Geant4ActionSD* sens_det); 0179 0180 /// Access volume manager usage flag. This is a subdetector specific flag 0181 bool useVolumeManager() const { 0182 return m_useVolumeManager; 0183 } 0184 0185 /// Property access to the hit creation mode 0186 int hitCreationMode() const { 0187 return m_hitCreationMode; 0188 } 0189 0190 /// G4VSensitiveDetector internals: Access to the detector name 0191 std::string detectorName() const { 0192 return detector().name(); 0193 } 0194 0195 /// G4VSensitiveDetector internals: Access to the detector path name 0196 std::string path() const { 0197 return detector().path(); 0198 } 0199 0200 /// G4VSensitiveDetector internals: Access to the detector path name 0201 std::string fullPath() const { 0202 return detector().fullPath(); 0203 } 0204 0205 /// G4VSensitiveDetector internals: Is the detector active? 0206 bool isActive() const { 0207 return detector().isActive(); 0208 } 0209 0210 /// Access the dd4hep sensitive detector 0211 SensitiveDetector sensitiveDetector() const { 0212 return m_sensitive; 0213 } 0214 0215 /// Access to the readout geometry of the sensitive detector 0216 G4VReadOutGeometry* readoutGeometry() const { 0217 return detector().readoutGeometry(); 0218 } 0219 0220 /// Access the detector description object 0221 Detector& detectorDescription() const; 0222 0223 /// Mark the track to be kept for MC truth propagation during hit processing 0224 void mark(const G4Track* track) const; 0225 0226 /// Mark the track of this step to be kept for MC truth propagation during hit processing 0227 void mark(const G4Step* step) const; 0228 0229 /// Access to the hosting sequence 0230 Geant4SensDetActionSequence& sequence() const; 0231 0232 /// Add an actor responding to all callbacks. Sequence takes ownership. 0233 void adopt(Geant4Filter* filter); 0234 0235 /// Add an actor responding to all callbacks to the sequence front. Sequence takes ownership. 0236 void adopt_front(Geant4Filter* filter); 0237 0238 /// Add an actor responding to all callbacks. Sequence takes ownership. 0239 void adoptFilter(Geant4Action* filter); 0240 0241 /// Add an actor responding to all callbacks to the sequence front. Sequence takes ownership. 0242 void adoptFilter_front(Geant4Action* filter); 0243 0244 /// Callback before hit processing starts. Invoke all filters. 0245 /** Return false if any filter returns false 0246 */ 0247 bool accept(const G4Step* step) const; 0248 0249 /// GFLASH/FastSim interface: Callback before hit processing starts. Invoke all filters. 0250 /** Return false if any filter returns false 0251 */ 0252 bool accept(const Geant4FastSimSpot* step) const; 0253 0254 /// Initialize the usage of a single hit collection. Returns the collection ID 0255 template <typename TYPE> std::size_t defineCollection(const std::string& coll_name); 0256 0257 /// Access HitCollection container names 0258 const std::string& hitCollectionName(std::size_t which) const; 0259 0260 /// Retrieve the hits collection associated with this detector by its serial number 0261 Geant4HitCollection* collection(std::size_t which); 0262 0263 /// Retrieve the hits collection associated with this detector by its collection identifier 0264 Geant4HitCollection* collectionByID(std::size_t id); 0265 0266 /// Define collections created by this sensitivie action object 0267 virtual void defineCollections(); 0268 0269 /// G4VSensitiveDetector interface: Method invoked at the beginning of each event. 0270 /** The hits collection(s) created by this sensitive detector must 0271 * be set to the G4HCofThisEvent object at one of these two methods. 0272 */ 0273 virtual void begin(G4HCofThisEvent* hce); 0274 0275 /// G4VSensitiveDetector interface: Method invoked at the end of each event. 0276 virtual void end(G4HCofThisEvent* hce); 0277 0278 /// G4VSensitiveDetector interface: Method invoked if the event was aborted. 0279 /** Hits collections created but not being set to G4HCofThisEvent 0280 * at the event should be deleted. 0281 * Collection(s) which have already set to G4HCofThisEvent 0282 * will be deleted automatically. 0283 */ 0284 virtual void clear(G4HCofThisEvent* hce); 0285 0286 /// Returns the volumeID of the sensitive volume corresponding to the step 0287 /** Combining the VolIDS of the complete geometry path (Geant4TouchableHistory) 0288 * from the current sensitive volume to the world volume 0289 */ 0290 long long int volumeID(const G4Step* step); 0291 0292 /// Returns the volumeID of the sensitive volume corresponding to the G4VTouchable 0293 /** Combining the VolIDS of the complete geometry path (Geant4TouchableHistory) 0294 * from the current sensitive volume to the world volume 0295 */ 0296 long long int volumeID(const G4VTouchable* touchable); 0297 0298 /// Returns the cellID of the sensitive volume corresponding to the step 0299 /** The CellID is the VolumeID + the local coordinates of the sensitive area. 0300 * Calculated by combining the VolIDS of the complete geometry path (Geant4TouchableHistory) 0301 * from the current sensitive volume to the world volume 0302 */ 0303 long long int cellID(const G4Step* step); 0304 0305 /// Returns the cellID of the sensitive volume corresponding to the G4VTouchable 0306 /** The CellID is the VolumeID + the local coordinates of the sensitive area. 0307 * Calculated by combining the VolIDS of the complete geometry path (Geant4TouchableHistory) 0308 * from the current sensitive volume to the world volume 0309 */ 0310 long long int cellID(const G4VTouchable* touchable, const G4ThreeVector& global); 0311 0312 /// G4VSensitiveDetector interface: Method for generating hit(s) using the information of G4Step object. 0313 virtual bool process(const G4Step* step, G4TouchableHistory* history); 0314 0315 /// GFLASH/FastSim interface: Method for generating hit(s) using the information of the fast simulation spot object. 0316 /** The default implementation throws an exception that the 0317 * GFLASH/FastSim interface is not implemented. 0318 */ 0319 virtual bool processFastSim(const Geant4FastSimSpot* spot, G4TouchableHistory* history); 0320 }; 0321 0322 /// The sequencer to host Geant4 sensitive actions called if particles interact with sensitive elements 0323 /** 0324 * Concrete implementation of the sensitive detector action sequence 0325 * 0326 * \author M.Frank 0327 * \version 1.0 0328 * \ingroup DD4HEP_SIMULATION 0329 */ 0330 class Geant4SensDetActionSequence : public Geant4Action { 0331 public: 0332 typedef Geant4HitCollection* (*create_t)(const std::string&, const std::string&, Geant4Sensitive*); 0333 typedef std::pair<std::string, std::pair<Geant4Sensitive*,create_t> > HitCollection; 0334 typedef std::vector<HitCollection> HitCollections; 0335 0336 protected: 0337 /// Geant4 hit collection context 0338 G4HCofThisEvent* m_hce { nullptr }; 0339 /// Callback sequence for event initialization action 0340 CallbackSequence m_begin; 0341 /// Callback sequence for event finalization action 0342 CallbackSequence m_end; 0343 /// Callback sequence for step processing 0344 CallbackSequence m_process; 0345 /// Callback sequence to invoke the event deletion 0346 CallbackSequence m_clear; 0347 /// The list of sensitive detector objects 0348 Actors<Geant4Sensitive> m_actors; 0349 /// The list of sensitive detector filter objects 0350 Actors<Geant4Filter> m_filters; 0351 0352 /// Hit collection creators 0353 HitCollections m_collections; 0354 /// Reference to the sensitive detector element 0355 SensitiveDetector m_sensitive; 0356 /// Reference to G4 sensitive detector 0357 Geant4ActionSD* m_detector; 0358 /// The true sensitive type of the detector 0359 std::string m_sensitiveType; 0360 /// Create a new typed hit collection 0361 template <typename TYPE> static 0362 Geant4HitCollection* _create(const std::string& det, const std::string& coll, Geant4Sensitive* sd) { 0363 return new Geant4HitCollection(det, coll, sd, (TYPE*) 0); 0364 } 0365 0366 protected: 0367 /// Define standard assignments and constructors 0368 DDG4_DEFINE_ACTION_CONSTRUCTORS(Geant4SensDetActionSequence); 0369 0370 public: 0371 /// Standard constructor 0372 Geant4SensDetActionSequence(Geant4Context* context, const std::string& name); 0373 0374 /// Default destructor 0375 virtual ~Geant4SensDetActionSequence(); 0376 0377 /// Access to the sensitive type of the detector 0378 virtual const std::string& sensitiveType() const { 0379 return m_sensitiveType; 0380 } 0381 0382 /// Set or update client context 0383 virtual void updateContext(Geant4Context* ctxt) override; 0384 0385 /// Called at construction time of the sensitive detector to declare all hit collections 0386 std::size_t defineCollections(Geant4ActionSD* sens_det); 0387 0388 /// Initialize the usage of a hit collection. Returns the collection identifier 0389 std::size_t defineCollection(Geant4Sensitive* owner, const std::string& name, create_t func); 0390 0391 /// Define a named collection containing hist of a specified type 0392 template <typename TYPE> std::size_t defineCollection(Geant4Sensitive* owner, const std::string& coll_name) { 0393 return defineCollection(owner, coll_name, Geant4SensDetActionSequence::_create<TYPE>); 0394 } 0395 0396 /// Access HitCollection container names 0397 const std::string& hitCollectionName(std::size_t which) const; 0398 0399 /// Retrieve the hits collection associated with this detector by its serial number 0400 Geant4HitCollection* collection(std::size_t which) const; 0401 0402 /// Retrieve the hits collection associated with this detector by its collection identifier 0403 Geant4HitCollection* collectionByID(std::size_t id) const; 0404 0405 /// Register begin-of-event callback 0406 template <typename T> void callAtBegin(T* p, void (T::*f)(G4HCofThisEvent*)) { 0407 m_begin.add(p, f); 0408 } 0409 0410 /// Register end-of-event callback 0411 template <typename T> void callAtEnd(T* p, void (T::*f)(G4HCofThisEvent*)) { 0412 m_end.add(p, f); 0413 } 0414 0415 /// Register process-hit callback 0416 template <typename T> void callAtProcess(T* p, void (T::*f)(G4Step*, G4TouchableHistory*)) { 0417 m_process.add(p, f); 0418 } 0419 0420 /// Register clear callback 0421 template <typename T> void callAtClear(T* p, void (T::*f)(G4HCofThisEvent*)) { 0422 m_clear.add(p, f); 0423 } 0424 0425 /// Add an actor responding to all callbacks. Sequence takes ownership. 0426 void adopt(Geant4Sensitive* sensitive); 0427 0428 /// Add an actor responding to all callbacks. Sequence takes ownership. 0429 void adopt(Geant4Filter* filter); 0430 0431 /// Add an actor responding to all callbacks. Sequence takes ownership. 0432 void adoptFilter(Geant4Action* filter); 0433 0434 /// Callback before hit processing starts. Invoke all filters. 0435 bool accept(const G4Step* step) const; 0436 0437 /// GFLASH/FastSim interface: Callback before hit processing starts. Invoke all filters. 0438 bool accept(const Geant4FastSimSpot* step) const; 0439 0440 /// G4VSensitiveDetector interface: Method invoked at the beginning of each event. 0441 /** The hits collection(s) created by this sensitive detector must 0442 * be set to the G4HCofThisEvent object at one of these two methods. 0443 */ 0444 virtual void begin(G4HCofThisEvent* hce); 0445 0446 /// G4VSensitiveDetector interface: Method invoked at the end of each event. 0447 0448 virtual void end(G4HCofThisEvent* hce); 0449 /// G4VSensitiveDetector interface: Method invoked if the event was aborted. 0450 /** Hits collections created but not beibg set to G4HCofThisEvent 0451 * at the event should be deleted. 0452 * Collection(s) which have already set to G4HCofThisEvent 0453 * will be deleted automatically. 0454 */ 0455 virtual void clear(); 0456 0457 /// G4VSensitiveDetector interface: Method for generating hit(s) using the information of G4Step object. 0458 virtual bool process(const G4Step* step, G4TouchableHistory* history); 0459 0460 /// GFLASH/FastSim interface: Method for generating hit(s) using the information of the fast simulation spot object. 0461 virtual bool processFastSim(const Geant4FastSimSpot* spot, G4TouchableHistory* history); 0462 }; 0463 0464 /// Geant4SensDetSequences: class to access groups of sensitive actions 0465 /** 0466 * Concrete implementation of the sensitive detector action sequence 0467 * 0468 * Note Multi-Threading issue: 0469 * Neither callbacks not the action list is protected against multiple 0470 * threads calling the Geant4 callbacks! 0471 * These must be protected in the user actions themselves. 0472 * 0473 * \author M.Frank 0474 * \version 1.0 0475 * \ingroup DD4HEP_SIMULATION 0476 */ 0477 class Geant4SensDetSequences { 0478 public: 0479 friend class Geant4ActionContainer; 0480 friend class Geant4SensDetActionSequence; 0481 typedef std::map<std::string, Geant4SensDetActionSequence*> Members; 0482 private: 0483 Members m_sequences; 0484 /// Insert sequence member 0485 void insert(const std::string& name, Geant4SensDetActionSequence* seq); 0486 0487 public: 0488 /// Default constructor 0489 Geant4SensDetSequences() = default; 0490 /// Default destructor 0491 virtual ~Geant4SensDetSequences(); 0492 /// Access sequence member by name 0493 Geant4SensDetActionSequence* operator[](const std::string& name) const; 0494 /// Access sequence member by name 0495 Geant4SensDetActionSequence* find(const std::string& name) const; 0496 /// Access to the members 0497 Members& sequences() { 0498 return m_sequences; 0499 } 0500 /// Access to the members CONST 0501 const Members& sequences() const { 0502 return m_sequences; 0503 } 0504 /// Clear the sequence list 0505 void clear(); 0506 }; 0507 0508 /// Initialize the usage of a single hit collection. Returns the collection ID 0509 template <typename TYPE> inline std::size_t Geant4Sensitive::defineCollection(const std::string& coll_name) { 0510 return sequence().defineCollection<TYPE>(this, coll_name); 0511 } 0512 0513 /// Template class to ease the construction of sensitive detectors using particle template specialization 0514 /** 0515 * Templated implementation to realize sensitive detectors. 0516 * Default implementations for all functions are provided in the file 0517 * DDG4/Geant4SensDetAction.inl. 0518 * 0519 * Users may override any of the templated callbacks or the of the virtual functions 0520 * of the base class using explicit template specialization. 0521 * An example may be found in DDG4/plugins/Geant4SDActions. 0522 * 0523 * \author M.Frank 0524 * \version 1.0 0525 * \ingroup DD4HEP_SIMULATION 0526 */ 0527 template <typename T> class Geant4SensitiveAction : public Geant4Sensitive { 0528 public: 0529 typedef T UserData; 0530 protected: 0531 /// Property: collection name. If not set default is readout name! 0532 std::string m_collectionName { }; 0533 /// Property: segmentation name for parallel readouts. If not set readout segmentation is used! 0534 std::string m_readoutName { }; 0535 0536 /// Collection identifier 0537 std::size_t m_collectionID { 0 }; 0538 /// User data block 0539 UserData m_userData { }; 0540 0541 protected: 0542 /// Define standard assignments and constructors 0543 DDG4_DEFINE_ACTION_CONSTRUCTORS(Geant4SensitiveAction); 0544 0545 public: 0546 /// Standard , initializing constructor 0547 Geant4SensitiveAction(Geant4Context* context, 0548 const std::string& name, 0549 DetElement det, 0550 Detector& description); 0551 0552 /// Default destructor 0553 virtual ~Geant4SensitiveAction(); 0554 0555 /// Declare optional properties from embedded structure 0556 void declareOptionalProperties(); 0557 0558 /// Define collections created by this sensitivie action object 0559 virtual void defineCollections(); 0560 0561 /// Access the readout object. Note: if m_readoutName is set, the m_readout != m_sensitive.readout() 0562 Readout readout(); 0563 0564 /// Define readout specific hit collection with volume ID filtering 0565 /** 0566 * Convenience function. To be called by specialized sensitive actions inheriting this class. 0567 * 0568 * - If the property CollectionName ist NOT set, one default collection is declared, 0569 * with the readout name as the collection name. 0570 * - If the property CollectionName is set, the readout structure is searched for 0571 * the corresponding entry and a collection with the corrsponding name is declared. 0572 * At the same time a VolumeID filter is injected at the front of the sensitive's 0573 * filter queue to ONLY act on volume IDs matching this criterium. 0574 */ 0575 template <typename HIT> std::size_t declareReadoutFilteredCollection(); 0576 0577 /// Define readout specific hit collection. matching name must be present in readout structure 0578 template <typename HIT> 0579 std::size_t defineReadoutCollection(const std::string collection_name); 0580 0581 /// Initialization overload for specialization 0582 virtual void initialize() final; 0583 /// Finalization overload for specialization 0584 virtual void finalize() final; 0585 0586 /// G4VSensitiveDetector interface: Method invoked at the beginning of each event. 0587 virtual void begin(G4HCofThisEvent* hce) final; 0588 /// G4VSensitiveDetector interface: Method invoked at the end of each event. 0589 virtual void end(G4HCofThisEvent* hce) final; 0590 /// G4VSensitiveDetector interface: Method invoked if the event was aborted. 0591 virtual void clear(G4HCofThisEvent* hce) final; 0592 0593 /// G4VSensitiveDetector interface: Method for generating hit(s) using the G4Step object. 0594 virtual bool process(const G4Step* step,G4TouchableHistory* history) final; 0595 0596 /// GFLASH/FastSim interface: Method for generating hit(s) using the information of the fast simulation spot object. 0597 virtual bool processFastSim(const Geant4FastSimSpot* spot, G4TouchableHistory* history) final; 0598 }; 0599 0600 } // End namespace sim 0601 } // End namespace dd4hep 0602 #endif // DDG4_GEANT4SENSDETACTION_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|