Changeset 1953 for trunk/MagicSoft/Cosy/main/MCosy.cc
- Timestamp:
- 04/12/03 19:06:27 (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/MagicSoft/Cosy/main/MCosy.cc
r1819 r1953 13 13 14 14 #include <TH2.h> 15 #include <TH3.h> 15 16 #include <TProfile.h> 16 17 #include <TCanvas.h> … … 76 77 } 77 78 79 /* 78 80 ZdAz MCosy::CorrectTarget(const ZdAz &src, const ZdAz &dst) 79 81 { … … 145 147 return ret*(16384.0/360.0); 146 148 } 149 */ 147 150 148 151 // -------------------------------------------------------------------------- … … 329 332 { 330 333 // FIXME, what when waiting times out (Zombie) 334 331 335 while ((fMac1->IsPositioning() || fMac2->IsPositioning()) && 332 !(Break() || HasError() ) && !HasZombie())336 !(Break() || HasError() || HasZombie())) 333 337 usleep(1); 334 338 335 339 if (Break() || HasError() || HasZombie()) 336 lout << "WaitForEndMovement aborted..." << endl; 340 { 341 lout << "WaitForEndMovement aborted... "; 342 if (Break()) 343 lout << "Break signal." << endl; 344 if (HasError()) 345 lout << "Network has error." << endl; 346 if (HasZombie()) 347 lout << "Network has zombie." << endl; 348 } 337 349 } 338 350 … … 382 394 } 383 395 396 Bool_t MCosy::CheckRange(const ZdAz &d) const 397 { 398 // d [deg] 399 400 if (d.Zd()<fMin.Zd() || d.Zd()>fMax.Zd()) 401 { 402 lout << "ERROR: Requested Zenith Angle (" << d.Zd() << "deg) not "; 403 lout << "inside allowed range." << endl; 404 return kFALSE; 405 } 406 407 if (d.Az()<fMin.Az() || d.Az()>fMax.Az()) 408 { 409 lout << "ERROR: Requested Azimuth Angle (" << d.Az() << "deg) not "; 410 lout << "inside allowed range." << endl; 411 return kFALSE; 412 } 413 414 return kTRUE; 415 } 416 384 417 // -------------------------------------------------------------------------- 385 418 // … … 396 429 { 397 430 // FIXME: Correct by fOffset ? 398 /*399 ZdAz400 401 if (dst.Az()<-TMath::Pi()/2)402 dst.Az(dst.Az() + TMath::Pi()*2);403 404 if (dst.Az()>3*TMath::Pi()/2)405 dst.Az(dst.Az() -TMath::Pi()*2);406 */407 // track=kFALSE;408 409 // const ZdAz d1 = track ? CorrectTarget(src, dst) : dst*16384/TMath::Pi()/2; // [se]410 431 411 432 const ZdAz d = dst*kRad2Deg; … … 413 434 lout << "Target Position: " << d.Zd() << "deg, " << d.Az() << "deg (Zd/Az)" << endl; 414 435 415 if (d.Zd()<fMin.Zd() || d.Zd()>fMax.Zd()) 416 { 417 lout << "ERROR: Requested Zenith Angle (" << d.Zd() << "deg) not "; 418 lout << "inside allowed range." << endl; 436 if (!CheckRange(d)) 419 437 return kFALSE; 420 }421 422 if (d.Az()<fMin.Az() || d.Az()>fMax.Az())423 {424 lout << "ERROR: Requested Azimuth Angle (" << d.Az() << "deg) not ";425 lout << "inside allowed range." << endl;426 return kFALSE;427 }428 438 429 439 // … … 520 530 cout << "Estimated1: " << 16384*dx + dk << endl; 521 531 cout << "Estimated2: " << (16384*dx + dk)/1.085949688 << endl; 532 cout << "Estimated3: " << rd.Zd()*432 << endl; 522 533 // =========================================== 523 534 … … 775 786 } 776 787 788 Bool_t MCosy::AlignTrackingPos(ZdAz pointing, ZdAz &za) 789 { 790 // pointing [deg] 791 792 if (pointing.Zd()<0) 793 { 794 pointing.Zd(-pointing.Zd()); 795 pointing.Az(pointing.Az()+180); 796 } 797 798 const ZdAz se = GetSePos()*360/16384; // [deg] 799 const ZdAz unbendedse = fBending.CorrectBack(se); // ist pointing 800 801 do 802 { 803 const Double_t d = unbendedse.Az() - pointing.Az(); 804 if (d>-180 && d<=180) 805 break; 806 807 pointing.Az(pointing.Az()+TMath::Sign(360., -d)); 808 } while (1); 809 /* 810 while (pointing.Az()<fMin.Az()) 811 pointing.Az(pointing.Az() + 360); 812 813 while (pointing.Az()>fMax.Az()) 814 pointing.Az(pointing.Az() - 360); 815 */ 816 const Bool_t rc = CheckRange(pointing); 817 za = fBending(pointing/kRad2Deg); // [rad] 818 819 if (!rc) 820 lout << "Error: Aligned position out of Range." << endl; 821 822 return rc; 823 } 824 777 825 void MCosy::TrackPosition(const RaDec &dst) // ra, dec [rad] 778 826 { … … 787 835 ZdAz dest = sla.CalcZdAz(dst); 788 836 837 // FIXME: Determin tracking start point by star culmination 789 838 if (dest.Az()<-TMath::Pi()/2) 839 { 840 lout << "Adding 360deg to Azimuth " << dest.Az()*kRad2Deg << endl; 790 841 dest.Az(dest.Az() + TMath::Pi()*2); 842 } 791 843 792 844 if (dest.Az()>3*TMath::Pi()/2) 845 { 846 lout << "Substracting 360deg to Azimuth " << dest.Az()*kRad2Deg << endl; 793 847 dest.Az(dest.Az() -TMath::Pi()*2); 848 } 794 849 795 850 if (!SetPosition(dest, kTRUE)) … … 849 904 // 850 905 // *OLD*const float dt = 1; // 1 second 851 const float dt = 3; // 2 second852 while (!(Break() || HasError() ) && !HasZombie())906 const float dt = 5;//3; // 2 second 907 while (!(Break() || HasError() || HasZombie())) 853 908 { 854 909 // … … 860 915 // Request theoretical Position for a time in the future (To+dt) from CPU 861 916 // 862 sla.SetMjd(sla.GetMjd()+dt/(60*60*24)); 917 const Double_t mjd = sla.GetMjd()+dt/(60*60*24); 918 const ZdAz pointing = sla.CalcZdAz(fRaDec, mjd)*kRad2Deg; // soll pointing [deg] 919 920 ZdAz dest; 921 if (!AlignTrackingPos(pointing, dest)) 922 break; 923 924 dest *= 16384/TMath::Pi()/2; // [se] 925 926 /* 863 927 ZdAz dummy1 = sla.CalcZdAz(fRaDec); 864 928 … … 868 932 dummy1.Az(dummy1.Az() -TMath::Pi()*2); 869 933 934 if (!CheckRange(dummy1*kRad2Deg)) 935 { 936 lout << "Error: Tracking position out of Range." << endl; 937 break; 938 } 939 870 940 ZdAz dummy = fBending(dummy1); 871 941 dest = CorrectTarget(GetSePos(), dummy); // [se] 872 873 const ZdAz d = dest*360./16384; // [deg] 942 */ 943 944 //*LP* const ZdAz d = dest*360./16384; // [deg] 874 945 dest *= kGearRatio; // [re] 875 946 876 ZdAz min = fBending(fMin/kRad2Deg)*kRad2Deg; 877 ZdAz max = fBending(fMax/kRad2Deg)*kRad2Deg; 878 879 /* 880 if (d.Zd()<min.Zd() || d.Az()<min.Az()) 881 { 882 lout << "ERROR: Calculated position for T+dt not inside allowed range." << endl; 883 lout << "< " << d.Zd() << " " << min.Zd() << " " << d.Az() << " " << min.Az() << endl; 884 break; 885 } 886 if (d.Zd()>max.Zd() || d.Az()>max.Az()) 887 { 888 lout << "ERROR: Calculated position for T+dt not inside allowed range." << endl; 889 lout << "> " << d.Zd() << " " << max.Zd() << " " << d.Az() << " " << max.Az() << endl; 890 break; 891 } 892 */ 947 //*LP* ZdAz min = fBending(fMin/kRad2Deg)*kRad2Deg; 948 //*LP* ZdAz max = fBending(fMax/kRad2Deg)*kRad2Deg; 949 893 950 ZdAz vcalc = sla.GetApproxVel(fRaDec) * kGearRatio2*4./60.; // [re/min] 894 951 … … 963 1020 // (This is important on fast machines >500MHz) 964 1021 // 965 usleep( 50000); // 0.25s1022 usleep(1000000); // 1s 966 1023 //usleep(50000); // 0.05s 967 1024 } … … 989 1046 // set deceleration to 50% 990 1047 // 991 cout << "Stopping movement (dec= 20%)..." << endl;1048 cout << "Stopping movement (dec=30%)..." << endl; 992 1049 993 1050 fMac1->SetDeceleration(0.3*fMac1->GetVelRes()); … … 1103 1160 StopMovement(); 1104 1161 return NULL; 1105 1162 /* 1106 1163 case WM_PRESET: 1107 1164 cout << "WM_Preset: start." << endl; … … 1113 1170 cout << "WM_Preset: done. (return 0xaffe)" << endl; 1114 1171 return (void*)0xaffe; 1115 1172 */ 1173 /* 1116 1174 case WM_CALIB: 1117 1175 { … … 1126 1184 1127 1185 //RaDec rd(37.94, 89.2644); // POLARIS 1128 //RaDec rd(213.915417, 19.1825); // A CTURUS1186 //RaDec rd(213.915417, 19.1825); // ARCTURUS 1129 1187 1130 1188 cout << "Calibrating to: " << rd.Ra()*24/360 << "h " << rd.Dec() << "°" << endl; … … 1144 1202 } 1145 1203 return (void*)0xaffe; 1204 */ 1146 1205 1147 1206 case WM_TPOINT: … … 1170 1229 } 1171 1230 return (void*)0xca1b; 1231 1232 case WM_TRACKPOS: 1233 cout << "WM_TrackPosition: start." << endl; 1234 { 1235 if (!CheckNetwork()) 1236 return (void*)0xebb0; 1237 1238 ZdAz dest = *((ZdAz*)mp) * kDeg2Rad; 1239 //if (!SetPosition(dest)) 1240 // return (void*)0x1234; 1241 1242 SlaStars sla(fObservatory); 1243 sla.Now(); 1244 1245 RaDec rd = sla.CalcRaDec(dest); 1246 cout << dest.Zd()*180/3.1415 << " " << dest.Az()*180/3.1415 << endl; 1247 cout << rd.Ra()*12/3.1415 << " " << rd.Dec()*180/3.1415 << endl; 1248 TrackPosition(rd); 1249 } 1250 cout << "WM_TrackPosition: done. (return 0xabcd)" << endl; 1251 return (void*)0xabcd; 1172 1252 1173 1253 case WM_POSITION: … … 1273 1353 RaDec rd(xy.X()*15., xy.Y()); // [deg] 1274 1354 1275 ZdAz a0 = sla.CalcZdAz(rd*kDeg2Rad); 1276 ZdAz a1 = fBending(a0); 1277 ZdAz se = CorrectTarget(GetSePos(), a1); 1278 a0 *= kRad2Deg; 1279 a1 *= kRad2Deg; 1280 ZdAz a2 = a1*16384/360; 1355 const ZdAz a0 = sla.CalcZdAz(rd*kDeg2Rad); 1356 1357 ZdAz a1; 1358 AlignTrackingPos(a0, a1); 1359 a1 *= 180/TMath::Pi(); 1360 1361 const ZdAz a2 = a1*16384/360; 1362 const ZdAz se = a0*16384/360; 1363 1281 1364 cout << "Ra/Dec source: " << xy.X() << "h " << xy.Y() << "°" << endl; 1282 cout << "Zd/Az source: " << a0.Zd() << "° " << a0.Az() << "°" << endl;1365 cout << "Zd/Az target: " << a0.Zd() << "° " << a0.Az() << "°" << endl; 1283 1366 cout << "Zd/Az bended: " << a1.Zd() << "° " << a1.Az() << "°" << endl; 1367 cout << "SE target: " << se.Zd() << " " << se.Az() << endl; 1284 1368 cout << "SE bended: " << a2.Zd() << " " << a2.Az() << endl; 1285 cout << "SE target: " << se.Zd() << " " << se.Az() << endl;1286 1369 } 1287 1370 return (void*)0xa17a; … … 1401 1484 1402 1485 SlaStars sla(fObservatory); 1486 sla.Now(); 1403 1487 1404 1488 ZdAz old; 1405 ZdAz ist; 1406 1407 ZdAz sollzd; 1408 ZdAz sollaz; 1409 1410 ZdAz istre = -fOffset; // [re] 1489 ZdAz ist = GetSePos(); // [se] 1490 1491 // ZdAz istre = -fOffset; // [re] 1411 1492 ZdAz time; 1493 1494 ZdAz sollzd = sla.CalcZdAz(fRaDec); // [rad] 1495 ZdAz sollaz = sollzd; // [rad] 1412 1496 1413 1497 // … … 1456 1540 continue; 1457 1541 */ 1458 istre = GetRePosPdo();1542 ZdAz istre = GetRePosPdo(); 1459 1543 1460 1544 // … … 1479 1563 if (phca1 || phca2 /*(int)ist.Zd() != (int)old.Zd()*/) 1480 1564 { 1481 s la.SetMjd(time.Zd());1482 1565 sollzd = sla.CalcZdAz(fRaDec, time.Zd()); // [rad] 1566 /* 1483 1567 ZdAz dummy = fBending(sla.CalcZdAz(fRaDec)); 1484 1568 sollzd = CorrectTarget(ist, dummy); // [se] 1485 1569 */ 1486 1570 fOffset.Zd(fOffset.Zd()*(1.-weight)+(ist.Zd()*kGearRatio.X()-istre.Zd())*weight); 1487 1571 } … … 1489 1573 if (phcaz /*(int)ist.Az() != (int)old.Az()*/) 1490 1574 { 1491 s la.SetMjd(time.Az());1492 1575 sollaz = sla.CalcZdAz(fRaDec, time.Az()); // [rad] 1576 /* 1493 1577 ZdAz dummy = fBending(sla.CalcZdAz(fRaDec)); 1494 1578 sollaz = CorrectTarget(ist, dummy); // [se] 1495 1579 */ 1496 1580 fOffset.Az(fOffset.Az()*(1.-weight)+(ist.Az()*kGearRatio.Y()-istre.Az())*weight); 1497 1581 } 1498 1582 1499 ZdAz soll(sollzd.Zd(), sollaz.Az()); // [se] 1583 ZdAz soll(sollzd.Zd(), sollaz.Az()); // [rad] 1584 1585 AlignTrackingPos(soll*360/16384, fZdAzSoll); 1586 /* 1500 1587 fZdAzSoll = fBending.CorrectBack(soll*2*TMath::Pi()/16384); 1501 1588 1502 fTrackingError.Set((ist.Zd()-sollzd.Zd())*kGearRatio.X(), 1503 (ist.Az()-sollaz.Az())*kGearRatio.Y()); 1589 // FIXME? 1590 if (fZdAzSoll.Az()<-TMath::Pi()/2) 1591 fZdAzSoll.Az(fZdAzSoll.Az() + TMath::Pi()*2); 1592 if (fZdAzSoll.Az()>3*TMath::Pi()/2) 1593 fZdAzSoll.Az(fZdAzSoll.Az() -TMath::Pi()*2); 1594 1595 // FIXME? 1596 while (ist.Az()>3*16384/4/2) 1597 ist.Az(ist.Az() - 16384); 1598 while (soll.Az()>3*16384/4/2) 1599 soll.Az(soll.Az() - 16384); 1600 while (ist.Az()<-16384/4) 1601 ist.Az(ist.Az() + 16384); 1602 while (soll.Az()<-16384/4) 1603 soll.Az(soll.Az() + 16384); 1604 */ 1605 ist *= TMath::Pi()*2/16384; 1606 fTrackingError.Set(ist.Zd()-fZdAzSoll.Zd(), ist.Az()-fZdAzSoll.Az()); 1504 1607 1505 1608 //--- fout << setprecision(15) << setw(17) << time.Zd()*60.*60.*24. << " "; … … 1586 1689 } 1587 1690 1588 // fHist = new TH2F("Gear", "Gear Ratio Re/Se", 1589 // 201, fMin.Zd(), fMax.Zd(), 61, 349.5, 500.5); 1590 fHist = new TH2F("Gear", "Gear Ratio Re/Se", 1591 201, fMin.Az(), fMax.Az(), 61, 419.5, 570.5); 1592 fHist->SetXTitle("ZA [\\circ]"); 1593 fHist->SetYTitle("Re/Se"); 1691 fHist = new TH3F("Gear", "Gear Ratio Re/Se", 1692 (int)((fMax.Zd()-fMin.Zd())/2.5+1), fMin.Zd(), fMax.Zd(), 1693 (int)((fMax.Az()-fMin.Az())/2.5+1), fMin.Az(), fMax.Az(), 1694 61, 349.5, 500.5); 1695 1696 fHist->SetXTitle("Zd [\\circ]"); 1697 fHist->SetYTitle("Az [\\circ]"); 1698 fHist->SetZTitle("Re/Se"); 1594 1699 1595 1700 lout << "Starting Gear determination..." << endl; … … 1614 1719 ZdAz dre = re-re0; 1615 1720 1616 if (fabs(dse.Zd())*144>16384) // Each 2.5deg 1721 if (fabs(dse.Zd())*144>16384) // Each 2.5deg (144) 1617 1722 { 1618 1723 se0.Zd(se.Zd()); … … 1620 1725 1621 1726 ZdAz bend = fBending.CorrectBack(se*2*TMath::Pi()/16384)*kRad2Deg; 1622 fHist->Fill(bend.Zd(), dre.Zd()/dse.Zd());1727 ((TH3*)fHist)->Fill(bend.Zd(), bend.Az(), dre.Zd()/dse.Zd()); 1623 1728 } 1624 1729 1625 if (fabs(dse.Az())*144>16384) // Each 2.5deg 1730 if (fabs(dse.Az())*144>16384) // Each 2.5deg (144) 1626 1731 { 1627 1732 se0.Az(se.Az()); … … 1629 1734 1630 1735 ZdAz bend = fBending.CorrectBack(se*2*TMath::Pi()/16384)*kRad2Deg; 1631 fHist->Fill(bend.Az(), dre.Az()/dse.Az()); 1632 1633 cout << bend.Az() << ": " << dre.Az()/dse.Az() << endl; 1736 ((TH3*)fHist)->Fill(bend.Az(), bend.Az(), dre.Az()/dse.Az()); 1634 1737 } 1635 1636 /*1637 const Double_t pos[3] = {1638 (fZd1->GetPos()+8192)%16384,1639 (fZd2->GetPos()+8192)%16384,1640 fAz->GetPos() };1641 1642 //1643 // Estimate Offset from the first ten positions1644 //1645 if (cnt++<10)1646 {1647 offset += pos[0]+pos[1];1648 continue;1649 }1650 if (cnt==11)1651 {1652 offset /= 10;1653 cnt++;1654 }1655 1656 Double_t apos = (pos[0]-pos[1])/2 * TMath::Pi()*2 / 16384;1657 1658 ZdAz bend = fBending.CorrectBack(ZdAz(apos, pos[2]))*kRad2Deg;1659 fHistTestSe->Fill(bend.Zd(), pos[0]+pos[1]-offset);1660 */1661 1738 } 1662 1739 lout << "Gear Test Stopped... displaying Histogram." << endl; … … 1748 1825 lout.UpdateGui(); 1749 1826 1750 fWin->Update(bendist*(360.0/2/TMath::Pi()), fTrackingError /kGearRatio2,1827 fWin->Update(bendist*(360.0/2/TMath::Pi()), fTrackingError, 1751 1828 fVelocity, fOffset, fRaDec, fZdAzSoll, fStatus, avail); 1752 1753 /*1754 cout << (int)(fMac1->GetStatus()&Macs::kOutOfControl) << " ";1755 cout << (int)(fMac2->GetStatus()&Macs::kOutOfControl) << " ";1756 cout << (int)(fMac3->GetStatus()&Macs::kOutOfControl) << endl;1757 */1758 1829 1759 1830 const Bool_t trigger = fTriggerDisplay; … … 1773 1844 lout << "Displaying histogram..." << endl; 1774 1845 1775 TH2F &hist = * fHist;1846 TH2F &hist = *(TH2F*)fHist; 1776 1847 1777 1848 if (del) … … 1796 1867 TH1F p2("spread", "Spread of the differences", hist.GetNbinsX(), hist.GetBinLowEdge(1), 1797 1868 hist.GetBinLowEdge(hist.GetNbinsX()+1)); 1798 p2.SetXTitle("Z A[\\circ]");1869 p2.SetXTitle("Zd [\\circ]"); 1799 1870 for (int i=0; i<hist.GetNbinsX(); i++) 1800 1871 p2.SetBinError(i, p->GetBinError(i)); … … 1811 1882 lout << "Displaying histogram..." << endl; 1812 1883 1813 TH 2F &hist = *fHist;1884 TH3F &hist = *(TH3F*)fHist; 1814 1885 1815 1886 if (del) … … 1820 1891 1821 1892 TCanvas *c=new TCanvas("c1", "", 1000, 1000); 1822 c->Divide(1,2); 1893 c->Divide(2,2); 1894 1895 // ---------- 1823 1896 1824 1897 c->cd(1); 1825 TH2 *h=(TH2*)hist.DrawCopy(); 1826 1827 TProfile *p = h->ProfileX("_pfx", -1, 9999, "s"); 1828 p->SetLineColor(kBlue); 1829 p->Draw("same"); 1830 p->SetBit(kCanDelete); 1898 TH2D &h1=*(TH2D*)hist.Project3D("zx"); // Zd 1899 h1.SetTitle(" Gear Ratio Zenith Distance [re/se] "); 1900 h1.SetXTitle("Zd [\\circ]"); 1901 h1.Draw(); 1902 h1.SetBit(kCanDelete); 1903 1904 TProfile *p1 = h1.ProfileX("_pfx", -1, 9999, "s"); 1905 p1->SetLineColor(kBlue); 1906 p1->Draw("same"); 1907 p1->SetBit(kCanDelete); 1908 1909 // ---------- 1831 1910 1832 1911 c->cd(2); 1833 1834 TH1F p2("spread", "Spread of the gear [16384/1500/4*U/U]", hist.GetNbinsX(), hist.GetBinLowEdge(1), 1835 hist.GetBinLowEdge(hist.GetNbinsX()+1)); 1836 p2.SetXTitle("ZA [\\circ]"); 1837 for (int i=0; i<hist.GetNbinsX(); i++) 1838 p2.SetBinError(i, p->GetBinError(i)); 1839 p2.SetLineColor(kRed); 1840 p2.SetStats(0); 1841 p2.DrawCopy(); 1912 TH2D &h2=*(TH2D*)hist.Project3D("zy"); // Az 1913 h2.SetTitle(" Gear Ratio Azimuth [re/se] "); 1914 h2.SetXTitle("Zd [\\circ]"); 1915 h2.Draw(); 1916 h2.SetBit(kCanDelete); 1917 1918 TProfile *p2 = h2.ProfileX("_pfx", -1, 9999, "s"); 1919 p2->SetLineColor(kBlue); 1920 p2->Draw("same"); 1921 p2->SetBit(kCanDelete); 1922 1923 // ---------- 1924 1925 c->cd(3); 1926 1927 TAxis &axe1 = *h1.GetXaxis(); 1928 1929 TH1F f1("spreadzd", " Spread Zenith Distance ", 1930 axe1.GetNbins(), axe1.GetXmin(), axe1.GetXmax()); 1931 f1.SetXTitle("Zd [\\circ]"); 1932 for (int i=0; i<axe1.GetNbins(); i++) 1933 f1.SetBinError(i, p1->GetBinError(i)); 1934 f1.SetLineColor(kRed); 1935 f1.SetStats(0); 1936 f1.DrawCopy(); 1937 1938 c->cd(4); 1939 1940 // ---------- 1941 1942 TAxis &axe2 = *h2.GetXaxis(); 1943 1944 TH1F f2("spreadaz", " Spread Azimuth ", 1945 axe2.GetNbins(), axe2.GetXmin(), axe2.GetXmax()); 1946 f2.SetXTitle("Az [\\circ]"); 1947 for (int i=0; i<axe2.GetNbins(); i++) 1948 f2.SetBinError(i, p2->GetBinError(i)); 1949 f2.SetLineColor(kRed); 1950 f2.SetStats(0); 1951 f2.DrawCopy(); 1952 1953 // ---------- 1842 1954 1843 1955 if (del)
Note:
See TracChangeset
for help on using the changeset viewer.