Jpp test-rotations-new
the software that should make you happy
Loading...
Searching...
No Matches
FreePathSolver Class Reference

Finds photon paths from a nanobeacon source to a target PMT that have a non-zero probability. More...

Public Member Functions

 FreePathSolver ()
 
JPhotonPath solve (int nscat, const JDirectedSource *src, const JPMTTarget *trg)
 

Protected Member Functions

double sourceScore (const JPhotonPath &p, const JDirectedSource *src)
 
double targetScore (const JPhotonPath &p, const JPMTTarget *trg)
 
double intersectScore (const JPhotonPath &p, const JPMTTarget *trg)
 
double getScore (const JPhotonPath &p, const JDirectedSource *src, const JPMTTarget *trg)
 

Detailed Description

Finds photon paths from a nanobeacon source to a target PMT that have a non-zero probability.

This means that

  • the emission angle has to be within the nanobeacon opening angle
  • the photon has to hit the PMT at an angle less than 90 degrees
  • the photon may not intersect the target

It works by maximizing a score function. If we find a score of 0, the path meets all criteria.

Definition at line 162 of file JBeaconSimulator.cc.

Constructor & Destructor Documentation

◆ FreePathSolver()

FreePathSolver::FreePathSolver ( )
inline

Definition at line 165 of file JBeaconSimulator.cc.

165{}

Member Function Documentation

◆ solve()

JPhotonPath FreePathSolver::solve ( int nscat,
const JDirectedSource * src,
const JPMTTarget * trg )
inline

Definition at line 167 of file JBeaconSimulator.cc.

