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