Changeset 25480


Ignore:
Timestamp:
08/26/20 18:47:35 (5 years ago)
Author:
Eric.Larour
Message:

CHG: starting implementation of a histogram capability in issm_post.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified issm/branches/trunk-larour-SLPS2020/src/c/main/issm_post.cpp

    r25361 r25480  
    2727        int    nindices;
    2828        int*   indices=NULL;
     29        int    nbins;
    2930       
    3031        /*datasets*/
     
    9293
    9394                ComputeMeanVariance(parameters,results);
     95        }
     96        else if(strcmp(method,"Histogram")==0){
     97               
     98                /*Retrieve the size of the histogram (number of bins):*/
     99                nbins=atoi(argv[offset]); offset++;
     100                parameters->AddObject(new IntParam(NbinsEnum,nbins));
     101               
     102                ComputeHistogram(parameters,results);
     103
    94104        }
    95105        else if(strcmp(method,"SampleSeries")==0){
     
    244254        _printf0_("Done reading files, now computing mean and variance.\n");
    245255
    246         /*We have agregated x and x^2 across the cluster, now consolidate: */
     256        /*We have agregated x and x^2 across the cluster, now gather across the cluster onto
     257         *cpu0 and then compute statistics:*/
    247258        for (int f=0;f<nfields;f++){
    248                 for (int j=0;j<nsteps;j++){
    249                         int counter=f*nsteps+j;
    250                         if (xtype[counter]==1){
     259
     260                IssmDouble sumscalar_alltimes=0;
     261                IssmDouble sumscalar2_alltimes=0;
     262                IssmDouble* sumarray_alltimes=NULL;
     263                IssmDouble* sumarray2_alltimes=NULL;
     264                       
     265                int counter0=f*nsteps+0;
     266                if (xtype[counter0]==1){ /*deal with scalars {{{*/
     267                        IssmDouble mean,stddev;
     268                        for (int j=0;j<nsteps;j++){
     269                                int counter=f*nsteps+j;
     270
    251271                                /*we are broadcasting doubles:*/
    252272                                IssmDouble scalar=*xs[counter];
     
    254274                                IssmDouble sumscalar;
    255275                                IssmDouble sumscalar2;
    256                                 IssmDouble mean,stddev;
    257276
    258277                                ISSM_MPI_Reduce(&scalar,&sumscalar,1,ISSM_MPI_PDOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm());
     
    266285                                if(my_rank==0){
    267286                                        char fieldname[1000];
    268                                        
     287
    269288                                        sprintf(fieldname,"%s%s",fields[f],"Mean");
    270289                                        results->AddResult(new GenericExternalResult<IssmDouble>(results->Size()+1,fieldname,mean,j+1,0));
     
    272291                                        results->AddResult(new GenericExternalResult<IssmDouble>(results->Size()+1,fieldname,stddev,j+1,0));
    273292                                }
    274                         }
    275                         else{
     293
     294                                /*We are also looking for the mean and stddev  over all time steps,
     295                                 *so accumulate sums again:*/
     296                                sumscalar_alltimes+=sumscalar;
     297                                sumscalar2_alltimes+=sumscalar2;
     298                        }
     299                        /*Build averae and standard deviation for all time steps:*/
     300                        mean=sumscalar_alltimes/nsamples/nsteps;
     301                        stddev=sqrt(sumscalar2_alltimes/nsamples/nsteps-pow(mean,2.0));
     302                        /*add to results at step 1:*/
     303                        if(my_rank==0){
     304                                char fieldname[1000];
     305
     306                                sprintf(fieldname,"%s%s",fields[f],"TimeMean");
     307                                results->AddResult(new GenericExternalResult<IssmDouble>(results->Size()+1,fieldname,mean,1,0));
     308                                sprintf(fieldname,"%s%s",fields[f],"TimeStddev");
     309                                results->AddResult(new GenericExternalResult<IssmDouble>(results->Size()+1,fieldname,stddev,1,0));
     310                        }
     311                } /*}}}*/
     312                else{ /*deal with arrays:{{{*/
     313
     314                        int size=xsize[counter0];
     315                        sumarray_alltimes=xNewZeroInit<IssmDouble>(size);
     316                        sumarray2_alltimes=xNewZeroInit<IssmDouble>(size);
     317
     318                        IssmDouble*  mean=xNew<IssmDouble>(size);
     319                        IssmDouble*  stddev=xNew<IssmDouble>(size);
     320
     321                        for (int j=0;j<nsteps;j++){
     322                                int counter=f*nsteps+j;
     323
    276324                                /*we are broadcasting double arrays:*/
    277325                                x=xs[counter];
    278326                                x2=xs2[counter];
    279                                 int size=xsize[counter];
    280                                
     327
    281328                                IssmDouble*  sumx=xNew<IssmDouble>(size);
    282329                                IssmDouble*  sumx2=xNew<IssmDouble>(size);
    283                                 IssmDouble*  mean=xNew<IssmDouble>(size);
    284                                 IssmDouble*  stddev=xNew<IssmDouble>(size);
    285 
     330                               
    286331                                ISSM_MPI_Reduce(x,sumx,size,ISSM_MPI_PDOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm());
    287332                                ISSM_MPI_Reduce(x2,sumx2,size,ISSM_MPI_PDOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm());
     
    303348                                        results->AddResult(new GenericExternalResult<IssmPDouble*>(results->Size()+1,fieldname,stddev,size,1,j+1,0));
    304349                                }
    305                         }
    306                 }
    307         }
    308 
     350
     351                                /*We want mean and stddev across time too, so accumulate through time: */
     352                                for (int k=0;k<size;k++){
     353                                        sumarray_alltimes[k]+=sumx[k];
     354                                        sumarray2_alltimes[k]+=sumx2[k];
     355                                }
     356                        }
     357
     358                        /*build time mean and stddev:*/
     359                        for (int k=0;k<size;k++){
     360                                mean[k]=sumarray_alltimes[k]/nsamples/nsteps;
     361                                stddev[k]=sqrt(sumarray2_alltimes[k]/nsamples/nsteps-pow(mean[k],2.0));
     362                        }
     363
     364                        /*add to results at step 1:*/
     365                        if(my_rank==0){
     366                                char fieldname[1000];
     367
     368                                sprintf(fieldname,"%s%s",fields[f],"TimeMean");
     369                                results->AddResult(new GenericExternalResult<IssmPDouble*>(results->Size()+1,fieldname,mean,size,1,1,0));
     370                                sprintf(fieldname,"%s%s",fields[f],"TimeStddev");
     371                                results->AddResult(new GenericExternalResult<IssmPDouble*>(results->Size()+1,fieldname,stddev,size,1,1,0));
     372                        }
     373                } /*}}}*/
     374
     375        }
    309376
    310377} /*}}}*/
     
    462529
    463530} /*}}}*/
     531int ComputeHistogram(Parameters* parameters,Results* results){ /*{{{*/
     532
     533        int nsamples;
     534        char* directory=NULL;
     535        char* model=NULL;
     536        char** fields=NULL;
     537        int* steps=NULL;
     538        int nsteps;
     539        int nfields;
     540        int nbins;
     541        int range,lower_row,upper_row;
     542       
     543        /*intermediary:*/
     544        IssmDouble* doublemat=NULL;
     545        int         doublematsize;
     546        IssmDouble scalar;
     547
     548        /*computation of average and variance itself:*/
     549        IssmDouble** maxxs = NULL;
     550        IssmDouble** minxs = NULL;
     551        int*         xtype=NULL;
     552        int*         xsize=NULL;
     553
     554        IssmDouble** maxmeans=NULL;
     555        IssmDouble** minmeans=NULL;
     556        int*         meanxtype=NULL;
     557        int*         meanxsize=NULL;
     558
     559        /*Retrieve parameters:*/
     560        parameters->FindParam(&nsamples,QmuNsampleEnum);
     561        parameters->FindParam(&directory,DirectoryNameEnum);
     562        parameters->FindParam(&model,InputFileNameEnum);
     563        parameters->FindParam(&fields,&nfields,FieldsEnum);
     564        parameters->FindParam(&steps,&nsteps,StepsEnum);
     565        parameters->FindParam(&nbins,NbinsEnum);
     566
     567        /*Get rank:*/
     568        int my_rank=IssmComm::GetRank();
     569
     570        /*Open files and read them complelety, in a distributed way:*/
     571        range=DetermineLocalSize(nsamples,IssmComm::GetComm());
     572        GetOwnershipBoundariesFromRange(&lower_row,&upper_row,range,IssmComm::GetComm());
     573
     574        /*Initialize arrays:*/
     575
     576        maxmeans=xNew<IssmDouble*>(nfields);
     577        minmeans=xNew<IssmDouble*>(nfields);
     578        meanxtype=xNew<IssmDouble*>(nfields);
     579        meanxsize=xNew<IssmDouble*>(nfields);
     580
     581        maxxs=xNew<IssmDouble*>(nfields*nsteps);
     582        minxs=xNew<IssmDouble*>(nfields*nsteps);
     583        xtype=xNew<int>(nfields*nsteps);
     584        xsize=xNew<int>(nfields*nsteps);
     585
     586        /*Start opening files:*/
     587        for (int i=(lower_row+1);i<=upper_row;i++){
     588                _printf0_("reading file #: " << i << "\n");
     589                char file[1000];
     590                int  length;
     591                char* buffer=NULL;
     592
     593                /*string:*/
     594                sprintf(file,"%s/%i/%s.outbin.%i",directory,my_rank+1,model,i);
     595
     596                /*open file: */
     597                _printf0_("    opening file:\n");
     598                FILE* fid=fopen(file,"rb");
     599
     600                /*figure out size of file, and read the whole thing:*/
     601                _printf0_("    reading file:\n");
     602                fseek (fid, 0, SEEK_END);
     603                length = ftell (fid);
     604                fseek (fid, 0, SEEK_SET);
     605                buffer = xNew<char>(length);
     606                fread (buffer, sizeof(char), length, fid);
     607
     608                /*close file:*/
     609                fclose (fid);
     610
     611                /*create a memory stream with this buffer:*/
     612                _printf0_("    processing file:\n");
     613                fid=fmemopen(buffer, length, "rb");
     614
     615                /*start reading data from the buffer directly:*/
     616                for (int f=0;f<nfields;f++){
     617                        char* field=fields[f];
     618                        for (int j=0;j<nsteps;j++){
     619                                int counter=f*nsteps+j;
     620                                xtype[counter]=readdata(&doublemat, &doublematsize, &scalar, fid,field,steps[j]);
     621                                if(i==(lower_row+1)){
     622                                        if(xtype[counter]==1){
     623                                                maxxs[counter]=xNew<IssmDouble>(1);
     624                                                minxs[counter]=xNew<IssmDouble>(1);
     625                                                *maxxs[counter]=scalar;
     626                                                *minxs[counter]=scalar;
     627                                                xsize[counter]=1;
     628                                        }
     629                                        else if (xtype[counter]==3){
     630                                                maxxs[counter]=doublemat;
     631                                                minxs[counter]=doublemat;
     632                                                xsize[counter]=doublematsize;
     633                                        }
     634                                        else _error_("cannot carry out statistics on type " << xtype[counter]);
     635                                }
     636                                else{
     637                                        if(xtype[counter]==1){
     638                                                *maxxs[counter]=max(*maxxs[counter],scalar);
     639                                                *minxs[counter]=min(*minxs[counter],scalar);
     640                                        }
     641                                        else if (xtype[counter]==3){
     642                                                IssmDouble* newmax=minxs[counter];
     643                                                IssmDouble* newmin=maxxs[counter];
     644                                                for(int k=0;k<doublematsize;k++){
     645                                                        newmax[k]=max(newmax[k],doublemat[k]);
     646                                                        newmin[k]=min(newmin[k],doublemat[k]);
     647                                                }
     648                                                maxxs[counter]=newmax;
     649                                                minxs[counter]=newmin;
     650                                        }
     651                                        else _error_("cannot carry out statistics on type " << xtype[counter]);
     652                                }
     653                        }
     654                }
     655               
     656                /*Deal with average in time: */
     657                for (int f=0;f<nfields;f++){
     658                        char* field=fields[f];
     659                        meanxtype[f]=readdata(&doublemat, &doublematsize, &scalar, fid,field,steps[0]);
     660                        if(i==(lower_row+1)){
     661                                if(meanxtype[f]==1){
     662                                        maxmeans[f]=xNewZeroInit<IssmDouble>(1);
     663                                        minmeans[f]=xNewZeroInit<IssmDouble>(1);
     664                                        meanxsize[f]=1;
     665                                }
     666                                else{
     667                                        maxmeans[f]=xNewZeroInit<IssmDouble>(doublematsize);
     668                                        minmeans[f]=xNewZeroInit<IssmDouble>(doublematsize);
     669                                        meanxsize[f]=doublematsize;
     670                                }
     671
     672                        }
     673                        if(meanxtype[f]==1){
     674                                IssmDouble timemean=0;
     675                                for (int j=0;j<nsteps;j++){
     676                                        readdata(&doublemat, &doublematsize, &scalar, fid,field,steps[j]);
     677                                        timemean+=scalar/nsteps;
     678                                }
     679                                /*Figure out max and min of time means: */
     680                                *maxmeans[f]=max(*maxmeans[f],timemean);
     681                                *minmeans[f]=min(*minmeans[f],timemean);
     682                        }
     683                        else{
     684                                IssmDouble* maxx=maxmeans[f];
     685                                IssmDouble* minx=minmeans[f];
     686                                for(int k=0;k<doublematsize;k++){
     687                                        maxx[k]=max(maxx[k],doublemat[k]);
     688                                        minx[k]=min(minx[k],doublemat[k]);
     689                                }
     690                                maxmeans[f]=maxx;
     691                                minmeans[f]=minx;
     692                                }
     693                }
     694                fclose(fid);
     695
     696                /*delete buffer:*/
     697                xDelete<char>(buffer);
     698        }
     699        ISSM_MPI_Barrier(ISSM_MPI_COMM_WORLD);
     700        _printf0_("Done reading files, now computing min and max.\n");
     701
     702        /*We have agregated minx and max across the cluster, now gather across the cluster onto
     703         *cpu0 and then compute statistics:*/
     704        for (int f=0;f<nfields;f++){
     705                int counter0=f*nsteps+0;
     706                if (xtype[counter0]==1){ /*deal with scalars {{{*/
     707                        for (int j=0;j<nsteps;j++){
     708                                int counter=f*nsteps+j;
     709
     710                                /*we are broadcasting doubles:*/
     711                                IssmDouble maxscalar=*maxxs[counter];
     712                                IssmDouble minscalar=*minxs[counter];
     713                                IssmDouble allmaxscalar;
     714                                IssmDouble allminscalar;
     715                                IssmDouble sumscalar_alltimes=0;
     716
     717                                ISSM_MPI_Reduce(&maxscalar,&allmaxscalar,1,ISSM_MPI_PDOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm());
     718                                ISSM_MPI_Reduce(&minscalar,&allminscalar,1,ISSM_MPI_PDOUBLE,ISSM_MPI_MIN,0,IssmComm::GetComm());
     719
     720                                /*add to results:*/
     721                                if(my_rank==0){
     722                                        char fieldname[1000];
     723
     724                                        sprintf(fieldname,"%s%s",fields[f],"Max");
     725                                        results->AddResult(new GenericExternalResult<IssmDouble>(results->Size()+1,fieldname,allmaxscalar,j+1,0));
     726                                        sprintf(fieldname,"%s%s",fields[f],"Min");
     727                                        results->AddResult(new GenericExternalResult<IssmDouble>(results->Size()+1,fieldname,allminscalar,j+1,0));
     728                                }
     729                        }
     730                } /*}}}*/
     731                else{ /*deal with arrays:{{{*/
     732
     733                        int size=xsize[counter0];
     734                        for (int j=0;j<nsteps;j++){
     735                                int counter=f*nsteps+j;
     736
     737                                /*we are broadcasting double arrays:*/
     738                                IssmDouble* maxx==maxxs[counter];
     739                                IssmDouble* minx==minxs[counter];
     740
     741                                IssmDouble*  allmax=xNew<IssmDouble>(size);
     742                                IssmDouble*  allmin=xNew<IssmDouble>(size);
     743                               
     744                                ISSM_MPI_Reduce(maxx,allmax,size,ISSM_MPI_PDOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm());
     745                                ISSM_MPI_Reduce(minx,allmin,size,ISSM_MPI_PDOUBLE,ISSM_MPI_MIN,0,IssmComm::GetComm());
     746
     747                                /*add to results:*/
     748                                if(my_rank==0){
     749                                        char fieldname[1000];
     750
     751                                        sprintf(fieldname,"%s%s",fields[f],"Max");
     752                                        results->AddResult(new GenericExternalResult<IssmPDouble*>(results->Size()+1,fieldname,allmax,size,1,j+1,0));
     753                                        sprintf(fieldname,"%s%s",fields[f],"Min");
     754                                        results->AddResult(new GenericExternalResult<IssmPDouble*>(results->Size()+1,fieldname,allmin,size,1,j+1,0));
     755                                }
     756                        }
     757                } /*}}}*/
     758        }
     759       
     760        /*Now do the same for the time mean fields:*/
     761        for (int f=0;f<nfields;f++){
     762                if (meanxtype[f]==1){ /*deal with scalars {{{*/
     763
     764                        /*we are broadcasting doubles:*/
     765                        IssmDouble maxscalar=*maxmeans[f];
     766                        IssmDouble minscalar=*minmeans[f];
     767                        IssmDouble allmaxscalar;
     768                        IssmDouble allminscalar;
     769
     770                        ISSM_MPI_Reduce(&maxscalar,&allmaxscalar,1,ISSM_MPI_PDOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm());
     771                        ISSM_MPI_Reduce(&minscalar,&allminscalar,1,ISSM_MPI_PDOUBLE,ISSM_MPI_MIN,0,IssmComm::GetComm());
     772
     773                        /*add to results at time step 1:*/
     774                        if(my_rank==0){
     775                                char fieldname[1000];
     776
     777                                sprintf(fieldname,"%s%s",fields[f],"TimeMeanMax");
     778                                results->AddResult(new GenericExternalResult<IssmDouble>(results->Size()+1,fieldname,allmaxscalar,1,0));
     779                                sprintf(fieldname,"%s%s",fields[f],"TimeMeaMin");
     780                                results->AddResult(new GenericExternalResult<IssmDouble>(results->Size()+1,fieldname,allminscalar,1,0));
     781                        }
     782                } /*}}}*/
     783                else{ /*deal with arrays:{{{*/
     784
     785                        int size=meanxsize[f];
     786
     787                        /*we are broadcasting double arrays:*/
     788                        IssmDouble* maxx==maxmeans[f];
     789                        IssmDouble* minx==minmeans[f];
     790
     791                        IssmDouble*  allmax=xNew<IssmDouble>(size);
     792                        IssmDouble*  allmin=xNew<IssmDouble>(size);
     793
     794                        ISSM_MPI_Reduce(maxx,allmax,size,ISSM_MPI_PDOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm());
     795                        ISSM_MPI_Reduce(minx,allmin,size,ISSM_MPI_PDOUBLE,ISSM_MPI_MIN,0,IssmComm::GetComm());
     796
     797                        /*add to results at step 1:*/
     798                        if(my_rank==0){
     799                                char fieldname[1000];
     800
     801                                sprintf(fieldname,"%s%s",fields[f],"TimeMeanMax");
     802                                results->AddResult(new GenericExternalResult<IssmPDouble*>(results->Size()+1,fieldname,allmax,size,1,j,0));
     803                                sprintf(fieldname,"%s%s",fields[f],"TimeMeanMin");
     804                                results->AddResult(new GenericExternalResult<IssmPDouble*>(results->Size()+1,fieldname,allmin,size,1,j,0));
     805                        }
     806                } /*}}}*/
     807        }
     808
     809
     810} /*}}}*/
    464811int OutputStatistics(Parameters* parameters,Results* results){ /*{{{*/
    465812       
     
    469816        char* method=NULL;
    470817        int   nsamples;
     818        int* steps=NULL;
     819        int nsteps;
     820
    471821        FemModel* femmodel=new FemModel();
    472 
    473822       
    474823        /*Some parameters that will allow us to use the OutputResultsx module:*/
     
    480829        parameters->FindParam(&method,AnalysisTypeEnum);
    481830        parameters->FindParam(&nsamples,QmuNsampleEnum);
    482         sprintf(outputfilename,"%s/%s-%s.stats-%i",directory,model,method,nsamples);
     831        parameters->FindParam(&steps,&nsteps,StepsEnum);
     832
     833        sprintf(outputfilename,"%s/%s-%s.stats-samp%i-time%i:%i",directory,model,method,nsamples,steps[0],steps[nsteps-1]);
    483834        parameters->AddObject(new StringParam(OutputFileNameEnum,outputfilename));
    484835
Note: See TracChangeset for help on using the changeset viewer.