예제 #1
0
파일: rtree.c 프로젝트: rainwoodman/psphray
void main() {
	size_t * perm = malloc(sizeof(size_t) * 1000);
	struct rtree_t t = {0};
	int i, j, k;
	float pos[1000][3];
	float sml[1000];
	intptr_t key[1000];
	int l = 0;
	for(i = 0; i < 10; i++) {
		for(j = 0; j < 10; j++) {
			for(k = 0; k < 10; k++) {
				pos[l][0] = i * 0.1 * (1<<20);
				pos[l][1] = j * 0.1 * (1<<20);
				pos[l][2] = k * 0.1 * (1<<20);
				sml[l] = 0;
				key[l] = peano_hilbert_key(pos[l][0], pos[l][1], pos[l][2], 20);
				l++;
			}
		}
	}

	gsl_heapsort_index(perm, key, 1000, sizeof(intptr_t), (void*)intptr_t_compare);

	float (*__pos)[3] = permute(perm, pos, 3 * sizeof(float), 3 * sizeof(float), 1000, 1000);
	float * __sml = permute(perm, sml, sizeof(float), sizeof(float), 1000, 1000);
	intptr_t * __key = permute(perm, key, sizeof(intptr_t), sizeof(intptr_t), 1000, 1000);
	rtree_build(&t, __pos, __sml, __key, 1000);
	float dist[10];
	intptr_t nei[10];
	int nused = 0;
	float hhint = 100000;
	float p[3] = {499999, 499999,499999};

	rtree_neighbours(&t, p, __pos, 1000, nei, dist, 10, &nused, NULL);
	printf("hello\n");
}
예제 #2
0
 point(double a, double b, double c) : x(a), y(b), z(c) {
     q = x*x + y*y + z*z;
     peanokey = peano_hilbert_key(x, y, z, 52);
     return; 
 };
