Пример #1
0
// ============================================================================
// GLOctree::insertParticle()                                                  
// insert a new particle in the tree                                           
void GLOctree::insertParticle(int index, Node ** node, float * rmid, int level, int obj)
{
  int bit;
  int octant=0;
  float new_rmid[3];
  //assert(level < 30);
  if (level > 30) {
    PRINT_D ;
    //std::cerr << "Skip particle with index [" << index << "]\n";
    return;
  }
  level_max = MAX(level,level_max);
  if ( ! (*node) ) {
    (*node) = new Node();
  }

  // look for position in the cube (octant)
  for (int i=0; i<3; i++) {
    float comp=p_data->pos[index*3+i];
    if ((comp-rmid[i]) < 0) {
      bit=0;
      new_rmid[i]=((float ) (-size_max)/(float) (1<<level))+rmid[i];
    } else {
      bit=1;
      new_rmid[i]=((float ) (size_max)/(float ) (1<<level))+rmid[i];
    }
    octant+=(bit << (2-i));
  }
  // check if octant is free
  if (((*node)->node[octant])==NULL) { // yes it's free !
    Node * new_node=new Node(index,obj); // insert a particle (leaf)
    (*node)->node[octant] = new_node;
    p_data->tree_depth[index] = level; // Save particle's level
  }
  else { // octant is not free
    if ((*node)->node[octant]->type ==0) { // it's a node
      insertParticle(index,&((*node)->node[octant]),new_rmid,level+1,obj);
    }
    else { // it's a leaf
      // we must insert particles's leaf itself in a new octant
      int save_index=(*node)->node[octant]->index;
      //std::cerr << "save index="<< save_index <<"\n";
      (*node)->node[octant]->type=0; // leaf become node
      int old_obj = (*node)->node[octant]->obj; // must use old obj !!
      insertParticle(save_index,&((*node)->node[octant]),new_rmid,level+1,old_obj); 
      // we must now insert our particle
      insertParticle(index,&((*node)->node[octant]),new_rmid,level+1,obj);
    }
  }
}
Пример #2
0
void PFReconstructor::reconstructBlock(const PFBlock& block) {
  /// see class description for summary of reconstruction approach

  Ids ids = block.elementIds();
#if WITHSORT
  std::sort(ids.begin(), ids.end());
#endif
  for (auto id : ids) {
    m_locked[id] = false;
  }

  if (ids.size() == 1) {  //#TODO WARNING!!! LOTS OF MISSING CASES
    IdType id = ids[0];
    if (Id::isEcal(id)) {
      insertParticle(block, reconstructCluster(m_pfEvent.ECALCluster(id), papas::Layer::kEcal));
    } else if (Id::isHcal(id)) {
      insertParticle(block, reconstructCluster(m_pfEvent.HCALCluster(id), papas::Layer::kHcal));
    } else if (Id::isTrack(id)) {
      insertParticle(block, reconstructTrack(m_pfEvent.track(id)));
    } else {  // ask Colin about energy balance - what happened to the associated clusters that one would expect?
              // TODO
    }
  } else {
    for (auto id : ids) {
      if (Id::isHcal(id)) {
        reconstructHcal(block, id);
      }
    }
    for (auto id : ids) {
      if (Id::isTrack(id) && !m_locked[id]) {
        /* unused tracks, so not linked to HCAL
         # reconstructing charged hadrons.
         # ELECTRONS TO BE DEALT WITH.*/
        insertParticle(block, reconstructTrack(m_pfEvent.track(id)));
        for (auto idlink : block.linkedIds(id, Edge::EdgeType::kEcalTrack)) {
          // TODO ask colin what happened to possible photons here:
          // TODO add in extra photons but decide where they should go?
          m_locked[idlink] = true;
        }
      }
    }
  }
  for (auto& id : ids) {
    if (!m_locked[id]) {
      m_unused.push_back(id);
    }
  }
}
Пример #3
0
// ============================================================================
// GLOctree::build()                                                           
// build octree                                                                
int GLOctree::build()
{
  if (psv && store_options->octree_enable) {
    new_data=false;
    init();
    computeSizeMax();
    p_data->tree_size_max = size_max;
    
    PRINT_D std::cerr << "Start build\n";
    
    for (int obj=0; obj< (int ) psv->size(); obj++ ) { 
      VirtualParticlesSelect * vps = (*psv)[obj].vps;
      if (vps->is_visible) {
        //for (int i=0; i < vps->npart; i+=vps->step_part) {
        for (int i=0; i < vps->ni_index; i++) {
          int index=vps->index_tab[i];
	  assert(index<*p_data->nbody);
          //std::cerr << "Nbody = " << nbody << " Obj = " << obj << " I = " << i << " Index = " << index << "\n";
          insertParticle(index,&root, rmid, 1, obj );
        }
      } 
    }
    
    PRINT_D std::cerr << "stop build Level max= " << level_max << "\n";
    return 1;
  }   
  return 0;
}
Пример #4
0
int main(int argc, char *argv[]) 
{
	int i, N=2500;
	const float L=1,W=1,dt=1e-6;
	G=2.0/N;
	double *x,*y,*mass,*forceX,*forceY,*u,*v,ax,ay;
	const int frameskip=100;
	int frame=frameskip-1;
	const double initSpeedLimit=0.001;
	const float theta = 0.8;
	x = (double *)malloc(N*sizeof(double));
	y = (double *)malloc(N*sizeof(double));
	u = (double *)malloc(N*sizeof(double));
	v = (double *)malloc(N*sizeof(double));
	mass = (double *)malloc(N*sizeof(double));
	forceX = (double *)malloc(N*sizeof(double));
	forceY = (double *)malloc(N*sizeof(double));
	#ifndef DISTRIBUTION_AS_IN_ASSIGNMENT
  	for(i=0;i<N;i++) 
  	{
		x[i]=frand(0,1);
		y[i]=frand(.25,.75);
		relativePosition(&u[i], &v[i], 0, 0, x[i], y[i]);
		u[i]*=frand(-initSpeedLimit,initSpeedLimit);
		v[i]*=frand(-initSpeedLimit,initSpeedLimit);
		mass[i]=frand(1, 100);
		forceX[i]=0;
		forceY[i]=0;
  	}
  
	  x[0]=x[1]=0.5;
	  y[0]=0.45; y[1]=0.55;
	  v[0]=v[1]=0;
	  u[0]=-0.007;
	  u[1]=0.007;
	  mass[0]=mass[1]=1000;
	  #endif
	 #ifdef DISTRIBUTION_AS_IN_ASSIGNMENT

	const double alpha=0.25;
	const double V=20.0;
	for(i = 0; i<N; i++)
	  {
	    mass[i]=1;
	    double R=frand(0, L/4.0);
	    double fi=frand(0, 2*3.1415);
	    x[i]=L/2.0+R*cos(fi);
	    y[i]=W/2.0+alpha*R*sin(fi);
	    double Rprim = sqrt((x[i]-L/2.0)*(x[i]-L/2.0) + (y[i]-W/2.0)*(y[i]-W/2.0));
	    u[i] = -V*Rprim*sin(fi);
	    v[i] = V*Rprim*cos(fi);
	    forceX[i]=0;
	    forceY[i]=0;
	  }
	#endif
	
	  InitializeGraphics(argv[0],windowWidth,windowWidth);
	  SetCAxes(0,1);
	  Node *root;
	  printf("Hit q to quit.\n");
	  int iterations=0;
  	while(!CheckForQuit()) 
  	{
	  iterations++;
  		#ifndef BARNESHUT
  		for(i=0;i<N;i++) {
  		#endif
  		
  	
  		#ifdef BARNESHUT
		  //  		Bounce(&x[0],&y[0],&u[0],&v[0],L,W); 
  		root = createNode(0,x,y,mass);
		for(i=1;i<N;i++) {
		#endif
			if (x[i] > 2*L || x[i]< -1 || y[i] > 2*W || y[i] < -1)
			{
				printf("Things are going out of bounds");
				exit(-1);
			}
			//			Bounce(&x[i],&y[i],&u[i],&v[i],L,W); 
			#ifndef BARNESHUT
				calculateForce(&forceX[i], &forceY[i], i, x, y, mass, N);
			#endif
			#ifdef BARNESHUT
				insertParticle(root, x, y, mass, i);	
			#endif
		}
		#ifdef BARNESHUT
	  		for(i=0; i<N; i++)
				BarnesHut(root, x, y, mass, theta, i, &forceX[i], &forceY[i]);
		#endif
  		update(x,y,u,v,mass,forceX, forceY,dt, N);
		frame++;
		frame=frame%frameskip;
		if(frame==0) {
		  ClearScreen();  
		  for(i=0;i<N;i++)
		    DrawCircle(x[i],y[i],L,W,(1+log10(mass[i]))*circleRadius,circleColor);
		  Refresh();
		}
		freeNodes(root);
	}
	XFlush(display);
	XCloseDisplay(display);
	printf("Iterations: %d\n", iterations);
	return 0;
}

/*
 * Function: Bounce
 * Usage: Bounce(&x[i],&y[i],&u[i],&v[i],L,W);
 * -------------------------------------------
 * If a particle moves beyond any of the boundaries then set
 * it on the other side of the boundary back in the domain and
 * reverse the velocities.
 *
 */
void Bounce(double *x, double *y, double *u, double *v, double L, double W) {
  if(*x>L ) {
    *x=2*L-*x;
    *u=-*u;
  }

  if(*x<0 ) {
    *x=-*x;
    *u=-*u;
  }

  if(*y>W ) {
    *y=2*W-*y;
    *v=-*v;
  }

  if(*y<0 ) {
    *y=-*y;
    *v=-*v;
  }
}
Пример #5
0
//--------------------------------------------------------------
void testApp::update(){

	while( receiver.hasWaitingMessages() ){
		ofxOscMessage m;
		receiver.getNextMessage( &m );

		if( m.getAddress() == "/particle/new" ){
			int x = m.getArgAsInt32( 0 );
			int y = m.getArgAsInt32( 1 );
			int n = m.getArgAsInt32( 2 );
			int h = m.getArgAsInt32( 3 );
			insertParticle(x, y, n, h);
		}
	}

	tuioClient.getMessage();

	//-------------------------------

	if (timer <= standBy){
		nucle.mass				= 10;
		nucle.maxDistance		= screenHeight*0.07;

		if ( timer >= (standBy-standBy/3)){
			universe.mass		= 10;
			universe.proportional= false;
			universe.clockwise	= false;
			universe.impulse	= timer - (standBy - standBy/3);
			universe.angle		= -40;
			universe.density	= 0.8;
			blur.setRadius(1);
			fboAlpha			= 200;
		} else {
			universe.mass		= 0.75;
			universe.proportional= true;
			universe.clockwise	= true;
			universe.impulse	= 0.3;
			universe.angle		= 0;
			universe.density	= 0.7;
			blur.setRadius(0.5);
			fboAlpha			= 150;
		}
	} else {
		nucle.maxDistance		= screenHeight*0.01;
		nucle.mass				= 0.7;
		blur.setRadius(2);
		fboAlpha				= 255;
	}

	for (int i=0; i < pAct.size() ; i++)
		if (universe.onSpace(pAct[i]->loc) && (pAct[i]->alpha > 5) ){
			pAct[i]->update();

			if (nucle.onSpace(pAct[i]->loc))
				if (pAct[i]->bArrive)
					killParticle(i);

		} else killParticle(i);


	for (int i=0; i < pInact.size() ; i++)
		if (!universe.onSpace(pInact[i]->loc) || (pInact[i]->alpha < 5) )
			pInact.erase(pInact.begin()+i);
		else pInact[i]->update();

	timer += 1/ofGetFrameRate();
}
Пример #6
0
void PFReconstructor::reconstructHcal(const PFBlock& block, IdType hcalId) {
  /*
   block: element ids and edges
   hcalid: id of the hcal being processed her

   has hcal and has a track
   -> add up all connected tracks, turn each track into a charged hadron
   -> add up all ecal energies
   -> if track energies is greater than hcal energy then turn the missing energies into an ecal (photon)
   NB this links the photon to the hcal rather than the ecals
   -> if track energies are less than hcal then make a neutral hadron with rest of hcal energy and turn all ecals into
   photons
   has hcal but no track (nb by design there will be no attached ecals because hcal ecal links have been removed)
   -> make a neutral hadron
   has hcals
   -> each hcal is treated using rules above
   */

  // hcal used to make ecal_in has a couple of possible issues
  // m_pfEvent.HCALCluster(hcalId);

  // TODO assert(len(block.linked_ids(hcalid, "hcal_hcal"))==0  )
  // TODO sorting Ids trackids =    block.sort_distance_energy(hcalid, block.linked_ids(hcalid, "hcal_track") )

  Ids ecalIds;
  Ids trackIds = block.linkedIds(hcalId, Edge::EdgeType::kHcalTrack);
#if WITHSORT
  std::sort(trackIds.begin(), trackIds.end());
#endif
  for (auto trackId : trackIds) {
    for (auto ecalId : block.linkedIds(trackId, Edge::EdgeType::kEcalTrack)) {
      /*the ecals get all grouped together for all tracks in the block
       # Maybe we want to link ecals to their closest track etc?
       # this might help with history work
       # ask colin.*/
      if (!m_locked[ecalId]) {
        ecalIds.push_back(ecalId);
        m_locked[ecalId] = true;
      }
    }
  }
#if WITHSORT
  std::sort(trackIds.begin(), trackIds.end());
  std::sort(ecalIds.begin(), ecalIds.end());
#endif
  // hcal should be the only remaining linked hcal cluster (closest one)
  const Cluster& hcal = m_pfEvent.HCALCluster(hcalId);
  double hcalEnergy = hcal.energy();
  double ecalEnergy = 0.;
  double trackEnergy = 0.;

  if (!trackIds.empty()) {
    for (auto id : trackIds) {
      const Track& track = m_pfEvent.tracks().at(id);
      insertParticle(block, reconstructTrack(track));
      trackEnergy += track.energy();
    }
    for (auto id : ecalIds) {
      ecalEnergy += m_pfEvent.ECALCluster(id).energy();
    }
    double deltaERel = (hcalEnergy + ecalEnergy) / trackEnergy - 1.;
    double caloERes = neutralHadronEnergyResolution(hcal);
    /*self.log.info( 'dE/p, res = {derel}, {res} '.format(
     derel = delta_e_rel,
     res = calo_eres ))*/
    if (deltaERel > nsigmaHcal(hcal) * caloERes) {  //# approx means hcal energy + ecal energies > track energies

      double excess = deltaERel * trackEnergy;  // energy in excess of track energies
      // print( 'excess = {excess:5.2f}, ecal_E = {ecal_e:5.2f}, diff = {diff:5.2f}'.format(
      //   excess=excess, ecal_e = ecal_energy, diff=excess-ecal_energy))
      if (excess <= ecalEnergy) { /* # approx means hcal energy > track energies
                                   # Make a photon from the ecal energy
                                   # We make only one photon using only the combined ecal energies*/
        insertParticle(block, reconstructCluster(hcal, papas::Layer::kEcal, excess));
      }

      else {  // approx means that hcal energy>track energies so we must have a neutral hadron
              // excess-ecal_energy is approximately hcal energy  - track energies
        insertParticle(block, reconstructCluster(hcal, papas::Layer::kHcal, excess - ecalEnergy));
        if (ecalEnergy) {
          // make a photon from the remaining ecal energies
          // again history is confusingbecause hcal is used to provide direction
          // be better to make several smaller photons one per ecal?
          insertParticle(block, reconstructCluster(hcal, papas::Layer::kEcal, ecalEnergy));
        }
      }
    }
  } else {  // # case whether there are no tracks make a neutral hadron for each hcal
            //# note that hcal-ecal links have been removed so hcal should only be linked to
            //# other hcals

    insertParticle(block, reconstructCluster(hcal, papas::Layer::kHcal));
  }
  m_locked[hcalId] = true;
}