00001
00002
00003 #include "DetectorDescription/Base/interface/DDException.h"
00004 #include "DetectorDescription/Core/interface/DDSolid.h"
00005 #include "DetectorDescription/Core/src/Solid.h"
00006
00007 #include "DetectorDescription/Core/src/Box.h"
00008 #include "DetectorDescription/Core/src/Polycone.h"
00009 #include "DetectorDescription/Core/src/Polyhedra.h"
00010 #include "DetectorDescription/Core/src/Boolean.h"
00011 #include "DetectorDescription/Core/src/Reflection.h"
00012 #include "DetectorDescription/Core/src/Shapeless.h"
00013 #include "DetectorDescription/Core/src/Torus.h"
00014 #include "DetectorDescription/Core/src/Trap.h"
00015 #include "DetectorDescription/Core/src/Tubs.h"
00016 #include "DetectorDescription/Core/src/Cons.h"
00017 #include "DetectorDescription/Core/src/PseudoTrap.h"
00018 #include "DetectorDescription/Core/src/TruncTubs.h"
00019 #include <algorithm>
00020
00021
00022 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00023
00024 using DDI::Solid;
00025
00026
00027
00028
00029
00030 std::ostream &
00031 operator<<(std::ostream & os, const DDSolid & solid)
00032 {
00033 DDBase<DDName,DDI::Solid*>::def_type defined(solid.isDefined());
00034 if (defined.first) {
00035 os << *(defined.first) << " ";
00036 if (defined.second) {
00037 os << " " << DDSolidShapesName::name(solid.shape()) << ": ";
00038 solid.rep().stream(os);
00039 }
00040 else {
00041 os << "* solid not defined * ";
00042 }
00043 }
00044 else {
00045 os << "* solid not declared * ";
00046 }
00047 return os;
00048 }
00049
00050
00051
00052
00053 DDSolid::DDSolid() : DDBase<DDName,Solid*>() { }
00054
00055
00056 DDSolid::DDSolid(const DDName & n) : DDBase<DDName,Solid*>()
00057 {
00058 prep_ = StoreT::instance().create(n);
00059 }
00060
00061 DDSolid::DDSolid(const DDName & n, Solid * s) : DDBase<DDName,Solid*>()
00062 {
00063 prep_ = StoreT::instance().create(n,s);
00064 }
00065
00066
00067 DDSolid::DDSolid(const DDName & n, DDSolidShape s, const std::vector<double> & p)
00068 {
00069 DDI::Solid * solid(0);
00070 std::vector<double> dummy;
00071 switch(s) {
00072 case ddbox:
00073 solid = new DDI::Box(0,0,0);
00074 break;
00075 case ddtubs:
00076 solid = new DDI::Tubs(0,0,0,0,0);
00077 break;
00078 case ddcons:
00079 solid = new DDI::Cons(0,0,0,0,0,0,0);
00080 break;
00081 case ddpseudotrap:
00082 solid = new DDI::PseudoTrap(0,0,0,0,0,0,0);
00083 break;
00084 case ddshapeless:
00085 solid = new DDI::Shapeless();
00086 break;
00087 case ddtrap:
00088 solid = new DDI::Trap(0,0,0,0,0,0,0,0,0,0,0);
00089 break;
00090 case ddpolyhedra_rz:
00091 solid = new DDI::Polyhedra(0,0,0,dummy,dummy);
00092 break;
00093 case ddpolyhedra_rrz:
00094 solid = new DDI::Polyhedra(0,0,0,dummy,dummy,dummy);
00095 break;
00096 case ddpolycone_rz:
00097 solid = new DDI::Polycone(0,0,dummy,dummy);
00098 break;
00099 case ddpolycone_rrz:
00100 solid = new DDI::Polycone(0,0,dummy,dummy,dummy);
00101 break;
00102 case ddtrunctubs:
00103 solid = new DDI::TruncTubs(0,0,0,0,0,0,0,0);
00104 break;
00105 case ddtorus:
00106 solid = new DDI::Torus(0,0,0,0,0);
00107 break;
00108 default:
00109 throw DDException("DDSolid::DDSolid(DDName,DDSolidShape,std::vector<double>: wrong shape");
00110 }
00111 solid->setParameters(p);
00112 prep_ = StoreT::instance().create(n,solid);
00113 }
00114
00115
00116 double DDSolid::volume() const
00117 {
00118 return rep().volume();
00119 }
00120
00121 void DDSolid::clear()
00122 {
00123 StoreT::instance().clear();
00124 }
00125
00126
00127 DDSolidShape DDSolid::shape() const
00128 {
00129 return rep().shape();
00130 }
00131
00132
00133 const std::vector<double> & DDSolid::parameters() const
00134 {
00135 return rep().parameters();
00136 }
00137
00138
00139
00140
00141 DDTrap::DDTrap(const DDSolid & s) : DDSolid(s)
00142 {
00143 if (s.shape() != ddtrap) {
00144 std::string ex = "Solid [" + s.name().ns() + ":" + s.name().name() + "] is no DDTrap.\n";
00145 ex = ex + "Use a different solid interface!";
00146 throw DDException(ex);
00147 }
00148 }
00149
00150 double DDTrap::halfZ() const { return rep().parameters()[0]; }
00151
00152 double DDTrap::theta() const { return rep().parameters()[1]; }
00153
00154 double DDTrap::phi() const { return rep().parameters()[2]; }
00155
00156 double DDTrap::y1() const { return rep().parameters()[3]; }
00157
00158 double DDTrap::x1() const { return rep().parameters()[4]; }
00159
00160 double DDTrap::x2() const { return rep().parameters()[5]; }
00161
00162 double DDTrap::alpha1() const { return rep().parameters()[6]; }
00163
00164 double DDTrap::y2() const { return rep().parameters()[7]; }
00165
00166 double DDTrap::x3() const { return rep().parameters()[8]; }
00167
00168 double DDTrap::x4() const { return rep().parameters()[9]; }
00169
00170 double DDTrap::alpha2() const { return rep().parameters()[10]; }
00171
00172
00173
00174 DDTruncTubs::DDTruncTubs(const DDSolid & s) : DDSolid(s)
00175 {
00176 if (s.shape() != ddtrunctubs) {
00177 edm::LogError ("DDSolid") << "s.shape()=" << s.shape() << " " << s << std::endl;
00178 std::string ex = "Solid [" + s.name().ns() + ":" + s.name().name() + "] is no DDTruncTubs\n";
00179 ex = ex + "Use a different solid interface!";
00180 throw DDException(ex);
00181 }
00182 }
00183
00184 double DDTruncTubs::zHalf() const { return rep().parameters()[0];}
00185
00186 double DDTruncTubs::rIn() const { return rep().parameters()[1];}
00187
00188 double DDTruncTubs::rOut() const { return rep().parameters()[2];}
00189
00190 double DDTruncTubs::startPhi() const { return rep().parameters()[3];}
00191
00192 double DDTruncTubs::deltaPhi() const { return rep().parameters()[4];}
00193
00194 double DDTruncTubs::cutAtStart() const { return rep().parameters()[5];}
00195
00196 double DDTruncTubs::cutAtDelta() const { return rep().parameters()[6];}
00197
00198 bool DDTruncTubs::cutInside() const { return bool(rep().parameters()[7]);}
00199
00200
00201
00202 DDPseudoTrap::DDPseudoTrap(const DDSolid & s) : DDSolid(s)
00203 {
00204 if (s.shape() != ddpseudotrap) {
00205 std::string ex = "Solid [" + s.name().ns() + ":" + s.name().name() + "] is no DDPseudoTrap\n";
00206 ex = ex + "Use a different solid interface!";
00207 throw DDException(ex);
00208 }
00209 }
00210
00211 double DDPseudoTrap::halfZ() const { return rep().parameters()[4]; }
00212
00213 double DDPseudoTrap::x1() const { return rep().parameters()[0]; }
00214
00215 double DDPseudoTrap::x2() const { return rep().parameters()[1]; }
00216
00217 double DDPseudoTrap::y1() const { return rep().parameters()[2]; }
00218
00219 double DDPseudoTrap::y2() const { return rep().parameters()[3]; }
00220
00221 double DDPseudoTrap::radius() const { return rep().parameters()[5]; }
00222
00223 bool DDPseudoTrap::atMinusZ() const { return rep().parameters()[6]; }
00224
00225
00226
00227 DDBox::DDBox(const DDSolid & s)
00228 : DDSolid(s)
00229 {
00230 if (s.shape() != ddbox) {
00231 std::string ex = "Solid [" + s.name().ns() + ":" + s.name().name() + "] is not a DDBox.\n";
00232 ex = ex + "Use a different solid interface!";
00233 throw DDException(ex);
00234 }
00235 }
00236
00237 double DDBox::halfX() const
00238 { return rep().parameters()[0]; }
00239 double DDBox::halfY() const
00240 { return rep().parameters()[1]; }
00241 double DDBox::halfZ() const
00242 { return rep().parameters()[2]; }
00243
00244
00245
00246
00247 DDReflectionSolid::DDReflectionSolid(const DDSolid & s)
00248 : DDSolid(s), reflected_(0)
00249 {
00250
00251 reflected_ = dynamic_cast<DDI::Reflection*>(&s.rep());
00252 }
00253
00254
00255 DDSolid DDReflectionSolid::unreflected() const
00256 { return reflected_->solid();}
00257
00258
00259
00260
00261 DDShapelessSolid::DDShapelessSolid (const DDSolid & s) : DDSolid(s)
00262 {
00263 if (s.shape() != ddshapeless) {
00264 std::string ex = "Solid [" + s.name().ns() + ":" + s.name().name() + "] is not a DDShapelessSolid.\n";
00265 ex = ex + "Use a different solid interface!";
00266 throw DDException(ex);
00267 }
00268 }
00269
00270
00271
00272
00273 DDUnion::DDUnion(const DDSolid & s)
00274 : DDBooleanSolid(s)
00275 {
00276 if (s.shape() != ddunion) {
00277 std::string ex = "Solid [" + s.name().ns() + ":" + s.name().name() + "] is not a DDUnion.\n";
00278 ex = ex + "Use a different solid interface!";
00279 throw DDException(ex);
00280 }
00281 }
00282
00283
00284
00285
00286 DDIntersection::DDIntersection(const DDSolid & s)
00287 : DDBooleanSolid(s)
00288 {
00289 if (s.shape() != ddunion) {
00290 std::string ex = "Solid [" + s.name().ns() + ":" + s.name().name() + "] is not a DDIntersection.\n";
00291 ex = ex + "Use a different solid interface!";
00292 throw DDException(ex);
00293 }
00294 }
00295
00296
00297
00298
00299 DDSubtraction::DDSubtraction(const DDSolid & s)
00300 : DDBooleanSolid(s)
00301 {
00302 if (s.shape() != ddsubtraction) {
00303 std::string ex = "Solid [" + s.name().ns() + ":" + s.name().name() + "] is no DDSubtraction.\n";
00304 ex = ex + "Use a different solid interface!";
00305 throw DDException(ex);
00306 }
00307 }
00308
00309
00310
00311
00312 DDPolySolid::DDPolySolid(const DDSolid & s)
00313 : DDSolid(s)
00314 { }
00315
00316 std::vector<double> DDPolySolid::getVec (const size_t& which,
00317 const size_t& offset,
00318 const size_t& numVecs) const {
00319
00320
00321
00322 std::string locErr;
00323 size_t szVec = 0;
00324 std::vector<double> tvec;
00325 if ( (rep().parameters().size() - offset) % numVecs != 0 ) {
00326 locErr = std::string("Could not find equal sized components of std::vectors in a PolySolid description.");
00327 edm::LogError ("DDSolid") << "rep().parameters().size()=" << rep().parameters().size() << " numVecs=" << numVecs
00328 << " offset=" << offset << std::endl;
00329 }
00330 else {
00331 szVec = (rep().parameters().size() - offset)/ numVecs;
00332 }
00333 for (size_t i = offset + which; i < rep().parameters().size(); i = i + numVecs) {
00334 tvec.push_back(rep().parameters()[i]);
00335 }
00336 return tvec;
00337 }
00338
00339
00340
00341 DDPolycone::DDPolycone(const DDSolid & s)
00342 : DDPolySolid(s)
00343 {
00344 if (s.shape() != ddpolycone_rz && s.shape() != ddpolycone_rrz) {
00345 std::string ex = "Solid [" + s.name().ns() + ":" + s.name().name() + "] is not a DDPolycone.\n";
00346 ex = ex + "Use a different solid interface!";
00347 throw DDException(ex);
00348 }
00349 }
00350
00351 double DDPolycone::startPhi() const { return rep().parameters()[0]; }
00352
00353 double DDPolycone::deltaPhi() const { return rep().parameters()[1]; }
00354
00355 std::vector<double> DDPolycone::rVec() const {
00356 std::vector<double> tvec;
00357 if (shape() == ddpolycone_rz)
00358 tvec = getVec(1, 2, 2);
00359 return tvec;
00360 }
00361
00362 std::vector<double> DDPolycone::zVec() const {
00363 if (shape() == ddpolycone_rz)
00364 return getVec(0, 2, 2);
00365 else
00366 return getVec(0, 2, 3);
00367 }
00368
00369 std::vector<double> DDPolycone::rMinVec() const {
00370 std::vector<double> tvec;
00371 if (shape() == ddpolycone_rrz)
00372 tvec = getVec(1, 2, 3);
00373 return tvec;
00374 }
00375
00376 std::vector<double> DDPolycone::rMaxVec() const {
00377 std::vector<double> tvec;
00378 if (shape() == ddpolycone_rrz)
00379 tvec = getVec(2, 2, 3);
00380 return tvec;
00381 }
00382
00383
00384
00385
00386 DDPolyhedra::DDPolyhedra(const DDSolid & s)
00387 : DDPolySolid(s)
00388 {
00389 if (s.shape() != ddpolyhedra_rz && s.shape() != ddpolyhedra_rrz) {
00390 std::string ex = "Solid [" + s.name().ns() + ":" + s.name().name() + "] is not a DDPolyhedra.\n";
00391 ex = ex + "Use a different solid interface!";
00392 throw DDException(ex);
00393 }
00394 }
00395
00396 int DDPolyhedra::sides() const { return int(rep().parameters()[0]); }
00397
00398 double DDPolyhedra::startPhi() const { return rep().parameters()[1]; }
00399
00400 double DDPolyhedra::deltaPhi() const { return rep().parameters()[2]; }
00401
00402 std::vector<double> DDPolyhedra::rVec() const {
00403 std::vector<double> tvec;
00404 if (shape() == ddpolyhedra_rz)
00405 tvec = getVec(1, 3, 2);
00406 return tvec;
00407 }
00408
00409 std::vector<double> DDPolyhedra::zVec() const {
00410 if (shape() == ddpolyhedra_rz)
00411 return getVec(0, 3, 2);
00412 else
00413 return getVec(0, 3, 3);
00414 }
00415
00416 std::vector<double> DDPolyhedra::rMinVec() const {
00417 std::vector<double> tvec;
00418 if (shape() == ddpolyhedra_rrz)
00419 tvec = getVec(1, 3, 3);
00420 return tvec;
00421 }
00422
00423 std::vector<double> DDPolyhedra::rMaxVec() const {
00424 std::vector<double> tvec;
00425 if (shape() == ddpolyhedra_rrz)
00426 tvec = getVec(2, 3, 3);
00427 return tvec;
00428 }
00429
00430
00431
00432 DDCons::DDCons(const DDSolid& s)
00433 : DDSolid(s) {
00434 if (s.shape() != ddcons) {
00435 std::string ex = "Solid [" + s.name().ns() + ":" + s.name().name() + "] is not a DDCons.\n";
00436 ex = ex + "Use a different solid interface!";
00437 throw DDException(ex);
00438 }
00439 }
00440
00441 double DDCons::zhalf() const { return rep().parameters()[0]; }
00442
00443 double DDCons::rInMinusZ() const { return rep().parameters()[1]; }
00444
00445 double DDCons::rOutMinusZ () const { return rep().parameters()[2]; }
00446
00447 double DDCons::rInPlusZ() const { return rep().parameters()[3]; }
00448
00449 double DDCons::rOutPlusZ() const { return rep().parameters()[4]; }
00450
00451 double DDCons::phiFrom() const { return rep().parameters()[5]; }
00452
00453 double DDCons::deltaPhi() const { return rep().parameters()[6]; }
00454
00455
00456
00457 DDTorus::DDTorus(const DDSolid& s)
00458 : DDSolid(s) {
00459 if (s.shape() != ddtorus) {
00460 std::string ex = "Solid [" + s.name().ns() + ":" + s.name().name() + "] is not a DDTorus.\n";
00461 ex = ex + "Use a different solid interface!";
00462 throw DDException(ex);
00463 }
00464 }
00465
00466 double DDTorus::rMin() const { return rep().parameters()[0]; }
00467
00468 double DDTorus::rMax() const { return rep().parameters()[1]; }
00469
00470 double DDTorus::rTorus () const { return rep().parameters()[2]; }
00471
00472 double DDTorus::startPhi() const { return rep().parameters()[3]; }
00473
00474 double DDTorus::deltaPhi() const { return rep().parameters()[4]; }
00475
00476
00477
00478
00479 DDTubs::DDTubs(const DDSolid& s)
00480 : DDSolid(s) {
00481 if (s.shape() != ddtubs) {
00482 std::string ex = "Solid [" + s.name().ns() + ":" + s.name().name() + "] is not a DDTubs.\n";
00483 ex = ex + "Use a different solid interface!";
00484 throw DDException(ex);
00485 }
00486 }
00487
00488 double DDTubs::zhalf() const { return rep().parameters()[0]; }
00489
00490 double DDTubs::rIn() const { return rep().parameters()[1]; }
00491
00492 double DDTubs::rOut() const { return rep().parameters()[2]; }
00493
00494 double DDTubs::startPhi() const { return rep().parameters()[3]; }
00495
00496 double DDTubs::deltaPhi() const { return rep().parameters()[4]; }
00497
00498
00499
00500
00501
00502 DDSolid DDSolidFactory::box(const DDName & name,
00503 double xHalf,
00504 double yHalf,
00505 double zHalf)
00506 {
00507 return DDSolid(name, new DDI::Box(xHalf, yHalf, zHalf ));
00508 }
00509
00510
00511 DDBooleanSolid::DDBooleanSolid(const DDSolid &s)
00512 : DDSolid(s), boolean_(0)
00513 {
00514 boolean_ = dynamic_cast<DDI::BooleanSolid*>(&s.rep());
00515 }
00516
00517
00518 DDRotation DDBooleanSolid::rotation() const
00519 {
00520 return boolean_->r();
00521 }
00522
00523 DDTranslation DDBooleanSolid::translation() const
00524 {
00525 return boolean_->t();
00526 }
00527
00528 DDSolid DDBooleanSolid::solidA() const
00529 {
00530 return boolean_->a();
00531 }
00532
00533 DDSolid DDBooleanSolid::solidB() const
00534 {
00535 return boolean_->b();
00536 }
00537
00538 DDSolid DDSolidFactory::polycone(const DDName & name, double startPhi, double deltaPhi,
00539 const std::vector<double> & z,
00540 const std::vector<double> & rmin,
00541 const std::vector<double> & rmax)
00542 {
00543 return DDSolid(name, new DDI::Polycone(startPhi, deltaPhi, z, rmin, rmax));
00544 }
00545
00546
00547 DDSolid DDSolidFactory::polycone(const DDName & name, double startPhi, double deltaPhi,
00548 const std::vector<double> & z,
00549 const std::vector<double> & r)
00550 {
00551 return DDSolid(name, new DDI::Polycone(startPhi, deltaPhi, z, r));
00552 }
00553
00554
00555 DDSolid DDSolidFactory::polyhedra(const DDName & name,
00556 int sides,
00557 double startPhi,
00558 double deltaPhi,
00559 const std::vector<double> & z,
00560 const std::vector<double> & rmin,
00561 const std::vector<double> & rmax)
00562 {
00563 return DDSolid(name, new DDI::Polyhedra(sides, startPhi, deltaPhi, z, rmin,rmax));
00564 }
00565
00566
00567 DDSolid DDSolidFactory::polyhedra(const DDName & name,
00568 int sides,
00569 double startPhi,
00570 double deltaPhi,
00571 const std::vector<double> & z,
00572 const std::vector<double> & r)
00573 {
00574 return DDSolid(name, new DDI::Polyhedra(sides, startPhi, deltaPhi, z, r));
00575 }
00576
00577
00578 DDSolid DDSolidFactory::unionSolid(const DDName & name,
00579 const DDSolid & a, const DDSolid & b,
00580 const DDTranslation & t,
00581 const DDRotation & r)
00582 {
00583 return DDSolid(name, new DDI::Union(a,b,t,r));
00584 }
00585
00586
00587 DDSolid DDSolidFactory::subtraction(const DDName & name,
00588 const DDSolid & a, const DDSolid & b,
00589 const DDTranslation & t,
00590 const DDRotation & r)
00591 {
00592 return DDSolid(name, new DDI::Subtraction(a,b,t,r));
00593 }
00594
00595
00596 DDSolid DDSolidFactory::intersection(const DDName & name,
00597 const DDSolid & a, const DDSolid & b,
00598 const DDTranslation & t,
00599 const DDRotation & r)
00600 {
00601 return DDSolid(name, new DDI::Intersection(a,b,t,r));
00602 }
00603
00604
00605 DDSolid DDSolidFactory::trap(const DDName & name,
00606 double pDz,
00607 double pTheta, double pPhi,
00608 double pDy1, double pDx1, double pDx2,
00609 double pAlp1,
00610 double pDy2, double pDx3, double pDx4,
00611 double pAlp2)
00612 {
00613 return DDSolid(name, new DDI::Trap(pDz, pTheta, pPhi,
00614 pDy1, pDx1, pDx2, pAlp1,
00615 pDy2, pDx3, pDx4, pAlp2));
00616 }
00617
00618
00619 DDSolid DDSolidFactory::pseudoTrap(const DDName & name,
00620 double pDx1,
00621 double pDx2,
00622 double pDy1,
00623 double pDy2,
00624 double pDz,
00625 double radius,
00626 bool atMinusZ
00627 )
00628 {
00629 return DDSolid(name, new DDI::PseudoTrap(pDx1, pDx2, pDy1, pDy2, pDz, radius, atMinusZ));
00630 }
00631
00632 DDSolid DDSolidFactory::truncTubs(const DDName & name,
00633 double zHalf,
00634 double rIn,
00635 double rOut,
00636 double startPhi,
00637 double deltaPhi,
00638 double cutAtStart,
00639 double cutAtDelta,
00640 bool cutInside )
00641 {
00642 return DDSolid(name, new DDI::TruncTubs(zHalf,rIn,rOut,startPhi,deltaPhi,cutAtStart,cutAtDelta,cutInside));
00643 }
00644
00645 DDSolid DDSolidFactory::cons(const DDName & name,
00646 double zhalf,
00647 double rInMinusZ,
00648 double rOutMinusZ,
00649 double rInPlusZ,
00650 double rOutPlusZ,
00651 double phiFrom,
00652 double deltaPhi)
00653 {
00654 return DDSolid(name, new DDI::Cons(zhalf,
00655 rInMinusZ, rOutMinusZ,
00656 rInPlusZ, rOutPlusZ,
00657 phiFrom, deltaPhi));
00658 }
00659
00660 DDSolid DDSolidFactory::torus(const DDName & name,
00661 double rMin,
00662 double rMax,
00663 double rTorus,
00664 double startPhi,
00665 double deltaPhi)
00666 {
00667 return DDSolid(name, new DDI::Torus(rMin, rMax, rTorus, startPhi, deltaPhi));
00668 }
00669
00670 DDSolid DDSolidFactory::tubs(const DDName & name,
00671 double zhalf,
00672 double rIn, double rOut,
00673 double phiFrom, double deltaPhi)
00674 {
00675 return DDSolid(name, new DDI::Tubs(zhalf,rIn,rOut,phiFrom,deltaPhi));
00676 }
00677
00678
00679 DDSolid DDSolidFactory::shapeless(const DDName & name)
00680 {
00681 return DDSolid(name, new DDI::Shapeless());
00682 }
00683
00684
00685 DDSolid DDSolidFactory::reflection(const DDName & name,
00686 const DDSolid & s)
00687 {
00688 return DDSolid(name, new DDI::Reflection(s));
00689 }
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772