예제 #3
0
파일: save.c 프로젝트: boywert/L-Galaxy_RT
void prepare_galaxy_for_output(int n, struct GALAXY *g, struct GALAXY_OUTPUT *o)
#endif
{
  int j,ibin;

#ifndef NO_PROPS_OUTPUTS
  o->Type = g->Type;
  o->SnapNum = g->SnapNum;
  o->CentralMvir = get_virial_mass(Halo[g->HaloNr].FirstHaloInFOFgroup);
  o->CentralRvir = get_virial_radius(Halo[g->HaloNr].FirstHaloInFOFgroup);
  o->Mvir = g->Mvir;
  o->Rvir = g->Rvir;
  o->Vvir = g->Vvir;

  for(j = 0; j < 3; j++)
    {
	  o->Pos[j] = g->Pos[j];
	  o->DistanceToCentralGal[j] = wrap(Halo[Halo[g->HaloNr].FirstHaloInFOFgroup].Pos[j] - g->Pos[j],BoxSize);;
    }

  o->ColdGas = g->ColdGas;
  o->DiskMass = g->DiskMass;
  o->BulgeMass = g->BulgeMass;
  o->HotGas = g->HotGas;
  o->BlackHoleMass = g->BlackHoleMass;
#endif


#ifdef COMPUTE_SPECPHOT_PROPERTIES
#ifndef POST_PROCESS_MAGS
#ifdef OUTPUT_REST_MAGS 
  /* Luminosities are converted into Mags in various bands */
  for(j = 0; j < NMAG; j++)
 	o->Mag[j] = lum_to_mag(g->Lum[j][n]);
#endif
#endif //ndef POST_PROCESS_MAGS
#endif //COMPUTE_SPECPHOT_PROPERTIES

#ifndef LIGHT_OUTPUT
  
#ifndef NO_PROPS_OUTPUTS
#ifdef GALAXYTREE
  o->HaloID = HaloIDs[g->HaloNr].HaloID;
  o->Redshift = ZZ[g->SnapNum];

  int ii = (int) floor(o->Pos[0] * ScaleFactor);
  int jj = (int) floor(o->Pos[1] * ScaleFactor);
  int kk = (int) floor(o->Pos[2] * ScaleFactor);

  o->PeanoKey = peano_hilbert_key(ii, jj, kk, Hashbits);

  o->SubID = calc_big_db_subid_index(g->SnapNum, Halo[g->HaloNr].FileNr, Halo[g->HaloNr].SubhaloIndex);

  int tmpfirst = Halo[g->HaloNr].FirstHaloInFOFgroup;
  int lenmax = 0;
  int next = tmpfirst;
  while(next != -1)
    {
      if(Halo[next].Len > lenmax)
	{
	  lenmax = Halo[next].Len;
	  tmpfirst = next;
	}
      next = Halo[next].NextHaloInFOFgroup;
    }

  o->MMSubID = calc_big_db_subid_index(g->SnapNum, Halo[tmpfirst].FileNr, Halo[tmpfirst].SubhaloIndex);
#endif

  o->LookBackTimeToSnap = NumToTime(g->SnapNum)*UnitTime_in_years/Hubble_h;
  o->InfallVmax = g->InfallVmax;
  o->InfallSnap = g->InfallSnap;
  o-> InfallHotGas = g-> InfallHotGas;
  o->HotRadius =  g->HotRadius;
#ifdef HALOPROPERTIES
  o->HaloM_Mean200 = g->HaloM_Mean200;
  o->HaloM_Crit200 = g->HaloM_Crit200;
  o->HaloM_TopHat = g->HaloM_TopHat;
  o->HaloVelDisp = g->HaloVelDisp;
  o->HaloVmax = g->HaloVmax;
#endif

  o->Len = g->Len;
  o->Vmax = g->Vmax;

  o->BulgeSize = g->BulgeSize;
  o->EjectedMass = g->EjectedMass;
  o->BlackHoleGas = g->BlackHoleGas;

  for(j = 0; j < 3; j++)
    {
      o->Vel[j] = g->Vel[j];
#ifdef HALOSPIN
      o->HaloSpin[j] = g->HaloSpin[j];
#endif
#ifndef H2_AND_RINGS
      o->GasSpin[j] = g->GasSpin[j];
      o->StellarSpin[j] = g->StellarSpin[j];
#else
      o->DiskSpin[j] = g->DiskSpin[j];
#endif
#ifdef HALOPROPERTIES
      o->HaloPos[j] = g->HaloPos[j];
      o->HaloVel[j] = g->HaloVel[j];
      o->HaloSpin[j] = g->HaloSpin[j];
#endif      
    }

  o->XrayLum = g->XrayLum;
  o->GasDiskRadius = g->GasDiskRadius;
  o->StellarDiskRadius = g->StellarDiskRadius;
  o->CoolingRadius = g->CoolingRadius;
  o->ICM = g->ICM;
  //o->MetalsICM = CORRECTDBFLOAT(g->MetalsICM);
  o->MetalsICM = g->MetalsICM;
  o->QuasarAccretionRate = g->QuasarAccretionRate * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS;
  o->RadioAccretionRate = g->RadioAccretionRate * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS;
  o->CosInclination = g->CosInclination;

  if(g->Type == 2 || (g->Type == 1 && g->MergeOn == 1)) {
    o->OriMergTime=g->OriMergTime;
    o->MergTime = g->MergTime;
  }
  else {
    o->OriMergTime=0.0;
    o->MergTime = 0.0;
  }


#ifndef GALAXYTREE
  o->HaloIndex = g->HaloNr;
#endif
#ifdef MBPID
  o->MostBoundID = g->MostBoundID;
#endif


#ifdef GALAXYTREE
  o->DisruptOn = g->DisruptOn;
#endif
#ifdef MERGE01
  o->MergeOn = g->MergeOn;
#endif


//METALS

  /*o->MetalsColdGas = CORRECTDBFLOAT(g->MetalsColdGas);
  o->MetalsDiskMass = CORRECTDBFLOAT(g->MetalsDiskMass);
  o->MetalsBulgeMass = CORRECTDBFLOAT(g->MetalsBulgeMass);
  o->MetalsHotGas = CORRECTDBFLOAT(g->MetalsHotGas);
  o->MetalsEjectedMass = CORRECTDBFLOAT(g->MetalsEjectedMass);   
#ifdef METALS_SELF
  o->MetalsHotGasSelf = CORRECTDBFLOAT(g->MetalsHotGasSelf);
#endif*/
  o->MetalsColdGas = g->MetalsColdGas;
  o->MetalsDiskMass = g->MetalsDiskMass;
  o->MetalsBulgeMass = g->MetalsBulgeMass;
  o->MetalsHotGas = g->MetalsHotGas;
  o->MetalsEjectedMass = g->MetalsEjectedMass;
#ifdef METALS_SELF
  o->MetalsHotGasSelf = g->MetalsHotGasSelf;
#endif
#ifdef TRACK_BURST
  o->BurstMass=g->BurstMass;
#endif

#ifdef H2_AND_RINGS
  for(j=0; j<RNUM; j++)
  {
  	o->H2fractionr[j] = g -> H2fractionr[j];
  	o->ColdGasr[j] = g->ColdGasr[j];
  	o->DiskMassr[j] = g->DiskMassr[j];
  	o->MetalsColdGasr[j] = g->MetalsColdGasr[j];
  	o->MetalsDiskMassr[j] = g->MetalsDiskMassr[j];
  }
#endif

 //STAR FORMATION HISTORIES / RATES

#ifdef STAR_FORMATION_HISTORY
  o->sfh_ibin=g->sfh_ibin;
  ibin=0;
  for (j=0;j<=o->sfh_ibin;j++) {

#ifndef NORMALIZEDDB
// 	  o->sfh_time[j]=(g->sfh_t[j]+g->sfh_dt[j]/2.-NumToTime(g->SnapNum))*UnitTime_in_years/Hubble_h; //Time from middle of this sfh bin to snapshot - converted from code units to years
 	  //o->sfh_time[j]=(g->sfh_t[j]+g->sfh_dt[j]/2.)*UnitTime_in_years/Hubble_h; //ROB: Lookback time to middle of SFH bin, in years //ROB: Now use LookBackTimeToSnap + sfh_time instead.
// 	  o->sfh_dt[j]=g->sfh_dt[j]*UnitTime_in_years/Hubble_h;
 	  o->sfh_DiskMass[j]=g->sfh_DiskMass[j];
 	  o->sfh_BulgeMass[j]=g->sfh_BulgeMass[j];
 	  o->sfh_ICM[j]=g->sfh_ICM[j];
 	  o->sfh_MetalsDiskMass[j]=g->sfh_MetalsDiskMass[j];
 	  o->sfh_MetalsBulgeMass[j]=g->sfh_MetalsBulgeMass[j];
 	  o->sfh_MetalsICM[j]=g->sfh_MetalsICM[j];
	  //#ifdef DETAILED_METALS_AND_MASS_RETURN
#ifdef INDIVIDUAL_ELEMENTS
	  o->sfh_ElementsDiskMass[j]=g->sfh_ElementsDiskMass[j];
	  o->sfh_ElementsBulgeMass[j]=g->sfh_ElementsBulgeMass[j];
	  o->sfh_ElementsICM[j]=g->sfh_ElementsICM[j];
#endif
	  //#endif
#ifdef TRACK_BURST
	  o->sfh_BurstMass[j]=g->sfh_BurstMass[j];
#endif
#else // NORMALIZEDDB
	  sfh_bin[j].sfh_DiskMass = g->sfh_DiskMass[j];
	  sfh_bin[j].sfh_BulgeMass = g->sfh_BulgeMass[j];
	  sfh_bin[j].sfh_ICM = g->sfh_ICM[j];
	  sfh_bin[j].sfh_MetalsDiskMass = g->sfh_MetalsDiskMass[j];
	  sfh_bin[j].sfh_MetalsBulgeMass = g->sfh_MetalsBulgeMass[j];
	  sfh_bin[j].sfh_MetalsICM = g->sfh_MetalsICM[j];
	  sfh_bin[j].sfh_ibin = j;
	  sfh_bin[j].snapnum = g->SnapNum;
	  sfh_bin[j].GalID = -1; // TODO must be reset
#endif // NORMALIZEDDB
   }

  //Set all non-used array elements to zero:
  // important if we want to read files in database that all values are valid SQLServer floats
  for (j=o->sfh_ibin+1;j<SFH_NBIN;j++) {
#ifndef NORMALIZEDDB
//	  o->sfh_time[j]=0.;
//	  o->sfh_dt[j]=0.;
	  o->sfh_DiskMass[j]=0.;
	  o->sfh_BulgeMass[j]=0.;
	  o->sfh_ICM[j]=0.;
	  o->sfh_MetalsDiskMass[j]=metals_init();
	  o->sfh_MetalsBulgeMass[j]=metals_init();
	  o->sfh_MetalsICM[j]=metals_init();
#ifdef INDIVIDUAL_ELEMENTS
	  o->sfh_ElementsDiskMass[j]=elements_init();
	  o->sfh_ElementsBulgeMass[j]=elements_init();
	  o->sfh_ElementsICM[j]=elements_init();
#endif
#ifdef TRACK_BURST
	  o->sfh_BurstMass[j]=0.;
#endif
#else
	  sfh_bin[j].sfh_DiskMass=0;
	  sfh_bin[j].sfh_BulgeMass=0;
	  sfh_bin[j].sfh_ICM=0;
	  sfh_bin[j].sfh_ibin = 0;
	  sfh_bin[j].snapnum = g->SnapNum;
	  // TODO other elements not important, are not being written anyway. Or are they used elsewhere?
#endif
  }
#endif //STAR_FORMATION_HISTORY

#ifdef INDIVIDUAL_ELEMENTS
  /*for (j=0;j<ELEMENT_NUM;j++)
  {
	  o->DiskMass_elements[j]=g->DiskMass_elements[j];
	  o->BulgeMass_elements[j]=g->BulgeMass_elements[j];
	  o->ColdGas_elements[j]=g->ColdGas_elements[j];
	  o->HotGas_elements[j]=g->HotGas_elements[j];
	  o->EjectedMass_elements[j]=g->EjectedMass_elements[j];
	  o->ICM_elements[j]=g->ICM_elements[j];
  }*/

  /*o->DiskMass_elements = CORRECTDBFLOAT(g->DiskMass_elements);
  o->BulgeMass_elements = CORRECTDBFLOAT(g->BulgeMass_elements);
  o->ColdGas_elements = CORRECTDBFLOAT(g->ColdGas_elements);
  o->HotGas_elements = CORRECTDBFLOAT(g->HotGas_elements);
  o->ICM_elements = CORRECTDBFLOAT(g->ICM_elements);*/
  o->DiskMass_elements = g->DiskMass_elements;
  o->BulgeMass_elements = g->BulgeMass_elements;
  o->ColdGas_elements = g->ColdGas_elements;
  o->HotGas_elements = g->HotGas_elements;
  o->EjectedMass_elements = g->EjectedMass_elements;
  o->ICM_elements = g->ICM_elements;
#endif

  o->PrimordialAccretionRate = CORRECTDBFLOAT(g->PrimordialAccretionRate * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS);
  o->CoolingRate = CORRECTDBFLOAT(g->CoolingRate * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS);
  o->CoolingRate_beforeAGN = CORRECTDBFLOAT(g->CoolingRate_beforeAGN * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS);

 //NOTE: in Msun/yr
#ifdef SAVE_MEMORY
  o->Sfr = CORRECTDBFLOAT(g->Sfr * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS);
  o->SfrBulge = CORRECTDBFLOAT(g->SfrBulge * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS);
 #ifdef H2_AND_RINGS
  for(j=0; j<RNUM; j++) o->Sfrr[j] = g->Sfrr[j] * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS;  
#endif
#else
  o->Sfr = CORRECTDBFLOAT(g->Sfr[n] * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS);
  o->SfrBulge = CORRECTDBFLOAT(g->SfrBulge[n] * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS);
#endif 

#endif //NO_PROPS_OUTPUTS


//MAGNITUDES
#ifdef COMPUTE_SPECPHOT_PROPERTIES
#ifdef POST_PROCESS_MAGS

  /*   int N_vespa_files=29, N_vespa_AgeBins=16;
       double vespa_age[17]={0.000125893, 0.02000, 0.03000, 0.04800, 0.07400, 0.11500,
                          0.17700, 0.27500, 0.42500, 0.65800, 1.02000, 1.57000,
                          2.44000, 3.78000, 5.84000, 9.04000, 14.0000};
       int vespa_sfh_IDs[29]={0,   1, 12, 16,  2, 22, 23, 27, 29, 36,
       		               42, 44, 50, 53, 54, 55, 56, 57, 61, 62,
       		               63, 64, 65, 71, 81, 82, 90, 94, 99};
       double vespa_sfh[N_vespa_AgeBins], vespa_metal[N_vespa_AgeBins], dumb[6];
       int ii, jj, kk;
       char buf[1000], sbuf[1000];
       FILE *fa;

       for (ii=1;ii<N_vespa_files;ii++)
        {

       	sprintf(buf, "./devel/vespa_sfh/disc_good_%d.txt", vespa_sfh_IDs[ii]);
       	if(!(fa = fopen(buf, "r")))
       	{
       		char sbuf[1000];
       		sprintf(sbuf, "can't open file `%s'\n", buf);
       		terminate(sbuf);
       	}

       	for(jj=0;jj<6;jj++)
       		fgets(buf, 300, fa);

       	//read vespa SFH and metallicities
       	for (jj=0;jj<N_vespa_AgeBins;jj++)
       	{
       		vespa_sfh[jj]=0.;
       		vespa_metal[jj]=0.;
       		fscanf(fa,"%lg %lg %lg %lg %lg %lg %lg %lg\n", &dumb[0], &dumb[1], &vespa_sfh[jj], &dumb[2], &vespa_metal[jj],
       			                                     &dumb[3], &dumb[4], &dumb[5]);
       	}
       	fclose(fa);

       	for (jj=0;jj<SFH_NBIN;jj++)
       	 {
       		if(jj<N_vespa_AgeBins)
       		{
       			o->sfh_time[jj]=(vespa_age[jj]+vespa_age[jj+1])/2.*1.e9;
       			o->sfh_dt[jj]=(vespa_age[jj+1]-vespa_age[jj])/2.*1.e9;
       		  o->sfh_DiskMass[jj]=vespa_sfh[jj];
       		  o->sfh_BulgeMass[jj]=0.;
       		  o->sfh_MetalsDiskMass[jj]=vespa_metal[jj]*o->sfh_DiskMass[jj];
       		  o->sfh_MetalsBulgeMass[jj]=metals_init();
       		}
       		else
       		{
       			o->sfh_time[jj]=0.;
       			o->sfh_dt[jj]=0.;
       			o->sfh_DiskMass[jj]=0.;
       			o->sfh_BulgeMass[jj]=0.;
       			o->sfh_MetalsDiskMass[jj]=metals_init();
       			o->sfh_MetalsBulgeMass[jj]=metals_init();
       		}
       	 }

        	post_process_spec_mags(o);

        	sprintf(buf, "./devel/vespa_sfh/output_spectradisc_good_%d.txt", vespa_sfh_IDs[ii]);
        	if(!(fa = fopen(buf, "w")))
        	{
        		char sbuf[1000];
        		sprintf(sbuf, "can't open file `%s'\n", buf);
        		terminate(sbuf);
        	}

        	for(jj=0;jj<NMAG;jj++)
        		fprintf(fa,"%e\n",o->Mag[jj]);
        	fclose(fa);

         exit(0);
       }
  */
      //Convert recorded star formation histories into mags
#ifdef NORMALIZEDDB
    post_process_spec_mags(o, &(sfh_bin[0]));
#else
    post_process_spec_mags(o);
#endif

#else //ndef POST_PROCESS_MAGS

#ifdef OUTPUT_REST_MAGS
  // Luminosities are converted into Mags in various bands
  for(j = 0; j < NMAG; j++)
    {
	  //o->Mag[j] = lum_to_mag(g->Lum[j][n]); -> DONE ON TOP FOR LIGHT_OUTPUT AS WELL
	  o->MagBulge[j] = lum_to_mag(g->LumBulge[j][n]);
	  o->MagDust[j] = lum_to_mag(g->LumDust[j][n]);
#ifdef ICL
	  o->MagICL[j] = lum_to_mag(g->ICLLum[j][n]);
#endif
    }
#if defined(READXFRAC) || defined(WITHRADIATIVETRANSFER)
  o->Xfrac3d = g->Xfrac3d;
#endif

#endif //OUTPUT_REST_MAGS
#ifdef OUTPUT_OBS_MAGS
#ifdef COMPUTE_OBS_MAGS
  // Luminosities in various bands
  for(j = 0; j < NMAG; j++)
    {
	  o->ObsMag[j] = lum_to_mag(g->ObsLum[j][n]);
	  o->ObsMagBulge[j] = lum_to_mag(g->ObsLumBulge[j][n]);
	  o->ObsMagDust[j] = lum_to_mag(g->ObsLumDust[j][n]);
#ifdef ICL
	  o->ObsMagICL[j] = lum_to_mag(g->ObsICL[j][n]);
#endif

#ifdef OUTPUT_MOMAF_INPUTS
	  o->dObsMag[j] = lum_to_mag(g->dObsLum[j][n]);
	  o->dObsMagBulge[j] = lum_to_mag(g->dObsLumBulge[j][n]);
	  o->dObsMagDust[j] = lum_to_mag(g->dObsLumDust[j][n]);
#ifdef ICL
	  o->dObsMagICL[j] = lum_to_mag(g->dObsICL[j][n]);
#endif
#endif
    }
#endif //COMPUTE_OBS_MAGS
#endif //OUTPUT_OBS_MAGS
#endif //ndef POST_PROCESS_MAGS
#endif //COMPUTE_SPECPHOT_PROPERTIES

#ifndef NO_PROPS_OUTPUTS
  if((g->DiskMass+g->BulgeMass)> 0.0)
      {
  	  o->MassWeightAge = g->MassWeightAge[n] / (g->DiskMass+g->BulgeMass);
  	  o->MassWeightAge = o->MassWeightAge / 1000. * UnitTime_in_Megayears / Hubble_h;	//Age in Gyr
      }
    else
  	o->MassWeightAge = 0.;
#endif

#ifdef FIX_OUTPUT_UNITS
  fix_units_for_ouput(o);
#endif
#endif //ndef LIGHT_OUTPUT

  // DEBUG
//  printf("  EXIT sfh_bin %d %f\n",sfh_bin,sfh_bin[0].sfh_DiskMass);


}
예제 #4
0
 /*@brief Copies all the relevant properties from the Galaxy structure
        into the Galaxy output structure, some units are corrected.*/
