manuelcampagnolo / S2CHANGE

1 stars 0 forks source link

Paralelizar a execução do ccd.detect após carregar valores com XArray #17

Closed danielm09 closed 6 months ago

danielm09 commented 6 months ago

Olá.

Penso que essa parte do código poderia ser paralelizada, com um simples thread pool, conforme fazíamos na versão anterior do código.

@scaetano1997 vê se consegue parelelizar, pois calculo que vamos ganhar muito tempo.

A partir da linha 182:

for i in tqdm(range(selection.shape[2])):
    ponto = sel_values[:,:,i]
    dates = selection.time

    ponto_desejado=selection.x[i],selection.y[i]

    ponto_with_dates = np.column_stack((dates, ponto[:, 0], ponto[:, 1:]))

    mask = (ponto_with_dates != NODATA_VALUE).all(axis=1)
    ponto_with_dates_filtered = ponto_with_dates[mask].transpose()

    dates, blues, greens, reds, nirs, swir1s, swir2s = ponto_with_dates_filtered

    ndvis = np.where((nirs + reds) > 0, 10000 * (nirs - reds) / (nirs + reds), NODATA_VALUE)

    ponto_with_dates_filtered[1]=ndvis

    ponto_with_dates_filtered1=ponto_with_dates_filtered.transpose()

    ponto_with_dates_filtered2 = ponto_with_dates_filtered1[~np.any(ponto_with_dates_filtered1 == NODATA_VALUE, axis=1)]

    ponto_with_dates_filtered3=ponto_with_dates_filtered2.transpose()

    dates, ndvis, greens, reds, nirs, swir1s, swir2s = ponto_with_dates_filtered3

    results = ccd.detect(dates, ndvis, greens, reds, nirs, swir1s, swir2s)

    predicted_values = []
    prediction_dates = []
    break_dates = []
    start_dates = []
    end_dates=[]
    # coeficientes=[]
    prob=[]

    for num, result in enumerate(results['change_models']):
        days = np.arange(result['start_day'], result['end_day'] + 1)
        prediction_dates.append(days)
        break_dates.append(result['break_day'])
        start_dates.append(result['start_day'])
        end_dates.append(result['end_day'])
        prob.append(result['change_probability'])

        intercept = result['blue']['intercept']
        coef = result['blue']['coefficients']

        predicted_values.append(intercept + coef[0] * days +
                                coef[1]*np.cos(days*1*2*np.pi/365.25) + coef[2]*np.sin(days*1*2*np.pi/365.25) +
                                coef[3]*np.cos(days*2*2*np.pi/365.25) + coef[4]*np.sin(days*2*2*np.pi/365.25) +
                                coef[5]*np.cos(days*3*2*np.pi/365.25) + coef[6]*np.sin(days*3*2*np.pi/365.25))

    ndvi_magnitudes = [predicted_values[num][-1] - predicted_values[num + 1][0] for num in range(len(predicted_values) - 1)]

    # Se não houver mais segmentos a seguir adiciona NODATA_VALUE se só existir um segmento adiciona 0
    ndvi_magnitudes.append(65535 if ndvi_magnitudes and any(ndvi_magnitudes) else 0)

    datas = [datetime.fromordinal(data) for data in break_dates]
    break_dates_epoch = [int(data.replace(tzinfo=timezone.utc).timestamp() * 1000) for data in datas]

    datas = [datetime.fromordinal(data) for data in start_dates]
    start_dates_epoch = [int(data.replace(tzinfo=timezone.utc).timestamp() * 1000) for data in datas]

    datas = [datetime.fromordinal(data) for data in end_dates]
    end_dates_epoch = [int(data.replace(tzinfo=timezone.utc).timestamp() * 1000) for data in datas]

    ponto_desejado_wgs = convertPointToCrs(ponto_desejado, 32629, 4326)

    ponto_desejado_wgs_x, ponto_desejado_wgs_y = ponto_desejado_wgs

    dados = [
        {'tBreak': break_dates_epoch,'tEnd': end_dates_epoch,'tStart':start_dates_epoch,'changeProb':prob, 'Lat': ponto_desejado_wgs_y,'Lon': ponto_desejado_wgs_x, 'ndvi_magnitude' : ndvi_magnitudes}
    ]

    df = pd.DataFrame(dados)

    # Reorganizar colunas
    ordem_colunas = ['tBreak', 'tEnd', 'tStart', 'changeProb', 'Lat', 'Lon', 'ndvi_magnitude']
    df=df[ordem_colunas]
    df_result.append(df)