167 {
168 //cout << "Running FreePathSolver::solve with nscat = " << nscat << endl ;
169
170 JPhotonPath p(min(2,nscat)) ;
171
172 // start at source
173 p.front() = src->getPosition() ;
174 // end on PMT surface
175 p.back() = trg->getPosition() ;
176 if( trg->getRadius()>0 ) p.back() = trg->getPosition() + trg->getRadius() * JVector3D(trg->getDirection()) ;
177
178 if( nscat == 0 ) return p ;
179
180 // create intermediate points
181 for( int nv=1 ; nv<(int)p.size()-1 ; ++nv ) {
182 double factor = 1.0 * nv / (p.size()-1) ;
183 p[nv] = (1-factor)*p.front() + factor*p.back() ;
184 }
185
186 int maxnsteps = -1 ;
187
188 if( nscat == 1 ) {
189 double score = getScore(p,src,trg) ;
190 double dl = 1 ; // m
191 const double dlmin = 0.0001 ;
192 JPosition3D dx(1,0,0) ;
193 JPosition3D dy(0,1,0) ;
194 JPosition3D dz(0,0,1) ;
195 int istep = 0 ;
196 while( score<0 ) {
197 if( ++istep == maxnsteps ) break ;
198 double initscore = score ;
199
200 // try step in x-direction
201 p[1] = p[1] + dl*dx ;
202 if( getScore(p,src,trg) < score ) {
203 // try moving in the opposite direction
204 p[1] = p[1] - 2*dl*dx ;
205 if( getScore(p,src,trg) < score ) p[1] = p[1] + dl*dx ;
206 }
207
208 // try step in y-direction
209 p[1] = p[1] + dl*dy ;
210 if( getScore(p,src,trg) < score ) {
211 // try moving in the opposite direction
212 p[1] = p[1] - 2*dl*dy ;
213 if( getScore(p,src,trg) < score ) p[1] = p[1] + dl*dy ;
214 }
215
216 // try step in z-direction
217 p[1] = p[1] + dl*dz ;
218 if( getScore(p,src,trg) < score ) {
219 // try moving in the opposite direction
220 p[1] = p[1] - 2*dl*dz ;
221 if( getScore(p,src,trg) < score ) p[1] = p[1] + dl*dz ;
222 }
223
224 // see if it worked
225 score = getScore(p,src,trg) ;
226 // check if we are stuck
227 if( score == initscore ) {
228 dl = 0.5 * dl ;
229 //cout << "dl = " << dl << endl ;
230 if( dl<dlmin ) break ;
231 }
232 if( p.getLength() > 10000 ) break ;
233 }
234 }
235
236 if( nscat>1) {
237 //cout << "nscat more than one" << endl ;
238 //cout << "starting with " << endl ;
239 //for( vector<JPosition3D>::iterator it=p.begin() ; it!= p.end() ; ++it ) cout << *it << endl ;
240 //cout << endl ;
241
242 double score = getScore(p,src,trg) ;
243 double dl = 1 ; // m
244 const double dlmin = 1e-10 ;
245
246 const int nsm = 6 ;
247 JPosition3D single_moves[nsm] = { JPosition3D(1,0,0), JPosition3D(0,1,0), JPosition3D(0,0,1),
248 JPosition3D(-1,0,0), JPosition3D(0,-1,0), JPosition3D(0,0,-1) } ;
249 /*ctor< pair<JPosition3D,JPosition3D> > moves ;
250 for( int i=0 ; i<nsm ; ++i ) {
251 for( int j=0 ; j<nsm ; ++j ) {
252 moves.push_back( pair<JPosition3D,JPosition3D>(single_moves[i],single_moves[j]) ) ;
253 }
254 }*/
255
256 int i = 0 ;
257
258 while( score<0 ) {
259 if( ++i>100 ) break ;
260 //cout << "@ " << JPosition3D(p[1]-src->getPosition()) << ", " << JPosition3D(p[2]-src->getPosition()) << ", score = " << score << ", dl = " << dl << endl ;
261 double initscore = score ;
262
263 for( int i=0; i<nsm; ++i ) {
264 // try move
265 p[1] = p[1] + dl * single_moves[i] ;
266 double newscore = getScore(p,src,trg) ;
267 if( newscore < score ) {
268 // if the score is reduced, undo the move
269 p[1] = p[1] - dl * single_moves[i] ;
270 } else {
271 //cout << "First vertex adds " << single_moves[i]
272 // << ", score difference = " << newscore - score << endl ;
273 score = newscore ;
274 }
275 }
276
277 for( int i=0; i<nsm; ++i ) {
278 // try move
279 p[2] = p[2] + dl * single_moves[i] ;
280 double newscore = getScore(p,src,trg) ;
281 if( newscore < score ) {
282 // if the score is reduced, undo the move
283 p[2] = p[2] - dl * single_moves[i] ;
284 } else {
285 //cout << "Second vertex adds " << single_moves[i]
286 // << ", score difference = " << newscore - score << endl ;
287 score = newscore ;
288 }
289 }
290
291 // see if it worked
292 score = getScore(p,src,trg) ;
293 // check if we are stuck
294 if( score == initscore ) {
295 //cout << "Stuck" << endl ;
296 dl = 0.5*dl ;
297 if( dl<dlmin ) break ;
298 }
299 if( p.getLength() > 10000 ) {
300 //cout << "Too long" << endl ;
301 break ;
302 }
303 }
304
305 // fill in the gaps
306 JPhotonPath p2(nscat) ;
307 p2[0] = p[0] ;
308 p2[1] = p[1] ;
309 p2[2] = p[2] ;
310 p2.back() = p.back() ;
311 for( int nv=3 ; nv<nscat+1 ; ++nv ) {
312 double factor = 1.0 * (nv-2) / (nscat-1) ;
313 p2[nv] = (1-factor)*p2[2] + factor*p2.back() ;
314 }
315 return p2 ;
316 }
317
318 return p ;
319
320 }
double getScore(const JPhotonPath &p, const JDirectedSource *src, const JPMTTarget *trg)
Data structure for position in three dimensions.
Data structure for vector in three dimensions.
Definition JVector3D.hh:36
A photon path.
const JPosition3D & getPosition() const
const JVersor3D & getDirection() const
const JPosition3D & getPosition() const

◆ sourceScore()

double FreePathSolver::sourceScore ( const JPhotonPath & p,
const JDirectedSource * src )
inlineprotected

Definition at line 324 of file JBeaconSimulator.cc.