void prepare_galaxy_for_output(int n, struct GALAXY *g, struct GALAXY_OUTPUT *o)
{
  int j;

  o->Type = g->Type;
  o->SnapNum = g->SnapNum;
  o->CentralMvir = get_virial_mass(Halo[g->HaloNr].FirstHaloInFOFgroup);
  o->Mvir = g->Mvir;
  o->Rvir = g->Rvir;
  o->Vvir = g->Vvir;

  for(j = 0; j < 3; j++)
    {
	  o->Pos[j] = g->Pos[j];
	  o->DistanceToCentralGal[j] = wrap(Halo[Halo[g->HaloNr].FirstHaloInFOFgroup].Pos[j] - g->Pos[j],BoxSize);;
    }

  o->ColdGas = g->ColdGas;
  o->DiskMass = g->DiskMass;
  o->BulgeMass = g->BulgeMass;
  o->HotGas = g->HotGas;
  o->BlackHoleMass = g->BlackHoleMass;

#ifndef POST_PROCESS_MAGS
#ifdef OUTPUT_REST_MAGS
  /* Luminosities are converted into Mags in various bands */
  for(j = 0; j < NMAG; j++)
 	o->Mag[j] = lum_to_mag(g->Lum[j][n]);
#endif
#endif

#ifndef LIGHT_OUTPUT
  
#ifdef GALAXYTREE
  o->HaloID = HaloIDs[g->HaloNr].HaloID;
  o->Redshift = ZZ[g->SnapNum];

  int ii = (int) floor(o->Pos[0] * ScaleFactor);
  int jj = (int) floor(o->Pos[1] * ScaleFactor);
  int kk = (int) floor(o->Pos[2] * ScaleFactor);

  o->PeanoKey = peano_hilbert_key(ii, jj, kk, Hashbits);

  o->SubID = calc_big_db_subid_index(g->SnapNum, Halo[g->HaloNr].FileNr, Halo[g->HaloNr].SubhaloIndex);

  int tmpfirst = Halo[g->HaloNr].FirstHaloInFOFgroup;
  int lenmax = 0;
  int next = tmpfirst;
  while(next != -1)
    {
      if(Halo[next].Len > lenmax)
	{
	  lenmax = Halo[next].Len;
	  tmpfirst = next;
	}
      next = Halo[next].NextHaloInFOFgroup;
    }

  o->MMSubID = calc_big_db_subid_index(g->SnapNum, Halo[tmpfirst].FileNr, Halo[tmpfirst].SubhaloIndex);
#endif

  o->LookBackTimeToSnap = NumToTime(g->SnapNum)*UnitTime_in_years/Hubble_h;

  o->InfallVmax = g->InfallVmax;
  o->InfallSnap = g->InfallSnap;
  o->HotRadius =  g->HotRadius;
#ifdef HALOPROPERTIES
  o->HaloM_Mean200 = g->HaloM_Mean200;
  o->HaloM_Crit200 = g->HaloM_Crit200;
  o->HaloM_TopHat = g->HaloM_TopHat;
  o->HaloVelDisp = g->HaloVelDisp;
  o->HaloVmax = g->HaloVmax;
#endif

  o->Len = g->Len;
  o->Vmax = g->Vmax;

  o->BulgeSize = g->BulgeSize;
  o->EjectedMass = g->EjectedMass;
  o->BlackHoleGas = g->BlackHoleGas;

  for(j = 0; j < 3; j++)
    {
      o->Vel[j] = g->Vel[j];
#ifdef HALOSPIN
      o->HaloSpin[j] = g->HaloSpin[j];
#endif
      o->GasSpin[j] = g->GasSpin[j];
      o->StellarSpin[j] = g->StellarSpin[j];
#ifdef HALOPROPERTIES
      o->HaloPos[j] = g->HaloPos[j];
      o->HaloVel[j] = g->HaloVel[j];
      o->HaloSpin[j] = g->HaloSpin[j];
#endif      
    }

  o->XrayLum = g->XrayLum;
  o->GasDiskRadius = g->GasDiskRadius;
  o->StellarDiskRadius = g->StellarDiskRadius;
  o->CoolingRadius = g->CoolingRadius;
  o->ICM = g->ICM;
  //o->MetalsICM = CORRECTDBFLOAT(g->MetalsICM);
  o->MetalsICM = g->MetalsICM;
  o->QuasarAccretionRate = g->QuasarAccretionRate * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS;
  o->RadioAccretionRate = g->RadioAccretionRate * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS;
  o->CosInclination = g->CosInclination;

  if(g->Type == 2 || (g->Type == 1 && g->MergeOn == 1)) {
    o->OriMergTime=g->OriMergTime;
    o->MergTime = g->MergTime;
  }
  else {
    o->OriMergTime=0.0;
    o->MergTime = 0.0;
  }


#ifndef GALAXYTREE
  o->HaloIndex = g->HaloNr;
#endif
#ifdef MBPID
  o->MostBoundID = g->MostBoundID;
#endif


#ifdef GALAXYTREE
  o->DisruptOn = g->DisruptOn;
#endif
#ifdef MERGE01
  o->MergeOn = g->MergeOn;
#endif


//METALS

  /*o->MetalsColdGas = CORRECTDBFLOAT(g->MetalsColdGas);
  o->MetalsDiskMass = CORRECTDBFLOAT(g->MetalsDiskMass);
  o->MetalsBulgeMass = CORRECTDBFLOAT(g->MetalsBulgeMass);
  o->MetalsHotGas = CORRECTDBFLOAT(g->MetalsHotGas);
  o->MetalsEjectedMass = CORRECTDBFLOAT(g->MetalsEjectedMass);   
#ifdef METALS_SELF
  o->MetalsHotGasSelf = CORRECTDBFLOAT(g->MetalsHotGasSelf);
#endif*/
  o->MetalsColdGas = g->MetalsColdGas;
  o->MetalsDiskMass = g->MetalsDiskMass;
  o->MetalsBulgeMass = g->MetalsBulgeMass;
  o->MetalsHotGas = g->MetalsHotGas;
  o->MetalsEjectedMass = g->MetalsEjectedMass;
#ifdef METALS_SELF
  o->MetalsHotGasSelf = g->MetalsHotGasSelf;
#endif



 //STAR FORMATION HISTORIES / RATES

#ifdef STAR_FORMATION_HISTORY
  o->sfh_ibin=g->sfh_ibin;
  for (j=0;j<=o->sfh_ibin;j++) {
  	// Lookback time from output snap to middle of SFh bin, in years
 	  o->sfh_time[j]=(g->sfh_t[j]+g->sfh_dt[j]/2.-NumToTime(g->SnapNum))*UnitTime_in_years/Hubble_h;
 	  //o->sfh_time[j]=(g->sfh_t[j]+g->sfh_dt[j]/2.)*UnitTime_in_years/Hubble_h; //ROB: Lookback time to middle of SFH bin, in years
 	  o->sfh_dt[j]=g->sfh_dt[j]*UnitTime_in_years/Hubble_h;
 	  o->sfh_DiskMass[j]=g->sfh_DiskMass[j];
 	  o->sfh_BulgeMass[j]=g->sfh_BulgeMass[j];
 	  o->sfh_ICM[j]=g->sfh_ICM[j];
 	  o->sfh_MetalsDiskMass[j]=g->sfh_MetalsDiskMass[j];
 	  o->sfh_MetalsBulgeMass[j]=g->sfh_MetalsBulgeMass[j];
 	  o->sfh_MetalsICM[j]=g->sfh_MetalsICM[j];
#ifdef YIELDS
	  o->sfh_ElementsDiskMass[j]=g->sfh_ElementsDiskMass[j];
	  o->sfh_ElementsBulgeMass[j]=g->sfh_ElementsBulgeMass[j];
	  o->sfh_ElementsICM[j]=g->sfh_ElementsICM[j];
#endif
   }

  for (j=o->sfh_ibin+1;j<SFH_NBIN;j++) {
	  o->sfh_time[j]=0.;
	  o->sfh_DiskMass[j]=0.;
	  o->sfh_BulgeMass[j]=0.;
	  o->sfh_ICM[j]=0.;
	  o->sfh_MetalsDiskMass[j]=metals_init();
	  o->sfh_MetalsBulgeMass[j]=metals_init();
	  o->sfh_MetalsICM[j]=metals_init();
#ifdef YIELDS
	  o->sfh_ElementsDiskMass[j]=elements_init();
	  o->sfh_ElementsBulgeMass[j]=elements_init();
	  o->sfh_ElementsICM[j]=elements_init();
#endif
  }
#endif

#ifdef YIELDS
  /*for (j=0;j<ELEMENT_NUM;j++)
  {
	  o->DiskMass_elements[j]=g->DiskMass_elements[j];
	  o->BulgeMass_elements[j]=g->BulgeMass_elements[j];
	  o->ColdGas_elements[j]=g->ColdGas_elements[j];
	  o->HotGas_elements[j]=g->HotGas_elements[j];
	  o->EjectedMass_elements[j]=g->EjectedMass_elements[j];
	  o->ICM_elements[j]=g->ICM_elements[j];
  }*/

  /*o->DiskMass_elements = CORRECTDBFLOAT(g->DiskMass_elements);
  o->BulgeMass_elements = CORRECTDBFLOAT(g->BulgeMass_elements);
  o->ColdGas_elements = CORRECTDBFLOAT(g->ColdGas_elements);
  o->HotGas_elements = CORRECTDBFLOAT(g->HotGas_elements);
  o->ICM_elements = CORRECTDBFLOAT(g->ICM_elements);*/
  o->DiskMass_elements = g->DiskMass_elements;
  o->BulgeMass_elements = g->BulgeMass_elements;
  o->ColdGas_elements = g->ColdGas_elements;
  o->HotGas_elements = g->HotGas_elements;
  o->EjectedMass_elements = g->EjectedMass_elements;
  o->ICM_elements = g->ICM_elements;
#endif

 //NOTE: in Msun/yr
#ifdef SAVE_MEMORY
  o->Sfr = CORRECTDBFLOAT(g->Sfr * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS);
  o->SfrBulge = CORRECTDBFLOAT(g->SfrBulge * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS);
#else
  o->Sfr = CORRECTDBFLOAT(g->Sfr[n] * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS);
  o->SfrBulge = CORRECTDBFLOAT(g->SfrBulge[n] * UnitMass_in_g / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS);
#endif 




//MAGNITUDES

#ifdef POST_PROCESS_MAGS
    //Convert recorded star formation histories into mags
    post_process_mags(o);
#else //POST_PROCESS_MAGS

#ifdef OUTPUT_REST_MAGS
  // Luminosities are converted into Mags in various bands
  for(j = 0; j < NMAG; j++)
    {
	  //o->Mag[j] = lum_to_mag(g->Lum[j][n]); -> DONE ON TOP FOR LIGHT_OUTPUT AS WELL
	  o->MagBulge[j] = lum_to_mag(g->LumBulge[j][n]);
	  o->MagDust[j] = lum_to_mag(g->LumDust[j][n]);
#ifdef ICL
	  o->MagICL[j] = lum_to_mag(g->ICLLum[j][n]);
#endif
    }

 
  if((g->DiskMass+g->BulgeMass)> 0.0)
    {
	  o->MassWeightAge = g->MassWeightAge[n] / (g->DiskMass+g->BulgeMass);
	  o->MassWeightAge = o->MassWeightAge / 1000. * UnitTime_in_Megayears / Hubble_h;	//Age in Gyr
    }
  else
	o->MassWeightAge = 0.;

#endif //OUTPUT_REST_MAGS
#ifdef OUTPUT_OBS_MAGS
#ifdef COMPUTE_OBS_MAGS
  // Luminosities in various bands
  for(j = 0; j < NMAG; j++)
    {
	  o->ObsMag[j] = lum_to_mag(g->ObsLum[j][n]);
	  o->ObsMagBulge[j] = lum_to_mag(g->ObsLumBulge[j][n]);
	  o->ObsMagDust[j] = lum_to_mag(g->ObsLumDust[j][n]);
#ifdef ICL
	  o->ObsMagICL[j] = lum_to_mag(g->ObsICL[j][n]);
#endif

#ifdef OUTPUT_MOMAF_INPUTS
	  o->dObsMag[j] = lum_to_mag(g->dObsLum[j][n]);
	  o->dObsMagBulge[j] = lum_to_mag(g->dObsLumBulge[j][n]);
	  o->dObsMagDust[j] = lum_to_mag(g->dObsLumDust[j][n]);
#endif
    }
#endif //COMPUTE_OBS_MAGS
#endif //OUTPUT_OBS_MAGS
#endif //POST_PROCESS_MAGS

#ifdef FIX_OUTPUT_UNITS
  fix_units_for_ouput(o);
#endif
#endif //ndef LIGHT_OUTPUT
}