SpatialFamilyPopulation.cpp

Go to the documentation of this file.
00001 
00012 #include "SpatialFamilyPopulation.h"
00013 #include "PCSIMException.h"
00014 #include <boost/format.hpp>
00015 
00016 #include <map>
00017 using std::map;
00018 
00019 #include <algorithm>
00020 using std::sort;
00021 
00022 #include <iostream>
00023 using std::cerr;
00024 using std::endl;
00025 
00027 SpatialFamilyPopulation::SpatialFamilyPopulation( SimNetwork* net, 
00028                                                   vector<SimObject::ID::Packed> const& objIDs, 
00029                                                   vector<familyid_t> const& famIDs,
00030                                                   shared_ptr<Point3DSet> locs )
00031     : SpatialSimObjectPopulation( *net, locs )
00032 {
00033     if( !( (objIDs.size() == famIDs.size()) && (objIDs.size() == locs->size()) ) ) {
00034         throw( PCSIM::ConstructionException( "SpatialFamilyPopulation::SpatialFamilyPopulation", "All vectors must be of same size." ) );
00035     }
00036 
00037     shared_ptr< vector<familyid_t> > tmpfam( new vector<familyid_t>(famIDs) );
00038     this->familyIDs = tmpfam;
00039 
00040     shared_ptr< vector<SimObject::ID::Packed> > tmpobj( new vector<SimObject::ID::Packed>(objIDs) );
00041     this->shr_ptr_vec = tmpobj;
00042     id_vec = shr_ptr_vec.get();
00043 }
00044 
00045 SpatialFamilyPopulation::SpatialFamilyPopulation( SimNetwork & net, shared_ptr<Point3DSet> locs)
00046     : SpatialSimObjectPopulation( net, locs )
00047 {
00048     this->net = &net;
00049 }
00050 
00060 SpatialFamilyPopulation::SpatialFamilyPopulation( SimNetwork & net,
00061                                                   vector< SimObjectFactory* > const& families,
00062                                                   SpatialFamilyIDGenerator const& fidgen,
00063                                                   shared_ptr<Point3DSet> locs )
00064     : SpatialSimObjectPopulation( net, locs )
00065 {
00066     this->familyIDs = fidgen.generateIDs( net, families, *locations );
00067     shr_ptr_vec = populate( families );
00068     id_vec = shr_ptr_vec.get();
00069 }
00070 
00080 SpatialFamilyPopulation::SpatialFamilyPopulation( SimNetwork & net,
00081                                                   vector< shared_ptr<SimObjectFactory> > const& familiesArg,
00082                                                   SpatialFamilyIDGenerator const& fidgen,
00083                                                   shared_ptr<Point3DSet> locs )
00084     : SpatialSimObjectPopulation( net, locs )
00085 {
00086     vector< SimObjectFactory* > families( familiesArg.size() );
00087     for (size_t f=0; f<familiesArg.size(); f++ ) {
00088         families[f] = &(*familiesArg[f]);
00089     }
00090     this->familyIDs = fidgen.generateIDs( net, families, *locations );
00091     shr_ptr_vec = populate( families );
00092     id_vec = shr_ptr_vec.get();
00093 }
00094 
00101 SpatialFamilyPopulation::SpatialFamilyPopulation( SimNetwork & net,
00102                                                   SimObjectFactory * fam0,
00103                                                   shared_ptr<Point3DSet> locs )
00104     : SpatialSimObjectPopulation( net, locs )
00105 {
00106     shared_ptr< vector<familyid_t> > temp( new vector<familyid_t>( locs->size(), 0 ) );
00107     this->familyIDs = temp;
00108     vector< SimObjectFactory* > families(1);
00109     families[0] = fam0;
00110 
00111     shr_ptr_vec = populate( families );
00112     id_vec = shr_ptr_vec.get();
00113 }
00114 
00120 SpatialFamilyPopulation::SpatialFamilyPopulation( vector< shared_ptr<SpatialFamilyPopulation> >  const& pops )
00121 {
00122     if( pops.size() < 1 ) {
00123         throw( PCSIM::ConstructionException( "SpatialFamilyPopulation::SpatialFamilyPopulation", "Empty set of populations specified to merge." ) );
00124     }
00125 
00126     // Calculate total size and check net
00127     this->net = &( pops[0]->getNet() );
00128     size_t tot_size = 0;
00129     size_t p;
00130     for( p = 0; p<pops.size(); p++ ) {
00131         tot_size += pops[p]->size();
00132         if( this->net != &( pops[p]->getNet() ) ) {
00133             throw( PCSIM::ConstructionException( "SpatialFamilyPopulation::SpatialFamilyPopulation", "Can not merge populations which belong to different networks." ) );
00134         }
00135     }
00136 
00137     shared_ptr< vector<familyid_t> > temp( new vector<familyid_t>( tot_size, 0 ) );
00138     this->familyIDs = temp;
00139 
00140     shared_ptr< vector<SimObject::ID::Packed> > tmpobj( new vector<SimObject::ID::Packed>( tot_size, 0 ) );
00141     this->shr_ptr_vec = tmpobj;
00142     id_vec = shr_ptr_vec.get();
00143 
00144     vector< Point3D<double> > points( tot_size );
00145     size_t ii=0;
00146     for( p = 0; p<pops.size(); p++ ) {
00147         SpatialFamilyPopulation* P = pops[p].get();
00148         for( size_t i = 0; i<pops[p]->size(); i++ ) {
00149             (*familyIDs)[ ii ]   = P->getFamilyID( i );
00150             (*shr_ptr_vec)[ ii ] = (*(P->shr_ptr_vec))[ i ];
00151             points[ ii ]         = P->getLocation( i );
00152             ii++;
00153         }
00154     }
00155 
00156     locations = shared_ptr<Point3DSet>( new Point3DSet( points ) );
00157 }
00158 
00162 SpatialFamilyPopulation::~SpatialFamilyPopulation()
00163 {
00164   // NOOP
00165 }
00166 
00170 SimObject::ID::Vector SpatialFamilyPopulation::populate( vector< SimObjectFactory* > const& families ) 
00171 {
00172     size_t n = this->locations->size();
00173     SimObject::ID::Vector ids( new vector<SimObject::ID::Packed>(n) );
00174     SimObject::ID id;
00175     familyid_t fid;
00176     for( size_t i=0; i<n; i++ ) {
00177         fid = (*familyIDs)[i];
00178         net->addObject( *(families[fid]), id );
00179         (*ids)[i] = id.packed();
00180     }
00181     return ids;
00182 }
00183 
00184 familyid_t SpatialFamilyPopulation::getFamilyIdAt( Point3D<double> const& p ) {
00185     return (*familyIDs)[ locations->getIndex( p ) ];
00186 }
00187 
00188 familyid_t SpatialFamilyPopulation::getFamilyIdAt( double const& x, double const& y, double const& z) {
00189     return (*familyIDs)[ locations->getIndex( x, y, z ) ];
00190 }
00191 
00192 
00193 familyid_t SpatialFamilyPopulation::getFamilyID( size_t index ) {
00194     return (*familyIDs)[ index ];
00195 }
00196 
00197 void SpatialFamilyPopulation::setFamilyID( familyid_t newID )
00198 {
00199     for( size_t i=0; i<familyIDs->size(); i++ )
00200         (*familyIDs)[ i ] = newID;
00201 }
00202 
00206 shared_ptr<SpatialFamilyPopulation> SpatialFamilyPopulation::subPopulation( vector< familyid_t > const& families )
00207 {
00208     vector<size_t> subindices;
00209     map< size_t, size_t >  fid_set;
00210     for( size_t f=0; f<families.size(); f ++ ) {
00211         fid_set[ families[f] ] = 1;
00212     }
00213     for( size_t i=0; i<id_vec->size(); i++ ) {
00214         if( fid_set.find( (*familyIDs)[ i ] ) !=  fid_set.end() ) {
00215             subindices.push_back( i );
00216         }
00217     }
00218     return shared_ptr<SpatialFamilyPopulation>( new_subset( subindices ) );
00219 }
00220 
00221 SpatialFamilyPopulation* SpatialFamilyPopulation::new_subset( vector< size_t > const& subindices ) const 
00222 {
00223     size_t s;
00224     vector<SimObject::ID::Packed> objIDs( subindices.size() );
00225     vector<familyid_t> famIDs( subindices.size() );
00226     for( size_t i=0; i<subindices.size(); i++ ) {
00227         s = subindices[i];
00228         objIDs[i] = (*id_vec)[ s ];
00229         famIDs[i] = (*familyIDs)[ s ];
00230     }
00231     return new SpatialFamilyPopulation( net, objIDs, famIDs, locations->subset( subindices ) );
00232 }
00233 
00234 shared_ptr< vector< shared_ptr<SpatialFamilyPopulation> > > SpatialFamilyPopulation::splitFamilies()
00235 {
00236     size_t n = familyIDs->size();
00237     familyid_t fid;
00238 
00240     map< familyid_t, size_t >  cnt;
00241     vector< vector< size_t > > subs;
00242     vector< size_t > famids;
00243 
00244     for( size_t i=0; i<n; i++ ) {
00245         fid = (*familyIDs)[i];
00246         if (  cnt.find( fid ) == cnt.end() ) {
00247             cnt[ fid ] = cnt.size() - 1;
00248             subs.resize( cnt.size() );
00249             subs[ subs.size() - 1 ].resize(0);
00250             famids.push_back( fid );
00251         }
00252         subs[ cnt[fid] ].push_back( i );
00253     }
00254     sort( famids.begin(), famids.end() );
00255 
00256     shared_ptr< vector< shared_ptr<SpatialFamilyPopulation> > > subpops( new vector< shared_ptr<SpatialFamilyPopulation> >( subs.size() ) );
00257 
00258     for( size_t s = 0; s < famids.size(); s++ ) {
00259         fid = famids[s];
00260         (*subpops)[s] = shared_ptr<SpatialFamilyPopulation>( new_subset( subs[ cnt[fid] ] ) );
00261     }
00262     return subpops;
00263 
00264 }

Generated on Wed Jul 9 16:34:37 2008 for PCSIM by  doxygen 1.5.5