Ambarlarda Zararlı Böceklere Karşı Fümigasyon ve Koruyucu İlaç Deneme Metodları
Fümigasyon Standart İlaç Deneme Metodu
Genel Prensipler ve Hedef Zararlılar
Fümigasyon denemesi, ambarlarda zararlı olan böcek türlerine karşı gazlı ilaçların etkinliğini değerlendirmek amacıyla yapılır. Bu yöntem, depolanmış ürünlerde bulunan çeşitli gelişme dönemlerindeki (ergin, yumurta, larva, pupa) zararlıları hedef alır.
Deneme Ortamı ve Ekipmanlar
Fümigasyon denemeleri üç farklı ortamda gerçekleştirilebilir:
- Fümigatuvar Ortamı: Özel olarak yapılmış gaz geçirmez fümigatuvarlarda
- Çadır Sistemi: Gaz geçirmez zemin üzerinde gaz geçirmez çadır altında
- Hacim Fümigasyonu: Bulaşık ürünün bulunduğu ortam veya boş ambar gaz geçirmez hale getirildiğinde
Deneme Tasarımı ve İstatistiksel Gereksinimler
Deneme tasarımında şu kriterlere dikkat edilmelidir:
- Deneme Deseni: Eş yapma veya tesadüf parselleri deneme desenleri
- Tekerrür Sayısı: Minimum 4 tekerrür (hata serbestlik derecesi 9'un altına düşmemeli)
- Test Materyali: Her tekerrürde her dönem için en az 25 birey
- Parsel Büyüklüğü: Deneme ortamının büyüklüğüne bağlı olarak belirlenir.
Test Materyali ve Yerleştirme
Test organizmaları, laboratuvarda kültür ortamında yetiştirilen zararlı böceklerin farklı gelişme dönemlerinden (ergin, yumurta, larva, pupa) oluşur. Bu materyaller:
- Tülbent torba, tel kafes veya fümigasyon bastonları içinde
- Ürünün çeşitli derinliklerine veya fümigasyon ortamının 3 farklı düzeyine yerleştirilir
Uygulama Prosedürleri
İlaçlama Yöntemi
Fümigasyon uygulaması iki şekilde yapılabilir: - Gaz sevketmek yoluyla
- Gaz verici preparatın ortama bırakılması
Güvenlik Önlemleri
- Belli süre ortamın kapatılarak gazın etkili yoğunlukta tutulması
- 4-5 saat aralıklarla dedektör ile gaz yoğunluğu kontrolü
- Dış ortamda gaz kaçağı kontrolü
- Deneme ortamına girerken gaz maskesi kullanımı
Uygulama Parametreleri
- Tek uygulama yapılır
- Firmanın önerdiği etkili en düşük doz ve en az iki alt doz test edilir
- Doz hesaplama: preparat/ton veya preparat/m³ olarak
Veri Toplama ve Değerlendirme
Sayım Prosedürleri
- Bulaşık Üründe Deneme: Fümigasyon öncesi ve sonrası 0.5 kg örnekler alınır
- Test Materyali ile Deneme: Fümigasyon süresi sonunda bir kez sayım yapılır
- 24 saat bekleme sonrası ergin, larva, pupa sayımı
- Yumurta ve dane içi gelişen böcekler için gelişme süresi kadar bekleme
Kalite Analizi
- Kuru Meyveler: Kabuk rengi, su aktivitesi, şekerlenme analizi
- Tohumluk Ürünler: Çimlenme testi
- Ürün özelliğine göre spesifik kalite parametrelerinin değerlendirilmesi
Koruyucu Standart İlaç Deneme Metodu
Hedef Zararlılar ve Test Organizması
Koruyucu ilaç denemeleri, depolanmış tahıl ve bakliyat çeşitlerinde zararlı olan böceklere karşı uygulanır. Test organizması olarak:
- Güveler: 1-3 günlük ergin dönem
- Diğer Zararlılar: 1-15 günlük ergin dönem
Deneme Ortamları
Laboratuvar Koşulları
- Lepidoptera'lar: 1000 cm³ cam kavanozlar
- Diğer Zararlılar: 250 cm³ cam kavanozlar
- Kontrollü sıcaklık: 25±1°C
- Kontrollü nem: %60±5
Ambar Koşulları
- 5 kg'lık bez torbalar
- Doğal ambar koşulları
- Bulaşık ambar ortamında yerleştirme
Deneme Tasarımı ve Protokol
İstatistiksel Gereksinimler
- Deneme Deseni: Tesadüf parselleri, eş yapma veya tesadüf blokları
- Tekerrür Sayısı: Eş yapma deseninde minimum 6, diğer desenlerde 4
- Serbestlik Derecesi: 9'un altına düşmemeli
Uygulama Metodları
Laboratuvar Uygulaması: - Ürün sterilizasyonu/fümigasyonu
- Nem değeri ölçümü
- 3 kg'lık partilere ayırma
- İlaç homojen karıştırması (5 dakika çalkalama)
Ambar Uygulaması: - Laboratuvar prosedürü ile aynı ilaçlama
- 5 kg'lık torbalara yerleştirme
- Bulaşık ambar ortamına yerleştirme
- Torba koruyucu ilaçlaması seçeneği
Veri Toplama ve Analiz Protokolü
Sayım Programı
Laboratuvar Koşulları:
- İlaçlamadan 24 saat sonra 50 g örnekler
- 25 adet test böceği ilavesi
- 6 gün bekleme (güveler için 48 saat)
- Aylık tekrar (etki %80 altına düşene kadar)
Özel Mineral Uygulamaları:
- 3, 7, 14, 21, 28 gün sonra sayımlar
- 12 aya kadar koruyuculuk süre testi
Ambar Koşulları:
- 24 saat sonra başlayarak aylık 250 g örnekler
- 6 gün laboratuvar bekletme sonrası sayım
- Diğer zararlılara etki değerlendirmesi
F1 Döl Analizi
- Her sayım sonrası böcekler alınır
- Gelişme süreleri kadar bekleme
- F1 dölünün çıkış zamanına göre koruyuculuk süresi belirleme
İstatistiksel Analiz Yöntemleri
Abbott Formülü
Abbott düzeltmesi, kontroldeki doğal ölüm oranını hesaba katarak gerçek ilaç etkinliğini belirler:
Abbott Düzeltmesi = (Pt - Pc) / (1 - Pc) × 100
Burada:
- Pt: İlaçlı parseldeki ölüm oranı
- Pc: Kontrol parseldeki ölüm oranı
Varyans Analizi (ANOVA)
Mortalite verilerinde arcsine transformasyonu uygulanır:
- Transformasyon: arcsin(√p)
- Çoklu karşılaştırma: Tukey HSD testi
- Önem düzeyi: α = 0.05
Doz-Cevap Analizi
Probit Analizi
Doz-cevap ilişkisinin belirlenmesi için probit modeli kullanılır:
- LD₅₀ ve LD₉₀ değerlerinin hesaplanması
- %95 güven aralıklarının belirlenmesi
- Model uygunluğunun değerlendirilmesi
GLM (Genelleştirilmiş Doğrusal Model)
Binomiyal dağılım varsayımıyla logit link fonksiyonu:
- Delta yöntemiyle güven aralıkları
- Bootstrap yöntemiyle alternatif tahminler
Modern Analiz Yazılımları ve Araçları
Yaygın Kullanılan Yazılımlar
R ve Paketleri
- Agricolae: Tarımsal deneme analizi
- Insectbioassay: Böcek biyolojik denemeleri
- drc: Doz-cevap eğrileri
- ecotox: Ekotoksikolojik analiz
Özel Yazılımlar
- PoloPlus/Polo-PC: Böcek biyolojik denemeleri için özelleşmiş
- ARM (Agricultural Research Manager): Tarla ve laboratuvar denemeleri
- GenStat: Tarım ve biyoloji odaklı analiz
Python Tabanlı Analiz Çözümü
Aşağıda yer alan Python scripti, fümigasyon ve koruyucu ilaç denemeleri için kapsamlı analiz imkanı sunar:
Temel Özellikler
- CSV/Excel veri okuma
- Abbott düzeltmesi hesaplama
- ANOVA ve Tukey HSD testleri
- GLM ve Probit doz-cevap analizi
- LD₅₀/LD₉₀ tahminleri ve güven aralıkları
- Bootstrap analizi
- Özet tablolar ve grafik üretimi
Analiz Akışı - Veri Ön İşleme: Mortalite hesaplamaları ve Abbott düzeltmesi
- Tanımlayıcı Analiz: Muamele bazında özetler
- İstatistiksel Testler: ANOVA ve çoklu karşılaştırmalar
- Doz-Cevap Analizi: LD değerleri ve güven aralıkları
- Rapor Üretimi: Excel çıktıları ve grafikler
fumigation_full_analysis.py
Comprehensive summary-focused analysis for fumigation / protective insecticide trials.
Features:
- read CSV/Excel data
- compute raw and Abbott-corrected mortalities
- summary tables by treatment/dose/time
- arcsine-transform ANOVA and Tukey HSD
- dose-response fits (GLM-logit and Probit), LD50 & LD90 estimates with delta-method CI
- bootstrap CI for LD50 (replicate-level)
- save summarized results into an Excel workbook (sheets for each summary)
- save basic plots (mean mortality, dose-response)
Usage:
from fumigation_full_analysis import run_summary
run_summary('your_data.csv', output_excel='out.xlsx')
Author: generated by Rıdvan
import os
import warnings
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import statsmodels.api as sm
import statsmodels.formula.api as smf
from statsmodels.stats.multicomp import pairwise_tukeyhsd
from statsmodels.genmod.families import Binomial
-------------------------
I/O and helpers
-------------------------
def read_data(path_or_df):
if isinstance(path_or_df, pd.DataFrame):
return path_or_df.copy()
ext = os.path.splitext(path_or_df)[1].lower()
if ext in ('.xls', '.xlsx'):
return pd.read_excel(path_or_df)
return pd.read_csv(path_or_df)
-------------------------
Mortality computations
-------------------------
def compute_mortalities(df, dead_col='dead', alive_col='alive', control_col='control'):
df = df.copy()
if dead_col not in df.columns or alive_col not in df.columns:
raise ValueError("Input data must contain 'dead' and 'alive' columns.")
df['n'] = df[dead_col] + df[alive_col]
df.loc[df['n'] == 0, 'n'] = np.nan
df['mortality_raw'] = df[dead_col] / df['n']
control mortality: per time if 'time' and control column exist else global control
if 'time' in df.columns and control_col in df.columns:
pc_map = df[df.get(control_col, False)].groupby('time')['mortality_raw'].mean().to_dict()
df['pc'] = df['time'].map(pc_map).fillna(0.0)
else:
pc = df[df.get(control_col, False)]['mortality_raw'].mean() if control_col in df.columns and df[control_col].any() else 0.0
df['pc'] = pc
def abbott(pt, pc):
if pd.isna(pt):
return np.nan
if pc >= 1.0:
return np.nan
return (pt - pc) / (1 - pc)
df['mortality_abbott'] = df.apply(lambda r: abbott(r['mortality_raw'], r['pc']), axis=1)
df['mortality_abbott'] = df['mortality_abbott'].clip(lower=0.0, upper=1.0)
return df
-------------------------
Summaries
-------------------------
def summarize_by(df, group_cols=['treatment']):
agg = df.groupby(group_cols).agg(
n_rep=('n', 'count'),
mean_raw=('mortality_raw', 'mean'),
sd_raw=('mortality_raw', 'std'),
mean_abbott=('mortality_abbott', 'mean'),
sd_abbott=('mortality_abbott', 'std')
).reset_index()
return agg
-------------------------
ANOVA and Tukey HSD
-------------------------
def anova_and_tukey(df, response='mortality_abbott', factor='treatment'):
df2 = df.dropna(subset=[response, factor]).copy()
if df2.empty:
return None, None
df2['y_trans'] = np.arcsin(np.sqrt(np.clip(df2[response], 0, 1)))
model = smf.ols(f'y_trans ~ C({factor})', data=df2).fit()
anova_table = sm.stats.anova_lm(model, typ=2)
Tukey HSD
tukey_summary = None
try:
tuk = pairwise_tukeyhsd(df2['y_trans'], df2[factor])
tukey_summary = pd.DataFrame(data=tuk.summary().data[1:], columns=tuk.summary().data[0])
except Exception:
tukey_summary = None
return anova_table, tukey_summary
-------------------------
GLM (logit) dose-response (aggregated)
-------------------------
def fit_glm_binomial_agg(df, dose_col='dose', dead_col='dead', alive_col='alive', transform_log=True):
if dose_col not in df.columns:
raise ValueError('Dose column not found.')
d = df.dropna(subset=[dose_col])
agg = d.groupby(dose_col).apply(lambda g: pd.Series({
'dead': int(g[dead_col].sum()),
'total': int((g[dead_col] + g[alive_col]).sum())
})).reset_index()
agg['prop'] = agg['dead'] / agg['total']
if transform_log and (agg[dose_col] > 0).all():
agg['x'] = np.log(agg[dose_col])
else:
agg['x'] = agg[dose_col].astype(float)
X = sm.add_constant(agg['x'])
model = sm.GLM(agg['dead'], X, family=sm.families.Binomial(), var_weights=agg['total']).fit()
params = model.params
cov = model.cov_params()
results = {}
compute LD50 and LD90 with delta-method CI
for p in (0.5, 0.9):
logit_p = np.log(p / (1 - p))
beta = params.get('x', np.nan)
const = params.get('const', params.get('Intercept', np.nan))
if pd.isna(beta) or beta == 0:
results[f'LD{int(p*100)}'] = np.nan
results[f'LD{int(p*100)}_ci'] = (np.nan, np.nan)
continue
x_p = (logit_p - const) / beta
ld = np.exp(x_p) if transform_log and (agg[dose_col] > 0).all() else x_p
delta-method variance
derivatives: dx/dconst = -1/beta ; dx/dbeta = -(logit_p - const)/beta^2 = -x_p / beta
dvec = np.array([-1.0 / beta, -x_p / (beta)])
cov arrangement: const, x
cov_mat = cov.loc[[list(cov.index)[0], 'x'], [list(cov.index)[0], 'x']].values if 'x' in cov.index else cov.values
safer: select ('const' or 'Intercept') and 'x' if present
try:
if 'const' in cov.index:
cov_mat = cov.loc[['const', 'x'], ['const', 'x']].values
else:
cov_mat = cov.loc[['Intercept', 'x'], ['Intercept', 'x']].values
except Exception:
cov_mat = cov.values
var_x = float(dvec.dot(cov_mat).dot(dvec))
se_x = np.sqrt(var_x) if var_x > 0 else np.nan
z = 1.96
lower_x, upper_x = x_p - z * se_x, x_p + z * se_x
ci = (np.exp(lower_x), np.exp(upper_x)) if transform_log and (agg[dose_col] > 0).all() else (lower_x, upper_x)
results[f'LD{int(p*100)}'] = ld
results[f'LD{int(p*100)}_ci'] = ci
return model, agg, results
-------------------------
Probit model (aggregated)
-------------------------
def fit_probit_agg(df, dose_col='dose', dead_col='dead', alive_col='alive', transform_log=True):
if dose_col not in df.columns:
raise ValueError('Dose column not found.')
d = df.dropna(subset=[dose_col])
agg = d.groupby(dose_col).apply(lambda g: pd.Series({
'dead': int(g[dead_col].sum()),
'total': int((g[dead_col] + g[alive_col]).sum())
})).reset_index()
agg['prop'] = agg['dead'] / agg['total']
if transform_log and (agg[dose_col] > 0).all():
agg['x'] = np.log(agg[dose_col])
else:
agg['x'] = agg[dose_col].astype(float)
X = sm.add_constant(agg['x'])
Probit link via GLM
model = sm.GLM(agg['dead'], X, family=sm.families.Binomial(link=sm.families.links.probit())).fit()
params = model.params
cov = model.cov_params()
results = {}
from scipy import stats
for p in (0.5, 0.9):
q = stats.norm.ppf(p)
beta = params.get('x', np.nan)
const = params.get('const', params.get('Intercept', np.nan))
if pd.isna(beta) or beta == 0:
results[f'LD{int(p*100)}'] = np.nan
results[f'LD{int(p*100)}_ci'] = (np.nan, np.nan)
continue
x_p = (q - const) / beta
ld = np.exp(x_p) if transform_log and (agg[dose_col] > 0).all() else x_p
dvec = np.array([-1.0 / beta, -x_p / beta])
try:
if 'const' in cov.index:
cov_mat = cov.loc[['const', 'x'], ['const', 'x']].values
else:
cov_mat = cov.loc[['Intercept', 'x'], ['Intercept', 'x']].values
except Exception:
cov_mat = cov.values
var_x = float(dvec.dot(cov_mat).dot(dvec))
se_x = np.sqrt(var_x) if var_x > 0 else np.nan
z = 1.96
lower_x, upper_x = x_p - z * se_x, x_p + z * se_x
ci = (np.exp(lower_x), np.exp(upper_x)) if transform_log and (agg[dose_col] > 0).all() else (lower_x, upper_x)
results[f'LD{int(p*100)}'] = ld
results[f'LD{int(p*100)}_ci'] = ci
return model, agg, results
-------------------------
Bootstrap LD50 (replicate-level)
-------------------------
def bootstrap_ld50(df, model_type='probit', dose_col='dose', dead_col='dead', alive_col='alive', n_boot=500, seed=123, transform_log=True):
rng = np.random.default_rng(seed)
if 'replicate' not in df.columns:
df = df.copy()
df['replicate'] = df.groupby(['treatment', dose_col]).cumcount() + 1
groups = df.groupby(['treatment', dose_col])
ld50s = []
for b in range(n_boot):
sampled = []
for (tr, d), g in groups:
idx = rng.choice(g.index, size=len(g), replace=True)
sampled.append(g.loc[idx])
boot_df = pd.concat(sampled, ignore_index=True)
try:
if model_type.lower().startswith('prob'):
_, _, res = fit_probit_agg(boot_df, dose_col=dose_col, dead_col=dead_col, alive_col=alive_col, transform_log=transform_log)
ld = res.get('LD50', np.nan)
else:
_, _, res = fit_glm_binomial_agg(boot_df, dose_col=dose_col, dead_col=dead_col, alive_col=alive_col, transform_log=transform_log)
ld = res.get('LD50', np.nan)
except Exception:
ld = np.nan
ld50s.append(ld)
arr = np.array(ld50s, dtype=float)
arr = arr[~np.isnan(arr)]
if len(arr) == 0:
return np.nan, (np.nan, np.nan)
lower = np.percentile(arr, 2.5)
upper = np.percentile(arr, 97.5)
median = np.median(arr)
return median, (lower, upper)
-------------------------
Plot helpers
-------------------------
def plot_mean_abbott(df, outpath='mean_abbott.png'):
means = df.groupby('treatment')['mortality_abbott'].mean().reset_index()
plt.figure()
plt.bar(means['treatment'], means['mortality_abbott'])
plt.ylabel('Abbott-corrected mortality')
plt.title('Mean Abbott-corrected mortality by treatment')
plt.savefig(outpath, bbox_inches='tight')
plt.close()
return outpath
def plot_dose_response(agg, model, outpath='dose_response.png', transform_log=True, dose_col='dose'):
x = agg['x']
x_grid = np.linspace(x.min(), x.max(), 200)
Xg = sm.add_constant(x_grid)
pred = model.predict(Xg)
if transform_log and (agg[dose_col] > 0).all():
dose_grid = np.exp(x_grid)
else:
dose_grid = x_grid
plt.figure()
plt.plot(dose_grid, pred, label='fitted')
plt.scatter(agg[dose_col], agg['prop'], label='observed')
if transform_log and (agg[dose_col] > 0).all():
try:
plt.xscale('log')
except Exception:
pass
plt.xlabel('dose')
plt.ylabel('mortality proportion')
plt.title('Dose-response curve')
plt.legend()
plt.savefig(outpath, bbox_inches='tight')
plt.close()
return outpath
-------------------------
Main runner
-------------------------
def run_summary(input_path_or_df, output_excel='fumigation_summary.xlsx', generate_plots=True, bootstrap_B=500):
df = read_data(input_path_or_df)
df = compute_mortalities(df)
per_rep = df.copy()
summary_treat = summarize_by(df, ['treatment'])
anova_table, tukey = None, None
try:
anova_table, tukey = anova_and_tukey(df)
except Exception:
anova_table, tukey = None, None
dose_results = {}
if 'dose' in df.columns:
try:
glm_model, glm_agg, glm_res = fit_glm_binomial_agg(df)
dose_results['glm'] = {'model': glm_model, 'agg': glm_agg, 'res': glm_res}
except Exception as e:
dose_results['glm'] = {'error': str(e)}
try:
prob_model, prob_agg, prob_res = fit_probit_agg(df)
dose_results['probit'] = {'model': prob_model, 'agg': prob_agg, 'res': prob_res}
except Exception as e:
dose_results['probit'] = {'error': str(e)}
try:
median_ld50, ci_ld50 = bootstrap_ld50(df, model_type='probit', n_boot=bootstrap_B)
dose_results['bootstrap_ld50'] = {'median': median_ld50, 'ci': ci_ld50}
except Exception as e:
dose_results['bootstrap_ld50'] = {'error': str(e)}
write Excel
with pd.ExcelWriter(output_excel, engine='xlsxwriter') as writer:
per_rep.to_excel(writer, sheet_name='per_replicate', index=False)
summary_treat.to_excel(writer, sheet_name='summary_by_treatment', index=False)
if anova_table is not None:
anova_table.to_excel(writer, sheet_name='anova')
if tukey is not None:
tukey.to_excel(writer, sheet_name='tukey_hsd', index=False)
if 'glm' in dose_results and 'agg' in dose_results['glm']:
dose_results['glm']['agg'].to_excel(writer, sheet_name='glm_dose_agg', index=False)
if 'probit' in dose_results and 'agg' in dose_results['probit']:
dose_results['probit']['agg'].to_excel(writer, sheet_name='probit_dose_agg', index=False)
LD estimates
ldrows = []
if 'glm' in dose_results and 'res' in dose_results['glm'] and isinstance(dose_results['glm']['res'], dict):
for k, v in dose_results['glm']['res'].items():
if 'LD' in k:
ldrows.append({'model': 'glm', 'parameter': k, 'value': v})
if 'probit' in dose_results and 'res' in dose_results['probit'] and isinstance(dose_results['probit']['res'], dict):
for k, v in dose_results['pro