Classes | |
class | AccumulateIntervals |
accumulation utility to accumulate the total length of intervals More... | |
class | AccumulateIntersections |
accumulation utility to accumulate the total length of intersections More... | |
class | CompareIntersections |
"very specific" comparison for intersections!!! More... | |
Functions | |
int | intersect (const ILVolume::Interval &i1, const ILVolume::Interval &i2) |
check the intersection | |
int | intersect (const ILVolume::Intersection &i1, const ILVolume::Intersection &i2) |
check the intersection | |
template<class OUTPUTTYPE> | |
unsigned int | TicksToIntervals (const ISolid::Ticks &ticks, OUTPUTTYPE out) |
helpful method to decode the ticks sequence into sequence of intervals return the number of intervals | |
template<class OUTPUTTYPE> | |
StatusCode | MergeOwnAndChildContainers (const ILVolume::Intersections &own, const ILVolume::Intersections &child, OUTPUTTYPE out, const ILVolume *, const double) |
helpful method of merging 2 containers | |
template<class OUTPUTTYPE> | |
StatusCode | MergeOwnAndChildContainers2 (const ILVolume::Intersections &own, const ILVolume::Intersections &child, OUTPUTTYPE out, const ILVolume *volume, const double length) |
helpful method of merging 2 containers | |
int | correct (const ILVolume *volume, ILVolume::Intersections &cnt, const double tick, unsigned int index=0) |
try to validate&correct the intersections |
int VolumeIntersectionIntervals::intersect | ( | const ILVolume::Interval & | i1, | |
const ILVolume::Interval & | i2 | |||
) | [inline] |
check the intersection
Definition at line 92 of file VolumeIntersectionIntervals.h.
00094 { 00095 const int res1 = DetDesc::compare ( i1.second , i2.first ) ; 00096 if ( ! ( 0 < res1 ) ) { return -1 ; } // RETURN 00097 const int res2 = DetDesc::compare ( i2.second , i1.first ) ; 00098 if ( ! ( 0 < res2 ) ) { return 1 ; } // RETURN 00099 return 0 ; // RETURN 00100 }
int VolumeIntersectionIntervals::intersect | ( | const ILVolume::Intersection & | i1, | |
const ILVolume::Intersection & | i2 | |||
) | [inline] |
check the intersection
Definition at line 104 of file VolumeIntersectionIntervals.h.
00106 { 00107 return intersect ( i1.first , i2.first ) ; 00108 }
unsigned int VolumeIntersectionIntervals::TicksToIntervals | ( | const ISolid::Ticks & | ticks, | |
OUTPUTTYPE | out | |||
) | [inline] |
helpful method to decode the ticks sequence into sequence of intervals return the number of intervals
ticks | input container of Ticks | |
out | output iterator for container of "Intervals" |
Definition at line 120 of file VolumeIntersectionIntervals.h.
00122 { 00123 // interval can be constructed from at least 2 ticks! 00124 if( ticks.size() < 2 ) { return 0 ; } // RETURN! 00125 00126 unsigned int res = 0 ; 00127 00128 ISolid::Ticks::const_iterator it = ticks.begin(); 00129 ISolid::Tick tickPrevious = *it++; // size tested. this is safe 00130 while( ticks.end() != it ) { 00131 ISolid::Tick tickCurrent = *it++; 00132 if( tickCurrent > tickPrevious ) { 00133 ++res; 00134 *out++ = ILVolume::Interval( tickPrevious , tickCurrent ) ; 00135 } 00136 if ( ticks.end() != it ) { tickPrevious = *it++; } 00137 } 00139 return res; 00140 }
StatusCode VolumeIntersectionIntervals::MergeOwnAndChildContainers | ( | const ILVolume::Intersections & | own, | |
const ILVolume::Intersections & | child, | |||
OUTPUTTYPE | out, | |||
const ILVolume * | , | |||
const | double | |||
) | [inline] |
helpful method of merging 2 containers
own | container of 'own' intersections | |
child | container of 'child' intersections | |
out | ?? |
here we have both containers - own and child containers try to merge the containers
this situation means that something wrong with geometry description!!!
return status
Definition at line 183 of file VolumeIntersectionIntervals.h.
00188 { 00192 typedef std::vector<ILVolume::Intersections::size_type> IndexCont ; 00193 typedef ILVolume::Intersections::const_iterator Iter ; 00194 typedef ISolid::Tick Tick ; 00195 typedef ILVolume::Interval Interval ; 00196 const double tol = 1.e-6; // Needed to test equalities... 00199 for( Iter iterTop = own.begin(); own.end() != iterTop ; ++iterTop ) { 00200 const Interval& intervalTop = iterTop->first ; 00201 const Material* matTop = iterTop->second ; 00202 // temporary container of indexes of related intervals 00203 IndexCont tmpIndex; 00204 for( Iter iter = child.begin(); child.end() != iter ; ++iter ) { 00205 const Interval& intervalLoc = iter->first; 00206 00207 if( intervalLoc.second <= (intervalTop.first+tol) ) { 00208 ; // the second interval is lower then the first one! it's OK 00209 } else if( intervalTop.first <= (intervalLoc.first+tol) && 00210 intervalLoc.second <= (intervalTop.second+tol) ) { 00211 // the second interval is inside the first one! it's OK 00212 tmpIndex.push_back( iter - child.begin() ); 00213 } else if( intervalTop.second <= (intervalLoc.first+tol) ) { 00214 ; // the second interval in higher then the first one! it's OK 00215 } else { 00219 DetDesc::Services* services = DetDesc::services(); 00220 MsgStream log (services->msgSvc() , "TransportSvc"); 00221 log << MSG::ERROR 00222 << "VolumeIntersection:Merge error 15 : interval " 00223 << intervalLoc.first << " " 00224 << intervalLoc.second << " master " 00225 << intervalTop.first << " " 00226 << intervalTop.second << endreq; 00227 services->release(); 00228 return StatusCode(15) ; 00229 } 00230 // ? RETURN !!! 00231 } // end of loop over the child container 00233 // try to merge intervals 00234 Tick leftTick = intervalTop.first ; 00235 Tick mostRightTick = intervalTop.second ; 00236 const Material* prevMatLocal = 0; 00237 for( IndexCont::const_iterator it = tmpIndex.begin(); 00238 tmpIndex.end() != it ; ++it ) { 00239 Iter iterLocal = child.begin() + (*it) ; 00240 const Interval& intervalLocal = iterLocal->first ; 00241 const Material* matLocal = iterLocal->second ; 00243 if( leftTick <= (intervalLocal.first + tol) && 00244 intervalLocal.first < mostRightTick ) { 00245 if( leftTick <= (intervalLocal.first - tol) ) { 00246 *out++ = ILVolume::Intersection( Interval( leftTick , 00247 intervalLocal.first ), 00248 matTop ) ; 00249 } 00250 leftTick = intervalLocal.first; 00251 00252 if( intervalLocal.second <= (mostRightTick+tol) ) { 00253 *out++ = ILVolume::Intersection( Interval( leftTick , 00254 intervalLocal.second), 00255 matLocal ) ; 00256 } else { // geometry error!!! 00257 return StatusCode(16) ; 00258 } // RETURN !!! 00259 00260 //=== This is a hack, to accept overlaping volumes with same 00261 //=== material without complaining... 00262 } else if ( (matLocal == prevMatLocal) && 00263 (intervalLocal.second <= (mostRightTick+tol) ) ) { 00264 if ( intervalLocal.second > leftTick ) { 00265 *out++ = ILVolume::Intersection( Interval( leftTick , 00266 intervalLocal.second), 00267 matLocal ) ; 00268 } 00269 } else { // geometry error!!! 00270 DetDesc::Services* services = DetDesc::services(); 00271 MsgStream log (services->msgSvc() , "TransportSvc"); 00272 log << MSG::ERROR 00273 << "VolumeIntersection:Merge error 17 : interval " 00274 << intervalLocal.first << " " 00275 << intervalLocal.second << " master " 00276 << leftTick << " " 00277 << mostRightTick << endreq; 00278 services->release(); 00279 return StatusCode(17) ; 00280 } // RETURN !!! 00281 leftTick = intervalLocal.second; 00282 prevMatLocal = matLocal; 00283 } // end of loop over temporary index container 00284 00285 if( leftTick <= (mostRightTick - tol) ) { 00286 *out++ = ILVolume::Intersection( Interval( leftTick , mostRightTick ) , 00287 matTop ) ; 00288 } 00289 leftTick = mostRightTick; 00290 } // end of loop over own intervals 00291 00293 return StatusCode::SUCCESS; 00294 }
StatusCode VolumeIntersectionIntervals::MergeOwnAndChildContainers2 | ( | const ILVolume::Intersections & | own, | |
const ILVolume::Intersections & | child, | |||
OUTPUTTYPE | out, | |||
const ILVolume * | volume, | |||
const double | length | |||
) | [inline] |
helpful method of merging 2 containers
own | container of 'own' intersections | |
child | container of 'child' intersections | |
out | ?? |
ignore the child with the same material : ?
return status
Definition at line 306 of file VolumeIntersectionIntervals.h.
00311 { 00312 /* here we have both containers - own and child containers 00313 * try to merge the containers 00314 */ 00315 typedef std::vector<ILVolume::Intersections::size_type> IndexCont ; 00316 typedef ILVolume::Intersections::const_iterator Iter ; 00317 typedef ISolid::Tick Tick ; 00318 typedef ILVolume::Interval Interval ; 00319 // loop over all "own" intervals 00320 for ( Iter iterTop = own.begin(); own.end() != iterTop ; ++iterTop ) 00321 { 00322 const Interval& intervalTop = iterTop->first ; 00323 const Material* matTop = iterTop->second ; 00324 // temporary container of indexes of related intervals 00325 IndexCont tmpIndex; 00326 for ( Iter iter = child.begin(); child.end() != iter ; ++iter ) 00327 { 00328 const Interval& intervalLoc = iter->first ; 00329 00330 const int result = VolumeIntersectionIntervals::intersect 00331 ( intervalTop , intervalLoc ) ; 00332 00333 if ( 0 != result ) { /* it is OK */ } 00334 else 00335 { 00336 // here we have either GOOD case or geometry error , 00337 // keep them togather for a moment 00338 tmpIndex.push_back ( iter - child.begin() ); 00339 } 00340 } 00341 // end of loop over the child container 00342 // 00343 // try to merge intervals 00344 Tick leftTick = intervalTop.first ; 00345 Tick mostRightTick = intervalTop.second ; 00346 00347 for ( IndexCont::const_iterator it = tmpIndex.begin(); 00348 tmpIndex.end() != it ; ++it ) 00349 { 00350 Iter iterLocal = child.begin() + (*it) ; 00351 const Interval& intervalLocal = iterLocal->first ; 00352 const Material* matLocal = iterLocal->second ; 00354 if ( matLocal == matTop ) { continue ; } 00355 // 00356 const int rL = DetDesc::compare ( leftTick , intervalLocal.first ) ; 00357 const int rR = DetDesc::compare ( intervalLocal.second , mostRightTick ) ; 00358 00359 if ( rL <= 0 && rR <=0 ) 00360 { 00361 // 00362 if ( rL < 0 ) 00363 { 00364 *out++ = ILVolume::Intersection 00365 ( ILVolume::Interval ( leftTick , intervalLocal.first ) , matTop ) ; 00366 leftTick = intervalLocal.first ; 00367 } 00368 // 00369 if ( rR < 0 ) 00370 { 00371 *out++ = ILVolume::Intersection 00372 ( ILVolume::Interval ( leftTick , intervalLocal.second ) , matLocal ) ; 00373 leftTick = intervalLocal.second ; 00374 } 00375 else if ( rR ==0 ) 00376 { 00377 *out++ = ILVolume::Intersection 00378 ( ILVolume::Interval ( leftTick , mostRightTick ) , matLocal ) ; 00379 leftTick = mostRightTick ; 00380 } 00381 } 00382 else 00383 { 00384 /* here we have real problems */ 00385 00386 /* the problem is serious, but we have some guess how to solve it */ 00387 if ( DetDesc::IntersectionErrors::recovery() ) 00388 { 00389 // try to recover (1) 00390 if ( 0 < rL && rR < 0 ) 00391 { 00392 *out++ = ILVolume::Intersection 00393 ( ILVolume::Interval ( leftTick , intervalLocal.second ) , matLocal ) ; 00394 // report the problem 00395 DetDesc::IntersectionErrors::recovered 00396 ( volume , matTop , matLocal , 00397 length * ( leftTick - intervalLocal.first ) ) ; 00398 // 00399 leftTick = intervalLocal.second ; 00400 } 00401 // try to recover (2) 00402 else if ( 0 < rL && rR == 0 ) 00403 { 00404 *out++ = ILVolume::Intersection 00405 ( ILVolume::Interval ( leftTick , mostRightTick ) , matLocal ) ; 00406 // 00407 // report the problem 00408 DetDesc::IntersectionErrors::recovered 00409 ( volume , matTop , matLocal , 00410 length * ( leftTick - intervalLocal.first ) ) ; 00411 // 00412 leftTick = mostRightTick ; 00413 } 00414 // try to recover (3) 00415 else if ( rL <= 0 && 0 < rR ) 00416 { 00417 if ( rL < 0 ) 00418 { 00419 *out++ = ILVolume::Intersection 00420 ( ILVolume::Interval ( leftTick , intervalLocal.first ) , matTop ) ; 00421 leftTick = intervalLocal.first ; 00422 } 00423 // 00424 *out++ = ILVolume::Intersection 00425 ( ILVolume::Interval ( leftTick , mostRightTick ) , matLocal ) ; 00426 // 00427 // report the problem 00428 DetDesc::IntersectionErrors::recovered 00429 ( volume , matTop , matLocal , 00430 length * ( intervalLocal.second - mostRightTick ) ) ; 00431 // 00432 leftTick = mostRightTick ; 00433 } 00434 else if ( rL > 0 && rR > 0 ) 00435 { 00436 *out++ = ILVolume::Intersection 00437 ( ILVolume::Interval ( leftTick , mostRightTick) , matLocal ) ; 00438 // 00439 // report the problem 00440 DetDesc::IntersectionErrors::recovered 00441 ( volume , matTop , matLocal , 00442 length * ( intervalLocal.second - mostRightTick + 00443 leftTick - intervalLocal.first ) ) ; 00444 // 00445 leftTick = mostRightTick ; 00446 } 00447 } // recover allowed? 00448 else 00449 { 00450 DetDesc::IntersectionErrors::setCode ( 17 , volume ) ; 00451 return StatusCode ( 17 ) ; 00452 } 00453 } // geometry problmes 00454 }// end of loop over the temporary index container 00455 // the last intersection 00456 const int rF = DetDesc::compare ( leftTick , mostRightTick ) ; 00457 if ( rF < 0 ) 00458 { 00459 *out++ = ILVolume::Intersection 00460 ( ILVolume::Interval ( leftTick , mostRightTick ) , matTop ) ; 00461 } 00462 // adjuts the left tick 00463 leftTick = mostRightTick; 00464 } // end of loop over own intervals 00465 00467 return StatusCode::SUCCESS; 00468 }
int VolumeIntersectionIntervals::correct | ( | const ILVolume * | volume, | |
ILVolume::Intersections & | cnt, | |||
const double | tick, | |||
unsigned int | index = 0 | |||
) | [inline] |
try to validate&correct the intersections
Definition at line 491 of file VolumeIntersectionIntervals.h.
00495 { 00496 // nothing to correct? 00497 if ( 2 + index > cnt.size() ) { return 0 ; } // RETURN 00498 ILVolume::Intersections::iterator i1 = cnt.begin() + index ; 00499 // loop over all the intersections 00500 for ( ILVolume::Intersections::iterator i2 = i1 + 1 ; 00501 i2 != cnt.end() ; ++i1 , ++i2 , ++index ) 00502 { 00503 // OPTIONAL CHECK (could be removed) 00504 // the intersection of the zero length 00505 // check the length of the intersecion: 00506 const int length = DetDesc::compare ( i1->first.first , i1->first.second ) ; 00507 // invalid or empty intersection!!! 00508 if ( 0 < length ) 00509 { 00510 if ( DetDesc::IntersectionErrors::recovery () ) 00511 { 00512 DetDesc::IntersectionErrors::skip 00513 ( volume , i1->second , 00514 tick * ( i1->first.second - i1->first.first ) ) ; 00515 cnt.erase( i1 ) ; 00516 return correct ( volume , cnt , tick , index ) + 1 ; // RETURN 00517 } 00518 DetDesc::IntersectionErrors::setCode ( 26 , volume ) ; 00519 return 0 ; 00520 } 00521 else if ( 0 == length ) 00522 { 00523 DetDesc::IntersectionErrors::skip 00524 ( volume , i1->second , 0 ) ; 00525 cnt.erase ( i1 ) ; 00526 return correct ( volume , cnt , tick , index ) + 1 ; // RETURN 00527 } 00528 // ====================================================================== 00529 /* check the end point of the first intersection 00530 * and the begin point of the second intersection 00531 */ 00532 const int result = DetDesc::compare ( i1->first.second , i2->first.first ) ; 00533 // invalid position of the points: 00534 if ( 0 < result && i1->second != i2->second ) 00535 { 00536 if ( DetDesc::IntersectionErrors::recovery() ) 00537 { 00538 DetDesc::IntersectionErrors::recovered 00539 ( volume , 00540 i1 -> second , 00541 i2 -> second , 00542 tick * ( i1->first.second - i2->first.first ) ) ; 00543 const double t1 = 0.5 * ( i1 -> first.second + i1 -> first.first) ; 00544 i1 -> first.second = t1 ; 00545 i2 -> first.first = t1 ; 00546 return correct ( volume , cnt , tick , index ) + 1 ; // RETURN 00547 } 00548 DetDesc::IntersectionErrors::setCode ( 27 , volume ) ; 00549 return 0 ; 00550 } 00551 // try to recover this pathological case 00552 if ( 0 < result && i1->second == i2->second ) 00553 { 00554 if ( DetDesc::IntersectionErrors::recovery() ) 00555 { 00556 DetDesc::IntersectionErrors::recovered 00557 ( volume , 00558 i1 -> second , 00559 i2 -> second , 00560 tick * ( i1->first.second - i2->first.first ) ) ; 00561 i1->first.second = i2->first.second ; 00562 cnt.erase ( i2 ) ; 00563 return correct ( volume , cnt , tick , index ) + 1 ; // RETURN 00564 } 00565 DetDesc::IntersectionErrors::setCode ( 28 , volume ) ; 00566 return 0 ; 00567 } 00568 // the points are "comparable" 00569 if ( 0 == result ) 00570 { 00571 // redefine the intersection for the exact match: 00572 i1 -> first.second = i2->first.first ; 00573 // but if we have the same material, 00574 // we can "merge" both intersection togather: 00575 if ( i1->second == i2->second ) // the same material! 00576 { 00577 i1->first.second = i2->first.second ; 00578 cnt.erase ( i2 ) ; 00579 return correct ( volume , cnt , tick , index ) + 1 ; // RETURN 00580 } // the same material 00581 } // the points are comparable 00582 } // loop over intersections 00583 return 0 ; // RETURN 00584 } // "correct"