Geant4_10
G4HepRepSceneHandler.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 // $Id: G4HepRepSceneHandler.cc 71534 2013-06-17 16:07:53Z gcosmo $
27 //
28 
33 #include <stdio.h>
34 
35 #include "globals.hh"
36 #include <vector>
37 #include <iostream>
38 // NOTE not available on Solaris 5.2 and Linux g++ 2.95.2
39 // #include <sstream>
40 #include <iomanip>
41 #include <fstream>
42 #include <cmath>
43 #include <cassert>
44 
45 //HepRep
46 #include "HEPREP/HepRep.h"
47 #include "G4HepRepMessenger.hh"
48 
49 //G4
50 #include "G4PhysicalConstants.hh"
51 #include "G4Vector3D.hh"
52 #include "G4Version.hh"
53 #include "G4Types.hh"
54 #include "G4Point3D.hh"
55 #include "G4Normal3D.hh"
56 #include "G4Polyline.hh"
57 #include "G4Polymarker.hh"
58 #include "G4Polyhedron.hh"
59 #include "G4Circle.hh"
60 #include "G4Square.hh"
61 #include "G4Text.hh"
62 #include "G4VPhysicalVolume.hh"
63 #include "G4VisAttributes.hh"
64 #include "G4VSolid.hh"
65 #include "G4VTrajectory.hh"
66 #include "G4VTrajectoryPoint.hh"
67 #include "G4VHit.hh"
68 #include "G4Scene.hh"
69 #include "G4Material.hh"
70 #include "G4AttDef.hh"
71 #include "G4AttValue.hh"
72 #include "G4AttCheck.hh"
73 
74 // CHepRep
76 
77 // This
78 #include "G4HepRep.hh"
79 #include "G4HepRepSceneHandler.hh"
80 #include "G4HepRepViewer.hh"
81 
82 
83 using namespace HEPREP;
84 using namespace cheprep;
85 using namespace std;
86 
87 G4int G4HepRepSceneHandler::sceneIdCount = 0;
88 
89 //#define LDEBUG 1
90 //#define SDEBUG 1
91 //#define PDEBUG 1
92 
94  : G4VSceneHandler (system, sceneIdCount++, name),
95  out (0),
96  geometryLayer ("Geometry"),
97  eventLayer ("Event"),
98  calHitLayer ("CalHit"),
99  trajectoryLayer ("Trajectory"),
100  hitLayer ("Hit"),
101  rootVolumeName ("Geometry"),
102  baseName (""),
103  eventNumberPrefix (""),
104  eventNumberSuffix (""),
105  eventNumber (1),
106  eventNumberWidth (-1),
107  extension (""),
108  writeBinary (false),
109  writeZip (false),
110  writeGZ (false),
111  writeMultipleFiles (false),
112  currentHit (NULL),
113  currentTrack (NULL),
114  _heprep (NULL),
115  _heprepGeometry (NULL)
116 {
117 
118 #ifdef LDEBUG
119  cout << "G4HepRepSceneHandler::G4HepRepSceneHandler: " << system << endl;
120 #endif
121 
122  materialState[kStateSolid] = G4String("Solid");
123  materialState[kStateLiquid] = G4String("Liquid");
124  materialState[kStateGas] = G4String("Gas");
125  materialState[kStateUndefined] = G4String("Undefined");
126 
127  factory = new XMLHepRepFactory();
128  writer = NULL;
129 
130  // opening of file deferred to closeHepRep();
131  openHepRep();
132 }
133 
134 
136 #ifdef LDEBUG
137  cout << "G4HepRepSceneHandler::~G4HepRepSceneHandler() " << endl;
138 #endif
139  close();
140 
141  delete factory;
142  factory = NULL;
143 
144  G4HepRep* pHepRepSystem = dynamic_cast<G4HepRep*>(GetGraphicsSystem());
145  if (pHepRepSystem) pHepRepSystem->removeSceneHandler();
146 }
147 
148 
149 void G4HepRepSceneHandler::open(G4String name) {
150  if (writer != NULL) return;
151 
152  if (name == "stdout") {
153 #ifdef LDEBUG
154  cout << "G4HepRepSceneHandler::Open() stdout" << endl;
155 #endif
156  writer = factory->createHepRepWriter(&cout, false, false);
157  out = NULL;
158  baseName = name;
159  eventNumberPrefix = "";
160  eventNumberSuffix = "";
161  extension = "";
162  writeBinary = false;
163  writeZip = false;
164  writeGZ = false;
165  writeMultipleFiles = false;
166  eventNumber = 0;
167  eventNumberWidth = 0;
168  } else if (name == "stderr") {
169 #ifdef LDEBUG
170  cout << "G4HepRepSceneHandler::Open() stderr" << endl;
171 #endif
172  writer = factory->createHepRepWriter(&cerr, false, false);
173  out = NULL;
174  baseName = name;
175  eventNumberPrefix = "";
176  eventNumberSuffix = "";
177  extension = "";
178  writeBinary = false;
179  writeZip = false;
180  writeGZ = false;
181  writeMultipleFiles = false;
182  eventNumber = 0;
183  eventNumberWidth = 0;
184  } else {
185 #ifdef LDEBUG
186  cout << "G4HepRepSceneHandler::Open() " << name << endl;
187 #endif
188  if (eventNumberWidth < 0) {
189  // derive filename(s)
190  // check for extensions
191  const unsigned int numberOfExtensions = 8;
192  string ext[numberOfExtensions] = {".heprep", ".heprep.xml", ".heprep.zip", ".heprep.gz",
193  ".bheprep", ".bheprep.xml", ".bheprep.zip", ".bheprep.gz"};
194  unsigned int i=0;
195  while (i < numberOfExtensions) {
196  int dot = name.size() - ext[i].size();
197  if ((dot >= 0) &&
198  (name.substr(dot, ext[i].size()) == ext[i])) break;
199  i++;
200  }
201 
202  if (i != numberOfExtensions) {
203  extension = ext[i];
204  writeBinary = i >= (numberOfExtensions/2);
205  writeZip = (i == 2) || (i == 6);
206  writeGZ = (i == 3) || (i == 7);
207 
208  int dot = name.length() - extension.length();
209  baseName = (dot >= 0) ? name.substr(0, dot) : "";
210 
211  } else {
212  // Default for no extension
213  extension = ".heprep.zip";
214  writeBinary = false;
215  writeZip = true;
216  writeGZ = false;
217  baseName = name;
218  }
219 
220  writeMultipleFiles = false;
221  int startDigit = -1; int endDigit = -1;
222 
224 
225  string suffix = messenger->getEventNumberSuffix();
226  if (suffix != "") {
227  // look for 0000 pattern in suffix
228  endDigit = suffix.length()-1;
229  while (endDigit >= 0) {
230  if (isdigit(suffix.at(endDigit))) break;
231  endDigit--;
232  }
233  if (endDigit < 0) {
234  cerr << "/vis/heprep/appendEventNumberSuffix contains no digits" << endl;
235  } else {
236  writeMultipleFiles = true;
237  startDigit = endDigit;
238  while (startDigit >= 0) {
239  if (!isdigit(suffix.at(startDigit))) break;
240  startDigit--;
241  }
242  startDigit++;
243  }
244  }
245 
246  if (writeMultipleFiles) {
247  eventNumberPrefix = suffix.substr(0, startDigit);
248  eventNumber = atoi(suffix.substr(startDigit, endDigit).c_str());
249  eventNumberWidth = endDigit +1 - startDigit;
250  eventNumberSuffix = suffix.substr(endDigit+1);
251  } else {
252  // open single file here
253  openFile(baseName+extension);
254 
255  eventNumber = 1;
256  eventNumberWidth = 10;
257  eventNumberPrefix = "";
258  eventNumberSuffix = "";
259  }
260  }
261  }
262 }
263 
264 
266 #ifdef LDEBUG
267  cout << "G4HepRepSceneHandler::OpenHepRep() " << endl;
268 #endif
269 
270  if (_heprep != NULL) return;
271 
272  // all done on demand, once pointers are set to NULL
273  _heprepGeometry = NULL;
274  _geometryInstanceTree = NULL;
275  _geometryRootInstance = NULL;
276  _geometryInstance.clear();
277  _geometryTypeTree = NULL;
278  _geometryRootType = NULL;
279  _geometryTypeName.clear();
280  _geometryType.clear();
281  _eventInstanceTree = NULL;
282  _eventInstance = NULL;
283  _eventTypeTree = NULL;
284  _eventType = NULL;
285  _trajectoryType = NULL;
286  _hitType = NULL;
287  _calHitType = NULL;
288  _calHitFaceType = NULL;
289 }
290 
291 
296  if (_heprep == NULL) return true;
297 
298 #ifdef LDEBUG
299  cout << "G4HepRepSceneHandler::CloseHepRep() start" << endl;
300 #endif
301 
302  // if this is the final close, then there should not be any event pending to be written.
303  if (final) {
304  if (_eventInstanceTree != NULL) {
305  cerr << "WARNING: you probably used '/vis/viewer/endOfEventAction accumulate' and "
306  << "forgot to call /vis/viewer/update before exit. No event written." << endl;
307  }
308  } else {
309 
311 
312  // add geometry to the heprep if there is an event (separate geometries are written
313  // using DrawView() called from /vis/viewer/flush)
314  if (_eventInstanceTree != NULL) {
316 
317  // couple geometry
318 
319  if ( messenger->appendGeometry()) {
320  // couple geometry to event if geometry was written
321  if ((_geometryInstanceTree != NULL)) {
322  getEventInstanceTree()->addInstanceTree(getGeometryInstanceTree());
323  }
324  } else {
325  char name[128];
326  if (writeMultipleFiles) {
327  sprintf(name, "%s%s%s#%s", baseName.c_str(), "-geometry", extension.c_str(), "G4GeometryData");
328  } else {
329  sprintf(name, "%s%s#%s", "geometry", (writeBinary ? ".bheprep" : ".heprep"), "G4GeometryData");
330  }
331  getEventInstanceTree()->addInstanceTree(factory->createHepRepTreeID(name, "1.0"));
332  }
333  }
334 
335  // force inclusion of all subtypes of event
336  if (_eventInstanceTree != NULL) {
337  getEventType();
338  getTrajectoryType();
339  getHitType();
340  getCalHitType();
341  getCalHitFaceType();
342  }
343 
344  // Give this HepRep all of the layer order info for both geometry and event,
345  // since these will both end up in a single HepRep.
346  writeLayers(_heprepGeometry);
347  writeLayers(_heprep);
348 
349  // open heprep file
350  if (writer == NULL) {
351  open((GetScene() == NULL) ? G4String("G4HepRepOutput.heprep.zip") : GetScene()->GetName());
352  }
353 
354  // write out separate geometry
355  if (! messenger->appendGeometry() && (_heprepGeometry != NULL)) {
356  if (writeMultipleFiles) {
357  char fileName[128];
358  sprintf(fileName, "%s%s%s", baseName.c_str(), "-geometry", extension.c_str());
359  openFile(G4String(fileName));
360  }
361 
362  char name[128];
363  sprintf(name, "%s%s", "geometry", (writeBinary ? ".bheprep" : ".heprep"));
364  if (!writeMultipleFiles) {
365  writer->addProperty("RecordLoop.ignore", name);
366  }
367 
368  writer->write(_heprepGeometry, G4String(name));
369 
370  delete _heprepGeometry;
371  _heprepGeometry = NULL;
372 
373  if (writeMultipleFiles) closeFile();
374  }
375 
376  if (writeMultipleFiles) {
377 // NOTE: does not work on Solaris 5.2 and Linux 2.95.2
378 // stringstream fileName;
379 // fileName << baseName << eventNumberPrefix << setw(eventNumberWidth) << setfill('0') << eventNumber << eventNumberSuffix << extension;
380 // openFile(fileName.str());
381 // Use instead:
382  char fileName[128];
383  char fileFormat[128];
384  sprintf(fileFormat, "%s%d%s", "%s%s%0", eventNumberWidth, "d%s%s");
385  sprintf(fileName, fileFormat, baseName.c_str(), eventNumberPrefix.c_str(), eventNumber, eventNumberSuffix.c_str(), extension.c_str());
386  openFile(G4String(fileName));
387  }
388 
389  // write out the heprep
390 // NOTE: does not work on Solaris 5.2 and Linux 2.95.2
391 // stringstream eventName;
392 // eventName << "event-" << setw(eventNumberWidth) << setfill('0') << eventNumber << (writeBinary ? ".bheprep" : ".heprep");
393 // writer->write(_heprep, eventName.str());
394 // Use instead:
395  char eventName[128];
396  char eventFormat[128];
397  sprintf(eventFormat, "%s%d%s%s", "event-%0", eventNumberWidth, "d", (writeBinary ? ".bheprep" : ".heprep"));
398  sprintf(eventName, eventFormat, eventNumber);
399  if (writer) writer->write(_heprep, G4String(eventName));
400 
401  eventNumber++;
402  }
403 
404  delete _heprep;
405  _heprep = NULL;
406 
407  if (writeMultipleFiles) closeFile();
408 
409  return true;
410 }
411 
412 
413 void G4HepRepSceneHandler::close() {
414 
415 #ifdef LDEBUG
416  cout << "G4HepRepSceneHandler::Close() " << endl;
417 #endif
418 
419  if (writer == NULL) return;
420 
421  if (!writeMultipleFiles) {
422  closeHepRep(true);
423  closeFile();
424  }
425 
426  G4HepRepViewer* viewer = dynamic_cast<G4HepRepViewer*>(GetCurrentViewer());
427  viewer->reset();
428 }
429 
431  out = new ofstream(name.c_str(), std::ios::out | std::ios::binary );
432  writer = factory->createHepRepWriter(out, writeZip, writeZip || writeGZ);
433 }
434 
436  writer->close();
437  delete writer;
438  writer = NULL;
439 
440  delete out;
441  out = NULL;
442 }
443 
444 void G4HepRepSceneHandler::writeLayers(HepRep* heprep) {
445  if (heprep == NULL) return;
446  heprep->addLayer(geometryLayer);
447  heprep->addLayer(eventLayer);
448  heprep->addLayer(calHitLayer);
449  heprep->addLayer(trajectoryLayer);
450  heprep->addLayer(hitLayer);
451 }
452 
454 #ifdef SDEBUG
455  cout << "G4HepRepSceneHandler::BeginModeling() " << endl;
456 #endif
458 }
459 
460 
462 #ifdef SDEBUG
463  cout << "G4HepRepSceneHandler::EndModeling() " << endl;
464 #endif
466 }
467 
469 #ifdef SDEBUG
470  cout << "G4HepRepSceneHandler::AddSolid(const G4Box& box)" << endl;
471 #endif
472 
473  if (dontWrite()) return;
474 
476 
477  if (! messenger->useSolids()) {
479  return;
480  }
481 
482  G4double dx = box.GetXHalfLength();
483  G4double dy = box.GetYHalfLength();
484  G4double dz = box.GetZHalfLength();
485 
486  G4Point3D vertex1(G4Point3D( dx, dy,-dz));
487  G4Point3D vertex2(G4Point3D( dx,-dy,-dz));
488  G4Point3D vertex3(G4Point3D(-dx,-dy,-dz));
489  G4Point3D vertex4(G4Point3D(-dx, dy,-dz));
490  G4Point3D vertex5(G4Point3D( dx, dy, dz));
491  G4Point3D vertex6(G4Point3D( dx,-dy, dz));
492  G4Point3D vertex7(G4Point3D(-dx,-dy, dz));
493  G4Point3D vertex8(G4Point3D(-dx, dy, dz));
494 
495  vertex1 = (transform) * vertex1;
496  vertex2 = (transform) * vertex2;
497  vertex3 = (transform) * vertex3;
498  vertex4 = (transform) * vertex4;
499  vertex5 = (transform) * vertex5;
500  vertex6 = (transform) * vertex6;
501  vertex7 = (transform) * vertex7;
502  vertex8 = (transform) * vertex8;
503 
504  HepRepInstance* instance = getGeometryOrEventInstance(getCalHitType());
505  addAttributes(instance, getCalHitType());
506 
507  setAttribute(instance, "DrawAs", G4String("Prism"));
508 
509  setVisibility(instance, box);
510  setLine(instance, box);
511  setColor(instance, getColorFor(box));
512 
513  factory->createHepRepPoint(instance, vertex1.x(), vertex1.y(), vertex1.z());
514  factory->createHepRepPoint(instance, vertex2.x(), vertex2.y(), vertex2.z());
515  factory->createHepRepPoint(instance, vertex3.x(), vertex3.y(), vertex3.z());
516  factory->createHepRepPoint(instance, vertex4.x(), vertex4.y(), vertex4.z());
517  factory->createHepRepPoint(instance, vertex5.x(), vertex5.y(), vertex5.z());
518  factory->createHepRepPoint(instance, vertex6.x(), vertex6.y(), vertex6.z());
519  factory->createHepRepPoint(instance, vertex7.x(), vertex7.y(), vertex7.z());
520  factory->createHepRepPoint(instance, vertex8.x(), vertex8.y(), vertex8.z());
521 }
522 
523 
525 #ifdef SDEBUG
526  cout << "G4HepRepSceneHandler::AddSolid(const G4Cons& cons)" << endl;
527 #endif
528 
529  if (dontWrite()) return;
530 
532 
533  if (! messenger->useSolids() || (cons.GetDeltaPhiAngle() < twopi)) {
535  return;
536  }
537 
538  G4PhysicalVolumeModel* pPVModel =
539  dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
540  if (!pPVModel) {
542  return;
543  }
544 
545  G4LogicalVolume* pCurrentLV = pPVModel->GetCurrentLV();
546  G4int currentDepth = pPVModel->GetCurrentDepth();
547  G4Material* pCurrentMaterial = pPVModel->GetCurrentMaterial();
548 
549  G4Point3D vertex1(G4Point3D( 0., 0., cons.GetZHalfLength()));
550  G4Point3D vertex2(G4Point3D( 0., 0.,-cons.GetZHalfLength()));
551 
552  vertex1 = (transform) * vertex1;
553  vertex2 = (transform) * vertex2;
554 
555  HepRepInstance* instance = getGeometryInstance(pCurrentLV, pCurrentMaterial, currentDepth);
556  setAttribute(instance, "DrawAs", G4String("Cylinder"));
557 
558  setVisibility(instance, cons);
559  setLine(instance, cons);
560  setColor(instance, getColorFor(cons));
561 
562  HepRepType* type = getGeometryType(pCurrentLV->GetName(), currentDepth);
563 
564  // Outer cylinder.
565  HepRepInstance* outer = factory->createHepRepInstance(instance, type);
566  outer->addAttValue("pickParent",true);
567  outer->addAttValue("showParentAttributes",true);
568 
569  HepRepPoint* op1 = factory->createHepRepPoint(outer, vertex1.x(), vertex1.y(), vertex1.z());
570  op1->addAttValue("Radius",cons.GetOuterRadiusPlusZ());
571 
572  HepRepPoint* op2 = factory->createHepRepPoint(outer, vertex2.x(), vertex2.y(), vertex2.z());
573  op2->addAttValue("Radius",cons.GetOuterRadiusMinusZ());
574 
575  // Inner cylinder.
576  HepRepInstance* inner = factory->createHepRepInstance(instance, type);
577  inner->addAttValue("pickParent",true);
578  inner->addAttValue("showParentAttributes",true);
579 
580  HepRepPoint* ip1 = factory->createHepRepPoint(inner, vertex1.x(), vertex1.y(), vertex1.z());
581  ip1->addAttValue("Radius",cons.GetInnerRadiusPlusZ());
582 
583  HepRepPoint* ip2 = factory->createHepRepPoint(inner, vertex2.x(), vertex2.y(), vertex2.z());
584  ip2->addAttValue("Radius",cons.GetInnerRadiusMinusZ());
585 }
586 
587 
589 #ifdef SDEBUG
590  cout << "G4HepRepSceneHandler::AddSolid(const G4Tubs& tubs)" << endl;
591 #endif
592 
593  if (dontWrite()) return;
594 
596 
597  if (! messenger->useSolids() || (tubs.GetDeltaPhiAngle() < twopi)) {
599  return;
600  }
601 
602  G4PhysicalVolumeModel* pPVModel =
603  dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
604  if (!pPVModel) {
606  return;
607  }
608 
609  G4LogicalVolume* pCurrentLV = pPVModel->GetCurrentLV();
610  G4int currentDepth = pPVModel->GetCurrentDepth();
611  G4Material* pCurrentMaterial = pPVModel->GetCurrentMaterial();
612 
613  G4Point3D vertex1(G4Point3D( 0., 0., tubs.GetZHalfLength()));
614  G4Point3D vertex2(G4Point3D( 0., 0.,-tubs.GetZHalfLength()));
615 
616  vertex1 = (transform) * vertex1;
617  vertex2 = (transform) * vertex2;
618 
619  HepRepInstance* instance = getGeometryInstance(pCurrentLV, pCurrentMaterial, currentDepth);
620  setAttribute(instance, "DrawAs", G4String("Cylinder"));
621 
622  setVisibility(instance, tubs);
623  setLine(instance, tubs);
624  setColor(instance, getColorFor(tubs));
625 
626  HepRepType* type = getGeometryType(pCurrentLV->GetName(), currentDepth);
627 
628  // Outer cylinder.
629  HepRepInstance* outer = factory->createHepRepInstance(instance, type);
630  outer->addAttValue("Radius",tubs.GetOuterRadius());
631  outer->addAttValue("pickParent",true);
632  outer->addAttValue("showParentAttributes",true);
633  factory->createHepRepPoint(outer, vertex1.x(), vertex1.y(), vertex1.z());
634  factory->createHepRepPoint(outer, vertex2.x(), vertex2.y(), vertex2.z());
635 
636  // Inner cylinder.
637  if (tubs.GetInnerRadius() > 0.) {
638  HepRepInstance* inner = factory->createHepRepInstance(instance, type);
639  inner->addAttValue("Radius",tubs.GetInnerRadius());
640  inner->addAttValue("pickParent",true);
641  inner->addAttValue("showParentAttributes",true);
642  factory->createHepRepPoint(inner, vertex1.x(), vertex1.y(), vertex1.z());
643  factory->createHepRepPoint(inner, vertex2.x(), vertex2.y(), vertex2.z());
644  }
645 }
646 
647 
649 #ifdef SDEBUG
650  cout << "G4HepRepSceneHandler::AddSolid(const G4Trd& trd)" << endl;
651 #endif
652  if (dontWrite()) return;
653 
655 
656  if (! messenger->useSolids()) {
658  return;
659  }
660 
661  G4double dx1 = trd.GetXHalfLength1();
662  G4double dy1 = trd.GetYHalfLength1();
663  G4double dx2 = trd.GetXHalfLength2();
664  G4double dy2 = trd.GetYHalfLength2();
665  G4double dz = trd.GetZHalfLength();
666 
667  G4Point3D vertex1(G4Point3D( dx1, dy1,-dz));
668  G4Point3D vertex2(G4Point3D( dx1,-dy1,-dz));
669  G4Point3D vertex3(G4Point3D(-dx1,-dy1,-dz));
670  G4Point3D vertex4(G4Point3D(-dx1, dy1,-dz));
671  G4Point3D vertex5(G4Point3D( dx2, dy2, dz));
672  G4Point3D vertex6(G4Point3D( dx2,-dy2, dz));
673  G4Point3D vertex7(G4Point3D(-dx2,-dy2, dz));
674  G4Point3D vertex8(G4Point3D(-dx2, dy2, dz));
675 
676  vertex1 = (transform) * vertex1;
677  vertex2 = (transform) * vertex2;
678  vertex3 = (transform) * vertex3;
679  vertex4 = (transform) * vertex4;
680  vertex5 = (transform) * vertex5;
681  vertex6 = (transform) * vertex6;
682  vertex7 = (transform) * vertex7;
683  vertex8 = (transform) * vertex8;
684 
685  HepRepInstance* instance = getGeometryOrEventInstance(getCalHitType());
686 
687  addAttributes(instance, getCalHitType());
688 
689  setAttribute(instance, "DrawAs", G4String("Prism"));
690 
691  setVisibility(instance, trd);
692  setLine(instance, trd);
693  setColor(instance, getColorFor(trd));
694 
695  factory->createHepRepPoint(instance, vertex1.x(), vertex1.y(), vertex1.z());
696  factory->createHepRepPoint(instance, vertex2.x(), vertex2.y(), vertex2.z());
697  factory->createHepRepPoint(instance, vertex3.x(), vertex3.y(), vertex3.z());
698  factory->createHepRepPoint(instance, vertex4.x(), vertex4.y(), vertex4.z());
699  factory->createHepRepPoint(instance, vertex5.x(), vertex5.y(), vertex5.z());
700  factory->createHepRepPoint(instance, vertex6.x(), vertex6.y(), vertex6.z());
701  factory->createHepRepPoint(instance, vertex7.x(), vertex7.y(), vertex7.z());
702  factory->createHepRepPoint(instance, vertex8.x(), vertex8.y(), vertex8.z());
703 }
704 
706  if (dontWrite()) return;
708 }
709 
711  if (dontWrite()) return;
712  G4VSceneHandler::AddSolid (sphere);
713 }
714 
716  if (dontWrite()) return;
718 }
719 
721  if (dontWrite()) return;
722  G4VSceneHandler::AddSolid (torus);
723 }
724 
726  if (dontWrite()) return;
727  G4VSceneHandler::AddSolid (polycone);
728 }
729 
730 void G4HepRepSceneHandler::AddSolid (const G4Polyhedra& polyhedra) {
731  if (dontWrite()) return;
732  G4VSceneHandler::AddSolid (polyhedra);
733 }
734 
736  if (dontWrite()) return;
738 }
739 
740 
742 
743 #ifdef PDEBUG
744  cout << "G4HepRepSceneHandler::AddPrimitive(G4Polyline&) " << line.size() << endl;
745 #endif
746  if (dontWrite()) return;
747 
748  if (fProcessing2D) {
749  static G4bool warned = false;
750  if (!warned) {
751  warned = true;
753  ("G4HepRepSceneHandler::AddPrimitive (const G4Polyline&)",
754  "vis-HepRep1001", JustWarning,
755  "2D polylines not implemented. Ignored.");
756  }
757  return;
758  }
759 
760  HepRepInstance* instance = factory->createHepRepInstance(getEventInstance(), getTrajectoryType());
761 
762  addAttributes(instance, getTrajectoryType());
763 
764  setColor(instance, GetColor(line));
765 
766  setVisibility(instance, line);
767 
768  setLine(instance, line);
769 
770  for (size_t i=0; i < line.size(); i++) {
771  G4Point3D vertex = transform * line[i];
772  factory->createHepRepPoint(instance, vertex.x(), vertex.y(), vertex.z());
773  }
774 }
775 
776 
778 
779 #ifdef PDEBUG
780  cout << "G4HepRepSceneHandler::AddPrimitive(G4Polymarker&) " << line.size() << endl;
781 #endif
782  if (dontWrite()) return;
783 
784  if (fProcessing2D) {
785  static G4bool warned = false;
786  if (!warned) {
787  warned = true;
789  ("G4HepRepSceneHandler::AddPrimitive (const G4Polymarker&)",
790  "vis-HepRep1002", JustWarning,
791  "2D polymarkers not implemented. Ignored.");
792  }
793  return;
794  }
795 
796  HepRepInstance* instance = factory->createHepRepInstance(getEventInstance(), getHitType());
797 
798  addAttributes(instance, getHitType());
799 
800  setColor(instance, GetColor(line));
801 
802  setVisibility(instance, line);
803 
804  setMarker(instance, line);
805 
806  // Default MarkName is set to Circle for this Type.
807  int mtype = line.GetMarkerType();
808 
809  // Cannot be case statement since line.xxx is not a constant
810  if (mtype == line.dots) {
811  setAttribute(instance, "Fill", true);
812  setColor(instance, GetColor(line), G4String("FillColor"));
813  } else if (mtype == line.circles) {
814  } else if (line.squares) {
815  setAttribute(instance, "MarkName", G4String("Box"));
816  } else {
817  // line.line + default
818  setAttribute(instance, "MarkName", G4String("Plus"));
819  }
820 
821  for (size_t i=0; i < line.size(); i++) {
822  G4Point3D vertex = transform * line[i];
823  factory->createHepRepPoint(instance, vertex.x(), vertex.y(), vertex.z());
824  }
825 }
826 
827 
829 #ifdef PDEBUG
830  cout << "G4HepRepSceneHandler::AddPrimitive(G4Circle&) " << endl;
831 #endif
832  if (dontWrite()) return;
833 
834  if (fProcessing2D) {
835  static G4bool warned = false;
836  if (!warned) {
837  warned = true;
839  ("G4HepRepSceneHandler::AddPrimitive (const G4Circle&)",
840  "vis-HepRep1003", JustWarning,
841  "2D circles not implemented. Ignored.");
842  }
843  return;
844  }
845 
846  HepRepInstance* instance = factory->createHepRepInstance(getEventInstance(), getHitType());
847 
848  addAttributes(instance, getHitType());
849 
850  G4Point3D center = transform * circle.GetPosition();
851 
852  setColor (instance, GetColor(circle));
853 
854  setVisibility(instance, circle);
855 
856  setMarker(instance, circle);
857 
858  factory->createHepRepPoint(instance, center.x(), center.y(), center.z());
859 }
860 
861 
863 
864 #ifdef PDEBUG
865  cout << "G4HepRepSceneHandler::AddPrimitive(G4Polyhedron&) " << endl;
866 #endif
867  if (dontWrite()) return;
868 
869  if (fProcessing2D) {
870  static G4bool warned = false;
871  if (!warned) {
872  warned = true;
874  ("G4HepRepSceneHandler::AddPrimitive (const G4Polyhedron&)",
875  "vis-HepRep1004", JustWarning,
876  "2D polyhedra not implemented. Ignored.");
877  }
878  return;
879  }
880 
881  G4Normal3D surfaceNormal;
882  G4Point3D vertex;
883 
884  if (polyhedron.GetNoFacets()==0) return;
885 
886  HepRepInstance* instance = getGeometryOrEventInstance(getCalHitType());
887 
888  addAttributes(instance, getCalHitType());
889 
890  setVisibility(instance, polyhedron);
891 
892  G4int currentDepth = 0;
893  G4PhysicalVolumeModel* pPVModel =
894  dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
895  if (pPVModel) currentDepth = pPVModel->GetCurrentDepth();
896 
897  G4bool notLastFace;
898  do {
899  HepRepInstance* face;
900  if (isEventData()) {
901  face = factory->createHepRepInstance(instance, getCalHitFaceType());
902  } else {
903  face = getGeometryInstance("*Face", currentDepth+1);
904  setAttribute(face, "PickParent", true);
905  setAttribute(face, "DrawAs", G4String("Polygon"));
906  }
907 
908  setLine(face, polyhedron);
909  setColor(face, GetColor(polyhedron));
910  if (isEventData()) setColor(face, GetColor(polyhedron), G4String("FillColor"));
911 
912  notLastFace = polyhedron.GetNextNormal (surfaceNormal);
913 
914  G4int edgeFlag = 1;
915  G4bool notLastEdge;
916  do {
917  notLastEdge = polyhedron.GetNextVertex (vertex, edgeFlag);
918  vertex = transform * vertex;
919  factory->createHepRepPoint(face, vertex.x(), vertex.y(), vertex.z());
920  } while (notLastEdge);
921  } while (notLastFace);
922 }
923 
924 
926 #ifdef PDEBUG
927  cout << "G4HepRepSceneHandler::AddPrimitive(G4Text&) " << endl;
928 #endif
929  if (dontWrite()) return;
930 
931  /*** You may need this
932  if (fProcessing2D) {
933  static G4bool warned = false;
934  if (!warned) {
935  warned = true;
936  G4Exception
937  ("G4HepRepSceneHandler::AddPrimitive (const G4Text&)",
938  "vis-HepRep1005", JustWarning,
939  "2D text not implemented. Ignored.");
940  }
941  return;
942  }
943  ***/
944 
945  cout << "G4HepRepSceneHandler::AddPrimitive G4Text : not yet implemented. " << endl;
946 }
947 
948 
950 #ifdef PDEBUG
951  cout << "G4HepRepSceneHandler::AddPrimitive(G4Square&) " << endl;
952 #endif
953  if (dontWrite()) return;
954 
955  if (fProcessing2D) {
956  static G4bool warned = false;
957  if (!warned) {
958  warned = true;
960  ("G4HepRepSceneHandler::AddPrimitive (const G4Square&)",
961  "vis-HepRep1006", JustWarning,
962  "2D squares not implemented. Ignored.");
963  }
964  return;
965  }
966 
967  HepRepInstance* instance = factory->createHepRepInstance(getEventInstance(), getHitType());
968 
969  addAttributes(instance, getHitType());
970 
971  G4Point3D center = transform * square.GetPosition();
972 
973  setColor (instance, getColorFor(square));
974 
975  setVisibility(instance, square);
976 
977  setMarker(instance, square);
978 
979  factory->createHepRepPoint(instance, center.x(), center.y(), center.z());
980 }
981 
983  if (dontWrite()) return;
985 }
986 
988 #ifdef PDEBUG
989  cout << "G4HepRepSceneHandler::AddCompound(G4VTrajectory&) " << endl;
990 #endif
991  if (dontWrite()) return;
992 
993  currentTrack = &trajectory;
994  G4VSceneHandler::AddCompound(trajectory);
995  currentTrack = NULL;
996 }
997 
998 
1000 #ifdef PDEBUG
1001  cout << "G4HepRepSceneHandler::AddCompound(G4VHit&) " << endl;
1002 #endif
1003  if (dontWrite()) return;
1004 
1005  currentHit = &hit;
1007  currentHit = NULL;
1008 }
1009 
1010 void G4HepRepSceneHandler::PreAddSolid (const G4Transform3D& objectTransformation,
1011  const G4VisAttributes& visAttribs) {
1012 
1013  G4VSceneHandler::PreAddSolid (objectTransformation, visAttribs);
1014 
1015  transform = objectTransformation;
1016 #ifdef SDEBUG
1017  cout << "G4HepRepSceneHandler::PreAddSolid(G4Transform3D&, G4VisAttributes&)" << endl;
1018 #endif
1019 }
1020 
1021 
1023 #ifdef SDEBUG
1024  cout << "G4HepRepSceneHandler::PostAddSolid()" << endl;
1025 #endif
1027 }
1028 
1029 
1030 void G4HepRepSceneHandler::BeginPrimitives (const G4Transform3D& objectTransformation) {
1031 #ifdef SDEBUG
1032  cout << "G4HepRepSceneHandler::BeginPrimitives(G4Transform3D&)" << endl;
1033 #endif
1034 
1035  G4VSceneHandler::BeginPrimitives (objectTransformation);
1036  transform = objectTransformation;
1037 }
1038 
1039 
1041 #ifdef SDEBUG
1042  cout << "G4HepRepSceneHandler::EndPrimitives" << endl;
1043 #endif
1045 }
1046 
1047 
1048 G4bool G4HepRepSceneHandler::dontWrite() {
1050  return !( messenger->writeInvisibles() || (fpVisAttribs ? (bool)fpVisAttribs->IsVisible() : true));
1051 }
1052 
1053 void G4HepRepSceneHandler::setColor (HepRepAttribute *attribute,
1054  const G4Color& color,
1055  const G4String& key) {
1056 #ifdef CDEBUG
1057  cout << "G4HepRepSceneHandler::setColor : red : " << color.GetRed () <<
1058  " green : " << color.GetGreen () <<
1059  " blue : " << color.GetBlue () << endl;
1060 #endif
1061 
1062  setAttribute(attribute, key, color.GetRed(), color.GetGreen(), color.GetBlue(), color.GetAlpha());
1063 }
1064 
1065 G4Color G4HepRepSceneHandler::getColorFor (const G4VSolid& /* solid */) {
1066  return fpVisAttribs ? fpVisAttribs->GetColor() : GetColor(NULL);
1067 }
1068 
1069 G4Color G4HepRepSceneHandler::getColorFor (const G4Visible& visible) {
1070  return GetColor(visible);
1071 }
1072 
1073 void G4HepRepSceneHandler::setVisibility (HepRepAttribute *attribute, const G4VSolid& /* solid */) {
1074  setAttribute(attribute, "Visibility", (fpVisAttribs ? (bool)fpVisAttribs->IsVisible() : true));
1075 }
1076 
1077 void G4HepRepSceneHandler::setVisibility ( HepRepAttribute *attribute, const G4Visible& visible) {
1078  const G4VisAttributes* atts = visible.GetVisAttributes();
1079 
1080  setAttribute(attribute, "Visibility", (atts && (atts->IsVisible()==0)) ? false : true);
1081 }
1082 
1083 void G4HepRepSceneHandler::setLine (HepRepAttribute *attribute, const G4VSolid& /* solid*/) {
1084  setAttribute(attribute, "LineWidth", 1.0);
1085 }
1086 
1087 void G4HepRepSceneHandler::setLine (HepRepAttribute *attribute, const G4Visible& visible) {
1088  const G4VisAttributes* atts = visible.GetVisAttributes();
1089 
1090  setAttribute(attribute, "LineWidth", (atts != NULL) ? atts->GetLineWidth() : 1.0);
1091 
1092  if (atts != NULL) {
1093  switch (atts->GetLineStyle()) {
1095  setAttribute(attribute, "LineStyle", G4String("Dotted"));
1096  break;
1098  setAttribute(attribute, "LineStyle", G4String("Dashed"));
1099  break;
1101  default:
1102  break;
1103  }
1104  }
1105 }
1106 
1107 void G4HepRepSceneHandler::setMarker (HepRepAttribute *attribute, const G4VMarker& marker) {
1108  MarkerSizeType markerType;
1109  G4double size = GetMarkerRadius( marker , markerType );
1110 
1111  setAttribute(attribute, "MarkSize", size);
1112 
1113  if (markerType == screen) setAttribute(attribute, "MarkType", G4String("Symbol"));
1114  if (marker.GetFillStyle() == G4VMarker::noFill) {
1115  setAttribute(attribute, "Fill", false);
1116  } else {
1117  setColor(attribute, GetColor(marker), G4String("FillColor"));
1118  }
1119 }
1120 
1121 void G4HepRepSceneHandler::addAttributes(HepRepInstance* instance, HepRepType* type) {
1122  if (currentHit) {
1123  vector<G4AttValue>* hitAttValues = currentHit->CreateAttValues();
1124  const map<G4String,G4AttDef>* hitAttDefs = currentHit->GetAttDefs();
1125 
1126  addAttDefs(getHitType(), hitAttDefs);
1127 
1128  // these attValues are non-standard, so can only be added when we have the attDef.
1129  type->addAttValue("LVol", G4String(""));
1130  type->addAttValue("HitType", G4String(""));
1131  type->addAttValue("ID", -1);
1132  type->addAttValue("Column", -1);
1133  type->addAttValue("Row", -1);
1134  type->addAttValue("Energy", 0.0);
1135  type->addAttValue("Pos", G4String(""));
1136 
1137  addAttVals(instance, hitAttDefs, hitAttValues);
1138 
1139  delete hitAttValues;
1140 
1141  } else if (currentTrack) {
1142  vector<G4AttValue>* trajectoryAttValues = currentTrack->CreateAttValues();
1143  const map<G4String,G4AttDef>* trajectoryAttDefs = currentTrack->GetAttDefs();
1144 
1145  addAttDefs(type, trajectoryAttDefs);
1146 
1147  // these attValues are non-standard, so can only be added when we have the attDef.
1148  type->addAttValue("Ch", 0.0);
1149  type->addAttValue("Color", 1.0, 1.0, 1.0, 1.0);
1150  type->addAttValue("ID", -1);
1151  type->addAttValue("IMom", G4String(""));
1152  type->addAttValue("IMag", 0.0);
1153  type->addAttValue("PDG", -1);
1154  type->addAttValue("PN", G4String(""));
1155  type->addAttValue("PID", -1);
1156 
1157  addAttVals(instance, trajectoryAttDefs, trajectoryAttValues);
1158 
1159  delete trajectoryAttValues;
1160 
1161  }
1162 }
1163 
1164 void G4HepRepSceneHandler::setAttribute(HepRepAttribute* attribute, G4String name, G4String value) {
1165  HepRepAttValue* attValue = attribute->getAttValue(name);
1166  if ((attValue == NULL) || (attValue->getString() != value)) {
1167  HepRepPoint* point = dynamic_cast<HepRepPoint*>(attribute);
1168  if (point != NULL) {
1169  if (point->getInstance()->getAttValueFromNode(name) == NULL) {
1170  attribute = point->getInstance();
1171  }
1172  }
1173 
1174  HepRepInstance* instance = dynamic_cast<HepRepInstance*>(attribute);
1175  if (instance != NULL) {
1176  // look for definition on type (node only)
1177  if (instance->getType()->getAttValueFromNode(name) == NULL) {
1178  attribute = instance->getType();
1179  }
1180  }
1181 
1182  attribute->addAttValue(name, value);
1183  }
1184 }
1185 
1186 void G4HepRepSceneHandler::setAttribute(HepRepAttribute* attribute, G4String name, bool value) {
1187  HepRepAttValue* attValue = attribute->getAttValue(name);
1188  if ((attValue == NULL) || (attValue->getBoolean() != value)) {
1189  HepRepPoint* point = dynamic_cast<HepRepPoint*>(attribute);
1190  if (point != NULL) {
1191  if (point->getInstance()->getAttValueFromNode(name) == NULL) {
1192  attribute = point->getInstance();
1193  }
1194  }
1195 
1196  HepRepInstance* instance = dynamic_cast<HepRepInstance*>(attribute);
1197  if (instance != NULL) {
1198  // look for definition on type (node only)
1199  if (instance->getType()->getAttValueFromNode(name) == NULL) {
1200  attribute = instance->getType();
1201  }
1202  }
1203 
1204  attribute->addAttValue(name, value);
1205  }
1206 }
1207 
1208 void G4HepRepSceneHandler::setAttribute(HepRepAttribute* attribute, G4String name, double value) {
1209  HepRepAttValue* attValue = attribute->getAttValue(name);
1210  if ((attValue == NULL) || (attValue->getDouble() != value)) {
1211  HepRepPoint* point = dynamic_cast<HepRepPoint*>(attribute);
1212  if (point != NULL) {
1213  if (point->getInstance()->getAttValueFromNode(name) == NULL) {
1214  attribute = point->getInstance();
1215  }
1216  }
1217 
1218  HepRepInstance* instance = dynamic_cast<HepRepInstance*>(attribute);
1219  if (instance != NULL) {
1220  // look for definition on type (node only)
1221  if (instance->getType()->getAttValueFromNode(name) == NULL) {
1222  attribute = instance->getType();
1223  }
1224  }
1225 
1226  attribute->addAttValue(name, value);
1227  }
1228 }
1229 
1230 void G4HepRepSceneHandler::setAttribute(HepRepAttribute* attribute, G4String name, int value) {
1231  HepRepAttValue* attValue = attribute->getAttValue(name);
1232  if ((attValue == NULL) || (attValue->getInteger() != value)) {
1233  HepRepPoint* point = dynamic_cast<HepRepPoint*>(attribute);
1234  if (point != NULL) {
1235  if (point->getInstance()->getAttValueFromNode(name) == NULL) {
1236  attribute = point->getInstance();
1237  }
1238  }
1239 
1240  HepRepInstance* instance = dynamic_cast<HepRepInstance*>(attribute);
1241  if (instance != NULL) {
1242  // look for definition on type (node only)
1243  if (instance->getType()->getAttValueFromNode(name) == NULL) {
1244  attribute = instance->getType();
1245  }
1246  }
1247 
1248  attribute->addAttValue(name, value);
1249  }
1250 }
1251 
1252 void G4HepRepSceneHandler::setAttribute(HepRepAttribute* attribute, G4String name, double red, double green, double blue, double alpha) {
1253  HepRepAttValue* attValue = attribute->getAttValue(name);
1254  vector<double> color;
1255  if (attValue != NULL) color = attValue->getColor();
1256  if ((color.size() == 0) ||
1257  (color[0] != red) ||
1258  (color[1] != green) ||
1259  (color[2] != blue) ||
1260  ((color.size() > 3) && (color[3] != alpha))) {
1261 
1262  HepRepPoint* point = dynamic_cast<HepRepPoint*>(attribute);
1263  if (point != NULL) {
1264  if (point->getInstance()->getAttValueFromNode(name) == NULL) {
1265  attribute = point->getInstance();
1266  }
1267  }
1268 
1269  HepRepInstance* instance = dynamic_cast<HepRepInstance*>(attribute);
1270  if (instance != NULL) {
1271  // look for definition on type (node only)
1272  if (instance->getType()->getAttValueFromNode(name) == NULL) {
1273  attribute = instance->getType();
1274  }
1275  }
1276 
1277  attribute->addAttValue(name, red, green, blue, alpha);
1278  }
1279 }
1280 
1281 void G4HepRepSceneHandler::addAttDefs(HepRepDefinition* definition, const map<G4String,G4AttDef>* attDefs) {
1282  if (attDefs == NULL) return;
1283 
1284  // Specify additional attribute definitions.
1285  map<G4String,G4AttDef>::const_iterator attDefIterator = attDefs->begin();
1286  while (attDefIterator != attDefs->end()) {
1287  definition->addAttDef(attDefIterator->first, attDefIterator->second.GetDesc(),
1288  attDefIterator->second.GetCategory(), attDefIterator->second.GetExtra());
1289  attDefIterator++;
1290  }
1291 }
1292 
1293 void G4HepRepSceneHandler::addAttVals(HepRepAttribute* attribute, const map<G4String,G4AttDef>* attDefs, vector<G4AttValue>* attValues) {
1294  if (attValues == NULL) return;
1295 
1296  // Copy the instance's G4AttValues to HepRepAttValues.
1297  for (vector<G4AttValue>::iterator attValIterator = attValues->begin(); attValIterator != attValues->end(); attValIterator++) {
1298  G4String name = attValIterator->GetName();
1299 
1300  HepRepPoint* point = dynamic_cast<HepRepPoint*>(attribute);
1301  if ((name == "Pos") && (point != NULL)) {
1302  G4String pos = attValIterator->GetValue();
1303 // cout << "Pos* " << pos << endl;
1304  int is = 0;
1305  int in = 0;
1306  int im = 0;
1307  G4String unit;
1308  for (unsigned int i=0; i<pos.length(); i++) {
1309  if (pos[i] == ' ') {
1310  if (in == 0) {
1311  // first coordinate
1312  double factor = atof(pos.substr(is, i-is).c_str())/point->getX();
1313  im = (int)(std::log10(factor)+((factor < 1) ? -0.5 : 0.5));
1314 // cout << factor << ", " << im << endl;
1315  } else if (in == 3) {
1316  // unit
1317  unit = pos.substr(is, i-is);
1318  if (unit == G4String("mum")) {
1319  im += -6;
1320  } else if (unit == G4String("mm")) {
1321  im += -3;
1322  } else if (unit == G4String("cm")) {
1323  im += -2;
1324  } else if (unit == G4String("m")) {
1325  im += 0;
1326  } else if (unit == G4String("km")) {
1327  im += 3;
1328  } else {
1329  cerr << "HepRepSceneHandler: Unrecognized Unit: '" << unit << "'" << endl;
1330  }
1331  }
1332  is = i+1;
1333  in++;
1334  }
1335  }
1336  switch(im) {
1337  case -6:
1338  unit = G4String("mum");
1339  break;
1340  case -3:
1341  unit = G4String("mm");
1342  break;
1343  case -2:
1344  unit = G4String("cm");
1345  break;
1346  case 0:
1347  unit = G4String("m");
1348  break;
1349  case 3:
1350  unit = G4String("km");
1351  break;
1352  default:
1353  cerr << "HepRepSceneHandler: No valid unit found for im: " << im << endl;
1354  unit = G4String("*im");
1355  break;
1356  }
1357 // cout << "U: " << unit << endl;
1358  setAttribute(attribute, G4String("PointUnit"), unit);
1359  continue;
1360  }
1361 
1362  // NTP already in points being written
1363  if (name == "NTP") continue;
1364 
1365  // find type of attribute using def
1366  const map<G4String,G4AttDef>::const_iterator attDefIterator = attDefs->find(name);
1367  G4String type = attDefIterator->second.GetValueType();
1368 
1369  // set based on type
1370  if ((type == "G4double") || (type == "double")) {
1371  setAttribute(attribute, attValIterator->GetName(), atof(attValIterator->GetValue()));
1372  } else if ((type == "G4int") || (type == "int")) {
1373  setAttribute(attribute, attValIterator->GetName(), atoi(attValIterator->GetValue()));
1374  } else { // G4String, string and others
1375  setAttribute(attribute, attValIterator->GetName(), attValIterator->GetValue());
1376  }
1377  }
1378 }
1379 
1380 
1381 bool G4HepRepSceneHandler::isEventData () {
1382  G4PhysicalVolumeModel* pPVModel =
1383  dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
1384  return !pPVModel || fReadyForTransients || currentHit || currentTrack;
1385 }
1386 
1387 void G4HepRepSceneHandler::addTopLevelAttributes(HepRepType* type) {
1388 
1389  // Some non-standard attributes
1390  type->addAttDef( "Generator", "Generator of the file", "General", "");
1391  type->addAttValue("Generator", G4String("Geant4"));
1392 
1393  type->addAttDef( "GeneratorVersion", "Version of the Generator", "General", "");
1394  G4String versionString = G4Version;
1395  versionString = versionString.substr(1,versionString.size()-2);
1396  versionString = " Geant4 version " + versionString + " " + G4Date;
1397  type->addAttValue("GeneratorVersion", versionString);
1398 
1399  const G4ViewParameters parameters = GetCurrentViewer()->GetViewParameters();
1400  const G4Vector3D& viewPointDirection = parameters.GetViewpointDirection();
1401  type->addAttDef( "ViewTheta", "Theta of initial suggested viewpoint", "Draw", "rad");
1402  type->addAttValue("ViewTheta", viewPointDirection.theta());
1403 
1404  type->addAttDef( "ViewPhi", "Phi of initial suggested viewpoint", "Draw", "rad");
1405  type->addAttValue("ViewPhi", viewPointDirection.phi());
1406 
1407  type->addAttDef( "ViewScale", "Scale of initial suggested viewpoint", "Draw", "");
1408  type->addAttValue("ViewScale", parameters.GetZoomFactor());
1409 
1410 // FIXME, no way to set these
1411  type->addAttDef( "ViewTranslateX", "Translate in X of initial suggested viewpoint", "Draw", "");
1412  type->addAttValue("ViewTranslateX", 0.0);
1413 
1414  type->addAttDef( "ViewTranslateY", "Translate in Y of initial suggested viewpoint", "Draw", "");
1415  type->addAttValue("ViewTranslateY", 0.0);
1416 
1417  type->addAttDef( "ViewTranslateZ", "Translate in Z of initial suggested viewpoint", "Draw", "");
1418  type->addAttValue("ViewTranslateZ", 0.0);
1419 
1420  type->addAttDef( "PointUnit", "Length", "Physics", "");
1421  type->addAttValue("PointUnit", G4String("m"));
1422 
1424 
1425  type->addAttDef( "UseSolids", "Use HepRep Solids rather than Geant4 Primitives", "Draw", "");
1426  type->addAttValue("UseSolids", messenger->useSolids());
1427 
1428  type->addAttDef( "WriteInvisibles", "Write Invisible Objects", "Draw", "");
1429  type->addAttValue("WriteInvisibles", messenger->writeInvisibles());
1430 }
1431 
1432 
1433 HepRepInstance* G4HepRepSceneHandler::getGeometryOrEventInstance(HepRepType* type) {
1434  if (isEventData()) {
1435  return factory->createHepRepInstance(getEventInstance(), type);
1436  } else {
1437  G4PhysicalVolumeModel* pPVModel =
1438  dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
1439  assert(pPVModel); // To keep Coverity happy.
1440  G4LogicalVolume* pCurrentLV = pPVModel->GetCurrentLV();
1441  G4int currentDepth = pPVModel->GetCurrentDepth();
1442  G4Material* pCurrentMaterial = pPVModel->GetCurrentMaterial();
1443  return getGeometryInstance(pCurrentLV, pCurrentMaterial, currentDepth);
1444  }
1445 }
1446 
1447 HepRep* G4HepRepSceneHandler::getHepRep() {
1448  if (_heprep == NULL) {
1449  // Create the HepRep that holds the Trees.
1450  _heprep = factory->createHepRep();
1451  }
1452  return _heprep;
1453 }
1454 
1455 HepRep* G4HepRepSceneHandler::getHepRepGeometry() {
1456  if (_heprepGeometry == NULL) {
1457  // Create the HepRep that holds the Trees.
1458  _heprepGeometry = factory->createHepRep();
1459  }
1460  return _heprepGeometry;
1461 }
1462 
1463 HepRepInstanceTree* G4HepRepSceneHandler::getGeometryInstanceTree() {
1464  if (_geometryInstanceTree == NULL) {
1465  // Create the Geometry InstanceTree.
1466  _geometryInstanceTree = factory->createHepRepInstanceTree("G4GeometryData", "1.0", getGeometryTypeTree());
1467 
1469  if ( messenger->appendGeometry()) {
1470  getHepRep()->addInstanceTree(_geometryInstanceTree);
1471  } else {
1472  getHepRepGeometry()->addInstanceTree(_geometryInstanceTree);
1473  }
1474  }
1475  return _geometryInstanceTree;
1476 }
1477 
1478 HepRepInstance* G4HepRepSceneHandler::getGeometryRootInstance() {
1479  if (_geometryRootInstance == NULL) {
1480  // Create the top level Geometry Instance.
1481  _geometryRootInstance = factory->createHepRepInstance(getGeometryInstanceTree(), getGeometryRootType());
1482  }
1483  return _geometryRootInstance;
1484 }
1485 
1486 HepRepInstance* G4HepRepSceneHandler::getGeometryInstance(G4LogicalVolume* volume, G4Material* material, int depth) {
1487  HepRepInstance* instance = getGeometryInstance(volume->GetName(), depth);
1488 
1489  setAttribute(instance, "LVol", volume->GetName());
1490  G4Region* region = volume->GetRegion();
1491  G4String regionName = region? region->GetName(): G4String("No region");
1492  setAttribute(instance, "Region", regionName);
1493  setAttribute(instance, "RootRegion", volume->IsRootRegion());
1494  setAttribute(instance, "Solid", volume->GetSolid()->GetName());
1495  setAttribute(instance, "EType", volume->GetSolid()->GetEntityType());
1496  G4String matName = material? material->GetName(): G4String("No material");
1497  setAttribute(instance, "Material", matName );
1498  G4double matDensity = material? material->GetDensity(): 0.;
1499  setAttribute(instance, "Density", matDensity);
1500  G4double matRadlen = material? material->GetRadlen(): 0.;
1501  setAttribute(instance, "Radlen", matRadlen);
1502 
1503  G4State matState = material? material->GetState(): kStateUndefined;
1504  G4String state = materialState[matState];
1505  setAttribute(instance, "State", state);
1506 
1507  return instance;
1508 }
1509 
1510 HepRepInstance* G4HepRepSceneHandler::getGeometryInstance(G4String volumeName, int depth) {
1511  // no extra checks since these are done in the geometryType already
1512 
1513  // adjust depth, also pop the current instance
1514  while ((int)_geometryInstance.size() > depth) {
1515  _geometryInstance.pop_back();
1516  }
1517 
1518  // get parent
1519  HepRepInstance* parent = (_geometryInstance.empty()) ? getGeometryRootInstance() : _geometryInstance.back();
1520 
1521  // get type
1522  HepRepType* type = getGeometryType(volumeName, depth);
1523 
1524  // create instance
1525  HepRepInstance* instance = factory->createHepRepInstance(parent, type);
1526  _geometryInstance.push_back(instance);
1527 
1528  return instance;
1529 }
1530 
1531 HepRepTypeTree* G4HepRepSceneHandler::getGeometryTypeTree() {
1532  if (_geometryTypeTree == NULL) {
1533  // Create the Geometry TypeTree.
1534  HepRepTreeID* geometryTreeID = factory->createHepRepTreeID("G4GeometryTypes", "1.0");
1535  _geometryTypeTree = factory->createHepRepTypeTree(geometryTreeID);
1536 
1538  if ( messenger->appendGeometry()) {
1539  getHepRep()->addTypeTree(_geometryTypeTree);
1540  } else {
1541  getHepRepGeometry()->addTypeTree(_geometryTypeTree);
1542  }
1543  }
1544  return _geometryTypeTree;
1545 }
1546 
1547 HepRepType* G4HepRepSceneHandler::getGeometryRootType() {
1548  if (_geometryRootType == NULL) {
1549  // Create the top level Geometry Type.
1550  _geometryRootType = factory->createHepRepType(getGeometryTypeTree(), rootVolumeName);
1551  _geometryRootType->addAttValue("Layer", geometryLayer);
1552 
1553  // Add attdefs used by all geometry types.
1554  _geometryRootType->addAttDef ("LVol", "Logical Volume", "Physics","");
1555  _geometryRootType->addAttValue("LVol", G4String(""));
1556  _geometryRootType->addAttDef ("Region", "Cuts Region", "Physics","");
1557  _geometryRootType->addAttValue("Region", G4String(""));
1558  _geometryRootType->addAttDef ("RootRegion", "Root Region", "Physics","");
1559  _geometryRootType->addAttValue("RootRegion", false);
1560  _geometryRootType->addAttDef ("Solid", "Solid Name", "Physics","");
1561  _geometryRootType->addAttValue("Solid", G4String(""));
1562  _geometryRootType->addAttDef ("EType", "Entity Type", "Physics","");
1563  _geometryRootType->addAttValue("EType", G4String("G4Box"));
1564  _geometryRootType->addAttDef ("Material", "Material Name", "Physics","");
1565  _geometryRootType->addAttValue("Material", G4String("Air"));
1566  _geometryRootType->addAttDef ("Density", "Material Density", "Physics","");
1567  _geometryRootType->addAttValue("Density", 0.0);
1568  _geometryRootType->addAttDef ("State", "Material State", "Physics","");
1569  _geometryRootType->addAttValue("State", G4String("Gas"));
1570  _geometryRootType->addAttDef ("Radlen", "Material Radiation Length", "Physics","");
1571  _geometryRootType->addAttValue("Radlen", 0.0);
1572 
1573  // add defaults for Geometry
1574  _geometryRootType->addAttValue("Color", 0.8, 0.8, 0.8, 1.0);
1575  _geometryRootType->addAttValue("Visibility", true);
1576  _geometryRootType->addAttValue("FillColor", 0.8, 0.8, 0.8, 1.0);
1577  _geometryRootType->addAttValue("LineWidth", 1.0);
1578  _geometryRootType->addAttValue("DrawAs", G4String("Polygon"));
1579  _geometryRootType->addAttValue("PickParent", false);
1580  _geometryRootType->addAttValue("ShowParentAttributes", true);
1581 
1582  _geometryRootType->addAttValue("MarkSizeMultiplier", 4.0);
1583  _geometryRootType->addAttValue("LineWidthMultiplier", 1.0);
1584 
1585  addTopLevelAttributes(_geometryRootType);
1586 
1587  _geometryType["/"+_geometryRootType->getName()] = _geometryRootType;
1588  }
1589  return _geometryRootType;
1590 }
1591 
1592 HepRepType* G4HepRepSceneHandler::getGeometryType(G4String volumeName, int depth) {
1593  // make sure we have a root
1594  getGeometryRootType();
1595 
1596  // construct the full name for this volume
1597  G4String name = getFullTypeName(volumeName, depth);
1598 
1599  // lookup type and create if necessary
1600  HepRepType* type = _geometryType[name];
1601  if (type == NULL) {
1602  G4String parentName = getParentTypeName(depth);
1603  HepRepType* parentType = _geometryType[parentName];
1604  // HepRep uses hierarchical names
1605  type = factory->createHepRepType(parentType, volumeName);
1606  _geometryType[name] = type;
1607  }
1608  return type;
1609 }
1610 
1611 G4String G4HepRepSceneHandler::getFullTypeName(G4String volumeName, int depth) {
1612  // check for name depth
1613  if (depth > (int)_geometryTypeName.size()) {
1614  // there is a problem, book this type under problems
1615  G4String problem = "HierarchyProblem";
1616  if (_geometryType["/"+problem] == NULL) {
1617  // HepRep uses hierarchical names
1618  HepRepType* type = factory->createHepRepType(getGeometryRootType(), problem);
1619  _geometryType["/"+problem] = type;
1620  }
1621  return "/" + problem + "/" + volumeName;
1622  }
1623 
1624  // adjust name depth, also pop the current volumeName
1625  while ((int)_geometryTypeName.size() > depth) {
1626  _geometryTypeName.pop_back();
1627  }
1628 
1629  // construct full name and push it
1630  G4String name = (_geometryTypeName.empty()) ? G4String("/"+rootVolumeName) : _geometryTypeName.back();
1631  name = name + "/" + volumeName;
1632  _geometryTypeName.push_back(name);
1633  return name;
1634 }
1635 
1636 G4String G4HepRepSceneHandler::getParentTypeName(int depth) {
1637  return (depth >= 1) ? _geometryTypeName[depth-1] : G4String("/"+rootVolumeName);
1638 }
1639 
1640 HepRepInstanceTree* G4HepRepSceneHandler::getEventInstanceTree() {
1641  if (_eventInstanceTree == NULL) {
1642  // Create the Event InstanceTree.
1643  _eventInstanceTree = factory->createHepRepInstanceTree("G4EventData", "1.0", getEventTypeTree());
1644  getHepRep()->addInstanceTree(_eventInstanceTree);
1645  }
1646  return _eventInstanceTree;
1647 }
1648 
1649 HepRepInstance* G4HepRepSceneHandler::getEventInstance() {
1650  if (_eventInstance == NULL) {
1651  // Create the top level Event Instance.
1652  _eventInstance = factory->createHepRepInstance(getEventInstanceTree(), getEventType());
1653  }
1654  return _eventInstance;
1655 }
1656 
1657 HepRepTypeTree* G4HepRepSceneHandler::getEventTypeTree() {
1658  if (_eventTypeTree == NULL) {
1659  // Create the Event TypeTree.
1660  HepRepTreeID* eventTreeID = factory->createHepRepTreeID("G4EventTypes", "1.0");
1661  _eventTypeTree = factory->createHepRepTypeTree(eventTreeID);
1662  getHepRep()->addTypeTree(_eventTypeTree);
1663  }
1664 
1665  return _eventTypeTree;
1666 }
1667 
1668 HepRepType* G4HepRepSceneHandler::getEventType() {
1669  if (_eventType == NULL) {
1670  // Create the top level Event Type.
1671  _eventType = factory->createHepRepType(getEventTypeTree(), "Event");
1672  _eventType->addAttValue("Layer", eventLayer);
1673 
1674  // add defaults for Events
1675  _eventType->addAttValue("Visibility", true);
1676  _eventType->addAttValue("Color", 1.0, 1.0, 1.0, 1.0);
1677  _eventType->addAttValue("FillColor", 1.0, 1.0, 1.0, 1.0);
1678  _eventType->addAttValue("LineWidth", 1.0);
1679  _eventType->addAttValue("HasFrame", true);
1680  _eventType->addAttValue("PickParent", false);
1681  _eventType->addAttValue("ShowParentAttributes", false);
1682 
1683  _eventType->addAttValue("MarkSizeMultiplier", 4.0);
1684  _eventType->addAttValue("LineWidthMultiplier", 1.0);
1685 
1686  addTopLevelAttributes(_eventType);
1687  }
1688 
1689  return _eventType;
1690 }
1691 
1692 HepRepType* G4HepRepSceneHandler::getTrajectoryType() {
1693  if (_trajectoryType == NULL) {
1694  _trajectoryType = factory->createHepRepType(getEventType(), "Trajectory");
1695 
1696  _trajectoryType->addAttValue("Layer", trajectoryLayer);
1697  _trajectoryType->addAttValue("DrawAs", G4String("Line"));
1698 
1699  _trajectoryType->addAttValue("LineWidthMultiplier", 2.0);
1700 
1701  // attributes to draw the points of a track as markers.
1702  _trajectoryType->addAttValue("MarkName", G4String("Box"));
1703  _trajectoryType->addAttValue("MarkSize", 4);
1704  _trajectoryType->addAttValue("MarkType", G4String("Symbol"));
1705  _trajectoryType->addAttValue("Fill", true);
1706  }
1707  return _trajectoryType;
1708 }
1709 
1710 HepRepType* G4HepRepSceneHandler::getHitType() {
1711  if (_hitType == NULL) {
1712  _hitType = factory->createHepRepType(getEventType(), "Hit");
1713  _hitType->addAttValue("Layer", hitLayer);
1714  _hitType->addAttValue("DrawAs", G4String("Point"));
1715  _hitType->addAttValue("MarkName", G4String("Box"));
1716  _hitType->addAttValue("MarkSize", 4.0);
1717  _hitType->addAttValue("MarkType", G4String("Symbol"));
1718  _hitType->addAttValue("Fill", true);
1719  }
1720  return _hitType;
1721 }
1722 
1723 HepRepType* G4HepRepSceneHandler::getCalHitType() {
1724  if (_calHitType == NULL) {
1725  _calHitType = factory->createHepRepType(getEventType(), "CalHit");
1726  _calHitType->addAttValue("Layer", calHitLayer);
1727  _calHitType->addAttValue("Fill", true);
1728  _calHitType->addAttValue("DrawAs", G4String("Polygon"));
1729  }
1730  return _calHitType;
1731 }
1732 
1733 HepRepType* G4HepRepSceneHandler::getCalHitFaceType() {
1734  if (_calHitFaceType == NULL) {
1735  _calHitFaceType = factory->createHepRepType(getCalHitType(), "CalHitFace");
1736  _calHitFaceType->addAttValue("PickParent", true);
1737  }
1738  return _calHitFaceType;
1739 }
1740 
const G4Colour & GetColor(const G4Visible &)
G4String GetName() const
void removeSceneHandler()
Definition: G4HepRep.cc:79
G4double GetZoomFactor() const
virtual bool write(HepRep *heprep, std::string name)=0
G4double GetXHalfLength() const
void AddSolid(const G4Box &box)
Definition: G4Para.hh:76
virtual void AddSolid(const G4Box &)
Definition: G4Text.hh:73
virtual HepRepWriter * createHepRepWriter(std::ostream *out, bool randomAccess, bool compress)=0
G4double GetAlpha() const
Definition: G4Colour.hh:142
MarkerType GetMarkerType() const
Definition: test07.cc:36
virtual G4bool writeInvisibles()
G4double GetYHalfLength1() const
G4String GetName() const
virtual void BeginModeling()
virtual void BeginPrimitives(const G4Transform3D &objectTransformation)
void BeginPrimitives(const G4Transform3D &objectTransformation)
G4bool GetNextNormal(G4Normal3D &normal) const
bool closeHepRep(bool final=false)
virtual void addTypeTree(HepRepTypeTree *typeTree)=0
G4double GetLineWidth() const
G4State
Definition: G4Material.hh:114
typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData)
void openFile(G4String name)
Definition: G4Box.hh:63
ifstream in
Definition: comparison.C:7
void PreAddSolid(const G4Transform3D &objectTransformation, const G4VisAttributes &visAttribs)
virtual bool addProperty(std::string key, std::string value)=0
const G4String & GetName() const
Definition: G4Material.hh:176
#define assert(x)
Definition: mymalloc.cc:1309
virtual HepRepTreeID * createHepRepTreeID(std::string name, std::string version, std::string qualifier="top-level")=0
G4VViewer * GetCurrentViewer() const
Definition: G4Tubs.hh:84
G4Material * GetCurrentMaterial() const
virtual void PostAddSolid()
virtual HepRepInstance * getInstance()=0
const G4ViewParameters & GetViewParameters() const
G4double GetDensity() const
Definition: G4Material.hh:178
G4bool IsVisible() const
virtual std::string getString()=0
const G4String & GetName() const
const XML_Char * name
Definition: expat.h:151
HepGeom::Point3D< G4double > G4Point3D
Definition: G4Point3D.hh:35
Definition: G4VHit.hh:48
G4double GetBlue() const
Definition: G4Colour.hh:141
G4double GetOuterRadiusMinusZ() const
Definition: G4Trd.hh:71
G4Point3D GetPosition() const
const G4VisAttributes * GetVisAttributes() const
virtual std::vector< double > getColor()=0
G4Region * GetRegion() const
virtual G4GeometryType GetEntityType() const =0
virtual void addAttDef(std::string name, std::string desc, std::string category, std::string extra)=0
G4double GetZHalfLength() const
Definition: test07.cc:36
int G4int
Definition: G4Types.hh:78
virtual void AddPrimitive(const G4Polyline &)=0
G4double GetZHalfLength() const
const XML_Char const XML_Char ** atts
Definition: expat.h:253
LineStyle GetLineStyle() const
virtual G4String getEventNumberSuffix()
virtual void addInstanceTree(HepRepTreeID *instanceTree)=0
virtual double getDouble()=0
virtual HepRepAttValue * getAttValueFromNode(std::string lowerCaseName)=0
virtual HepRepInstance * createHepRepInstance(HepRepInstance *parent, HepRepType *type)=0
string material
Definition: eplot.py:19
virtual HepRepPoint * createHepRepPoint(HepRepInstance *instance, double x, double y, double z)=0
G4double GetXHalfLength2() const
virtual HepRep * createHepRep()=0
virtual int getInteger()=0
virtual HepRepType * getType()=0
const G4Vector3D & GetViewpointDirection() const
G4double GetRed() const
Definition: G4Colour.hh:139
G4double GetDeltaPhiAngle() const
virtual const std::map< G4String, G4AttDef > * GetAttDefs() const
virtual std::string getName()=0
bool G4bool
Definition: G4Types.hh:79
G4double GetGreen() const
Definition: G4Colour.hh:140
G4bool IsRootRegion() const
Definition: G4Cons.hh:82
virtual bool close()=0
G4double GetMarkerRadius(const G4VMarker &, MarkerSizeType &)
virtual void EndModeling()
static G4HepRepMessenger * GetInstance()
G4VGraphicsSystem * GetGraphicsSystem() const
virtual void EndPrimitives()
G4double GetYHalfLength() const
virtual void addAttValue(HepRepAttValue *attValue)=0
G4double GetYHalfLength2() const
G4double GetInnerRadiusPlusZ() const
G4double GetInnerRadius() const
virtual G4bool appendGeometry()
G4double GetRadlen() const
Definition: G4Material.hh:218
Double_t scale
Definition: plot.C:11
virtual double getX()=0
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
const G4Color & GetColor() const
virtual HepRepType * createHepRepType(HepRepTypeTree *parent, std::string name)=0
virtual bool getBoolean()=0
const G4VisAttributes * fpVisAttribs
G4Scene * GetScene() const
virtual void AddCompound(const G4VTrajectory &)
virtual std::vector< G4AttValue > * CreateAttValues() const
virtual HepRepAttValue * getAttValue(std::string name)=0
virtual HepRepTypeTree * createHepRepTypeTree(HepRepTreeID *treeID)=0
virtual HepRepInstanceTree * createHepRepInstanceTree(std::string name, std::string version, HepRepTreeID *typeTree)=0
virtual const std::map< G4String, G4AttDef > * GetAttDefs() const
Definition: G4VHit.hh:60
virtual void addLayer(std::string layer)=0
void AddCompound(const G4VTrajectory &)
system("rm -rf dna.root")
G4HepRepSceneHandler(G4VGraphicsSystem &system, const G4String &name="")
G4double GetZHalfLength() const
virtual void PreAddSolid(const G4Transform3D &objectTransformation, const G4VisAttributes &)
virtual std::vector< G4AttValue > * CreateAttValues() const
Definition: G4VHit.hh:67
const XML_Char int const XML_Char * value
Definition: expat.h:331
FillStyle GetFillStyle() const
G4double GetXHalfLength1() const
void AddPrimitive(const G4Polyline &)
G4State GetState() const
Definition: G4Material.hh:179
double G4double
Definition: G4Types.hh:76
G4double GetInnerRadiusMinusZ() const
G4bool GetNextVertex(G4Point3D &vertex, G4int &edgeFlag) const
UBox box
Definition: UPolycone.cc:32
G4LogicalVolume * GetCurrentLV() const
G4int GetNoFacets() const
virtual void addInstanceTree(HepRepInstanceTree *instanceTree)=0
G4double GetOuterRadiusPlusZ() const
G4double GetZHalfLength() const
virtual G4bool useSolids()
G4VSolid * GetSolid() const
G4double GetOuterRadius() const
virtual void DrawView()=0
G4double GetDeltaPhiAngle() const