324 {
325 double ct = JVersor3D(p[1]-src->getPosition()).getDot(src->getDirection()) ;
326 const double ctmin = cos(0.5*src->getOpeningAngle()) ;
327 double val = max(ctmin-ct,0.0) / (1-ctmin) ;
328 return -val*val ;
329 }
Data structure for normalised vector in three dimensions.
Definition JVersor3D.hh:28
double getDot(const JVersor3D &versor) const
Get dot product.
Definition JVersor3D.hh:156
JVersor3D getDirection() const
return the source direction
double getOpeningAngle() const
return the opening angle in radians

◆ targetScore()

double FreePathSolver::targetScore ( const JPhotonPath & p,
const JPMTTarget * trg )
inlineprotected

Definition at line 331 of file JBeaconSimulator.cc.

331 {
332 double ct = JVersor3D(p[p.size()-2]-p[p.size()-1]).getDot(trg->getDirection()) ;
333 const double ctmin = cos(0.5*trg->getOpeningAngle()) ;
334 double val = max(ctmin-ct,0.0) / (1-ctmin) ;
335 return -val*val ;
336 }
double getOpeningAngle() const
return the PMT opening angle in radians

◆ intersectScore()

double FreePathSolver::intersectScore ( const JPhotonPath & p,
const JPMTTarget * trg )
inlineprotected

Definition at line 338 of file JBeaconSimulator.cc.

338 {
339 double score = 0 ;
340
341 // check whether the photon path goes through the target sphere
342 // we do not need to consider the last vertex, because if that intersects the sphere
343 // the target score would be 0.
344 if( p.n == 2 ) return score ;
345
346 for( int nv=1 ; nv<(int)p.size()-2 ; ++nv ) {
347 JPhotonPath seg(0) ;
348 seg[0] = p[nv] ;
349 seg[1] = p[nv+1] ;
350 if( seg.hitsSphere(trg->getPosition(),trg->getRadius()) ) {
351 double d = JAxis3D( seg[0], JVersor3D(seg[1]-seg[0]) ).getDistance(trg->getPosition()) ;
352 double R = trg->getRadius() ;
353 double val = (R-d)/R ;
354 score -= val*val ;
355 //cout << "Segment from " << nv << " to " << nv+1 << "intersects sphere"
356 // << ", distance = " << d << ", val = " << val << endl ;
357 }
358 }
359
360 /*JPhotonPath pshort(p) ;
361 pshort.resize( pshort.size()-1 ) ;
362 --pshort.n ;
363 if( pshort.hitsSphere(trg->getPosition(),trg->getRadius()) ) {
364 JVersor3D hit_dir( pshort.getSphereHitPosition(trg->getPosition(),trg->getRadius()) - trg->getPosition() ) ;
365 double val = hit_dir.getDot(trg->getDirection()) ;
366 score -= val * val ;
367 }
368
369 // extra penalty when a vertex is inside the target
370 for( int nv=1 ; nv<p.n-1 ; ++nv ) {
371 double r = p[nv].getDistance(trg->getPosition()) ;
372 if( r < trg->getRadius() ) {
373 double val = ( trg->getRadius() - r ) / trg->getRadius() ;
374 score -= val * val ;
375 }
376 }*/
377
378 return score ;
379 }
Axis object.
Definition JAxis3D.hh:41
double getDistance(const JVector3D &pos) const
Get distance.
Definition JAxis3D.hh:213

◆ getScore()

double FreePathSolver::getScore ( const JPhotonPath & p,
const JDirectedSource * src,
const JPMTTarget * trg )
inlineprotected

Definition at line 382 of file JBeaconSimulator.cc.

382 {
383 double score = sourceScore(p,src) + targetScore(p,trg) + intersectScore(p,trg) ;
384 return score ;
385 }
double sourceScore(const JPhotonPath &p, const JDirectedSource *src)
double targetScore(const JPhotonPath &p, const JPMTTarget *trg)
double intersectScore(const JPhotonPath &p, const JPMTTarget *trg)

The documentation for this class was generated from the following file: