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
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
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 }