Fork me on GitHub

source: svn/trunk/Utilities/Fastjet/plugins/SISCone/src/protocones.cc@ 733

Last change on this file since 733 was 11, checked in by severine ovyn, 16 years ago

Fastjet added; CDFCones directory has been changed

File size: 28.4 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2// File: protocones.cpp //
3// Description: source file for stable cones determination (Cstable_cones) //
4// This file is part of the SISCone project. //
5// For more details, see http://projects.hepforge.org/siscone //
6// //
7// Copyright (c) 2006 Gavin Salam and Gregory Soyez //
8// //
9// This program is free software; you can redistribute it and/or modify //
10// it under the terms of the GNU General Public License as published by //
11// the Free Software Foundation; either version 2 of the License, or //
12// (at your option) any later version. //
13// //
14// This program is distributed in the hope that it will be useful, //
15// but WITHOUT ANY WARRANTY; without even the implied warranty of //
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
17// GNU General Public License for more details. //
18// //
19// You should have received a copy of the GNU General Public License //
20// along with this program; if not, write to the Free Software //
21// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
22// //
23// $Revision: 1.1 $//
24// $Date: 2008-11-06 14:32:12 $//
25///////////////////////////////////////////////////////////////////////////////
26
27/*******************************************************
28 * Introductory note: *
29 * Since this file has many member functions, we have *
30 * structured them in categories: *
31 * INITIALISATION FUNCTIONS *
32 * - ctor() *
33 * - ctor(particle_list) *
34 * - dtor() *
35 * - init(particle_list) *
36 * ALGORITHM MAIN ENTRY *
37 * - get_stable_cone(radius) *
38 * ALGORITHM MAIN STEPS *
39 * - init_cone() *
40 * - test_cone() *
41 * - update_cone() *
42 * - proceed_with_stability() *
43 * ALGORITHM MAIN STEPS FOR COCIRCULAR SITUATIONS *
44 * - cocircular_pt_less(v1, v2) *
45 * - prepare_cocircular_list() *
46 * - test_cone_cocircular() *
47 * - test_stability(candidate, border_list) *
48 * - updat_cone_cocircular() *
49 * RECOMPUTATION OF CONE CONTENTS *
50 * - compute_cone_contents() *
51 * - recompute_cone_contents() *
52 * - recompute_cone_contents_if_needed() *
53 * VARIOUS TOOLS *
54 * - circle_intersect() *
55 * - is_inside() *
56 * - abs_dangle() *
57 *******************************************************/
58
59#include "../interface/protocones.h"
60#include "../interface/siscone_error.h"
61#include "../interface/defines.h"
62#include <math.h>
63#include <iostream>
64#include "../interface/circulator.h"
65#include <algorithm>
66
67namespace siscone{
68
69using namespace std;
70
71/**********************************************************************
72 * Cstable_cones implementation *
73 * Computes the list of stable comes from a particle list. *
74 * This class does the first fundamental task of te cone algorithm: *
75 * it is used to compute the list of stable cones given a list *
76 * of particles. *
77 **********************************************************************/
78
79////////////////////////////////////////////////////////
80// INITIALISATION FUNCTIONS //
81// - ctor() //
82// - ctor(particle_list) //
83// - dtor() //
84// - init(particle_list) //
85////////////////////////////////////////////////////////
86
87// default ctor
88//--------------
89Cstable_cones::Cstable_cones(){
90 nb_tot = 0;
91 hc = NULL;
92}
93
94// ctor with initialisation
95//--------------------------
96Cstable_cones::Cstable_cones(vector<Cmomentum> &_particle_list)
97 : Cvicinity(_particle_list){
98
99 nb_tot = 0;
100 hc = NULL;
101}
102
103// default dtor
104//--------------
105Cstable_cones::~Cstable_cones(){
106 if (hc!=NULL) delete hc;
107}
108
109/*
110 * initialisation
111 * - _particle_list list of particles
112 * - _n number of particles
113 *********************************************************************/
114void Cstable_cones::init(vector<Cmomentum> &_particle_list){
115 // check already allocated mem
116 if (hc!=NULL){
117 delete hc;
118 }
119 if (protocones.size()!=0)
120 protocones.clear();
121
122 multiple_centre_done.clear();
123
124 // initialisation
125 set_particle_list(_particle_list);
126}
127
128
129////////////////////////////////////////////////////////
130// ALGORITHM MAIN ENTRY //
131// - get_stable_cone(radius) //
132////////////////////////////////////////////////////////
133
134/*
135 * compute stable cones.
136 * This function really does the job i.e. computes
137 * the list of stable cones (in a seedless way)
138 * - _radius: radius of the cones
139 * The number of stable cones found is returned
140 *********************************************************************/
141int Cstable_cones::get_stable_cones(double _radius){
142 int p_idx;
143
144 // check if everything is correctly initialised
145 if (n_part==0){
146 return 0;
147 }
148
149 R = _radius;
150 R2 = R*R;
151
152 // allow hash for cones candidates
153 hc = new hash_cones(n_part, R2);
154
155 // browse all particles
156 for (p_idx=0;p_idx<n_part;p_idx++){
157 // step 0: compute the child list CL.
158 // Note that this automatically sets the parent P
159 build(&plist[p_idx], 2.0*R);
160
161 // special case:
162 // if the vicinity is empty, the parent particle is a
163 // stable cone by itself. Add it to protocones list.
164 if (vicinity_size==0){
165 protocones.push_back(*parent);
166 continue;
167 }
168
169 // step 1: initialise with the first cone candidate
170 init_cone();
171
172 do{
173 // step 2: test cone stability for that pair (P,C)
174 test_cone();
175
176 // step 3: go to the next cone child candidate C
177 } while (!update_cone());
178 }
179
180 return proceed_with_stability();
181}
182
183
184////////////////////////////////////////////////////////
185// ALGORITHM MAIN STEPS //
186// - init_cone() //
187// - test_cone() //
188// - update_cone() //
189// - proceed_with_stability() //
190////////////////////////////////////////////////////////
191
192/*
193 * initialise the cone.
194 * We take the first particle in the angular ordering to compute
195 * this one
196 * return 0 on success, 1 on error
197 *********************************************************************/
198int Cstable_cones::init_cone(){
199 // The previous version of the algorithm was starting the
200 // loop around vicinity elements with the "most isolated" child.
201 // given the nodist method to calculate the cone contents, we no
202 // longer need to worry about which cone comes first...
203 first_cone=0;
204
205 // now make sure we have lists of the cocircular particles
206 prepare_cocircular_lists();
207
208 //TODO? deal with a configuration with only degeneracies ?
209 // The only possibility seems a regular hexagon with a parent point
210 // in the centre. And this situation is by itself unclear.
211 // Hence, we do nothing here !
212
213 // init set child C
214 centre = vicinity[first_cone];
215 child = centre->v;
216 centre_idx = first_cone;
217
218 // build the initial cone (nodist: avoids calculating distances --
219 // just deduces contents by circulating around all in/out operations)
220 // this function also sets the list of included particles
221 compute_cone_contents();
222
223 return 0;
224}
225
226
227/*
228 * test cones.
229 * We check if the cone(s) built with the present parent and child
230 * are stable
231 * return 0 on success 1 on error
232 *********************************************************************/
233int Cstable_cones::test_cone(){
234 Creference weighted_cone_ref;
235
236 // depending on the side we are taking the child particle,
237 // we test different configuration.
238 // Each time, two configurations are tested in such a way that
239 // all 4 possible cases (parent or child in or out the cone)
240 // are tested when taking the pair of particle parent+child
241 // and child+parent.
242
243 // here are the tests entering the first series:
244 // 1. check if the cone is already inserted
245 // 2. check cone stability for the parent and child particles
246
247 if (centre->side){
248 // test when both particles are not in the cone
249 // or when both are in.
250 // Note: for the totally exclusive case, test emptyness before
251 cone_candidate = cone;
252 if (cone.ref.not_empty()){
253 hc->insert(&cone_candidate, parent, child, false, false);
254 }
255
256 cone_candidate = cone;
257 cone_candidate+= *parent + *child;
258 hc->insert(&cone_candidate, parent, child, true, true);
259 } else {
260 // test when 1! of the particles is in the cone
261 cone_candidate = cone + *parent;
262 hc->insert(&cone_candidate, parent, child, true, false);
263
264 cone_candidate = cone + *child;
265 hc->insert(&cone_candidate, parent, child, false, true);
266 }
267
268 nb_tot+=2;
269
270 return 0;
271}
272
273
274/*
275 * update the cone
276 * go to the next child for that parent and update 'cone' appropriately
277 * return 0 if update candidate found, 1 otherwise
278 ***********************************************************************/
279int Cstable_cones::update_cone(){
280 // get the next child and centre
281 centre_idx++;
282 if (centre_idx==vicinity_size)
283 centre_idx=0;
284 if (centre_idx==first_cone)
285 return 1;
286
287 // update the cone w.r.t. the old child
288 // only required if the old child is entering inside in which
289 // case we need to add it. We also know that the child is
290 // inside iff its side is -.
291 if (!centre->side){
292 // update cone
293 cone += (*child);
294
295 // update info on particles inside
296 centre->is_inside->cone = true;
297
298 // update stability check quantities
299 dpt += fabs(child->px)+fabs(child->py);
300 }
301
302 // update centre and child to correspond to the new position
303 centre = vicinity[centre_idx];
304 child = centre->v;
305
306 // check cocircularity
307 // note that if cocirculaity is detected (i.e. if we receive 1
308 // in the next test), we need to recall 'update_cone' directly
309 // since tests and remaining part of te update has been performed
310 //if (cocircular_check())
311 if (cocircular_check())
312 return update_cone();
313
314
315 // update the cone w.r.t. the new child
316 // only required if the new child was already inside in which
317 // case we need to remove it. We also know that the child is
318 // inside iff its side is +.
319 if ((centre->side) && (cone.ref.not_empty())){
320 // update cone
321 cone -= (*child);
322
323 // update info on particles inside
324 centre->is_inside->cone = false;
325
326 // update stability check quantities
327 dpt += fabs(child->px)+fabs(child->py); //child->perp2();
328 }
329
330 // check that the addition and subtraction of vectors does
331 // not lead to too much rounding error
332 // for that, we compute the sum of pt modifications and of |pt|
333 // since last recomputation and once the ratio overpasses a threshold
334 // we recompute vicinity.
335 if ((dpt>PT_TSHOLD*(fabs(cone.px)+fabs(cone.py))) && (cone.ref.not_empty())){
336 recompute_cone_contents();
337 }
338 if (cone.ref.is_empty()){
339 cone = Cmomentum();
340 dpt=0.0;
341 }
342
343 return 0;
344}
345
346
347/*
348 * compute stability of all enumerated candidates.
349 * For all candidate cones which are stable w.r.t. their border particles,
350 * pass the last test: stability with quadtree intersection
351 ************************************************************************/
352int Cstable_cones::proceed_with_stability(){
353 int i,n;
354 hash_element *elm;
355
356 n=0;
357 for (i=0;i<=hc->mask;i++){
358 // test ith cell of the hash array
359 elm = hc->hash_array[i];
360
361 // browse elements therein
362 while (elm!=NULL){
363 // test stability
364 if (elm->is_stable){
365 // stability is not ensured by all pairs of "edges" already browsed
366#ifdef USE_QUADTREE_FOR_STABILITY_TEST
367 // => testing stability with quadtree intersection
368 if (quadtree->circle_intersect(elm->eta, elm->phi, R2)==elm->ref)
369#else
370 // => testing stability with the particle-list intersection
371 if (circle_intersect(elm->eta, elm->phi)==elm->ref)
372#endif
373 protocones.push_back(Cmomentum(elm->eta, elm->phi, elm->ref));
374 }
375
376 // jump to the next one
377 elm = elm->next;
378 }
379 }
380
381 // free hash
382 // we do that at this level because hash eats rather a lot of memory
383 // we want to free it before running the split/merge algorithm
384 delete hc;
385 hc=NULL;
386
387 return protocones.size();
388}
389
390
391////////////////////////////////////////////////////////
392// ALGORITHM MAIN STEPS FOR COCIRCULAR SITUATIONS //
393// - cocircular_pt_less(v1, v2) //
394// - prepare_cocircular_list() //
395// - test_cone_cocircular() //
396// - test_stability(candidate, border_vect) //
397// - updat_cone_cocircular() //
398////////////////////////////////////////////////////////
399
400/// pt-ordering of momenta used for the cocircular case
401bool cocircular_pt_less(Cmomentum *v1, Cmomentum *v2){
402 return v1->perp2() < v2->perp2();
403}
404
405/*
406 * run through the vicinity of the current parent and for each child
407 * establish which other members are cocircular... Note that the list
408 * associated with each child contains references to vicinity
409 * elements: thus two vicinity elements each associated with one given
410 * particle may appear in a list -- this needs to be watched out for
411 * later on...
412 **********************************************************************/
413void Cstable_cones::prepare_cocircular_lists() {
414 circulator<vector<Cvicinity_elm*>::iterator > here(vicinity.begin(),
415 vicinity.begin(),
416 vicinity.end());
417
418 circulator<vector<Cvicinity_elm*>::iterator > search(here);
419
420 do {
421 Cvicinity_elm* here_pntr = *here();
422 search.set_position(here);
423
424 // search forwards for things that should have "here" included in
425 // their cocircularity list
426 while (true) {
427 ++search;
428 if ( abs_dphi((*search())->angle, here_pntr->angle) <
429 here_pntr->cocircular_range
430 && search() != here()) {
431 (*search())->cocircular.push_back(here_pntr);
432 } else {
433 break;
434 }
435 }
436
437 // search backwards
438 search.set_position(here);
439 while (true) {
440 --search;
441 if ( abs_dphi((*search())->angle, here_pntr->angle) <
442 here_pntr->cocircular_range
443 && search() != here()) {
444 (*search())->cocircular.push_back(here_pntr);
445 } else {
446 break;
447 }
448 }
449
450 ++here;
451 } while (here() != vicinity.begin());
452
453}
454
455/*
456 * Testing cocircular configurations in p^3 time,
457 * rather than 2^p time; we will test all contiguous subsets of points
458 * on the border --- note that this is till probably overkill, since
459 * in principle we only have to test situations where up to a
460 * half-circle is filled (but going to a full circle is simpler)
461 ******************************************************************/
462void Cstable_cones::test_cone_cocircular(Cmomentum & borderless_cone,
463 list<Cmomentum *> & border_list) {
464 vector<Cborder_store> border_vect;
465
466 border_vect.reserve(border_list.size());
467 for (list<Cmomentum *>::iterator it = border_list.begin();
468 it != border_list.end(); it++) {
469 border_vect.push_back(Cborder_store(*it, centre->eta, centre->phi));
470 }
471
472 // get them into order of angle
473 sort(border_vect.begin(), border_vect.end());
474
475 // set up some circulators, since these will help us go around the
476 // circle easily
477 circulator<vector<Cborder_store>::iterator >
478 start(border_vect.begin(), border_vect.begin(),border_vect.end());
479 circulator<vector<Cborder_store>::iterator > mid(start), end(start);
480
481 // test the borderless cone
482 Cmomentum candidate = borderless_cone;
483 candidate.build_etaphi();
484 if (candidate.ref.not_empty())
485 test_stability(candidate, border_vect);
486
487 do {
488 // reset status wrt inclusion in the cone
489 mid = start;
490 do {
491 mid()->is_in = false;
492 } while (++mid != start);
493
494 // now run over all inclusion possibilities with this starting point
495 candidate = borderless_cone;
496 while (++mid != start) {
497 // will begin with start+1 and go up to start-1
498 mid()->is_in = true;
499 candidate += *(mid()->mom);
500 test_stability(candidate, border_vect);
501 }
502
503 } while (++start != end);
504
505 // mid corresponds to momentum that we need to include to get the
506 // full cone
507 mid()->is_in = true;
508 candidate += *(mid()->mom);
509 test_stability(candidate, border_vect);
510}
511
512
513/**
514 * carry out the computations needed for the stability check of the
515 * candidate, using the border_vect to indicate which particles
516 * should / should not be in the stable cone; if the cone is stable
517 * insert it into the hash.
518 **********************************************************************/
519void Cstable_cones::test_stability(Cmomentum & candidate, const vector<Cborder_store> & border_vect) {
520
521 // this almost certainly has not been done...
522 candidate.build_etaphi();
523
524 bool stable = true;
525 for (unsigned i = 0; i < border_vect.size(); i++) {
526 if (is_inside(&candidate, border_vect[i].mom) ^ (border_vect[i].is_in)) {
527 stable = false;
528 break; // it's unstable so there's no point continuing
529 }
530 }
531
532 if (stable) hc->insert(&candidate);
533}
534
535/*
536 * check if we are in a situation of cocircularity.
537 * if it is the case, update and test in the corresponding way
538 * return 'false' if no cocircularity detected, 'true' otherwise
539 * Note that if cocircularity is detected, we need to
540 * recall 'update' from 'update' !!!
541 ***************************************************************/
542bool Cstable_cones::cocircular_check(){
543 // check if many configurations have the same centre.
544 // if this is the case, branch on the algorithm for this
545 // special case.
546 // Note that those situation, being considered separately in
547 // test_cone_multiple, must only be considered here if all
548 // angles are on the same side (this avoid multiple counting)
549
550 if (centre->cocircular.empty()) return false;
551
552 // first get cone into status required at end...
553 if ((centre->side) && (cone.ref.not_empty())){
554 // update cone
555 cone -= (*child);
556
557 // update info on particles inside
558 centre->is_inside->cone = false;
559
560 // update stability check quantities
561 dpt += fabs(child->px)+fabs(child->py); //child->perp2();
562 }
563
564
565 // now establish the list of unique children in the list
566 // first make sure parent and child are in!
567
568 list<Cvicinity_inclusion *> removed_from_cone;
569 list<Cvicinity_inclusion *> put_in_border;
570 list<Cmomentum *> border_list;
571
572 Cmomentum cone_removal;
573 Cmomentum border = *parent;
574 border_list.push_back(parent);
575
576 // make sure child appears in the border region
577 centre->cocircular.push_back(centre);
578
579 // now establish the full contents of the cone minus the cocircular
580 // region and of the cocircular region itself
581 for(list<Cvicinity_elm *>::iterator it = centre->cocircular.begin();
582 it != centre->cocircular.end(); it++) {
583
584 if ((*it)->is_inside->cone) {
585 cone_removal += *((*it)->v);
586 (*it)->is_inside->cone = false;
587 removed_from_cone.push_back((*it)->is_inside);
588 }
589
590 // if a point appears twice (i.e. with + and - sign) in the list of
591 // points on the border, we take care not to include it twice.
592 // Note that this situation may appear when a point is at a distance
593 // close to 2R from the parent
594 if (!(*it)->is_inside->cocirc) {
595 border += *((*it)->v);
596 (*it)->is_inside->cocirc = true;
597 put_in_border.push_back((*it)->is_inside);
598 border_list.push_back((*it)->v);
599 }
600 }
601
602
603 // figure out whether this pairing has been observed before
604 Cmomentum borderless_cone = cone;
605 borderless_cone -= cone_removal;
606 bool consider = true;
607 for (unsigned int i=0;i<multiple_centre_done.size();i++){
608 if ((multiple_centre_done[i].first ==borderless_cone.ref) &&
609 (multiple_centre_done[i].second==border.ref))
610 consider = false;
611 }
612
613 // now prepare the hard work
614 if (consider) {
615 // record the fact that we've now seen this combination
616 multiple_centre_done.push_back(pair<Creference,Creference>(borderless_cone.ref,
617 border.ref));
618
619 // first figure out whether our cone momentum is good
620 double local_dpt = fabs(cone_removal.px) + fabs(cone_removal.py);
621 double total_dpt = dpt + local_dpt;
622
623 recompute_cone_contents_if_needed(borderless_cone, total_dpt);
624 if (total_dpt == 0) {
625 // a recomputation has taken place -- so take advantage of this
626 // and update the member cone momentum
627 cone = borderless_cone + cone_removal;
628 dpt = local_dpt;
629 }
630
631 test_cone_cocircular(borderless_cone, border_list);
632 }
633
634
635 // relabel things that were in the cone but got removed
636 for(list<Cvicinity_inclusion *>::iterator is_in = removed_from_cone.begin();
637 is_in != removed_from_cone.end(); is_in++) {
638 (*is_in)->cone = true;
639 }
640
641 // relabel things that got put into the border
642 for(list<Cvicinity_inclusion *>::iterator is_in = put_in_border.begin();
643 is_in != put_in_border.end(); is_in++) {
644 (*is_in)->cocirc = false;
645 }
646
647 // we're done with everything -- return true to signal to user that we've
648 // been through the co-circularity rigmarole
649 return true;
650}
651
652
653////////////////////////////////////////////////////////
654// RECOMPUTATION OF CONE CONTENTS //
655// - compute_cone_contents() //
656// - recompute_cone_contents() //
657// - recompute_cone_contents_if_needed() //
658////////////////////////////////////////////////////////
659
660/**
661 * compute the cone contents by going once around the full set of
662 * circles and tracking the entry/exit status each time
663 * given parent, child and centre compute the momentum
664 * of the particle inside the cone
665 * This sets up the inclusion information, which can then be directly
666 * used to calculate the cone momentum.
667 **********************************************************************/
668void Cstable_cones::compute_cone_contents() {
669 circulator<vector<Cvicinity_elm*>::iterator >
670 start(vicinity.begin()+first_cone, vicinity.begin(), vicinity.end());
671
672 circulator<vector<Cvicinity_elm*>::iterator > here(start);
673
674 // note that in the following algorithm, the cone contents never includes
675 // the child. Indeed, if it has positive sign, then it will be set as
676 // outside at the last step in the loop. If it has negative sign, then the
677 // loop will at some point go to the corresponding situation with positive
678 // sign and set the inclusion status to 0.
679
680 do {
681 // as we leave this position a particle enters if its side is
682 // negative (i.e. the centre is the one at -ve angle wrt to the
683 // parent-child line
684 if (!(*here())->side) ((*here())->is_inside->cone) = 1;
685
686 // move on to the next position
687 ++here;
688
689 // as we arrive at this position a particle leaves if its side is positive
690 if ((*here())->side) ((*here())->is_inside->cone) = 0;
691 } while (here != start);
692
693 // once we've reached the start the 'is_inside' information should be
694 // 100% complete, so we can use it to calculate the cone contents
695 // and then exit
696 recompute_cone_contents();
697 return;
698
699}
700
701
702/*
703 * compute the cone momentum from particle list.
704 * in this version, we use the 'pincluded' information
705 * from the Cvicinity class
706 */
707void Cstable_cones::recompute_cone_contents(){
708 unsigned int i;
709
710 // set momentum to 0
711 cone = Cmomentum();
712
713 // Important note: we can browse only the particles
714 // in vicinity since all particles in the cone are
715 // withing a distance 2R w.r.t. parent hence in vicinity.
716 // Among those, we only add the particles for which 'is_inside' is true !
717 // This methos rather than a direct comparison avoids rounding errors
718 for (i=0;i<vicinity_size;i++){
719 // to avoid double-counting, only use particles with + angle
720 if ((vicinity[i]->side) && (vicinity[i]->is_inside->cone))
721 cone += *vicinity[i]->v;
722 }
723
724 // set check variables back to 0
725 dpt = 0.0;
726}
727
728
729/*
730 * if we have gone beyond the acceptable threshold of change, compute
731 * the cone momentum from particle list. in this version, we use the
732 * 'pincluded' information from the Cvicinity class, but we don't
733 * change the member cone, only the locally supplied one
734 */
735void Cstable_cones::recompute_cone_contents_if_needed(Cmomentum & this_cone,
736 double & this_dpt){
737
738 if (this_dpt > PT_TSHOLD*(fabs(this_cone.px)+fabs(this_cone.py))) {
739 if (cone.ref.is_empty()) {
740 this_cone = Cmomentum();
741 } else {
742 // set momentum to 0
743 this_cone = Cmomentum();
744
745 // Important note: we can browse only the particles
746 // in vicinity since all particles in the this_cone are
747 // withing a distance 2R w.r.t. parent hence in vicinity.
748 // Among those, we only add the particles for which 'is_inside' is true !
749 // This methos rather than a direct comparison avoids rounding errors
750 for (unsigned int i=0;i<vicinity_size;i++){
751 // to avoid double-counting, only use particles with + angle
752 if ((vicinity[i]->side) && (vicinity[i]->is_inside->cone))
753 this_cone += *vicinity[i]->v;
754 }
755
756 }
757 // set check variables back to 0
758 this_dpt = 0.0;
759 }
760
761}
762
763
764////////////////////////////////////////////////////////
765// VARIOUS TOOLS //
766// - circle_intersect() //
767// - is_inside() //
768// - abs_dangle() //
769////////////////////////////////////////////////////////
770
771
772/*
773 * circle intersection.
774 * computes the intersection with a circle of given centre and radius.
775 * The output takes the form of a checkxor of the intersection's particles
776 * - cx circle centre x coordinate
777 * - cy circle centre y coordinate
778 * return the checkxor for the intersection
779 ******************************************************************/
780Creference Cstable_cones::circle_intersect(double cx, double cy){
781 Creference intersection;
782 int i;
783 double dx, dy;
784
785 for (i=0;i<n_part;i++){
786 // compute the distance of the i-th particle with the parent
787 dx = plist[i].eta - cx;
788 dy = fabs(plist[i].phi - cy);
789
790 // pay attention to the periodicity in phi !
791 if (dy>M_PI)
792 dy -= twopi;
793
794 // really check if the distance is less than VR
795 if (dx*dx+dy*dy<R2)
796 intersection+=plist[i].ref;
797 }
798
799 return intersection;
800}
801
802/*
803 * test if a particle is inside a cone of given centre.
804 * check if the particle of coordinates 'v' is inside the circle of radius R
805 * centered at 'centre'.
806 * - centre centre of the circle
807 * - v particle to test
808 * return true if inside, false if outside
809 *****************************************************************************/
810inline bool Cstable_cones::is_inside(Cmomentum *centre, Cmomentum *v){
811 double dx, dy;
812
813 dx = centre->eta - v->eta;
814 dy = fabs(centre->phi - v->phi);
815 if (dy>M_PI)
816 dy -= twopi;
817
818 return dx*dx+dy*dy<R2;
819}
820
821/*
822 * compute the absolute value of the difference between 2 angles.
823 * We take care of the 2pi periodicity
824 * - angle1 first angle
825 * - angle2 second angle
826 * return the absolute value of the difference between the angles
827 *****************************************************************/
828inline double abs_dangle(double &angle1, double &angle2){
829 double dphi;
830
831 dphi = fabs(angle1-angle2);
832 if (dphi>M_PI)
833 dphi = dphi-twopi;
834
835 return dphi;
836}
837
838}
Note: See TracBrowser for help on using the repository browser.