24constexpr std::size_t size_of(T 
const&) {
 
   28template<
typename PType>
 
   36  double time,redshift,omega,lambda,hubble;
 
   37  std::string filebasename;
 
   39  GadgetFile (
string inpfn,std::vector<PType> &data);
 
   42  void checkMultiple ();
 
   46  void readBlock (
const char *blockname);
 
   48  int find_block(FILE *fd,
const char *label);
 
   50  int read_gadget_head(
int *npart,
double *massarr,
double *time,
double *redshift,
double *omega, 
double *lambda, 
double *hubble, FILE *fd);
 
   52  bool FileExists(
string strFilename);
 
   54  std::vector<PType> &p_data;
 
   65  ifstream::pos_type size;
 
   66  int4bytes blksize, swap;
 
   73  int np_file_start, np_file_end;
 
   75  int read_gadget_float(
float *data,
const char *label,FILE *fd);
 
   77  int read_gadget_float3(
float *data,
const char *label,FILE *fd);
 
   78  size_t my_fread(
void *ptr, 
size_t size, 
size_t nmemb, FILE * stream);
 
   79  void swap_Nbyte(
char *data,
int n,
int m);
 
   82template<
typename PType>
 
   83GadgetFile<PType>::GadgetFile(
string inpfn,std::vector<PType> &data):
 
   84multipleFiles(false),numfiles(0),filebasename(inpfn),p_data(data),swap(0)
 
   85,filecnt(0),np_file_start(0),np_file_end(-1)
 
   90template<
typename PType>
 
   91void GadgetFile<PType>::checkMultiple(){
 
   93  char *filename = 
new char [filebasename.size()+1];
 
   95  filename[filebasename.size()]=0;
 
   96  memcpy(filename,filebasename.c_str(),filebasename.size());
 
   98  bool exists=FileExists(filename);
 
   99  if (exists) {cout << 
"The file exists..." << endl;
 
  101    if(!(fd = fopen(filename,
"r")))
 
  103      printf(
"Cant open file <%s> !\n",filename);
 
  106      cout << 
"Reading header" << endl;
 
  109      n = read_gadget_head(npart,masstab,&time,&redshift,&omega,&lambda,&hubble,fd);
 
  114        printf(
"PartSpecies %d, anz=%d, masstab=%f\n",i,npart[i],masstab[i]);
 
  117      printf(
"Omage %f Lambda %f hubble %f\n",omega,lambda,hubble);
 
  122    cout << 
"The file does not exist or the simulation is splitted in multiple files..." << endl;
 
  123    cout << 
"Trying multiple files..." << endl;
 
  126    for (
int i=0; i<=nmaxf-1; i++) {
 
  128      std::ostringstream filenum;
 
  131      string filebasename_=filebasename+odot+filenum.str();
 
  132      char *filename_ = 
new char [filebasename.size()+1];
 
  133      filename_[filebasename_.size()]=0;
 
  134      memcpy(filename_,filebasename_.c_str(),filebasename_.size());
 
  135      bool exists=FileExists(filename_);
 
  136      if (exists) {numfiles++;}
 
  141      cout << 
"The simulation is splitted into " << numfiles << 
" files" << endl;
 
  143      for (
int j=0; j<=numfiles-1; j++) {
 
  144        std::ostringstream filenum;
 
  147        string filebasename_=filebasename+odot+filenum.str();
 
  148        char *filename_ = 
new char [filebasename.size()+1];
 
  149        filename_[filebasename_.size()]=0;
 
  150        memcpy(filename_,filebasename_.c_str(),filebasename_.size());
 
  152        if(!(fd = fopen(filename_,
"r")))
 
  154          printf(
"Cant open file <%s> !\n",filename_);
 
  159          cout << 
"-> Reading header# " << j << endl;
 
  162          n = read_gadget_head(npart,masstab,&time,&redshift,&omega,&lambda,&hubble,fd);
 
  166            printf(
"* PartSpecies %d, anz=%d, masstab=%f\n",i,npart[i],masstab[i]);
 
  174  cout << 
"TOTAL NUMBER OF PARTICLES: " << ntot << endl;
 
  176  printf(
"Allocating memory for a total of %zu particles...\n",ntot);
 
  186  cout << 
"done" << endl;
 
  197#define SKIP  {my_fread(&blksize,sizeof(int),1,fd); swap_Nbyte((char*)&blksize,1,4);} 
  199template<
typename PType>
 
  200void GadgetFile<PType>::openFile () {
 
  209    char *filename = 
new char [filebasename.size()+1];
 
  210    filename[filebasename.size()]=0;
 
  211    memcpy(filename,filebasename.c_str(),filebasename.size());
 
  212    fd = fopen(filename,
"r");
 
  215    n = read_gadget_head(npart,masstab,&time,&redshift,&omega,&lambda,&hubble,fd);
 
  220    np_file_start=nstart;
 
  222    for (
int ips=0; ips<6; ips++){
 
  224        for (
int i=nstart; i<nstart+npart[ips]; i++){
 
  225          p_data[i].type = ips;
 
  227        nstart=nstart+npart[ips];
 
  230    np_file_end=np_file_start+ntot-1;
 
  240    std::ostringstream filenum;
 
  243    string filebasename_=filebasename+odot+filenum.str();
 
  244    char *filename_ = 
new char [filebasename.size()+1];
 
  245    filename_[filebasename_.size()]=0;
 
  246    memcpy(filename_,filebasename_.c_str(),filebasename_.size());
 
  248    fd = fopen(filename_,
"r");
 
  251    n = read_gadget_head(npart,masstab,&time,&redshift,&omega,&lambda,&hubble,fd);
 
  256    np_file_start=np_file_end+1;
 
  257    nstart=np_file_start;
 
  259    for (
int ips=0; ips<6; ips++){
 
  261        for (
int i=nstart; i<nstart+npart[ips]; i++){
 
  263          p_data[i].type = ips;
 
  265        nstart=nstart+npart[ips];
 
  266        np_in_file=np_in_file+npart[ips];
 
  269    np_file_end=np_file_start+np_in_file-1;
 
  275template<
typename PType>
 
  276void GadgetFile<PType>::closeFile () {
 
  295template<
typename PType>
 
  296int GadgetFile<PType>::read_gadget_head(
int *npart,
double *massarr,
double *time,
double *redshift, 
double *omega, 
double *lambda, 
double *hubble, FILE *fd)
 
  298  int blocksize,dummysize;
 
  304  blocksize = find_block(fd,
"HEAD");
 
  309    printf(
"Block <%s> not fond !\n",
"HEAD");
 
  314    dummysize=blocksize - 6 * 
sizeof(int) - 8 * 
sizeof(
double);
 
  315    std::cout << blocksize << 
" " << dummysize << std::endl;
 
  317    my_fread(npart,6*
sizeof(
int), 1, fd);        swap_Nbyte((
char*)npart,6,4);
 
  318    my_fread(massarr,6*
sizeof(
double), 1, fd);   swap_Nbyte((
char*)massarr,6,8);
 
  319    my_fread(time,
sizeof(
double), 1, fd);        swap_Nbyte((
char*)time,1,8);
 
  320    my_fread(redshift,
sizeof(
double), 1, fd);    swap_Nbyte((
char*)redshift,1,8);
 
  321    my_fread(&dummyint,
sizeof(
int), 1, fd);       swap_Nbyte((
char*)&dummyint,1,4);
 
  322    my_fread(&dummyint,
sizeof(
int), 1, fd);       swap_Nbyte((
char*)&dummyint,1,4);
 
  323    my_fread(dummyarr,6*
sizeof(
int), 1, fd);     swap_Nbyte((
char*)dummyarr,6,4);
 
  324    my_fread(&dummyint,
sizeof(
int), 1, fd);       swap_Nbyte((
char*)&dummyint,1,4);
 
  325    my_fread(&dummyint,
sizeof(
int), 1, fd);       swap_Nbyte((
char*)&dummyint,1,4);
 
  326    my_fread(&boxl,
sizeof(
double), 1, fd);        swap_Nbyte((
char*)&boxl,1,8);
 
  330    my_fread(omega,
sizeof(
double), 1, fd);   swap_Nbyte((
char*)omega,1,8);
 
  331    my_fread(lambda,
sizeof(
double), 1, fd);  swap_Nbyte((
char*)lambda,1,8);
 
  332    my_fread(hubble,
sizeof(
double), 1, fd);  swap_Nbyte((
char*)hubble,1,8);
 
  333    fseek(fd,dummysize,1);
 
  347template<
typename PType>
 
  348void GadgetFile<PType>::swap_Nbyte(
char *data,
int n,
int m)
 
  357      memcpy(&old_data[0],&data[j*m],m);
 
  360        data[j*m+i]=old_data[m-i-1];
 
  373template<
typename PType>
 
  374int GadgetFile<PType>::find_block(FILE *fd,
const char *label)
 
  376  int4bytes blocksize=0;
 
  377  char blocklabel[5]={
"    "};
 
  381  while(!feof(fd) && blocksize == 0)
 
  384    if(blksize == 134217728)
 
  387      printf(
"Enable ENDIAN swapping !\n");
 
  390      swap_Nbyte((
char*)&blksize,1,4);
 
  394      printf(
"incorrect format (blksize=%d)!\n",blksize);
 
  399      my_fread(blocklabel, 4*
sizeof(
char), 1, fd);
 
  400      my_fread(&blocksize, 
sizeof(int4bytes), 1, fd);
 
  401      swap_Nbyte((
char*)&blocksize,1,4);
 
  403      printf(
"Found Block <%s> with %d bytes\n",blocklabel,blocksize);
 
  406      if(strcmp(label,blocklabel)!=0)
 
  408        fseek(fd,blocksize,1);
 
  421 template<
typename PType>
 
  422 size_t GadgetFile<PType>::my_fread(
void *ptr, 
size_t size, 
size_t nmemb, FILE * stream)
 
  426 if((nread = fread(ptr, size, nmemb, stream)) != nmemb)
 
  428 printf(
"I/O error (fread) !\n");
 
  435template<
typename PType>
 
  436bool GadgetFile<PType>::FileExists(
string strFilename) {
 
  437  struct stat stFileInfo;
 
  442  intStat = stat(strFilename.c_str(),&stFileInfo);
 
  460template<
typename PType>
 
  461void GadgetFile<PType>::readBlock(
const char *blockname) {
 
  466  int np_in_file=np_file_end-np_file_start+1;
 
  467  cout << string(blockname) << endl;
 
  468  if (
string(blockname)==
"POS") {
 
  469    cout << 
"Reading block "<< string(blockname) << endl;
 
  470    pvector *pos=
new pvector[ntot];
 
  471    cout << 
"...memory allocated." << endl;
 
  472    n = read_gadget_float3((
float*)pos,
"POS ",fd);
 
  473    cout << 
"...data are in memory." << endl;
 
  474    for (
int i=0; i<=np_in_file-1; i++) {
 
  476      p_data[i+np_file_start][0] = pos[i].x;
 
  477      p_data[i+np_file_start][1] = pos[i].y;
 
  478      p_data[i+np_file_start][2] = pos[i].z;
 
  482  }  
else if (
string(blockname)==
"VEL") {
 
  483    cout << 
"Reading block "<< string(blockname) << endl;
 
  484    pvector *vel=
new pvector[ntot];
 
  485    cout << 
"...memory allocated..." << endl;
 
  486    n = read_gadget_float3((
float*)vel,
"VEL ",fd);
 
  487    cout << 
"...data is in memory." << endl;
 
  488    for (
int i=0; i<=np_in_file-1; i++) {
 
  490      p_data[i+np_file_start].Vel[0] = vel[i].x;
 
  491      p_data[i+np_file_start].Vel[1] = vel[i].y;
 
  492      p_data[i+np_file_start].Vel[2] = vel[i].z;
 
  496  } 
else if (
string(blockname)==
"MASS"){
 
  497    cout << 
"Reading block "<< string(blockname) << endl;
 
  499    for (
int i=0; i<=5; i++) {
 
  500      if (masstab[i]==0.0) {nmass=nmass+npart[i];}}
 
  501    float *mass=
new float[nmass];
 
  502    cout << 
"...memory allocated..." << endl;
 
  503    n = read_gadget_float((
float*)mass,
"MASS",fd);
 
  504    cout << 
"...data is in memory." << endl;
 
  506    for (
int i=0; i<=np_in_file-1; i++) {
 
  507      int ips=p_data[i+np_file_start].type;
 
  508      if (masstab[ips] > 0.0) {
 
  510        p_data[i+np_file_start].Mass = masstab[ips]*umass;
 
  513        p_data[i+np_file_start].Mass = mass[icounter]*umass;
 
  519  }
else if (
string(blockname)==
"RHO"){
 
  520    cout << 
"Reading block "<< string(blockname) << endl;
 
  521    float *rho=
new float[npart[0]];
 
  522    cout << 
"...memory allocated..." << endl;
 
  523    n = read_gadget_float((
float*)rho,
"RHO ",fd);
 
  524    cout << 
"...data is in memory." << endl;
 
  525    for (
int i=0; i<=npart[0]-1; i++) {
 
  527      p_data[i+np_file_start].Rho = rho[i];
 
  531  } 
else if (
string(blockname)==
"RHOD"){
 
  532    cout << 
"Reading block "<< string(blockname) << endl;
 
  533    float *rho=
new float[npart[1]];
 
  534    cout << 
"...memory allocated..." << endl;
 
  535    n = read_gadget_float((
float*)rho,
"RHOD",fd);
 
  536    cout << 
"...data is in memory." << endl;
 
  538    for (
int i=npart[0]; i<=npart[0]+npart[1]-1; i++) {
 
  540      p_data[i+np_file_start].Rho = rho[icount]*umass;
 
  545  }   
else if (
string(blockname)==
"TEMP"){
 
  546    cout << 
"Reading block "<< string(blockname) << endl;
 
  547    float *temp=
new float[npart[0]];
 
  548    cout << 
"...memory allocated..." << endl;
 
  549    n = read_gadget_float((
float*)temp,
"TEMP",fd);
 
  550    cout << 
"...data is in memory." << endl;
 
  552    for (
int i=0; i<=npart[0]-1; i++) {
 
  554      p_data[i+np_file_start].Temp = temp[icount];
 
  560    std::cerr << 
"*** No " << blockname << 
" in file(s) " << filebasename << 
" ***" << std::endl;
 
  567void GadgetFile<ParticleType<float> >::readBlock(
const char *blockname) {
 
  572  int np_in_file=np_file_end-np_file_start+1;
 
  573  cout << string(blockname) << endl;
 
  574  if (
string(blockname)==
"POS") {
 
  575    cout << 
"Reading block "<< string(blockname) << endl;
 
  576    pvector *pos=
new pvector[ntot];
 
  577    cout << 
"...memory allocated." << endl;
 
  578    n = read_gadget_float3((
float*)pos,
"POS ",fd);
 
  579    cout << 
"...data are in memory." << endl;
 
  580    for (
int i=0; i<=np_in_file-1; i++) {
 
  582      p_data[i+np_file_start][0] = pos[i].x;
 
  583      p_data[i+np_file_start][1] = pos[i].y;
 
  584      p_data[i+np_file_start][2] = pos[i].z;
 
  588  } 
else if (
string(blockname)==
"MASS"){
 
  589    cout << 
"Reading block "<< string(blockname) << endl;
 
  591    for (
int i=0; i<=5; i++) {
 
  592      if (masstab[i]==0.0) {nmass=nmass+npart[i];}}
 
  593    float *mass=
new float[nmass];
 
  594    cout << 
"...memory allocated..." << endl;
 
  595    n = read_gadget_float((
float*)mass,
"MASS",fd);
 
  596    cout << 
"...data is in memory." << endl;
 
  598    for (
int i=0; i<=np_in_file-1; i++) {
 
  599      int ips=p_data[i+np_file_start].type;
 
  600      if (masstab[ips] > 0.0) {
 
  602        p_data[i+np_file_start].Mass = masstab[ips]*umass;
 
  605        p_data[i+np_file_start].Mass = mass[icounter]*umass;
 
  612    std::cerr << 
"*** You cannot load " << blockname << 
" from file(s) " << filebasename << 
" into a ParticleType type. ***" << std::endl;
 
  624template<
typename PType>
 
  625int GadgetFile<PType>::read_gadget_float(
float *data,
const char *label,FILE *fd)
 
  629  blocksize = find_block(fd,label);
 
  632    printf(
"Block <%s> not fond !\n",label);
 
  638    printf(
"Reading %d bytes of data from <%s>...\n",blocksize,label);
 
  641    my_fread(data,blocksize, 1, fd);
 
  642    swap_Nbyte((
char*)data,blocksize/
sizeof(
float),4);
 
  645  return(blocksize/
sizeof(
float));
 
  655 template<
typename PType>
 
  656 int GadgetFile<PType>::read_gadget_float3(
float *data,
const char *label,FILE *fd)
 
  660 blocksize = find_block(fd,label);
 
  663 printf(
"Block <%s> not fond !\n",label);
 
  669 printf(
"Reding %d bytes of data from <%s>...\n",blocksize,label);
 
  672 my_fread(data,blocksize, 1, fd);
 
  673 swap_Nbyte((
char*)data,blocksize/
sizeof(
float),4);
 
  676 return(blocksize/
sizeof(
float)/3);