def add_missing_station(self, cnn, clusters, stations, stn_diff): # this method does not update the labels because they are not used # labels are only used to tie station # find the station objects for the elements listed in stn_diff stnobj_diff = [ s for s in stations if s.NetworkCode + '.' + s.StationCode in stn_diff ] tqdm.write(' -- Adding missing stations %s' % ' '.join(stn_diff)) if len(clusters['centroids']) == 1: # single station network, just add the missing station clusters['stations'][0] += stnobj_diff clusters['labels'] = np.zeros(len(clusters['stations'][0])) # because a station was added, delete the gamit_stats record to force reprocessing cnn.delete('gamit_stats', Project=self.name, Year=self.date.year, DOY=self.date.doy, subnet=0) cnn.delete('gamit_subnets', Project=self.name, Year=self.date.year, DOY=self.date.doy, subnet=0) else: for stn in stnobj_diff: # find the closest centroid to this station xyz = np.zeros((1, 3)) xyz[0] = np.array([stn.X, stn.Y, stn.Z]) sd = distance.cdist(xyz, clusters['centroids']) / 1e3 for i in range(len(clusters['centroids'])): s = smallestN_indices(sd, len(clusters['centroids']))[i] if sd[s[0], s[1]] <= MAX_DIST: # can add the station to this sub-network clusters['stations'][i].append(stn) # because a station was added, delete the gamit_stats and subnets record to force reprocessing cnn.delete('gamit_stats', Project=self.name, Year=self.date.year, DOY=self.date.doy, subnet=i + 1) cnn.delete('gamit_subnets', Project=self.name, Year=self.date.year, DOY=self.date.doy, subnet=i + 1) return clusters
def add_missing_station(self, cnn, clusters, add_station): # this method does not update the labels because they are not used # labels are only used to tie station if len(clusters['centroids']) == 1: # single station network, just add the missing station clusters['stations'][0].append(add_station) clusters['labels'] = np.zeros(len(clusters['stations'][0])) # because a station was added, delete the gamit_stats record to force reprocessing cnn.delete('gamit_stats', Project=self.name, Year=self.date.year, DOY=self.date.doy, subnet=0) cnn.delete('gamit_subnets', Project=self.name, Year=self.date.year, DOY=self.date.doy, subnet=0) tqdm.write(' -- %s was not originally in the processing, will be added to sub-network %s00' % (add_station.netstn, self.org)) else: # find the closest centroid to this station xyz = np.zeros((1, 3)) xyz[0] = np.array([add_station.X, add_station.Y, add_station.Z]) sd = distance.cdist(xyz, clusters['centroids']) / 1e3 for i in range(len(clusters['centroids'])): s = smallestN_indices(sd, len(clusters['centroids']))[i] if sd[s[0], s[1]] <= MAX_DIST: # can add the station to this sub-network clusters['stations'][i].append(add_station) # because a station was added, delete the gamit_stats and subnets record to force reprocessing cnn.delete('gamit_stats', Project=self.name, Year=self.date.year, DOY=self.date.doy, subnet=i + 1) cnn.delete('gamit_subnets', Project=self.name, Year=self.date.year, DOY=self.date.doy, subnet=i + 1) tqdm.write(' -- %s was not originally in the processing, will be added to sub-network %s%02i' % (add_station.netstn, self.org, i + 1)) break return clusters
def tie_subnetworks(points, clusters, stations): # get centroids and lables centroids = clusters['centroids'] labels = clusters['labels'] # calculate distance between centroids dist = distance.cdist(centroids, centroids) / 1e3 # variable to keep track of the number of ties for each subnetwork ties = np.zeros((centroids.shape[0], centroids.shape[0])) # make distance to self centroid infinite dist[dist == 0] = np.inf ties_vector = [[] for _ in range(len(centroids))] for c in range(len(centroids)): # get the closest three centroids to find the closest subnetworks neighbors = np.argsort(dist[:, c]) # check that there are less than 3 ties if sum(ties[c, :]) < 3: # for each neighbor for n in neighbors: # only enter if not already tied AND ties of n < 3, unless ties c < 2 AND n != c if ties[n, c] == 0 and (np.sum(ties[n, :]) < 3 or np.sum(ties[c, :]) < 2) and n != c: # to link to this neighbor, it has to have less then 3 ties. Otherwise continue to next # print 'working on net ' + str(c) + ' - ' + str(n) # get all stations from current subnet and dist to each station of neighbor n sd = distance.cdist(points[labels == c], points[labels == n]) / 1e3 # find the 4 closest stations tie_c = [] tie_n = [] for i in range(len(sd)): s = smallestN_indices(sd, len(sd))[i] # ONLY ALLOW TIES BETWEEN MIN_DIST AND MAX_DIST. Also, tie stations should be > MIN_DIST # from stations on the other subnetwork if MIN_DIST <= sd[s[0], s[1]] <= MAX_DIST and np.all(sd[s[0], :] > MIN_DIST) \ and np.all(sd[:, s[1]] > MIN_DIST): # print ' pair: ' + str([st for la, st in zip(labels.tolist(), stations) # if la == n][s[1]])\ # + ' - ' + str([st for la, st in zip(labels.tolist(), # stations) if la == c][s[0]]) + ' ( %.1f' % sd[s[0], s[1]] + ' km)' # station objects: # find the stations that have labels == (c, n) and from that subset, find the row (c) # and col (n) obtained by smallestN_indices tie_c += [[st for la, st in zip(labels.tolist(), stations) if la == n][s[1]]] tie_n += [[st for la, st in zip(labels.tolist(), stations) if la == c][s[0]]] # make these distances infinite to avoid selecting again sd[s[0], :] = np.inf sd[:, s[1]] = np.inf if len(tie_c) == 4: break # if successfully added 3 or more tie stations, then declared it tied if len(tie_c) >= 3: # add a tie to c and n subnets ties[n, c] += 1 ties[c, n] += 1 ties_vector[c] += tie_c ties_vector[n] += tie_n # print ties else: # print ' no suitable ties found between these two networks' pass if sum(ties[c, :]) >= 3: # if current subnet already has 3 ties, continue to next one break # return the vector with the station objects representing the ties return ties_vector