00001 #ifndef GEOMETRY_CC
00002 #define GEOMETRY_CC
00003
00004 #include "Geometry.hh"
00005
00006 namespace larutil {
00007
00008 Geometry* Geometry::_me = 0;
00009
00010 Geometry::Geometry(bool default_load) : LArUtilBase()
00011 {
00012 _name = "Geometry";
00013 if(default_load) {
00014 _file_name = Form("%s/LArUtil/dat/%s",
00015 getenv("LARLIGHT_CORE_DIR"),
00016 kUTIL_DATA_FILENAME[LArUtilConfig::Detector()].c_str());
00017 _tree_name = kTREENAME_GEOMETRY;
00018 LoadData();
00019 }
00020 }
00021
00022 bool Geometry::LoadData(bool force_reload)
00023 {
00024 bool status = LArUtilBase::LoadData(force_reload);
00025
00026 if(!status) return status;
00027
00028 fOrthVectorsY.resize(this->Nplanes());
00029 fOrthVectorsZ.resize(this->Nplanes());
00030 fFirstWireProj.resize(this->Nplanes());
00031 for(size_t plane=0; plane<this->Nplanes(); ++plane) {
00032
00033 larlight::GEO::View_t view = this->PlaneToView(plane);
00034
00035 Double_t ThisWirePitch = this->WirePitch(view);
00036
00037 Double_t WireCentre1[3] = {0.};
00038 Double_t WireCentre2[3] = {0.};
00039
00040 Double_t th = this->WireAngleToVertical(view);
00041 Double_t sth = TMath::Sin(th);
00042 Double_t cth = TMath::Cos(th);
00043
00044 for(size_t coord=0; coord<3; ++coord) {
00045 WireCentre1[coord] = (fWireEndVtx.at(plane).at(0).at(coord) + fWireStartVtx.at(plane).at(0).at(coord)) / 2.;
00046 WireCentre2[coord] = (fWireEndVtx.at(plane).at(1).at(coord) + fWireStartVtx.at(plane).at(1).at(coord)) / 2.;
00047 }
00048
00049 Double_t OrthY = cth;
00050 Double_t OrthZ = -sth;
00051 if(((WireCentre2[1] - WireCentre1[1])*OrthY
00052 + (WireCentre2[2] - WireCentre1[2])*OrthZ) < 0){
00053 OrthZ *= -1;
00054 OrthY *= -1;
00055 }
00056
00057 fOrthVectorsY[plane] = OrthY / ThisWirePitch;
00058 fOrthVectorsZ[plane] = OrthZ / ThisWirePitch;
00059
00060 fFirstWireProj[plane] = WireCentre1[1]*OrthY + WireCentre1[2]*OrthZ;
00061 fFirstWireProj[plane] /= ThisWirePitch;
00062 fFirstWireProj[plane] -= 0.5;
00063
00064 }
00065 return status;
00066 }
00067
00068 void Geometry::ClearData()
00069 {
00070 fDetLength = larlight::DATA::INVALID_DOUBLE;
00071 fDetHalfWidth = larlight::DATA::INVALID_DOUBLE;
00072 fDetHalfHeight = larlight::DATA::INVALID_DOUBLE;
00073
00074 fCryoLength = larlight::DATA::INVALID_DOUBLE;
00075 fCryoHalfWidth = larlight::DATA::INVALID_DOUBLE;
00076 fCryoHalfHeight = larlight::DATA::INVALID_DOUBLE;
00077
00078 fChannelToPlaneMap.clear();
00079 fChannelToWireMap.clear();
00080 fPlaneWireToChannelMap.clear();
00081 fSignalType.clear();
00082 fViewType.clear();
00083 fPlanePitch.clear();
00084
00085
00086 fWireStartVtx.clear();
00087 fWireEndVtx.clear();
00088 fWirePitch.clear();
00089 fWireAngle.clear();
00090 fOpChannelVtx.clear();
00091 fPlaneOriginVtx.clear();
00092 }
00093
00094 bool Geometry::ReadTree()
00095 {
00096 ClearData();
00097
00098 TChain *ch = new TChain(_tree_name.c_str());
00099 ch->AddFile(_file_name.c_str());
00100
00101 std::string error_msg("");
00102 if(!(ch->GetBranch("fDetLength"))) error_msg += " fDetLength\n";
00103 if(!(ch->GetBranch("fDetHalfWidth"))) error_msg += " fDetHalfWidth\n";
00104 if(!(ch->GetBranch("fDetHalfHeight"))) error_msg += " fDetHalfHeight\n";
00105
00106 if(!(ch->GetBranch("fCryoLength"))) error_msg += " fCryoLength\n";
00107 if(!(ch->GetBranch("fCryoHalfWidth"))) error_msg += " fCryoHalfWidth\n";
00108 if(!(ch->GetBranch("fCryoHalfHeight"))) error_msg += " fCryoHalfHeight\n";
00109
00110 if(!(ch->GetBranch("fChannelToPlaneMap"))) error_msg += " fChannelToPlaneMap\n";
00111 if(!(ch->GetBranch("fChannelToWireMap"))) error_msg += " fChannelToWireMap\n";
00112 if(!(ch->GetBranch("fPlaneWireToChannelMap"))) error_msg += " fPlaneWireToChannelMap\n";
00113
00114 if(!(ch->GetBranch("fSignalType"))) error_msg += " fSignalType\n";
00115 if(!(ch->GetBranch("fViewType"))) error_msg += " fViewType\n";
00116 if(!(ch->GetBranch("fPlanePitch"))) error_msg += " fPlanePitch\n";
00117
00118
00119
00120
00121 if(!(ch->GetBranch("fWireStartVtx"))) error_msg += " fWireStartVtx\n";
00122 if(!(ch->GetBranch("fWireEndVtx"))) error_msg += " fWireEndVtx\n";
00123
00124 if(!(ch->GetBranch("fWirePitch"))) error_msg += " fWirePitch\n";
00125 if(!(ch->GetBranch("fWireAngle"))) error_msg += " fWireAngle\n";
00126 if(!(ch->GetBranch("fOpChannelVtx"))) error_msg += " fOpChannelVtx\n";
00127
00128 if(!(ch->GetBranch("fPlaneOriginVtx"))) error_msg += " fPlaneOriginVtx\n";
00129
00130 if(!error_msg.empty()) {
00131
00132 throw LArUtilException(Form("Missing following TBranches...\n%s",error_msg.c_str()));
00133
00134 return false;
00135 }
00136
00137
00138 std::vector<UChar_t> *pChannelToPlaneMap = nullptr;
00139 std::vector<UShort_t> *pChannelToWireMap = nullptr;
00140
00141
00142 std::vector<std::vector<UShort_t> > *pPlaneWireToChannelMap = nullptr;
00143 std::vector<larlight::GEO::SigType_t> *pSignalType = nullptr;
00144 std::vector<larlight::GEO::View_t> *pViewType = nullptr;
00145 std::vector<Double_t> *pPlanePitch = nullptr;
00146
00147
00148 std::vector<std::vector<std::vector<Double_t> > > *pWireStartVtx = nullptr;
00149 std::vector<std::vector<std::vector<Double_t> > > *pWireEndVtx = nullptr;
00150 std::vector<std::vector<Double_t> > *pPlaneOriginVtx = nullptr;
00151
00152
00153 std::vector<Double_t> *pWirePitch = nullptr;
00154 std::vector<Double_t> *pWireAngle = nullptr;
00155
00156 std::vector<std::vector<Float_t> > *pOpChannelVtx = nullptr;
00157
00158 ch->SetBranchAddress("fDetLength",&fDetLength);
00159 ch->SetBranchAddress("fDetHalfWidth",&fDetHalfWidth);
00160 ch->SetBranchAddress("fDetHalfHeight",&fDetHalfHeight);
00161
00162 ch->SetBranchAddress("fCryoLength",&fCryoLength);
00163 ch->SetBranchAddress("fCryoHalfWidth",&fCryoHalfWidth);
00164 ch->SetBranchAddress("fCryoHalfHeight",&fCryoHalfHeight);
00165
00166 ch->SetBranchAddress("fChannelToWireMap", &pChannelToWireMap);
00167 ch->SetBranchAddress("fChannelToPlaneMap", &pChannelToPlaneMap);
00168 ch->SetBranchAddress("fPlaneWireToChannelMap",&pPlaneWireToChannelMap);
00169
00170 ch->SetBranchAddress("fSignalType",&pSignalType);
00171 ch->SetBranchAddress("fViewType",&pViewType);
00172 ch->SetBranchAddress("fPlanePitch",&pPlanePitch);
00173
00174
00175
00176 ch->SetBranchAddress("fWireStartVtx",&pWireStartVtx);
00177 ch->SetBranchAddress("fWireEndVtx",&pWireEndVtx);
00178 ch->SetBranchAddress("fPlaneOriginVtx",&pPlaneOriginVtx);
00179
00180 ch->SetBranchAddress("fWirePitch",&pWirePitch);
00181 ch->SetBranchAddress("fWireAngle",&pWireAngle);
00182
00183 ch->SetBranchAddress("fOpChannelVtx",&pOpChannelVtx);
00184
00185 ch->GetEntry(0);
00186
00187
00188 size_t n_channels = pChannelToPlaneMap->size();
00189 fChannelToPlaneMap.reserve(n_channels);
00190 fChannelToWireMap.reserve(n_channels);
00191 for(size_t i=0; i<n_channels; ++i) {
00192 fChannelToPlaneMap.push_back(pChannelToPlaneMap->at(i));
00193 fChannelToWireMap.push_back(pChannelToWireMap->at(i));
00194 }
00195
00196
00197 size_t n_planes = pPlaneWireToChannelMap->size();
00198 fPlaneWireToChannelMap.reserve(n_planes);
00199 fSignalType.reserve(n_planes);
00200 fViewType.reserve(n_planes);
00201 fPlanePitch.reserve(n_planes);
00202
00203
00204 fWireStartVtx.reserve(n_planes);
00205 fWireEndVtx.reserve(n_planes);
00206 fPlaneOriginVtx.reserve(n_planes);
00207 for(size_t i=0; i<n_planes; ++i) {
00208 fPlaneWireToChannelMap.push_back(pPlaneWireToChannelMap->at(i));
00209 fSignalType.push_back(pSignalType->at(i));
00210 fViewType.push_back(pViewType->at(i));
00211 fPlanePitch.push_back(pPlanePitch->at(i));
00212
00213
00214 fWireStartVtx.push_back(pWireStartVtx->at(i));
00215 fWireEndVtx.push_back(pWireEndVtx->at(i));
00216
00217 fPlaneOriginVtx.push_back(pPlaneOriginVtx->at(i));
00218 }
00219
00220
00221
00222 size_t n_views = pWirePitch->size();
00223 fWirePitch.reserve(n_views);
00224 fWireAngle.reserve(n_views);
00225 for(size_t i=0; i<n_views; ++i) {
00226 fWirePitch.push_back(pWirePitch->at(i));
00227 fWireAngle.push_back(pWireAngle->at(i));
00228 }
00229
00230
00231 size_t n_opchannel = pOpChannelVtx->size();
00232 fOpChannelVtx.reserve(n_opchannel);
00233 for(size_t i=0; i<n_opchannel; ++i)
00234 fOpChannelVtx.push_back(pOpChannelVtx->at(i));
00235
00236 delete ch;
00237 return true;
00238 }
00239
00240
00241 UInt_t Geometry::Nwires(UInt_t p) const
00242 {
00243 if(Nplanes() <= p) {
00244 throw LArUtilException(Form("Invalid plane ID :%d",p));
00245 return larlight::DATA::INVALID_UINT;
00246 }
00247
00248 return fPlaneWireToChannelMap.at(p).size();
00249 }
00250
00251 UChar_t Geometry::ChannelToPlane(const UInt_t ch) const
00252 {
00253 if(ch >= fChannelToPlaneMap.size()) {
00254 throw LArUtilException(Form("Invalid channel number: %d",ch));
00255 return larlight::DATA::INVALID_CHAR;
00256 }
00257 return fChannelToPlaneMap.at(ch);
00258 }
00259
00260 UInt_t Geometry::ChannelToWire(const UInt_t ch)const
00261 {
00262 if(ch >= fChannelToWireMap.size()) {
00263 throw LArUtilException(Form("Invalid channel number: %d",ch));
00264 return larlight::DATA::INVALID_CHAR;
00265 }
00266 return fChannelToWireMap.at(ch);
00267 }
00268
00269 larlight::GEO::SigType_t Geometry::SignalType(const UInt_t ch) const
00270 {
00271 if(ch >= fChannelToPlaneMap.size()) {
00272 throw LArUtilException(Form("Invalid Channel number :%d",ch));
00273 return larlight::GEO::kMysteryType;
00274 }
00275
00276 return fSignalType.at(fChannelToPlaneMap.at(ch));
00277 }
00278
00279 larlight::GEO::SigType_t Geometry::PlaneToSignalType(const UChar_t plane) const
00280 {
00281 if(plane >= fSignalType.size()) {
00282 throw LArUtilException(Form("Invalid Plane number: %d",plane));
00283 return larlight::GEO::kMysteryType;
00284 }
00285
00286 return fSignalType.at(plane);
00287 }
00288
00289 larlight::GEO::View_t Geometry::View(const UInt_t ch) const
00290 {
00291 if(ch >= fChannelToPlaneMap.size()) {
00292 throw LArUtilException(Form("Invalid Channel number :%d",ch));
00293 return larlight::GEO::kUnknown;
00294 }
00295
00296 return fViewType.at(fChannelToPlaneMap.at(ch));
00297 }
00298
00299 larlight::GEO::View_t Geometry::PlaneToView(const UChar_t plane) const
00300 {
00301 if(plane >= fViewType.size()) {
00302 throw LArUtilException(Form("Invalid Plane number: %d",plane));
00303 return larlight::GEO::kUnknown;
00304 }
00305
00306 return fViewType.at(plane);
00307 }
00308
00309 std::set<larlight::GEO::View_t> const Geometry::Views() const
00310 {
00311 std::set<larlight::GEO::View_t> views;
00312 for(auto const v : fViewType) views.insert(v);
00313 return views;
00314 }
00315
00316 UInt_t Geometry::PlaneWireToChannel(const UInt_t plane,
00317 const UInt_t wire) const
00318 {
00319 if(plane >= Nplanes() || fPlaneWireToChannelMap.at(plane).size() >= wire) {
00320 throw LArUtilException(Form("Invalid (plane, wire) = (%d, %d)",plane,wire));
00321 return larlight::DATA::INVALID_UINT;
00322 }
00323 return fPlaneWireToChannelMap.at(plane).at(wire);
00324 }
00325
00326 UInt_t Geometry::NearestChannel(const Double_t worldLoc[3],
00327 const UInt_t PlaneNo) const
00328 {
00329 return PlaneWireToChannel(PlaneNo,NearestWire(worldLoc,PlaneNo));
00330 }
00331
00332 UInt_t Geometry::NearestChannel(const std::vector<Double_t> &worldLoc,
00333 const UInt_t PlaneNo) const
00334 {
00335 return PlaneWireToChannel(PlaneNo,NearestWire(worldLoc,PlaneNo));
00336 }
00337
00338 UInt_t Geometry::NearestChannel(const TVector3 &worldLoc,
00339 const UInt_t PlaneNo) const
00340 {
00341 return PlaneWireToChannel(PlaneNo,NearestWire(worldLoc,PlaneNo));
00342 }
00343
00344 UInt_t Geometry::NearestWire(const Double_t worldLoc[3],
00345 const UInt_t PlaneNo) const
00346 {
00347 TVector3 loc(worldLoc);
00348 return NearestWire(loc,PlaneNo);
00349 }
00350
00351 UInt_t Geometry::NearestWire(const std::vector<Double_t> &worldLoc,
00352 const UInt_t PlaneNo) const
00353 {
00354 TVector3 loc(&worldLoc[0]);
00355 return NearestWire(loc,PlaneNo);
00356 }
00357
00358 UInt_t Geometry::NearestWire(const TVector3 &worldLoc,
00359 const UInt_t PlaneNo) const
00360 {
00361
00362 int NearestWireNumber = int(nearbyint(worldLoc[1]*fOrthVectorsY.at(PlaneNo)
00363 + worldLoc[2]*fOrthVectorsZ.at(PlaneNo)
00364 - fFirstWireProj.at(PlaneNo)));
00365
00366 unsigned int wireNumber = (unsigned int) NearestWireNumber;
00367
00368 if(NearestWireNumber < 0 ||
00369 NearestWireNumber >= (int)(this->Nwires(PlaneNo)) ){
00370
00371 if(NearestWireNumber < 0) wireNumber = 0;
00372 else wireNumber = this->Nwires(PlaneNo) - 1;
00373
00374 throw larutil::LArUtilException(Form("Can't find nearest wire for (%g,%g,%g)",
00375 worldLoc[0],worldLoc[1], worldLoc[2]));
00376
00377 }
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388 return wireNumber;
00389 }
00390
00391
00392 Double_t Geometry::PlanePitch(const UChar_t p1, const UChar_t p2) const
00393 {
00394 if( p1==p2 ) return 0;
00395 else if( (p1==0 && p2==1) || (p1==1 && p2==0) ) return fPlanePitch.at(0);
00396 else if( (p1==1 && p2==2) || (p1==2 && p2==1) ) return fPlanePitch.at(1);
00397 else if( (p1==0 && p2==2) || (p1==2 && p2==0) ) return fPlanePitch.at(2);
00398 else {
00399 throw LArUtilException("Plane number > 2 not supported!");
00400 return larlight::DATA::INVALID_DOUBLE;
00401 }
00402 }
00403
00404 Double_t Geometry::WirePitch(const UInt_t w1,
00405 const UInt_t w2,
00406 const UChar_t plane) const
00407 {
00408 if( w1 > w2 && w1 >= fPlaneWireToChannelMap.at(plane).size() ) {
00409 throw LArUtilException(Form("Invalid wire number: %d",w1));
00410 return larlight::DATA::INVALID_DOUBLE;
00411 }
00412 if( w2 > w1 && w2 >= fPlaneWireToChannelMap.at(plane).size() ) {
00413 throw LArUtilException(Form("Invalid wire number: %d",w2));
00414 return larlight::DATA::INVALID_DOUBLE;
00415 }
00416
00417 return ( w1 < w2 ? (w2-w1)*(fWirePitch.at(fViewType.at(plane))) : (w1-w2)*(fWirePitch.at(fViewType.at(plane))));
00418 }
00419
00421 Double_t Geometry::WirePitch(const larlight::GEO::View_t view) const
00422 {
00423 if((size_t)view > Nviews()) {
00424 throw LArUtilException(Form("Invalid view: %d",view));
00425 return larlight::DATA::INVALID_DOUBLE;
00426 }
00427
00428 return fWirePitch.at((size_t)view);
00429 }
00430
00431 Double_t Geometry::WireAngleToVertical(larlight::GEO::View_t view) const
00432 {
00433 if((size_t)view > Nviews()) {
00434 throw LArUtilException(Form("Invalid view: %d",view));
00435 return larlight::DATA::INVALID_DOUBLE;
00436 }
00437
00438 return fWireAngle.at((size_t)view);
00439 }
00440
00441
00442 void Geometry::WireEndPoints(const UChar_t plane,
00443 const UInt_t wire,
00444 Double_t *xyzStart, Double_t *xyzEnd) const
00445 {
00446
00447 if(plane >= fWireStartVtx.size()) {
00448 throw LArUtilException(Form("Plane %d invalid!",plane));
00449 return;
00450 }
00451 if(wire >= fWireStartVtx.at(plane).size()) {
00452 throw LArUtilException(Form("Wire %d invalid!",wire));
00453 return;
00454 }
00455
00456 xyzStart[0] = fWireStartVtx.at(plane).at(wire).at(0);
00457 xyzStart[1] = fWireStartVtx.at(plane).at(wire).at(1);
00458 xyzStart[2] = fWireStartVtx.at(plane).at(wire).at(2);
00459 xyzEnd[0] = fWireEndVtx.at(plane).at(wire).at(0);
00460 xyzEnd[1] = fWireEndVtx.at(plane).at(wire).at(1);
00461 xyzEnd[2] = fWireEndVtx.at(plane).at(wire).at(2);
00462
00463 }
00464
00465 bool Geometry::ChannelsIntersect(const UInt_t c1,
00466 const UInt_t c2,
00467 Double_t &y, Double_t &z) const
00468 {
00469 if(c1==c2){
00470 throw LArUtilException("Same channel does not intersect!");
00471 return false;
00472 }
00473
00474 if( c1 >= fChannelToPlaneMap.size() || c2>= fChannelToPlaneMap.size() ) {
00475 throw LArUtilException(Form("Invalid channels : %d and %d",c1,c2));
00476 return false;
00477 }
00478 if( fViewType.at(fChannelToPlaneMap.at(c1)) == fViewType.at(fChannelToPlaneMap.at(c2)) ) {
00479 return false;
00480 }
00481
00482 UInt_t w1 = fChannelToWireMap.at(c1);
00483 UInt_t w2 = fChannelToWireMap.at(c2);
00484
00485 UChar_t p1 = fChannelToPlaneMap.at(c1);
00486 UChar_t p2 = fChannelToPlaneMap.at(c2);
00487
00488 larlight::GEO::View_t v1 = fViewType.at(p1);
00489 larlight::GEO::View_t v2 = fViewType.at(p2);
00490
00491 Double_t start1[3]={0.};
00492 Double_t start2[3]={0.};
00493 Double_t end1[3]={0.};
00494 Double_t end2[3]={0.};
00495
00496 WireEndPoints(p1, w1, start1, end1);
00497 WireEndPoints(p2, w2, start2, end2);
00498
00499
00500
00501 bool overlapY = (ValueInRange(start1[1], start2[1], end2[1]) || ValueInRange(end1[1], start2[1], end2[1]));
00502 bool overlapZ = (ValueInRange(start1[2], start2[2], end2[2]) || ValueInRange(end1[2], start2[2], end2[2]));
00503
00504 bool overlapY_rev = (ValueInRange(start2[1], start1[1], end1[1]) || ValueInRange(end2[1], start1[1], end1[1]));
00505 bool overlapZ_rev = (ValueInRange(start2[2], start1[2], end1[2]) || ValueInRange(end2[2], start1[2], end1[2]));
00506
00507
00508 if( fWireAngle.at(v1) == TMath::Pi()/2 || fWireAngle.at(v2) == TMath::Pi()/2 ) {
00509 overlapY = true;
00510 overlapY_rev = true;
00511 }
00512
00513
00514 if(std::abs(start2[2] - end2[2]) < 0.01) overlapZ = overlapZ_rev;
00515
00516
00517 if(overlapY && overlapZ){
00518 IntersectionPoint(w1,w2, p1, p2,
00519 start1, end1,
00520 start2, end2,
00521 y, z);
00522 return true;
00523 }
00524
00525 else if(overlapY_rev && overlapZ_rev){
00526 this->IntersectionPoint(w2, w1, p2, p1,
00527 start2, end2,
00528 start1, end1,
00529 y, z);
00530 return true;
00531 }
00532
00533 return false;
00534
00535 }
00536
00537 void Geometry::IntersectionPoint(const UInt_t wire1, const UInt_t wire2,
00538 const UChar_t plane1, const UChar_t plane2,
00539 Double_t start_w1[3], Double_t end_w1[3],
00540 Double_t start_w2[3], Double_t end_w2[3],
00541 Double_t &y, Double_t &z) const
00542 {
00543
00544 larlight::GEO::View_t v1 = fViewType.at(plane1);
00545 larlight::GEO::View_t v2 = fViewType.at(plane2);
00546
00547 Double_t angle1 = fWireAngle.at(v1);
00548
00549 Double_t angle2 = fWireAngle.at(v2);
00550
00551 if(angle1 == angle2) return;
00552
00553
00554 double a = 0.;
00555 double b = 0.;
00556 double c = 0.;
00557 double d = 0.;
00558 double angle = 0.;
00559 double anglex = 0.;
00560
00561
00562 angle1 < angle2 ? angle = angle1 : angle = angle2;
00563
00564
00565 if(angle1 == TMath::Pi()/2 || angle2 == TMath::Pi()/2){
00566 if(angle1 == TMath::Pi()/2){
00567
00568 anglex = (angle2-TMath::Pi()/2);
00569 a = end_w1[2];
00570 b = end_w1[1];
00571 c = end_w2[2];
00572 d = end_w2[1];
00573
00574
00575
00576 if((anglex) > 0 ) b = start_w1[1];
00577
00578 }
00579 else if(angle2 == TMath::Pi()/2){
00580 anglex = (angle1-TMath::Pi()/2);
00581 a = end_w2[2];
00582 b = end_w2[1];
00583 c = end_w1[2];
00584 d = end_w1[1];
00585
00586
00587
00588 if((anglex) > 0 ) b = start_w2[1];
00589 }
00590
00591 y = b + ((c-a) - (b-d)*tan(anglex))/tan(anglex);
00592 z = a;
00593
00594 return;
00595 }
00596
00597
00598 z = 0;y = 0;
00599
00600 if(angle1 < (TMath::Pi()/2.0)){
00601 c = end_w1[2];
00602 d = end_w1[1];
00603 a = start_w2[2];
00604 b = start_w2[1];
00605 }
00606 else{
00607 c = end_w2[2];
00608 d = end_w2[1];
00609 a = start_w1[2];
00610 b = start_w1[1];
00611 }
00612
00613
00614
00615 z = 0.5 * ( c + a + (b-d)/TMath::Tan(angle) );
00616 y = 0.5 * ( b + d + (a-c)*TMath::Tan(angle) );
00617
00618 return;
00619
00620 }
00621
00622
00623
00624
00625
00626 void Geometry::IntersectionPoint(const UInt_t wire1, const UInt_t wire2,
00627 const UChar_t plane1, const UChar_t plane2,
00628 Double_t &y, Double_t &z) const
00629
00630 {
00631 double WireStart1[3] = {0.};
00632 double WireStart2[3] = {0.};
00633 double WireEnd1[3] = {0.};
00634 double WireEnd2[3] = {0.};
00635
00636 this->WireEndPoints(plane1, wire1, WireStart1, WireEnd1);
00637 this->WireEndPoints(plane2, wire2, WireStart2, WireEnd2);
00638 this->IntersectionPoint(wire1, wire2, plane1, plane2,
00639 WireStart1, WireEnd1,
00640 WireStart2, WireEnd2, y, z);
00641 }
00642
00643 UInt_t Geometry::GetClosestOpChannel(const Double_t *xyz) const
00644 {
00645 Double_t dist2 = 0;
00646 Double_t min_dist2 = larlight::DATA::INVALID_DOUBLE;
00647 UInt_t closest_ch = larlight::DATA::INVALID_UINT;
00648 for(size_t ch=0; ch<fOpChannelVtx.size(); ++ch) {
00649
00650 dist2 =
00651 pow(xyz[0] - fOpChannelVtx.at(ch).at(0),2) +
00652 pow(xyz[1] - fOpChannelVtx.at(ch).at(1),2) +
00653 pow(xyz[2] - fOpChannelVtx.at(ch).at(2),2);
00654
00655 if( dist2 < min_dist2 ) {
00656
00657 min_dist2 = dist2;
00658 closest_ch = ch;
00659
00660 }
00661 }
00662
00663 return closest_ch;
00664 }
00665
00666 UInt_t Geometry::GetClosestOpChannel(const Double_t *xyz, Double_t &dist) const
00667 {
00668 Double_t min_dist2 = larlight::DATA::INVALID_DOUBLE;
00669 UInt_t closest_ch = larlight::DATA::INVALID_UINT;
00670 for(size_t ch=0; ch<fOpChannelVtx.size(); ++ch) {
00671
00672 dist =
00673 pow(xyz[0] - fOpChannelVtx.at(ch).at(0),2) +
00674 pow(xyz[1] - fOpChannelVtx.at(ch).at(1),2) +
00675 pow(xyz[2] - fOpChannelVtx.at(ch).at(2),2);
00676
00677 if( dist < min_dist2 ) {
00678
00679 min_dist2 = dist;
00680 closest_ch = ch;
00681
00682 }
00683 }
00684 dist = sqrt(dist);
00685 return closest_ch;
00686 }
00687
00688 void Geometry::GetOpChannelPosition(const UInt_t i, Double_t *xyz) const
00689 {
00690 if( i >= fOpChannelVtx.size() ) {
00691 throw LArUtilException(Form("Invalid PMT channel number: %d",i));
00692 xyz[0] = larlight::DATA::INVALID_DOUBLE;
00693 xyz[0] = larlight::DATA::INVALID_DOUBLE;
00694 xyz[0] = larlight::DATA::INVALID_DOUBLE;
00695 return;
00696 }
00697
00698 xyz[0] = fOpChannelVtx.at(i).at(0);
00699 xyz[1] = fOpChannelVtx.at(i).at(1);
00700 xyz[2] = fOpChannelVtx.at(i).at(2);
00701 return;
00702 }
00703
00704 const std::vector<Double_t>& Geometry::PlaneOriginVtx(UChar_t plane)
00705 {
00706 if(plane >= fPlaneOriginVtx.size()) {
00707 throw LArUtilException(Form("Invalid plane number: %d",plane));
00708 fPlaneOriginVtx.push_back(std::vector<Double_t>(3,larlight::DATA::INVALID_DOUBLE));
00709 return fPlaneOriginVtx.at(this->Nplanes());
00710 }
00711
00712 return fPlaneOriginVtx.at(plane);
00713 }
00714
00715 void Geometry::PlaneOriginVtx(UChar_t plane, Double_t *vtx) const
00716 {
00717 vtx[0] = fPlaneOriginVtx.at(plane)[0];
00718 vtx[1] = fPlaneOriginVtx.at(plane)[1];
00719 vtx[2] = fPlaneOriginVtx.at(plane)[2];
00720 }
00721
00722 }
00723
00724
00725 #endif