00001
00011 #include "AugmentedSpatialPopulation.h"
00012 #include "PopObjectAttributeFactory.h"
00013
00014
00015
00016
00017
00018
00019
00020 AugmentedSpatialPopulation::AugmentedSpatialPopulation(
00021 SimNetwork & net,
00022 vector< shared_ptr<PopObjectAttributeFactory> > const& familiesArg,
00023 SpatialFamilyIDGenerator const& fidgen,
00024 shared_ptr<Point3DSet> locs )
00025 : SpatialFamilyPopulation( net, locs )
00026 {
00027 vector< SimObjectFactory* > families( familiesArg.size() );
00028 for( size_t f=0; f<familiesArg.size(); f++ ) {
00029 families[f] = &(*familiesArg[f]);
00030 }
00031 this->familyIDs = fidgen.generateIDs(net, families, *locations);
00032
00033 populate(familiesArg);
00034 id_vec = shr_ptr_vec.get();
00035 }
00036
00037
00038 AugmentedSpatialPopulation::AugmentedSpatialPopulation(SimNetwork & net,
00039 shared_ptr<PopObjectAttributeFactory> fam0,
00040 shared_ptr<Point3DSet> locs )
00041 : SpatialFamilyPopulation( net, locs )
00042 {
00043 shared_ptr< vector<familyid_t> > temp( new vector<familyid_t>( locs->size(), 0 ) );
00044 this->familyIDs = temp;
00045 vector< shared_ptr<PopObjectAttributeFactory> > families(1);
00046 families[0] = fam0;
00047
00048 populate( families );
00049 id_vec = shr_ptr_vec.get();
00050 }
00051
00052
00053 AugmentedSpatialPopulation::AugmentedSpatialPopulation(vector< shared_ptr<AugmentedSpatialPopulation> > const& pops)
00054 {
00055 if( pops.size() < 1 ) {
00056 throw( PCSIM::ConstructionException( "AugmentedSpatialPopulation::AugmentedSpatialPopulation", "Empty set of populations specified to merge." ) );
00057 }
00058
00059
00060 this->net = &( pops[0]->getNet() );
00061 size_t tot_size = 0;
00062 size_t p;
00063 for( p = 0; p<pops.size(); p++ ) {
00064 tot_size += pops[p]->size();
00065 if( this->net != &( pops[p]->getNet() ) ) {
00066 throw( PCSIM::ConstructionException( "AugmentedSpatialPopulation::AugmentedSpatialPopulation", "Can not merge populations which belong to different networks." ) );
00067 }
00068 }
00069
00070 shared_ptr< vector<familyid_t> > temp( new vector<familyid_t>( tot_size, 0 ) );
00071 this->familyIDs = temp;
00072
00073 shared_ptr< vector<SimObject::ID::Packed> > tmpobj( new vector<SimObject::ID::Packed>( tot_size, 0 ) );
00074 this->shr_ptr_vec = tmpobj;
00075 id_vec = shr_ptr_vec.get();
00076
00077 attributes.resize( tot_size );
00078
00079 vector< Point3D<double> > points( tot_size );
00080 size_t ii=0;
00081 for( p = 0; p<pops.size(); p++ ) {
00082 AugmentedSpatialPopulation* P = pops[p].get();
00083 for( size_t i = 0; i<pops[p]->size(); i++ ) {
00084 (*familyIDs)[ ii ] = P->getFamilyID( i );
00085 (*shr_ptr_vec)[ ii ] = (*(P->shr_ptr_vec))[ i ];
00086 points[ ii ] = P->getLocation( i );
00087
00088 attributes[ ii ] = P->attributes[ i ];
00089
00090 ii++;
00091 }
00092 }
00093
00094 locations = shared_ptr<Point3DSet>( new Point3DSet( points ) );
00095 }
00096
00100 AugmentedSpatialPopulation::~AugmentedSpatialPopulation()
00101 {
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 }
00113
00114
00118 void AugmentedSpatialPopulation::populate( vector< shared_ptr<PopObjectAttributeFactory> > const& families )
00119 {
00120 size_t n = this->locations->size();
00121 SimObject::ID::Vector ids( new vector<SimObject::ID::Packed>(n) );
00122 SimObject::ID id;
00123 familyid_t fid;
00124
00125 attributes.resize(n);
00126
00127 for( size_t i=0; i<n; i++ )
00128 {
00129 fid = (*familyIDs)[i];
00130 families[fid]->announce(*this, i);
00131 net->addObject( *(families[fid]), id );
00132 (*ids)[i] = id.packed();
00133
00134
00135 attributes[ i ].reset(families[fid]->createAttributes(net->getMainConstructRNGEngine()));
00136 }
00137
00138 this->shr_ptr_vec = ids;
00139 }
00140
00141
00142 SimObjectAttributes const& AugmentedSpatialPopulation::getAttributesAt(Point3D<double> const& p) const
00143 {
00144 size_t index = locations->getIndex(p);
00145
00146 return getAttributes(index);
00147 }
00148
00149
00150 SimObjectAttributes const& AugmentedSpatialPopulation::getAttributesAt(double const& x, double const& y, double const& z) const
00151 {
00152 size_t index = locations->getIndex(x, y, z);
00153
00154 return getAttributes(index);
00155 }
00156
00157
00158 SimObjectAttributes const& AugmentedSpatialPopulation::getAttributes(size_t index) const
00159 {
00160 if (index < 0)
00161 throw( PCSIM::ConstructionException("AugmentedSpatialPopulation::AugmentedSpatialPopulation", "index out of bounds."));
00162
00163 if (index >= attributes.size())
00164 throw( PCSIM::ConstructionException("AugmentedSpatialPopulation::AugmentedSpatialPopulation", "index out of bounds."));
00165
00166 return *( attributes[ index ] );
00167 }
00168
00169
00170 AugmentedSpatialPopulation* AugmentedSpatialPopulation::new_subset( vector< size_t > const& subindices ) const
00171 {
00172 size_t s;
00173 vector<SimObject::ID::Packed> objIDs( subindices.size() );
00174 vector<familyid_t> famIDs( subindices.size() );
00175 vector< shared_ptr<SimObjectAttributes> > attrs( subindices.size() );
00176
00177 for( size_t i=0; i<subindices.size(); i++ ) {
00178 s = subindices[i];
00179 objIDs[i] = (*id_vec)[ s ];
00180 famIDs[i] = (*familyIDs)[ s ];
00181
00182 attrs[i] = attributes[s];
00183 }
00184
00185 return new AugmentedSpatialPopulation( net, objIDs, famIDs, attrs, locations->subset( subindices ) );
00186 }
00187
00189 AugmentedSpatialPopulation::AugmentedSpatialPopulation(
00190 SimNetwork* net,
00191 vector<SimObject::ID::Packed> const& objIDs,
00192 vector<familyid_t> const& famIDs,
00193 vector<shared_ptr<SimObjectAttributes> > const& attrs,
00194 shared_ptr<Point3DSet> locs
00195 )
00196 : SpatialFamilyPopulation( net, objIDs, famIDs, locs )
00197 {
00198 this->attributes = attrs;
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234