24 constexpr std::size_t size_of(T
const&) {
28 template<
typename PType>
36 double time,redshift,omega,lambda,hubble,boxl;
37 std::string filebasename;
39 GadgetFile (
string inpfn,std::vector<PType> &data);
42 void checkMultiple ();
46 void readBlock (
const char *blockname);
49 int find_block(FILE *fd,
const char *label);
51 int read_gadget_head(
int *npart,
double *massarr,
double *time,
double *redshift,
double *omega,
double *lambda,
double *hubble, FILE *fd);
53 bool FileExists(
string strFilename);
55 std::vector<PType> &p_data;
67 ifstream::pos_type size;
68 int4bytes blksize, swap;
75 int np_file_start, np_file_end;
77 int read_gadget_float(
float *data,
const char *label,FILE *fd);
79 int read_gadget_float3(
float *data,
const char *label,FILE *fd);
80 size_t my_fread(
void *ptr,
size_t size,
size_t nmemb, FILE * stream);
81 void swap_Nbyte(
char *data,
int n,
int m);
84 template<
typename PType>
85 GadgetFile<PType>::GadgetFile(
string inpfn,std::vector<PType> &data):
86 multipleFiles(false),numfiles(0),filebasename(inpfn),p_data(data),swap(0)
87 ,filecnt(0),np_file_start(0),np_file_end(-1)
92 template<
typename PType>
93 void GadgetFile<PType>::checkMultiple(){
95 char *filename =
new char [filebasename.size()+1];
97 filename[filebasename.size()]=0;
98 memcpy(filename,filebasename.c_str(),filebasename.size());
100 bool exists=FileExists(filename);
101 if (exists) {cout <<
"The file exists..." << endl;
103 if(!(fd = fopen(filename,
"r")))
105 printf(
"Cant open file <%s> !\n",filename);
108 cout <<
"Reading header" << endl;
111 n = read_gadget_head(npart,masstab,&time,&redshift,&omega,&lambda,&hubble,fd);
116 printf(
"PartSpecies %d, anz=%d, masstab=%f\n",i,npart[i],masstab[i]);
119 printf(
"Omage %f Lambda %f hubble %f boxl %f\n",omega,lambda,hubble,boxl);
123 cout <<
"The file does not exist or the simulation is splitted in multiple files..." << endl;
124 cout <<
"Trying multiple files..." << endl;
127 for (
int i=0; i<=nmaxf-1; i++) {
129 std::ostringstream filenum;
132 string filebasename_=filebasename+odot+filenum.str();
133 char *filename_ =
new char [filebasename.size()+1];
134 filename_[filebasename_.size()]=0;
135 memcpy(filename_,filebasename_.c_str(),filebasename_.size());
136 bool exists=FileExists(filename_);
137 if (exists) {numfiles++;}
142 cout <<
"The simulation is splitted into " << numfiles <<
" files" << endl;
144 for (
int j=0; j<=numfiles-1; j++) {
145 std::ostringstream filenum;
148 string filebasename_=filebasename+odot+filenum.str();
149 char *filename_ =
new char [filebasename.size()+1];
150 filename_[filebasename_.size()]=0;
151 memcpy(filename_,filebasename_.c_str(),filebasename_.size());
153 if(!(fd = fopen(filename_,
"r")))
155 printf(
"Cant open file <%s> !\n",filename_);
160 cout <<
"-> Reading header# " << j << endl;
163 n = read_gadget_head(npart,masstab,&time,&redshift,&omega,&lambda,&hubble,fd);
167 printf(
"* PartSpecies %d, anz=%d, masstab=%f\n",i,npart[i],masstab[i]);
175 cout <<
"TOTAL NUMBER OF PARTICLES: " << ntot << endl;
177 printf(
"Allocating memory for a total of %zu particles...\n",ntot);
181 cout <<
"done" << endl;
192 #define SKIP {my_fread(&blksize,sizeof(int),1,fd); swap_Nbyte((char*)&blksize,1,4);}
194 template<
typename PType>
195 void GadgetFile<PType>::openFile () {
204 char *filename =
new char [filebasename.size()+1];
205 filename[filebasename.size()]=0;
206 memcpy(filename,filebasename.c_str(),filebasename.size());
207 fd = fopen(filename,
"r");
210 n = read_gadget_head(npart,masstab,&time,&redshift,&omega,&lambda,&hubble,fd);
215 np_file_start=nstart;
217 for (
int ips=0; ips<6; ips++){
222 nstart=nstart+npart[ips];
225 np_file_end=np_file_start+ntot-1;
235 std::ostringstream filenum;
238 string filebasename_=filebasename+odot+filenum.str();
239 char *filename_ =
new char [filebasename.size()+1];
240 filename_[filebasename_.size()]=0;
241 memcpy(filename_,filebasename_.c_str(),filebasename_.size());
243 fd = fopen(filename_,
"r");
246 n = read_gadget_head(npart,masstab,&time,&redshift,&omega,&lambda,&hubble,fd);
251 np_file_start=np_file_end+1;
252 nstart=np_file_start;
254 for (
int ips=0; ips<6; ips++){
260 nstart=nstart+npart[ips];
261 np_in_file=np_in_file+npart[ips];
264 np_file_end=np_file_start+np_in_file-1;
270 template<
typename PType>
271 void GadgetFile<PType>::closeFile () {
290 template<
typename PType>
291 int GadgetFile<PType>::read_gadget_head(
int *npart,
double *massarr,
double *time,
double *redshift,
double *omega,
double *lambda,
double *hubble, FILE *fd)
293 int blocksize,dummysize;
298 blocksize = find_block(fd,
"HEAD");
302 printf(
"Block <%s> not fond !\n",
"HEAD");
307 dummysize=blocksize - 6 *
sizeof(int) - 8 *
sizeof(
double);
308 std::cout << blocksize <<
" " << dummysize << std::endl;
310 my_fread(npart,6*
sizeof(
int), 1, fd); swap_Nbyte((
char*)npart,6,4);
311 my_fread(massarr,6*
sizeof(
double), 1, fd); swap_Nbyte((
char*)massarr,6,8);
312 my_fread(time,
sizeof(
double), 1, fd); swap_Nbyte((
char*)time,1,8);
313 my_fread(redshift,
sizeof(
double), 1, fd); swap_Nbyte((
char*)redshift,1,8);
314 my_fread(&dummyint,
sizeof(
int), 1, fd); swap_Nbyte((
char*)&dummyint,1,4);
315 my_fread(&dummyint,
sizeof(
int), 1, fd); swap_Nbyte((
char*)&dummyint,1,4);
316 my_fread(dummyarr,6*
sizeof(
int), 1, fd); swap_Nbyte((
char*)dummyarr,6,4);
317 my_fread(&dummyint,
sizeof(
int), 1, fd); swap_Nbyte((
char*)&dummyint,1,4);
318 my_fread(&dummyint,
sizeof(
int), 1, fd); swap_Nbyte((
char*)&dummyint,1,4);
319 my_fread(&boxl,
sizeof(
double), 1, fd); swap_Nbyte((
char*)&boxl,1,8);
323 my_fread(omega,
sizeof(
double), 1, fd); swap_Nbyte((
char*)omega,1,8);
324 my_fread(lambda,
sizeof(
double), 1, fd); swap_Nbyte((
char*)lambda,1,8);
325 my_fread(hubble,
sizeof(
double), 1, fd); swap_Nbyte((
char*)hubble,1,8);
326 fseek(fd,dummysize,1);
340 template<
typename PType>
341 void GadgetFile<PType>::swap_Nbyte(
char *data,
int n,
int m)
350 memcpy(&old_data[0],&data[j*m],m);
353 data[j*m+i]=old_data[m-i-1];
366 template<
typename PType>
367 int GadgetFile<PType>::find_block(FILE *fd,
const char *label)
369 int4bytes blocksize=0;
370 char blocklabel[5]={
" "};
374 while(!feof(fd) && blocksize == 0)
377 if(blksize == 134217728)
380 printf(
"Enable ENDIAN swapping !\n");
383 swap_Nbyte((
char*)&blksize,1,4);
387 printf(
"incorrect format (blksize=%d)!\n",blksize);
392 my_fread(blocklabel, 4*
sizeof(
char), 1, fd);
393 my_fread(&blocksize,
sizeof(int4bytes), 1, fd);
394 swap_Nbyte((
char*)&blocksize,1,4);
396 printf(
"Found Block <%s> with %d bytes\n",blocklabel,blocksize);
399 if(strcmp(label,blocklabel)!=0)
401 fseek(fd,blocksize,1);
414 template<
typename PType>
415 size_t GadgetFile<PType>::my_fread(
void *ptr,
size_t size,
size_t nmemb, FILE * stream)
419 if((nread = fread(ptr, size, nmemb, stream)) != nmemb)
421 printf(
"I/O error (fread) !\n");
428 template<
typename PType>
429 bool GadgetFile<PType>::FileExists(
string strFilename) {
430 struct stat stFileInfo;
435 intStat = stat(strFilename.c_str(),&stFileInfo);
453 template<
typename PType>
454 void GadgetFile<PType>::readPOS() {
462 int np_in_file=np_file_end-np_file_start+1;
464 cout <<
"Reading block POS block" << endl;
465 pvector *pos=
new pvector[ntot];
466 cout <<
"...memory allocated." << endl;
467 n = read_gadget_float3((
float*)pos,
"POS ",fd);
468 cout <<
"...data are in memory." << endl;
469 for (
int i=0; i<=np_in_file-1; i++) {
471 p_data[i+np_file_start][0] = pos[i].x;
472 p_data[i+np_file_start][1] = pos[i].y;
473 p_data[i+np_file_start][2] = pos[i].z;
481 void GadgetFile<Point_3d<float> >::readPOS() {
485 cout <<
"Reading POS block" << endl;
487 cout <<
"...memory allocated." << endl;
488 int n = read_gadget_float3((
float*)(p_data.data()),
"POS ",fd);
489 cout <<
"...data are in memory." << endl;
498 template<
typename PType>
499 void GadgetFile<PType>::getMasses(){
502 for (
int i=0; i<=5; i++) {
503 if (masstab[i]==0.0) {nmass=nmass+npart[i];}}
506 float *mass=
new float[nmass];
507 cout <<
"...memory allocated..." << endl;
508 long n = read_gadget_float((
float*)mass,
"MASS",fd);
509 cout <<
"...data is in memory." << endl;
511 for (
int i=0; i<=5; i++) {
512 if (masstab[i]==0.0) masstab[i] = mass[icounter];
513 icounter += npart[i];
522 template<
typename PType>
523 void GadgetFile<PType>::readBlock(
const char *blockname) {
530 int np_in_file=np_file_end-np_file_start+1;
531 cout << string(blockname) << endl;
532 if (
string(blockname)==
"POS") {
533 cout <<
"Reading block "<< string(blockname) << endl;
534 pvector *pos=
new pvector[ntot];
535 cout <<
"...memory allocated." << endl;
536 n = read_gadget_float3((
float*)pos,
"POS ",fd);
537 cout <<
"...data are in memory." << endl;
538 for (
int i=0; i<=np_in_file-1; i++) {
540 p_data[i+np_file_start][0] = pos[i].x;
541 p_data[i+np_file_start][1] = pos[i].y;
542 p_data[i+np_file_start][2] = pos[i].z;
546 }
else if (
string(blockname)==
"VEL") {
547 cout <<
"Reading block "<< string(blockname) << endl;
548 pvector *vel=
new pvector[ntot];
549 cout <<
"...memory allocated..." << endl;
550 n = read_gadget_float3((
float*)vel,
"VEL ",fd);
551 cout <<
"...data is in memory." << endl;
552 for (
int i=0; i<=np_in_file-1; i++) {
554 p_data[i+np_file_start].Vel[0] = vel[i].x;
555 p_data[i+np_file_start].Vel[1] = vel[i].y;
556 p_data[i+np_file_start].Vel[2] = vel[i].z;
560 }
else if (
string(blockname)==
"MASS"){
561 cout <<
"Reading block "<< string(blockname) << endl;
563 for (
int i=0; i<=5; i++) {
564 if (masstab[i]==0.0) {nmass=nmass+npart[i];}}
565 float *mass=
new float[nmass];
566 cout <<
"...memory allocated..." << endl;
567 n = read_gadget_float((
float*)mass,
"MASS",fd);
568 cout <<
"...data is in memory." << endl;
570 for (
int i=0; i<=np_in_file-1; i++) {
571 int ips=p_data[i+np_file_start].type;
572 if (masstab[ips] > 0.0) {
573 p_data[i+np_file_start].Mass = masstab[ips]*umass;
575 p_data[i+np_file_start].Mass = mass[icounter]*umass;
581 }
else if (
string(blockname)==
"RHO"){
582 cout <<
"Reading block "<< string(blockname) << endl;
583 float *rho=
new float[npart[0]];
584 cout <<
"...memory allocated..." << endl;
585 n = read_gadget_float((
float*)rho,
"RHO ",fd);
586 cout <<
"...data is in memory." << endl;
587 for (
int i=0; i<=npart[0]-1; i++) {
589 p_data[i+np_file_start].Rho = rho[i];
593 }
else if (
string(blockname)==
"RHOD"){
594 cout <<
"Reading block "<< string(blockname) << endl;
595 float *rho=
new float[npart[1]];
596 cout <<
"...memory allocated..." << endl;
597 n = read_gadget_float((
float*)rho,
"RHOD",fd);
598 cout <<
"...data is in memory." << endl;
600 for (
int i=npart[0]; i<=npart[0]+npart[1]-1; i++) {
602 p_data[i+np_file_start].Rho = rho[icount]*umass;
607 }
else if (
string(blockname)==
"TEMP"){
608 cout <<
"Reading block "<< string(blockname) << endl;
609 float *temp=
new float[npart[0]];
610 cout <<
"...memory allocated..." << endl;
611 n = read_gadget_float((
float*)temp,
"TEMP",fd);
612 cout <<
"...data is in memory." << endl;
614 for (
int i=0; i<=npart[0]-1; i++) {
616 p_data[i+np_file_start].Temp = temp[icount];
622 std::cerr <<
"*** No " << blockname <<
" in file(s) " << filebasename <<
" ***" << std::endl;
629 void GadgetFile<ParticleType<float> >::readBlock(
const char *blockname) {
634 int np_in_file=np_file_end-np_file_start+1;
635 cout << string(blockname) << endl;
636 if (
string(blockname)==
"POS") {
637 cout <<
"Reading block "<< string(blockname) << endl;
638 pvector *pos=
new pvector[ntot];
639 cout <<
"...memory allocated." << endl;
640 n = read_gadget_float3((
float*)pos,
"POS ",fd);
641 cout <<
"...data are in memory." << endl;
642 for (
int i=0; i<=np_in_file-1; i++) {
644 p_data[i+np_file_start][0] = pos[i].x;
645 p_data[i+np_file_start][1] = pos[i].y;
646 p_data[i+np_file_start][2] = pos[i].z;
650 }
else if (
string(blockname)==
"MASS"){
651 cout <<
"Reading block "<< string(blockname) << endl;
653 for (
int i=0; i<=5; i++) {
654 if (masstab[i]==0.0) {nmass=nmass+npart[i];}}
655 float *mass=
new float[nmass];
656 cout <<
"...memory allocated..." << endl;
657 n = read_gadget_float((
float*)mass,
"MASS",fd);
658 cout <<
"...data is in memory." << endl;
660 for (
int i=0; i<=np_in_file-1; i++) {
661 int ips=p_data[i+np_file_start].type;
662 if (masstab[ips] > 0.0) {
664 p_data[i+np_file_start].Mass = masstab[ips]*umass;
667 p_data[i+np_file_start].Mass = mass[icounter]*umass;
674 std::cerr <<
"*** You cannot load " << blockname <<
" from file(s) " << filebasename <<
" into a ParticleType type. ***" << std::endl;
686 template<
typename PType>
687 int GadgetFile<PType>::read_gadget_float(
float *data,
const char *label,FILE *fd)
691 blocksize = find_block(fd,label);
694 printf(
"Block <%s> not fond !\n",label);
700 printf(
"Reading %d bytes of data from <%s>...\n",blocksize,label);
703 my_fread(data,blocksize, 1, fd);
704 swap_Nbyte((
char*)data,blocksize/
sizeof(
float),4);
707 return(blocksize/
sizeof(
float));
717 template<
typename PType>
718 int GadgetFile<PType>::read_gadget_float3(
float *data,
const char *label,FILE *fd)
722 blocksize = find_block(fd,label);
725 printf(
"Block <%s> not fond !\n",label);
731 printf(
"Reding %d bytes of data from <%s>...\n",blocksize,label);
734 my_fread(data,blocksize, 1, fd);
735 swap_Nbyte((
char*)data,blocksize/
sizeof(
float),4);
738 return(blocksize/
sizeof(
float)/3);